source: SVN/rincon/u-boot/board/netta/pcmcia.c @ 55

Last change on this file since 55 was 55, checked in by Tim Harvey, 22 months ago

rincon: added latest u-boot source

restored form server backup

Signed-off-by: Tim Harvey <tharvey@…>

File size: 8.4 KB
Line 
1#include <common.h>
2#include <mpc8xx.h>
3#include <pcmcia.h>
4
5#undef  CONFIG_PCMCIA
6
7#if defined(CONFIG_CMD_PCMCIA)
8#define CONFIG_PCMCIA
9#endif
10
11#if defined(CONFIG_CMD_IDE) && defined(CONFIG_IDE_8xx_PCCARD)
12#define CONFIG_PCMCIA
13#endif
14
15#ifdef  CONFIG_PCMCIA
16
17/* some sane bit macros */
18#define _BD(_b)                         (1U << (31-(_b)))
19#define _BDR(_l, _h)                    (((((1U << (31-(_l))) - 1) << 1) | 1) & ~((1U << (31-(_h))) - 1))
20
21#define _BW(_b)                         (1U << (15-(_b)))
22#define _BWR(_l, _h)                    (((((1U << (15-(_l))) - 1) << 1) | 1) & ~((1U << (15-(_h))) - 1))
23
24#define _BB(_b)                         (1U << (7-(_b)))
25#define _BBR(_l, _h)                    (((((1U << (7-(_l))) - 1) << 1) | 1) & ~((1U << (7-(_h))) - 1))
26
27#define _B(_b)                          _BD(_b)
28#define _BR(_l, _h)                     _BDR(_l, _h)
29
30#define PCMCIA_BOARD_MSG "NETTA"
31
32static const unsigned short vppd_masks[2] = { _BW(14), _BW(15) };
33
34static void cfg_vppd(int no)
35{
36        volatile immap_t *immap = (immap_t *)CFG_IMMR;
37        unsigned short mask;
38
39        if ((unsigned int)no >= sizeof(vppd_masks)/sizeof(vppd_masks[0]))
40                return;
41
42        mask = vppd_masks[no];
43
44        immap->im_ioport.iop_papar &= ~mask;
45        immap->im_ioport.iop_paodr &= ~mask;
46        immap->im_ioport.iop_padir |=  mask;
47}
48
49static void set_vppd(int no, int what)
50{
51        volatile immap_t *immap = (immap_t *)CFG_IMMR;
52        unsigned short mask;
53
54        if ((unsigned int)no >= sizeof(vppd_masks)/sizeof(vppd_masks[0]))
55                return;
56
57        mask = vppd_masks[no];
58
59        if (what)
60                immap->im_ioport.iop_padat |= mask;
61        else
62                immap->im_ioport.iop_padat &= ~mask;
63}
64
65static const unsigned short vccd_masks[2] = { _BW(10), _BW(6) };
66
67static void cfg_vccd(int no)
68{
69        volatile immap_t *immap = (immap_t *)CFG_IMMR;
70        unsigned short mask;
71
72        if ((unsigned int)no >= sizeof(vccd_masks)/sizeof(vccd_masks[0]))
73                return;
74
75        mask = vccd_masks[no];
76
77        immap->im_ioport.iop_papar &= ~mask;
78        immap->im_ioport.iop_paodr &= ~mask;
79        immap->im_ioport.iop_padir |=  mask;
80}
81
82static void set_vccd(int no, int what)
83{
84        volatile immap_t *immap = (immap_t *)CFG_IMMR;
85        unsigned short mask;
86
87        if ((unsigned int)no >= sizeof(vccd_masks)/sizeof(vccd_masks[0]))
88                return;
89
90        mask = vccd_masks[no];
91
92        if (what)
93                immap->im_ioport.iop_padat |= mask;
94        else
95                immap->im_ioport.iop_padat &= ~mask;
96}
97
98static const unsigned short oc_mask = _BW(8);
99
100static void cfg_oc(void)
101{
102        volatile immap_t *immap = (immap_t *)CFG_IMMR;
103        unsigned short mask = oc_mask;
104
105        immap->im_ioport.iop_pcdir &= ~mask;
106        immap->im_ioport.iop_pcso  &= ~mask;
107        immap->im_ioport.iop_pcint &= ~mask;
108        immap->im_ioport.iop_pcpar &= ~mask;
109}
110
111static int get_oc(void)
112{
113        volatile immap_t *immap = (immap_t *)CFG_IMMR;
114        unsigned short mask = oc_mask;
115        int what;
116
117        what = !!(immap->im_ioport.iop_pcdat & mask);;
118        return what;
119}
120
121static const unsigned short shdn_mask = _BW(12);
122
123static void cfg_shdn(void)
124{
125        volatile immap_t *immap = (immap_t *)CFG_IMMR;
126        unsigned short mask;
127
128        mask = shdn_mask;
129
130        immap->im_ioport.iop_papar &= ~mask;
131        immap->im_ioport.iop_paodr &= ~mask;
132        immap->im_ioport.iop_padir |=  mask;
133}
134
135static void set_shdn(int what)
136{
137        volatile immap_t *immap = (immap_t *)CFG_IMMR;
138        unsigned short mask;
139
140        mask = shdn_mask;
141
142        if (what)
143                immap->im_ioport.iop_padat |= mask;
144        else
145                immap->im_ioport.iop_padat &= ~mask;
146}
147
148static void cfg_ports (void)
149{
150        volatile immap_t        *immap;
151        volatile cpm8xx_t       *cp;
152
153        immap = (immap_t *)CFG_IMMR;
154        cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
155
156
157        cfg_vppd(0); cfg_vppd(1);       /* VPPD0,VPPD1 VAVPP => Hi-Z */
158        cfg_vccd(0); cfg_vccd(1);       /* 3V and 5V off */
159        cfg_shdn();
160        cfg_oc();
161
162        /*
163        * Configure Port A for TPS2211 PC-Card Power-Interface Switch
164        *
165        * Switch off all voltages, assert shutdown
166        */
167        set_vppd(0, 1); set_vppd(1, 1);
168        set_vccd(0, 0); set_vccd(1, 0);
169        set_shdn(1);
170
171        udelay(100000);
172}
173
174int pcmcia_hardware_enable(int slot)
175{
176        volatile immap_t        *immap;
177        volatile cpm8xx_t       *cp;
178        volatile pcmconf8xx_t   *pcmp;
179        volatile sysconf8xx_t   *sysp;
180        uint reg, pipr, mask;
181        int i;
182
183        debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
184
185        udelay(10000);
186
187        immap = (immap_t *)CFG_IMMR;
188        sysp  = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
189        pcmp  = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
190        cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
191
192        /* Configure Ports for TPS2211A PC-Card Power-Interface Switch */
193        cfg_ports ();
194
195        /* clear interrupt state, and disable interrupts */
196        pcmp->pcmc_pscr =  PCMCIA_MASK(_slot_);
197        pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
198
199        /*
200        * Disable interrupts, DMA, and PCMCIA buffers
201        * (isolate the interface) and assert RESET signal
202        */
203        debug ("Disable PCMCIA buffers and assert RESET\n");
204        reg  = 0;
205        reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
206        reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
207        PCMCIA_PGCRX(_slot_) = reg;
208
209        udelay(500);
210
211        /*
212        * Make sure there is a card in the slot, then configure the interface.
213        */
214        udelay(10000);
215        debug ("[%d] %s: PIPR(%p)=0x%x\n",
216               __LINE__,__FUNCTION__,
217               &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
218        if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
219                printf ("   No Card found\n");
220                return (1);
221        }
222
223        /*
224        * Power On: Set VAVCC to 3.3V or 5V, set VAVPP to Hi-Z
225        */
226        mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
227        pipr = pcmp->pcmc_pipr;
228        debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
229               pipr,
230               (reg&PCMCIA_VS1(slot))?"n":"ff",
231               (reg&PCMCIA_VS2(slot))?"n":"ff");
232
233        if ((pipr & mask) == mask) {
234                set_vppd(0, 1); set_vppd(1, 1);         /* VAVPP => Hi-Z */
235                set_vccd(0, 0); set_vccd(1, 1);         /* 5V on, 3V off */
236                puts (" 5.0V card found: ");
237        } else {
238                set_vppd(0, 1); set_vppd(1, 1);         /* VAVPP => Hi-Z */
239                set_vccd(0, 1); set_vccd(1, 0);         /* 5V off, 3V on */
240                puts (" 3.3V card found: ");
241        }
242
243        /*  Wait 500 ms; use this to check for over-current */
244        for (i=0; i<5000; ++i) {
245                if (!get_oc()) {
246                        printf ("   *** Overcurrent - Safety shutdown ***\n");
247                        set_vccd(0, 0); set_vccd(1, 0);         /* VAVPP => Hi-Z */
248                        return (1);
249                }
250                udelay (100);
251        }
252
253        debug ("Enable PCMCIA buffers and stop RESET\n");
254        reg  =  PCMCIA_PGCRX(_slot_);
255        reg &= ~__MY_PCMCIA_GCRX_CXRESET;       /* active high */
256        reg &= ~__MY_PCMCIA_GCRX_CXOE;          /* active low  */
257        PCMCIA_PGCRX(_slot_) = reg;
258
259        udelay(250000); /* some cards need >150 ms to come up :-( */
260
261        debug ("# hardware_enable done\n");
262
263        return (0);
264}
265
266
267#if defined(CONFIG_CMD_PCMCIA)
268int pcmcia_hardware_disable(int slot)
269{
270        volatile immap_t        *immap;
271        volatile pcmconf8xx_t   *pcmp;
272        u_long reg;
273
274        debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
275
276        immap = (immap_t *)CFG_IMMR;
277        pcmp  = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
278
279        /* Configure PCMCIA General Control Register */
280        debug ("Disable PCMCIA buffers and assert RESET\n");
281        reg  = 0;
282        reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
283        reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
284        PCMCIA_PGCRX(_slot_) = reg;
285
286        /* All voltages off / Hi-Z */
287        set_vppd(0, 1); set_vppd(1, 1);
288        set_vccd(0, 1); set_vccd(1, 1);
289
290        udelay(10000);
291
292        return (0);
293}
294#endif
295
296
297int pcmcia_voltage_set(int slot, int vcc, int vpp)
298{
299        volatile immap_t        *immap;
300        volatile cpm8xx_t       *cp;
301        volatile pcmconf8xx_t   *pcmp;
302        u_long reg;
303        ushort sreg;
304
305        debug ("voltage_set: "
306                        PCMCIA_BOARD_MSG
307                        " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
308        'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
309
310        immap = (immap_t *)CFG_IMMR;
311        cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
312        pcmp  = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
313        /*
314        * Disable PCMCIA buffers (isolate the interface)
315        * and assert RESET signal
316        */
317        debug ("Disable PCMCIA buffers and assert RESET\n");
318        reg  = PCMCIA_PGCRX(_slot_);
319        reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
320        reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
321        PCMCIA_PGCRX(_slot_) = reg;
322        udelay(500);
323
324        /*
325        * Configure Port C pins for
326        * 5 Volts Enable and 3 Volts enable,
327        * Turn all power pins to Hi-Z
328        */
329        debug ("PCMCIA power OFF\n");
330        cfg_ports ();   /* Enables switch, but all in Hi-Z */
331
332        sreg  = immap->im_ioport.iop_pcdat;
333        set_vppd(0, 1); set_vppd(1, 1);
334
335        switch(vcc) {
336                case  0:
337                        break;  /* Switch off           */
338
339                case 33:
340                        set_vccd(0, 1); set_vccd(1, 0);
341                        break;
342
343                case 50:
344                        set_vccd(0, 0); set_vccd(1, 1);
345                        break;
346
347                default:
348                        goto done;
349        }
350
351        /* Checking supported voltages */
352
353        debug ("PIPR: 0x%x --> %s\n",
354               pcmp->pcmc_pipr,
355               (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
356
357done:
358                        debug ("Enable PCMCIA buffers and stop RESET\n");
359        reg  =  PCMCIA_PGCRX(_slot_);
360        reg &= ~__MY_PCMCIA_GCRX_CXRESET;       /* active high */
361        reg &= ~__MY_PCMCIA_GCRX_CXOE;          /* active low  */
362        PCMCIA_PGCRX(_slot_) = reg;
363        udelay(500);
364
365        debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
366               slot+'A');
367        return (0);
368}
369
370#endif  /* CONFIG_PCMCIA */
Note: See TracBrowser for help on using the repository browser.