source: SVN/rincon/u-boot/board/icu862/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: 6.6 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#define PCMCIA_BOARD_MSG "ICU862"
18
19static void cfg_port_B (void)
20{
21        volatile immap_t        *immap;
22        volatile cpm8xx_t       *cp;
23        uint reg;
24
25        immap = (immap_t *)CFG_IMMR;
26        cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
27
28        /*
29        * Configure Port B for TPS2205 PC-Card Power-Interface Switch
30        *
31        * Switch off all voltages, assert shutdown
32        */
33        reg  = cp->cp_pbdat;
34        reg |= (TPS2205_VPP_PGM | TPS2205_VPP_VCC |     /* VAVPP => Hi-Z */
35                        TPS2205_VCC3    | TPS2205_VCC5    |     /* VAVCC => Hi-Z */
36                        TPS2205_SHDN);                          /* enable switch */
37        cp->cp_pbdat = reg;
38
39        cp->cp_pbpar &= ~(TPS2205_INPUTS | TPS2205_OUTPUTS);
40
41        reg = cp->cp_pbdir & ~(TPS2205_INPUTS);
42        cp->cp_pbdir = reg | TPS2205_OUTPUTS;
43
44        debug ("Set Port B: PAR: %08x DIR: %08x DAT: %08x\n",
45               cp->cp_pbpar, cp->cp_pbdir, cp->cp_pbdat);
46}
47
48int pcmcia_hardware_enable(int slot)
49{
50        volatile immap_t        *immap;
51        volatile cpm8xx_t       *cp;
52        volatile pcmconf8xx_t   *pcmp;
53        volatile sysconf8xx_t   *sysp;
54        uint reg, pipr, mask;
55        int i;
56
57        debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
58
59        udelay(10000);
60
61        immap = (immap_t *)CFG_IMMR;
62        sysp  = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
63        pcmp  = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
64        cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
65
66        /* Configure Port B for TPS2205 PC-Card Power-Interface Switch */
67        cfg_port_B ();
68
69        /*
70        * Configure SIUMCR to enable PCMCIA port B
71        * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
72        */
73        sysp->sc_siumcr &= ~SIUMCR_DBGC11;      /* set DBGC to 00 */
74
75        /* clear interrupt state, and disable interrupts */
76        pcmp->pcmc_pscr =  PCMCIA_MASK(_slot_);
77        pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
78
79        /*
80        * Disable interrupts, DMA, and PCMCIA buffers
81        * (isolate the interface) and assert RESET signal
82        */
83        debug ("Disable PCMCIA buffers and assert RESET\n");
84        reg  = 0;
85        reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
86        reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
87        PCMCIA_PGCRX(_slot_) = reg;
88        udelay(500);
89
90        /*
91        * Make sure there is a card in the slot, then configure the interface.
92        */
93        udelay(10000);
94        debug ("[%d] %s: PIPR(%p)=0x%x\n",
95               __LINE__,__FUNCTION__,
96               &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
97        if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
98                printf ("   No Card found\n");
99                return (1);
100        }
101
102        /*
103        * Power On: Set VAVCC to 3.3V or 5V, set VAVPP to Hi-Z
104        */
105        mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
106        pipr = pcmp->pcmc_pipr;
107        debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
108               pipr,
109               (reg&PCMCIA_VS1(slot))?"n":"ff",
110               (reg&PCMCIA_VS2(slot))?"n":"ff");
111
112        reg  = cp->cp_pbdat;
113        if ((pipr & mask) == mask) {
114                reg |= (TPS2205_VPP_PGM | TPS2205_VPP_VCC |     /* VAVPP => Hi-Z */
115                                TPS2205_VCC3);                          /* 3V off       */
116                reg &= ~(TPS2205_VCC5);                         /* 5V on        */
117                puts (" 5.0V card found: ");
118        } else {
119                reg |= (TPS2205_VPP_PGM | TPS2205_VPP_VCC |     /* VAVPP => Hi-Z */
120                                TPS2205_VCC5);                          /* 5V off       */
121                reg &= ~(TPS2205_VCC3);                         /* 3V on        */
122                puts (" 3.3V card found: ");
123        }
124
125        debug ("\nPB DAT: %08x -> 3.3V %s 5.0V %s VPP_PGM %s VPP_VCC %s\n",
126               reg,
127               (reg & TPS2205_VCC3)    ? "off" : "on",
128               (reg & TPS2205_VCC5)    ? "off" : "on",
129               (reg & TPS2205_VPP_PGM) ? "off" : "on",
130               (reg & TPS2205_VPP_VCC) ? "off" : "on" );
131
132        cp->cp_pbdat = reg;
133
134        /*  Wait 500 ms; use this to check for over-current */
135        for (i=0; i<5000; ++i) {
136                if ((cp->cp_pbdat & TPS2205_OC) == 0) {
137                        printf ("   *** Overcurrent - Safety shutdown ***\n");
138                        cp->cp_pbdat &= ~(TPS2205_SHDN);
139                        return (1);
140                }
141                udelay (100);
142        }
143
144        debug ("Enable PCMCIA buffers and stop RESET\n");
145        reg  =  PCMCIA_PGCRX(_slot_);
146        reg &= ~__MY_PCMCIA_GCRX_CXRESET;       /* active high */
147        reg &= ~__MY_PCMCIA_GCRX_CXOE;          /* active low  */
148        PCMCIA_PGCRX(_slot_) = reg;
149
150        udelay(250000); /* some cards need >150 ms to come up :-( */
151
152        debug ("# hardware_enable done\n");
153
154        return (0);
155}
156
157
158#if defined(CONFIG_CMD_PCMCIA)
159int pcmcia_hardware_disable(int slot)
160{
161        volatile immap_t        *immap;
162        volatile cpm8xx_t       *cp;
163        volatile pcmconf8xx_t   *pcmp;
164        u_long reg;
165
166        debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
167
168        immap = (immap_t *)CFG_IMMR;
169        cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
170        pcmp  = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
171
172        /* Shut down */
173        cp->cp_pbdat &= ~(TPS2205_SHDN);
174
175        /* Configure PCMCIA General Control Register */
176        debug ("Disable PCMCIA buffers and assert RESET\n");
177        reg  = 0;
178        reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
179        reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
180        PCMCIA_PGCRX(_slot_) = reg;
181
182        udelay(10000);
183
184        return (0);
185}
186#endif
187
188
189int pcmcia_voltage_set(int slot, int vcc, int vpp)
190{
191        volatile immap_t        *immap;
192        volatile cpm8xx_t       *cp;
193        volatile pcmconf8xx_t   *pcmp;
194        u_long reg;
195
196        debug ("voltage_set: "
197                        PCMCIA_BOARD_MSG
198                        " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
199        'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
200
201        immap = (immap_t *)CFG_IMMR;
202        cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
203        pcmp  = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
204        /*
205        * Disable PCMCIA buffers (isolate the interface)
206        * and assert RESET signal
207        */
208        debug ("Disable PCMCIA buffers and assert RESET\n");
209        reg  = PCMCIA_PGCRX(_slot_);
210        reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
211        reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
212        PCMCIA_PGCRX(_slot_) = reg;
213        udelay(500);
214
215        /*
216        * Configure Port C pins for
217        * 5 Volts Enable and 3 Volts enable,
218        * Turn all power pins to Hi-Z
219        */
220        debug ("PCMCIA power OFF\n");
221        cfg_port_B ();  /* Enables switch, but all in Hi-Z */
222
223        reg  = cp->cp_pbdat;
224
225        switch(vcc) {
226                case  0:                        break;  /* Switch off           */
227                case 33: reg &= ~TPS2205_VCC3;  break;  /* Switch on 3.3V       */
228                case 50: reg &= ~TPS2205_VCC5;  break;  /* Switch on 5.0V       */
229                default:                        goto done;
230        }
231
232        /* Checking supported voltages */
233
234        debug ("PIPR: 0x%x --> %s\n",
235               pcmp->pcmc_pipr,
236               (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
237
238        cp->cp_pbdat = reg;
239
240#ifdef DEBUG
241{
242        char *s;
243
244        if ((reg & TPS2205_VCC3) == 0) {
245                s = "at 3.3V";
246        } else if ((reg & TPS2205_VCC5) == 0) {
247                s = "at 5.0V";
248        } else {
249                s = "down";
250        }
251        printf ("PCMCIA powered %s\n", s);
252}
253#endif
254
255done:
256        debug ("Enable PCMCIA buffers and stop RESET\n");
257        reg  =  PCMCIA_PGCRX(_slot_);
258        reg &= ~__MY_PCMCIA_GCRX_CXRESET;       /* active high */
259        reg &= ~__MY_PCMCIA_GCRX_CXOE;          /* active low  */
260        PCMCIA_PGCRX(_slot_) = reg;
261        udelay(500);
262
263        debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
264               slot+'A');
265        return (0);
266}
267
268#endif  /* CONFIG_PCMCIA */
Note: See TracBrowser for help on using the repository browser.