]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - common/cmd_pcmcia.c
8c17859daa3e11b5c5431c0a4f52a8a3032b6ac8
[karo-tx-uboot.git] / common / cmd_pcmcia.c
1 /*
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>
60 #if 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
70 int pcmcia_on (void);
71
72 #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
73 static int  pcmcia_off (void);
74 #endif
75
76 #ifdef CONFIG_I82365
77
78 extern int i82365_init (void);
79 extern void i82365_exit (void);
80
81 #else /* ! CONFIG_I82365 */
82
83 #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
84 static int  hardware_disable(int slot);
85 #endif
86 static int  hardware_enable (int slot);
87 static int  voltage_set(int slot, int vcc, int vpp);
88
89 #ifndef CONFIG_I82365
90 static u_int m8xx_get_graycode(u_int size);
91 #endif  /* CONFIG_I82365 */
92 #if 0
93 static u_int m8xx_get_speed(u_int ns, u_int is_io);
94 #endif
95
96 /* -------------------------------------------------------------------- */
97
98 /* look up table for pgcrx registers */
99
100 static 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
107 #endif /* CONFIG_I82365 */
108
109 #ifdef CONFIG_IDE_8xx_PCCARD
110 static void print_funcid (int func);
111 static void print_fixed  (volatile uchar *p);
112 static int  identify     (volatile uchar *p);
113 static int  check_ide_device (int slot);
114 #endif  /* CONFIG_IDE_8xx_PCCARD */
115
116 const char *indent = "\t   ";
117
118 /* -------------------------------------------------------------------- */
119
120 #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
121
122 int 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
143 /* -------------------------------------------------------------------- */
144
145 #ifdef CONFIG_I82365
146 int 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
163 #if defined(CONFIG_LWMON) || defined(CONFIG_NSCU)
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
169 int pcmcia_on (void)
170 {
171         int i;
172         u_long reg, base;
173         pcmcia_win_t *win;
174         u_int slotbit;
175         u_int rc, slot;
176
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
189         slotbit = PCMCIA_SLOT_x;
190         for (i=0; i<PCMCIA_MEM_WIN_NO; ++i) {
191                 win->br = base;
192
193 #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
197                 switch (i) {
198 #ifdef CONFIG_IDE_8xx_PCCARD
199                 case 4:
200                 case 0: {       /* map attribute memory */
201                         win->or = (     PCMCIA_BSIZE_64M
202                                 |       PCMCIA_PPS_8
203                                 |       PCMCIA_PRS_ATTR
204                                 |       slotbit
205                                 |       PCMCIA_PV
206                                 |       CFG_PCMCIA_TIMING );
207                         break;
208                     }
209                 case 5:
210                 case 1: {       /* map I/O window for data reg */
211                         win->or = (     PCMCIA_BSIZE_1K
212                                 |       PCMCIA_PPS_16
213                                 |       PCMCIA_PRS_IO
214                                 |       slotbit
215                                 |       PCMCIA_PV
216                                 |       CFG_PCMCIA_TIMING );
217                         break;
218                     }
219                 case 6:
220                 case 2: {       /* map I/O window for cmd/ctrl reg block */
221                         win->or = (     PCMCIA_BSIZE_1K
222                                 |       PCMCIA_PPS_8
223                                 |       PCMCIA_PRS_IO
224                                 |       slotbit
225                                 |       PCMCIA_PV
226                                 |       CFG_PCMCIA_TIMING );
227                         break;
228                     }
229 #endif  /* CONFIG_IDE_8xx_PCCARD */
230 #ifdef CONFIG_BMS2003
231                 case 3: {       /* map I/O window for 4xUART data/ctrl */
232                         win->br += 0x40000;
233                         win->or = (     PCMCIA_BSIZE_256K
234                                 |       PCMCIA_PPS_8
235                                 |       PCMCIA_PRS_IO
236                                 |       slotbit
237                                 |       PCMCIA_PV
238                                 |       CFG_PCMCIA_TIMING );
239                         break;
240                     }
241 #endif /* CONFIG_BMS2003 */
242                 default:        /* set to not valid */
243                         win->or = 0;
244                         break;
245                 }
246
247                 debug ("MemWin %d: PBR 0x%08lX  POR %08lX\n",
248                         i, win->br, win->or);
249                 base += CFG_PCMCIA_MEM_SIZE;
250                 ++win;
251         }
252
253         for (i=0, rc=0, slot=_slot_; i<PCMCIA_SOCKETS_NO; i++, slot = !slot) {
254                 /* turn off voltage */
255                 if ((rc = voltage_set(slot, 0, 0)))
256                         continue;
257
258                 /* Enable external hardware */
259                 if ((rc = hardware_enable(slot)))
260                         continue;
261
262 #ifdef CONFIG_IDE_8xx_PCCARD
263                 if ((rc = check_ide_device(i)))
264                         continue;
265 #endif
266         }
267         return (rc);
268 }
269 #endif /* CONFIG_I82365 */
270
271 /* -------------------------------------------------------------------- */
272
273 #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
274
275 #ifdef CONFIG_I82365
276 static int pcmcia_off (void)
277 {
278         printf ("Disable PCMCIA " PCMCIA_SLOT_MSG "\n");
279
280         i82365_exit();
281
282         return 0;
283 }
284 #else
285 static int pcmcia_off (void)
286 {
287         int i;
288         pcmcia_win_t *win;
289
290         printf ("Disable PCMCIA " PCMCIA_SLOT_MSG "\n");
291
292         /* clear interrupt state, and disable interrupts */
293         ((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_pscr =  PCMCIA_MASK(_slot_);
294         ((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_per &= ~PCMCIA_MASK(_slot_);
295
296         /* turn off interrupt and disable CxOE */
297         PCMCIA_PGCRX(_slot_) = __MY_PCMCIA_GCRX_CXOE;
298
299         /* turn off memory windows */
300         win = (pcmcia_win_t *)(&((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_pbr0);
301
302         for (i=0; i<PCMCIA_MEM_WIN_NO; ++i) {
303                 /* disable memory window */
304                 win->or = 0;
305                 ++win;
306         }
307
308         /* turn off voltage */
309         voltage_set(_slot_, 0, 0);
310
311         /* disable external hardware */
312         printf ("Shutdown and Poweroff " PCMCIA_SLOT_MSG "\n");
313         hardware_disable(_slot_);
314         return 0;
315 }
316 #endif /* CONFIG_I82365 */
317
318 #endif  /* CFG_CMD_PCMCIA */
319
320 /* -------------------------------------------------------------------- */
321
322 #ifdef CONFIG_IDE_8xx_PCCARD
323
324 #define MAX_TUPEL_SZ    512
325 #define MAX_FEATURES    4
326
327 int ide_devices_found;
328 static int check_ide_device (int slot)
329 {
330         volatile uchar *ident = NULL;
331         volatile uchar *feature_p[MAX_FEATURES];
332         volatile uchar *p, *start, *addr;
333         int n_features = 0;
334         uchar func_id = ~0;
335         uchar code, len;
336         ushort config_base = 0;
337         int found = 0;
338         int i;
339
340         addr = (volatile uchar *)(CFG_PCMCIA_MEM_ADDR +
341                                   CFG_PCMCIA_MEM_SIZE * (slot * 4));
342         debug ("PCMCIA MEM: %08lX\n", (ulong)addr);
343
344         start = p = (volatile uchar *) addr;
345
346         while ((p - start) < MAX_TUPEL_SZ) {
347
348                 code = *p; p += 2;
349
350                 if (code == 0xFF) { /* End of chain */
351                         break;
352                 }
353
354                 len = *p; p += 2;
355 #if defined(DEBUG) && (DEBUG > 1)
356                 { volatile uchar *q = p;
357                         printf ("\nTuple code %02x  length %d\n\tData:",
358                                 code, len);
359
360                         for (i = 0; i < len; ++i) {
361                                 printf (" %02x", *q);
362                                 q+= 2;
363                         }
364                 }
365 #endif  /* DEBUG */
366                 switch (code) {
367                 case CISTPL_VERS_1:
368                         ident = p + 4;
369                         break;
370                 case CISTPL_FUNCID:
371                         /* Fix for broken SanDisk which may have 0x80 bit set */
372                         func_id = *p & 0x7F;
373                         break;
374                 case CISTPL_FUNCE:
375                         if (n_features < MAX_FEATURES)
376                                 feature_p[n_features++] = p;
377                         break;
378                 case CISTPL_CONFIG:
379                         config_base = (*(p+6) << 8) + (*(p+4));
380                         debug ("\n## Config_base = %04x ###\n", config_base);
381                 default:
382                         break;
383                 }
384                 p += 2 * len;
385         }
386
387         found = identify (ident);
388
389         if (func_id != ((uchar)~0)) {
390                 print_funcid (func_id);
391
392                 if (func_id == CISTPL_FUNCID_FIXED)
393                         found = 1;
394                 else
395                         return (1);     /* no disk drive */
396         }
397
398         for (i=0; i<n_features; ++i) {
399                 print_fixed (feature_p[i]);
400         }
401
402         if (!found) {
403                 printf ("unknown card type\n");
404                 return (1);
405         }
406
407         ide_devices_found |= (1 << slot);
408
409         /* set I/O area in config reg -> only valid for ARGOSY D5!!! */
410         *((uchar *)(addr + config_base)) = 1;
411
412         return (0);
413 }
414 #endif  /* CONFIG_IDE_8xx_PCCARD */
415
416 /* -------------------------------------------------------------------- */
417
418
419 /* -------------------------------------------------------------------- */
420 /* board specific stuff:                                                */
421 /* voltage_set(), hardware_enable() and hardware_disable()              */
422 /* -------------------------------------------------------------------- */
423
424 /* -------------------------------------------------------------------- */
425 /* RPX Boards from Embedded Planet                                      */
426 /* -------------------------------------------------------------------- */
427
428 #if defined(CONFIG_RPXCLASSIC) || defined(CONFIG_RPXLITE)
429
430 /* The RPX boards seems to have it's bus monitor timeout set to 6*8 clocks.
431  * SYPCR is write once only, therefore must the slowest memory be faster
432  * than the bus monitor or we will get a machine check due to the bus timeout.
433  */
434
435 #define PCMCIA_BOARD_MSG "RPX CLASSIC or RPX LITE"
436
437 #undef PCMCIA_BMT_LIMIT
438 #define PCMCIA_BMT_LIMIT (6*8)
439
440 static int voltage_set(int slot, int vcc, int vpp)
441 {
442         u_long reg = 0;
443
444         switch(vcc) {
445         case 0: break;
446         case 33: reg |= BCSR1_PCVCTL4; break;
447         case 50: reg |= BCSR1_PCVCTL5; break;
448         default: return 1;
449         }
450
451         switch(vpp) {
452         case 0: break;
453         case 33:
454         case 50:
455                 if(vcc == vpp)
456                         reg |= BCSR1_PCVCTL6;
457                 else
458                         return 1;
459                 break;
460         case 120:
461                 reg |= BCSR1_PCVCTL7;
462         default: return 1;
463         }
464
465         if(vcc == 120)
466            return 1;
467
468         /* first, turn off all power */
469
470         *((uint *)RPX_CSR_ADDR) &= ~(BCSR1_PCVCTL4 | BCSR1_PCVCTL5
471                                      | BCSR1_PCVCTL6 | BCSR1_PCVCTL7);
472
473         /* enable new powersettings */
474
475         *((uint *)RPX_CSR_ADDR) |= reg;
476
477         return 0;
478 }
479
480 #define socket_get(_slot_) PCMCIA_SOCKET_KEY_5V
481 static int hardware_enable (int slot)
482 {
483         return 0;       /* No hardware to enable */
484 }
485 #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
486 static int hardware_disable(int slot)
487 {
488         return 0;       /* No hardware to disable */
489 }
490 #endif  /* CFG_CMD_PCMCIA */
491 #endif  /* CONFIG_RPXCLASSIC */
492
493 /* -------------------------------------------------------------------- */
494 /* (F)ADS Boards from Motorola                                          */
495 /* -------------------------------------------------------------------- */
496
497 #if defined(CONFIG_ADS) || defined(CONFIG_FADS)
498
499 #ifdef CONFIG_ADS
500 #define PCMCIA_BOARD_MSG "ADS"
501 #define PCMCIA_GLITCHY_CD  /* My ADS board needs this */
502 #else
503 #define PCMCIA_BOARD_MSG "FADS"
504 #endif
505
506 static int voltage_set(int slot, int vcc, int vpp)
507 {
508         u_long reg = 0;
509
510         switch(vpp) {
511         case 0: reg = 0; break;
512         case 50: reg = 1; break;
513         case 120: reg = 2; break;
514         default: return 1;
515         }
516
517         switch(vcc) {
518         case 0: reg = 0; break;
519 #ifdef CONFIG_ADS
520         case 50: reg = BCSR1_PCCVCCON; break;
521 #endif
522 #ifdef CONFIG_FADS
523         case 33: reg = BCSR1_PCCVCC0 | BCSR1_PCCVCC1; break;
524         case 50: reg = BCSR1_PCCVCC1; break;
525 #endif
526         default: return 1;
527         }
528
529         /* first, turn off all power */
530
531 #ifdef CONFIG_ADS
532         *((uint *)BCSR1) |= BCSR1_PCCVCCON;
533 #endif
534 #ifdef CONFIG_FADS
535         *((uint *)BCSR1) &= ~(BCSR1_PCCVCC0 | BCSR1_PCCVCC1);
536 #endif
537         *((uint *)BCSR1) &= ~BCSR1_PCCVPP_MASK;
538
539         /* enable new powersettings */
540
541 #ifdef CONFIG_ADS
542         *((uint *)BCSR1) &= ~reg;
543 #endif
544 #ifdef CONFIG_FADS
545         *((uint *)BCSR1) |= reg;
546 #endif
547
548         *((uint *)BCSR1) |= reg << 20;
549
550         return 0;
551 }
552
553 #define socket_get(_slot_) PCMCIA_SOCKET_KEY_5V
554
555 static int hardware_enable(int slot)
556 {
557         *((uint *)BCSR1) &= ~BCSR1_PCCEN;
558         return 0;
559 }
560
561 #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
562 static int hardware_disable(int slot)
563 {
564         *((uint *)BCSR1) &= ~BCSR1_PCCEN;
565         return 0;
566 }
567 #endif  /* CFG_CMD_PCMCIA */
568
569 #endif  /* (F)ADS */
570
571 /* -------------------------------------------------------------------- */
572 /* TQM8xxL Boards by TQ Components                                      */
573 /* SC8xx   Boards by SinoVee Microsystems                               */
574 /* -------------------------------------------------------------------- */
575
576 #if defined(CONFIG_TQM8xxL) || defined(CONFIG_SVM_SC8xx)
577
578 #if defined(CONFIG_TQM8xxL)
579 #define PCMCIA_BOARD_MSG "TQM8xxL"
580 #endif
581 #if defined(CONFIG_SVM_SC8xx)
582 #define PCMCIA_BOARD_MSG "SC8xx"
583 #endif
584
585 static int hardware_enable(int slot)
586 {
587         volatile immap_t        *immap;
588         volatile cpm8xx_t       *cp;
589         volatile pcmconf8xx_t   *pcmp;
590         volatile sysconf8xx_t   *sysp;
591         uint reg, mask;
592
593         debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
594
595         udelay(10000);
596
597         immap = (immap_t *)CFG_IMMR;
598         sysp  = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
599         pcmp  = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
600         cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
601
602         /*
603          * Configure SIUMCR to enable PCMCIA port B
604          * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
605          */
606         sysp->sc_siumcr &= ~SIUMCR_DBGC11;      /* set DBGC to 00 */
607
608         /* clear interrupt state, and disable interrupts */
609         pcmp->pcmc_pscr =  PCMCIA_MASK(slot);
610         pcmp->pcmc_per &= ~PCMCIA_MASK(slot);
611
612         /*
613          * Disable interrupts, DMA, and PCMCIA buffers
614          * (isolate the interface) and assert RESET signal
615          */
616         debug ("Disable PCMCIA buffers and assert RESET\n");
617         reg  = 0;
618         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
619 #ifndef NSCU_OE_INV
620         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
621 #endif
622         PCMCIA_PGCRX(slot) = reg;
623         udelay(500);
624
625 #ifndef CONFIG_BMS2003
626 #ifndef CONFIG_NSCU
627         /*
628          * Configure Port C pins for
629          * 5 Volts Enable and 3 Volts enable
630          */
631         immap->im_ioport.iop_pcpar &= ~(0x0002 | 0x0004);
632         immap->im_ioport.iop_pcso  &= ~(0x0002 | 0x0004);
633         /* remove all power */
634
635         immap->im_ioport.iop_pcdat &= ~(0x0002 | 0x0004);
636 #endif
637 #else   /* CONFIG_BMS2003 */
638         /*
639          * Configure Port B  pins for
640          * 5 Volts Enable and 3 Volts enable
641          */
642         immap->im_cpm.cp_pbpar &= ~(0x00000300);
643
644         /* remove all power */
645         immap->im_cpm.cp_pbdat |= 0x00000300;
646 #endif  /* CONFIG_BMS2003 */
647
648         /*
649          * Make sure there is a card in the slot, then configure the interface.
650          */
651         udelay(10000);
652         debug ("[%d] %s: PIPR(%p)=0x%x\n",
653                 __LINE__,__FUNCTION__,
654                 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
655 #ifndef CONFIG_BMS2003
656         if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
657 #else
658         if (pcmp->pcmc_pipr & (0x10000000 >> (slot << 4))) {
659 #endif  /* CONFIG_BMS2003 */
660                 printf ("   No Card found\n");
661                 return (1);
662         }
663
664         /*
665          * Power On.
666          */
667         mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
668         reg  = pcmp->pcmc_pipr;
669         debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
670                 reg,
671                 (reg&PCMCIA_VS1(slot))?"n":"ff",
672                 (reg&PCMCIA_VS2(slot))?"n":"ff");
673 #ifndef CONFIG_NSCU
674         if ((reg & mask) == mask) {
675 #ifndef CONFIG_BMS2003
676                 immap->im_ioport.iop_pcdat |= 0x0004;
677 #else
678                 immap->im_cpm.cp_pbdat &= ~(0x0000100);
679 #endif  /* CONFIG_BMS2003 */
680                 puts (" 5.0V card found: ");
681         } else {
682 #ifndef CONFIG_BMS2003
683                 immap->im_ioport.iop_pcdat |= 0x0002;
684 #else
685                 immap->im_cpm.cp_pbdat &= ~(0x0000200);
686 #endif  /* CONFIG_BMS2003 */
687                 puts (" 3.3V card found: ");
688         }
689 #ifndef CONFIG_BMS2003
690         immap->im_ioport.iop_pcdir |= (0x0002 | 0x0004);
691 #else
692         immap->im_cpm.cp_pbdir |= 0x00000300;
693 #endif  /* CONFIG_BMS2003 */
694 #else
695         if ((reg & mask) == mask) {
696                 puts (" 5.0V card found: ");
697         } else {
698                 puts (" 3.3V card found: ");
699         }
700 #endif
701 #if 0
702         /*  VCC switch error flag, PCMCIA slot INPACK_ pin */
703         cp->cp_pbdir &= ~(0x0020 | 0x0010);
704         cp->cp_pbpar &= ~(0x0020 | 0x0010);
705         udelay(500000);
706 #endif
707         udelay(1000);
708         debug ("Enable PCMCIA buffers and stop RESET\n");
709         reg  =  PCMCIA_PGCRX(slot);
710         reg &= ~__MY_PCMCIA_GCRX_CXRESET;       /* active high */
711 #ifndef NSCU_OE_INV
712         reg &= ~__MY_PCMCIA_GCRX_CXOE;          /* active low  */
713 #else
714         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
715 #endif
716         PCMCIA_PGCRX(slot) = reg;
717
718         udelay(250000); /* some cards need >150 ms to come up :-( */
719
720         debug ("# hardware_enable done\n");
721
722         return (0);
723 }
724
725
726 #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
727 static int hardware_disable(int slot)
728 {
729         volatile immap_t        *immap;
730         volatile pcmconf8xx_t   *pcmp;
731         u_long reg;
732
733         debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
734
735         immap = (immap_t *)CFG_IMMR;
736         pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
737
738 #ifndef CONFIG_BMS2003
739 #ifndef CONFIG_NSCU
740         /* remove all power */
741         immap->im_ioport.iop_pcdat &= ~(0x0002 | 0x0004);
742 #endif
743 #else   /* CONFIG_BMS2003 */
744         immap->im_cpm.cp_pbdat |= 0x00000300;
745 #endif  /* CONFIG_BMS2003 */
746
747         debug ("Disable PCMCIA buffers and assert RESET\n");
748         reg  = 0;
749         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
750 #ifndef NSCU_OE_INV
751         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
752 #endif
753         PCMCIA_PGCRX(slot) = reg;
754
755         udelay(10000);
756
757         return (0);
758 }
759 #endif  /* CFG_CMD_PCMCIA */
760
761 #ifdef CONFIG_NSCU
762 static int voltage_set(int slot, int vcc, int vpp)
763 {
764         return 0;
765 }
766 #else
767 static int voltage_set(int slot, int vcc, int vpp)
768 {
769         volatile immap_t        *immap;
770         volatile pcmconf8xx_t   *pcmp;
771         u_long reg;
772
773         debug ("voltage_set: "
774                 PCMCIA_BOARD_MSG
775                 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
776                 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
777
778         immap = (immap_t *)CFG_IMMR;
779         pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
780         /*
781          * Disable PCMCIA buffers (isolate the interface)
782          * and assert RESET signal
783          */
784         debug ("Disable PCMCIA buffers and assert RESET\n");
785         reg  = PCMCIA_PGCRX(slot);
786         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
787 #ifndef NSCU_OE_INV
788         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
789 #else
790         reg &= ~__MY_PCMCIA_GCRX_CXOE;          /* active low  */
791 #endif
792         PCMCIA_PGCRX(slot) = reg;
793         udelay(500);
794
795 #ifndef CONFIG_BMS2003
796         /*
797          * Configure Port C pins for
798          * 5 Volts Enable and 3 Volts enable,
799          * Turn off all power
800          */
801         debug ("PCMCIA power OFF\n");
802         immap->im_ioport.iop_pcpar &= ~(0x0002 | 0x0004);
803         immap->im_ioport.iop_pcso  &= ~(0x0002 | 0x0004);
804         immap->im_ioport.iop_pcdat &= ~(0x0002 | 0x0004);
805
806         reg = 0;
807         switch(vcc) {
808         case  0:                break;
809         case 33: reg |= 0x0002; break;
810         case 50: reg |= 0x0004; break;
811         default:                goto done;
812         }
813 #else   /* CONFIG_BMS2003 */
814         /*
815          * Configure Port B pins for
816          * 5 Volts Enable and 3 Volts enable,
817          * Turn off all power
818          */
819         debug ("PCMCIA power OFF\n");
820         immap->im_cpm.cp_pbpar &= ~(0x00000300);
821         /* remove all power */
822
823         immap->im_cpm.cp_pbdat |= 0x00000300;
824
825         reg = 0;
826         switch(vcc) {
827                 case  0:                        break;
828                 case 33: reg |= 0x00000200;     break;
829                 case 50: reg |= 0x00000100;     break;
830                 default:                        goto done;
831 }
832 #endif  /* CONFIG_BMS2003 */
833
834         /* Checking supported voltages */
835
836         debug ("PIPR: 0x%x --> %s\n",
837                 pcmp->pcmc_pipr,
838                 (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
839
840 #ifndef CONFIG_BMS2003
841         immap->im_ioport.iop_pcdat |= reg;
842         immap->im_ioport.iop_pcdir |= (0x0002 | 0x0004);
843 #else
844         immap->im_cpm.cp_pbdat &= !reg;
845         immap->im_cpm.cp_pbdir |= 0x00000300;
846 #endif  /* CONFIG_BMS2003 */
847         if (reg) {
848 #ifndef CONFIG_BMS2003
849                 debug ("PCMCIA powered at %sV\n",
850                         (reg&0x0004) ? "5.0" : "3.3");
851 #else
852                 debug ("PCMCIA powered at %sV\n",
853                         (reg&0x00000200) ? "5.0" : "3.3");
854 #endif  /* CONFIG_BMS2003 */
855         } else {
856                 debug ("PCMCIA powered down\n");
857         }
858
859 done:
860         debug ("Enable PCMCIA buffers and stop RESET\n");
861         reg  =  PCMCIA_PGCRX(slot);
862         reg &= ~__MY_PCMCIA_GCRX_CXRESET;       /* active high */
863 #ifndef NSCU_OE_INV
864         reg &= ~__MY_PCMCIA_GCRX_CXOE;          /* active low  */
865 #else
866         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
867 #endif
868         PCMCIA_PGCRX(slot) = reg;
869         udelay(500);
870
871         debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
872                 slot+'A');
873         return (0);
874 }
875 #endif
876
877 #endif  /* TQM8xxL */
878
879
880 /* -------------------------------------------------------------------- */
881 /* LWMON Board                                                          */
882 /* -------------------------------------------------------------------- */
883
884 #if defined(CONFIG_LWMON)
885
886 #define PCMCIA_BOARD_MSG "LWMON"
887
888 /* #define's for MAX1604 Power Switch */
889 #define MAX1604_OP_SUS          0x80
890 #define MAX1604_VCCBON          0x40
891 #define MAX1604_VCC_35          0x20
892 #define MAX1604_VCCBHIZ         0x10
893 #define MAX1604_VPPBON          0x08
894 #define MAX1604_VPPBPBPGM       0x04
895 #define MAX1604_VPPBHIZ         0x02
896 /* reserved                     0x01    */
897
898 static int hardware_enable(int slot)
899 {
900         volatile immap_t        *immap;
901         volatile cpm8xx_t       *cp;
902         volatile pcmconf8xx_t   *pcmp;
903         volatile sysconf8xx_t   *sysp;
904         uint reg, mask;
905         uchar val;
906
907
908         debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
909
910         /* Switch on PCMCIA port in PIC register 0x60 */
911         reg = pic_read  (0x60);
912         debug ("[%d] PIC read: reg_60 = 0x%02x\n", __LINE__, reg);
913         reg &= ~0x10;
914         /* reg |= 0x08; Vpp not needed */
915         pic_write (0x60, reg);
916 #ifdef DEBUG
917         reg = pic_read  (0x60);
918         printf ("[%d] PIC read: reg_60 = 0x%02x\n", __LINE__, reg);
919 #endif
920         udelay(10000);
921
922         immap = (immap_t *)CFG_IMMR;
923         sysp  = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
924         pcmp  = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
925         cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
926
927         /*
928          * Configure SIUMCR to enable PCMCIA port B
929          * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
930          */
931         sysp->sc_siumcr &= ~SIUMCR_DBGC11;      /* set DBGC to 00 */
932
933         /* clear interrupt state, and disable interrupts */
934         pcmp->pcmc_pscr =  PCMCIA_MASK(_slot_);
935         pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
936
937         /*
938          * Disable interrupts, DMA, and PCMCIA buffers
939          * (isolate the interface) and assert RESET signal
940          */
941         debug ("Disable PCMCIA buffers and assert RESET\n");
942         reg  = 0;
943         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
944         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
945         PCMCIA_PGCRX(_slot_) = reg;
946         udelay(500);
947
948         /*
949          * Make sure there is a card in the slot, then configure the interface.
950          */
951         udelay(10000);
952         debug ("[%d] %s: PIPR(%p)=0x%x\n",
953                 __LINE__,__FUNCTION__,
954                 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
955         if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
956                 printf ("   No Card found\n");
957                 return (1);
958         }
959
960         /*
961          * Power On.
962          */
963         mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
964         reg  = pcmp->pcmc_pipr;
965         debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
966                 reg,
967                 (reg&PCMCIA_VS1(slot))?"n":"ff",
968                 (reg&PCMCIA_VS2(slot))?"n":"ff");
969         if ((reg & mask) == mask) {
970                 val = 0;                /* VCCB3/5 = 0 ==> use Vx = 5.0 V */
971                 puts (" 5.0V card found: ");
972         } else {
973                 val = MAX1604_VCC_35;   /* VCCB3/5 = 1 ==> use Vy = 3.3 V */
974                 puts (" 3.3V card found: ");
975         }
976
977         /*  switch VCC on */
978         val |= MAX1604_OP_SUS | MAX1604_VCCBON;
979         i2c_init  (CFG_I2C_SPEED, CFG_I2C_SLAVE);
980         i2c_write (CFG_I2C_POWER_A_ADDR, 0, 0, &val, 1);
981
982         udelay(500000);
983
984         debug ("Enable PCMCIA buffers and stop RESET\n");
985         reg  =  PCMCIA_PGCRX(_slot_);
986         reg &= ~__MY_PCMCIA_GCRX_CXRESET;       /* active high */
987         reg &= ~__MY_PCMCIA_GCRX_CXOE;          /* active low  */
988         PCMCIA_PGCRX(_slot_) = reg;
989
990         udelay(250000); /* some cards need >150 ms to come up :-( */
991
992         debug ("# hardware_enable done\n");
993
994         return (0);
995 }
996
997
998 #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
999 static int hardware_disable(int slot)
1000 {
1001         volatile immap_t        *immap;
1002         volatile pcmconf8xx_t   *pcmp;
1003         u_long reg;
1004         uchar val;
1005
1006         debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1007
1008         immap = (immap_t *)CFG_IMMR;
1009         pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1010
1011         /* remove all power, put output in high impedance state */
1012         val  = MAX1604_VCCBHIZ | MAX1604_VPPBHIZ;
1013         i2c_init  (CFG_I2C_SPEED, CFG_I2C_SLAVE);
1014         i2c_write (CFG_I2C_POWER_A_ADDR, 0, 0, &val, 1);
1015
1016         /* Configure PCMCIA General Control Register */
1017         debug ("Disable PCMCIA buffers and assert RESET\n");
1018         reg  = 0;
1019         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
1020         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
1021         PCMCIA_PGCRX(_slot_) = reg;
1022
1023         /* Switch off PCMCIA port in PIC register 0x60 */
1024         reg = pic_read  (0x60);
1025         debug ("[%d] PIC read: reg_60 = 0x%02x\n", __LINE__, reg);
1026         reg |=  0x10;
1027         reg &= ~0x08;
1028         pic_write (0x60, reg);
1029 #ifdef DEBUG
1030         reg = pic_read  (0x60);
1031         printf ("[%d] PIC read: reg_60 = 0x%02x\n", __LINE__, reg);
1032 #endif
1033         udelay(10000);
1034
1035         return (0);
1036 }
1037 #endif  /* CFG_CMD_PCMCIA */
1038
1039
1040 static int voltage_set(int slot, int vcc, int vpp)
1041 {
1042         volatile immap_t        *immap;
1043         volatile pcmconf8xx_t   *pcmp;
1044         u_long reg;
1045         uchar val;
1046
1047         debug ("voltage_set: "
1048                 PCMCIA_BOARD_MSG
1049                 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
1050                 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
1051
1052         immap = (immap_t *)CFG_IMMR;
1053         pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1054         /*
1055          * Disable PCMCIA buffers (isolate the interface)
1056          * and assert RESET signal
1057          */
1058         debug ("Disable PCMCIA buffers and assert RESET\n");
1059         reg  = PCMCIA_PGCRX(_slot_);
1060         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
1061         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
1062         PCMCIA_PGCRX(_slot_) = reg;
1063         udelay(500);
1064
1065         /*
1066          * Turn off all power (switch to high impedance)
1067          */
1068         debug ("PCMCIA power OFF\n");
1069         val  = MAX1604_VCCBHIZ | MAX1604_VPPBHIZ;
1070         i2c_init  (CFG_I2C_SPEED, CFG_I2C_SLAVE);
1071         i2c_write (CFG_I2C_POWER_A_ADDR, 0, 0, &val, 1);
1072
1073         val = 0;
1074         switch(vcc) {
1075         case  0:                        break;
1076         case 33: val = MAX1604_VCC_35;  break;
1077         case 50:                        break;
1078         default:                        goto done;
1079         }
1080
1081         /* Checking supported voltages */
1082
1083         debug ("PIPR: 0x%x --> %s\n",
1084                 pcmp->pcmc_pipr,
1085                 (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
1086
1087         i2c_write (CFG_I2C_POWER_A_ADDR, 0, 0, &val, 1);
1088         if (val) {
1089                 debug ("PCMCIA powered at %sV\n",
1090                         (val & MAX1604_VCC_35) ? "3.3" : "5.0");
1091         } else {
1092                 debug ("PCMCIA powered down\n");
1093         }
1094
1095 done:
1096         debug ("Enable PCMCIA buffers and stop RESET\n");
1097         reg  =  PCMCIA_PGCRX(_slot_);
1098         reg &= ~__MY_PCMCIA_GCRX_CXRESET;       /* active high */
1099         reg &= ~__MY_PCMCIA_GCRX_CXOE;          /* active low  */
1100         PCMCIA_PGCRX(_slot_) = reg;
1101         udelay(500);
1102
1103         debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
1104                 slot+'A');
1105         return (0);
1106 }
1107
1108 #endif  /* LWMON */
1109
1110 /* -------------------------------------------------------------------- */
1111 /* GTH board by Corelatus AB                                            */
1112 /* -------------------------------------------------------------------- */
1113 #if defined(CONFIG_GTH)
1114
1115 #define PCMCIA_BOARD_MSG "GTH COMPACT FLASH"
1116
1117 static int voltage_set (int slot, int vcc, int vpp)
1118 {       /* Do nothing */
1119         return 0;
1120 }
1121
1122 static int hardware_enable (int slot)
1123 {
1124         volatile immap_t *immap;
1125         volatile cpm8xx_t *cp;
1126         volatile pcmconf8xx_t *pcmp;
1127         volatile sysconf8xx_t *sysp;
1128         uint reg, mask;
1129
1130         debug ("hardware_enable: GTH Slot %c\n", 'A' + slot);
1131
1132         immap = (immap_t *) CFG_IMMR;
1133         sysp = (sysconf8xx_t *) (&(((immap_t *) CFG_IMMR)->im_siu_conf));
1134         pcmp = (pcmconf8xx_t *) (&(((immap_t *) CFG_IMMR)->im_pcmcia));
1135         cp = (cpm8xx_t *) (&(((immap_t *) CFG_IMMR)->im_cpm));
1136
1137         /* clear interrupt state, and disable interrupts */
1138         pcmp->pcmc_pscr = PCMCIA_MASK (_slot_);
1139         pcmp->pcmc_per &= ~PCMCIA_MASK (_slot_);
1140
1141         /*
1142          * Disable interrupts, DMA, and PCMCIA buffers
1143          * (isolate the interface) and assert RESET signal
1144          */
1145         debug ("Disable PCMCIA buffers and assert RESET\n");
1146         reg = 0;
1147         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
1148         reg |= __MY_PCMCIA_GCRX_CXOE;   /* active low  */
1149         PCMCIA_PGCRX (_slot_) = reg;
1150         udelay (500);
1151
1152         /*
1153          * Make sure there is a card in the slot,
1154          * then configure the interface.
1155          */
1156         udelay (10000);
1157         debug ("[%d] %s: PIPR(%p)=0x%x\n",
1158                 __LINE__, __FUNCTION__,
1159                 &(pcmp->pcmc_pipr), pcmp->pcmc_pipr);
1160         if (pcmp->pcmc_pipr & 0x98000000) {
1161                 printf ("   No Card found\n");
1162                 return (1);
1163         }
1164
1165         mask = PCMCIA_VS1 (slot) | PCMCIA_VS2 (slot);
1166         reg = pcmp->pcmc_pipr;
1167         debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
1168                    reg,
1169                    (reg & PCMCIA_VS1 (slot)) ? "n" : "ff",
1170                    (reg & PCMCIA_VS2 (slot)) ? "n" : "ff");
1171
1172         debug ("Enable PCMCIA buffers and stop RESET\n");
1173         reg  =  PCMCIA_PGCRX (_slot_);
1174         reg &= ~__MY_PCMCIA_GCRX_CXRESET;       /* active high */
1175         reg &= ~__MY_PCMCIA_GCRX_CXOE;          /* active low  */
1176         PCMCIA_PGCRX (_slot_) = reg;
1177
1178         udelay (250000);        /* some cards need >150 ms to come up :-( */
1179
1180         debug ("# hardware_enable done\n");
1181
1182         return 0;
1183 }
1184 #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
1185 static int hardware_disable(int slot)
1186 {
1187         return 0;       /* No hardware to disable */
1188 }
1189 #endif  /* CFG_CMD_PCMCIA */
1190 #endif  /* CONFIG_GTH */
1191
1192 /* -------------------------------------------------------------------- */
1193 /* ICU862 Boards by Cambridge Broadband Ltd.                            */
1194 /* -------------------------------------------------------------------- */
1195
1196 #if defined(CONFIG_ICU862)
1197
1198 #define PCMCIA_BOARD_MSG "ICU862"
1199
1200 static void cfg_port_B (void);
1201
1202 static int hardware_enable(int slot)
1203 {
1204         volatile immap_t        *immap;
1205         volatile cpm8xx_t       *cp;
1206         volatile pcmconf8xx_t   *pcmp;
1207         volatile sysconf8xx_t   *sysp;
1208         uint reg, pipr, mask;
1209         int i;
1210
1211         debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1212
1213         udelay(10000);
1214
1215         immap = (immap_t *)CFG_IMMR;
1216         sysp  = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
1217         pcmp  = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1218         cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1219
1220         /* Configure Port B for TPS2205 PC-Card Power-Interface Switch */
1221         cfg_port_B ();
1222
1223         /*
1224          * Configure SIUMCR to enable PCMCIA port B
1225          * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
1226          */
1227         sysp->sc_siumcr &= ~SIUMCR_DBGC11;      /* set DBGC to 00 */
1228
1229         /* clear interrupt state, and disable interrupts */
1230         pcmp->pcmc_pscr =  PCMCIA_MASK(_slot_);
1231         pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
1232
1233         /*
1234          * Disable interrupts, DMA, and PCMCIA buffers
1235          * (isolate the interface) and assert RESET signal
1236          */
1237         debug ("Disable PCMCIA buffers and assert RESET\n");
1238         reg  = 0;
1239         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
1240         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
1241         PCMCIA_PGCRX(_slot_) = reg;
1242         udelay(500);
1243
1244         /*
1245          * Make sure there is a card in the slot, then configure the interface.
1246          */
1247         udelay(10000);
1248         debug ("[%d] %s: PIPR(%p)=0x%x\n",
1249                 __LINE__,__FUNCTION__,
1250                 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
1251         if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
1252                 printf ("   No Card found\n");
1253                 return (1);
1254         }
1255
1256         /*
1257          * Power On: Set VAVCC to 3.3V or 5V, set VAVPP to Hi-Z
1258          */
1259         mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
1260         pipr = pcmp->pcmc_pipr;
1261         debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
1262                 pipr,
1263                 (reg&PCMCIA_VS1(slot))?"n":"ff",
1264                 (reg&PCMCIA_VS2(slot))?"n":"ff");
1265
1266         reg  = cp->cp_pbdat;
1267         if ((pipr & mask) == mask) {
1268                 reg |= (TPS2205_VPP_PGM | TPS2205_VPP_VCC |     /* VAVPP => Hi-Z */
1269                         TPS2205_VCC3);                          /* 3V off       */
1270                 reg &= ~(TPS2205_VCC5);                         /* 5V on        */
1271                 puts (" 5.0V card found: ");
1272         } else {
1273                 reg |= (TPS2205_VPP_PGM | TPS2205_VPP_VCC |     /* VAVPP => Hi-Z */
1274                         TPS2205_VCC5);                          /* 5V off       */
1275                 reg &= ~(TPS2205_VCC3);                         /* 3V on        */
1276                 puts (" 3.3V card found: ");
1277         }
1278
1279         debug ("\nPB DAT: %08x -> 3.3V %s 5.0V %s VPP_PGM %s VPP_VCC %s\n",
1280                 reg,
1281                 (reg & TPS2205_VCC3)    ? "off" : "on",
1282                 (reg & TPS2205_VCC5)    ? "off" : "on",
1283                 (reg & TPS2205_VPP_PGM) ? "off" : "on",
1284                 (reg & TPS2205_VPP_VCC) ? "off" : "on" );
1285
1286         cp->cp_pbdat = reg;
1287
1288         /*  Wait 500 ms; use this to check for over-current */
1289         for (i=0; i<5000; ++i) {
1290                 if ((cp->cp_pbdat & TPS2205_OC) == 0) {
1291                         printf ("   *** Overcurrent - Safety shutdown ***\n");
1292                         cp->cp_pbdat &= ~(TPS2205_SHDN);
1293                         return (1);
1294                 }
1295                 udelay (100);
1296         }
1297
1298         debug ("Enable PCMCIA buffers and stop RESET\n");
1299         reg  =  PCMCIA_PGCRX(_slot_);
1300         reg &= ~__MY_PCMCIA_GCRX_CXRESET;       /* active high */
1301         reg &= ~__MY_PCMCIA_GCRX_CXOE;          /* active low  */
1302         PCMCIA_PGCRX(_slot_) = reg;
1303
1304         udelay(250000); /* some cards need >150 ms to come up :-( */
1305
1306         debug ("# hardware_enable done\n");
1307
1308         return (0);
1309 }
1310
1311
1312 #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
1313 static int hardware_disable(int slot)
1314 {
1315         volatile immap_t        *immap;
1316         volatile cpm8xx_t       *cp;
1317         volatile pcmconf8xx_t   *pcmp;
1318         u_long reg;
1319
1320         debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1321
1322         immap = (immap_t *)CFG_IMMR;
1323         cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1324         pcmp  = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1325
1326         /* Shut down */
1327         cp->cp_pbdat &= ~(TPS2205_SHDN);
1328
1329         /* Configure PCMCIA General Control Register */
1330         debug ("Disable PCMCIA buffers and assert RESET\n");
1331         reg  = 0;
1332         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
1333         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
1334         PCMCIA_PGCRX(_slot_) = reg;
1335
1336         udelay(10000);
1337
1338         return (0);
1339 }
1340 #endif  /* CFG_CMD_PCMCIA */
1341
1342
1343 static int voltage_set(int slot, int vcc, int vpp)
1344 {
1345         volatile immap_t        *immap;
1346         volatile cpm8xx_t       *cp;
1347         volatile pcmconf8xx_t   *pcmp;
1348         u_long reg;
1349
1350         debug ("voltage_set: "
1351                 PCMCIA_BOARD_MSG
1352                 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
1353                 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
1354
1355         immap = (immap_t *)CFG_IMMR;
1356         cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1357         pcmp  = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1358         /*
1359          * Disable PCMCIA buffers (isolate the interface)
1360          * and assert RESET signal
1361          */
1362         debug ("Disable PCMCIA buffers and assert RESET\n");
1363         reg  = PCMCIA_PGCRX(_slot_);
1364         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
1365         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
1366         PCMCIA_PGCRX(_slot_) = reg;
1367         udelay(500);
1368
1369         /*
1370          * Configure Port C pins for
1371          * 5 Volts Enable and 3 Volts enable,
1372          * Turn all power pins to Hi-Z
1373          */
1374         debug ("PCMCIA power OFF\n");
1375         cfg_port_B ();  /* Enables switch, but all in Hi-Z */
1376
1377         reg  = cp->cp_pbdat;
1378
1379         switch(vcc) {
1380         case  0:                        break;  /* Switch off           */
1381         case 33: reg &= ~TPS2205_VCC3;  break;  /* Switch on 3.3V       */
1382         case 50: reg &= ~TPS2205_VCC5;  break;  /* Switch on 5.0V       */
1383         default:                        goto done;
1384         }
1385
1386         /* Checking supported voltages */
1387
1388         debug ("PIPR: 0x%x --> %s\n",
1389                 pcmp->pcmc_pipr,
1390                 (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
1391
1392         cp->cp_pbdat = reg;
1393
1394 #ifdef DEBUG
1395     {
1396         char *s;
1397
1398         if ((reg & TPS2205_VCC3) == 0) {
1399                 s = "at 3.3V";
1400         } else if ((reg & TPS2205_VCC5) == 0) {
1401                 s = "at 5.0V";
1402         } else {
1403                 s = "down";
1404         }
1405         printf ("PCMCIA powered %s\n", s);
1406     }
1407 #endif
1408
1409 done:
1410         debug ("Enable PCMCIA buffers and stop RESET\n");
1411         reg  =  PCMCIA_PGCRX(_slot_);
1412         reg &= ~__MY_PCMCIA_GCRX_CXRESET;       /* active high */
1413         reg &= ~__MY_PCMCIA_GCRX_CXOE;          /* active low  */
1414         PCMCIA_PGCRX(_slot_) = reg;
1415         udelay(500);
1416
1417         debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
1418                 slot+'A');
1419         return (0);
1420 }
1421
1422 static void cfg_port_B (void)
1423 {
1424         volatile immap_t        *immap;
1425         volatile cpm8xx_t       *cp;
1426         uint reg;
1427
1428         immap = (immap_t *)CFG_IMMR;
1429         cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1430
1431         /*
1432          * Configure Port B for TPS2205 PC-Card Power-Interface Switch
1433          *
1434          * Switch off all voltages, assert shutdown
1435          */
1436         reg  = cp->cp_pbdat;
1437         reg |= (TPS2205_VPP_PGM | TPS2205_VPP_VCC |     /* VAVPP => Hi-Z */
1438                 TPS2205_VCC3    | TPS2205_VCC5    |     /* VAVCC => Hi-Z */
1439                 TPS2205_SHDN);                          /* enable switch */
1440         cp->cp_pbdat = reg;
1441
1442         cp->cp_pbpar &= ~(TPS2205_INPUTS | TPS2205_OUTPUTS);
1443
1444         reg = cp->cp_pbdir & ~(TPS2205_INPUTS);
1445         cp->cp_pbdir = reg | TPS2205_OUTPUTS;
1446
1447         debug ("Set Port B: PAR: %08x DIR: %08x DAT: %08x\n",
1448                 cp->cp_pbpar, cp->cp_pbdir, cp->cp_pbdat);
1449 }
1450
1451 #endif  /* ICU862 */
1452
1453
1454 /* -------------------------------------------------------------------- */
1455 /* C2MON Boards by TTTech Computertechnik AG                            */
1456 /* -------------------------------------------------------------------- */
1457
1458 #if defined(CONFIG_C2MON)
1459
1460 #define PCMCIA_BOARD_MSG "C2MON"
1461
1462 static void cfg_ports (void);
1463
1464 static int hardware_enable(int slot)
1465 {
1466         volatile immap_t        *immap;
1467         volatile cpm8xx_t       *cp;
1468         volatile pcmconf8xx_t   *pcmp;
1469         volatile sysconf8xx_t   *sysp;
1470         uint reg, pipr, mask;
1471         ushort sreg;
1472         int i;
1473
1474         debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1475
1476         udelay(10000);
1477
1478         immap = (immap_t *)CFG_IMMR;
1479         sysp  = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
1480         pcmp  = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1481         cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1482
1483         /* Configure Ports for TPS2211A PC-Card Power-Interface Switch */
1484         cfg_ports ();
1485
1486         /*
1487          * Configure SIUMCR to enable PCMCIA port B
1488          * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
1489          */
1490         sysp->sc_siumcr &= ~SIUMCR_DBGC11;      /* set DBGC to 00 */
1491
1492         /* clear interrupt state, and disable interrupts */
1493         pcmp->pcmc_pscr =  PCMCIA_MASK(_slot_);
1494         pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
1495
1496         /*
1497          * Disable interrupts, DMA, and PCMCIA buffers
1498          * (isolate the interface) and assert RESET signal
1499          */
1500         debug ("Disable PCMCIA buffers and assert RESET\n");
1501         reg  = 0;
1502         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
1503         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
1504         PCMCIA_PGCRX(_slot_) = reg;
1505         udelay(500);
1506
1507         /*
1508          * Make sure there is a card in the slot, then configure the interface.
1509          */
1510         udelay(10000);
1511         debug ("[%d] %s: PIPR(%p)=0x%x\n",
1512                 __LINE__,__FUNCTION__,
1513                 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
1514         if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
1515                 printf ("   No Card found\n");
1516                 return (1);
1517         }
1518
1519         /*
1520          * Power On: Set VAVCC to 3.3V or 5V, set VAVPP to Hi-Z
1521          */
1522         mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
1523         pipr = pcmp->pcmc_pipr;
1524         debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
1525                 pipr,
1526                 (reg&PCMCIA_VS1(slot))?"n":"ff",
1527                 (reg&PCMCIA_VS2(slot))?"n":"ff");
1528
1529         sreg = immap->im_ioport.iop_pcdat;
1530         if ((pipr & mask) == mask) {
1531                 sreg |=  (TPS2211_VPPD0 | TPS2211_VPPD1 |       /* VAVPP => Hi-Z */
1532                           TPS2211_VCCD1);                       /* 5V on        */
1533                 sreg &= ~(TPS2211_VCCD0);                       /* 3V off       */
1534                 puts (" 5.0V card found: ");
1535         } else {
1536                 sreg |=  (TPS2211_VPPD0 | TPS2211_VPPD1 |       /* VAVPP => Hi-Z */
1537                           TPS2211_VCCD0);                       /* 3V on        */
1538                 sreg &= ~(TPS2211_VCCD1);                       /* 5V off       */
1539                 puts (" 3.3V card found: ");
1540         }
1541
1542         debug ("\nPC DAT: %04x -> 3.3V %s 5.0V %s\n",
1543                 sreg,
1544                 ( (sreg & TPS2211_VCCD0) && !(sreg & TPS2211_VCCD1)) ? "on" : "off",
1545                 (!(sreg & TPS2211_VCCD0) &&  (sreg & TPS2211_VCCD1)) ? "on" : "off"
1546         );
1547
1548         immap->im_ioport.iop_pcdat = sreg;
1549
1550         /*  Wait 500 ms; use this to check for over-current */
1551         for (i=0; i<5000; ++i) {
1552                 if ((cp->cp_pbdat & TPS2211_OC) == 0) {
1553                     printf ("   *** Overcurrent - Safety shutdown ***\n");
1554                     immap->im_ioport.iop_pcdat &= ~(TPS2211_VCCD0|TPS2211_VCCD1);
1555                     return (1);
1556                 }
1557                 udelay (100);
1558         }
1559
1560         debug ("Enable PCMCIA buffers and stop RESET\n");
1561         reg  =  PCMCIA_PGCRX(_slot_);
1562         reg &= ~__MY_PCMCIA_GCRX_CXRESET;       /* active high */
1563         reg &= ~__MY_PCMCIA_GCRX_CXOE;          /* active low  */
1564         PCMCIA_PGCRX(_slot_) = reg;
1565
1566         udelay(250000); /* some cards need >150 ms to come up :-( */
1567
1568         debug ("# hardware_enable done\n");
1569
1570         return (0);
1571 }
1572
1573
1574 #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
1575 static int hardware_disable(int slot)
1576 {
1577         volatile immap_t        *immap;
1578         volatile cpm8xx_t       *cp;
1579         volatile pcmconf8xx_t   *pcmp;
1580         u_long reg;
1581
1582         debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1583
1584         immap = (immap_t *)CFG_IMMR;
1585         pcmp  = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1586
1587         /* Configure PCMCIA General Control Register */
1588         debug ("Disable PCMCIA buffers and assert RESET\n");
1589         reg  = 0;
1590         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
1591         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
1592         PCMCIA_PGCRX(_slot_) = reg;
1593
1594         /* ALl voltages off / Hi-Z */
1595         immap->im_ioport.iop_pcdat |= (TPS2211_VPPD0 | TPS2211_VPPD1 |
1596                                        TPS2211_VCCD0 | TPS2211_VCCD1 );
1597
1598         udelay(10000);
1599
1600         return (0);
1601 }
1602 #endif  /* CFG_CMD_PCMCIA */
1603
1604
1605 static int voltage_set(int slot, int vcc, int vpp)
1606 {
1607         volatile immap_t        *immap;
1608         volatile cpm8xx_t       *cp;
1609         volatile pcmconf8xx_t   *pcmp;
1610         u_long reg;
1611         ushort sreg;
1612
1613         debug ("voltage_set: "
1614                 PCMCIA_BOARD_MSG
1615                 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
1616                 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
1617
1618         immap = (immap_t *)CFG_IMMR;
1619         cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1620         pcmp  = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1621         /*
1622          * Disable PCMCIA buffers (isolate the interface)
1623          * and assert RESET signal
1624          */
1625         debug ("Disable PCMCIA buffers and assert RESET\n");
1626         reg  = PCMCIA_PGCRX(_slot_);
1627         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
1628         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
1629         PCMCIA_PGCRX(_slot_) = reg;
1630         udelay(500);
1631
1632         /*
1633          * Configure Port C pins for
1634          * 5 Volts Enable and 3 Volts enable,
1635          * Turn all power pins to Hi-Z
1636          */
1637         debug ("PCMCIA power OFF\n");
1638         cfg_ports ();   /* Enables switch, but all in Hi-Z */
1639
1640         sreg  = immap->im_ioport.iop_pcdat;
1641         sreg |= TPS2211_VPPD0 | TPS2211_VPPD1;          /* VAVPP always Hi-Z */
1642
1643         switch(vcc) {
1644         case  0:                        break;  /* Switch off           */
1645         case 33: sreg |=  TPS2211_VCCD0;        /* Switch on 3.3V       */
1646                  sreg &= ~TPS2211_VCCD1;
1647                                         break;
1648         case 50: sreg &= ~TPS2211_VCCD0;        /* Switch on 5.0V       */
1649                  sreg |=  TPS2211_VCCD1;
1650                                         break;
1651         default:                        goto done;
1652         }
1653
1654         /* Checking supported voltages */
1655
1656         debug ("PIPR: 0x%x --> %s\n",
1657                 pcmp->pcmc_pipr,
1658                 (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
1659
1660         immap->im_ioport.iop_pcdat = sreg;
1661
1662 #ifdef DEBUG
1663     {
1664         char *s;
1665
1666         if ((sreg & TPS2211_VCCD0) && !(sreg & TPS2211_VCCD1)) {
1667                 s = "at 3.3V";
1668         } else if (!(sreg & TPS2211_VCCD0) &&  (sreg & TPS2211_VCCD1)) {
1669                 s = "at 5.0V";
1670         } else {
1671                 s = "down";
1672         }
1673         printf ("PCMCIA powered %s\n", s);
1674     }
1675 #endif
1676
1677 done:
1678         debug ("Enable PCMCIA buffers and stop RESET\n");
1679         reg  =  PCMCIA_PGCRX(_slot_);
1680         reg &= ~__MY_PCMCIA_GCRX_CXRESET;       /* active high */
1681         reg &= ~__MY_PCMCIA_GCRX_CXOE;          /* active low  */
1682         PCMCIA_PGCRX(_slot_) = reg;
1683         udelay(500);
1684
1685         debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
1686                 slot+'A');
1687         return (0);
1688 }
1689
1690 static void cfg_ports (void)
1691 {
1692         volatile immap_t        *immap;
1693         volatile cpm8xx_t       *cp;
1694         ushort sreg;
1695
1696         immap = (immap_t *)CFG_IMMR;
1697         cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1698
1699         /*
1700          * Configure Port C for TPS2211 PC-Card Power-Interface Switch
1701          *
1702          * Switch off all voltages, assert shutdown
1703          */
1704         sreg = immap->im_ioport.iop_pcdat;
1705         sreg |=  (TPS2211_VPPD0 | TPS2211_VPPD1);       /* VAVPP => Hi-Z */
1706         sreg &= ~(TPS2211_VCCD0 | TPS2211_VCCD1);       /* 3V and 5V off */
1707         immap->im_ioport.iop_pcdat = sreg;
1708
1709         immap->im_ioport.iop_pcpar &= ~(TPS2211_OUTPUTS);
1710         immap->im_ioport.iop_pcdir |=   TPS2211_OUTPUTS;
1711
1712         debug ("Set Port C: PAR:     %04x DIR:     %04x DAT:     %04x\n",
1713                 immap->im_ioport.iop_pcpar,
1714                 immap->im_ioport.iop_pcdir,
1715                 immap->im_ioport.iop_pcdat);
1716
1717         /*
1718          * Configure Port B for TPS2211 PC-Card Power-Interface Switch
1719          *
1720          * Over-Current Input only
1721          */
1722         cp->cp_pbpar &= ~(TPS2211_INPUTS);
1723         cp->cp_pbdir &= ~(TPS2211_INPUTS);
1724
1725         debug ("Set Port B: PAR: %08x DIR: %08x DAT: %08x\n",
1726                 cp->cp_pbpar, cp->cp_pbdir, cp->cp_pbdat);
1727 }
1728
1729 #endif  /* C2MON */
1730
1731 /* -------------------------------------------------------------------- */
1732 /* MBX board from Morotola                                              */
1733 /* -------------------------------------------------------------------- */
1734
1735 #if defined( CONFIG_MBX )
1736 #include <../board/mbx8xx/csr.h>
1737
1738 /* A lot of this has been taken from the RPX code in this file it works from me.
1739    I have added the voltage selection for the MBX board. */
1740
1741 /* MBX voltage bit in control register #2 */
1742 #define CR2_VPP12       ((uchar)0x10)
1743 #define CR2_VPPVDD      ((uchar)0x20)
1744 #define CR2_VDD5        ((uchar)0x40)
1745 #define CR2_VDD3        ((uchar)0x80)
1746
1747 #define PCMCIA_BOARD_MSG "MBX860"
1748
1749 static int voltage_set (int slot, int vcc, int vpp)
1750 {
1751         uchar reg = 0;
1752
1753         debug ("voltage_set: PCMCIA_BOARD_MSG Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
1754                  'A' + slot, vcc / 10, vcc % 10, vpp / 10, vcc % 10);
1755
1756         switch (vcc) {
1757         case 0:
1758                 break;
1759         case 33:
1760                 reg |= CR2_VDD3;
1761                 break;
1762         case 50:
1763                 reg |= CR2_VDD5;
1764                 break;
1765         default:
1766                 return 1;
1767         }
1768
1769         switch (vpp) {
1770         case 0:
1771                 break;
1772         case 33:
1773         case 50:
1774                 if (vcc == vpp) {
1775                         reg |= CR2_VPPVDD;
1776                 } else {
1777                         return 1;
1778                 }
1779                 break;
1780         case 120:
1781                 reg |= CR2_VPP12;
1782                 break;
1783         default:
1784                 return 1;
1785         }
1786
1787         /* first, turn off all power */
1788         MBX_CSR2 &= ~(CR2_VDDSEL | CR2_VPPSEL);
1789
1790         /* enable new powersettings */
1791         MBX_CSR2 |= reg;
1792         debug ("MBX_CSR2 read = 0x%02x\n", MBX_CSR2);
1793
1794         return (0);
1795 }
1796
1797 static int hardware_enable (int slot)
1798 {
1799         volatile immap_t *immap;
1800         volatile cpm8xx_t *cp;
1801         volatile pcmconf8xx_t *pcmp;
1802         volatile sysconf8xx_t *sysp;
1803         uint reg, mask;
1804
1805         debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n",
1806                                   'A' + slot);
1807
1808         udelay (10000);
1809
1810         immap = (immap_t *) CFG_IMMR;
1811         sysp = (sysconf8xx_t *) (&(((immap_t *) CFG_IMMR)->im_siu_conf));
1812         pcmp = (pcmconf8xx_t *) (&(((immap_t *) CFG_IMMR)->im_pcmcia));
1813         cp = (cpm8xx_t *) (&(((immap_t *) CFG_IMMR)->im_cpm));
1814
1815         /* clear interrupt state, and disable interrupts */
1816         pcmp->pcmc_pscr = PCMCIA_MASK (_slot_);
1817         pcmp->pcmc_per &= ~PCMCIA_MASK (_slot_);
1818
1819         /*
1820          * Disable interrupts, DMA, and PCMCIA buffers
1821          * (isolate the interface) and assert RESET signal
1822          */
1823         debug ("Disable PCMCIA buffers and assert RESET\n");
1824         reg = 0;
1825         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
1826         reg |= __MY_PCMCIA_GCRX_CXOE;   /* active low  */
1827         PCMCIA_PGCRX (_slot_) = reg;
1828         udelay (500);
1829
1830         /* remove all power */
1831         voltage_set (slot, 0, 0);
1832         /*
1833          * Make sure there is a card in the slot, then configure the interface.
1834          */
1835         udelay(10000);
1836         debug ("[%d] %s: PIPR(%p)=0x%x\n",
1837                 __LINE__,__FUNCTION__,
1838                 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
1839 #ifndef CONFIG_BMS2003
1840         if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
1841 #else
1842         if (pcmp->pcmc_pipr & (0x10000000 >> (slot << 4))) {
1843 #endif  /* CONFIG_BMS2003 */
1844                 printf ("   No Card found\n");
1845                 return (1);
1846         }
1847
1848         /*
1849          * Power On.
1850          */
1851         mask = PCMCIA_VS1 (_slot_) | PCMCIA_VS2 (_slot_);
1852         reg = pcmp->pcmc_pipr;
1853         debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n", reg,
1854                   (reg & PCMCIA_VS1 (slot)) ? "n" : "ff",
1855                   (reg & PCMCIA_VS2 (slot)) ? "n" : "ff");
1856
1857         if ((reg & mask) == mask) {
1858                 voltage_set (_slot_, 50, 0);
1859                 printf (" 5.0V card found: ");
1860         } else {
1861                 voltage_set (_slot_, 33, 0);
1862                 printf (" 3.3V card found: ");
1863         }
1864
1865         debug ("Enable PCMCIA buffers and stop RESET\n");
1866         reg = PCMCIA_PGCRX (_slot_);
1867         reg &= ~__MY_PCMCIA_GCRX_CXRESET;       /* active high */
1868         reg &= ~__MY_PCMCIA_GCRX_CXOE;  /* active low  */
1869         PCMCIA_PGCRX (_slot_) = reg;
1870
1871         udelay (250000);        /* some cards need >150 ms to come up :-( */
1872
1873         debug ("# hardware_enable done\n");
1874
1875         return (0);
1876 }
1877
1878 #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
1879 static int hardware_disable (int slot)
1880 {
1881         return 0;       /* No hardware to disable */
1882 }
1883 #endif /* CFG_CMD_PCMCIA */
1884 #endif /* CONFIG_MBX */
1885 /* -------------------------------------------------------------------- */
1886 /* R360MPI Board                                                        */
1887 /* -------------------------------------------------------------------- */
1888
1889 #if defined(CONFIG_R360MPI)
1890
1891 #define PCMCIA_BOARD_MSG "R360MPI"
1892
1893
1894 static int hardware_enable(int slot)
1895 {
1896         volatile immap_t        *immap;
1897         volatile cpm8xx_t       *cp;
1898         volatile pcmconf8xx_t   *pcmp;
1899         volatile sysconf8xx_t   *sysp;
1900         uint reg, mask;
1901
1902         debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1903
1904         udelay(10000);
1905
1906         immap = (immap_t *)CFG_IMMR;
1907         sysp  = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
1908         pcmp  = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1909         cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1910
1911         /*
1912          * Configure SIUMCR to enable PCMCIA port B
1913          * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
1914          */
1915         sysp->sc_siumcr &= ~SIUMCR_DBGC11;      /* set DBGC to 00 */
1916
1917         /* clear interrupt state, and disable interrupts */
1918         pcmp->pcmc_pscr =  PCMCIA_MASK(_slot_);
1919         pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
1920
1921         /*
1922          * Disable interrupts, DMA, and PCMCIA buffers
1923          * (isolate the interface) and assert RESET signal
1924          */
1925         debug ("Disable PCMCIA buffers and assert RESET\n");
1926         reg  = 0;
1927         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
1928         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
1929         PCMCIA_PGCRX(_slot_) = reg;
1930         udelay(500);
1931
1932         /*
1933          * Configure Ports A, B & C pins for
1934          * 5 Volts Enable and 3 Volts enable
1935          */
1936         immap->im_ioport.iop_pcpar &= ~(0x0400);
1937         immap->im_ioport.iop_pcso  &= ~(0x0400);/*
1938         immap->im_ioport.iop_pcdir |= 0x0400;*/
1939
1940         immap->im_ioport.iop_papar &= ~(0x0200);/*
1941         immap->im_ioport.iop_padir |= 0x0200;*/
1942 #if 0
1943         immap->im_ioport.iop_pbpar &= ~(0xC000);
1944         immap->im_ioport.iop_pbdir &= ~(0xC000);
1945 #endif
1946         /* remove all power */
1947
1948         immap->im_ioport.iop_pcdat |= 0x0400;
1949         immap->im_ioport.iop_padat |= 0x0200;
1950
1951         /*
1952          * Make sure there is a card in the slot, then configure the interface.
1953          */
1954         udelay(10000);
1955         debug ("[%d] %s: PIPR(%p)=0x%x\n",
1956                 __LINE__,__FUNCTION__,
1957                 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
1958         if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
1959                 printf ("   No Card found\n");
1960                 return (1);
1961         }
1962
1963         /*
1964          * Power On.
1965          */
1966         mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
1967         reg  = pcmp->pcmc_pipr;
1968         debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
1969                 reg,
1970                 (reg&PCMCIA_VS1(slot))?"n":"ff",
1971                 (reg&PCMCIA_VS2(slot))?"n":"ff");
1972         if ((reg & mask) == mask) {
1973                 immap->im_ioport.iop_pcdat &= ~(0x4000);
1974                 puts (" 5.0V card found: ");
1975         } else {
1976                 immap->im_ioport.iop_padat &= ~(0x0002);
1977                 puts (" 3.3V card found: ");
1978         }
1979         immap->im_ioport.iop_pcdir |= 0x0400;
1980         immap->im_ioport.iop_padir |= 0x0200;
1981 #if 0
1982         /*  VCC switch error flag, PCMCIA slot INPACK_ pin */
1983         cp->cp_pbdir &= ~(0x0020 | 0x0010);
1984         cp->cp_pbpar &= ~(0x0020 | 0x0010);
1985         udelay(500000);
1986 #endif
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
1993         udelay(250000); /* some cards need >150 ms to come up :-( */
1994
1995         debug ("# hardware_enable done\n");
1996
1997         return (0);
1998 }
1999
2000
2001 #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
2002 static int hardware_disable(int slot)
2003 {
2004         volatile immap_t        *immap;
2005         volatile pcmconf8xx_t   *pcmp;
2006         u_long reg;
2007
2008         debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
2009
2010         immap = (immap_t *)CFG_IMMR;
2011         pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
2012
2013         /* remove all power */
2014         immap->im_ioport.iop_pcdat |= 0x0400;
2015         immap->im_ioport.iop_padat |= 0x0200;
2016
2017         /* Configure PCMCIA General Control Register */
2018         debug ("Disable PCMCIA buffers and assert RESET\n");
2019         reg  = 0;
2020         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
2021         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
2022         PCMCIA_PGCRX(_slot_) = reg;
2023
2024         udelay(10000);
2025
2026         return (0);
2027 }
2028 #endif  /* CFG_CMD_PCMCIA */
2029
2030
2031 static int voltage_set(int slot, int vcc, int vpp)
2032 {
2033         volatile immap_t        *immap;
2034         volatile pcmconf8xx_t   *pcmp;
2035         u_long reg;
2036
2037         debug ("voltage_set: "
2038                 PCMCIA_BOARD_MSG
2039                 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
2040                 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
2041
2042         immap = (immap_t *)CFG_IMMR;
2043         pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
2044         /*
2045          * Disable PCMCIA buffers (isolate the interface)
2046          * and assert RESET signal
2047          */
2048         debug ("Disable PCMCIA buffers and assert RESET\n");
2049         reg  = PCMCIA_PGCRX(_slot_);
2050         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
2051         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
2052         PCMCIA_PGCRX(_slot_) = reg;
2053         udelay(500);
2054
2055         /*
2056          * Configure Ports A & C pins for
2057          * 5 Volts Enable and 3 Volts enable,
2058          * Turn off all power
2059          */
2060         debug ("PCMCIA power OFF\n");
2061         immap->im_ioport.iop_pcpar &= ~(0x0400);
2062         immap->im_ioport.iop_pcso  &= ~(0x0400);/*
2063         immap->im_ioport.iop_pcdir |= 0x0400;*/
2064
2065         immap->im_ioport.iop_papar &= ~(0x0200);/*
2066         immap->im_ioport.iop_padir |= 0x0200;*/
2067
2068         immap->im_ioport.iop_pcdat |= 0x0400;
2069         immap->im_ioport.iop_padat |= 0x0200;
2070
2071         reg = 0;
2072         switch(vcc) {
2073         case  0:                break;
2074         case 33: reg |= 0x0200; break;
2075         case 50: reg |= 0x0400; break;
2076         default:                goto done;
2077         }
2078
2079         /* Checking supported voltages */
2080
2081         debug ("PIPR: 0x%x --> %s\n",
2082                 pcmp->pcmc_pipr,
2083                 (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
2084
2085         if (reg & 0x0200)
2086                 immap->im_ioport.iop_pcdat &= !reg;
2087         if (reg & 0x0400)
2088                 immap->im_ioport.iop_padat &= !reg;
2089         immap->im_ioport.iop_pcdir |= 0x0200;
2090         immap->im_ioport.iop_padir |= 0x0400;
2091         if (reg) {
2092                 debug ("PCMCIA powered at %sV\n",
2093                         (reg&0x0400) ? "5.0" : "3.3");
2094         } else {
2095                 debug ("PCMCIA powered down\n");
2096         }
2097
2098 done:
2099         debug ("Enable PCMCIA buffers and stop RESET\n");
2100         reg  =  PCMCIA_PGCRX(_slot_);
2101         reg &= ~__MY_PCMCIA_GCRX_CXRESET;       /* active high */
2102         reg &= ~__MY_PCMCIA_GCRX_CXOE;          /* active low  */
2103         PCMCIA_PGCRX(_slot_) = reg;
2104         udelay(500);
2105
2106         debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
2107                 slot+'A');
2108         return (0);
2109 }
2110
2111 #endif  /* R360MPI */
2112
2113 /* -------------------------------------------------------------------- */
2114 /* KUP4K Board                                                          */
2115 /* -------------------------------------------------------------------- */
2116 #if defined(CONFIG_KUP4K)
2117
2118 #define PCMCIA_BOARD_MSG "KUP4K"
2119
2120 #define KUP4K_PCMCIA_B_3V3 (0x00020000)
2121
2122 static int hardware_enable(int slot)
2123 {
2124         volatile immap_t        *immap;
2125         volatile cpm8xx_t       *cp;
2126         volatile pcmconf8xx_t   *pcmp;
2127         volatile sysconf8xx_t   *sysp;
2128         uint reg, mask;
2129
2130         debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
2131
2132         udelay(10000);
2133
2134         immap = (immap_t *)CFG_IMMR;
2135         sysp  = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
2136         pcmp  = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
2137         cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
2138
2139         /*
2140          * Configure SIUMCR to enable PCMCIA port B
2141          * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
2142          */
2143         sysp->sc_siumcr &= ~SIUMCR_DBGC11;      /* set DBGC to 00 */
2144
2145         /* clear interrupt state, and disable interrupts */
2146         pcmp->pcmc_pscr =  PCMCIA_MASK(slot);
2147         pcmp->pcmc_per &= ~PCMCIA_MASK(slot);
2148
2149         /*
2150          * Disable interrupts, DMA, and PCMCIA buffers
2151          * (isolate the interface) and assert RESET signal
2152          */
2153         debug ("Disable PCMCIA buffers and assert RESET\n");
2154         reg  = 0;
2155         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
2156         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
2157         PCMCIA_PGCRX(slot) = reg;
2158         udelay(2500);
2159
2160         /*
2161          * Configure Port B pins for
2162          * 3 Volts enable
2163          */
2164         if (slot) { /* Slot A is built-in */
2165                 cp->cp_pbdir |=  KUP4K_PCMCIA_B_3V3;
2166                 cp->cp_pbpar &= ~KUP4K_PCMCIA_B_3V3;
2167                 /* remove all power */
2168                 cp->cp_pbdat |=  KUP4K_PCMCIA_B_3V3; /* active low */
2169         }
2170         /*
2171          * Make sure there is a card in the slot, then configure the interface.
2172          */
2173         udelay(10000);
2174         debug ("[%d] %s: PIPR(%p)=0x%x\n",
2175                 __LINE__,__FUNCTION__,
2176                 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
2177         if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
2178                 printf ("   No Card found\n");
2179                 return (1);
2180         }
2181
2182         /*
2183          * Power On.
2184          */
2185         printf("%s  Slot %c:", slot ? "" : "\n", 'A' + slot);
2186         mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
2187         reg  = pcmp->pcmc_pipr;
2188         debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
2189                 reg,
2190                 (reg&PCMCIA_VS1(slot))?"n":"ff",
2191                 (reg&PCMCIA_VS2(slot))?"n":"ff");
2192         if ((reg & mask) == mask) {
2193                 puts (" 5.0V card found: NOT SUPPORTED !!!\n");
2194         } else {
2195                 if(slot)
2196                         cp->cp_pbdat &= ~KUP4K_PCMCIA_B_3V3;
2197                 puts (" 3.3V card found: ");
2198         }
2199 #if 0
2200         /*  VCC switch error flag, PCMCIA slot INPACK_ pin */
2201         cp->cp_pbdir &= ~(0x0020 | 0x0010);
2202         cp->cp_pbpar &= ~(0x0020 | 0x0010);
2203         udelay(500000);
2204 #endif
2205         debug ("Enable PCMCIA buffers and stop RESET\n");
2206         reg  =  PCMCIA_PGCRX(slot);
2207         reg &= ~__MY_PCMCIA_GCRX_CXRESET;       /* active high */
2208         reg &= ~__MY_PCMCIA_GCRX_CXOE;          /* active low  */
2209         PCMCIA_PGCRX(slot) = reg;
2210
2211         udelay(250000); /* some cards need >150 ms to come up :-( */
2212
2213         debug ("# hardware_enable done\n");
2214
2215         return (0);
2216 }
2217
2218
2219 #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
2220 static int hardware_disable(int slot)
2221 {
2222         volatile immap_t        *immap;
2223         volatile cpm8xx_t       *cp;
2224         volatile pcmconf8xx_t   *pcmp;
2225         u_long reg;
2226
2227         debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
2228
2229         immap = (immap_t *)CFG_IMMR;
2230         pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
2231         cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
2232
2233         /* remove all power */
2234         if (slot)
2235                 cp->cp_pbdat |= KUP4K_PCMCIA_B_3V3;
2236
2237         /* Configure PCMCIA General Control Register */
2238         debug ("Disable PCMCIA buffers and assert RESET\n");
2239         reg  = 0;
2240         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
2241         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
2242         PCMCIA_PGCRX(slot) = reg;
2243
2244         udelay(10000);
2245
2246         return (0);
2247 }
2248 #endif  /* CFG_CMD_PCMCIA */
2249
2250
2251 static int voltage_set(int slot, int vcc, int vpp)
2252 {
2253         volatile immap_t        *immap;
2254         volatile cpm8xx_t       *cp;
2255         volatile pcmconf8xx_t   *pcmp;
2256         u_long reg;
2257
2258         debug ("voltage_set: "  \
2259                 PCMCIA_BOARD_MSG        \
2260                 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
2261                 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
2262
2263         if (!slot) /* Slot A is not configurable */
2264                 return 0;
2265
2266         immap = (immap_t *)CFG_IMMR;
2267         pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
2268         cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
2269
2270         /*
2271          * Disable PCMCIA buffers (isolate the interface)
2272          * and assert RESET signal
2273          */
2274         debug ("Disable PCMCIA buffers and assert RESET\n");
2275         reg  = PCMCIA_PGCRX(slot);
2276         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
2277         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
2278         PCMCIA_PGCRX(slot) = reg;
2279         udelay(500);
2280
2281         debug ("PCMCIA power OFF\n");
2282         /*
2283          * Configure Port B pins for
2284          * 3 Volts enable
2285          */
2286         cp->cp_pbdir |=  KUP4K_PCMCIA_B_3V3;
2287         cp->cp_pbpar &= ~KUP4K_PCMCIA_B_3V3;
2288         /* remove all power */
2289         cp->cp_pbdat |=  KUP4K_PCMCIA_B_3V3; /* active low */
2290
2291         switch(vcc) {
2292         case  0:                break;
2293         case 33:
2294                 cp->cp_pbdat &= ~KUP4K_PCMCIA_B_3V3;
2295                 debug ("PCMCIA powered at 3.3V\n");
2296                 break;
2297         case 50:
2298                 debug ("PCMCIA: 5Volt vcc not supported\n");
2299                 break;
2300         default:
2301                 puts("PCMCIA: vcc not supported");
2302                 break;
2303         }
2304         udelay(10000);
2305         /* Checking supported voltages */
2306
2307         debug ("PIPR: 0x%x --> %s\n",
2308                 pcmp->pcmc_pipr,
2309                    (pcmp->pcmc_pipr & (0x80000000 >> (slot << 4)))
2310                         ? "only 5 V --> NOT SUPPORTED"
2311                         : "can do 3.3V");
2312
2313
2314         debug ("Enable PCMCIA buffers and stop RESET\n");
2315         reg  =  PCMCIA_PGCRX(slot);
2316         reg &= ~__MY_PCMCIA_GCRX_CXRESET;       /* active high */
2317         reg &= ~__MY_PCMCIA_GCRX_CXOE;          /* active low  */
2318         PCMCIA_PGCRX(slot) = reg;
2319         udelay(500);
2320
2321         debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
2322                 slot+'A');
2323         return (0);
2324 }
2325
2326 #endif  /* KUP4K */
2327
2328
2329 /* -------------------------------------------------------------------- */
2330 /* End of Board Specific Stuff                                          */
2331 /* -------------------------------------------------------------------- */
2332
2333
2334 /* -------------------------------------------------------------------- */
2335 /* MPC8xx Specific Stuff - should go to MPC8xx directory                */
2336 /* -------------------------------------------------------------------- */
2337
2338 /*
2339  * Search this table to see if the windowsize is
2340  * supported...
2341  */
2342
2343 #define M8XX_SIZES_NO 32
2344
2345 static const u_int m8xx_size_to_gray[M8XX_SIZES_NO] =
2346 { 0x00000001, 0x00000002, 0x00000008, 0x00000004,
2347   0x00000080, 0x00000040, 0x00000010, 0x00000020,
2348   0x00008000, 0x00004000, 0x00001000, 0x00002000,
2349   0x00000100, 0x00000200, 0x00000800, 0x00000400,
2350
2351   0x0fffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2352   0x01000000, 0x02000000, 0xffffffff, 0x04000000,
2353   0x00010000, 0x00020000, 0x00080000, 0x00040000,
2354   0x00800000, 0x00400000, 0x00100000, 0x00200000 };
2355
2356
2357 /* -------------------------------------------------------------------- */
2358
2359 #ifndef CONFIG_I82365
2360
2361 static u_int m8xx_get_graycode(u_int size)
2362 {
2363         u_int k;
2364
2365         for (k = 0; k < M8XX_SIZES_NO; k++) {
2366                 if(m8xx_size_to_gray[k] == size)
2367                         break;
2368         }
2369
2370         if((k == M8XX_SIZES_NO) || (m8xx_size_to_gray[k] == -1))
2371                 k = -1;
2372
2373         return k;
2374 }
2375
2376 #endif  /* CONFIG_I82365 */
2377
2378 /* -------------------------------------------------------------------- */
2379
2380 #if 0
2381 static u_int m8xx_get_speed(u_int ns, u_int is_io)
2382 {
2383         u_int reg, clocks, psst, psl, psht;
2384
2385         if(!ns) {
2386
2387                 /*
2388                  * We get called with IO maps setup to 0ns
2389                  * if not specified by the user.
2390                  * They should be 255ns.
2391                  */
2392
2393                 if(is_io)
2394                         ns = 255;
2395                 else
2396                         ns = 100;  /* fast memory if 0 */
2397         }
2398
2399         /*
2400          * In PSST, PSL, PSHT fields we tell the controller
2401          * timing parameters in CLKOUT clock cycles.
2402          * CLKOUT is the same as GCLK2_50.
2403          */
2404
2405 /* how we want to adjust the timing - in percent */
2406
2407 #define ADJ 180 /* 80 % longer accesstime - to be sure */
2408
2409         clocks = ((M8XX_BUSFREQ / 1000) * ns) / 1000;
2410         clocks = (clocks * ADJ) / (100*1000);
2411
2412         if(clocks >= PCMCIA_BMT_LIMIT) {
2413                 DEBUG(0, "Max access time limit reached\n");
2414                 clocks = PCMCIA_BMT_LIMIT-1;
2415         }
2416
2417         psst = clocks / 7;          /* setup time */
2418         psht = clocks / 7;          /* hold time */
2419         psl  = (clocks * 5) / 7;    /* strobe length */
2420
2421         psst += clocks - (psst + psht + psl);
2422
2423         reg =  psst << 12;
2424         reg |= psl  << 7;
2425         reg |= psht << 16;
2426
2427         return reg;
2428 }
2429 #endif
2430
2431 /* -------------------------------------------------------------------- */
2432
2433 #ifdef CONFIG_IDE_8xx_PCCARD
2434 static void print_funcid (int func)
2435 {
2436         puts (indent);
2437         switch (func) {
2438         case CISTPL_FUNCID_MULTI:
2439                 puts (" Multi-Function");
2440                 break;
2441         case CISTPL_FUNCID_MEMORY:
2442                 puts (" Memory");
2443                 break;
2444         case CISTPL_FUNCID_SERIAL:
2445                 puts (" Serial Port");
2446                 break;
2447         case CISTPL_FUNCID_PARALLEL:
2448                 puts (" Parallel Port");
2449                 break;
2450         case CISTPL_FUNCID_FIXED:
2451                 puts (" Fixed Disk");
2452                 break;
2453         case CISTPL_FUNCID_VIDEO:
2454                 puts (" Video Adapter");
2455                 break;
2456         case CISTPL_FUNCID_NETWORK:
2457                 puts (" Network Adapter");
2458                 break;
2459         case CISTPL_FUNCID_AIMS:
2460                 puts (" AIMS Card");
2461                 break;
2462         case CISTPL_FUNCID_SCSI:
2463                 puts (" SCSI Adapter");
2464                 break;
2465         default:
2466                 puts (" Unknown");
2467                 break;
2468         }
2469         puts (" Card\n");
2470 }
2471 #endif  /* CONFIG_IDE_8xx_PCCARD */
2472
2473 /* -------------------------------------------------------------------- */
2474
2475 #ifdef CONFIG_IDE_8xx_PCCARD
2476 static void print_fixed (volatile uchar *p)
2477 {
2478         if (p == NULL)
2479                 return;
2480
2481         puts(indent);
2482
2483         switch (*p) {
2484         case CISTPL_FUNCE_IDE_IFACE:
2485             {   uchar iface = *(p+2);
2486
2487                 puts ((iface == CISTPL_IDE_INTERFACE) ? " IDE" : " unknown");
2488                 puts (" interface ");
2489                 break;
2490             }
2491         case CISTPL_FUNCE_IDE_MASTER:
2492         case CISTPL_FUNCE_IDE_SLAVE:
2493             {   uchar f1 = *(p+2);
2494                 uchar f2 = *(p+4);
2495
2496                 puts ((f1 & CISTPL_IDE_SILICON) ? " [silicon]" : " [rotating]");
2497
2498                 if (f1 & CISTPL_IDE_UNIQUE)
2499                         puts (" [unique]");
2500
2501                 puts ((f1 & CISTPL_IDE_DUAL) ? " [dual]" : " [single]");
2502
2503                 if (f2 & CISTPL_IDE_HAS_SLEEP)
2504                         puts (" [sleep]");
2505
2506                 if (f2 & CISTPL_IDE_HAS_STANDBY)
2507                         puts (" [standby]");
2508
2509                 if (f2 & CISTPL_IDE_HAS_IDLE)
2510                         puts (" [idle]");
2511
2512                 if (f2 & CISTPL_IDE_LOW_POWER)
2513                         puts (" [low power]");
2514
2515                 if (f2 & CISTPL_IDE_REG_INHIBIT)
2516                         puts (" [reg inhibit]");
2517
2518                 if (f2 & CISTPL_IDE_HAS_INDEX)
2519                         puts (" [index]");
2520
2521                 if (f2 & CISTPL_IDE_IOIS16)
2522                         puts (" [IOis16]");
2523
2524                 break;
2525             }
2526         }
2527         putc ('\n');
2528 }
2529 #endif  /* CONFIG_IDE_8xx_PCCARD */
2530
2531 /* -------------------------------------------------------------------- */
2532
2533 #ifdef CONFIG_IDE_8xx_PCCARD
2534
2535 #define MAX_IDENT_CHARS         64
2536 #define MAX_IDENT_FIELDS        4
2537
2538 static uchar *known_cards[] = {
2539         "ARGOSY PnPIDE D5",
2540         NULL
2541 };
2542
2543 static int identify  (volatile uchar *p)
2544 {
2545         uchar id_str[MAX_IDENT_CHARS];
2546         uchar data;
2547         uchar *t;
2548         uchar **card;
2549         int i, done;
2550
2551         if (p == NULL)
2552                 return (0);     /* Don't know */
2553
2554         t = id_str;
2555         done =0;
2556
2557         for (i=0; i<=4 && !done; ++i, p+=2) {
2558                 while ((data = *p) != '\0') {
2559                         if (data == 0xFF) {
2560                                 done = 1;
2561                                 break;
2562                         }
2563                         *t++ = data;
2564                         if (t == &id_str[MAX_IDENT_CHARS-1]) {
2565                                 done = 1;
2566                                 break;
2567                         }
2568                         p += 2;
2569                 }
2570                 if (!done)
2571                         *t++ = ' ';
2572         }
2573         *t = '\0';
2574         while (--t > id_str) {
2575                 if (*t == ' ')
2576                         *t = '\0';
2577                 else
2578                         break;
2579         }
2580         puts (id_str);
2581         putc ('\n');
2582
2583         for (card=known_cards; *card; ++card) {
2584                 debug ("## Compare against \"%s\"\n", *card);
2585                 if (strcmp(*card, id_str) == 0) {       /* found! */
2586                         debug ("## CARD FOUND ##\n");
2587                         return (1);
2588                 }
2589         }
2590
2591         return (0);     /* don't know */
2592 }
2593 #endif  /* CONFIG_IDE_8xx_PCCARD */
2594
2595 /* -------------------------------------------------------------------- */
2596
2597 #endif /* CFG_CMD_PCMCIA || (CFG_CMD_IDE && CONFIG_IDE_8xx_PCCARD) */
2598
2599 /**************************************************/
2600
2601 #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
2602 U_BOOT_CMD(
2603         pinit,  2,      1,      do_pinit,
2604         "pinit   - PCMCIA sub-system\n",
2605         "on  - power on PCMCIA socket\n"
2606         "pinit off - power off PCMCIA socket\n"
2607 );
2608 #endif