]>
Commit | Line | Data |
---|---|---|
9d407995 WD |
1 | #include <common.h> |
2 | #include <mpc8xx.h> | |
3 | #include <pcmcia.h> | |
4 | ||
5 | #undef CONFIG_PCMCIA | |
6 | ||
c508a4ce | 7 | #if defined(CONFIG_CMD_PCMCIA) |
9d407995 WD |
8 | #define CONFIG_PCMCIA |
9 | #endif | |
10 | ||
c508a4ce | 11 | #if defined(CONFIG_CMD_IDE) && defined(CONFIG_IDE_8xx_PCCARD) |
9d407995 WD |
12 | #define CONFIG_PCMCIA |
13 | #endif | |
14 | ||
15 | #ifdef CONFIG_PCMCIA | |
16 | ||
17 | #define PCMCIA_BOARD_MSG "KUP" | |
18 | ||
19 | #define KUP4K_PCMCIA_B_3V3 (0x00020000) | |
20 | ||
21 | int pcmcia_hardware_enable(int slot) | |
22 | { | |
23 | volatile immap_t *immap; | |
24 | volatile cpm8xx_t *cp; | |
25 | volatile pcmconf8xx_t *pcmp; | |
26 | volatile sysconf8xx_t *sysp; | |
27 | uint reg, mask; | |
28 | ||
29 | debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot); | |
30 | ||
31 | udelay(10000); | |
32 | ||
6d0f6bcf JCPV |
33 | immap = (immap_t *)CONFIG_SYS_IMMR; |
34 | sysp = (sysconf8xx_t *)(&(((immap_t *)CONFIG_SYS_IMMR)->im_siu_conf)); | |
35 | pcmp = (pcmconf8xx_t *)(&(((immap_t *)CONFIG_SYS_IMMR)->im_pcmcia)); | |
36 | cp = (cpm8xx_t *)(&(((immap_t *)CONFIG_SYS_IMMR)->im_cpm)); | |
9d407995 WD |
37 | |
38 | /* | |
39 | * Configure SIUMCR to enable PCMCIA port B | |
40 | * (VFLS[0:1] are not used for debugging, we connect FRZ# instead) | |
41 | */ | |
42 | sysp->sc_siumcr &= ~SIUMCR_DBGC11; /* set DBGC to 00 */ | |
43 | ||
44 | /* clear interrupt state, and disable interrupts */ | |
45 | pcmp->pcmc_pscr = PCMCIA_MASK(slot); | |
46 | pcmp->pcmc_per &= ~PCMCIA_MASK(slot); | |
47 | ||
48 | /* | |
49 | * Disable interrupts, DMA, and PCMCIA buffers | |
50 | * (isolate the interface) and assert RESET signal | |
51 | */ | |
52 | debug ("Disable PCMCIA buffers and assert RESET\n"); | |
53 | reg = 0; | |
54 | reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */ | |
55 | reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */ | |
56 | PCMCIA_PGCRX(slot) = reg; | |
57 | udelay(2500); | |
58 | ||
59 | /* | |
60 | * Configure Port B pins for | |
61 | * 3 Volts enable | |
62 | */ | |
63 | if (slot) { /* Slot A is built-in */ | |
64 | cp->cp_pbdir |= KUP4K_PCMCIA_B_3V3; | |
65 | cp->cp_pbpar &= ~KUP4K_PCMCIA_B_3V3; | |
66 | /* remove all power */ | |
67 | cp->cp_pbdat |= KUP4K_PCMCIA_B_3V3; /* active low */ | |
68 | } | |
69 | /* | |
70 | * Make sure there is a card in the slot, then configure the interface. | |
71 | */ | |
72 | udelay(10000); | |
73 | debug ("[%d] %s: PIPR(%p)=0x%x\n", | |
74 | __LINE__,__FUNCTION__, | |
75 | &(pcmp->pcmc_pipr),pcmp->pcmc_pipr); | |
76 | if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) { | |
77 | printf (" No Card found\n"); | |
78 | return (1); | |
79 | } | |
80 | ||
81 | /* | |
82 | * Power On. | |
83 | */ | |
84 | printf("%s Slot %c:", slot ? "" : "\n", 'A' + slot); | |
85 | mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot); | |
86 | reg = pcmp->pcmc_pipr; | |
87 | debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n", | |
88 | reg, | |
89 | (reg&PCMCIA_VS1(slot))?"n":"ff", | |
90 | (reg&PCMCIA_VS2(slot))?"n":"ff"); | |
91 | if ((reg & mask) == mask) { | |
92 | puts (" 5.0V card found: NOT SUPPORTED !!!\n"); | |
93 | } else { | |
94 | if(slot) | |
95 | cp->cp_pbdat &= ~KUP4K_PCMCIA_B_3V3; | |
96 | puts (" 3.3V card found: "); | |
97 | } | |
98 | #if 0 | |
99 | /* VCC switch error flag, PCMCIA slot INPACK_ pin */ | |
100 | cp->cp_pbdir &= ~(0x0020 | 0x0010); | |
101 | cp->cp_pbpar &= ~(0x0020 | 0x0010); | |
102 | udelay(500000); | |
103 | #endif | |
104 | debug ("Enable PCMCIA buffers and stop RESET\n"); | |
105 | reg = PCMCIA_PGCRX(slot); | |
106 | reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */ | |
107 | reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */ | |
108 | PCMCIA_PGCRX(slot) = reg; | |
109 | ||
110 | udelay(250000); /* some cards need >150 ms to come up :-( */ | |
111 | ||
112 | debug ("# hardware_enable done\n"); | |
113 | ||
114 | return (0); | |
115 | } | |
116 | ||
117 | ||
c508a4ce | 118 | #if defined(CONFIG_CMD_PCMCIA) |
9d407995 WD |
119 | int pcmcia_hardware_disable(int slot) |
120 | { | |
121 | volatile immap_t *immap; | |
122 | volatile cpm8xx_t *cp; | |
123 | volatile pcmconf8xx_t *pcmp; | |
124 | u_long reg; | |
125 | ||
126 | debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot); | |
127 | ||
6d0f6bcf JCPV |
128 | immap = (immap_t *)CONFIG_SYS_IMMR; |
129 | pcmp = (pcmconf8xx_t *)(&(((immap_t *)CONFIG_SYS_IMMR)->im_pcmcia)); | |
130 | cp = (cpm8xx_t *)(&(((immap_t *)CONFIG_SYS_IMMR)->im_cpm)); | |
9d407995 WD |
131 | |
132 | /* remove all power */ | |
133 | if (slot) | |
134 | cp->cp_pbdat |= KUP4K_PCMCIA_B_3V3; | |
135 | ||
136 | /* Configure PCMCIA General Control Register */ | |
137 | debug ("Disable PCMCIA buffers and assert RESET\n"); | |
138 | reg = 0; | |
139 | reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */ | |
140 | reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */ | |
141 | PCMCIA_PGCRX(slot) = reg; | |
142 | ||
143 | udelay(10000); | |
144 | ||
145 | return (0); | |
146 | } | |
d39b5741 | 147 | #endif |
9d407995 WD |
148 | |
149 | ||
150 | int pcmcia_voltage_set(int slot, int vcc, int vpp) | |
151 | { | |
152 | volatile immap_t *immap; | |
153 | volatile cpm8xx_t *cp; | |
154 | volatile pcmconf8xx_t *pcmp; | |
155 | u_long reg; | |
156 | ||
157 | debug ("voltage_set: " \ | |
158 | PCMCIA_BOARD_MSG \ | |
159 | " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n", | |
160 | 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10); | |
161 | ||
162 | if (!slot) /* Slot A is not configurable */ | |
163 | return 0; | |
164 | ||
6d0f6bcf JCPV |
165 | immap = (immap_t *)CONFIG_SYS_IMMR; |
166 | pcmp = (pcmconf8xx_t *)(&(((immap_t *)CONFIG_SYS_IMMR)->im_pcmcia)); | |
167 | cp = (cpm8xx_t *)(&(((immap_t *)CONFIG_SYS_IMMR)->im_cpm)); | |
9d407995 WD |
168 | |
169 | /* | |
170 | * Disable PCMCIA buffers (isolate the interface) | |
171 | * and assert RESET signal | |
172 | */ | |
173 | debug ("Disable PCMCIA buffers and assert RESET\n"); | |
174 | reg = PCMCIA_PGCRX(slot); | |
175 | reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */ | |
176 | reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */ | |
177 | PCMCIA_PGCRX(slot) = reg; | |
178 | udelay(500); | |
179 | ||
180 | debug ("PCMCIA power OFF\n"); | |
181 | /* | |
182 | * Configure Port B pins for | |
183 | * 3 Volts enable | |
184 | */ | |
185 | cp->cp_pbdir |= KUP4K_PCMCIA_B_3V3; | |
186 | cp->cp_pbpar &= ~KUP4K_PCMCIA_B_3V3; | |
187 | /* remove all power */ | |
188 | cp->cp_pbdat |= KUP4K_PCMCIA_B_3V3; /* active low */ | |
189 | ||
190 | switch(vcc) { | |
53677ef1 | 191 | case 0: break; |
9d407995 WD |
192 | case 33: |
193 | cp->cp_pbdat &= ~KUP4K_PCMCIA_B_3V3; | |
194 | debug ("PCMCIA powered at 3.3V\n"); | |
195 | break; | |
196 | case 50: | |
197 | debug ("PCMCIA: 5Volt vcc not supported\n"); | |
198 | break; | |
199 | default: | |
200 | puts("PCMCIA: vcc not supported"); | |
201 | break; | |
202 | } | |
203 | udelay(10000); | |
204 | /* Checking supported voltages */ | |
205 | ||
206 | debug ("PIPR: 0x%x --> %s\n", | |
207 | pcmp->pcmc_pipr, | |
208 | (pcmp->pcmc_pipr & (0x80000000 >> (slot << 4))) | |
209 | ? "only 5 V --> NOT SUPPORTED" | |
210 | : "can do 3.3V"); | |
211 | ||
212 | ||
213 | debug ("Enable PCMCIA buffers and stop RESET\n"); | |
214 | reg = PCMCIA_PGCRX(slot); | |
215 | reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */ | |
216 | reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */ | |
217 | PCMCIA_PGCRX(slot) = reg; | |
218 | udelay(500); | |
219 | ||
220 | debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n", | |
221 | slot+'A'); | |
222 | return (0); | |
223 | } | |
224 | ||
225 | #endif /* CONFIG_PCMCIA */ |