blob: bfdcbda9fbeb4c3c15b11f94c0897a3eb844b48a [file] [log] [blame]
wdenkc6097192002-11-03 00:24:07 +00001/*
2 * (C) Copyright 2000-2002
3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
4 *
5 * See file CREDITS for list of people who contributed to this
6 * project.
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of
11 * the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21 * MA 02111-1307 USA
22 *
23 ********************************************************************
24 *
25 * Lots of code copied from:
26 *
27 * m8xx_pcmcia.c - Linux PCMCIA socket driver for the mpc8xx series.
28 * (C) 1999-2000 Magnus Damm <damm@bitsmart.com>
29 *
30 * "The ExCA standard specifies that socket controllers should provide
31 * two IO and five memory windows per socket, which can be independently
32 * configured and positioned in the host address space and mapped to
33 * arbitrary segments of card address space. " - David A Hinds. 1999
34 *
35 * This controller does _not_ meet the ExCA standard.
36 *
37 * m8xx pcmcia controller brief info:
38 * + 8 windows (attrib, mem, i/o)
39 * + up to two slots (SLOT_A and SLOT_B)
40 * + inputpins, outputpins, event and mask registers.
41 * - no offset register. sigh.
42 *
43 * Because of the lacking offset register we must map the whole card.
44 * We assign each memory window PCMCIA_MEM_WIN_SIZE address space.
45 * Make sure there is (PCMCIA_MEM_WIN_SIZE * PCMCIA_MEM_WIN_NO
46 * * PCMCIA_SOCKETS_NO) bytes at PCMCIA_MEM_WIN_BASE.
47 * The i/o windows are dynamically allocated at PCMCIA_IO_WIN_BASE.
48 * They are maximum 64KByte each...
49 */
50
51/* #define DEBUG 1 */
52
53/*
54 * PCMCIA support
55 */
56#include <common.h>
57#include <command.h>
58#include <config.h>
59#include <pcmcia.h>
wdenkc6097192002-11-03 00:24:07 +000060#if defined(CONFIG_IDE_8xx_PCCARD) && defined(CONFIG_8xx)
61#include <mpc8xx.h>
62#endif
63#if defined(CONFIG_LWMON)
64#include <i2c.h>
65#endif
66
67#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA) || \
68 ((CONFIG_COMMANDS & CFG_CMD_IDE) && defined(CONFIG_IDE_8xx_PCCARD))
69
70int pcmcia_on (void);
71
72#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
73static int pcmcia_off (void);
wdenke5d61c72003-05-18 11:30:09 +000074#endif
75
76#ifdef CONFIG_I82365
77
78extern int i82365_init (void);
79extern void i82365_exit (void);
80
81#else /* ! CONFIG_I82365 */
82
83#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
wdenkc6097192002-11-03 00:24:07 +000084static int hardware_disable(int slot);
85#endif
86static int hardware_enable (int slot);
87static int voltage_set(int slot, int vcc, int vpp);
wdenkc6097192002-11-03 00:24:07 +000088
wdenk0893c472003-05-20 14:25:27 +000089#ifndef CONFIG_I82365
wdenkc6097192002-11-03 00:24:07 +000090static u_int m8xx_get_graycode(u_int size);
wdenk0893c472003-05-20 14:25:27 +000091#endif /* CONFIG_I82365 */
wdenkc6097192002-11-03 00:24:07 +000092#if 0
93static u_int m8xx_get_speed(u_int ns, u_int is_io);
94#endif
95
wdenk90e7e422002-12-04 23:39:58 +000096/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +000097
98/* look up table for pgcrx registers */
99
100static u_int *pcmcia_pgcrx[2] = {
101 &((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_pgcra,
102 &((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_pgcrb,
103};
104
105#define PCMCIA_PGCRX(slot) (*pcmcia_pgcrx[slot])
106
wdenke5d61c72003-05-18 11:30:09 +0000107#endif /* CONFIG_I82365 */
108
109#ifdef CONFIG_IDE_8xx_PCCARD
110static void print_funcid (int func);
111static void print_fixed (volatile uchar *p);
112static int identify (volatile uchar *p);
113static int check_ide_device (int slot);
114#endif /* CONFIG_IDE_8xx_PCCARD */
115
wdenkc6097192002-11-03 00:24:07 +0000116const char *indent = "\t ";
117
wdenk90e7e422002-12-04 23:39:58 +0000118/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +0000119
120#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
121
122int do_pinit (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
123{
124 int rcode = 0;
125
126 if (argc != 2) {
127 printf ("Usage: pinit {on | off}\n");
128 return 1;
129 }
130 if (strcmp(argv[1],"on") == 0) {
131 rcode = pcmcia_on ();
132 } else if (strcmp(argv[1],"off") == 0) {
133 rcode = pcmcia_off ();
134 } else {
135 printf ("Usage: pinit {on | off}\n");
136 return 1;
137 }
138
139 return rcode;
140}
141#endif /* CFG_CMD_PCMCIA */
142
wdenk90e7e422002-12-04 23:39:58 +0000143/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +0000144
wdenke5d61c72003-05-18 11:30:09 +0000145#ifdef CONFIG_I82365
146int pcmcia_on (void)
147{
148 u_int rc;
149
150 debug ("Enable PCMCIA " PCMCIA_SLOT_MSG "\n");
151
152 rc = i82365_init();
153
154 if (rc == 0)
155 {
156 rc = check_ide_device(0);
157 }
158
159 return (rc);
160}
161#else
162
wdenkc6097192002-11-03 00:24:07 +0000163#if defined(CONFIG_LWMON)
164# define CFG_PCMCIA_TIMING (PCMCIA_SHT(9) | PCMCIA_SST(3) | PCMCIA_SL(12))
165#else
166# define CFG_PCMCIA_TIMING (PCMCIA_SHT(2) | PCMCIA_SST(4) | PCMCIA_SL(9))
167#endif
168
169int pcmcia_on (void)
170{
171 int i;
172 u_long reg, base;
173 pcmcia_win_t *win;
wdenk2029f4d2002-11-21 23:11:29 +0000174 u_int slotbit;
175 u_int rc, slot;
wdenkc6097192002-11-03 00:24:07 +0000176
177 debug ("Enable PCMCIA " PCMCIA_SLOT_MSG "\n");
178
179 /* intialize the fixed memory windows */
180 win = (pcmcia_win_t *)(&((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_pbr0);
181 base = CFG_PCMCIA_MEM_ADDR;
182
183 if((reg = m8xx_get_graycode(CFG_PCMCIA_MEM_SIZE)) == -1) {
184 printf ("Cannot set window size to 0x%08x\n",
185 CFG_PCMCIA_MEM_SIZE);
186 return (1);
187 }
188
wdenk2029f4d2002-11-21 23:11:29 +0000189 slotbit = PCMCIA_SLOT_x;
wdenkc6097192002-11-03 00:24:07 +0000190 for (i=0; i<PCMCIA_MEM_WIN_NO; ++i) {
191 win->br = base;
192
wdenk2029f4d2002-11-21 23:11:29 +0000193#if (PCMCIA_SOCKETS_NO == 2)
194 if (i == 4) /* Another slot starting from win 4 */
195 slotbit = (slotbit ? PCMCIA_PSLOT_A : PCMCIA_PSLOT_B);
196#endif
wdenkc6097192002-11-03 00:24:07 +0000197 switch (i) {
198#ifdef CONFIG_IDE_8xx_PCCARD
wdenk2029f4d2002-11-21 23:11:29 +0000199 case 4:
wdenkc6097192002-11-03 00:24:07 +0000200 case 0: { /* map attribute memory */
201 win->or = ( PCMCIA_BSIZE_64M
202 | PCMCIA_PPS_8
203 | PCMCIA_PRS_ATTR
wdenk2029f4d2002-11-21 23:11:29 +0000204 | slotbit
wdenkc6097192002-11-03 00:24:07 +0000205 | PCMCIA_PV
206 | CFG_PCMCIA_TIMING );
207 break;
208 }
wdenk2029f4d2002-11-21 23:11:29 +0000209 case 5:
wdenkc6097192002-11-03 00:24:07 +0000210 case 1: { /* map I/O window for data reg */
211 win->or = ( PCMCIA_BSIZE_1K
212 | PCMCIA_PPS_16
213 | PCMCIA_PRS_IO
wdenk2029f4d2002-11-21 23:11:29 +0000214 | slotbit
wdenkc6097192002-11-03 00:24:07 +0000215 | PCMCIA_PV
216 | CFG_PCMCIA_TIMING );
217 break;
218 }
wdenk2029f4d2002-11-21 23:11:29 +0000219 case 6:
wdenk90e7e422002-12-04 23:39:58 +0000220 case 2: { /* map I/O window for cmd/ctrl reg block */
wdenkc6097192002-11-03 00:24:07 +0000221 win->or = ( PCMCIA_BSIZE_1K
222 | PCMCIA_PPS_8
223 | PCMCIA_PRS_IO
wdenk2029f4d2002-11-21 23:11:29 +0000224 | slotbit
wdenkc6097192002-11-03 00:24:07 +0000225 | PCMCIA_PV
226 | CFG_PCMCIA_TIMING );
227 break;
228 }
229#endif /* CONFIG_IDE_8xx_PCCARD */
230 default: /* set to not valid */
231 win->or = 0;
232 break;
233 }
234
235 debug ("MemWin %d: PBR 0x%08lX POR %08lX\n",
236 i, win->br, win->or);
237 base += CFG_PCMCIA_MEM_SIZE;
238 ++win;
239 }
240
wdenk90e7e422002-12-04 23:39:58 +0000241 for (i=0, rc=0, slot=_slot_; i<PCMCIA_SOCKETS_NO; i++, slot = !slot) {
wdenk2029f4d2002-11-21 23:11:29 +0000242 /* turn off voltage */
243 if ((rc = voltage_set(slot, 0, 0)))
244 continue;
wdenk90e7e422002-12-04 23:39:58 +0000245
wdenk2029f4d2002-11-21 23:11:29 +0000246 /* Enable external hardware */
247 if ((rc = hardware_enable(slot)))
248 continue;
wdenk90e7e422002-12-04 23:39:58 +0000249
wdenkc6097192002-11-03 00:24:07 +0000250#ifdef CONFIG_IDE_8xx_PCCARD
wdenk2029f4d2002-11-21 23:11:29 +0000251 if ((rc = check_ide_device(i)))
252 continue;
wdenkc6097192002-11-03 00:24:07 +0000253#endif
wdenk2029f4d2002-11-21 23:11:29 +0000254 }
255 return (rc);
wdenkc6097192002-11-03 00:24:07 +0000256}
wdenke5d61c72003-05-18 11:30:09 +0000257#endif /* CONFIG_I82365 */
wdenkc6097192002-11-03 00:24:07 +0000258
wdenk90e7e422002-12-04 23:39:58 +0000259/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +0000260
261#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
262
wdenke5d61c72003-05-18 11:30:09 +0000263#ifdef CONFIG_I82365
264static int pcmcia_off (void)
265{
266 printf ("Disable PCMCIA " PCMCIA_SLOT_MSG "\n");
267
268 i82365_exit();
269
270 return 0;
271}
272#else
wdenkc6097192002-11-03 00:24:07 +0000273static int pcmcia_off (void)
274{
275 int i;
276 pcmcia_win_t *win;
277
278 printf ("Disable PCMCIA " PCMCIA_SLOT_MSG "\n");
279
280 /* clear interrupt state, and disable interrupts */
281 ((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_pscr = PCMCIA_MASK(_slot_);
282 ((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_per &= ~PCMCIA_MASK(_slot_);
283
284 /* turn off interrupt and disable CxOE */
285 PCMCIA_PGCRX(_slot_) = __MY_PCMCIA_GCRX_CXOE;
286
287 /* turn off memory windows */
288 win = (pcmcia_win_t *)(&((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_pbr0);
289
290 for (i=0; i<PCMCIA_MEM_WIN_NO; ++i) {
291 /* disable memory window */
292 win->or = 0;
293 ++win;
294 }
295
296 /* turn off voltage */
297 voltage_set(_slot_, 0, 0);
298
299 /* disable external hardware */
300 printf ("Shutdown and Poweroff " PCMCIA_SLOT_MSG "\n");
301 hardware_disable(_slot_);
302 return 0;
303}
wdenke5d61c72003-05-18 11:30:09 +0000304#endif /* CONFIG_I82365 */
wdenkc6097192002-11-03 00:24:07 +0000305
306#endif /* CFG_CMD_PCMCIA */
307
wdenk90e7e422002-12-04 23:39:58 +0000308/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +0000309
310#ifdef CONFIG_IDE_8xx_PCCARD
311
312#define MAX_TUPEL_SZ 512
313#define MAX_FEATURES 4
314
wdenk4fc95692003-02-28 00:49:47 +0000315int ide_devices_found;
wdenk2029f4d2002-11-21 23:11:29 +0000316static int check_ide_device (int slot)
wdenkc6097192002-11-03 00:24:07 +0000317{
318 volatile uchar *ident = NULL;
319 volatile uchar *feature_p[MAX_FEATURES];
wdenk2029f4d2002-11-21 23:11:29 +0000320 volatile uchar *p, *start, *addr;
wdenkc6097192002-11-03 00:24:07 +0000321 int n_features = 0;
322 uchar func_id = ~0;
323 uchar code, len;
324 ushort config_base = 0;
325 int found = 0;
326 int i;
327
wdenk90e7e422002-12-04 23:39:58 +0000328 addr = (volatile uchar *)(CFG_PCMCIA_MEM_ADDR +
329 CFG_PCMCIA_MEM_SIZE * (slot * 4));
wdenke7f34c62003-01-11 09:48:40 +0000330 debug ("PCMCIA MEM: %08lX\n", (ulong)addr);
wdenkc6097192002-11-03 00:24:07 +0000331
wdenk2029f4d2002-11-21 23:11:29 +0000332 start = p = (volatile uchar *) addr;
wdenkc6097192002-11-03 00:24:07 +0000333
334 while ((p - start) < MAX_TUPEL_SZ) {
335
336 code = *p; p += 2;
337
338 if (code == 0xFF) { /* End of chain */
339 break;
340 }
341
342 len = *p; p += 2;
343#if defined(DEBUG) && (DEBUG > 1)
344 { volatile uchar *q = p;
345 printf ("\nTuple code %02x length %d\n\tData:",
346 code, len);
347
348 for (i = 0; i < len; ++i) {
349 printf (" %02x", *q);
350 q+= 2;
351 }
352 }
353#endif /* DEBUG */
354 switch (code) {
355 case CISTPL_VERS_1:
356 ident = p + 4;
357 break;
358 case CISTPL_FUNCID:
359 /* Fix for broken SanDisk which may have 0x80 bit set */
360 func_id = *p & 0x7F;
361 break;
362 case CISTPL_FUNCE:
363 if (n_features < MAX_FEATURES)
364 feature_p[n_features++] = p;
365 break;
366 case CISTPL_CONFIG:
367 config_base = (*(p+6) << 8) + (*(p+4));
368 debug ("\n## Config_base = %04x ###\n", config_base);
369 default:
370 break;
371 }
372 p += 2 * len;
373 }
374
375 found = identify (ident);
376
377 if (func_id != ((uchar)~0)) {
378 print_funcid (func_id);
379
380 if (func_id == CISTPL_FUNCID_FIXED)
381 found = 1;
382 else
383 return (1); /* no disk drive */
384 }
385
386 for (i=0; i<n_features; ++i) {
387 print_fixed (feature_p[i]);
388 }
389
390 if (!found) {
391 printf ("unknown card type\n");
392 return (1);
393 }
394
wdenk4fc95692003-02-28 00:49:47 +0000395 ide_devices_found |= (1 << slot);
396
wdenkc6097192002-11-03 00:24:07 +0000397 /* set I/O area in config reg -> only valid for ARGOSY D5!!! */
wdenk2029f4d2002-11-21 23:11:29 +0000398 *((uchar *)(addr + config_base)) = 1;
wdenkc6097192002-11-03 00:24:07 +0000399
400 return (0);
401}
402#endif /* CONFIG_IDE_8xx_PCCARD */
403
wdenk90e7e422002-12-04 23:39:58 +0000404/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +0000405
406
wdenk90e7e422002-12-04 23:39:58 +0000407/* -------------------------------------------------------------------- */
408/* board specific stuff: */
409/* voltage_set(), hardware_enable() and hardware_disable() */
410/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +0000411
wdenk90e7e422002-12-04 23:39:58 +0000412/* -------------------------------------------------------------------- */
413/* RPX Boards from Embedded Planet */
414/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +0000415
416#if defined(CONFIG_RPXCLASSIC) || defined(CONFIG_RPXLITE)
417
418/* The RPX boards seems to have it's bus monitor timeout set to 6*8 clocks.
419 * SYPCR is write once only, therefore must the slowest memory be faster
420 * than the bus monitor or we will get a machine check due to the bus timeout.
421 */
422
423#define PCMCIA_BOARD_MSG "RPX CLASSIC or RPX LITE"
424
425#undef PCMCIA_BMT_LIMIT
426#define PCMCIA_BMT_LIMIT (6*8)
427
428static int voltage_set(int slot, int vcc, int vpp)
429{
430 u_long reg = 0;
431
432 switch(vcc) {
433 case 0: break;
434 case 33: reg |= BCSR1_PCVCTL4; break;
435 case 50: reg |= BCSR1_PCVCTL5; break;
436 default: return 1;
437 }
438
439 switch(vpp) {
440 case 0: break;
441 case 33:
442 case 50:
443 if(vcc == vpp)
444 reg |= BCSR1_PCVCTL6;
445 else
446 return 1;
447 break;
448 case 120:
449 reg |= BCSR1_PCVCTL7;
450 default: return 1;
451 }
452
453 if(vcc == 120)
454 return 1;
455
456 /* first, turn off all power */
457
458 *((uint *)RPX_CSR_ADDR) &= ~(BCSR1_PCVCTL4 | BCSR1_PCVCTL5
459 | BCSR1_PCVCTL6 | BCSR1_PCVCTL7);
460
461 /* enable new powersettings */
462
463 *((uint *)RPX_CSR_ADDR) |= reg;
464
465 return 0;
466}
467
468#define socket_get(_slot_) PCMCIA_SOCKET_KEY_5V
469static int hardware_enable (int slot)
470{
471 return 0; /* No hardware to enable */
472}
473#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
474static int hardware_disable(int slot)
475{
476 return 0; /* No hardware to disable */
477}
478#endif /* CFG_CMD_PCMCIA */
479#endif /* CONFIG_RPXCLASSIC */
480
wdenk90e7e422002-12-04 23:39:58 +0000481/* -------------------------------------------------------------------- */
482/* (F)ADS Boards from Motorola */
483/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +0000484
485#if defined(CONFIG_ADS) || defined(CONFIG_FADS)
486
487#ifdef CONFIG_ADS
488#define PCMCIA_BOARD_MSG "ADS"
489#define PCMCIA_GLITCHY_CD /* My ADS board needs this */
490#else
491#define PCMCIA_BOARD_MSG "FADS"
492#endif
493
494static int voltage_set(int slot, int vcc, int vpp)
495{
496 u_long reg = 0;
497
498 switch(vpp) {
499 case 0: reg = 0; break;
500 case 50: reg = 1; break;
501 case 120: reg = 2; break;
502 default: return 1;
503 }
504
505 switch(vcc) {
506 case 0: reg = 0; break;
507#ifdef CONFIG_ADS
508 case 50: reg = BCSR1_PCCVCCON; break;
509#endif
510#ifdef CONFIG_FADS
511 case 33: reg = BCSR1_PCCVCC0 | BCSR1_PCCVCC1; break;
512 case 50: reg = BCSR1_PCCVCC1; break;
513#endif
514 default: return 1;
515 }
516
517 /* first, turn off all power */
518
519#ifdef CONFIG_ADS
520 *((uint *)BCSR1) |= BCSR1_PCCVCCON;
521#endif
522#ifdef CONFIG_FADS
523 *((uint *)BCSR1) &= ~(BCSR1_PCCVCC0 | BCSR1_PCCVCC1);
524#endif
525 *((uint *)BCSR1) &= ~BCSR1_PCCVPP_MASK;
526
527 /* enable new powersettings */
528
529#ifdef CONFIG_ADS
530 *((uint *)BCSR1) &= ~reg;
531#endif
532#ifdef CONFIG_FADS
533 *((uint *)BCSR1) |= reg;
534#endif
535
536 *((uint *)BCSR1) |= reg << 20;
537
538 return 0;
539}
540
541#define socket_get(_slot_) PCMCIA_SOCKET_KEY_5V
542
543static int hardware_enable(int slot)
544{
545 *((uint *)BCSR1) &= ~BCSR1_PCCEN;
546 return 0;
547}
548
549#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
550static int hardware_disable(int slot)
551{
552 *((uint *)BCSR1) &= ~BCSR1_PCCEN;
553 return 0;
554}
555#endif /* CFG_CMD_PCMCIA */
556
557#endif /* (F)ADS */
558
wdenk90e7e422002-12-04 23:39:58 +0000559/* -------------------------------------------------------------------- */
560/* TQM8xxL Boards by TQ Components */
wdenkc8434db2003-03-26 06:55:25 +0000561/* SC8xx Boards by SinoVee Microsystems */
wdenk90e7e422002-12-04 23:39:58 +0000562/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +0000563
wdenkc8434db2003-03-26 06:55:25 +0000564#if defined(CONFIG_TQM8xxL) || defined(CONFIG_SVM_SC8xx)
wdenkc6097192002-11-03 00:24:07 +0000565
wdenkc8434db2003-03-26 06:55:25 +0000566#if defined(CONFIG_TQM8xxL)
wdenkc6097192002-11-03 00:24:07 +0000567#define PCMCIA_BOARD_MSG "TQM8xxL"
wdenkc8434db2003-03-26 06:55:25 +0000568#endif
569#if defined(CONFIG_SVM_SC8xx)
570#define PCMCIA_BOARD_MSG "SC8xx"
571#endif
wdenkc6097192002-11-03 00:24:07 +0000572
573static int hardware_enable(int slot)
574{
575 volatile immap_t *immap;
576 volatile cpm8xx_t *cp;
577 volatile pcmconf8xx_t *pcmp;
578 volatile sysconf8xx_t *sysp;
579 uint reg, mask;
580
581 debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
582
583 udelay(10000);
584
585 immap = (immap_t *)CFG_IMMR;
586 sysp = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
587 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
588 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
589
590 /*
591 * Configure SIUMCR to enable PCMCIA port B
592 * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
593 */
594 sysp->sc_siumcr &= ~SIUMCR_DBGC11; /* set DBGC to 00 */
595
596 /* clear interrupt state, and disable interrupts */
597 pcmp->pcmc_pscr = PCMCIA_MASK(_slot_);
598 pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
599
wdenkc6097192002-11-03 00:24:07 +0000600 /*
wdenk90e7e422002-12-04 23:39:58 +0000601 * Disable interrupts, DMA, and PCMCIA buffers
602 * (isolate the interface) and assert RESET signal
wdenkc6097192002-11-03 00:24:07 +0000603 */
604 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk90e7e422002-12-04 23:39:58 +0000605 reg = 0;
606 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
607 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkc6097192002-11-03 00:24:07 +0000608 PCMCIA_PGCRX(_slot_) = reg;
609 udelay(500);
610
611 /*
612 * Configure Port C pins for
613 * 5 Volts Enable and 3 Volts enable
614 */
615 immap->im_ioport.iop_pcpar &= ~(0x0002 | 0x0004);
616 immap->im_ioport.iop_pcso &= ~(0x0002 | 0x0004);
617 /* remove all power */
618
619 immap->im_ioport.iop_pcdat &= ~(0x0002 | 0x0004);
620
621 /*
622 * Make sure there is a card in the slot, then configure the interface.
623 */
624 udelay(10000);
625 debug ("[%d] %s: PIPR(%p)=0x%x\n",
626 __LINE__,__FUNCTION__,
627 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
wdenk2029f4d2002-11-21 23:11:29 +0000628 if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
wdenkc6097192002-11-03 00:24:07 +0000629 printf (" No Card found\n");
630 return (1);
631 }
632
633 /*
634 * Power On.
635 */
636 mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
637 reg = pcmp->pcmc_pipr;
638 debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
639 reg,
640 (reg&PCMCIA_VS1(slot))?"n":"ff",
641 (reg&PCMCIA_VS2(slot))?"n":"ff");
642 if ((reg & mask) == mask) {
643 immap->im_ioport.iop_pcdat |= 0x0004;
644 puts (" 5.0V card found: ");
645 } else {
646 immap->im_ioport.iop_pcdat |= 0x0002;
647 puts (" 3.3V card found: ");
648 }
wdenk90e7e422002-12-04 23:39:58 +0000649 immap->im_ioport.iop_pcdir |= (0x0002 | 0x0004);
wdenkc6097192002-11-03 00:24:07 +0000650#if 0
651 /* VCC switch error flag, PCMCIA slot INPACK_ pin */
652 cp->cp_pbdir &= ~(0x0020 | 0x0010);
653 cp->cp_pbpar &= ~(0x0020 | 0x0010);
654 udelay(500000);
655#endif
656 udelay(1000);
657 debug ("Enable PCMCIA buffers and stop RESET\n");
658 reg = PCMCIA_PGCRX(_slot_);
659 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
660 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
661 PCMCIA_PGCRX(_slot_) = reg;
662
663 udelay(250000); /* some cards need >150 ms to come up :-( */
664
665 debug ("# hardware_enable done\n");
666
667 return (0);
668}
669
670
wdenkc6097192002-11-03 00:24:07 +0000671#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
672static int hardware_disable(int slot)
673{
674 volatile immap_t *immap;
675 volatile pcmconf8xx_t *pcmp;
676 u_long reg;
677
678 debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
679
680 immap = (immap_t *)CFG_IMMR;
681 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
682
683 /* remove all power */
684 immap->im_ioport.iop_pcdat &= ~(0x0002 | 0x0004);
685
wdenkc6097192002-11-03 00:24:07 +0000686 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk90e7e422002-12-04 23:39:58 +0000687 reg = 0;
wdenkc6097192002-11-03 00:24:07 +0000688 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
689 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
690 PCMCIA_PGCRX(_slot_) = reg;
691
692 udelay(10000);
693
694 return (0);
695}
696#endif /* CFG_CMD_PCMCIA */
697
698
wdenkc6097192002-11-03 00:24:07 +0000699static int voltage_set(int slot, int vcc, int vpp)
700{
701 volatile immap_t *immap;
702 volatile pcmconf8xx_t *pcmp;
703 u_long reg;
704
705 debug ("voltage_set: "
706 PCMCIA_BOARD_MSG
707 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
708 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
709
710 immap = (immap_t *)CFG_IMMR;
711 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
712 /*
713 * Disable PCMCIA buffers (isolate the interface)
714 * and assert RESET signal
715 */
716 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk90e7e422002-12-04 23:39:58 +0000717 reg = PCMCIA_PGCRX(_slot_);
718 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
719 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkc6097192002-11-03 00:24:07 +0000720 PCMCIA_PGCRX(_slot_) = reg;
721 udelay(500);
722
723 /*
724 * Configure Port C pins for
725 * 5 Volts Enable and 3 Volts enable,
726 * Turn off all power
727 */
728 debug ("PCMCIA power OFF\n");
729 immap->im_ioport.iop_pcpar &= ~(0x0002 | 0x0004);
730 immap->im_ioport.iop_pcso &= ~(0x0002 | 0x0004);
731 immap->im_ioport.iop_pcdat &= ~(0x0002 | 0x0004);
732
733 reg = 0;
734 switch(vcc) {
735 case 0: break;
736 case 33: reg |= 0x0002; break;
737 case 50: reg |= 0x0004; break;
738 default: goto done;
739 }
740
741 /* Checking supported voltages */
742
743 debug ("PIPR: 0x%x --> %s\n",
744 pcmp->pcmc_pipr,
745 (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
746
747 immap->im_ioport.iop_pcdat |= reg;
wdenk90e7e422002-12-04 23:39:58 +0000748 immap->im_ioport.iop_pcdir |= (0x0002 | 0x0004);
wdenkc6097192002-11-03 00:24:07 +0000749 if (reg) {
750 debug ("PCMCIA powered at %sV\n",
751 (reg&0x0004) ? "5.0" : "3.3");
752 } else {
753 debug ("PCMCIA powered down\n");
754 }
755
756done:
757 debug ("Enable PCMCIA buffers and stop RESET\n");
758 reg = PCMCIA_PGCRX(_slot_);
759 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
760 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
761 PCMCIA_PGCRX(_slot_) = reg;
762 udelay(500);
763
764 debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
765 slot+'A');
766 return (0);
767}
768
769#endif /* TQM8xxL */
770
771
wdenk90e7e422002-12-04 23:39:58 +0000772/* -------------------------------------------------------------------- */
773/* LWMON Board */
774/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +0000775
776#if defined(CONFIG_LWMON)
777
778#define PCMCIA_BOARD_MSG "LWMON"
779
780/* #define's for MAX1604 Power Switch */
781#define MAX1604_OP_SUS 0x80
782#define MAX1604_VCCBON 0x40
783#define MAX1604_VCC_35 0x20
784#define MAX1604_VCCBHIZ 0x10
785#define MAX1604_VPPBON 0x08
786#define MAX1604_VPPBPBPGM 0x04
787#define MAX1604_VPPBHIZ 0x02
788/* reserved 0x01 */
789
790static int hardware_enable(int slot)
791{
792 volatile immap_t *immap;
793 volatile cpm8xx_t *cp;
794 volatile pcmconf8xx_t *pcmp;
795 volatile sysconf8xx_t *sysp;
796 uint reg, mask;
797 uchar val;
798
799
800 debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
801
802 /* Switch on PCMCIA port in PIC register 0x60 */
803 reg = pic_read (0x60);
804 debug ("[%d] PIC read: reg_60 = 0x%02x\n", __LINE__, reg);
805 reg &= ~0x10;
wdenk90e7e422002-12-04 23:39:58 +0000806 /* reg |= 0x08; Vpp not needed */
wdenkc6097192002-11-03 00:24:07 +0000807 pic_write (0x60, reg);
808#ifdef DEBUG
809 reg = pic_read (0x60);
810 printf ("[%d] PIC read: reg_60 = 0x%02x\n", __LINE__, reg);
811#endif
812 udelay(10000);
813
814 immap = (immap_t *)CFG_IMMR;
815 sysp = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
816 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
817 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
818
819 /*
820 * Configure SIUMCR to enable PCMCIA port B
821 * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
822 */
823 sysp->sc_siumcr &= ~SIUMCR_DBGC11; /* set DBGC to 00 */
824
825 /* clear interrupt state, and disable interrupts */
826 pcmp->pcmc_pscr = PCMCIA_MASK(_slot_);
827 pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
828
wdenkc6097192002-11-03 00:24:07 +0000829 /*
wdenk90e7e422002-12-04 23:39:58 +0000830 * Disable interrupts, DMA, and PCMCIA buffers
831 * (isolate the interface) and assert RESET signal
wdenkc6097192002-11-03 00:24:07 +0000832 */
833 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk90e7e422002-12-04 23:39:58 +0000834 reg = 0;
835 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
836 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkc6097192002-11-03 00:24:07 +0000837 PCMCIA_PGCRX(_slot_) = reg;
838 udelay(500);
839
840 /*
841 * Make sure there is a card in the slot, then configure the interface.
842 */
843 udelay(10000);
844 debug ("[%d] %s: PIPR(%p)=0x%x\n",
845 __LINE__,__FUNCTION__,
846 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
wdenk2029f4d2002-11-21 23:11:29 +0000847 if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
wdenkc6097192002-11-03 00:24:07 +0000848 printf (" No Card found\n");
849 return (1);
850 }
851
852 /*
853 * Power On.
854 */
855 mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
856 reg = pcmp->pcmc_pipr;
857 debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
858 reg,
859 (reg&PCMCIA_VS1(slot))?"n":"ff",
860 (reg&PCMCIA_VS2(slot))?"n":"ff");
861 if ((reg & mask) == mask) {
862 val = 0; /* VCCB3/5 = 0 ==> use Vx = 5.0 V */
863 puts (" 5.0V card found: ");
864 } else {
865 val = MAX1604_VCC_35; /* VCCB3/5 = 1 ==> use Vy = 3.3 V */
866 puts (" 3.3V card found: ");
867 }
868
869 /* switch VCC on */
wdenk90e7e422002-12-04 23:39:58 +0000870 val |= MAX1604_OP_SUS | MAX1604_VCCBON;
wdenkc6097192002-11-03 00:24:07 +0000871 i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE);
872 i2c_write (CFG_I2C_POWER_A_ADDR, 0, 0, &val, 1);
873
874 udelay(500000);
875
876 debug ("Enable PCMCIA buffers and stop RESET\n");
877 reg = PCMCIA_PGCRX(_slot_);
878 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
879 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
880 PCMCIA_PGCRX(_slot_) = reg;
881
882 udelay(250000); /* some cards need >150 ms to come up :-( */
883
884 debug ("# hardware_enable done\n");
885
886 return (0);
887}
888
889
wdenkc6097192002-11-03 00:24:07 +0000890#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
891static int hardware_disable(int slot)
892{
893 volatile immap_t *immap;
894 volatile pcmconf8xx_t *pcmp;
895 u_long reg;
896 uchar val;
897
898 debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
899
900 immap = (immap_t *)CFG_IMMR;
901 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
902
903 /* remove all power, put output in high impedance state */
904 val = MAX1604_VCCBHIZ | MAX1604_VPPBHIZ;
905 i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE);
906 i2c_write (CFG_I2C_POWER_A_ADDR, 0, 0, &val, 1);
907
908 /* Configure PCMCIA General Control Register */
wdenkc6097192002-11-03 00:24:07 +0000909 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk90e7e422002-12-04 23:39:58 +0000910 reg = 0;
wdenkc6097192002-11-03 00:24:07 +0000911 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
912 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
913 PCMCIA_PGCRX(_slot_) = reg;
914
915 /* Switch off PCMCIA port in PIC register 0x60 */
916 reg = pic_read (0x60);
917 debug ("[%d] PIC read: reg_60 = 0x%02x\n", __LINE__, reg);
918 reg |= 0x10;
919 reg &= ~0x08;
920 pic_write (0x60, reg);
921#ifdef DEBUG
922 reg = pic_read (0x60);
923 printf ("[%d] PIC read: reg_60 = 0x%02x\n", __LINE__, reg);
924#endif
925 udelay(10000);
926
927 return (0);
928}
929#endif /* CFG_CMD_PCMCIA */
930
931
wdenkc6097192002-11-03 00:24:07 +0000932static int voltage_set(int slot, int vcc, int vpp)
933{
934 volatile immap_t *immap;
935 volatile pcmconf8xx_t *pcmp;
936 u_long reg;
937 uchar val;
938
939 debug ("voltage_set: "
940 PCMCIA_BOARD_MSG
941 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
942 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
943
944 immap = (immap_t *)CFG_IMMR;
945 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
946 /*
947 * Disable PCMCIA buffers (isolate the interface)
948 * and assert RESET signal
949 */
950 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk90e7e422002-12-04 23:39:58 +0000951 reg = PCMCIA_PGCRX(_slot_);
952 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
953 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkc6097192002-11-03 00:24:07 +0000954 PCMCIA_PGCRX(_slot_) = reg;
955 udelay(500);
956
957 /*
958 * Turn off all power (switch to high impedance)
959 */
960 debug ("PCMCIA power OFF\n");
961 val = MAX1604_VCCBHIZ | MAX1604_VPPBHIZ;
962 i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE);
963 i2c_write (CFG_I2C_POWER_A_ADDR, 0, 0, &val, 1);
964
965 val = 0;
966 switch(vcc) {
967 case 0: break;
968 case 33: val = MAX1604_VCC_35; break;
969 case 50: break;
970 default: goto done;
971 }
972
973 /* Checking supported voltages */
974
975 debug ("PIPR: 0x%x --> %s\n",
976 pcmp->pcmc_pipr,
977 (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
978
979 i2c_write (CFG_I2C_POWER_A_ADDR, 0, 0, &val, 1);
980 if (val) {
981 debug ("PCMCIA powered at %sV\n",
982 (val & MAX1604_VCC_35) ? "3.3" : "5.0");
983 } else {
984 debug ("PCMCIA powered down\n");
985 }
986
987done:
988 debug ("Enable PCMCIA buffers and stop RESET\n");
989 reg = PCMCIA_PGCRX(_slot_);
990 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
991 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
992 PCMCIA_PGCRX(_slot_) = reg;
993 udelay(500);
994
995 debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
996 slot+'A');
997 return (0);
998}
999
1000#endif /* LWMON */
1001
wdenk90e7e422002-12-04 23:39:58 +00001002/* -------------------------------------------------------------------- */
1003/* GTH board by Corelatus AB */
1004/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00001005#if defined(CONFIG_GTH)
1006
1007#define PCMCIA_BOARD_MSG "GTH COMPACT FLASH"
1008
wdenk90e7e422002-12-04 23:39:58 +00001009static int voltage_set (int slot, int vcc, int vpp)
1010{ /* Do nothing */
1011 return 0;
wdenkc6097192002-11-03 00:24:07 +00001012}
1013
1014static int hardware_enable (int slot)
1015{
wdenk90e7e422002-12-04 23:39:58 +00001016 volatile immap_t *immap;
1017 volatile cpm8xx_t *cp;
1018 volatile pcmconf8xx_t *pcmp;
1019 volatile sysconf8xx_t *sysp;
1020 uint reg, mask;
wdenkc6097192002-11-03 00:24:07 +00001021
wdenk90e7e422002-12-04 23:39:58 +00001022 debug ("hardware_enable: GTH Slot %c\n", 'A' + slot);
wdenkc6097192002-11-03 00:24:07 +00001023
wdenk90e7e422002-12-04 23:39:58 +00001024 immap = (immap_t *) CFG_IMMR;
1025 sysp = (sysconf8xx_t *) (&(((immap_t *) CFG_IMMR)->im_siu_conf));
1026 pcmp = (pcmconf8xx_t *) (&(((immap_t *) CFG_IMMR)->im_pcmcia));
1027 cp = (cpm8xx_t *) (&(((immap_t *) CFG_IMMR)->im_cpm));
wdenkc6097192002-11-03 00:24:07 +00001028
wdenk90e7e422002-12-04 23:39:58 +00001029 /* clear interrupt state, and disable interrupts */
1030 pcmp->pcmc_pscr = PCMCIA_MASK (_slot_);
1031 pcmp->pcmc_per &= ~PCMCIA_MASK (_slot_);
wdenkc6097192002-11-03 00:24:07 +00001032
wdenk90e7e422002-12-04 23:39:58 +00001033 /*
1034 * Disable interrupts, DMA, and PCMCIA buffers
1035 * (isolate the interface) and assert RESET signal
1036 */
1037 debug ("Disable PCMCIA buffers and assert RESET\n");
1038 reg = 0;
1039 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1040 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
1041 PCMCIA_PGCRX (_slot_) = reg;
1042 udelay (500);
wdenkc6097192002-11-03 00:24:07 +00001043
wdenk90e7e422002-12-04 23:39:58 +00001044 /*
1045 * Make sure there is a card in the slot,
1046 * then configure the interface.
1047 */
1048 udelay (10000);
1049 debug ("[%d] %s: PIPR(%p)=0x%x\n",
1050 __LINE__, __FUNCTION__,
1051 &(pcmp->pcmc_pipr), pcmp->pcmc_pipr);
1052 if (pcmp->pcmc_pipr & 0x98000000) {
1053 printf (" No Card found\n");
1054 return (1);
1055 }
wdenkc6097192002-11-03 00:24:07 +00001056
wdenk90e7e422002-12-04 23:39:58 +00001057 mask = PCMCIA_VS1 (slot) | PCMCIA_VS2 (slot);
1058 reg = pcmp->pcmc_pipr;
1059 debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
1060 reg,
1061 (reg & PCMCIA_VS1 (slot)) ? "n" : "ff",
1062 (reg & PCMCIA_VS2 (slot)) ? "n" : "ff");
wdenkc6097192002-11-03 00:24:07 +00001063
wdenk90e7e422002-12-04 23:39:58 +00001064 debug ("Enable PCMCIA buffers and stop RESET\n");
1065 reg = PCMCIA_PGCRX (_slot_);
1066 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
1067 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
1068 PCMCIA_PGCRX (_slot_) = reg;
wdenkc6097192002-11-03 00:24:07 +00001069
wdenk90e7e422002-12-04 23:39:58 +00001070 udelay (250000); /* some cards need >150 ms to come up :-( */
wdenkc6097192002-11-03 00:24:07 +00001071
wdenk90e7e422002-12-04 23:39:58 +00001072 debug ("# hardware_enable done\n");
wdenkc6097192002-11-03 00:24:07 +00001073
wdenk90e7e422002-12-04 23:39:58 +00001074 return 0;
wdenkc6097192002-11-03 00:24:07 +00001075}
1076#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
1077static int hardware_disable(int slot)
1078{
1079 return 0; /* No hardware to disable */
1080}
1081#endif /* CFG_CMD_PCMCIA */
1082#endif /* CONFIG_GTH */
1083
wdenk90e7e422002-12-04 23:39:58 +00001084/* -------------------------------------------------------------------- */
1085/* ICU862 Boards by Cambridge Broadband Ltd. */
1086/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00001087
1088#if defined(CONFIG_ICU862)
1089
1090#define PCMCIA_BOARD_MSG "ICU862"
1091
1092static void cfg_port_B (void);
1093
1094static int hardware_enable(int slot)
1095{
1096 volatile immap_t *immap;
1097 volatile cpm8xx_t *cp;
1098 volatile pcmconf8xx_t *pcmp;
1099 volatile sysconf8xx_t *sysp;
1100 uint reg, pipr, mask;
1101 int i;
1102
1103 debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1104
1105 udelay(10000);
1106
1107 immap = (immap_t *)CFG_IMMR;
1108 sysp = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
1109 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1110 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1111
1112 /* Configure Port B for TPS2205 PC-Card Power-Interface Switch */
1113 cfg_port_B ();
1114
1115 /*
1116 * Configure SIUMCR to enable PCMCIA port B
1117 * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
1118 */
1119 sysp->sc_siumcr &= ~SIUMCR_DBGC11; /* set DBGC to 00 */
1120
1121 /* clear interrupt state, and disable interrupts */
1122 pcmp->pcmc_pscr = PCMCIA_MASK(_slot_);
1123 pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
1124
wdenkc6097192002-11-03 00:24:07 +00001125 /*
wdenk90e7e422002-12-04 23:39:58 +00001126 * Disable interrupts, DMA, and PCMCIA buffers
1127 * (isolate the interface) and assert RESET signal
wdenkc6097192002-11-03 00:24:07 +00001128 */
1129 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk90e7e422002-12-04 23:39:58 +00001130 reg = 0;
1131 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1132 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkc6097192002-11-03 00:24:07 +00001133 PCMCIA_PGCRX(_slot_) = reg;
1134 udelay(500);
1135
1136 /*
1137 * Make sure there is a card in the slot, then configure the interface.
1138 */
1139 udelay(10000);
1140 debug ("[%d] %s: PIPR(%p)=0x%x\n",
1141 __LINE__,__FUNCTION__,
1142 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
wdenk2029f4d2002-11-21 23:11:29 +00001143 if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
wdenkc6097192002-11-03 00:24:07 +00001144 printf (" No Card found\n");
1145 return (1);
1146 }
1147
1148 /*
1149 * Power On: Set VAVCC to 3.3V or 5V, set VAVPP to Hi-Z
1150 */
1151 mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
1152 pipr = pcmp->pcmc_pipr;
1153 debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
1154 pipr,
1155 (reg&PCMCIA_VS1(slot))?"n":"ff",
1156 (reg&PCMCIA_VS2(slot))?"n":"ff");
1157
1158 reg = cp->cp_pbdat;
1159 if ((pipr & mask) == mask) {
wdenk90e7e422002-12-04 23:39:58 +00001160 reg |= (TPS2205_VPP_PGM | TPS2205_VPP_VCC | /* VAVPP => Hi-Z */
1161 TPS2205_VCC3); /* 3V off */
wdenkc6097192002-11-03 00:24:07 +00001162 reg &= ~(TPS2205_VCC5); /* 5V on */
1163 puts (" 5.0V card found: ");
1164 } else {
wdenk90e7e422002-12-04 23:39:58 +00001165 reg |= (TPS2205_VPP_PGM | TPS2205_VPP_VCC | /* VAVPP => Hi-Z */
1166 TPS2205_VCC5); /* 5V off */
wdenkc6097192002-11-03 00:24:07 +00001167 reg &= ~(TPS2205_VCC3); /* 3V on */
1168 puts (" 3.3V card found: ");
1169 }
1170
1171 debug ("\nPB DAT: %08x -> 3.3V %s 5.0V %s VPP_PGM %s VPP_VCC %s\n",
1172 reg,
1173 (reg & TPS2205_VCC3) ? "off" : "on",
1174 (reg & TPS2205_VCC5) ? "off" : "on",
1175 (reg & TPS2205_VPP_PGM) ? "off" : "on",
1176 (reg & TPS2205_VPP_VCC) ? "off" : "on" );
1177
1178 cp->cp_pbdat = reg;
1179
1180 /* Wait 500 ms; use this to check for over-current */
1181 for (i=0; i<5000; ++i) {
1182 if ((cp->cp_pbdat & TPS2205_OC) == 0) {
1183 printf (" *** Overcurrent - Safety shutdown ***\n");
1184 cp->cp_pbdat &= ~(TPS2205_SHDN);
1185 return (1);
1186 }
1187 udelay (100);
1188 }
1189
1190 debug ("Enable PCMCIA buffers and stop RESET\n");
1191 reg = PCMCIA_PGCRX(_slot_);
1192 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
1193 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
1194 PCMCIA_PGCRX(_slot_) = reg;
1195
1196 udelay(250000); /* some cards need >150 ms to come up :-( */
1197
1198 debug ("# hardware_enable done\n");
1199
1200 return (0);
1201}
1202
1203
wdenkc6097192002-11-03 00:24:07 +00001204#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
1205static int hardware_disable(int slot)
1206{
1207 volatile immap_t *immap;
1208 volatile cpm8xx_t *cp;
1209 volatile pcmconf8xx_t *pcmp;
1210 u_long reg;
1211
1212 debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1213
1214 immap = (immap_t *)CFG_IMMR;
1215 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1216 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1217
1218 /* Shut down */
1219 cp->cp_pbdat &= ~(TPS2205_SHDN);
1220
1221 /* Configure PCMCIA General Control Register */
wdenkc6097192002-11-03 00:24:07 +00001222 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk90e7e422002-12-04 23:39:58 +00001223 reg = 0;
wdenkc6097192002-11-03 00:24:07 +00001224 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1225 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
1226 PCMCIA_PGCRX(_slot_) = reg;
1227
1228 udelay(10000);
1229
1230 return (0);
1231}
1232#endif /* CFG_CMD_PCMCIA */
1233
1234
wdenkc6097192002-11-03 00:24:07 +00001235static int voltage_set(int slot, int vcc, int vpp)
1236{
1237 volatile immap_t *immap;
1238 volatile cpm8xx_t *cp;
1239 volatile pcmconf8xx_t *pcmp;
1240 u_long reg;
1241
1242 debug ("voltage_set: "
1243 PCMCIA_BOARD_MSG
1244 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
1245 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
1246
1247 immap = (immap_t *)CFG_IMMR;
1248 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1249 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1250 /*
1251 * Disable PCMCIA buffers (isolate the interface)
1252 * and assert RESET signal
1253 */
1254 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk90e7e422002-12-04 23:39:58 +00001255 reg = PCMCIA_PGCRX(_slot_);
1256 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1257 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkc6097192002-11-03 00:24:07 +00001258 PCMCIA_PGCRX(_slot_) = reg;
1259 udelay(500);
1260
1261 /*
1262 * Configure Port C pins for
1263 * 5 Volts Enable and 3 Volts enable,
1264 * Turn all power pins to Hi-Z
1265 */
1266 debug ("PCMCIA power OFF\n");
1267 cfg_port_B (); /* Enables switch, but all in Hi-Z */
1268
1269 reg = cp->cp_pbdat;
1270
1271 switch(vcc) {
1272 case 0: break; /* Switch off */
1273 case 33: reg &= ~TPS2205_VCC3; break; /* Switch on 3.3V */
1274 case 50: reg &= ~TPS2205_VCC5; break; /* Switch on 5.0V */
1275 default: goto done;
1276 }
1277
1278 /* Checking supported voltages */
1279
1280 debug ("PIPR: 0x%x --> %s\n",
1281 pcmp->pcmc_pipr,
1282 (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
1283
1284 cp->cp_pbdat = reg;
1285
1286#ifdef DEBUG
1287 {
1288 char *s;
1289
1290 if ((reg & TPS2205_VCC3) == 0) {
1291 s = "at 3.3V";
1292 } else if ((reg & TPS2205_VCC5) == 0) {
1293 s = "at 5.0V";
1294 } else {
1295 s = "down";
1296 }
1297 printf ("PCMCIA powered %s\n", s);
1298 }
1299#endif
1300
1301done:
1302 debug ("Enable PCMCIA buffers and stop RESET\n");
1303 reg = PCMCIA_PGCRX(_slot_);
1304 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
1305 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
1306 PCMCIA_PGCRX(_slot_) = reg;
1307 udelay(500);
1308
1309 debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
1310 slot+'A');
1311 return (0);
1312}
1313
1314static void cfg_port_B (void)
1315{
1316 volatile immap_t *immap;
1317 volatile cpm8xx_t *cp;
1318 uint reg;
1319
1320 immap = (immap_t *)CFG_IMMR;
1321 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1322
1323 /*
1324 * Configure Port B for TPS2205 PC-Card Power-Interface Switch
1325 *
1326 * Switch off all voltages, assert shutdown
1327 */
1328 reg = cp->cp_pbdat;
wdenk90e7e422002-12-04 23:39:58 +00001329 reg |= (TPS2205_VPP_PGM | TPS2205_VPP_VCC | /* VAVPP => Hi-Z */
1330 TPS2205_VCC3 | TPS2205_VCC5 | /* VAVCC => Hi-Z */
1331 TPS2205_SHDN); /* enable switch */
wdenkc6097192002-11-03 00:24:07 +00001332 cp->cp_pbdat = reg;
1333
1334 cp->cp_pbpar &= ~(TPS2205_INPUTS | TPS2205_OUTPUTS);
1335
1336 reg = cp->cp_pbdir & ~(TPS2205_INPUTS);
1337 cp->cp_pbdir = reg | TPS2205_OUTPUTS;
1338
1339 debug ("Set Port B: PAR: %08x DIR: %08x DAT: %08x\n",
1340 cp->cp_pbpar, cp->cp_pbdir, cp->cp_pbdat);
1341}
1342
1343#endif /* ICU862 */
1344
1345
wdenk90e7e422002-12-04 23:39:58 +00001346/* -------------------------------------------------------------------- */
1347/* C2MON Boards by TTTech Computertechnik AG */
1348/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00001349
1350#if defined(CONFIG_C2MON)
1351
1352#define PCMCIA_BOARD_MSG "C2MON"
1353
1354static void cfg_ports (void);
1355
1356static int hardware_enable(int slot)
1357{
1358 volatile immap_t *immap;
1359 volatile cpm8xx_t *cp;
1360 volatile pcmconf8xx_t *pcmp;
1361 volatile sysconf8xx_t *sysp;
1362 uint reg, pipr, mask;
1363 ushort sreg;
1364 int i;
1365
1366 debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1367
1368 udelay(10000);
1369
1370 immap = (immap_t *)CFG_IMMR;
1371 sysp = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
1372 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1373 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1374
1375 /* Configure Ports for TPS2211A PC-Card Power-Interface Switch */
1376 cfg_ports ();
1377
1378 /*
1379 * Configure SIUMCR to enable PCMCIA port B
1380 * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
1381 */
1382 sysp->sc_siumcr &= ~SIUMCR_DBGC11; /* set DBGC to 00 */
1383
1384 /* clear interrupt state, and disable interrupts */
1385 pcmp->pcmc_pscr = PCMCIA_MASK(_slot_);
1386 pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
1387
wdenkc6097192002-11-03 00:24:07 +00001388 /*
wdenk90e7e422002-12-04 23:39:58 +00001389 * Disable interrupts, DMA, and PCMCIA buffers
1390 * (isolate the interface) and assert RESET signal
wdenkc6097192002-11-03 00:24:07 +00001391 */
1392 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk90e7e422002-12-04 23:39:58 +00001393 reg = 0;
1394 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1395 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkc6097192002-11-03 00:24:07 +00001396 PCMCIA_PGCRX(_slot_) = reg;
1397 udelay(500);
1398
1399 /*
1400 * Make sure there is a card in the slot, then configure the interface.
1401 */
1402 udelay(10000);
1403 debug ("[%d] %s: PIPR(%p)=0x%x\n",
1404 __LINE__,__FUNCTION__,
1405 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
wdenk2029f4d2002-11-21 23:11:29 +00001406 if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
wdenkc6097192002-11-03 00:24:07 +00001407 printf (" No Card found\n");
1408 return (1);
1409 }
1410
1411 /*
1412 * Power On: Set VAVCC to 3.3V or 5V, set VAVPP to Hi-Z
1413 */
1414 mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
1415 pipr = pcmp->pcmc_pipr;
1416 debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
1417 pipr,
1418 (reg&PCMCIA_VS1(slot))?"n":"ff",
1419 (reg&PCMCIA_VS2(slot))?"n":"ff");
1420
1421 sreg = immap->im_ioport.iop_pcdat;
1422 if ((pipr & mask) == mask) {
1423 sreg |= (TPS2211_VPPD0 | TPS2211_VPPD1 | /* VAVPP => Hi-Z */
1424 TPS2211_VCCD1); /* 5V on */
1425 sreg &= ~(TPS2211_VCCD0); /* 3V off */
1426 puts (" 5.0V card found: ");
1427 } else {
1428 sreg |= (TPS2211_VPPD0 | TPS2211_VPPD1 | /* VAVPP => Hi-Z */
1429 TPS2211_VCCD0); /* 3V on */
1430 sreg &= ~(TPS2211_VCCD1); /* 5V off */
1431 puts (" 3.3V card found: ");
1432 }
1433
1434 debug ("\nPC DAT: %04x -> 3.3V %s 5.0V %s\n",
1435 sreg,
1436 ( (sreg & TPS2211_VCCD0) && !(sreg & TPS2211_VCCD1)) ? "on" : "off",
1437 (!(sreg & TPS2211_VCCD0) && (sreg & TPS2211_VCCD1)) ? "on" : "off"
1438 );
1439
1440 immap->im_ioport.iop_pcdat = sreg;
1441
1442 /* Wait 500 ms; use this to check for over-current */
1443 for (i=0; i<5000; ++i) {
1444 if ((cp->cp_pbdat & TPS2211_OC) == 0) {
1445 printf (" *** Overcurrent - Safety shutdown ***\n");
1446 immap->im_ioport.iop_pcdat &= ~(TPS2211_VCCD0|TPS2211_VCCD1);
1447 return (1);
1448 }
1449 udelay (100);
1450 }
1451
1452 debug ("Enable PCMCIA buffers and stop RESET\n");
1453 reg = PCMCIA_PGCRX(_slot_);
1454 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
1455 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
1456 PCMCIA_PGCRX(_slot_) = reg;
1457
1458 udelay(250000); /* some cards need >150 ms to come up :-( */
1459
1460 debug ("# hardware_enable done\n");
1461
1462 return (0);
1463}
1464
1465
wdenkc6097192002-11-03 00:24:07 +00001466#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
1467static int hardware_disable(int slot)
1468{
1469 volatile immap_t *immap;
1470 volatile cpm8xx_t *cp;
1471 volatile pcmconf8xx_t *pcmp;
1472 u_long reg;
1473
1474 debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1475
1476 immap = (immap_t *)CFG_IMMR;
1477 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1478
1479 /* Configure PCMCIA General Control Register */
wdenkc6097192002-11-03 00:24:07 +00001480 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk90e7e422002-12-04 23:39:58 +00001481 reg = 0;
wdenkc6097192002-11-03 00:24:07 +00001482 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1483 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
1484 PCMCIA_PGCRX(_slot_) = reg;
1485
1486 /* ALl voltages off / Hi-Z */
1487 immap->im_ioport.iop_pcdat |= (TPS2211_VPPD0 | TPS2211_VPPD1 |
1488 TPS2211_VCCD0 | TPS2211_VCCD1 );
1489
1490 udelay(10000);
1491
1492 return (0);
1493}
1494#endif /* CFG_CMD_PCMCIA */
1495
1496
wdenkc6097192002-11-03 00:24:07 +00001497static int voltage_set(int slot, int vcc, int vpp)
1498{
1499 volatile immap_t *immap;
1500 volatile cpm8xx_t *cp;
1501 volatile pcmconf8xx_t *pcmp;
1502 u_long reg;
1503 ushort sreg;
1504
1505 debug ("voltage_set: "
1506 PCMCIA_BOARD_MSG
1507 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
1508 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
1509
1510 immap = (immap_t *)CFG_IMMR;
1511 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1512 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1513 /*
1514 * Disable PCMCIA buffers (isolate the interface)
1515 * and assert RESET signal
1516 */
1517 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk90e7e422002-12-04 23:39:58 +00001518 reg = PCMCIA_PGCRX(_slot_);
1519 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1520 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkc6097192002-11-03 00:24:07 +00001521 PCMCIA_PGCRX(_slot_) = reg;
1522 udelay(500);
1523
1524 /*
1525 * Configure Port C pins for
1526 * 5 Volts Enable and 3 Volts enable,
1527 * Turn all power pins to Hi-Z
1528 */
1529 debug ("PCMCIA power OFF\n");
1530 cfg_ports (); /* Enables switch, but all in Hi-Z */
1531
1532 sreg = immap->im_ioport.iop_pcdat;
1533 sreg |= TPS2211_VPPD0 | TPS2211_VPPD1; /* VAVPP always Hi-Z */
1534
1535 switch(vcc) {
1536 case 0: break; /* Switch off */
1537 case 33: sreg |= TPS2211_VCCD0; /* Switch on 3.3V */
1538 sreg &= ~TPS2211_VCCD1;
1539 break;
1540 case 50: sreg &= ~TPS2211_VCCD0; /* Switch on 5.0V */
1541 sreg |= TPS2211_VCCD1;
1542 break;
1543 default: goto done;
1544 }
1545
1546 /* Checking supported voltages */
1547
1548 debug ("PIPR: 0x%x --> %s\n",
1549 pcmp->pcmc_pipr,
1550 (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
1551
1552 immap->im_ioport.iop_pcdat = sreg;
1553
1554#ifdef DEBUG
1555 {
1556 char *s;
1557
1558 if ((sreg & TPS2211_VCCD0) && !(sreg & TPS2211_VCCD1)) {
1559 s = "at 3.3V";
1560 } else if (!(sreg & TPS2211_VCCD0) && (sreg & TPS2211_VCCD1)) {
1561 s = "at 5.0V";
1562 } else {
1563 s = "down";
1564 }
1565 printf ("PCMCIA powered %s\n", s);
1566 }
1567#endif
1568
1569done:
1570 debug ("Enable PCMCIA buffers and stop RESET\n");
1571 reg = PCMCIA_PGCRX(_slot_);
1572 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
1573 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
1574 PCMCIA_PGCRX(_slot_) = reg;
1575 udelay(500);
1576
1577 debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
1578 slot+'A');
1579 return (0);
1580}
1581
1582static void cfg_ports (void)
1583{
1584 volatile immap_t *immap;
1585 volatile cpm8xx_t *cp;
1586 ushort sreg;
1587
1588 immap = (immap_t *)CFG_IMMR;
1589 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1590
1591 /*
1592 * Configure Port C for TPS2211 PC-Card Power-Interface Switch
1593 *
1594 * Switch off all voltages, assert shutdown
1595 */
1596 sreg = immap->im_ioport.iop_pcdat;
1597 sreg |= (TPS2211_VPPD0 | TPS2211_VPPD1); /* VAVPP => Hi-Z */
1598 sreg &= ~(TPS2211_VCCD0 | TPS2211_VCCD1); /* 3V and 5V off */
1599 immap->im_ioport.iop_pcdat = sreg;
1600
1601 immap->im_ioport.iop_pcpar &= ~(TPS2211_OUTPUTS);
1602 immap->im_ioport.iop_pcdir |= TPS2211_OUTPUTS;
1603
1604 debug ("Set Port C: PAR: %04x DIR: %04x DAT: %04x\n",
1605 immap->im_ioport.iop_pcpar,
1606 immap->im_ioport.iop_pcdir,
1607 immap->im_ioport.iop_pcdat);
1608
1609 /*
1610 * Configure Port B for TPS2211 PC-Card Power-Interface Switch
1611 *
1612 * Over-Current Input only
1613 */
1614 cp->cp_pbpar &= ~(TPS2211_INPUTS);
1615 cp->cp_pbdir &= ~(TPS2211_INPUTS);
1616
1617 debug ("Set Port B: PAR: %08x DIR: %08x DAT: %08x\n",
1618 cp->cp_pbpar, cp->cp_pbdir, cp->cp_pbdat);
1619}
1620
1621#endif /* C2MON */
1622
wdenk90e7e422002-12-04 23:39:58 +00001623/* -------------------------------------------------------------------- */
1624/* MBX board from Morotola */
1625/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00001626
1627#if defined( CONFIG_MBX )
1628#include <../board/mbx8xx/csr.h>
1629
1630/* A lot of this has been taken from the RPX code in this file it works from me.
1631 I have added the voltage selection for the MBX board. */
1632
1633/* MBX voltage bit in control register #2 */
1634#define CR2_VPP12 ((uchar)0x10)
1635#define CR2_VPPVDD ((uchar)0x20)
1636#define CR2_VDD5 ((uchar)0x40)
1637#define CR2_VDD3 ((uchar)0x80)
1638
1639#define PCMCIA_BOARD_MSG "MBX860"
1640
1641static int voltage_set (int slot, int vcc, int vpp)
1642{
1643 uchar reg = 0;
1644
1645 debug ("voltage_set: PCMCIA_BOARD_MSG Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
1646 'A' + slot, vcc / 10, vcc % 10, vpp / 10, vcc % 10);
1647
1648 switch (vcc) {
1649 case 0:
1650 break;
1651 case 33:
1652 reg |= CR2_VDD3;
1653 break;
1654 case 50:
1655 reg |= CR2_VDD5;
1656 break;
1657 default:
1658 return 1;
1659 }
1660
1661 switch (vpp) {
1662 case 0:
1663 break;
1664 case 33:
1665 case 50:
1666 if (vcc == vpp) {
1667 reg |= CR2_VPPVDD;
1668 } else {
1669 return 1;
1670 }
1671 break;
1672 case 120:
1673 reg |= CR2_VPP12;
1674 break;
1675 default:
1676 return 1;
1677 }
1678
1679 /* first, turn off all power */
1680 MBX_CSR2 &= ~(CR2_VDDSEL | CR2_VPPSEL);
1681
1682 /* enable new powersettings */
1683 MBX_CSR2 |= reg;
1684 debug ("MBX_CSR2 read = 0x%02x\n", MBX_CSR2);
1685
1686 return (0);
1687}
1688
1689static int hardware_enable (int slot)
1690{
1691 volatile immap_t *immap;
1692 volatile cpm8xx_t *cp;
1693 volatile pcmconf8xx_t *pcmp;
1694 volatile sysconf8xx_t *sysp;
1695 uint reg, mask;
1696
1697 debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n",
1698 'A' + slot);
1699
1700 udelay (10000);
1701
1702 immap = (immap_t *) CFG_IMMR;
1703 sysp = (sysconf8xx_t *) (&(((immap_t *) CFG_IMMR)->im_siu_conf));
1704 pcmp = (pcmconf8xx_t *) (&(((immap_t *) CFG_IMMR)->im_pcmcia));
1705 cp = (cpm8xx_t *) (&(((immap_t *) CFG_IMMR)->im_cpm));
1706
1707 /* clear interrupt state, and disable interrupts */
1708 pcmp->pcmc_pscr = PCMCIA_MASK (_slot_);
1709 pcmp->pcmc_per &= ~PCMCIA_MASK (_slot_);
1710
wdenkc6097192002-11-03 00:24:07 +00001711 /*
wdenk90e7e422002-12-04 23:39:58 +00001712 * Disable interrupts, DMA, and PCMCIA buffers
1713 * (isolate the interface) and assert RESET signal
wdenkc6097192002-11-03 00:24:07 +00001714 */
1715 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk90e7e422002-12-04 23:39:58 +00001716 reg = 0;
wdenkc6097192002-11-03 00:24:07 +00001717 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1718 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
1719 PCMCIA_PGCRX (_slot_) = reg;
1720 udelay (500);
1721
1722 /* remove all power */
1723 voltage_set (slot, 0, 0);
1724 /*
1725 * Make sure there is a card in the slot, then configure the interface.
1726 */
wdenk2029f4d2002-11-21 23:11:29 +00001727 udelay(10000);
1728 debug ("[%d] %s: PIPR(%p)=0x%x\n",
1729 __LINE__,__FUNCTION__,
1730 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
1731 if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
wdenkc6097192002-11-03 00:24:07 +00001732 printf (" No Card found\n");
1733 return (1);
1734 }
1735
1736 /*
1737 * Power On.
1738 */
1739 mask = PCMCIA_VS1 (_slot_) | PCMCIA_VS2 (_slot_);
1740 reg = pcmp->pcmc_pipr;
1741 debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n", reg,
1742 (reg & PCMCIA_VS1 (slot)) ? "n" : "ff",
1743 (reg & PCMCIA_VS2 (slot)) ? "n" : "ff");
1744
1745 if ((reg & mask) == mask) {
1746 voltage_set (_slot_, 50, 0);
1747 printf (" 5.0V card found: ");
1748 } else {
1749 voltage_set (_slot_, 33, 0);
1750 printf (" 3.3V card found: ");
1751 }
1752
1753 debug ("Enable PCMCIA buffers and stop RESET\n");
1754 reg = PCMCIA_PGCRX (_slot_);
1755 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
1756 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
1757 PCMCIA_PGCRX (_slot_) = reg;
1758
1759 udelay (250000); /* some cards need >150 ms to come up :-( */
1760
1761 debug ("# hardware_enable done\n");
1762
1763 return (0);
1764}
1765
1766#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
1767static int hardware_disable (int slot)
1768{
1769 return 0; /* No hardware to disable */
1770}
1771#endif /* CFG_CMD_PCMCIA */
1772#endif /* CONFIG_MBX */
wdenk90e7e422002-12-04 23:39:58 +00001773/* -------------------------------------------------------------------- */
1774/* R360MPI Board */
1775/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00001776
1777#if defined(CONFIG_R360MPI)
1778
1779#define PCMCIA_BOARD_MSG "R360MPI"
1780
1781
1782static int hardware_enable(int slot)
1783{
1784 volatile immap_t *immap;
1785 volatile cpm8xx_t *cp;
1786 volatile pcmconf8xx_t *pcmp;
1787 volatile sysconf8xx_t *sysp;
1788 uint reg, mask;
1789
1790 debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1791
1792 udelay(10000);
1793
1794 immap = (immap_t *)CFG_IMMR;
1795 sysp = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
1796 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1797 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1798
1799 /*
1800 * Configure SIUMCR to enable PCMCIA port B
1801 * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
1802 */
1803 sysp->sc_siumcr &= ~SIUMCR_DBGC11; /* set DBGC to 00 */
1804
1805 /* clear interrupt state, and disable interrupts */
1806 pcmp->pcmc_pscr = PCMCIA_MASK(_slot_);
1807 pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
1808
wdenkc6097192002-11-03 00:24:07 +00001809 /*
wdenk90e7e422002-12-04 23:39:58 +00001810 * Disable interrupts, DMA, and PCMCIA buffers
1811 * (isolate the interface) and assert RESET signal
wdenkc6097192002-11-03 00:24:07 +00001812 */
1813 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk90e7e422002-12-04 23:39:58 +00001814 reg = 0;
1815 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1816 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkc6097192002-11-03 00:24:07 +00001817 PCMCIA_PGCRX(_slot_) = reg;
1818 udelay(500);
1819
1820 /*
1821 * Configure Ports A, B & C pins for
1822 * 5 Volts Enable and 3 Volts enable
1823 */
1824 immap->im_ioport.iop_pcpar &= ~(0x0400);
1825 immap->im_ioport.iop_pcso &= ~(0x0400);/*
1826 immap->im_ioport.iop_pcdir |= 0x0400;*/
1827
1828 immap->im_ioport.iop_papar &= ~(0x0200);/*
1829 immap->im_ioport.iop_padir |= 0x0200;*/
1830#if 0
1831 immap->im_ioport.iop_pbpar &= ~(0xC000);
1832 immap->im_ioport.iop_pbdir &= ~(0xC000);
1833#endif
1834 /* remove all power */
1835
1836 immap->im_ioport.iop_pcdat |= 0x0400;
1837 immap->im_ioport.iop_padat |= 0x0200;
1838
1839 /*
1840 * Make sure there is a card in the slot, then configure the interface.
1841 */
1842 udelay(10000);
1843 debug ("[%d] %s: PIPR(%p)=0x%x\n",
1844 __LINE__,__FUNCTION__,
1845 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
wdenk2029f4d2002-11-21 23:11:29 +00001846 if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
wdenkc6097192002-11-03 00:24:07 +00001847 printf (" No Card found\n");
1848 return (1);
1849 }
1850
1851 /*
1852 * Power On.
1853 */
1854 mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
1855 reg = pcmp->pcmc_pipr;
1856 debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
1857 reg,
1858 (reg&PCMCIA_VS1(slot))?"n":"ff",
1859 (reg&PCMCIA_VS2(slot))?"n":"ff");
1860 if ((reg & mask) == mask) {
1861 immap->im_ioport.iop_pcdat &= ~(0x4000);
1862 puts (" 5.0V card found: ");
1863 } else {
1864 immap->im_ioport.iop_padat &= ~(0x0002);
1865 puts (" 3.3V card found: ");
1866 }
1867 immap->im_ioport.iop_pcdir |= 0x0400;
1868 immap->im_ioport.iop_padir |= 0x0200;
1869#if 0
1870 /* VCC switch error flag, PCMCIA slot INPACK_ pin */
1871 cp->cp_pbdir &= ~(0x0020 | 0x0010);
1872 cp->cp_pbpar &= ~(0x0020 | 0x0010);
1873 udelay(500000);
1874#endif
1875 debug ("Enable PCMCIA buffers and stop RESET\n");
1876 reg = PCMCIA_PGCRX(_slot_);
1877 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
1878 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
1879 PCMCIA_PGCRX(_slot_) = reg;
1880
1881 udelay(250000); /* some cards need >150 ms to come up :-( */
1882
1883 debug ("# hardware_enable done\n");
1884
1885 return (0);
1886}
1887
1888
wdenkc6097192002-11-03 00:24:07 +00001889#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
1890static int hardware_disable(int slot)
1891{
1892 volatile immap_t *immap;
1893 volatile pcmconf8xx_t *pcmp;
1894 u_long reg;
1895
1896 debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1897
1898 immap = (immap_t *)CFG_IMMR;
1899 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1900
1901 /* remove all power */
1902 immap->im_ioport.iop_pcdat |= 0x0400;
1903 immap->im_ioport.iop_padat |= 0x0200;
1904
1905 /* Configure PCMCIA General Control Register */
wdenkc6097192002-11-03 00:24:07 +00001906 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk90e7e422002-12-04 23:39:58 +00001907 reg = 0;
wdenkc6097192002-11-03 00:24:07 +00001908 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1909 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
1910 PCMCIA_PGCRX(_slot_) = reg;
1911
1912 udelay(10000);
1913
1914 return (0);
1915}
1916#endif /* CFG_CMD_PCMCIA */
1917
1918
wdenkc6097192002-11-03 00:24:07 +00001919static int voltage_set(int slot, int vcc, int vpp)
1920{
1921 volatile immap_t *immap;
1922 volatile pcmconf8xx_t *pcmp;
1923 u_long reg;
1924
1925 debug ("voltage_set: "
1926 PCMCIA_BOARD_MSG
1927 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
1928 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
1929
1930 immap = (immap_t *)CFG_IMMR;
1931 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1932 /*
1933 * Disable PCMCIA buffers (isolate the interface)
1934 * and assert RESET signal
1935 */
1936 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk90e7e422002-12-04 23:39:58 +00001937 reg = PCMCIA_PGCRX(_slot_);
1938 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1939 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkc6097192002-11-03 00:24:07 +00001940 PCMCIA_PGCRX(_slot_) = reg;
1941 udelay(500);
1942
1943 /*
1944 * Configure Ports A & C pins for
1945 * 5 Volts Enable and 3 Volts enable,
1946 * Turn off all power
1947 */
1948 debug ("PCMCIA power OFF\n");
1949 immap->im_ioport.iop_pcpar &= ~(0x0400);
1950 immap->im_ioport.iop_pcso &= ~(0x0400);/*
1951 immap->im_ioport.iop_pcdir |= 0x0400;*/
1952
1953 immap->im_ioport.iop_papar &= ~(0x0200);/*
1954 immap->im_ioport.iop_padir |= 0x0200;*/
1955
1956 immap->im_ioport.iop_pcdat |= 0x0400;
1957 immap->im_ioport.iop_padat |= 0x0200;
1958
1959 reg = 0;
1960 switch(vcc) {
1961 case 0: break;
1962 case 33: reg |= 0x0200; break;
1963 case 50: reg |= 0x0400; break;
1964 default: goto done;
1965 }
1966
1967 /* Checking supported voltages */
1968
1969 debug ("PIPR: 0x%x --> %s\n",
1970 pcmp->pcmc_pipr,
1971 (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
1972
1973 if (reg & 0x0200)
1974 immap->im_ioport.iop_pcdat &= !reg;
1975 if (reg & 0x0400)
1976 immap->im_ioport.iop_padat &= !reg;
wdenk90e7e422002-12-04 23:39:58 +00001977 immap->im_ioport.iop_pcdir |= 0x0200;
1978 immap->im_ioport.iop_padir |= 0x0400;
wdenkc6097192002-11-03 00:24:07 +00001979 if (reg) {
1980 debug ("PCMCIA powered at %sV\n",
1981 (reg&0x0400) ? "5.0" : "3.3");
1982 } else {
1983 debug ("PCMCIA powered down\n");
1984 }
1985
1986done:
1987 debug ("Enable PCMCIA buffers and stop RESET\n");
1988 reg = PCMCIA_PGCRX(_slot_);
1989 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
1990 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
1991 PCMCIA_PGCRX(_slot_) = reg;
1992 udelay(500);
1993
1994 debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
1995 slot+'A');
1996 return (0);
1997}
1998
1999#endif /* R360MPI */
2000
wdenk90e7e422002-12-04 23:39:58 +00002001/* -------------------------------------------------------------------- */
2002/* KUP4K Board */
2003/* -------------------------------------------------------------------- */
wdenk56f94be2002-11-05 16:35:14 +00002004#if defined(CONFIG_KUP4K)
2005
2006#define PCMCIA_BOARD_MSG "KUP4K"
2007
2008#define KUP4K_PCMCIA_B_3V3 (0x00020000)
2009
2010static int hardware_enable(int slot)
2011{
2012 volatile immap_t *immap;
2013 volatile cpm8xx_t *cp;
2014 volatile pcmconf8xx_t *pcmp;
2015 volatile sysconf8xx_t *sysp;
2016 uint reg, mask;
2017
2018 debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
2019
2020 udelay(10000);
2021
2022 immap = (immap_t *)CFG_IMMR;
2023 sysp = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
2024 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
2025 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
2026
2027 /*
2028 * Configure SIUMCR to enable PCMCIA port B
2029 * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
2030 */
2031 sysp->sc_siumcr &= ~SIUMCR_DBGC11; /* set DBGC to 00 */
2032
2033 /* clear interrupt state, and disable interrupts */
wdenk2029f4d2002-11-21 23:11:29 +00002034 pcmp->pcmc_pscr = PCMCIA_MASK(slot);
2035 pcmp->pcmc_per &= ~PCMCIA_MASK(slot);
wdenk56f94be2002-11-05 16:35:14 +00002036
wdenk56f94be2002-11-05 16:35:14 +00002037 /*
wdenk90e7e422002-12-04 23:39:58 +00002038 * Disable interrupts, DMA, and PCMCIA buffers
2039 * (isolate the interface) and assert RESET signal
wdenk56f94be2002-11-05 16:35:14 +00002040 */
2041 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk90e7e422002-12-04 23:39:58 +00002042 reg = 0;
2043 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
2044 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenk2029f4d2002-11-21 23:11:29 +00002045 PCMCIA_PGCRX(slot) = reg;
2046 udelay(2500);
wdenk56f94be2002-11-05 16:35:14 +00002047
2048 /*
2049 * Configure Port B pins for
2050 * 3 Volts enable
2051 */
wdenk2029f4d2002-11-21 23:11:29 +00002052 if (slot) { /* Slot A is built-in */
2053 cp->cp_pbdir |= KUP4K_PCMCIA_B_3V3;
2054 cp->cp_pbpar &= ~KUP4K_PCMCIA_B_3V3;
2055 /* remove all power */
2056 cp->cp_pbdat |= KUP4K_PCMCIA_B_3V3; /* active low */
2057 }
wdenk56f94be2002-11-05 16:35:14 +00002058 /*
2059 * Make sure there is a card in the slot, then configure the interface.
2060 */
2061 udelay(10000);
2062 debug ("[%d] %s: PIPR(%p)=0x%x\n",
2063 __LINE__,__FUNCTION__,
2064 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
wdenk2029f4d2002-11-21 23:11:29 +00002065 if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
wdenk56f94be2002-11-05 16:35:14 +00002066 printf (" No Card found\n");
2067 return (1);
2068 }
2069
2070 /*
2071 * Power On.
2072 */
wdenk9dd2b882002-12-03 21:28:10 +00002073 printf("%s Slot %c:", slot ? "" : "\n", 'A' + slot);
wdenk56f94be2002-11-05 16:35:14 +00002074 mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
2075 reg = pcmp->pcmc_pipr;
2076 debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
2077 reg,
2078 (reg&PCMCIA_VS1(slot))?"n":"ff",
2079 (reg&PCMCIA_VS2(slot))?"n":"ff");
2080 if ((reg & mask) == mask) {
2081 puts (" 5.0V card found: NOT SUPPORTED !!!\n");
2082 } else {
wdenk2029f4d2002-11-21 23:11:29 +00002083 if(slot)
2084 cp->cp_pbdat &= ~KUP4K_PCMCIA_B_3V3;
wdenk56f94be2002-11-05 16:35:14 +00002085 puts (" 3.3V card found: ");
2086 }
2087#if 0
2088 /* VCC switch error flag, PCMCIA slot INPACK_ pin */
2089 cp->cp_pbdir &= ~(0x0020 | 0x0010);
2090 cp->cp_pbpar &= ~(0x0020 | 0x0010);
2091 udelay(500000);
2092#endif
2093 debug ("Enable PCMCIA buffers and stop RESET\n");
wdenk2029f4d2002-11-21 23:11:29 +00002094 reg = PCMCIA_PGCRX(slot);
wdenk56f94be2002-11-05 16:35:14 +00002095 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
2096 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
wdenk2029f4d2002-11-21 23:11:29 +00002097 PCMCIA_PGCRX(slot) = reg;
wdenk56f94be2002-11-05 16:35:14 +00002098
2099 udelay(250000); /* some cards need >150 ms to come up :-( */
2100
2101 debug ("# hardware_enable done\n");
2102
2103 return (0);
2104}
2105
2106
wdenk56f94be2002-11-05 16:35:14 +00002107#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
2108static int hardware_disable(int slot)
2109{
2110 volatile immap_t *immap;
2111 volatile cpm8xx_t *cp;
2112 volatile pcmconf8xx_t *pcmp;
2113 u_long reg;
2114
2115 debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
2116
2117 immap = (immap_t *)CFG_IMMR;
2118 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
2119 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
wdenk90e7e422002-12-04 23:39:58 +00002120
wdenk56f94be2002-11-05 16:35:14 +00002121 /* remove all power */
wdenk2029f4d2002-11-21 23:11:29 +00002122 if (slot)
2123 cp->cp_pbdat |= KUP4K_PCMCIA_B_3V3;
wdenk56f94be2002-11-05 16:35:14 +00002124
2125 /* Configure PCMCIA General Control Register */
wdenk56f94be2002-11-05 16:35:14 +00002126 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk90e7e422002-12-04 23:39:58 +00002127 reg = 0;
wdenk56f94be2002-11-05 16:35:14 +00002128 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
2129 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenk2029f4d2002-11-21 23:11:29 +00002130 PCMCIA_PGCRX(slot) = reg;
wdenk56f94be2002-11-05 16:35:14 +00002131
2132 udelay(10000);
2133
2134 return (0);
2135}
2136#endif /* CFG_CMD_PCMCIA */
2137
2138
wdenk56f94be2002-11-05 16:35:14 +00002139static int voltage_set(int slot, int vcc, int vpp)
2140{
2141 volatile immap_t *immap;
2142 volatile cpm8xx_t *cp;
2143 volatile pcmconf8xx_t *pcmp;
2144 u_long reg;
2145
2146 debug ("voltage_set: " \
2147 PCMCIA_BOARD_MSG \
2148 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
2149 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
2150
wdenk2029f4d2002-11-21 23:11:29 +00002151 if (!slot) /* Slot A is not configurable */
2152 return 0;
2153
wdenk56f94be2002-11-05 16:35:14 +00002154 immap = (immap_t *)CFG_IMMR;
2155 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
2156 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
2157
2158 /*
2159 * Disable PCMCIA buffers (isolate the interface)
2160 * and assert RESET signal
2161 */
2162 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk90e7e422002-12-04 23:39:58 +00002163 reg = PCMCIA_PGCRX(slot);
2164 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
2165 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenk2029f4d2002-11-21 23:11:29 +00002166 PCMCIA_PGCRX(slot) = reg;
wdenk56f94be2002-11-05 16:35:14 +00002167 udelay(500);
2168
2169 debug ("PCMCIA power OFF\n");
2170 /*
2171 * Configure Port B pins for
2172 * 3 Volts enable
2173 */
2174 cp->cp_pbdir |= KUP4K_PCMCIA_B_3V3;
2175 cp->cp_pbpar &= ~KUP4K_PCMCIA_B_3V3;
2176 /* remove all power */
2177 cp->cp_pbdat |= KUP4K_PCMCIA_B_3V3; /* active low */
2178
2179 switch(vcc) {
2180 case 0: break;
2181 case 33:
2182 cp->cp_pbdat &= ~KUP4K_PCMCIA_B_3V3;
2183 debug ("PCMCIA powered at 3.3V\n");
2184 break;
2185 case 50:
2186 debug ("PCMCIA: 5Volt vcc not supported\n");
2187 break;
2188 default:
2189 puts("PCMCIA: vcc not supported");
2190 break;
2191 }
wdenk2029f4d2002-11-21 23:11:29 +00002192 udelay(10000);
wdenk56f94be2002-11-05 16:35:14 +00002193 /* Checking supported voltages */
2194
2195 debug ("PIPR: 0x%x --> %s\n",
2196 pcmp->pcmc_pipr,
wdenk2029f4d2002-11-21 23:11:29 +00002197 (pcmp->pcmc_pipr & (0x80000000 >> (slot << 4)))
wdenk56f94be2002-11-05 16:35:14 +00002198 ? "only 5 V --> NOT SUPPORTED"
2199 : "can do 3.3V");
2200
2201
2202 debug ("Enable PCMCIA buffers and stop RESET\n");
wdenk2029f4d2002-11-21 23:11:29 +00002203 reg = PCMCIA_PGCRX(slot);
wdenk56f94be2002-11-05 16:35:14 +00002204 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
2205 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
wdenk2029f4d2002-11-21 23:11:29 +00002206 PCMCIA_PGCRX(slot) = reg;
wdenk56f94be2002-11-05 16:35:14 +00002207 udelay(500);
2208
2209 debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
2210 slot+'A');
2211 return (0);
2212}
2213
2214#endif /* KUP4K */
2215
2216
wdenk90e7e422002-12-04 23:39:58 +00002217/* -------------------------------------------------------------------- */
2218/* End of Board Specific Stuff */
2219/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00002220
2221
wdenk90e7e422002-12-04 23:39:58 +00002222/* -------------------------------------------------------------------- */
2223/* MPC8xx Specific Stuff - should go to MPC8xx directory */
2224/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00002225
2226/*
2227 * Search this table to see if the windowsize is
2228 * supported...
2229 */
2230
2231#define M8XX_SIZES_NO 32
2232
2233static const u_int m8xx_size_to_gray[M8XX_SIZES_NO] =
2234{ 0x00000001, 0x00000002, 0x00000008, 0x00000004,
2235 0x00000080, 0x00000040, 0x00000010, 0x00000020,
2236 0x00008000, 0x00004000, 0x00001000, 0x00002000,
2237 0x00000100, 0x00000200, 0x00000800, 0x00000400,
2238
2239 0x0fffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2240 0x01000000, 0x02000000, 0xffffffff, 0x04000000,
2241 0x00010000, 0x00020000, 0x00080000, 0x00040000,
2242 0x00800000, 0x00400000, 0x00100000, 0x00200000 };
2243
2244
wdenk90e7e422002-12-04 23:39:58 +00002245/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00002246
wdenk0893c472003-05-20 14:25:27 +00002247#ifndef CONFIG_I82365
2248
wdenkc6097192002-11-03 00:24:07 +00002249static u_int m8xx_get_graycode(u_int size)
2250{
2251 u_int k;
2252
2253 for (k = 0; k < M8XX_SIZES_NO; k++) {
2254 if(m8xx_size_to_gray[k] == size)
2255 break;
2256 }
2257
2258 if((k == M8XX_SIZES_NO) || (m8xx_size_to_gray[k] == -1))
2259 k = -1;
2260
2261 return k;
2262}
2263
wdenk0893c472003-05-20 14:25:27 +00002264#endif /* CONFIG_I82365 */
2265
wdenk90e7e422002-12-04 23:39:58 +00002266/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00002267
2268#if 0
2269static u_int m8xx_get_speed(u_int ns, u_int is_io)
2270{
2271 u_int reg, clocks, psst, psl, psht;
2272
2273 if(!ns) {
2274
2275 /*
2276 * We get called with IO maps setup to 0ns
2277 * if not specified by the user.
2278 * They should be 255ns.
2279 */
2280
2281 if(is_io)
2282 ns = 255;
2283 else
2284 ns = 100; /* fast memory if 0 */
2285 }
2286
2287 /*
2288 * In PSST, PSL, PSHT fields we tell the controller
2289 * timing parameters in CLKOUT clock cycles.
2290 * CLKOUT is the same as GCLK2_50.
2291 */
2292
2293/* how we want to adjust the timing - in percent */
2294
2295#define ADJ 180 /* 80 % longer accesstime - to be sure */
2296
2297 clocks = ((M8XX_BUSFREQ / 1000) * ns) / 1000;
2298 clocks = (clocks * ADJ) / (100*1000);
2299
2300 if(clocks >= PCMCIA_BMT_LIMIT) {
2301 DEBUG(0, "Max access time limit reached\n");
2302 clocks = PCMCIA_BMT_LIMIT-1;
2303 }
2304
2305 psst = clocks / 7; /* setup time */
2306 psht = clocks / 7; /* hold time */
2307 psl = (clocks * 5) / 7; /* strobe length */
2308
2309 psst += clocks - (psst + psht + psl);
2310
2311 reg = psst << 12;
2312 reg |= psl << 7;
2313 reg |= psht << 16;
2314
2315 return reg;
2316}
2317#endif
2318
wdenk90e7e422002-12-04 23:39:58 +00002319/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00002320
2321#ifdef CONFIG_IDE_8xx_PCCARD
2322static void print_funcid (int func)
2323{
2324 puts (indent);
2325 switch (func) {
2326 case CISTPL_FUNCID_MULTI:
2327 puts (" Multi-Function");
2328 break;
2329 case CISTPL_FUNCID_MEMORY:
2330 puts (" Memory");
2331 break;
2332 case CISTPL_FUNCID_SERIAL:
2333 puts (" Serial Port");
2334 break;
2335 case CISTPL_FUNCID_PARALLEL:
2336 puts (" Parallel Port");
2337 break;
2338 case CISTPL_FUNCID_FIXED:
2339 puts (" Fixed Disk");
2340 break;
2341 case CISTPL_FUNCID_VIDEO:
2342 puts (" Video Adapter");
2343 break;
2344 case CISTPL_FUNCID_NETWORK:
2345 puts (" Network Adapter");
2346 break;
2347 case CISTPL_FUNCID_AIMS:
2348 puts (" AIMS Card");
2349 break;
2350 case CISTPL_FUNCID_SCSI:
2351 puts (" SCSI Adapter");
2352 break;
2353 default:
2354 puts (" Unknown");
2355 break;
2356 }
2357 puts (" Card\n");
2358}
2359#endif /* CONFIG_IDE_8xx_PCCARD */
2360
wdenk90e7e422002-12-04 23:39:58 +00002361/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00002362
2363#ifdef CONFIG_IDE_8xx_PCCARD
2364static void print_fixed (volatile uchar *p)
2365{
2366 if (p == NULL)
2367 return;
2368
2369 puts(indent);
2370
2371 switch (*p) {
2372 case CISTPL_FUNCE_IDE_IFACE:
2373 { uchar iface = *(p+2);
2374
2375 puts ((iface == CISTPL_IDE_INTERFACE) ? " IDE" : " unknown");
2376 puts (" interface ");
2377 break;
2378 }
2379 case CISTPL_FUNCE_IDE_MASTER:
2380 case CISTPL_FUNCE_IDE_SLAVE:
2381 { uchar f1 = *(p+2);
2382 uchar f2 = *(p+4);
2383
2384 puts ((f1 & CISTPL_IDE_SILICON) ? " [silicon]" : " [rotating]");
2385
2386 if (f1 & CISTPL_IDE_UNIQUE)
2387 puts (" [unique]");
2388
2389 puts ((f1 & CISTPL_IDE_DUAL) ? " [dual]" : " [single]");
2390
2391 if (f2 & CISTPL_IDE_HAS_SLEEP)
2392 puts (" [sleep]");
2393
2394 if (f2 & CISTPL_IDE_HAS_STANDBY)
2395 puts (" [standby]");
2396
2397 if (f2 & CISTPL_IDE_HAS_IDLE)
2398 puts (" [idle]");
2399
2400 if (f2 & CISTPL_IDE_LOW_POWER)
2401 puts (" [low power]");
2402
2403 if (f2 & CISTPL_IDE_REG_INHIBIT)
2404 puts (" [reg inhibit]");
2405
2406 if (f2 & CISTPL_IDE_HAS_INDEX)
2407 puts (" [index]");
2408
2409 if (f2 & CISTPL_IDE_IOIS16)
2410 puts (" [IOis16]");
2411
2412 break;
2413 }
2414 }
2415 putc ('\n');
2416}
2417#endif /* CONFIG_IDE_8xx_PCCARD */
2418
wdenk90e7e422002-12-04 23:39:58 +00002419/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00002420
2421#ifdef CONFIG_IDE_8xx_PCCARD
2422
2423#define MAX_IDENT_CHARS 64
2424#define MAX_IDENT_FIELDS 4
2425
2426static uchar *known_cards[] = {
2427 "ARGOSY PnPIDE D5",
2428 NULL
2429};
2430
2431static int identify (volatile uchar *p)
2432{
2433 uchar id_str[MAX_IDENT_CHARS];
2434 uchar data;
2435 uchar *t;
2436 uchar **card;
2437 int i, done;
2438
2439 if (p == NULL)
2440 return (0); /* Don't know */
2441
2442 t = id_str;
2443 done =0;
2444
2445 for (i=0; i<=4 && !done; ++i, p+=2) {
2446 while ((data = *p) != '\0') {
2447 if (data == 0xFF) {
2448 done = 1;
2449 break;
2450 }
2451 *t++ = data;
2452 if (t == &id_str[MAX_IDENT_CHARS-1]) {
2453 done = 1;
2454 break;
2455 }
2456 p += 2;
2457 }
2458 if (!done)
2459 *t++ = ' ';
2460 }
2461 *t = '\0';
2462 while (--t > id_str) {
2463 if (*t == ' ')
2464 *t = '\0';
2465 else
2466 break;
2467 }
2468 puts (id_str);
2469 putc ('\n');
2470
2471 for (card=known_cards; *card; ++card) {
2472 debug ("## Compare against \"%s\"\n", *card);
2473 if (strcmp(*card, id_str) == 0) { /* found! */
2474 debug ("## CARD FOUND ##\n");
2475 return (1);
2476 }
2477 }
2478
2479 return (0); /* don't know */
2480}
2481#endif /* CONFIG_IDE_8xx_PCCARD */
2482
wdenk90e7e422002-12-04 23:39:58 +00002483/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00002484
2485#endif /* CFG_CMD_PCMCIA || (CFG_CMD_IDE && CONFIG_IDE_8xx_PCCARD) */
wdenk57b2d802003-06-27 21:31:46 +00002486
2487/**************************************************/
2488
2489#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
wdenkf287a242003-07-01 21:06:45 +00002490U_BOOT_CMD(
2491 pinit, 2, 1, do_pinit,
wdenk57b2d802003-06-27 21:31:46 +00002492 "pinit - PCMCIA sub-system\n",
2493 "on - power on PCMCIA socket\n"
2494 "pinit off - power off PCMCIA socket\n"
2495);
2496#endif