* Patch by Yuli Barcohen, 08 Nov 2004:
[platform/kernel/u-boot.git] / common / cmd_pcmcia.c
1 /*
2  * (C) Copyright 2000-2004
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 #ifdef CONFIG_PXA_PCMCIA
67 #include <asm/arch/pxa-regs.h>
68 #endif
69
70 #include <asm/io.h>
71
72 #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA) || \
73     ((CONFIG_COMMANDS & CFG_CMD_IDE) && defined(CONFIG_IDE_8xx_PCCARD))
74
75 int pcmcia_on (void);
76
77 #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
78 static int  pcmcia_off (void);
79 #endif
80
81 #ifdef CONFIG_I82365
82
83 extern int i82365_init (void);
84 extern void i82365_exit (void);
85
86 #else /* ! CONFIG_I82365 */
87
88 #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
89 static int  hardware_disable(int slot);
90 #endif
91 static int  hardware_enable (int slot);
92 static int  voltage_set(int slot, int vcc, int vpp);
93
94 #if (! defined(CONFIG_I82365)) && (! defined(CONFIG_PXA_PCMCIA))
95 static u_int m8xx_get_graycode(u_int size);
96 #endif  /* !CONFIG_I82365, !CONFIG_PXA_PCMCIA */
97 #if 0
98 static u_int m8xx_get_speed(u_int ns, u_int is_io);
99 #endif
100
101 /* -------------------------------------------------------------------- */
102
103 #ifndef CONFIG_PXA_PCMCIA
104
105 /* look up table for pgcrx registers */
106
107 static u_int *pcmcia_pgcrx[2] = {
108         &((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_pgcra,
109         &((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_pgcrb,
110 };
111 #define PCMCIA_PGCRX(slot)      (*pcmcia_pgcrx[slot])
112
113 #endif  /* CONFIG_PXA_PCMCIA */
114
115 #endif /* CONFIG_I82365 */
116
117 #if defined(CONFIG_IDE_8xx_PCCARD)  || defined(CONFIG_PXA_PCMCIA)
118 static void print_funcid (int func);
119 static void print_fixed  (volatile uchar *p);
120 static int  identify     (volatile uchar *p);
121 static int  check_ide_device (int slot);
122 #endif  /* CONFIG_IDE_8xx_PCCARD, CONFIG_PXA_PCMCIA */
123
124 const char *indent = "\t   ";
125
126 /* -------------------------------------------------------------------- */
127
128 #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
129
130 int do_pinit (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
131 {
132         int rcode = 0;
133
134         if (argc != 2) {
135                 printf ("Usage: pinit {on | off}\n");
136                 return 1;
137         }
138         if (strcmp(argv[1],"on") == 0) {
139                 rcode = pcmcia_on ();
140         } else if (strcmp(argv[1],"off") == 0) {
141                 rcode = pcmcia_off ();
142         } else {
143                 printf ("Usage: pinit {on | off}\n");
144                 return 1;
145         }
146
147         return rcode;
148 }
149 #endif  /* CFG_CMD_PCMCIA */
150
151 /* -------------------------------------------------------------------- */
152
153 #ifdef CONFIG_I82365
154 int pcmcia_on (void)
155 {
156         u_int rc;
157
158         debug ("Enable PCMCIA " PCMCIA_SLOT_MSG "\n");
159
160         rc = i82365_init();
161
162         if (rc == 0) {
163                 rc = check_ide_device(0);
164         }
165
166         return (rc);
167 }
168 #else
169
170 #ifndef CONFIG_PXA_PCMCIA
171
172 #ifdef CONFIG_HMI10
173 # define  HMI10_FRAM_TIMING     (PCMCIA_SHT(2) | PCMCIA_SST(2) | PCMCIA_SL(4))
174 #endif
175 #if defined(CONFIG_LWMON) || defined(CONFIG_NSCU)
176 # define  CFG_PCMCIA_TIMING     (PCMCIA_SHT(9) | PCMCIA_SST(3) | PCMCIA_SL(12))
177 #else
178 # define  CFG_PCMCIA_TIMING     (PCMCIA_SHT(2) | PCMCIA_SST(4) | PCMCIA_SL(9))
179 #endif
180
181 int pcmcia_on (void)
182 {
183         int i;
184         u_long reg, base;
185         pcmcia_win_t *win;
186         u_int slotbit;
187         u_int rc, slot;
188
189         debug ("Enable PCMCIA " PCMCIA_SLOT_MSG "\n");
190
191         /* intialize the fixed memory windows */
192         win = (pcmcia_win_t *)(&((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_pbr0);
193         base = CFG_PCMCIA_MEM_ADDR;
194
195         if((reg = m8xx_get_graycode(CFG_PCMCIA_MEM_SIZE)) == -1) {
196                 printf ("Cannot set window size to 0x%08x\n",
197                         CFG_PCMCIA_MEM_SIZE);
198                 return (1);
199         }
200
201         slotbit = PCMCIA_SLOT_x;
202         for (i=0; i<PCMCIA_MEM_WIN_NO; ++i) {
203                 win->br = base;
204
205 #if (PCMCIA_SOCKETS_NO == 2)
206                 if (i == 4) /* Another slot starting from win 4 */
207                         slotbit = (slotbit ? PCMCIA_PSLOT_A : PCMCIA_PSLOT_B);
208 #endif
209                 switch (i) {
210 #ifdef CONFIG_IDE_8xx_PCCARD
211                 case 4:
212 #ifdef CONFIG_HMI10
213                     {   /* map FRAM area */
214                         win->or = (     PCMCIA_BSIZE_256K
215                                 |       PCMCIA_PPS_8
216                                 |       PCMCIA_PRS_ATTR
217                                 |       slotbit
218                                 |       PCMCIA_PV
219                                 |       HMI10_FRAM_TIMING );
220                         break;
221                     }
222 #endif
223                 case 0: {       /* map attribute memory */
224                         win->or = (     PCMCIA_BSIZE_64M
225                                 |       PCMCIA_PPS_8
226                                 |       PCMCIA_PRS_ATTR
227                                 |       slotbit
228                                 |       PCMCIA_PV
229                                 |       CFG_PCMCIA_TIMING );
230                         break;
231                     }
232                 case 5:
233                 case 1: {       /* map I/O window for data reg */
234                         win->or = (     PCMCIA_BSIZE_1K
235                                 |       PCMCIA_PPS_16
236                                 |       PCMCIA_PRS_IO
237                                 |       slotbit
238                                 |       PCMCIA_PV
239                                 |       CFG_PCMCIA_TIMING );
240                         break;
241                     }
242                 case 6:
243                 case 2: {       /* map I/O window for cmd/ctrl reg block */
244                         win->or = (     PCMCIA_BSIZE_1K
245                                 |       PCMCIA_PPS_8
246                                 |       PCMCIA_PRS_IO
247                                 |       slotbit
248                                 |       PCMCIA_PV
249                                 |       CFG_PCMCIA_TIMING );
250                         break;
251                     }
252 #endif  /* CONFIG_IDE_8xx_PCCARD */
253 #ifdef CONFIG_HMI10
254                 case 3: {       /* map I/O window for 4xUART data/ctrl */
255                         win->br += 0x40000;
256                         win->or = (     PCMCIA_BSIZE_256K
257                                 |       PCMCIA_PPS_8
258                                 |       PCMCIA_PRS_IO
259                                 |       slotbit
260                                 |       PCMCIA_PV
261                                 |       CFG_PCMCIA_TIMING );
262                         break;
263                     }
264 #endif /* CONFIG_HMI10 */
265                 default:        /* set to not valid */
266                         win->or = 0;
267                         break;
268                 }
269
270                 debug ("MemWin %d: PBR 0x%08lX  POR %08lX\n",
271                         i, win->br, win->or);
272                 base += CFG_PCMCIA_MEM_SIZE;
273                 ++win;
274         }
275
276         for (i=0, rc=0, slot=_slot_; i<PCMCIA_SOCKETS_NO; i++, slot = !slot) {
277                 /* turn off voltage */
278                 if ((rc = voltage_set(slot, 0, 0)))
279                         continue;
280
281                 /* Enable external hardware */
282                 if ((rc = hardware_enable(slot)))
283                         continue;
284
285 #ifdef CONFIG_IDE_8xx_PCCARD
286                 if ((rc = check_ide_device(i)))
287                         continue;
288 #endif
289         }
290         return (rc);
291 }
292
293 #endif /* CONFIG_PXA_PCMCIA */
294
295 #endif /* CONFIG_I82365 */
296
297 #ifdef CONFIG_PXA_PCMCIA
298
299 static int hardware_enable (int slot)
300 {
301         return 0;       /* No hardware to enable */
302 }
303
304 static int hardware_disable(int slot)
305 {
306         return 0;       /* No hardware to disable */
307 }
308
309 static int voltage_set(int slot, int vcc, int vpp)
310 {
311         return 0;
312 }
313
314 void msWait(unsigned msVal)
315 {
316         udelay(msVal*1000);
317 }
318
319 int pcmcia_on (void)
320 {
321         unsigned int reg_arr[] = {
322                 0x48000028, CFG_MCMEM0_VAL,
323                 0x4800002c, CFG_MCMEM1_VAL,
324                 0x48000030, CFG_MCATT0_VAL,
325                 0x48000034, CFG_MCATT1_VAL,
326                 0x48000038, CFG_MCIO0_VAL,
327                 0x4800003c, CFG_MCIO1_VAL,
328
329                 0, 0
330         };
331         int i, rc;
332
333 #ifdef CONFIG_EXADRON1
334         int cardDetect;
335         volatile unsigned int *v_pBCRReg =
336                 (volatile unsigned int *) 0x08000000;
337 #endif
338
339         debug ("%s\n", __FUNCTION__);
340
341         i = 0;
342         while (reg_arr[i])
343                 *((volatile unsigned int *) reg_arr[i++]) |= reg_arr[i++];
344         udelay (1000);
345
346         debug ("%s: programmed mem controller \n", __FUNCTION__);
347
348 #ifdef CONFIG_EXADRON1
349
350 /*define useful BCR masks */
351 #define BCR_CF_INIT_VAL                     0x00007230
352 #define BCR_CF_PWRON_BUSOFF_RESETOFF_VAL    0x00007231
353 #define BCR_CF_PWRON_BUSOFF_RESETON_VAL     0x00007233
354 #define BCR_CF_PWRON_BUSON_RESETON_VAL      0x00007213
355 #define BCR_CF_PWRON_BUSON_RESETOFF_VAL     0x00007211
356
357         /* we see from the GPIO bit if the card is present */
358         cardDetect = !(GPLR0 & GPIO_bit (14));
359
360         if (cardDetect) {
361                 printf ("No PCMCIA card found!\n");
362         }
363
364         /* reset the card via the BCR line */
365         *v_pBCRReg = (unsigned) BCR_CF_INIT_VAL;
366         msWait (500);
367
368         *v_pBCRReg = (unsigned) BCR_CF_PWRON_BUSOFF_RESETOFF_VAL;
369         msWait (500);
370
371         *v_pBCRReg = (unsigned) BCR_CF_PWRON_BUSOFF_RESETON_VAL;
372         msWait (500);
373
374         *v_pBCRReg = (unsigned) BCR_CF_PWRON_BUSON_RESETON_VAL;
375         msWait (500);
376
377         *v_pBCRReg = (unsigned) BCR_CF_PWRON_BUSON_RESETOFF_VAL;
378         msWait (1500);
379
380         /* enable address bus */
381         GPCR1 = 0x01;
382         /* and the first CF slot */
383         MECR = 0x00000002;
384
385 #endif /* EXADRON 1 */
386
387         rc = check_ide_device (0);      /* use just slot 0 */
388
389         return rc;
390 }
391
392 #endif /* CONFIG_PXA_PCMCIA */
393
394 /* -------------------------------------------------------------------- */
395
396 #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
397
398 #ifdef CONFIG_I82365
399 static int pcmcia_off (void)
400 {
401         printf ("Disable PCMCIA " PCMCIA_SLOT_MSG "\n");
402
403         i82365_exit();
404
405         return 0;
406 }
407 #else
408
409 #ifndef CONFIG_PXA_PCMCIA
410
411 static int pcmcia_off (void)
412 {
413         int i;
414         pcmcia_win_t *win;
415
416         printf ("Disable PCMCIA " PCMCIA_SLOT_MSG "\n");
417
418         /* clear interrupt state, and disable interrupts */
419         ((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_pscr =  PCMCIA_MASK(_slot_);
420         ((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_per &= ~PCMCIA_MASK(_slot_);
421
422         /* turn off interrupt and disable CxOE */
423         PCMCIA_PGCRX(_slot_) = __MY_PCMCIA_GCRX_CXOE;
424
425         /* turn off memory windows */
426         win = (pcmcia_win_t *)(&((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_pbr0);
427
428         for (i=0; i<PCMCIA_MEM_WIN_NO; ++i) {
429                 /* disable memory window */
430                 win->or = 0;
431                 ++win;
432         }
433
434         /* turn off voltage */
435         voltage_set(_slot_, 0, 0);
436
437         /* disable external hardware */
438         printf ("Shutdown and Poweroff " PCMCIA_SLOT_MSG "\n");
439         hardware_disable(_slot_);
440         return 0;
441 }
442
443 #endif /* CONFIG_PXA_PCMCIA */
444
445 #endif /* CONFIG_I82365 */
446
447 #ifdef CONFIG_PXA_PCMCIA
448 static int pcmcia_off (void)
449 {
450         return 0;
451 }
452 #endif
453
454 #endif  /* CFG_CMD_PCMCIA */
455
456 /* -------------------------------------------------------------------- */
457
458 #if defined(CONFIG_IDE_8xx_PCCARD) || defined(CONFIG_PXA_PCMCIA)
459
460 #define MAX_TUPEL_SZ    512
461 #define MAX_FEATURES    4
462
463 int ide_devices_found;
464 static int check_ide_device (int slot)
465 {
466         volatile uchar *ident = NULL;
467         volatile uchar *feature_p[MAX_FEATURES];
468         volatile uchar *p, *start, *addr;
469         int n_features = 0;
470         uchar func_id = ~0;
471         uchar code, len;
472         ushort config_base = 0;
473         int found = 0;
474         int i;
475
476         addr = (volatile uchar *)(CFG_PCMCIA_MEM_ADDR +
477                                   CFG_PCMCIA_MEM_SIZE * (slot * 4));
478         debug ("PCMCIA MEM: %08lX\n", (ulong)addr);
479
480         start = p = (volatile uchar *) addr;
481
482         while ((p - start) < MAX_TUPEL_SZ) {
483
484                 code = *p; p += 2;
485
486                 if (code == 0xFF) { /* End of chain */
487                         break;
488                 }
489
490                 len = *p; p += 2;
491 #if defined(DEBUG) && (DEBUG > 1)
492                 { volatile uchar *q = p;
493                         printf ("\nTuple code %02x  length %d\n\tData:",
494                                 code, len);
495
496                         for (i = 0; i < len; ++i) {
497                                 printf (" %02x", *q);
498                                 q+= 2;
499                         }
500                 }
501 #endif  /* DEBUG */
502                 switch (code) {
503                 case CISTPL_VERS_1:
504                         ident = p + 4;
505                         break;
506                 case CISTPL_FUNCID:
507                         /* Fix for broken SanDisk which may have 0x80 bit set */
508                         func_id = *p & 0x7F;
509                         break;
510                 case CISTPL_FUNCE:
511                         if (n_features < MAX_FEATURES)
512                                 feature_p[n_features++] = p;
513                         break;
514                 case CISTPL_CONFIG:
515                         config_base = (*(p+6) << 8) + (*(p+4));
516                         debug ("\n## Config_base = %04x ###\n", config_base);
517                 default:
518                         break;
519                 }
520                 p += 2 * len;
521         }
522
523         found = identify (ident);
524
525         if (func_id != ((uchar)~0)) {
526                 print_funcid (func_id);
527
528                 if (func_id == CISTPL_FUNCID_FIXED)
529                         found = 1;
530                 else
531                         return (1);     /* no disk drive */
532         }
533
534         for (i=0; i<n_features; ++i) {
535                 print_fixed (feature_p[i]);
536         }
537
538         if (!found) {
539                 printf ("unknown card type\n");
540                 return (1);
541         }
542
543         ide_devices_found |= (1 << slot);
544
545 #if CONFIG_CPC45
546 #else
547         /* set I/O area in config reg -> only valid for ARGOSY D5!!! */
548         *((uchar *)(addr + config_base)) = 1;
549 #endif
550 #if 0
551         printf("\n## Config_base = %04x ###\n", config_base);
552         printf("Configuration Option Register: %02x @ %x\n", readb(addr + config_base), addr + config_base);
553         printf("Card Configuration and Status Register: %02x\n", readb(addr + config_base + 2));
554         printf("Pin Replacement Register Register: %02x\n", readb(addr + config_base + 4));
555         printf("Socket and Copy Register: %02x\n", readb(addr + config_base + 6));
556 #endif
557         return (0);
558 }
559 #endif  /* CONFIG_IDE_8xx_PCCARD */
560
561 /* -------------------------------------------------------------------- */
562
563
564 /* -------------------------------------------------------------------- */
565 /* board specific stuff:                                                */
566 /* voltage_set(), hardware_enable() and hardware_disable()              */
567 /* -------------------------------------------------------------------- */
568
569 /* -------------------------------------------------------------------- */
570 /* RPX Boards from Embedded Planet                                      */
571 /* -------------------------------------------------------------------- */
572
573 #if defined(CONFIG_RPXCLASSIC) || defined(CONFIG_RPXLITE)
574
575 /* The RPX boards seems to have it's bus monitor timeout set to 6*8 clocks.
576  * SYPCR is write once only, therefore must the slowest memory be faster
577  * than the bus monitor or we will get a machine check due to the bus timeout.
578  */
579
580 #define PCMCIA_BOARD_MSG "RPX CLASSIC or RPX LITE"
581
582 #undef PCMCIA_BMT_LIMIT
583 #define PCMCIA_BMT_LIMIT (6*8)
584
585 static int voltage_set(int slot, int vcc, int vpp)
586 {
587         u_long reg = 0;
588
589         switch(vcc) {
590         case 0: break;
591         case 33: reg |= BCSR1_PCVCTL4; break;
592         case 50: reg |= BCSR1_PCVCTL5; break;
593         default: return 1;
594         }
595
596         switch(vpp) {
597         case 0: break;
598         case 33:
599         case 50:
600                 if(vcc == vpp)
601                         reg |= BCSR1_PCVCTL6;
602                 else
603                         return 1;
604                 break;
605         case 120:
606                 reg |= BCSR1_PCVCTL7;
607         default: return 1;
608         }
609
610         if(vcc == 120)
611            return 1;
612
613         /* first, turn off all power */
614
615         *((uint *)RPX_CSR_ADDR) &= ~(BCSR1_PCVCTL4 | BCSR1_PCVCTL5
616                                      | BCSR1_PCVCTL6 | BCSR1_PCVCTL7);
617
618         /* enable new powersettings */
619
620         *((uint *)RPX_CSR_ADDR) |= reg;
621
622         return 0;
623 }
624
625 #define socket_get(_slot_) PCMCIA_SOCKET_KEY_5V
626 static int hardware_enable (int slot)
627 {
628         return 0;       /* No hardware to enable */
629 }
630 #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
631 static int hardware_disable(int slot)
632 {
633         return 0;       /* No hardware to disable */
634 }
635 #endif  /* CFG_CMD_PCMCIA */
636 #endif  /* CONFIG_RPXCLASSIC */
637
638 /* -------------------------------------------------------------------- */
639 /* (F)ADS Boards from Motorola                                          */
640 /* -------------------------------------------------------------------- */
641
642 #if defined(CONFIG_ADS) || defined(CONFIG_FADS)
643
644 #ifdef CONFIG_ADS
645 #define PCMCIA_BOARD_MSG "ADS"
646 #define PCMCIA_GLITCHY_CD  /* My ADS board needs this */
647 #else
648 #define PCMCIA_BOARD_MSG "FADS"
649 #endif
650
651 static int voltage_set(int slot, int vcc, int vpp)
652 {
653         u_long reg = 0;
654
655         switch(vpp) {
656         case 0: reg = 0; break;
657         case 50: reg = 1; break;
658         case 120: reg = 2; break;
659         default: return 1;
660         }
661
662         switch(vcc) {
663         case 0: reg = 0; break;
664 #ifdef CONFIG_ADS
665         case 50: reg = BCSR1_PCCVCCON; break;
666 #endif
667 #ifdef CONFIG_FADS
668         case 33: reg = BCSR1_PCCVCC0 | BCSR1_PCCVCC1; break;
669         case 50: reg = BCSR1_PCCVCC1; break;
670 #endif
671         default: return 1;
672         }
673
674         /* first, turn off all power */
675
676 #ifdef CONFIG_ADS
677         *((uint *)BCSR1) |= BCSR1_PCCVCCON;
678 #endif
679 #ifdef CONFIG_FADS
680         *((uint *)BCSR1) &= ~(BCSR1_PCCVCC0 | BCSR1_PCCVCC1);
681 #endif
682         *((uint *)BCSR1) &= ~BCSR1_PCCVPP_MASK;
683
684         /* enable new powersettings */
685
686 #ifdef CONFIG_ADS
687         *((uint *)BCSR1) &= ~reg;
688 #endif
689 #ifdef CONFIG_FADS
690         *((uint *)BCSR1) |= reg;
691 #endif
692
693         *((uint *)BCSR1) |= reg << 20;
694
695         return 0;
696 }
697
698 #define socket_get(_slot_) PCMCIA_SOCKET_KEY_5V
699
700 static int hardware_enable(int slot)
701 {
702         *((uint *)BCSR1) &= ~BCSR1_PCCEN;
703         return 0;
704 }
705
706 #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
707 static int hardware_disable(int slot)
708 {
709         *((uint *)BCSR1) &= ~BCSR1_PCCEN;
710         return 0;
711 }
712 #endif  /* CFG_CMD_PCMCIA */
713
714 #endif  /* (F)ADS */
715
716 /* -------------------------------------------------------------------- */
717 /* TQM8xxL Boards by TQ Components                                      */
718 /* SC8xx   Boards by SinoVee Microsystems                               */
719 /* -------------------------------------------------------------------- */
720
721 #if defined(CONFIG_TQM8xxL) || defined(CONFIG_SVM_SC8xx)
722
723 #if defined(CONFIG_TQM8xxL)
724 #define PCMCIA_BOARD_MSG "TQM8xxL"
725 #endif
726 #if defined(CONFIG_SVM_SC8xx)
727 #define PCMCIA_BOARD_MSG "SC8xx"
728 #endif
729
730 static int hardware_enable(int slot)
731 {
732         volatile immap_t        *immap;
733         volatile cpm8xx_t       *cp;
734         volatile pcmconf8xx_t   *pcmp;
735         volatile sysconf8xx_t   *sysp;
736         uint reg, mask;
737
738         debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
739
740         udelay(10000);
741
742         immap = (immap_t *)CFG_IMMR;
743         sysp  = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
744         pcmp  = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
745         cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
746
747         /*
748          * Configure SIUMCR to enable PCMCIA port B
749          * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
750          */
751         sysp->sc_siumcr &= ~SIUMCR_DBGC11;      /* set DBGC to 00 */
752
753         /* clear interrupt state, and disable interrupts */
754         pcmp->pcmc_pscr =  PCMCIA_MASK(slot);
755         pcmp->pcmc_per &= ~PCMCIA_MASK(slot);
756
757         /*
758          * Disable interrupts, DMA, and PCMCIA buffers
759          * (isolate the interface) and assert RESET signal
760          */
761         debug ("Disable PCMCIA buffers and assert RESET\n");
762         reg  = 0;
763         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
764 #ifndef NSCU_OE_INV
765         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
766 #endif
767         PCMCIA_PGCRX(slot) = reg;
768         udelay(500);
769
770 #ifndef CONFIG_HMI10
771 #ifndef CONFIG_NSCU
772         /*
773          * Configure Port C pins for
774          * 5 Volts Enable and 3 Volts enable
775          */
776         immap->im_ioport.iop_pcpar &= ~(0x0002 | 0x0004);
777         immap->im_ioport.iop_pcso  &= ~(0x0002 | 0x0004);
778         /* remove all power */
779
780         immap->im_ioport.iop_pcdat &= ~(0x0002 | 0x0004);
781 #endif
782 #else   /* CONFIG_HMI10 */
783         /*
784          * Configure Port B  pins for
785          * 5 Volts Enable and 3 Volts enable
786          */
787         immap->im_cpm.cp_pbpar &= ~(0x00000300);
788
789         /* remove all power */
790         immap->im_cpm.cp_pbdat |= 0x00000300;
791 #endif  /* CONFIG_HMI10 */
792
793         /*
794          * Make sure there is a card in the slot, then configure the interface.
795          */
796         udelay(10000);
797         debug ("[%d] %s: PIPR(%p)=0x%x\n",
798                 __LINE__,__FUNCTION__,
799                 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
800 #ifndef CONFIG_HMI10
801         if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
802 #else
803         if (pcmp->pcmc_pipr & (0x10000000 >> (slot << 4))) {
804 #endif  /* CONFIG_HMI10 */
805                 printf ("   No Card found\n");
806                 return (1);
807         }
808
809         /*
810          * Power On.
811          */
812         mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
813         reg  = pcmp->pcmc_pipr;
814         debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
815                 reg,
816                 (reg&PCMCIA_VS1(slot))?"n":"ff",
817                 (reg&PCMCIA_VS2(slot))?"n":"ff");
818 #ifndef CONFIG_NSCU
819         if ((reg & mask) == mask) {
820 #ifndef CONFIG_HMI10
821                 immap->im_ioport.iop_pcdat |= 0x0004;
822 #else
823                 immap->im_cpm.cp_pbdat &= ~(0x0000100);
824 #endif  /* CONFIG_HMI10 */
825                 puts (" 5.0V card found: ");
826         } else {
827 #ifndef CONFIG_HMI10
828                 immap->im_ioport.iop_pcdat |= 0x0002;
829 #else
830                 immap->im_cpm.cp_pbdat &= ~(0x0000200);
831 #endif  /* CONFIG_HMI10 */
832                 puts (" 3.3V card found: ");
833         }
834 #ifndef CONFIG_HMI10
835         immap->im_ioport.iop_pcdir |= (0x0002 | 0x0004);
836 #else
837         immap->im_cpm.cp_pbdir |= 0x00000300;
838 #endif  /* CONFIG_HMI10 */
839 #else
840         if ((reg & mask) == mask) {
841                 puts (" 5.0V card found: ");
842         } else {
843                 puts (" 3.3V card found: ");
844         }
845 #endif
846 #if 0
847         /*  VCC switch error flag, PCMCIA slot INPACK_ pin */
848         cp->cp_pbdir &= ~(0x0020 | 0x0010);
849         cp->cp_pbpar &= ~(0x0020 | 0x0010);
850         udelay(500000);
851 #endif
852         udelay(1000);
853         debug ("Enable PCMCIA buffers and stop RESET\n");
854         reg  =  PCMCIA_PGCRX(slot);
855         reg &= ~__MY_PCMCIA_GCRX_CXRESET;       /* active high */
856 #ifndef NSCU_OE_INV
857         reg &= ~__MY_PCMCIA_GCRX_CXOE;          /* active low  */
858 #else
859         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
860 #endif
861         PCMCIA_PGCRX(slot) = reg;
862
863         udelay(250000); /* some cards need >150 ms to come up :-( */
864
865         debug ("# hardware_enable done\n");
866
867         return (0);
868 }
869
870
871 #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
872 static int hardware_disable(int slot)
873 {
874         volatile immap_t        *immap;
875         volatile pcmconf8xx_t   *pcmp;
876         u_long reg;
877
878         debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
879
880         immap = (immap_t *)CFG_IMMR;
881         pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
882
883 #ifndef CONFIG_HMI10
884 #ifndef CONFIG_NSCU
885         /* remove all power */
886         immap->im_ioport.iop_pcdat &= ~(0x0002 | 0x0004);
887 #endif
888 #else   /* CONFIG_HMI10 */
889         immap->im_cpm.cp_pbdat |= 0x00000300;
890 #endif  /* CONFIG_HMI10 */
891
892         debug ("Disable PCMCIA buffers and assert RESET\n");
893         reg  = 0;
894         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
895 #ifndef NSCU_OE_INV
896         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
897 #endif
898         PCMCIA_PGCRX(slot) = reg;
899
900         udelay(10000);
901
902         return (0);
903 }
904 #endif  /* CFG_CMD_PCMCIA */
905
906 #ifdef CONFIG_NSCU
907 static int voltage_set(int slot, int vcc, int vpp)
908 {
909         return 0;
910 }
911 #else
912 static int voltage_set(int slot, int vcc, int vpp)
913 {
914         volatile immap_t        *immap;
915         volatile pcmconf8xx_t   *pcmp;
916         u_long reg;
917
918         debug ("voltage_set: "
919                 PCMCIA_BOARD_MSG
920                 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
921                 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
922
923         immap = (immap_t *)CFG_IMMR;
924         pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
925         /*
926          * Disable PCMCIA buffers (isolate the interface)
927          * and assert RESET signal
928          */
929         debug ("Disable PCMCIA buffers and assert RESET\n");
930         reg  = PCMCIA_PGCRX(slot);
931         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
932 #ifndef NSCU_OE_INV
933         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
934 #else
935         reg &= ~__MY_PCMCIA_GCRX_CXOE;          /* active low  */
936 #endif
937         PCMCIA_PGCRX(slot) = reg;
938         udelay(500);
939
940 #ifndef CONFIG_HMI10
941         /*
942          * Configure Port C pins for
943          * 5 Volts Enable and 3 Volts enable,
944          * Turn off all power
945          */
946         debug ("PCMCIA power OFF\n");
947         immap->im_ioport.iop_pcpar &= ~(0x0002 | 0x0004);
948         immap->im_ioport.iop_pcso  &= ~(0x0002 | 0x0004);
949         immap->im_ioport.iop_pcdat &= ~(0x0002 | 0x0004);
950
951         reg = 0;
952         switch(vcc) {
953         case  0:                break;
954         case 33: reg |= 0x0002; break;
955         case 50: reg |= 0x0004; break;
956         default:                goto done;
957         }
958 #else   /* CONFIG_HMI10 */
959         /*
960          * Configure Port B pins for
961          * 5 Volts Enable and 3 Volts enable,
962          * Turn off all power
963          */
964         debug ("PCMCIA power OFF\n");
965         immap->im_cpm.cp_pbpar &= ~(0x00000300);
966         /* remove all power */
967
968         immap->im_cpm.cp_pbdat |= 0x00000300;
969
970         reg = 0;
971         switch(vcc) {
972                 case  0:                        break;
973                 case 33: reg |= 0x00000200;     break;
974                 case 50: reg |= 0x00000100;     break;
975                 default:                        goto done;
976 }
977 #endif  /* CONFIG_HMI10 */
978
979         /* Checking supported voltages */
980
981         debug ("PIPR: 0x%x --> %s\n",
982                 pcmp->pcmc_pipr,
983                 (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
984
985 #ifndef CONFIG_HMI10
986         immap->im_ioport.iop_pcdat |= reg;
987         immap->im_ioport.iop_pcdir |= (0x0002 | 0x0004);
988 #else
989         immap->im_cpm.cp_pbdat &= !reg;
990         immap->im_cpm.cp_pbdir |= 0x00000300;
991 #endif  /* CONFIG_HMI10 */
992         if (reg) {
993 #ifndef CONFIG_HMI10
994                 debug ("PCMCIA powered at %sV\n",
995                         (reg&0x0004) ? "5.0" : "3.3");
996 #else
997                 debug ("PCMCIA powered at %sV\n",
998                         (reg&0x00000200) ? "5.0" : "3.3");
999 #endif  /* CONFIG_HMI10 */
1000         } else {
1001                 debug ("PCMCIA powered down\n");
1002         }
1003
1004 done:
1005         debug ("Enable PCMCIA buffers and stop RESET\n");
1006         reg  =  PCMCIA_PGCRX(slot);
1007         reg &= ~__MY_PCMCIA_GCRX_CXRESET;       /* active high */
1008 #ifndef NSCU_OE_INV
1009         reg &= ~__MY_PCMCIA_GCRX_CXOE;          /* active low  */
1010 #else
1011         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
1012 #endif
1013         PCMCIA_PGCRX(slot) = reg;
1014         udelay(500);
1015
1016         debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
1017                 slot+'A');
1018         return (0);
1019 }
1020 #endif
1021
1022 #endif  /* TQM8xxL */
1023
1024
1025 /* -------------------------------------------------------------------- */
1026 /* LWMON Board                                                          */
1027 /* -------------------------------------------------------------------- */
1028
1029 #if defined(CONFIG_LWMON)
1030
1031 #define PCMCIA_BOARD_MSG "LWMON"
1032
1033 /* #define's for MAX1604 Power Switch */
1034 #define MAX1604_OP_SUS          0x80
1035 #define MAX1604_VCCBON          0x40
1036 #define MAX1604_VCC_35          0x20
1037 #define MAX1604_VCCBHIZ         0x10
1038 #define MAX1604_VPPBON          0x08
1039 #define MAX1604_VPPBPBPGM       0x04
1040 #define MAX1604_VPPBHIZ         0x02
1041 /* reserved                     0x01    */
1042
1043 static int hardware_enable(int slot)
1044 {
1045         volatile immap_t        *immap;
1046         volatile cpm8xx_t       *cp;
1047         volatile pcmconf8xx_t   *pcmp;
1048         volatile sysconf8xx_t   *sysp;
1049         uint reg, mask;
1050         uchar val;
1051
1052
1053         debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1054
1055         /* Switch on PCMCIA port in PIC register 0x60 */
1056         reg = pic_read  (0x60);
1057         debug ("[%d] PIC read: reg_60 = 0x%02x\n", __LINE__, reg);
1058         reg &= ~0x10;
1059         /* reg |= 0x08; Vpp not needed */
1060         pic_write (0x60, reg);
1061 #ifdef DEBUG
1062         reg = pic_read  (0x60);
1063         printf ("[%d] PIC read: reg_60 = 0x%02x\n", __LINE__, reg);
1064 #endif
1065         udelay(10000);
1066
1067         immap = (immap_t *)CFG_IMMR;
1068         sysp  = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
1069         pcmp  = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1070         cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1071
1072         /*
1073          * Configure SIUMCR to enable PCMCIA port B
1074          * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
1075          */
1076         sysp->sc_siumcr &= ~SIUMCR_DBGC11;      /* set DBGC to 00 */
1077
1078         /* clear interrupt state, and disable interrupts */
1079         pcmp->pcmc_pscr =  PCMCIA_MASK(_slot_);
1080         pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
1081
1082         /*
1083          * Disable interrupts, DMA, and PCMCIA buffers
1084          * (isolate the interface) and assert RESET signal
1085          */
1086         debug ("Disable PCMCIA buffers and assert RESET\n");
1087         reg  = 0;
1088         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
1089         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
1090         PCMCIA_PGCRX(_slot_) = reg;
1091         udelay(500);
1092
1093         /*
1094          * Make sure there is a card in the slot, then configure the interface.
1095          */
1096         udelay(10000);
1097         debug ("[%d] %s: PIPR(%p)=0x%x\n",
1098                 __LINE__,__FUNCTION__,
1099                 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
1100         if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
1101                 printf ("   No Card found\n");
1102                 return (1);
1103         }
1104
1105         /*
1106          * Power On.
1107          */
1108         mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
1109         reg  = pcmp->pcmc_pipr;
1110         debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
1111                 reg,
1112                 (reg&PCMCIA_VS1(slot))?"n":"ff",
1113                 (reg&PCMCIA_VS2(slot))?"n":"ff");
1114         if ((reg & mask) == mask) {
1115                 val = 0;                /* VCCB3/5 = 0 ==> use Vx = 5.0 V */
1116                 puts (" 5.0V card found: ");
1117         } else {
1118                 val = MAX1604_VCC_35;   /* VCCB3/5 = 1 ==> use Vy = 3.3 V */
1119                 puts (" 3.3V card found: ");
1120         }
1121
1122         /*  switch VCC on */
1123         val |= MAX1604_OP_SUS | MAX1604_VCCBON;
1124         i2c_init  (CFG_I2C_SPEED, CFG_I2C_SLAVE);
1125         i2c_write (CFG_I2C_POWER_A_ADDR, 0, 0, &val, 1);
1126
1127         udelay(500000);
1128
1129         debug ("Enable PCMCIA buffers and stop RESET\n");
1130         reg  =  PCMCIA_PGCRX(_slot_);
1131         reg &= ~__MY_PCMCIA_GCRX_CXRESET;       /* active high */
1132         reg &= ~__MY_PCMCIA_GCRX_CXOE;          /* active low  */
1133         PCMCIA_PGCRX(_slot_) = reg;
1134
1135         udelay(250000); /* some cards need >150 ms to come up :-( */
1136
1137         debug ("# hardware_enable done\n");
1138
1139         return (0);
1140 }
1141
1142
1143 #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
1144 static int hardware_disable(int slot)
1145 {
1146         volatile immap_t        *immap;
1147         volatile pcmconf8xx_t   *pcmp;
1148         u_long reg;
1149         uchar val;
1150
1151         debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1152
1153         immap = (immap_t *)CFG_IMMR;
1154         pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1155
1156         /* remove all power, put output in high impedance state */
1157         val  = MAX1604_VCCBHIZ | MAX1604_VPPBHIZ;
1158         i2c_init  (CFG_I2C_SPEED, CFG_I2C_SLAVE);
1159         i2c_write (CFG_I2C_POWER_A_ADDR, 0, 0, &val, 1);
1160
1161         /* Configure PCMCIA General Control Register */
1162         debug ("Disable PCMCIA buffers and assert RESET\n");
1163         reg  = 0;
1164         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
1165         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
1166         PCMCIA_PGCRX(_slot_) = reg;
1167
1168         /* Switch off PCMCIA port in PIC register 0x60 */
1169         reg = pic_read  (0x60);
1170         debug ("[%d] PIC read: reg_60 = 0x%02x\n", __LINE__, reg);
1171         reg |=  0x10;
1172         reg &= ~0x08;
1173         pic_write (0x60, reg);
1174 #ifdef DEBUG
1175         reg = pic_read  (0x60);
1176         printf ("[%d] PIC read: reg_60 = 0x%02x\n", __LINE__, reg);
1177 #endif
1178         udelay(10000);
1179
1180         return (0);
1181 }
1182 #endif  /* CFG_CMD_PCMCIA */
1183
1184
1185 static int voltage_set(int slot, int vcc, int vpp)
1186 {
1187         volatile immap_t        *immap;
1188         volatile pcmconf8xx_t   *pcmp;
1189         u_long reg;
1190         uchar val;
1191
1192         debug ("voltage_set: "
1193                 PCMCIA_BOARD_MSG
1194                 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
1195                 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
1196
1197         immap = (immap_t *)CFG_IMMR;
1198         pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1199         /*
1200          * Disable PCMCIA buffers (isolate the interface)
1201          * and assert RESET signal
1202          */
1203         debug ("Disable PCMCIA buffers and assert RESET\n");
1204         reg  = PCMCIA_PGCRX(_slot_);
1205         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
1206         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
1207         PCMCIA_PGCRX(_slot_) = reg;
1208         udelay(500);
1209
1210         /*
1211          * Turn off all power (switch to high impedance)
1212          */
1213         debug ("PCMCIA power OFF\n");
1214         val  = MAX1604_VCCBHIZ | MAX1604_VPPBHIZ;
1215         i2c_init  (CFG_I2C_SPEED, CFG_I2C_SLAVE);
1216         i2c_write (CFG_I2C_POWER_A_ADDR, 0, 0, &val, 1);
1217
1218         val = 0;
1219         switch(vcc) {
1220         case  0:                        break;
1221         case 33: val = MAX1604_VCC_35;  break;
1222         case 50:                        break;
1223         default:                        goto done;
1224         }
1225
1226         /* Checking supported voltages */
1227
1228         debug ("PIPR: 0x%x --> %s\n",
1229                 pcmp->pcmc_pipr,
1230                 (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
1231
1232         i2c_write (CFG_I2C_POWER_A_ADDR, 0, 0, &val, 1);
1233         if (val) {
1234                 debug ("PCMCIA powered at %sV\n",
1235                         (val & MAX1604_VCC_35) ? "3.3" : "5.0");
1236         } else {
1237                 debug ("PCMCIA powered down\n");
1238         }
1239
1240 done:
1241         debug ("Enable PCMCIA buffers and stop RESET\n");
1242         reg  =  PCMCIA_PGCRX(_slot_);
1243         reg &= ~__MY_PCMCIA_GCRX_CXRESET;       /* active high */
1244         reg &= ~__MY_PCMCIA_GCRX_CXOE;          /* active low  */
1245         PCMCIA_PGCRX(_slot_) = reg;
1246         udelay(500);
1247
1248         debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
1249                 slot+'A');
1250         return (0);
1251 }
1252
1253 #endif  /* LWMON */
1254
1255 /* -------------------------------------------------------------------- */
1256 /* GTH board by Corelatus AB                                            */
1257 /* -------------------------------------------------------------------- */
1258 #if defined(CONFIG_GTH)
1259
1260 #define PCMCIA_BOARD_MSG "GTH COMPACT FLASH"
1261
1262 static int voltage_set (int slot, int vcc, int vpp)
1263 {       /* Do nothing */
1264         return 0;
1265 }
1266
1267 static int hardware_enable (int slot)
1268 {
1269         volatile immap_t *immap;
1270         volatile cpm8xx_t *cp;
1271         volatile pcmconf8xx_t *pcmp;
1272         volatile sysconf8xx_t *sysp;
1273         uint reg, mask;
1274
1275         debug ("hardware_enable: GTH Slot %c\n", 'A' + slot);
1276
1277         immap = (immap_t *) CFG_IMMR;
1278         sysp = (sysconf8xx_t *) (&(((immap_t *) CFG_IMMR)->im_siu_conf));
1279         pcmp = (pcmconf8xx_t *) (&(((immap_t *) CFG_IMMR)->im_pcmcia));
1280         cp = (cpm8xx_t *) (&(((immap_t *) CFG_IMMR)->im_cpm));
1281
1282         /* clear interrupt state, and disable interrupts */
1283         pcmp->pcmc_pscr = PCMCIA_MASK (_slot_);
1284         pcmp->pcmc_per &= ~PCMCIA_MASK (_slot_);
1285
1286         /*
1287          * Disable interrupts, DMA, and PCMCIA buffers
1288          * (isolate the interface) and assert RESET signal
1289          */
1290         debug ("Disable PCMCIA buffers and assert RESET\n");
1291         reg = 0;
1292         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
1293         reg |= __MY_PCMCIA_GCRX_CXOE;   /* active low  */
1294         PCMCIA_PGCRX (_slot_) = reg;
1295         udelay (500);
1296
1297         /*
1298          * Make sure there is a card in the slot,
1299          * then configure the interface.
1300          */
1301         udelay (10000);
1302         debug ("[%d] %s: PIPR(%p)=0x%x\n",
1303                 __LINE__, __FUNCTION__,
1304                 &(pcmp->pcmc_pipr), pcmp->pcmc_pipr);
1305         if (pcmp->pcmc_pipr & 0x98000000) {
1306                 printf ("   No Card found\n");
1307                 return (1);
1308         }
1309
1310         mask = PCMCIA_VS1 (slot) | PCMCIA_VS2 (slot);
1311         reg = pcmp->pcmc_pipr;
1312         debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
1313                    reg,
1314                    (reg & PCMCIA_VS1 (slot)) ? "n" : "ff",
1315                    (reg & PCMCIA_VS2 (slot)) ? "n" : "ff");
1316
1317         debug ("Enable PCMCIA buffers and stop RESET\n");
1318         reg  =  PCMCIA_PGCRX (_slot_);
1319         reg &= ~__MY_PCMCIA_GCRX_CXRESET;       /* active high */
1320         reg &= ~__MY_PCMCIA_GCRX_CXOE;          /* active low  */
1321         PCMCIA_PGCRX (_slot_) = reg;
1322
1323         udelay (250000);        /* some cards need >150 ms to come up :-( */
1324
1325         debug ("# hardware_enable done\n");
1326
1327         return 0;
1328 }
1329 #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
1330 static int hardware_disable(int slot)
1331 {
1332         return 0;       /* No hardware to disable */
1333 }
1334 #endif  /* CFG_CMD_PCMCIA */
1335 #endif  /* CONFIG_GTH */
1336
1337 /* -------------------------------------------------------------------- */
1338 /* ICU862 Boards by Cambridge Broadband Ltd.                            */
1339 /* -------------------------------------------------------------------- */
1340
1341 #if defined(CONFIG_ICU862)
1342
1343 #define PCMCIA_BOARD_MSG "ICU862"
1344
1345 static void cfg_port_B (void);
1346
1347 static int hardware_enable(int slot)
1348 {
1349         volatile immap_t        *immap;
1350         volatile cpm8xx_t       *cp;
1351         volatile pcmconf8xx_t   *pcmp;
1352         volatile sysconf8xx_t   *sysp;
1353         uint reg, pipr, mask;
1354         int i;
1355
1356         debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1357
1358         udelay(10000);
1359
1360         immap = (immap_t *)CFG_IMMR;
1361         sysp  = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
1362         pcmp  = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1363         cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1364
1365         /* Configure Port B for TPS2205 PC-Card Power-Interface Switch */
1366         cfg_port_B ();
1367
1368         /*
1369          * Configure SIUMCR to enable PCMCIA port B
1370          * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
1371          */
1372         sysp->sc_siumcr &= ~SIUMCR_DBGC11;      /* set DBGC to 00 */
1373
1374         /* clear interrupt state, and disable interrupts */
1375         pcmp->pcmc_pscr =  PCMCIA_MASK(_slot_);
1376         pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
1377
1378         /*
1379          * Disable interrupts, DMA, and PCMCIA buffers
1380          * (isolate the interface) and assert RESET signal
1381          */
1382         debug ("Disable PCMCIA buffers and assert RESET\n");
1383         reg  = 0;
1384         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
1385         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
1386         PCMCIA_PGCRX(_slot_) = reg;
1387         udelay(500);
1388
1389         /*
1390          * Make sure there is a card in the slot, then configure the interface.
1391          */
1392         udelay(10000);
1393         debug ("[%d] %s: PIPR(%p)=0x%x\n",
1394                 __LINE__,__FUNCTION__,
1395                 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
1396         if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
1397                 printf ("   No Card found\n");
1398                 return (1);
1399         }
1400
1401         /*
1402          * Power On: Set VAVCC to 3.3V or 5V, set VAVPP to Hi-Z
1403          */
1404         mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
1405         pipr = pcmp->pcmc_pipr;
1406         debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
1407                 pipr,
1408                 (reg&PCMCIA_VS1(slot))?"n":"ff",
1409                 (reg&PCMCIA_VS2(slot))?"n":"ff");
1410
1411         reg  = cp->cp_pbdat;
1412         if ((pipr & mask) == mask) {
1413                 reg |= (TPS2205_VPP_PGM | TPS2205_VPP_VCC |     /* VAVPP => Hi-Z */
1414                         TPS2205_VCC3);                          /* 3V off       */
1415                 reg &= ~(TPS2205_VCC5);                         /* 5V on        */
1416                 puts (" 5.0V card found: ");
1417         } else {
1418                 reg |= (TPS2205_VPP_PGM | TPS2205_VPP_VCC |     /* VAVPP => Hi-Z */
1419                         TPS2205_VCC5);                          /* 5V off       */
1420                 reg &= ~(TPS2205_VCC3);                         /* 3V on        */
1421                 puts (" 3.3V card found: ");
1422         }
1423
1424         debug ("\nPB DAT: %08x -> 3.3V %s 5.0V %s VPP_PGM %s VPP_VCC %s\n",
1425                 reg,
1426                 (reg & TPS2205_VCC3)    ? "off" : "on",
1427                 (reg & TPS2205_VCC5)    ? "off" : "on",
1428                 (reg & TPS2205_VPP_PGM) ? "off" : "on",
1429                 (reg & TPS2205_VPP_VCC) ? "off" : "on" );
1430
1431         cp->cp_pbdat = reg;
1432
1433         /*  Wait 500 ms; use this to check for over-current */
1434         for (i=0; i<5000; ++i) {
1435                 if ((cp->cp_pbdat & TPS2205_OC) == 0) {
1436                         printf ("   *** Overcurrent - Safety shutdown ***\n");
1437                         cp->cp_pbdat &= ~(TPS2205_SHDN);
1438                         return (1);
1439                 }
1440                 udelay (100);
1441         }
1442
1443         debug ("Enable PCMCIA buffers and stop RESET\n");
1444         reg  =  PCMCIA_PGCRX(_slot_);
1445         reg &= ~__MY_PCMCIA_GCRX_CXRESET;       /* active high */
1446         reg &= ~__MY_PCMCIA_GCRX_CXOE;          /* active low  */
1447         PCMCIA_PGCRX(_slot_) = reg;
1448
1449         udelay(250000); /* some cards need >150 ms to come up :-( */
1450
1451         debug ("# hardware_enable done\n");
1452
1453         return (0);
1454 }
1455
1456
1457 #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
1458 static int hardware_disable(int slot)
1459 {
1460         volatile immap_t        *immap;
1461         volatile cpm8xx_t       *cp;
1462         volatile pcmconf8xx_t   *pcmp;
1463         u_long reg;
1464
1465         debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1466
1467         immap = (immap_t *)CFG_IMMR;
1468         cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1469         pcmp  = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1470
1471         /* Shut down */
1472         cp->cp_pbdat &= ~(TPS2205_SHDN);
1473
1474         /* Configure PCMCIA General Control Register */
1475         debug ("Disable PCMCIA buffers and assert RESET\n");
1476         reg  = 0;
1477         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
1478         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
1479         PCMCIA_PGCRX(_slot_) = reg;
1480
1481         udelay(10000);
1482
1483         return (0);
1484 }
1485 #endif  /* CFG_CMD_PCMCIA */
1486
1487
1488 static int voltage_set(int slot, int vcc, int vpp)
1489 {
1490         volatile immap_t        *immap;
1491         volatile cpm8xx_t       *cp;
1492         volatile pcmconf8xx_t   *pcmp;
1493         u_long reg;
1494
1495         debug ("voltage_set: "
1496                 PCMCIA_BOARD_MSG
1497                 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
1498                 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
1499
1500         immap = (immap_t *)CFG_IMMR;
1501         cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1502         pcmp  = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1503         /*
1504          * Disable PCMCIA buffers (isolate the interface)
1505          * and assert RESET signal
1506          */
1507         debug ("Disable PCMCIA buffers and assert RESET\n");
1508         reg  = PCMCIA_PGCRX(_slot_);
1509         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
1510         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
1511         PCMCIA_PGCRX(_slot_) = reg;
1512         udelay(500);
1513
1514         /*
1515          * Configure Port C pins for
1516          * 5 Volts Enable and 3 Volts enable,
1517          * Turn all power pins to Hi-Z
1518          */
1519         debug ("PCMCIA power OFF\n");
1520         cfg_port_B ();  /* Enables switch, but all in Hi-Z */
1521
1522         reg  = cp->cp_pbdat;
1523
1524         switch(vcc) {
1525         case  0:                        break;  /* Switch off           */
1526         case 33: reg &= ~TPS2205_VCC3;  break;  /* Switch on 3.3V       */
1527         case 50: reg &= ~TPS2205_VCC5;  break;  /* Switch on 5.0V       */
1528         default:                        goto done;
1529         }
1530
1531         /* Checking supported voltages */
1532
1533         debug ("PIPR: 0x%x --> %s\n",
1534                 pcmp->pcmc_pipr,
1535                 (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
1536
1537         cp->cp_pbdat = reg;
1538
1539 #ifdef DEBUG
1540     {
1541         char *s;
1542
1543         if ((reg & TPS2205_VCC3) == 0) {
1544                 s = "at 3.3V";
1545         } else if ((reg & TPS2205_VCC5) == 0) {
1546                 s = "at 5.0V";
1547         } else {
1548                 s = "down";
1549         }
1550         printf ("PCMCIA powered %s\n", s);
1551     }
1552 #endif
1553
1554 done:
1555         debug ("Enable PCMCIA buffers and stop RESET\n");
1556         reg  =  PCMCIA_PGCRX(_slot_);
1557         reg &= ~__MY_PCMCIA_GCRX_CXRESET;       /* active high */
1558         reg &= ~__MY_PCMCIA_GCRX_CXOE;          /* active low  */
1559         PCMCIA_PGCRX(_slot_) = reg;
1560         udelay(500);
1561
1562         debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
1563                 slot+'A');
1564         return (0);
1565 }
1566
1567 static void cfg_port_B (void)
1568 {
1569         volatile immap_t        *immap;
1570         volatile cpm8xx_t       *cp;
1571         uint reg;
1572
1573         immap = (immap_t *)CFG_IMMR;
1574         cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1575
1576         /*
1577          * Configure Port B for TPS2205 PC-Card Power-Interface Switch
1578          *
1579          * Switch off all voltages, assert shutdown
1580          */
1581         reg  = cp->cp_pbdat;
1582         reg |= (TPS2205_VPP_PGM | TPS2205_VPP_VCC |     /* VAVPP => Hi-Z */
1583                 TPS2205_VCC3    | TPS2205_VCC5    |     /* VAVCC => Hi-Z */
1584                 TPS2205_SHDN);                          /* enable switch */
1585         cp->cp_pbdat = reg;
1586
1587         cp->cp_pbpar &= ~(TPS2205_INPUTS | TPS2205_OUTPUTS);
1588
1589         reg = cp->cp_pbdir & ~(TPS2205_INPUTS);
1590         cp->cp_pbdir = reg | TPS2205_OUTPUTS;
1591
1592         debug ("Set Port B: PAR: %08x DIR: %08x DAT: %08x\n",
1593                 cp->cp_pbpar, cp->cp_pbdir, cp->cp_pbdat);
1594 }
1595
1596 #endif  /* ICU862 */
1597
1598
1599 /* -------------------------------------------------------------------- */
1600 /* C2MON Boards by TTTech Computertechnik AG                            */
1601 /* -------------------------------------------------------------------- */
1602
1603 #if defined(CONFIG_C2MON)
1604
1605 #define PCMCIA_BOARD_MSG "C2MON"
1606
1607 static void cfg_ports (void);
1608
1609 static int hardware_enable(int slot)
1610 {
1611         volatile immap_t        *immap;
1612         volatile cpm8xx_t       *cp;
1613         volatile pcmconf8xx_t   *pcmp;
1614         volatile sysconf8xx_t   *sysp;
1615         uint reg, pipr, mask;
1616         ushort sreg;
1617         int i;
1618
1619         debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1620
1621         udelay(10000);
1622
1623         immap = (immap_t *)CFG_IMMR;
1624         sysp  = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
1625         pcmp  = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1626         cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1627
1628         /* Configure Ports for TPS2211A PC-Card Power-Interface Switch */
1629         cfg_ports ();
1630
1631         /*
1632          * Configure SIUMCR to enable PCMCIA port B
1633          * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
1634          */
1635         sysp->sc_siumcr &= ~SIUMCR_DBGC11;      /* set DBGC to 00 */
1636
1637         /* clear interrupt state, and disable interrupts */
1638         pcmp->pcmc_pscr =  PCMCIA_MASK(_slot_);
1639         pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
1640
1641         /*
1642          * Disable interrupts, DMA, and PCMCIA buffers
1643          * (isolate the interface) and assert RESET signal
1644          */
1645         debug ("Disable PCMCIA buffers and assert RESET\n");
1646         reg  = 0;
1647         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
1648         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
1649         PCMCIA_PGCRX(_slot_) = reg;
1650         udelay(500);
1651
1652         /*
1653          * Make sure there is a card in the slot, then configure the interface.
1654          */
1655         udelay(10000);
1656         debug ("[%d] %s: PIPR(%p)=0x%x\n",
1657                 __LINE__,__FUNCTION__,
1658                 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
1659         if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
1660                 printf ("   No Card found\n");
1661                 return (1);
1662         }
1663
1664         /*
1665          * Power On: Set VAVCC to 3.3V or 5V, set VAVPP to Hi-Z
1666          */
1667         mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
1668         pipr = pcmp->pcmc_pipr;
1669         debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
1670                 pipr,
1671                 (reg&PCMCIA_VS1(slot))?"n":"ff",
1672                 (reg&PCMCIA_VS2(slot))?"n":"ff");
1673
1674         sreg = immap->im_ioport.iop_pcdat;
1675         if ((pipr & mask) == mask) {
1676                 sreg |=  (TPS2211_VPPD0 | TPS2211_VPPD1 |       /* VAVPP => Hi-Z */
1677                           TPS2211_VCCD1);                       /* 5V on        */
1678                 sreg &= ~(TPS2211_VCCD0);                       /* 3V off       */
1679                 puts (" 5.0V card found: ");
1680         } else {
1681                 sreg |=  (TPS2211_VPPD0 | TPS2211_VPPD1 |       /* VAVPP => Hi-Z */
1682                           TPS2211_VCCD0);                       /* 3V on        */
1683                 sreg &= ~(TPS2211_VCCD1);                       /* 5V off       */
1684                 puts (" 3.3V card found: ");
1685         }
1686
1687         debug ("\nPC DAT: %04x -> 3.3V %s 5.0V %s\n",
1688                 sreg,
1689                 ( (sreg & TPS2211_VCCD0) && !(sreg & TPS2211_VCCD1)) ? "on" : "off",
1690                 (!(sreg & TPS2211_VCCD0) &&  (sreg & TPS2211_VCCD1)) ? "on" : "off"
1691         );
1692
1693         immap->im_ioport.iop_pcdat = sreg;
1694
1695         /*  Wait 500 ms; use this to check for over-current */
1696         for (i=0; i<5000; ++i) {
1697                 if ((cp->cp_pbdat & TPS2211_OC) == 0) {
1698                     printf ("   *** Overcurrent - Safety shutdown ***\n");
1699                     immap->im_ioport.iop_pcdat &= ~(TPS2211_VCCD0|TPS2211_VCCD1);
1700                     return (1);
1701                 }
1702                 udelay (100);
1703         }
1704
1705         debug ("Enable PCMCIA buffers and stop RESET\n");
1706         reg  =  PCMCIA_PGCRX(_slot_);
1707         reg &= ~__MY_PCMCIA_GCRX_CXRESET;       /* active high */
1708         reg &= ~__MY_PCMCIA_GCRX_CXOE;          /* active low  */
1709         PCMCIA_PGCRX(_slot_) = reg;
1710
1711         udelay(250000); /* some cards need >150 ms to come up :-( */
1712
1713         debug ("# hardware_enable done\n");
1714
1715         return (0);
1716 }
1717
1718
1719 #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
1720 static int hardware_disable(int slot)
1721 {
1722         volatile immap_t        *immap;
1723         volatile cpm8xx_t       *cp;
1724         volatile pcmconf8xx_t   *pcmp;
1725         u_long reg;
1726
1727         debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1728
1729         immap = (immap_t *)CFG_IMMR;
1730         pcmp  = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1731
1732         /* Configure PCMCIA General Control Register */
1733         debug ("Disable PCMCIA buffers and assert RESET\n");
1734         reg  = 0;
1735         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
1736         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
1737         PCMCIA_PGCRX(_slot_) = reg;
1738
1739         /* ALl voltages off / Hi-Z */
1740         immap->im_ioport.iop_pcdat |= (TPS2211_VPPD0 | TPS2211_VPPD1 |
1741                                        TPS2211_VCCD0 | TPS2211_VCCD1 );
1742
1743         udelay(10000);
1744
1745         return (0);
1746 }
1747 #endif  /* CFG_CMD_PCMCIA */
1748
1749
1750 static int voltage_set(int slot, int vcc, int vpp)
1751 {
1752         volatile immap_t        *immap;
1753         volatile cpm8xx_t       *cp;
1754         volatile pcmconf8xx_t   *pcmp;
1755         u_long reg;
1756         ushort sreg;
1757
1758         debug ("voltage_set: "
1759                 PCMCIA_BOARD_MSG
1760                 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
1761                 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
1762
1763         immap = (immap_t *)CFG_IMMR;
1764         cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1765         pcmp  = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1766         /*
1767          * Disable PCMCIA buffers (isolate the interface)
1768          * and assert RESET signal
1769          */
1770         debug ("Disable PCMCIA buffers and assert RESET\n");
1771         reg  = PCMCIA_PGCRX(_slot_);
1772         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
1773         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
1774         PCMCIA_PGCRX(_slot_) = reg;
1775         udelay(500);
1776
1777         /*
1778          * Configure Port C pins for
1779          * 5 Volts Enable and 3 Volts enable,
1780          * Turn all power pins to Hi-Z
1781          */
1782         debug ("PCMCIA power OFF\n");
1783         cfg_ports ();   /* Enables switch, but all in Hi-Z */
1784
1785         sreg  = immap->im_ioport.iop_pcdat;
1786         sreg |= TPS2211_VPPD0 | TPS2211_VPPD1;          /* VAVPP always Hi-Z */
1787
1788         switch(vcc) {
1789         case  0:                        break;  /* Switch off           */
1790         case 33: sreg |=  TPS2211_VCCD0;        /* Switch on 3.3V       */
1791                  sreg &= ~TPS2211_VCCD1;
1792                                         break;
1793         case 50: sreg &= ~TPS2211_VCCD0;        /* Switch on 5.0V       */
1794                  sreg |=  TPS2211_VCCD1;
1795                                         break;
1796         default:                        goto done;
1797         }
1798
1799         /* Checking supported voltages */
1800
1801         debug ("PIPR: 0x%x --> %s\n",
1802                 pcmp->pcmc_pipr,
1803                 (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
1804
1805         immap->im_ioport.iop_pcdat = sreg;
1806
1807 #ifdef DEBUG
1808     {
1809         char *s;
1810
1811         if ((sreg & TPS2211_VCCD0) && !(sreg & TPS2211_VCCD1)) {
1812                 s = "at 3.3V";
1813         } else if (!(sreg & TPS2211_VCCD0) &&  (sreg & TPS2211_VCCD1)) {
1814                 s = "at 5.0V";
1815         } else {
1816                 s = "down";
1817         }
1818         printf ("PCMCIA powered %s\n", s);
1819     }
1820 #endif
1821
1822 done:
1823         debug ("Enable PCMCIA buffers and stop RESET\n");
1824         reg  =  PCMCIA_PGCRX(_slot_);
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         debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
1831                 slot+'A');
1832         return (0);
1833 }
1834
1835 static void cfg_ports (void)
1836 {
1837         volatile immap_t        *immap;
1838         volatile cpm8xx_t       *cp;
1839         ushort sreg;
1840
1841         immap = (immap_t *)CFG_IMMR;
1842         cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1843
1844         /*
1845          * Configure Port C for TPS2211 PC-Card Power-Interface Switch
1846          *
1847          * Switch off all voltages, assert shutdown
1848          */
1849         sreg = immap->im_ioport.iop_pcdat;
1850         sreg |=  (TPS2211_VPPD0 | TPS2211_VPPD1);       /* VAVPP => Hi-Z */
1851         sreg &= ~(TPS2211_VCCD0 | TPS2211_VCCD1);       /* 3V and 5V off */
1852         immap->im_ioport.iop_pcdat = sreg;
1853
1854         immap->im_ioport.iop_pcpar &= ~(TPS2211_OUTPUTS);
1855         immap->im_ioport.iop_pcdir |=   TPS2211_OUTPUTS;
1856
1857         debug ("Set Port C: PAR:     %04x DIR:     %04x DAT:     %04x\n",
1858                 immap->im_ioport.iop_pcpar,
1859                 immap->im_ioport.iop_pcdir,
1860                 immap->im_ioport.iop_pcdat);
1861
1862         /*
1863          * Configure Port B for TPS2211 PC-Card Power-Interface Switch
1864          *
1865          * Over-Current Input only
1866          */
1867         cp->cp_pbpar &= ~(TPS2211_INPUTS);
1868         cp->cp_pbdir &= ~(TPS2211_INPUTS);
1869
1870         debug ("Set Port B: PAR: %08x DIR: %08x DAT: %08x\n",
1871                 cp->cp_pbpar, cp->cp_pbdir, cp->cp_pbdat);
1872 }
1873
1874 #endif  /* C2MON */
1875
1876 /* -------------------------------------------------------------------- */
1877 /* MBX board from Morotola                                              */
1878 /* -------------------------------------------------------------------- */
1879
1880 #if defined( CONFIG_MBX )
1881 #include <../board/mbx8xx/csr.h>
1882
1883 /* A lot of this has been taken from the RPX code in this file it works from me.
1884    I have added the voltage selection for the MBX board. */
1885
1886 /* MBX voltage bit in control register #2 */
1887 #define CR2_VPP12       ((uchar)0x10)
1888 #define CR2_VPPVDD      ((uchar)0x20)
1889 #define CR2_VDD5        ((uchar)0x40)
1890 #define CR2_VDD3        ((uchar)0x80)
1891
1892 #define PCMCIA_BOARD_MSG "MBX860"
1893
1894 static int voltage_set (int slot, int vcc, int vpp)
1895 {
1896         uchar reg = 0;
1897
1898         debug ("voltage_set: PCMCIA_BOARD_MSG Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
1899                  'A' + slot, vcc / 10, vcc % 10, vpp / 10, vcc % 10);
1900
1901         switch (vcc) {
1902         case 0:
1903                 break;
1904         case 33:
1905                 reg |= CR2_VDD3;
1906                 break;
1907         case 50:
1908                 reg |= CR2_VDD5;
1909                 break;
1910         default:
1911                 return 1;
1912         }
1913
1914         switch (vpp) {
1915         case 0:
1916                 break;
1917         case 33:
1918         case 50:
1919                 if (vcc == vpp) {
1920                         reg |= CR2_VPPVDD;
1921                 } else {
1922                         return 1;
1923                 }
1924                 break;
1925         case 120:
1926                 reg |= CR2_VPP12;
1927                 break;
1928         default:
1929                 return 1;
1930         }
1931
1932         /* first, turn off all power */
1933         MBX_CSR2 &= ~(CR2_VDDSEL | CR2_VPPSEL);
1934
1935         /* enable new powersettings */
1936         MBX_CSR2 |= reg;
1937         debug ("MBX_CSR2 read = 0x%02x\n", MBX_CSR2);
1938
1939         return (0);
1940 }
1941
1942 static int hardware_enable (int slot)
1943 {
1944         volatile immap_t *immap;
1945         volatile cpm8xx_t *cp;
1946         volatile pcmconf8xx_t *pcmp;
1947         volatile sysconf8xx_t *sysp;
1948         uint reg, mask;
1949
1950         debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n",
1951                                   'A' + slot);
1952
1953         udelay (10000);
1954
1955         immap = (immap_t *) CFG_IMMR;
1956         sysp = (sysconf8xx_t *) (&(((immap_t *) CFG_IMMR)->im_siu_conf));
1957         pcmp = (pcmconf8xx_t *) (&(((immap_t *) CFG_IMMR)->im_pcmcia));
1958         cp = (cpm8xx_t *) (&(((immap_t *) CFG_IMMR)->im_cpm));
1959
1960         /* clear interrupt state, and disable interrupts */
1961         pcmp->pcmc_pscr = PCMCIA_MASK (_slot_);
1962         pcmp->pcmc_per &= ~PCMCIA_MASK (_slot_);
1963
1964         /*
1965          * Disable interrupts, DMA, and PCMCIA buffers
1966          * (isolate the interface) and assert RESET signal
1967          */
1968         debug ("Disable PCMCIA buffers and assert RESET\n");
1969         reg = 0;
1970         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
1971         reg |= __MY_PCMCIA_GCRX_CXOE;   /* active low  */
1972         PCMCIA_PGCRX (_slot_) = reg;
1973         udelay (500);
1974
1975         /* remove all power */
1976         voltage_set (slot, 0, 0);
1977         /*
1978          * Make sure there is a card in the slot, then configure the interface.
1979          */
1980         udelay(10000);
1981         debug ("[%d] %s: PIPR(%p)=0x%x\n",
1982                 __LINE__,__FUNCTION__,
1983                 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
1984 #ifndef CONFIG_HMI10
1985         if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
1986 #else
1987         if (pcmp->pcmc_pipr & (0x10000000 >> (slot << 4))) {
1988 #endif  /* CONFIG_HMI10 */
1989                 printf ("   No Card found\n");
1990                 return (1);
1991         }
1992
1993         /*
1994          * Power On.
1995          */
1996         mask = PCMCIA_VS1 (_slot_) | PCMCIA_VS2 (_slot_);
1997         reg = pcmp->pcmc_pipr;
1998         debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n", reg,
1999                   (reg & PCMCIA_VS1 (slot)) ? "n" : "ff",
2000                   (reg & PCMCIA_VS2 (slot)) ? "n" : "ff");
2001
2002         if ((reg & mask) == mask) {
2003                 voltage_set (_slot_, 50, 0);
2004                 printf (" 5.0V card found: ");
2005         } else {
2006                 voltage_set (_slot_, 33, 0);
2007                 printf (" 3.3V card found: ");
2008         }
2009
2010         debug ("Enable PCMCIA buffers and stop RESET\n");
2011         reg = PCMCIA_PGCRX (_slot_);
2012         reg &= ~__MY_PCMCIA_GCRX_CXRESET;       /* active high */
2013         reg &= ~__MY_PCMCIA_GCRX_CXOE;  /* active low  */
2014         PCMCIA_PGCRX (_slot_) = reg;
2015
2016         udelay (250000);        /* some cards need >150 ms to come up :-( */
2017
2018         debug ("# hardware_enable done\n");
2019
2020         return (0);
2021 }
2022
2023 #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
2024 static int hardware_disable (int slot)
2025 {
2026         return 0;       /* No hardware to disable */
2027 }
2028 #endif /* CFG_CMD_PCMCIA */
2029 #endif /* CONFIG_MBX */
2030 /* -------------------------------------------------------------------- */
2031 /* R360MPI Board                                                        */
2032 /* -------------------------------------------------------------------- */
2033
2034 #if defined(CONFIG_R360MPI)
2035
2036 #define PCMCIA_BOARD_MSG "R360MPI"
2037
2038
2039 static int hardware_enable(int slot)
2040 {
2041         volatile immap_t        *immap;
2042         volatile cpm8xx_t       *cp;
2043         volatile pcmconf8xx_t   *pcmp;
2044         volatile sysconf8xx_t   *sysp;
2045         uint reg, mask;
2046
2047         debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
2048
2049         udelay(10000);
2050
2051         immap = (immap_t *)CFG_IMMR;
2052         sysp  = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
2053         pcmp  = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
2054         cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
2055
2056         /*
2057          * Configure SIUMCR to enable PCMCIA port B
2058          * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
2059          */
2060         sysp->sc_siumcr &= ~SIUMCR_DBGC11;      /* set DBGC to 00 */
2061
2062         /* clear interrupt state, and disable interrupts */
2063         pcmp->pcmc_pscr =  PCMCIA_MASK(_slot_);
2064         pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
2065
2066         /*
2067          * Disable interrupts, DMA, and PCMCIA buffers
2068          * (isolate the interface) and assert RESET signal
2069          */
2070         debug ("Disable PCMCIA buffers and assert RESET\n");
2071         reg  = 0;
2072         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
2073         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
2074         PCMCIA_PGCRX(_slot_) = reg;
2075         udelay(500);
2076
2077         /*
2078          * Configure Ports A, B & C pins for
2079          * 5 Volts Enable and 3 Volts enable
2080          */
2081         immap->im_ioport.iop_pcpar &= ~(0x0400);
2082         immap->im_ioport.iop_pcso  &= ~(0x0400);/*
2083         immap->im_ioport.iop_pcdir |= 0x0400;*/
2084
2085         immap->im_ioport.iop_papar &= ~(0x0200);/*
2086         immap->im_ioport.iop_padir |= 0x0200;*/
2087 #if 0
2088         immap->im_ioport.iop_pbpar &= ~(0xC000);
2089         immap->im_ioport.iop_pbdir &= ~(0xC000);
2090 #endif
2091         /* remove all power */
2092
2093         immap->im_ioport.iop_pcdat |= 0x0400;
2094         immap->im_ioport.iop_padat |= 0x0200;
2095
2096         /*
2097          * Make sure there is a card in the slot, then configure the interface.
2098          */
2099         udelay(10000);
2100         debug ("[%d] %s: PIPR(%p)=0x%x\n",
2101                 __LINE__,__FUNCTION__,
2102                 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
2103         if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
2104                 printf ("   No Card found\n");
2105                 return (1);
2106         }
2107
2108         /*
2109          * Power On.
2110          */
2111         mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
2112         reg  = pcmp->pcmc_pipr;
2113         debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
2114                 reg,
2115                 (reg&PCMCIA_VS1(slot))?"n":"ff",
2116                 (reg&PCMCIA_VS2(slot))?"n":"ff");
2117         if ((reg & mask) == mask) {
2118                 immap->im_ioport.iop_pcdat &= ~(0x4000);
2119                 puts (" 5.0V card found: ");
2120         } else {
2121                 immap->im_ioport.iop_padat &= ~(0x0002);
2122                 puts (" 3.3V card found: ");
2123         }
2124         immap->im_ioport.iop_pcdir |= 0x0400;
2125         immap->im_ioport.iop_padir |= 0x0200;
2126 #if 0
2127         /*  VCC switch error flag, PCMCIA slot INPACK_ pin */
2128         cp->cp_pbdir &= ~(0x0020 | 0x0010);
2129         cp->cp_pbpar &= ~(0x0020 | 0x0010);
2130         udelay(500000);
2131 #endif
2132         debug ("Enable PCMCIA buffers and stop RESET\n");
2133         reg  =  PCMCIA_PGCRX(_slot_);
2134         reg &= ~__MY_PCMCIA_GCRX_CXRESET;       /* active high */
2135         reg &= ~__MY_PCMCIA_GCRX_CXOE;          /* active low  */
2136         PCMCIA_PGCRX(_slot_) = reg;
2137
2138         udelay(250000); /* some cards need >150 ms to come up :-( */
2139
2140         debug ("# hardware_enable done\n");
2141
2142         return (0);
2143 }
2144
2145
2146 #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
2147 static int hardware_disable(int slot)
2148 {
2149         volatile immap_t        *immap;
2150         volatile pcmconf8xx_t   *pcmp;
2151         u_long reg;
2152
2153         debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
2154
2155         immap = (immap_t *)CFG_IMMR;
2156         pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
2157
2158         /* remove all power */
2159         immap->im_ioport.iop_pcdat |= 0x0400;
2160         immap->im_ioport.iop_padat |= 0x0200;
2161
2162         /* Configure PCMCIA General Control Register */
2163         debug ("Disable PCMCIA buffers and assert RESET\n");
2164         reg  = 0;
2165         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
2166         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
2167         PCMCIA_PGCRX(_slot_) = reg;
2168
2169         udelay(10000);
2170
2171         return (0);
2172 }
2173 #endif  /* CFG_CMD_PCMCIA */
2174
2175
2176 static int voltage_set(int slot, int vcc, int vpp)
2177 {
2178         volatile immap_t        *immap;
2179         volatile pcmconf8xx_t   *pcmp;
2180         u_long reg;
2181
2182         debug ("voltage_set: "
2183                 PCMCIA_BOARD_MSG
2184                 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
2185                 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
2186
2187         immap = (immap_t *)CFG_IMMR;
2188         pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
2189         /*
2190          * Disable PCMCIA buffers (isolate the interface)
2191          * and assert RESET signal
2192          */
2193         debug ("Disable PCMCIA buffers and assert RESET\n");
2194         reg  = PCMCIA_PGCRX(_slot_);
2195         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
2196         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
2197         PCMCIA_PGCRX(_slot_) = reg;
2198         udelay(500);
2199
2200         /*
2201          * Configure Ports A & C pins for
2202          * 5 Volts Enable and 3 Volts enable,
2203          * Turn off all power
2204          */
2205         debug ("PCMCIA power OFF\n");
2206         immap->im_ioport.iop_pcpar &= ~(0x0400);
2207         immap->im_ioport.iop_pcso  &= ~(0x0400);/*
2208         immap->im_ioport.iop_pcdir |= 0x0400;*/
2209
2210         immap->im_ioport.iop_papar &= ~(0x0200);/*
2211         immap->im_ioport.iop_padir |= 0x0200;*/
2212
2213         immap->im_ioport.iop_pcdat |= 0x0400;
2214         immap->im_ioport.iop_padat |= 0x0200;
2215
2216         reg = 0;
2217         switch(vcc) {
2218         case  0:                break;
2219         case 33: reg |= 0x0200; break;
2220         case 50: reg |= 0x0400; break;
2221         default:                goto done;
2222         }
2223
2224         /* Checking supported voltages */
2225
2226         debug ("PIPR: 0x%x --> %s\n",
2227                 pcmp->pcmc_pipr,
2228                 (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
2229
2230         if (reg & 0x0200)
2231                 immap->im_ioport.iop_pcdat &= !reg;
2232         if (reg & 0x0400)
2233                 immap->im_ioport.iop_padat &= !reg;
2234         immap->im_ioport.iop_pcdir |= 0x0200;
2235         immap->im_ioport.iop_padir |= 0x0400;
2236         if (reg) {
2237                 debug ("PCMCIA powered at %sV\n",
2238                         (reg&0x0400) ? "5.0" : "3.3");
2239         } else {
2240                 debug ("PCMCIA powered down\n");
2241         }
2242
2243 done:
2244         debug ("Enable PCMCIA buffers and stop RESET\n");
2245         reg  =  PCMCIA_PGCRX(_slot_);
2246         reg &= ~__MY_PCMCIA_GCRX_CXRESET;       /* active high */
2247         reg &= ~__MY_PCMCIA_GCRX_CXOE;          /* active low  */
2248         PCMCIA_PGCRX(_slot_) = reg;
2249         udelay(500);
2250
2251         debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
2252                 slot+'A');
2253         return (0);
2254 }
2255
2256 #endif  /* R360MPI */
2257
2258 /* -------------------------------------------------------------------- */
2259 /* KUP4K and KUP4X Boards                                                               */
2260 /* -------------------------------------------------------------------- */
2261 #if defined(CONFIG_KUP4K) || defined(CONFIG_KUP4X)
2262
2263 #define PCMCIA_BOARD_MSG "KUP"
2264
2265 #define KUP4K_PCMCIA_B_3V3 (0x00020000)
2266
2267 static int hardware_enable(int slot)
2268 {
2269         volatile immap_t        *immap;
2270         volatile cpm8xx_t       *cp;
2271         volatile pcmconf8xx_t   *pcmp;
2272         volatile sysconf8xx_t   *sysp;
2273         uint reg, mask;
2274
2275         debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
2276
2277         udelay(10000);
2278
2279         immap = (immap_t *)CFG_IMMR;
2280         sysp  = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
2281         pcmp  = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
2282         cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
2283
2284         /*
2285          * Configure SIUMCR to enable PCMCIA port B
2286          * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
2287          */
2288         sysp->sc_siumcr &= ~SIUMCR_DBGC11;      /* set DBGC to 00 */
2289
2290         /* clear interrupt state, and disable interrupts */
2291         pcmp->pcmc_pscr =  PCMCIA_MASK(slot);
2292         pcmp->pcmc_per &= ~PCMCIA_MASK(slot);
2293
2294         /*
2295          * Disable interrupts, DMA, and PCMCIA buffers
2296          * (isolate the interface) and assert RESET signal
2297          */
2298         debug ("Disable PCMCIA buffers and assert RESET\n");
2299         reg  = 0;
2300         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
2301         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
2302         PCMCIA_PGCRX(slot) = reg;
2303         udelay(2500);
2304
2305         /*
2306          * Configure Port B pins for
2307          * 3 Volts enable
2308          */
2309         if (slot) { /* Slot A is built-in */
2310                 cp->cp_pbdir |=  KUP4K_PCMCIA_B_3V3;
2311                 cp->cp_pbpar &= ~KUP4K_PCMCIA_B_3V3;
2312                 /* remove all power */
2313                 cp->cp_pbdat |=  KUP4K_PCMCIA_B_3V3; /* active low */
2314         }
2315         /*
2316          * Make sure there is a card in the slot, then configure the interface.
2317          */
2318         udelay(10000);
2319         debug ("[%d] %s: PIPR(%p)=0x%x\n",
2320                 __LINE__,__FUNCTION__,
2321                 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
2322         if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
2323                 printf ("   No Card found\n");
2324                 return (1);
2325         }
2326
2327         /*
2328          * Power On.
2329          */
2330         printf("%s  Slot %c:", slot ? "" : "\n", 'A' + slot);
2331         mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
2332         reg  = pcmp->pcmc_pipr;
2333         debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
2334                 reg,
2335                 (reg&PCMCIA_VS1(slot))?"n":"ff",
2336                 (reg&PCMCIA_VS2(slot))?"n":"ff");
2337         if ((reg & mask) == mask) {
2338                 puts (" 5.0V card found: NOT SUPPORTED !!!\n");
2339         } else {
2340                 if(slot)
2341                         cp->cp_pbdat &= ~KUP4K_PCMCIA_B_3V3;
2342                 puts (" 3.3V card found: ");
2343         }
2344 #if 0
2345         /*  VCC switch error flag, PCMCIA slot INPACK_ pin */
2346         cp->cp_pbdir &= ~(0x0020 | 0x0010);
2347         cp->cp_pbpar &= ~(0x0020 | 0x0010);
2348         udelay(500000);
2349 #endif
2350         debug ("Enable PCMCIA buffers and stop RESET\n");
2351         reg  =  PCMCIA_PGCRX(slot);
2352         reg &= ~__MY_PCMCIA_GCRX_CXRESET;       /* active high */
2353         reg &= ~__MY_PCMCIA_GCRX_CXOE;          /* active low  */
2354         PCMCIA_PGCRX(slot) = reg;
2355
2356         udelay(250000); /* some cards need >150 ms to come up :-( */
2357
2358         debug ("# hardware_enable done\n");
2359
2360         return (0);
2361 }
2362
2363
2364 #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
2365 static int hardware_disable(int slot)
2366 {
2367         volatile immap_t        *immap;
2368         volatile cpm8xx_t       *cp;
2369         volatile pcmconf8xx_t   *pcmp;
2370         u_long reg;
2371
2372         debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
2373
2374         immap = (immap_t *)CFG_IMMR;
2375         pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
2376         cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
2377
2378         /* remove all power */
2379         if (slot)
2380                 cp->cp_pbdat |= KUP4K_PCMCIA_B_3V3;
2381
2382         /* Configure PCMCIA General Control Register */
2383         debug ("Disable PCMCIA buffers and assert RESET\n");
2384         reg  = 0;
2385         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
2386         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
2387         PCMCIA_PGCRX(slot) = reg;
2388
2389         udelay(10000);
2390
2391         return (0);
2392 }
2393 #endif  /* CFG_CMD_PCMCIA */
2394
2395
2396 static int voltage_set(int slot, int vcc, int vpp)
2397 {
2398         volatile immap_t        *immap;
2399         volatile cpm8xx_t       *cp;
2400         volatile pcmconf8xx_t   *pcmp;
2401         u_long reg;
2402
2403         debug ("voltage_set: "  \
2404                 PCMCIA_BOARD_MSG        \
2405                 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
2406                 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
2407
2408         if (!slot) /* Slot A is not configurable */
2409                 return 0;
2410
2411         immap = (immap_t *)CFG_IMMR;
2412         pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
2413         cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
2414
2415         /*
2416          * Disable PCMCIA buffers (isolate the interface)
2417          * and assert RESET signal
2418          */
2419         debug ("Disable PCMCIA buffers and assert RESET\n");
2420         reg  = PCMCIA_PGCRX(slot);
2421         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
2422         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
2423         PCMCIA_PGCRX(slot) = reg;
2424         udelay(500);
2425
2426         debug ("PCMCIA power OFF\n");
2427         /*
2428          * Configure Port B pins for
2429          * 3 Volts enable
2430          */
2431         cp->cp_pbdir |=  KUP4K_PCMCIA_B_3V3;
2432         cp->cp_pbpar &= ~KUP4K_PCMCIA_B_3V3;
2433         /* remove all power */
2434         cp->cp_pbdat |=  KUP4K_PCMCIA_B_3V3; /* active low */
2435
2436         switch(vcc) {
2437         case  0:                break;
2438         case 33:
2439                 cp->cp_pbdat &= ~KUP4K_PCMCIA_B_3V3;
2440                 debug ("PCMCIA powered at 3.3V\n");
2441                 break;
2442         case 50:
2443                 debug ("PCMCIA: 5Volt vcc not supported\n");
2444                 break;
2445         default:
2446                 puts("PCMCIA: vcc not supported");
2447                 break;
2448         }
2449         udelay(10000);
2450         /* Checking supported voltages */
2451
2452         debug ("PIPR: 0x%x --> %s\n",
2453                 pcmp->pcmc_pipr,
2454                    (pcmp->pcmc_pipr & (0x80000000 >> (slot << 4)))
2455                         ? "only 5 V --> NOT SUPPORTED"
2456                         : "can do 3.3V");
2457
2458
2459         debug ("Enable PCMCIA buffers and stop RESET\n");
2460         reg  =  PCMCIA_PGCRX(slot);
2461         reg &= ~__MY_PCMCIA_GCRX_CXRESET;       /* active high */
2462         reg &= ~__MY_PCMCIA_GCRX_CXOE;          /* active low  */
2463         PCMCIA_PGCRX(slot) = reg;
2464         udelay(500);
2465
2466         debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
2467                 slot+'A');
2468         return (0);
2469 }
2470
2471 #endif  /* KUP4K || KUP4X */
2472
2473
2474 /* -------------------------------------------------------------------- */
2475 /* End of Board Specific Stuff                                          */
2476 /* -------------------------------------------------------------------- */
2477
2478
2479 /* -------------------------------------------------------------------- */
2480 /* MPC8xx Specific Stuff - should go to MPC8xx directory                */
2481 /* -------------------------------------------------------------------- */
2482
2483 /*
2484  * Search this table to see if the windowsize is
2485  * supported...
2486  */
2487
2488 #define M8XX_SIZES_NO 32
2489
2490 static const u_int m8xx_size_to_gray[M8XX_SIZES_NO] =
2491 { 0x00000001, 0x00000002, 0x00000008, 0x00000004,
2492   0x00000080, 0x00000040, 0x00000010, 0x00000020,
2493   0x00008000, 0x00004000, 0x00001000, 0x00002000,
2494   0x00000100, 0x00000200, 0x00000800, 0x00000400,
2495
2496   0x0fffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2497   0x01000000, 0x02000000, 0xffffffff, 0x04000000,
2498   0x00010000, 0x00020000, 0x00080000, 0x00040000,
2499   0x00800000, 0x00400000, 0x00100000, 0x00200000 };
2500
2501
2502 /* -------------------------------------------------------------------- */
2503
2504 #if ( ! defined(CONFIG_I82365) && ! defined(CONFIG_PXA_PCMCIA) )
2505
2506 static u_int m8xx_get_graycode(u_int size)
2507 {
2508         u_int k;
2509
2510         for (k = 0; k < M8XX_SIZES_NO; k++) {
2511                 if(m8xx_size_to_gray[k] == size)
2512                         break;
2513         }
2514
2515         if((k == M8XX_SIZES_NO) || (m8xx_size_to_gray[k] == -1))
2516                 k = -1;
2517
2518         return k;
2519 }
2520
2521 #endif  /* CONFIG_I82365 */
2522
2523 /* -------------------------------------------------------------------- */
2524
2525 #if 0
2526 static u_int m8xx_get_speed(u_int ns, u_int is_io)
2527 {
2528         u_int reg, clocks, psst, psl, psht;
2529
2530         if(!ns) {
2531
2532                 /*
2533                  * We get called with IO maps setup to 0ns
2534                  * if not specified by the user.
2535                  * They should be 255ns.
2536                  */
2537
2538                 if(is_io)
2539                         ns = 255;
2540                 else
2541                         ns = 100;  /* fast memory if 0 */
2542         }
2543
2544         /*
2545          * In PSST, PSL, PSHT fields we tell the controller
2546          * timing parameters in CLKOUT clock cycles.
2547          * CLKOUT is the same as GCLK2_50.
2548          */
2549
2550 /* how we want to adjust the timing - in percent */
2551
2552 #define ADJ 180 /* 80 % longer accesstime - to be sure */
2553
2554         clocks = ((M8XX_BUSFREQ / 1000) * ns) / 1000;
2555         clocks = (clocks * ADJ) / (100*1000);
2556
2557         if(clocks >= PCMCIA_BMT_LIMIT) {
2558                 DEBUG(0, "Max access time limit reached\n");
2559                 clocks = PCMCIA_BMT_LIMIT-1;
2560         }
2561
2562         psst = clocks / 7;          /* setup time */
2563         psht = clocks / 7;          /* hold time */
2564         psl  = (clocks * 5) / 7;    /* strobe length */
2565
2566         psst += clocks - (psst + psht + psl);
2567
2568         reg =  psst << 12;
2569         reg |= psl  << 7;
2570         reg |= psht << 16;
2571
2572         return reg;
2573 }
2574 #endif
2575
2576 /* -------------------------------------------------------------------- */
2577
2578 #if defined(CONFIG_IDE_8xx_PCCARD) || defined(CONFIG_PXA_PCMCIA)
2579 static void print_funcid (int func)
2580 {
2581         puts (indent);
2582         switch (func) {
2583         case CISTPL_FUNCID_MULTI:
2584                 puts (" Multi-Function");
2585                 break;
2586         case CISTPL_FUNCID_MEMORY:
2587                 puts (" Memory");
2588                 break;
2589         case CISTPL_FUNCID_SERIAL:
2590                 puts (" Serial Port");
2591                 break;
2592         case CISTPL_FUNCID_PARALLEL:
2593                 puts (" Parallel Port");
2594                 break;
2595         case CISTPL_FUNCID_FIXED:
2596                 puts (" Fixed Disk");
2597                 break;
2598         case CISTPL_FUNCID_VIDEO:
2599                 puts (" Video Adapter");
2600                 break;
2601         case CISTPL_FUNCID_NETWORK:
2602                 puts (" Network Adapter");
2603                 break;
2604         case CISTPL_FUNCID_AIMS:
2605                 puts (" AIMS Card");
2606                 break;
2607         case CISTPL_FUNCID_SCSI:
2608                 puts (" SCSI Adapter");
2609                 break;
2610         default:
2611                 puts (" Unknown");
2612                 break;
2613         }
2614         puts (" Card\n");
2615 }
2616 #endif  /* CONFIG_IDE_8xx_PCCARD */
2617
2618 /* -------------------------------------------------------------------- */
2619
2620 #if defined(CONFIG_IDE_8xx_PCCARD) || defined(CONFIG_PXA_PCMCIA)
2621 static void print_fixed (volatile uchar *p)
2622 {
2623         if (p == NULL)
2624                 return;
2625
2626         puts(indent);
2627
2628         switch (*p) {
2629         case CISTPL_FUNCE_IDE_IFACE:
2630             {   uchar iface = *(p+2);
2631
2632                 puts ((iface == CISTPL_IDE_INTERFACE) ? " IDE" : " unknown");
2633                 puts (" interface ");
2634                 break;
2635             }
2636         case CISTPL_FUNCE_IDE_MASTER:
2637         case CISTPL_FUNCE_IDE_SLAVE:
2638             {   uchar f1 = *(p+2);
2639                 uchar f2 = *(p+4);
2640
2641                 puts ((f1 & CISTPL_IDE_SILICON) ? " [silicon]" : " [rotating]");
2642
2643                 if (f1 & CISTPL_IDE_UNIQUE)
2644                         puts (" [unique]");
2645
2646                 puts ((f1 & CISTPL_IDE_DUAL) ? " [dual]" : " [single]");
2647
2648                 if (f2 & CISTPL_IDE_HAS_SLEEP)
2649                         puts (" [sleep]");
2650
2651                 if (f2 & CISTPL_IDE_HAS_STANDBY)
2652                         puts (" [standby]");
2653
2654                 if (f2 & CISTPL_IDE_HAS_IDLE)
2655                         puts (" [idle]");
2656
2657                 if (f2 & CISTPL_IDE_LOW_POWER)
2658                         puts (" [low power]");
2659
2660                 if (f2 & CISTPL_IDE_REG_INHIBIT)
2661                         puts (" [reg inhibit]");
2662
2663                 if (f2 & CISTPL_IDE_HAS_INDEX)
2664                         puts (" [index]");
2665
2666                 if (f2 & CISTPL_IDE_IOIS16)
2667                         puts (" [IOis16]");
2668
2669                 break;
2670             }
2671         }
2672         putc ('\n');
2673 }
2674 #endif  /* CONFIG_IDE_8xx_PCCARD */
2675
2676 /* -------------------------------------------------------------------- */
2677
2678 #if defined(CONFIG_IDE_8xx_PCCARD) || defined(CONFIG_PXA_PCMCIA)
2679
2680 #define MAX_IDENT_CHARS         64
2681 #define MAX_IDENT_FIELDS        4
2682
2683 static uchar *known_cards[] = {
2684         "ARGOSY PnPIDE D5",
2685         NULL
2686 };
2687
2688 static int identify  (volatile uchar *p)
2689 {
2690         uchar id_str[MAX_IDENT_CHARS];
2691         uchar data;
2692         uchar *t;
2693         uchar **card;
2694         int i, done;
2695
2696         if (p == NULL)
2697                 return (0);     /* Don't know */
2698
2699         t = id_str;
2700         done =0;
2701
2702         for (i=0; i<=4 && !done; ++i, p+=2) {
2703                 while ((data = *p) != '\0') {
2704                         if (data == 0xFF) {
2705                                 done = 1;
2706                                 break;
2707                         }
2708                         *t++ = data;
2709                         if (t == &id_str[MAX_IDENT_CHARS-1]) {
2710                                 done = 1;
2711                                 break;
2712                         }
2713                         p += 2;
2714                 }
2715                 if (!done)
2716                         *t++ = ' ';
2717         }
2718         *t = '\0';
2719         while (--t > id_str) {
2720                 if (*t == ' ')
2721                         *t = '\0';
2722                 else
2723                         break;
2724         }
2725         puts (id_str);
2726         putc ('\n');
2727
2728         for (card=known_cards; *card; ++card) {
2729                 debug ("## Compare against \"%s\"\n", *card);
2730                 if (strcmp(*card, id_str) == 0) {       /* found! */
2731                         debug ("## CARD FOUND ##\n");
2732                         return (1);
2733                 }
2734         }
2735
2736         return (0);     /* don't know */
2737 }
2738 #endif  /* CONFIG_IDE_8xx_PCCARD */
2739
2740 /* -------------------------------------------------------------------- */
2741 /* NETTA board by Intracom S.A.                                         */
2742 /* -------------------------------------------------------------------- */
2743
2744 #if defined(CONFIG_NETTA)
2745
2746 /* some sane bit macros */
2747 #define _BD(_b)                         (1U << (31-(_b)))
2748 #define _BDR(_l, _h)                    (((((1U << (31-(_l))) - 1) << 1) | 1) & ~((1U << (31-(_h))) - 1))
2749
2750 #define _BW(_b)                         (1U << (15-(_b)))
2751 #define _BWR(_l, _h)                    (((((1U << (15-(_l))) - 1) << 1) | 1) & ~((1U << (15-(_h))) - 1))
2752
2753 #define _BB(_b)                         (1U << (7-(_b)))
2754 #define _BBR(_l, _h)                    (((((1U << (7-(_l))) - 1) << 1) | 1) & ~((1U << (7-(_h))) - 1))
2755
2756 #define _B(_b)                          _BD(_b)
2757 #define _BR(_l, _h)                     _BDR(_l, _h)
2758
2759 #define PCMCIA_BOARD_MSG "NETTA"
2760
2761 static const unsigned short vppd_masks[2] = { _BW(14), _BW(15) };
2762
2763 static void cfg_vppd(int no)
2764 {
2765         volatile immap_t *immap = (immap_t *)CFG_IMMR;
2766         unsigned short mask;
2767
2768         if ((unsigned int)no >= sizeof(vppd_masks)/sizeof(vppd_masks[0]))
2769                 return;
2770
2771         mask = vppd_masks[no];
2772
2773         immap->im_ioport.iop_papar &= ~mask;
2774         immap->im_ioport.iop_paodr &= ~mask;
2775         immap->im_ioport.iop_padir |=  mask;
2776 }
2777
2778 static void set_vppd(int no, int what)
2779 {
2780         volatile immap_t *immap = (immap_t *)CFG_IMMR;
2781         unsigned short mask;
2782
2783         if ((unsigned int)no >= sizeof(vppd_masks)/sizeof(vppd_masks[0]))
2784                 return;
2785
2786         mask = vppd_masks[no];
2787
2788         if (what)
2789                 immap->im_ioport.iop_padat |= mask;
2790         else
2791                 immap->im_ioport.iop_padat &= ~mask;
2792 }
2793
2794 static const unsigned short vccd_masks[2] = { _BW(10), _BW(6) };
2795
2796 static void cfg_vccd(int no)
2797 {
2798         volatile immap_t *immap = (immap_t *)CFG_IMMR;
2799         unsigned short mask;
2800
2801         if ((unsigned int)no >= sizeof(vccd_masks)/sizeof(vccd_masks[0]))
2802                 return;
2803
2804         mask = vccd_masks[no];
2805
2806         immap->im_ioport.iop_papar &= ~mask;
2807         immap->im_ioport.iop_paodr &= ~mask;
2808         immap->im_ioport.iop_padir |=  mask;
2809 }
2810
2811 static void set_vccd(int no, int what)
2812 {
2813         volatile immap_t *immap = (immap_t *)CFG_IMMR;
2814         unsigned short mask;
2815
2816         if ((unsigned int)no >= sizeof(vccd_masks)/sizeof(vccd_masks[0]))
2817                 return;
2818
2819         mask = vccd_masks[no];
2820
2821         if (what)
2822                 immap->im_ioport.iop_padat |= mask;
2823         else
2824                 immap->im_ioport.iop_padat &= ~mask;
2825 }
2826
2827 static const unsigned short oc_mask = _BW(8);
2828
2829 static void cfg_oc(void)
2830 {
2831         volatile immap_t *immap = (immap_t *)CFG_IMMR;
2832         unsigned short mask = oc_mask;
2833
2834         immap->im_ioport.iop_pcdir &= ~mask;
2835         immap->im_ioport.iop_pcso  &= ~mask;
2836         immap->im_ioport.iop_pcint &= ~mask;
2837         immap->im_ioport.iop_pcpar &= ~mask;
2838 }
2839
2840 static int get_oc(void)
2841 {
2842         volatile immap_t *immap = (immap_t *)CFG_IMMR;
2843         unsigned short mask = oc_mask;
2844         int what;
2845
2846         what = !!(immap->im_ioport.iop_pcdat & mask);;
2847         return what;
2848 }
2849
2850 static const unsigned short shdn_mask = _BW(12);
2851
2852 static void cfg_shdn(void)
2853 {
2854         volatile immap_t *immap = (immap_t *)CFG_IMMR;
2855         unsigned short mask;
2856
2857         mask = shdn_mask;
2858
2859         immap->im_ioport.iop_papar &= ~mask;
2860         immap->im_ioport.iop_paodr &= ~mask;
2861         immap->im_ioport.iop_padir |=  mask;
2862 }
2863
2864 static void set_shdn(int what)
2865 {
2866         volatile immap_t *immap = (immap_t *)CFG_IMMR;
2867         unsigned short mask;
2868
2869         mask = shdn_mask;
2870
2871         if (what)
2872                 immap->im_ioport.iop_padat |= mask;
2873         else
2874                 immap->im_ioport.iop_padat &= ~mask;
2875 }
2876
2877 static void cfg_ports (void);
2878
2879 static int hardware_enable(int slot)
2880 {
2881         volatile immap_t        *immap;
2882         volatile cpm8xx_t       *cp;
2883         volatile pcmconf8xx_t   *pcmp;
2884         volatile sysconf8xx_t   *sysp;
2885         uint reg, pipr, mask;
2886         int i;
2887
2888         debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
2889
2890         udelay(10000);
2891
2892         immap = (immap_t *)CFG_IMMR;
2893         sysp  = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
2894         pcmp  = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
2895         cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
2896
2897         /* Configure Ports for TPS2211A PC-Card Power-Interface Switch */
2898         cfg_ports ();
2899
2900         /* clear interrupt state, and disable interrupts */
2901         pcmp->pcmc_pscr =  PCMCIA_MASK(_slot_);
2902         pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
2903
2904         /*
2905          * Disable interrupts, DMA, and PCMCIA buffers
2906          * (isolate the interface) and assert RESET signal
2907          */
2908         debug ("Disable PCMCIA buffers and assert RESET\n");
2909         reg  = 0;
2910         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
2911         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
2912         PCMCIA_PGCRX(_slot_) = reg;
2913
2914         udelay(500);
2915
2916         /*
2917          * Make sure there is a card in the slot, then configure the interface.
2918          */
2919         udelay(10000);
2920         debug ("[%d] %s: PIPR(%p)=0x%x\n",
2921                 __LINE__,__FUNCTION__,
2922                 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
2923         if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
2924                 printf ("   No Card found\n");
2925                 return (1);
2926         }
2927
2928         /*
2929          * Power On: Set VAVCC to 3.3V or 5V, set VAVPP to Hi-Z
2930          */
2931         mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
2932         pipr = pcmp->pcmc_pipr;
2933         debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
2934                 pipr,
2935                 (reg&PCMCIA_VS1(slot))?"n":"ff",
2936                 (reg&PCMCIA_VS2(slot))?"n":"ff");
2937
2938         if ((pipr & mask) == mask) {
2939                 set_vppd(0, 1); set_vppd(1, 1);                 /* VAVPP => Hi-Z */
2940                 set_vccd(0, 0); set_vccd(1, 1);                 /* 5V on, 3V off */
2941                 puts (" 5.0V card found: ");
2942         } else {
2943                 set_vppd(0, 1); set_vppd(1, 1);                 /* VAVPP => Hi-Z */
2944                 set_vccd(0, 1); set_vccd(1, 0);                 /* 5V off, 3V on */
2945                 puts (" 3.3V card found: ");
2946         }
2947
2948         /*  Wait 500 ms; use this to check for over-current */
2949         for (i=0; i<5000; ++i) {
2950                 if (!get_oc()) {
2951                         printf ("   *** Overcurrent - Safety shutdown ***\n");
2952                         set_vccd(0, 0); set_vccd(1, 0);                 /* VAVPP => Hi-Z */
2953                         return (1);
2954                 }
2955                 udelay (100);
2956         }
2957
2958         debug ("Enable PCMCIA buffers and stop RESET\n");
2959         reg  =  PCMCIA_PGCRX(_slot_);
2960         reg &= ~__MY_PCMCIA_GCRX_CXRESET;       /* active high */
2961         reg &= ~__MY_PCMCIA_GCRX_CXOE;          /* active low  */
2962         PCMCIA_PGCRX(_slot_) = reg;
2963
2964         udelay(250000); /* some cards need >150 ms to come up :-( */
2965
2966         debug ("# hardware_enable done\n");
2967
2968         return (0);
2969 }
2970
2971
2972 #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
2973 static int hardware_disable(int slot)
2974 {
2975         volatile immap_t        *immap;
2976         volatile pcmconf8xx_t   *pcmp;
2977         u_long reg;
2978
2979         debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
2980
2981         immap = (immap_t *)CFG_IMMR;
2982         pcmp  = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
2983
2984         /* Configure PCMCIA General Control Register */
2985         debug ("Disable PCMCIA buffers and assert RESET\n");
2986         reg  = 0;
2987         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
2988         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
2989         PCMCIA_PGCRX(_slot_) = reg;
2990
2991         /* All voltages off / Hi-Z */
2992                         set_vppd(0, 1); set_vppd(1, 1);
2993         set_vccd(0, 1); set_vccd(1, 1);
2994
2995         udelay(10000);
2996
2997         return (0);
2998 }
2999 #endif  /* CFG_CMD_PCMCIA */
3000
3001
3002 static int voltage_set(int slot, int vcc, int vpp)
3003 {
3004         volatile immap_t        *immap;
3005         volatile cpm8xx_t       *cp;
3006         volatile pcmconf8xx_t   *pcmp;
3007         u_long reg;
3008         ushort sreg;
3009
3010         debug ("voltage_set: "
3011                 PCMCIA_BOARD_MSG
3012                 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
3013                 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
3014
3015         immap = (immap_t *)CFG_IMMR;
3016         cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
3017         pcmp  = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
3018         /*
3019          * Disable PCMCIA buffers (isolate the interface)
3020          * and assert RESET signal
3021          */
3022         debug ("Disable PCMCIA buffers and assert RESET\n");
3023         reg  = PCMCIA_PGCRX(_slot_);
3024         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
3025         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
3026         PCMCIA_PGCRX(_slot_) = reg;
3027         udelay(500);
3028
3029         /*
3030          * Configure Port C pins for
3031          * 5 Volts Enable and 3 Volts enable,
3032          * Turn all power pins to Hi-Z
3033          */
3034         debug ("PCMCIA power OFF\n");
3035         cfg_ports ();   /* Enables switch, but all in Hi-Z */
3036
3037         sreg  = immap->im_ioport.iop_pcdat;
3038         set_vppd(0, 1); set_vppd(1, 1);
3039
3040         switch(vcc) {
3041         case  0:
3042                 break;  /* Switch off           */
3043
3044         case 33:
3045                 set_vccd(0, 1); set_vccd(1, 0);
3046                 break;
3047
3048         case 50:
3049                 set_vccd(0, 0); set_vccd(1, 1);
3050                 break;
3051
3052         default:
3053                 goto done;
3054         }
3055
3056         /* Checking supported voltages */
3057
3058         debug ("PIPR: 0x%x --> %s\n",
3059                 pcmp->pcmc_pipr,
3060                 (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
3061
3062 done:
3063         debug ("Enable PCMCIA buffers and stop RESET\n");
3064         reg  =  PCMCIA_PGCRX(_slot_);
3065         reg &= ~__MY_PCMCIA_GCRX_CXRESET;       /* active high */
3066         reg &= ~__MY_PCMCIA_GCRX_CXOE;          /* active low  */
3067         PCMCIA_PGCRX(_slot_) = reg;
3068         udelay(500);
3069
3070         debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
3071                 slot+'A');
3072         return (0);
3073 }
3074
3075 static void cfg_ports (void)
3076 {
3077         volatile immap_t        *immap;
3078         volatile cpm8xx_t       *cp;
3079
3080         immap = (immap_t *)CFG_IMMR;
3081         cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
3082
3083
3084         cfg_vppd(0); cfg_vppd(1);       /* VPPD0,VPPD1 VAVPP => Hi-Z */
3085         cfg_vccd(0); cfg_vccd(1);       /* 3V and 5V off */
3086         cfg_shdn();
3087         cfg_oc();
3088
3089         /*
3090          * Configure Port A for TPS2211 PC-Card Power-Interface Switch
3091          *
3092          * Switch off all voltages, assert shutdown
3093          */
3094         set_vppd(0, 1); set_vppd(1, 1);
3095         set_vccd(0, 0); set_vccd(1, 0);
3096         set_shdn(1);
3097
3098         udelay(100000);
3099 }
3100
3101 #endif  /* NETTA */
3102
3103
3104 /* -------------------------------------------------------------------- */
3105 /* UC100 Boards                                                         */
3106 /* -------------------------------------------------------------------- */
3107
3108 #if defined(CONFIG_UC100)
3109
3110 #define PCMCIA_BOARD_MSG "UC100"
3111
3112 /*
3113  * Remark: don't turn off OE "__MY_PCMCIA_GCRX_CXOE" on UC100 board.
3114  *         This leads to board-hangup! (sr, 8 Dez. 2004)
3115  */
3116
3117 static void cfg_ports (void);
3118
3119 static int hardware_enable(int slot)
3120 {
3121         volatile immap_t        *immap;
3122         volatile cpm8xx_t       *cp;
3123         volatile pcmconf8xx_t   *pcmp;
3124         volatile sysconf8xx_t   *sysp;
3125         uint reg, mask;
3126
3127         debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
3128
3129         udelay(10000);
3130
3131         immap = (immap_t *)CFG_IMMR;
3132         sysp  = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
3133         pcmp  = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
3134         cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
3135
3136         /* Configure Ports for TPS2211A PC-Card Power-Interface Switch */
3137         cfg_ports ();
3138
3139         /*
3140          * Configure SIUMCR to enable PCMCIA port B
3141          * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
3142          */
3143         sysp->sc_siumcr &= ~SIUMCR_DBGC11;      /* set DBGC to 00 */
3144
3145         /* clear interrupt state, and disable interrupts */
3146         pcmp->pcmc_pscr =  PCMCIA_MASK(_slot_);
3147         pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
3148
3149         /*
3150          * Disable interrupts, DMA, and PCMCIA buffers
3151          * (isolate the interface) and assert RESET signal
3152          */
3153         debug ("Disable PCMCIA buffers and assert RESET\n");
3154         reg  = 0;
3155         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
3156         PCMCIA_PGCRX(_slot_) = reg;
3157         udelay(500);
3158
3159         /*
3160          * Make sure there is a card in the slot, then configure the interface.
3161          */
3162         udelay(10000);
3163         debug ("[%d] %s: PIPR(%p)=0x%x\n",
3164                 __LINE__,__FUNCTION__,
3165                 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
3166         if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
3167                 printf ("   No Card found\n");
3168                 return (1);
3169         }
3170
3171         /*
3172          * Power On.
3173          */
3174         mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
3175         reg  = pcmp->pcmc_pipr;
3176         debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
3177                 reg,
3178                 (reg&PCMCIA_VS1(slot))?"n":"ff",
3179                 (reg&PCMCIA_VS2(slot))?"n":"ff");
3180         if ((reg & mask) == mask) {
3181                 puts (" 5.0V card found: ");
3182         } else {
3183                 puts (" 3.3V card found: ");
3184         }
3185
3186         /*  switch VCC on */
3187         immap->im_ioport.iop_padat |= 0x8000; /* power enable 3.3V */
3188
3189         udelay(10000);
3190
3191         debug ("Enable PCMCIA buffers and stop RESET\n");
3192         reg  =  PCMCIA_PGCRX(_slot_);
3193         reg &= ~__MY_PCMCIA_GCRX_CXRESET;       /* active high */
3194         reg &= ~__MY_PCMCIA_GCRX_CXOE;          /* active low  */
3195         PCMCIA_PGCRX(_slot_) = reg;
3196
3197         udelay(250000); /* some cards need >150 ms to come up :-( */
3198
3199         debug ("# hardware_enable done\n");
3200
3201         return (0);
3202 }
3203
3204
3205 #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
3206 static int hardware_disable(int slot)
3207 {
3208         volatile immap_t        *immap;
3209         volatile cpm8xx_t       *cp;
3210         volatile pcmconf8xx_t   *pcmp;
3211         u_long reg;
3212
3213         debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
3214
3215         immap = (immap_t *)CFG_IMMR;
3216         pcmp  = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
3217
3218         /* switch VCC off */
3219         immap->im_ioport.iop_padat &= ~0x8000; /* power disable 3.3V */
3220
3221         /* Configure PCMCIA General Control Register */
3222         debug ("Disable PCMCIA buffers and assert RESET\n");
3223         reg  = 0;
3224         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
3225         PCMCIA_PGCRX(_slot_) = reg;
3226
3227         udelay(10000);
3228
3229         return (0);
3230 }
3231 #endif  /* CFG_CMD_PCMCIA */
3232
3233
3234 static int voltage_set(int slot, int vcc, int vpp)
3235 {
3236         volatile immap_t        *immap;
3237         volatile pcmconf8xx_t   *pcmp;
3238         u_long reg;
3239
3240         debug ("voltage_set: "
3241                 PCMCIA_BOARD_MSG
3242                 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
3243                 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
3244
3245         immap = (immap_t *)CFG_IMMR;
3246         pcmp  = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
3247         /*
3248          * Disable PCMCIA buffers (isolate the interface)
3249          * and assert RESET signal
3250          */
3251         debug ("Disable PCMCIA buffers and assert RESET\n");
3252         reg  = PCMCIA_PGCRX(_slot_);
3253         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
3254         PCMCIA_PGCRX(_slot_) = reg;
3255         udelay(500);
3256
3257         /*
3258          * Configure Port C pins for
3259          * 5 Volts Enable and 3 Volts enable,
3260          * Turn all power pins to Hi-Z
3261          */
3262         debug ("PCMCIA power OFF\n");
3263         cfg_ports ();   /* Enables switch, but all in Hi-Z */
3264
3265         debug ("Enable PCMCIA buffers and stop RESET\n");
3266         reg  =  PCMCIA_PGCRX(_slot_);
3267         reg &= ~__MY_PCMCIA_GCRX_CXRESET;       /* active high */
3268         reg &= ~__MY_PCMCIA_GCRX_CXOE;          /* active low  */
3269         PCMCIA_PGCRX(_slot_) = reg;
3270         udelay(500);
3271
3272         debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
3273                 slot+'A');
3274         return (0);
3275 }
3276
3277 static void cfg_ports (void)
3278 {
3279         volatile immap_t        *immap;
3280
3281         immap = (immap_t *)CFG_IMMR;
3282
3283         /*
3284          * Configure Port A for MAX1602 PC-Card Power-Interface Switch
3285          */
3286         immap->im_ioport.iop_padat &= ~0x8000;  /* set port x output to low */
3287         immap->im_ioport.iop_padir |= 0x8000;   /* enable port x as output */
3288
3289         debug ("Set Port A: PAR: %08x DIR: %08x DAT: %08x\n",
3290                immap->im_ioport.iop_papar, immap->im_ioport.iop_padir,
3291                immap->im_ioport.iop_padat);
3292 }
3293
3294 #endif  /* UC100 */
3295
3296
3297 /* -------------------------------------------------------------------- */
3298
3299 #endif /* CFG_CMD_PCMCIA || (CFG_CMD_IDE && CONFIG_IDE_8xx_PCCARD) */
3300
3301 /**************************************************/
3302
3303 #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
3304 U_BOOT_CMD(
3305         pinit,  2,      1,      do_pinit,
3306         "pinit   - PCMCIA sub-system\n",
3307         "on  - power on PCMCIA socket\n"
3308         "pinit off - power off PCMCIA socket\n"
3309 );
3310 #endif