]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - drivers/pcmcia/mpc8xx_pcmcia.c
Remove HMI10 board support
[karo-tx-uboot.git] / drivers / pcmcia / mpc8xx_pcmcia.c
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 #if defined(CONFIG_PCMCIA)
16
17 #if     defined(CONFIG_IDE_8xx_PCCARD)
18 extern int check_ide_device (int slot);
19 #endif
20
21 extern int pcmcia_hardware_enable (int slot);
22 extern int pcmcia_voltage_set(int slot, int vcc, int vpp);
23
24 #if defined(CONFIG_CMD_PCMCIA)
25 extern int pcmcia_hardware_disable(int slot);
26 #endif
27
28 static u_int m8xx_get_graycode(u_int size);
29 #if 0 /* Disabled */
30 static u_int m8xx_get_speed(u_int ns, u_int is_io);
31 #endif
32
33 /* look up table for pgcrx registers */
34 u_int *pcmcia_pgcrx[2] = {
35         &((immap_t *)CONFIG_SYS_IMMR)->im_pcmcia.pcmc_pgcra,
36         &((immap_t *)CONFIG_SYS_IMMR)->im_pcmcia.pcmc_pgcrb,
37 };
38
39 /*
40  * Search this table to see if the windowsize is
41  * supported...
42  */
43
44 #define M8XX_SIZES_NO 32
45
46 static const u_int m8xx_size_to_gray[M8XX_SIZES_NO] =
47 { 0x00000001, 0x00000002, 0x00000008, 0x00000004,
48   0x00000080, 0x00000040, 0x00000010, 0x00000020,
49   0x00008000, 0x00004000, 0x00001000, 0x00002000,
50   0x00000100, 0x00000200, 0x00000800, 0x00000400,
51
52   0x0fffffff, 0xffffffff, 0xffffffff, 0xffffffff,
53   0x01000000, 0x02000000, 0xffffffff, 0x04000000,
54   0x00010000, 0x00020000, 0x00080000, 0x00040000,
55   0x00800000, 0x00400000, 0x00100000, 0x00200000 };
56
57
58 /* -------------------------------------------------------------------- */
59
60 #if     defined(CONFIG_LWMON) || defined(CONFIG_NSCU)
61 #define CONFIG_SYS_PCMCIA_TIMING        (       PCMCIA_SHT(9)   \
62                                 |       PCMCIA_SST(3)   \
63                                 |       PCMCIA_SL(12))
64 #else
65 #define CONFIG_SYS_PCMCIA_TIMING        (       PCMCIA_SHT(2)   \
66                                 |       PCMCIA_SST(4)   \
67                                 |       PCMCIA_SL(9))
68 #endif
69
70 /* -------------------------------------------------------------------- */
71
72 int pcmcia_on (void)
73 {
74         u_long reg, base;
75         pcmcia_win_t *win;
76         u_int slotbit;
77         u_int rc, slot;
78         int i;
79
80         debug ("Enable PCMCIA " PCMCIA_SLOT_MSG "\n");
81
82         /* intialize the fixed memory windows */
83         win = (pcmcia_win_t *)(&((immap_t *)CONFIG_SYS_IMMR)->im_pcmcia.pcmc_pbr0);
84         base = CONFIG_SYS_PCMCIA_MEM_ADDR;
85
86         if((reg = m8xx_get_graycode(CONFIG_SYS_PCMCIA_MEM_SIZE)) == -1) {
87                 printf ("Cannot set window size to 0x%08x\n",
88                         CONFIG_SYS_PCMCIA_MEM_SIZE);
89                 return (1);
90         }
91
92         slotbit = PCMCIA_SLOT_x;
93         for (i=0; i<PCMCIA_MEM_WIN_NO; ++i) {
94                 win->br = base;
95
96 #if     (PCMCIA_SOCKETS_NO == 2)
97                 if (i == 4) /* Another slot starting from win 4 */
98                         slotbit = (slotbit ? PCMCIA_PSLOT_A : PCMCIA_PSLOT_B);
99 #endif
100                 switch (i) {
101 #ifdef  CONFIG_IDE_8xx_PCCARD
102                 case 4:
103                 case 0: {       /* map attribute memory */
104                         win->or = (     PCMCIA_BSIZE_64M
105                                 |       PCMCIA_PPS_8
106                                 |       PCMCIA_PRS_ATTR
107                                 |       slotbit
108                                 |       PCMCIA_PV
109                                 |       CONFIG_SYS_PCMCIA_TIMING );
110                         break;
111                 }
112                 case 5:
113                 case 1: {       /* map I/O window for data reg */
114                         win->or = (     PCMCIA_BSIZE_1K
115                                 |       PCMCIA_PPS_16
116                                 |       PCMCIA_PRS_IO
117                                 |       slotbit
118                                 |       PCMCIA_PV
119                                 |       CONFIG_SYS_PCMCIA_TIMING );
120                         break;
121                 }
122                 case 6:
123                 case 2: {       /* map I/O window for cmd/ctrl reg block */
124                         win->or = (     PCMCIA_BSIZE_1K
125                                 |       PCMCIA_PPS_8
126                                 |       PCMCIA_PRS_IO
127                                 |       slotbit
128                                 |       PCMCIA_PV
129                                 |       CONFIG_SYS_PCMCIA_TIMING );
130                         break;
131                 }
132 #endif  /* CONFIG_IDE_8xx_PCCARD */
133                 default:        /* set to not valid */
134                         win->or = 0;
135                         break;
136                 }
137
138                 debug ("MemWin %d: PBR 0x%08lX  POR %08lX\n",
139                        i, win->br, win->or);
140                 base += CONFIG_SYS_PCMCIA_MEM_SIZE;
141                 ++win;
142         }
143
144         for (i=0, rc=0, slot=_slot_; i<PCMCIA_SOCKETS_NO; i++, slot = !slot) {
145                 /* turn off voltage */
146                 if ((rc = pcmcia_voltage_set(slot, 0, 0)))
147                         continue;
148
149                 /* Enable external hardware */
150                 if ((rc = pcmcia_hardware_enable(slot)))
151                         continue;
152
153 #ifdef  CONFIG_IDE_8xx_PCCARD
154                 if ((rc = check_ide_device(i)))
155                         continue;
156 #endif
157         }
158         return rc;
159 }
160
161 #if defined(CONFIG_CMD_PCMCIA)
162 int pcmcia_off (void)
163 {
164         int i;
165         pcmcia_win_t *win;
166
167         printf ("Disable PCMCIA " PCMCIA_SLOT_MSG "\n");
168
169         /* clear interrupt state, and disable interrupts */
170         ((immap_t *)CONFIG_SYS_IMMR)->im_pcmcia.pcmc_pscr =  PCMCIA_MASK(_slot_);
171         ((immap_t *)CONFIG_SYS_IMMR)->im_pcmcia.pcmc_per &= ~PCMCIA_MASK(_slot_);
172
173         /* turn off interrupt and disable CxOE */
174         PCMCIA_PGCRX(_slot_) = __MY_PCMCIA_GCRX_CXOE;
175
176         /* turn off memory windows */
177         win = (pcmcia_win_t *)(&((immap_t *)CONFIG_SYS_IMMR)->im_pcmcia.pcmc_pbr0);
178
179         for (i=0; i<PCMCIA_MEM_WIN_NO; ++i) {
180                 /* disable memory window */
181                 win->or = 0;
182                 ++win;
183         }
184
185         /* turn off voltage */
186         pcmcia_voltage_set(_slot_, 0, 0);
187
188         /* disable external hardware */
189         printf ("Shutdown and Poweroff " PCMCIA_SLOT_MSG "\n");
190         pcmcia_hardware_disable(_slot_);
191         return 0;
192 }
193 #endif
194
195
196 static u_int m8xx_get_graycode(u_int size)
197 {
198         u_int k;
199
200         for (k = 0; k < M8XX_SIZES_NO; k++) {
201                 if(m8xx_size_to_gray[k] == size)
202                         break;
203         }
204
205         if((k == M8XX_SIZES_NO) || (m8xx_size_to_gray[k] == -1))
206                 k = -1;
207
208         return k;
209 }
210
211 #if     0
212
213 #if     defined(CONFIG_RPXCLASSIC) || defined(CONFIG_RPXLITE)
214
215 /* The RPX boards seems to have it's bus monitor timeout set to 6*8 clocks.
216  * SYPCR is write once only, therefore must the slowest memory be faster
217  * than the bus monitor or we will get a machine check due to the bus timeout.
218  */
219 #undef  PCMCIA_BMT_LIMIT
220 #define PCMCIA_BMT_LIMIT (6*8)
221 #endif
222
223 static u_int m8xx_get_speed(u_int ns, u_int is_io)
224 {
225         u_int reg, clocks, psst, psl, psht;
226
227         if(!ns) {
228
229                 /*
230                 * We get called with IO maps setup to 0ns
231                 * if not specified by the user.
232                 * They should be 255ns.
233                 */
234
235                 if(is_io)
236                         ns = 255;
237                 else
238                         ns = 100;  /* fast memory if 0 */
239         }
240
241         /*
242         * In PSST, PSL, PSHT fields we tell the controller
243         * timing parameters in CLKOUT clock cycles.
244         * CLKOUT is the same as GCLK2_50.
245         */
246
247         /* how we want to adjust the timing - in percent */
248
249 #define ADJ 180 /* 80 % longer accesstime - to be sure */
250
251         clocks = ((M8XX_BUSFREQ / 1000) * ns) / 1000;
252         clocks = (clocks * ADJ) / (100*1000);
253
254         if(clocks >= PCMCIA_BMT_LIMIT) {
255                 DEBUG(0, "Max access time limit reached\n");
256                 clocks = PCMCIA_BMT_LIMIT-1;
257         }
258
259         psst = clocks / 7;          /* setup time */
260         psht = clocks / 7;          /* hold time */
261         psl  = (clocks * 5) / 7;    /* strobe length */
262
263         psst += clocks - (psst + psht + psl);
264
265         reg =  psst << 12;
266         reg |= psl  << 7;
267         reg |= psht << 16;
268
269         return reg;
270 }
271 #endif  /* 0 */
272
273 #endif  /* CONFIG_PCMCIA */