]>
Commit | Line | Data |
---|---|---|
9d407995 WD |
1 | /* -------------------------------------------------------------------- */ |
2 | /* TQM8xxL Boards by TQ Components */ | |
3 | /* SC8xx Boards by SinoVee Microsystems */ | |
4 | /* -------------------------------------------------------------------- */ | |
5 | #include <common.h> | |
966083e9 | 6 | #ifdef CONFIG_8xx |
9d407995 | 7 | #include <mpc8xx.h> |
966083e9 | 8 | #endif |
9d407995 WD |
9 | #include <pcmcia.h> |
10 | ||
11 | #undef CONFIG_PCMCIA | |
12 | ||
cb51c0bf | 13 | #if defined(CONFIG_CMD_PCMCIA) |
9d407995 WD |
14 | #define CONFIG_PCMCIA |
15 | #endif | |
16 | ||
cb51c0bf | 17 | #if defined(CONFIG_CMD_IDE) && defined(CONFIG_IDE_8xx_PCCARD) |
9d407995 WD |
18 | #define CONFIG_PCMCIA |
19 | #endif | |
20 | ||
21 | #if defined(CONFIG_PCMCIA) \ | |
22 | && (defined(CONFIG_TQM8xxL) || defined(CONFIG_SVM_SC8xx)) | |
23 | ||
24 | #if defined(CONFIG_VIRTLAB2) | |
25 | #define PCMCIA_BOARD_MSG "Virtlab2" | |
26 | #elif defined(CONFIG_TQM8xxL) | |
27 | #define PCMCIA_BOARD_MSG "TQM8xxL" | |
28 | #elif defined(CONFIG_SVM_SC8xx) | |
29 | #define PCMCIA_BOARD_MSG "SC8xx" | |
30 | #endif | |
31 | ||
32 | #if defined(CONFIG_NSCU) | |
33 | ||
34 | #define power_config(slot) do {} while (0) | |
35 | #define power_off(slot) do {} while (0) | |
36 | #define power_on_5_0(slot) do {} while (0) | |
37 | #define power_on_3_3(slot) do {} while (0) | |
38 | ||
39 | #elif defined(CONFIG_HMI10) | |
40 | ||
41 | static inline void power_config(int slot) | |
42 | { | |
43 | volatile immap_t *immap = (immap_t *)CFG_IMMR; | |
44 | /* | |
45 | * Configure Port B pins for | |
46 | * 5 Volts Enable and 3 Volts enable | |
47 | */ | |
48 | immap->im_cpm.cp_pbpar &= ~(0x00000300); | |
49 | } | |
50 | ||
51 | static inline void power_off(int slot) | |
52 | { | |
53 | volatile immap_t *immap = (immap_t *)CFG_IMMR; | |
54 | /* remove all power */ | |
55 | immap->im_cpm.cp_pbdat |= 0x00000300; | |
56 | } | |
57 | ||
58 | static inline void power_on_5_0(int slot) | |
59 | { | |
60 | volatile immap_t *immap = (immap_t *)CFG_IMMR; | |
61 | immap->im_cpm.cp_pbdat &= ~(0x0000100); | |
62 | immap->im_cpm.cp_pbdir |= 0x00000300; | |
63 | } | |
64 | ||
65 | static inline void power_on_3_3(int slot) | |
66 | { | |
67 | volatile immap_t *immap = (immap_t *)CFG_IMMR; | |
68 | immap->im_cpm.cp_pbdat &= ~(0x0000200); | |
69 | immap->im_cpm.cp_pbdir |= 0x00000300; | |
70 | } | |
71 | ||
72 | #elif defined(CONFIG_VIRTLAB2) | |
73 | ||
74 | #define power_config(slot) do {} while (0) | |
75 | static inline void power_off(int slot) | |
76 | { | |
77 | volatile unsigned char *powerctl = | |
78 | (volatile unsigned char *)PCMCIA_CTRL; | |
79 | *powerctl = 0; | |
80 | } | |
81 | ||
82 | static inline void power_on_5_0(int slot) | |
83 | { | |
84 | volatile unsigned char *powerctl = | |
85 | (volatile unsigned char *)PCMCIA_CTRL; | |
86 | *powerctl = 2; /* Enable 5V Vccout */ | |
87 | } | |
88 | ||
89 | static inline void power_on_3_3(int slot) | |
90 | { | |
91 | volatile unsigned char *powerctl = | |
92 | (volatile unsigned char *)PCMCIA_CTRL; | |
93 | *powerctl = 1; /* Enable 3.3V Vccout */ | |
94 | } | |
95 | ||
96 | #else | |
97 | ||
98 | static inline void power_config(int slot) | |
99 | { | |
100 | volatile immap_t *immap = (immap_t *)CFG_IMMR; | |
101 | /* | |
102 | * Configure Port C pins for | |
103 | * 5 Volts Enable and 3 Volts enable | |
104 | */ | |
105 | immap->im_ioport.iop_pcpar &= ~(0x0002 | 0x0004); | |
106 | immap->im_ioport.iop_pcso &= ~(0x0002 | 0x0004); | |
107 | } | |
108 | ||
109 | static inline void power_off(int slot) | |
110 | { | |
111 | volatile immap_t *immap = (immap_t *)CFG_IMMR; | |
112 | immap->im_ioport.iop_pcdat &= ~(0x0002 | 0x0004); | |
113 | } | |
114 | ||
115 | static inline void power_on_5_0(int slot) | |
116 | { | |
117 | volatile immap_t *immap = (immap_t *)CFG_IMMR; | |
118 | immap->im_ioport.iop_pcdat |= 0x0004; | |
119 | immap->im_ioport.iop_pcdir |= (0x0002 | 0x0004); | |
120 | } | |
121 | ||
122 | static inline void power_on_3_3(int slot) | |
123 | { | |
124 | volatile immap_t *immap = (immap_t *)CFG_IMMR; | |
125 | immap->im_ioport.iop_pcdat |= 0x0002; | |
126 | immap->im_ioport.iop_pcdir |= (0x0002 | 0x0004); | |
127 | } | |
128 | ||
129 | #endif | |
130 | ||
131 | #ifdef CONFIG_HMI10 | |
132 | static inline int check_card_is_absent(int slot) | |
133 | { | |
134 | volatile pcmconf8xx_t *pcmp = | |
135 | (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia)); | |
136 | return pcmp->pcmc_pipr & (0x10000000 >> (slot << 4)); | |
137 | } | |
138 | #else | |
139 | static inline int check_card_is_absent(int slot) | |
140 | { | |
141 | volatile pcmconf8xx_t *pcmp = | |
142 | (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia)); | |
143 | return pcmp->pcmc_pipr & (0x18000000 >> (slot << 4)); | |
144 | } | |
145 | #endif | |
146 | ||
147 | #ifdef NSCU_OE_INV | |
148 | #define NSCU_GCRX_CXOE 0 | |
149 | #else | |
150 | #define NSCU_GCRX_CXOE __MY_PCMCIA_GCRX_CXOE | |
151 | #endif | |
152 | ||
153 | int pcmcia_hardware_enable(int slot) | |
154 | { | |
155 | volatile pcmconf8xx_t *pcmp = | |
156 | (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia)); | |
157 | volatile sysconf8xx_t *sysp = | |
158 | (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf)); | |
159 | uint reg, mask; | |
160 | ||
161 | debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot); | |
162 | ||
163 | udelay(10000); | |
164 | ||
165 | /* | |
166 | * Configure SIUMCR to enable PCMCIA port B | |
167 | * (VFLS[0:1] are not used for debugging, we connect FRZ# instead) | |
168 | */ | |
169 | sysp->sc_siumcr &= ~SIUMCR_DBGC11; /* set DBGC to 00 */ | |
170 | ||
171 | /* clear interrupt state, and disable interrupts */ | |
172 | pcmp->pcmc_pscr = PCMCIA_MASK(slot); | |
173 | pcmp->pcmc_per &= ~PCMCIA_MASK(slot); | |
174 | ||
175 | /* | |
176 | * Disable interrupts, DMA, and PCMCIA buffers | |
177 | * (isolate the interface) and assert RESET signal | |
178 | */ | |
179 | debug ("Disable PCMCIA buffers and assert RESET\n"); | |
180 | reg = 0; | |
181 | reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */ | |
182 | reg |= NSCU_GCRX_CXOE; | |
183 | ||
184 | PCMCIA_PGCRX(slot) = reg; | |
185 | udelay(500); | |
186 | ||
187 | power_config(slot); | |
188 | power_off(slot); | |
189 | ||
190 | /* | |
191 | * Make sure there is a card in the slot, then configure the interface. | |
192 | */ | |
193 | udelay(10000); | |
194 | debug ("[%d] %s: PIPR(%p)=0x%x\n", __LINE__,__FUNCTION__, | |
195 | &(pcmp->pcmc_pipr),pcmp->pcmc_pipr); | |
b87dfd28 | 196 | |
9d407995 WD |
197 | if (check_card_is_absent(slot)) { |
198 | printf (" No Card found\n"); | |
199 | return (1); | |
200 | } | |
201 | ||
202 | /* | |
203 | * Power On. | |
204 | */ | |
205 | mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot); | |
206 | reg = pcmp->pcmc_pipr; | |
207 | debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n", | |
208 | reg, | |
209 | (reg&PCMCIA_VS1(slot))?"n":"ff", | |
210 | (reg&PCMCIA_VS2(slot))?"n":"ff"); | |
b87dfd28 | 211 | |
9d407995 WD |
212 | if ((reg & mask) == mask) { |
213 | power_on_5_0(slot); | |
214 | puts (" 5.0V card found: "); | |
215 | } else { | |
216 | power_on_3_3(slot); | |
217 | puts (" 3.3V card found: "); | |
218 | } | |
219 | ||
220 | #if 0 | |
221 | /* VCC switch error flag, PCMCIA slot INPACK_ pin */ | |
222 | cp->cp_pbdir &= ~(0x0020 | 0x0010); | |
223 | cp->cp_pbpar &= ~(0x0020 | 0x0010); | |
224 | udelay(500000); | |
225 | #endif | |
226 | ||
227 | udelay(1000); | |
228 | debug ("Enable PCMCIA buffers and stop RESET\n"); | |
229 | reg = PCMCIA_PGCRX(slot); | |
230 | reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */ | |
231 | reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */ | |
232 | reg &= ~NSCU_GCRX_CXOE; | |
b87dfd28 | 233 | |
9d407995 WD |
234 | PCMCIA_PGCRX(slot) = reg; |
235 | ||
236 | udelay(250000); /* some cards need >150 ms to come up :-( */ | |
237 | ||
238 | debug ("# hardware_enable done\n"); | |
239 | ||
240 | return (0); | |
241 | } | |
242 | ||
243 | ||
cb51c0bf | 244 | #if defined(CONFIG_CMD_PCMCIA) |
9d407995 WD |
245 | int pcmcia_hardware_disable(int slot) |
246 | { | |
9d407995 WD |
247 | u_long reg; |
248 | ||
249 | debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot); | |
250 | ||
251 | ||
252 | /* remove all power */ | |
253 | power_off(slot); | |
254 | ||
255 | debug ("Disable PCMCIA buffers and assert RESET\n"); | |
256 | reg = 0; | |
257 | reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */ | |
258 | reg |= NSCU_GCRX_CXOE; /* active low */ | |
259 | ||
260 | PCMCIA_PGCRX(slot) = reg; | |
261 | ||
262 | udelay(10000); | |
263 | ||
264 | return (0); | |
265 | } | |
ddb5d86f | 266 | #endif |
9d407995 WD |
267 | |
268 | int pcmcia_voltage_set(int slot, int vcc, int vpp) | |
269 | { | |
270 | #ifndef CONFIG_NSCU | |
966083e9 WD |
271 | u_long reg; |
272 | # ifdef DEBUG | |
9d407995 WD |
273 | volatile pcmconf8xx_t *pcmp = |
274 | (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia)); | |
966083e9 | 275 | # endif |
9d407995 WD |
276 | |
277 | debug ("voltage_set: " PCMCIA_BOARD_MSG | |
278 | " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n", | |
279 | 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10); | |
280 | ||
281 | /* | |
282 | * Disable PCMCIA buffers (isolate the interface) | |
283 | * and assert RESET signal | |
284 | */ | |
285 | debug ("Disable PCMCIA buffers and assert RESET\n"); | |
286 | reg = PCMCIA_PGCRX(slot); | |
287 | reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */ | |
288 | reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */ | |
289 | reg |= NSCU_GCRX_CXOE; /* active low */ | |
b87dfd28 | 290 | |
9d407995 WD |
291 | PCMCIA_PGCRX(slot) = reg; |
292 | udelay(500); | |
293 | ||
294 | debug ("PCMCIA power OFF\n"); | |
295 | power_config(slot); | |
296 | power_off(slot); | |
297 | ||
298 | switch(vcc) { | |
299 | case 0: break; | |
300 | case 33: power_on_3_3(slot); break; | |
301 | case 50: power_on_5_0(slot); break; | |
302 | default: goto done; | |
303 | } | |
304 | ||
305 | /* Checking supported voltages */ | |
306 | ||
307 | debug("PIPR: 0x%x --> %s\n", pcmp->pcmc_pipr, | |
308 | (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V"); | |
309 | ||
310 | if (vcc) | |
311 | debug("PCMCIA powered at %sV\n", (vcc == 50) ? "5.0" : "3.3"); | |
312 | else | |
313 | debug("PCMCIA powered down\n"); | |
314 | ||
315 | done: | |
316 | debug("Enable PCMCIA buffers and stop RESET\n"); | |
317 | reg = PCMCIA_PGCRX(slot); | |
318 | reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */ | |
319 | reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */ | |
320 | reg &= ~NSCU_GCRX_CXOE; /* active low */ | |
321 | ||
322 | PCMCIA_PGCRX(slot) = reg; | |
323 | udelay(500); | |
324 | ||
325 | debug("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n", slot+'A'); | |
326 | #endif /* CONFIG_NSCU */ | |
327 | return (0); | |
328 | } | |
329 | ||
330 | #endif /* CONFIG_PCMCIA && (CONFIG_TQM8xxL || CONFIG_SVM_SC8xx) */ |