]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - common/cmd_pcmcia.c
Fix PCMCIA support on virtlab2
[karo-tx-uboot.git] / common / cmd_pcmcia.c
1 /*
2  * (C) Copyright 2000-2006
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         && !defined(CONFIG_VIRTLAB2)
723
724 #if defined(CONFIG_TQM8xxL)
725 #define PCMCIA_BOARD_MSG "TQM8xxL"
726 #endif
727 #if defined(CONFIG_SVM_SC8xx)
728 #define PCMCIA_BOARD_MSG "SC8xx"
729 #endif
730
731 static int hardware_enable(int slot)
732 {
733         volatile immap_t        *immap;
734         volatile cpm8xx_t       *cp;
735         volatile pcmconf8xx_t   *pcmp;
736         volatile sysconf8xx_t   *sysp;
737         uint reg, mask;
738
739         debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
740
741         udelay(10000);
742
743         immap = (immap_t *)CFG_IMMR;
744         sysp  = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
745         pcmp  = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
746         cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
747
748         /*
749          * Configure SIUMCR to enable PCMCIA port B
750          * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
751          */
752         sysp->sc_siumcr &= ~SIUMCR_DBGC11;      /* set DBGC to 00 */
753
754         /* clear interrupt state, and disable interrupts */
755         pcmp->pcmc_pscr =  PCMCIA_MASK(slot);
756         pcmp->pcmc_per &= ~PCMCIA_MASK(slot);
757
758         /*
759          * Disable interrupts, DMA, and PCMCIA buffers
760          * (isolate the interface) and assert RESET signal
761          */
762         debug ("Disable PCMCIA buffers and assert RESET\n");
763         reg  = 0;
764         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
765 #ifndef NSCU_OE_INV
766         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
767 #endif
768         PCMCIA_PGCRX(slot) = reg;
769         udelay(500);
770
771 #ifndef CONFIG_HMI10
772 #ifndef CONFIG_NSCU
773         /*
774          * Configure Port C pins for
775          * 5 Volts Enable and 3 Volts enable
776          */
777         immap->im_ioport.iop_pcpar &= ~(0x0002 | 0x0004);
778         immap->im_ioport.iop_pcso  &= ~(0x0002 | 0x0004);
779         /* remove all power */
780
781         immap->im_ioport.iop_pcdat &= ~(0x0002 | 0x0004);
782 #endif
783 #else   /* CONFIG_HMI10 */
784         /*
785          * Configure Port B  pins for
786          * 5 Volts Enable and 3 Volts enable
787          */
788         immap->im_cpm.cp_pbpar &= ~(0x00000300);
789
790         /* remove all power */
791         immap->im_cpm.cp_pbdat |= 0x00000300;
792 #endif  /* CONFIG_HMI10 */
793
794         /*
795          * Make sure there is a card in the slot, then configure the interface.
796          */
797         udelay(10000);
798         debug ("[%d] %s: PIPR(%p)=0x%x\n",
799                 __LINE__,__FUNCTION__,
800                 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
801 #ifndef CONFIG_HMI10
802         if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
803 #else
804         if (pcmp->pcmc_pipr & (0x10000000 >> (slot << 4))) {
805 #endif  /* CONFIG_HMI10 */
806                 printf ("   No Card found\n");
807                 return (1);
808         }
809
810         /*
811          * Power On.
812          */
813         mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
814         reg  = pcmp->pcmc_pipr;
815         debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
816                 reg,
817                 (reg&PCMCIA_VS1(slot))?"n":"ff",
818                 (reg&PCMCIA_VS2(slot))?"n":"ff");
819 #ifndef CONFIG_NSCU
820         if ((reg & mask) == mask) {
821 #ifndef CONFIG_HMI10
822                 immap->im_ioport.iop_pcdat |= 0x0004;
823 #else
824                 immap->im_cpm.cp_pbdat &= ~(0x0000100);
825 #endif  /* CONFIG_HMI10 */
826                 puts (" 5.0V card found: ");
827         } else {
828 #ifndef CONFIG_HMI10
829                 immap->im_ioport.iop_pcdat |= 0x0002;
830 #else
831                 immap->im_cpm.cp_pbdat &= ~(0x0000200);
832 #endif  /* CONFIG_HMI10 */
833                 puts (" 3.3V card found: ");
834         }
835 #ifndef CONFIG_HMI10
836         immap->im_ioport.iop_pcdir |= (0x0002 | 0x0004);
837 #else
838         immap->im_cpm.cp_pbdir |= 0x00000300;
839 #endif  /* CONFIG_HMI10 */
840 #else
841         if ((reg & mask) == mask) {
842                 puts (" 5.0V card found: ");
843         } else {
844                 puts (" 3.3V card found: ");
845         }
846 #endif
847 #if 0
848         /*  VCC switch error flag, PCMCIA slot INPACK_ pin */
849         cp->cp_pbdir &= ~(0x0020 | 0x0010);
850         cp->cp_pbpar &= ~(0x0020 | 0x0010);
851         udelay(500000);
852 #endif
853         udelay(1000);
854         debug ("Enable PCMCIA buffers and stop RESET\n");
855         reg  =  PCMCIA_PGCRX(slot);
856         reg &= ~__MY_PCMCIA_GCRX_CXRESET;       /* active high */
857 #ifndef NSCU_OE_INV
858         reg &= ~__MY_PCMCIA_GCRX_CXOE;          /* active low  */
859 #else
860         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
861 #endif
862         PCMCIA_PGCRX(slot) = reg;
863
864         udelay(250000); /* some cards need >150 ms to come up :-( */
865
866         debug ("# hardware_enable done\n");
867
868         return (0);
869 }
870
871
872 #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
873 static int hardware_disable(int slot)
874 {
875         volatile immap_t        *immap;
876         volatile pcmconf8xx_t   *pcmp;
877         u_long reg;
878
879         debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
880
881         immap = (immap_t *)CFG_IMMR;
882         pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
883
884 #ifndef CONFIG_HMI10
885 #ifndef CONFIG_NSCU
886         /* remove all power */
887         immap->im_ioport.iop_pcdat &= ~(0x0002 | 0x0004);
888 #endif
889 #else   /* CONFIG_HMI10 */
890         immap->im_cpm.cp_pbdat |= 0x00000300;
891 #endif  /* CONFIG_HMI10 */
892
893         debug ("Disable PCMCIA buffers and assert RESET\n");
894         reg  = 0;
895         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
896 #ifndef NSCU_OE_INV
897         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
898 #endif
899         PCMCIA_PGCRX(slot) = reg;
900
901         udelay(10000);
902
903         return (0);
904 }
905 #endif  /* CFG_CMD_PCMCIA */
906
907 #ifdef CONFIG_NSCU
908 static int voltage_set(int slot, int vcc, int vpp)
909 {
910         return 0;
911 }
912 #else
913 static int voltage_set(int slot, int vcc, int vpp)
914 {
915         volatile immap_t        *immap;
916         volatile pcmconf8xx_t   *pcmp;
917         u_long reg;
918
919         debug ("voltage_set: "
920                 PCMCIA_BOARD_MSG
921                 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
922                 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
923
924         immap = (immap_t *)CFG_IMMR;
925         pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
926         /*
927          * Disable PCMCIA buffers (isolate the interface)
928          * and assert RESET signal
929          */
930         debug ("Disable PCMCIA buffers and assert RESET\n");
931         reg  = PCMCIA_PGCRX(slot);
932         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
933 #ifndef NSCU_OE_INV
934         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
935 #else
936         reg &= ~__MY_PCMCIA_GCRX_CXOE;          /* active low  */
937 #endif
938         PCMCIA_PGCRX(slot) = reg;
939         udelay(500);
940
941 #ifndef CONFIG_HMI10
942         /*
943          * Configure Port C pins for
944          * 5 Volts Enable and 3 Volts enable,
945          * Turn off all power
946          */
947         debug ("PCMCIA power OFF\n");
948         immap->im_ioport.iop_pcpar &= ~(0x0002 | 0x0004);
949         immap->im_ioport.iop_pcso  &= ~(0x0002 | 0x0004);
950         immap->im_ioport.iop_pcdat &= ~(0x0002 | 0x0004);
951
952         reg = 0;
953         switch(vcc) {
954         case  0:                break;
955         case 33: reg |= 0x0002; break;
956         case 50: reg |= 0x0004; break;
957         default:                goto done;
958         }
959 #else   /* CONFIG_HMI10 */
960         /*
961          * Configure Port B pins for
962          * 5 Volts Enable and 3 Volts enable,
963          * Turn off all power
964          */
965         debug ("PCMCIA power OFF\n");
966         immap->im_cpm.cp_pbpar &= ~(0x00000300);
967         /* remove all power */
968
969         immap->im_cpm.cp_pbdat |= 0x00000300;
970
971         reg = 0;
972         switch(vcc) {
973                 case  0:                        break;
974                 case 33: reg |= 0x00000200;     break;
975                 case 50: reg |= 0x00000100;     break;
976                 default:                        goto done;
977 }
978 #endif  /* CONFIG_HMI10 */
979
980         /* Checking supported voltages */
981
982         debug ("PIPR: 0x%x --> %s\n",
983                 pcmp->pcmc_pipr,
984                 (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
985
986 #ifndef CONFIG_HMI10
987         immap->im_ioport.iop_pcdat |= reg;
988         immap->im_ioport.iop_pcdir |= (0x0002 | 0x0004);
989 #else
990         immap->im_cpm.cp_pbdat &= !reg;
991         immap->im_cpm.cp_pbdir |= 0x00000300;
992 #endif  /* CONFIG_HMI10 */
993         if (reg) {
994 #ifndef CONFIG_HMI10
995                 debug ("PCMCIA powered at %sV\n",
996                         (reg&0x0004) ? "5.0" : "3.3");
997 #else
998                 debug ("PCMCIA powered at %sV\n",
999                         (reg&0x00000200) ? "5.0" : "3.3");
1000 #endif  /* CONFIG_HMI10 */
1001         } else {
1002                 debug ("PCMCIA powered down\n");
1003         }
1004
1005 done:
1006         debug ("Enable PCMCIA buffers and stop RESET\n");
1007         reg  =  PCMCIA_PGCRX(slot);
1008         reg &= ~__MY_PCMCIA_GCRX_CXRESET;       /* active high */
1009 #ifndef NSCU_OE_INV
1010         reg &= ~__MY_PCMCIA_GCRX_CXOE;          /* active low  */
1011 #else
1012         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
1013 #endif
1014         PCMCIA_PGCRX(slot) = reg;
1015         udelay(500);
1016
1017         debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
1018                 slot+'A');
1019         return (0);
1020 }
1021 #endif
1022
1023 #endif  /* TQM8xxL */
1024
1025 /* -------------------------------------------------------------------- */
1026 /* Virtlab2 Board by TQ Components                                      */
1027 /* -------------------------------------------------------------------- */
1028
1029 #if defined(CONFIG_VIRTLAB2)
1030 #define PCMCIA_BOARD_MSG "Virtlab2"
1031
1032 static int hardware_enable(int slot)
1033 {
1034         volatile pcmconf8xx_t   *pcmp =
1035                 (pcmconf8xx_t *)&(((immap_t *)CFG_IMMR)->im_pcmcia);
1036         volatile unsigned char  *powerctl =
1037                 (volatile unsigned char *)PCMCIA_CTRL;
1038         volatile sysconf8xx_t   *sysp =
1039                 (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
1040         unsigned int            reg, mask;
1041
1042         debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1043
1044         udelay(10000);
1045
1046         /*
1047          * Configure SIUMCR to enable PCMCIA port B
1048          */
1049         sysp->sc_siumcr &= ~SIUMCR_DBGC11;      /* set DBGC to 00 */
1050
1051         /* clear interrupt state, and disable interrupts */
1052         pcmp->pcmc_pscr =  PCMCIA_MASK(slot);
1053         pcmp->pcmc_per &= ~PCMCIA_MASK(slot);
1054
1055         /*
1056          * Disable interrupts, DMA, and PCMCIA buffers
1057          * (isolate the interface) and assert RESET signal
1058          */
1059         debug ("Disable PCMCIA buffers and assert RESET\n");
1060         reg = __MY_PCMCIA_GCRX_CXRESET;         /* active high */
1061         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
1062
1063         PCMCIA_PGCRX(slot) = reg;
1064         udelay(500);
1065
1066         /* remove all power */
1067         *powerctl = 0;
1068
1069         /*
1070          * Make sure there is a card in the slot, then configure the interface.
1071          */
1072         udelay(10000);
1073         debug ("[%d] %s: PIPR(%p)=0x%x\n", __LINE__,__FUNCTION__,
1074                 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
1075
1076         if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
1077                 printf ("   No Card found\n");
1078                 return (1);
1079         }
1080
1081         /*
1082          * Power On.
1083          */
1084         mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
1085         reg  = pcmp->pcmc_pipr;
1086         debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n", reg,
1087                 (reg&PCMCIA_VS1(slot))?"n":"ff",
1088                 (reg&PCMCIA_VS2(slot))?"n":"ff");
1089
1090         if ((reg & mask) == mask) {
1091                 *powerctl = 2;  /* Enable 5V Vccout */
1092                 puts (" 5.0V card found: ");
1093         } else {
1094                 *powerctl = 1;  /* Enable 3.3 V Vccout */
1095                 puts (" 3.3V card found: ");
1096         }
1097
1098         udelay(1000);
1099         debug ("Enable PCMCIA buffers and stop RESET\n");
1100         reg  =  PCMCIA_PGCRX(slot);
1101         reg &= ~__MY_PCMCIA_GCRX_CXRESET;       /* active high */
1102         reg &= ~__MY_PCMCIA_GCRX_CXOE;          /* active low  */
1103
1104         PCMCIA_PGCRX(slot) = reg;
1105
1106         udelay(250000); /* some cards need >150 ms to come up :-( */
1107
1108         debug ("# hardware_enable done\n");
1109
1110         return (0);
1111 }
1112
1113 #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
1114 static int hardware_disable(int slot)
1115 {
1116         volatile unsigned char  *powerctl =
1117                 (volatile unsigned char *)PCMCIA_CTRL;
1118         unsigned long            reg;
1119
1120         debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1121
1122         /* remove all power */
1123         *powerctl = 0;
1124
1125         debug ("Disable PCMCIA buffers and assert RESET\n");
1126         reg = __MY_PCMCIA_GCRX_CXRESET;         /* active high */
1127         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
1128
1129         PCMCIA_PGCRX(slot) = reg;
1130
1131         udelay(10000);
1132
1133         return (0);
1134 }
1135 #endif
1136
1137 static int voltage_set(int slot, int vcc, int vpp)
1138 {
1139 #ifdef DEBUG
1140         volatile pcmconf8xx_t   *pcmp =
1141                 (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1142 #endif
1143         volatile unsigned char  *powerctl =
1144                 (volatile unsigned char *)PCMCIA_CTRL;
1145         unsigned long           reg;
1146
1147         debug ("voltage_set: " PCMCIA_BOARD_MSG
1148                 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
1149                 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
1150
1151         /*
1152          * Disable PCMCIA buffers (isolate the interface)
1153          * and assert RESET signal
1154          */
1155         debug ("Disable PCMCIA buffers and assert RESET\n");
1156         reg  = PCMCIA_PGCRX(slot);
1157         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
1158         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
1159
1160         PCMCIA_PGCRX(slot) = reg;
1161         udelay(500);
1162
1163         /*
1164          * Configure pins for 5 Volts Enable and 3 Volts enable,
1165          * Turn off all power.
1166          */
1167         debug ("PCMCIA power OFF\n");
1168         reg = 0;
1169         switch(vcc) {
1170         case  0:                break;
1171         case 33: reg = 0x0001;  break;
1172         case 50: reg = 0x0002;  break;
1173         default:                goto done;
1174         }
1175
1176         /* Checking supported voltages */
1177
1178         debug ("PIPR: 0x%x --> %s\n", pcmp->pcmc_pipr,
1179                 (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
1180
1181         *powerctl = reg;
1182
1183         if (reg) {
1184                 debug ("PCMCIA powered at %sV\n", (reg&0x0004) ? "5.0" : "3.3");
1185         } else {
1186                 debug ("PCMCIA powered down\n");
1187         }
1188
1189 done:
1190         debug ("Enable PCMCIA buffers and stop RESET\n");
1191         reg  =  PCMCIA_PGCRX(slot);
1192         reg &= ~__MY_PCMCIA_GCRX_CXRESET;       /* active high */
1193         reg &= ~__MY_PCMCIA_GCRX_CXOE;          /* active low  */
1194
1195         PCMCIA_PGCRX(slot) = reg;
1196         udelay(500);
1197
1198         debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n", slot+'A');
1199         return (0);
1200 }
1201 #endif  /* CONFIG_VIRTLAB2 */
1202
1203 /* -------------------------------------------------------------------- */
1204 /* LWMON Board                                                          */
1205 /* -------------------------------------------------------------------- */
1206
1207 #if defined(CONFIG_LWMON)
1208
1209 #define PCMCIA_BOARD_MSG "LWMON"
1210
1211 /* #define's for MAX1604 Power Switch */
1212 #define MAX1604_OP_SUS          0x80
1213 #define MAX1604_VCCBON          0x40
1214 #define MAX1604_VCC_35          0x20
1215 #define MAX1604_VCCBHIZ         0x10
1216 #define MAX1604_VPPBON          0x08
1217 #define MAX1604_VPPBPBPGM       0x04
1218 #define MAX1604_VPPBHIZ         0x02
1219 /* reserved                     0x01    */
1220
1221 static int hardware_enable(int slot)
1222 {
1223         volatile immap_t        *immap;
1224         volatile cpm8xx_t       *cp;
1225         volatile pcmconf8xx_t   *pcmp;
1226         volatile sysconf8xx_t   *sysp;
1227         uint reg, mask;
1228         uchar val;
1229
1230
1231         debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1232
1233         /* Switch on PCMCIA port in PIC register 0x60 */
1234         reg = pic_read  (0x60);
1235         debug ("[%d] PIC read: reg_60 = 0x%02x\n", __LINE__, reg);
1236         reg &= ~0x10;
1237         /* reg |= 0x08; Vpp not needed */
1238         pic_write (0x60, reg);
1239 #ifdef DEBUG
1240         reg = pic_read  (0x60);
1241         printf ("[%d] PIC read: reg_60 = 0x%02x\n", __LINE__, reg);
1242 #endif
1243         udelay(10000);
1244
1245         immap = (immap_t *)CFG_IMMR;
1246         sysp  = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
1247         pcmp  = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1248         cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1249
1250         /*
1251          * Configure SIUMCR to enable PCMCIA port B
1252          * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
1253          */
1254         sysp->sc_siumcr &= ~SIUMCR_DBGC11;      /* set DBGC to 00 */
1255
1256         /* clear interrupt state, and disable interrupts */
1257         pcmp->pcmc_pscr =  PCMCIA_MASK(_slot_);
1258         pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
1259
1260         /*
1261          * Disable interrupts, DMA, and PCMCIA buffers
1262          * (isolate the interface) and assert RESET signal
1263          */
1264         debug ("Disable PCMCIA buffers and assert RESET\n");
1265         reg  = 0;
1266         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
1267         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
1268         PCMCIA_PGCRX(_slot_) = reg;
1269         udelay(500);
1270
1271         /*
1272          * Make sure there is a card in the slot, then configure the interface.
1273          */
1274         udelay(10000);
1275         debug ("[%d] %s: PIPR(%p)=0x%x\n",
1276                 __LINE__,__FUNCTION__,
1277                 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
1278         if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
1279                 printf ("   No Card found\n");
1280                 return (1);
1281         }
1282
1283         /*
1284          * Power On.
1285          */
1286         mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
1287         reg  = pcmp->pcmc_pipr;
1288         debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
1289                 reg,
1290                 (reg&PCMCIA_VS1(slot))?"n":"ff",
1291                 (reg&PCMCIA_VS2(slot))?"n":"ff");
1292         if ((reg & mask) == mask) {
1293                 val = 0;                /* VCCB3/5 = 0 ==> use Vx = 5.0 V */
1294                 puts (" 5.0V card found: ");
1295         } else {
1296                 val = MAX1604_VCC_35;   /* VCCB3/5 = 1 ==> use Vy = 3.3 V */
1297                 puts (" 3.3V card found: ");
1298         }
1299
1300         /*  switch VCC on */
1301         val |= MAX1604_OP_SUS | MAX1604_VCCBON;
1302         i2c_init  (CFG_I2C_SPEED, CFG_I2C_SLAVE);
1303         i2c_write (CFG_I2C_POWER_A_ADDR, 0, 0, &val, 1);
1304
1305         udelay(500000);
1306
1307         debug ("Enable PCMCIA buffers and stop RESET\n");
1308         reg  =  PCMCIA_PGCRX(_slot_);
1309         reg &= ~__MY_PCMCIA_GCRX_CXRESET;       /* active high */
1310         reg &= ~__MY_PCMCIA_GCRX_CXOE;          /* active low  */
1311         PCMCIA_PGCRX(_slot_) = reg;
1312
1313         udelay(250000); /* some cards need >150 ms to come up :-( */
1314
1315         debug ("# hardware_enable done\n");
1316
1317         return (0);
1318 }
1319
1320
1321 #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
1322 static int hardware_disable(int slot)
1323 {
1324         volatile immap_t        *immap;
1325         volatile pcmconf8xx_t   *pcmp;
1326         u_long reg;
1327         uchar val;
1328
1329         debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1330
1331         immap = (immap_t *)CFG_IMMR;
1332         pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1333
1334         /* remove all power, put output in high impedance state */
1335         val  = MAX1604_VCCBHIZ | MAX1604_VPPBHIZ;
1336         i2c_init  (CFG_I2C_SPEED, CFG_I2C_SLAVE);
1337         i2c_write (CFG_I2C_POWER_A_ADDR, 0, 0, &val, 1);
1338
1339         /* Configure PCMCIA General Control Register */
1340         debug ("Disable PCMCIA buffers and assert RESET\n");
1341         reg  = 0;
1342         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
1343         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
1344         PCMCIA_PGCRX(_slot_) = reg;
1345
1346         /* Switch off PCMCIA port in PIC register 0x60 */
1347         reg = pic_read  (0x60);
1348         debug ("[%d] PIC read: reg_60 = 0x%02x\n", __LINE__, reg);
1349         reg |=  0x10;
1350         reg &= ~0x08;
1351         pic_write (0x60, reg);
1352 #ifdef DEBUG
1353         reg = pic_read  (0x60);
1354         printf ("[%d] PIC read: reg_60 = 0x%02x\n", __LINE__, reg);
1355 #endif
1356         udelay(10000);
1357
1358         return (0);
1359 }
1360 #endif  /* CFG_CMD_PCMCIA */
1361
1362
1363 static int voltage_set(int slot, int vcc, int vpp)
1364 {
1365         volatile immap_t        *immap;
1366         volatile pcmconf8xx_t   *pcmp;
1367         u_long reg;
1368         uchar val;
1369
1370         debug ("voltage_set: "
1371                 PCMCIA_BOARD_MSG
1372                 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
1373                 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
1374
1375         immap = (immap_t *)CFG_IMMR;
1376         pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1377         /*
1378          * Disable PCMCIA buffers (isolate the interface)
1379          * and assert RESET signal
1380          */
1381         debug ("Disable PCMCIA buffers and assert RESET\n");
1382         reg  = PCMCIA_PGCRX(_slot_);
1383         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
1384         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
1385         PCMCIA_PGCRX(_slot_) = reg;
1386         udelay(500);
1387
1388         /*
1389          * Turn off all power (switch to high impedance)
1390          */
1391         debug ("PCMCIA power OFF\n");
1392         val  = MAX1604_VCCBHIZ | MAX1604_VPPBHIZ;
1393         i2c_init  (CFG_I2C_SPEED, CFG_I2C_SLAVE);
1394         i2c_write (CFG_I2C_POWER_A_ADDR, 0, 0, &val, 1);
1395
1396         val = 0;
1397         switch(vcc) {
1398         case  0:                        break;
1399         case 33: val = MAX1604_VCC_35;  break;
1400         case 50:                        break;
1401         default:                        goto done;
1402         }
1403
1404         /* Checking supported voltages */
1405
1406         debug ("PIPR: 0x%x --> %s\n",
1407                 pcmp->pcmc_pipr,
1408                 (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
1409
1410         i2c_write (CFG_I2C_POWER_A_ADDR, 0, 0, &val, 1);
1411         if (val) {
1412                 debug ("PCMCIA powered at %sV\n",
1413                         (val & MAX1604_VCC_35) ? "3.3" : "5.0");
1414         } else {
1415                 debug ("PCMCIA powered down\n");
1416         }
1417
1418 done:
1419         debug ("Enable PCMCIA buffers and stop RESET\n");
1420         reg  =  PCMCIA_PGCRX(_slot_);
1421         reg &= ~__MY_PCMCIA_GCRX_CXRESET;       /* active high */
1422         reg &= ~__MY_PCMCIA_GCRX_CXOE;          /* active low  */
1423         PCMCIA_PGCRX(_slot_) = reg;
1424         udelay(500);
1425
1426         debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
1427                 slot+'A');
1428         return (0);
1429 }
1430
1431 #endif  /* LWMON */
1432
1433 /* -------------------------------------------------------------------- */
1434 /* GTH board by Corelatus AB                                            */
1435 /* -------------------------------------------------------------------- */
1436 #if defined(CONFIG_GTH)
1437
1438 #define PCMCIA_BOARD_MSG "GTH COMPACT FLASH"
1439
1440 static int voltage_set (int slot, int vcc, int vpp)
1441 {       /* Do nothing */
1442         return 0;
1443 }
1444
1445 static int hardware_enable (int slot)
1446 {
1447         volatile immap_t *immap;
1448         volatile cpm8xx_t *cp;
1449         volatile pcmconf8xx_t *pcmp;
1450         volatile sysconf8xx_t *sysp;
1451         uint reg, mask;
1452
1453         debug ("hardware_enable: GTH Slot %c\n", 'A' + slot);
1454
1455         immap = (immap_t *) CFG_IMMR;
1456         sysp = (sysconf8xx_t *) (&(((immap_t *) CFG_IMMR)->im_siu_conf));
1457         pcmp = (pcmconf8xx_t *) (&(((immap_t *) CFG_IMMR)->im_pcmcia));
1458         cp = (cpm8xx_t *) (&(((immap_t *) CFG_IMMR)->im_cpm));
1459
1460         /* clear interrupt state, and disable interrupts */
1461         pcmp->pcmc_pscr = PCMCIA_MASK (_slot_);
1462         pcmp->pcmc_per &= ~PCMCIA_MASK (_slot_);
1463
1464         /*
1465          * Disable interrupts, DMA, and PCMCIA buffers
1466          * (isolate the interface) and assert RESET signal
1467          */
1468         debug ("Disable PCMCIA buffers and assert RESET\n");
1469         reg = 0;
1470         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
1471         reg |= __MY_PCMCIA_GCRX_CXOE;   /* active low  */
1472         PCMCIA_PGCRX (_slot_) = reg;
1473         udelay (500);
1474
1475         /*
1476          * Make sure there is a card in the slot,
1477          * then configure the interface.
1478          */
1479         udelay (10000);
1480         debug ("[%d] %s: PIPR(%p)=0x%x\n",
1481                 __LINE__, __FUNCTION__,
1482                 &(pcmp->pcmc_pipr), pcmp->pcmc_pipr);
1483         if (pcmp->pcmc_pipr & 0x98000000) {
1484                 printf ("   No Card found\n");
1485                 return (1);
1486         }
1487
1488         mask = PCMCIA_VS1 (slot) | PCMCIA_VS2 (slot);
1489         reg = pcmp->pcmc_pipr;
1490         debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
1491                    reg,
1492                    (reg & PCMCIA_VS1 (slot)) ? "n" : "ff",
1493                    (reg & PCMCIA_VS2 (slot)) ? "n" : "ff");
1494
1495         debug ("Enable PCMCIA buffers and stop RESET\n");
1496         reg  =  PCMCIA_PGCRX (_slot_);
1497         reg &= ~__MY_PCMCIA_GCRX_CXRESET;       /* active high */
1498         reg &= ~__MY_PCMCIA_GCRX_CXOE;          /* active low  */
1499         PCMCIA_PGCRX (_slot_) = reg;
1500
1501         udelay (250000);        /* some cards need >150 ms to come up :-( */
1502
1503         debug ("# hardware_enable done\n");
1504
1505         return 0;
1506 }
1507 #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
1508 static int hardware_disable(int slot)
1509 {
1510         return 0;       /* No hardware to disable */
1511 }
1512 #endif  /* CFG_CMD_PCMCIA */
1513 #endif  /* CONFIG_GTH */
1514
1515 /* -------------------------------------------------------------------- */
1516 /* ICU862 Boards by Cambridge Broadband Ltd.                            */
1517 /* -------------------------------------------------------------------- */
1518
1519 #if defined(CONFIG_ICU862)
1520
1521 #define PCMCIA_BOARD_MSG "ICU862"
1522
1523 static void cfg_port_B (void);
1524
1525 static int hardware_enable(int slot)
1526 {
1527         volatile immap_t        *immap;
1528         volatile cpm8xx_t       *cp;
1529         volatile pcmconf8xx_t   *pcmp;
1530         volatile sysconf8xx_t   *sysp;
1531         uint reg, pipr, mask;
1532         int i;
1533
1534         debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1535
1536         udelay(10000);
1537
1538         immap = (immap_t *)CFG_IMMR;
1539         sysp  = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
1540         pcmp  = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1541         cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1542
1543         /* Configure Port B for TPS2205 PC-Card Power-Interface Switch */
1544         cfg_port_B ();
1545
1546         /*
1547          * Configure SIUMCR to enable PCMCIA port B
1548          * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
1549          */
1550         sysp->sc_siumcr &= ~SIUMCR_DBGC11;      /* set DBGC to 00 */
1551
1552         /* clear interrupt state, and disable interrupts */
1553         pcmp->pcmc_pscr =  PCMCIA_MASK(_slot_);
1554         pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
1555
1556         /*
1557          * Disable interrupts, DMA, and PCMCIA buffers
1558          * (isolate the interface) and assert RESET signal
1559          */
1560         debug ("Disable PCMCIA buffers and assert RESET\n");
1561         reg  = 0;
1562         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
1563         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
1564         PCMCIA_PGCRX(_slot_) = reg;
1565         udelay(500);
1566
1567         /*
1568          * Make sure there is a card in the slot, then configure the interface.
1569          */
1570         udelay(10000);
1571         debug ("[%d] %s: PIPR(%p)=0x%x\n",
1572                 __LINE__,__FUNCTION__,
1573                 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
1574         if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
1575                 printf ("   No Card found\n");
1576                 return (1);
1577         }
1578
1579         /*
1580          * Power On: Set VAVCC to 3.3V or 5V, set VAVPP to Hi-Z
1581          */
1582         mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
1583         pipr = pcmp->pcmc_pipr;
1584         debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
1585                 pipr,
1586                 (reg&PCMCIA_VS1(slot))?"n":"ff",
1587                 (reg&PCMCIA_VS2(slot))?"n":"ff");
1588
1589         reg  = cp->cp_pbdat;
1590         if ((pipr & mask) == mask) {
1591                 reg |= (TPS2205_VPP_PGM | TPS2205_VPP_VCC |     /* VAVPP => Hi-Z */
1592                         TPS2205_VCC3);                          /* 3V off       */
1593                 reg &= ~(TPS2205_VCC5);                         /* 5V on        */
1594                 puts (" 5.0V card found: ");
1595         } else {
1596                 reg |= (TPS2205_VPP_PGM | TPS2205_VPP_VCC |     /* VAVPP => Hi-Z */
1597                         TPS2205_VCC5);                          /* 5V off       */
1598                 reg &= ~(TPS2205_VCC3);                         /* 3V on        */
1599                 puts (" 3.3V card found: ");
1600         }
1601
1602         debug ("\nPB DAT: %08x -> 3.3V %s 5.0V %s VPP_PGM %s VPP_VCC %s\n",
1603                 reg,
1604                 (reg & TPS2205_VCC3)    ? "off" : "on",
1605                 (reg & TPS2205_VCC5)    ? "off" : "on",
1606                 (reg & TPS2205_VPP_PGM) ? "off" : "on",
1607                 (reg & TPS2205_VPP_VCC) ? "off" : "on" );
1608
1609         cp->cp_pbdat = reg;
1610
1611         /*  Wait 500 ms; use this to check for over-current */
1612         for (i=0; i<5000; ++i) {
1613                 if ((cp->cp_pbdat & TPS2205_OC) == 0) {
1614                         printf ("   *** Overcurrent - Safety shutdown ***\n");
1615                         cp->cp_pbdat &= ~(TPS2205_SHDN);
1616                         return (1);
1617                 }
1618                 udelay (100);
1619         }
1620
1621         debug ("Enable PCMCIA buffers and stop RESET\n");
1622         reg  =  PCMCIA_PGCRX(_slot_);
1623         reg &= ~__MY_PCMCIA_GCRX_CXRESET;       /* active high */
1624         reg &= ~__MY_PCMCIA_GCRX_CXOE;          /* active low  */
1625         PCMCIA_PGCRX(_slot_) = reg;
1626
1627         udelay(250000); /* some cards need >150 ms to come up :-( */
1628
1629         debug ("# hardware_enable done\n");
1630
1631         return (0);
1632 }
1633
1634
1635 #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
1636 static int hardware_disable(int slot)
1637 {
1638         volatile immap_t        *immap;
1639         volatile cpm8xx_t       *cp;
1640         volatile pcmconf8xx_t   *pcmp;
1641         u_long reg;
1642
1643         debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1644
1645         immap = (immap_t *)CFG_IMMR;
1646         cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1647         pcmp  = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1648
1649         /* Shut down */
1650         cp->cp_pbdat &= ~(TPS2205_SHDN);
1651
1652         /* Configure PCMCIA General Control Register */
1653         debug ("Disable PCMCIA buffers and assert RESET\n");
1654         reg  = 0;
1655         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
1656         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
1657         PCMCIA_PGCRX(_slot_) = reg;
1658
1659         udelay(10000);
1660
1661         return (0);
1662 }
1663 #endif  /* CFG_CMD_PCMCIA */
1664
1665
1666 static int voltage_set(int slot, int vcc, int vpp)
1667 {
1668         volatile immap_t        *immap;
1669         volatile cpm8xx_t       *cp;
1670         volatile pcmconf8xx_t   *pcmp;
1671         u_long reg;
1672
1673         debug ("voltage_set: "
1674                 PCMCIA_BOARD_MSG
1675                 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
1676                 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
1677
1678         immap = (immap_t *)CFG_IMMR;
1679         cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1680         pcmp  = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1681         /*
1682          * Disable PCMCIA buffers (isolate the interface)
1683          * and assert RESET signal
1684          */
1685         debug ("Disable PCMCIA buffers and assert RESET\n");
1686         reg  = PCMCIA_PGCRX(_slot_);
1687         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
1688         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
1689         PCMCIA_PGCRX(_slot_) = reg;
1690         udelay(500);
1691
1692         /*
1693          * Configure Port C pins for
1694          * 5 Volts Enable and 3 Volts enable,
1695          * Turn all power pins to Hi-Z
1696          */
1697         debug ("PCMCIA power OFF\n");
1698         cfg_port_B ();  /* Enables switch, but all in Hi-Z */
1699
1700         reg  = cp->cp_pbdat;
1701
1702         switch(vcc) {
1703         case  0:                        break;  /* Switch off           */
1704         case 33: reg &= ~TPS2205_VCC3;  break;  /* Switch on 3.3V       */
1705         case 50: reg &= ~TPS2205_VCC5;  break;  /* Switch on 5.0V       */
1706         default:                        goto done;
1707         }
1708
1709         /* Checking supported voltages */
1710
1711         debug ("PIPR: 0x%x --> %s\n",
1712                 pcmp->pcmc_pipr,
1713                 (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
1714
1715         cp->cp_pbdat = reg;
1716
1717 #ifdef DEBUG
1718     {
1719         char *s;
1720
1721         if ((reg & TPS2205_VCC3) == 0) {
1722                 s = "at 3.3V";
1723         } else if ((reg & TPS2205_VCC5) == 0) {
1724                 s = "at 5.0V";
1725         } else {
1726                 s = "down";
1727         }
1728         printf ("PCMCIA powered %s\n", s);
1729     }
1730 #endif
1731
1732 done:
1733         debug ("Enable PCMCIA buffers and stop RESET\n");
1734         reg  =  PCMCIA_PGCRX(_slot_);
1735         reg &= ~__MY_PCMCIA_GCRX_CXRESET;       /* active high */
1736         reg &= ~__MY_PCMCIA_GCRX_CXOE;          /* active low  */
1737         PCMCIA_PGCRX(_slot_) = reg;
1738         udelay(500);
1739
1740         debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
1741                 slot+'A');
1742         return (0);
1743 }
1744
1745 static void cfg_port_B (void)
1746 {
1747         volatile immap_t        *immap;
1748         volatile cpm8xx_t       *cp;
1749         uint reg;
1750
1751         immap = (immap_t *)CFG_IMMR;
1752         cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1753
1754         /*
1755          * Configure Port B for TPS2205 PC-Card Power-Interface Switch
1756          *
1757          * Switch off all voltages, assert shutdown
1758          */
1759         reg  = cp->cp_pbdat;
1760         reg |= (TPS2205_VPP_PGM | TPS2205_VPP_VCC |     /* VAVPP => Hi-Z */
1761                 TPS2205_VCC3    | TPS2205_VCC5    |     /* VAVCC => Hi-Z */
1762                 TPS2205_SHDN);                          /* enable switch */
1763         cp->cp_pbdat = reg;
1764
1765         cp->cp_pbpar &= ~(TPS2205_INPUTS | TPS2205_OUTPUTS);
1766
1767         reg = cp->cp_pbdir & ~(TPS2205_INPUTS);
1768         cp->cp_pbdir = reg | TPS2205_OUTPUTS;
1769
1770         debug ("Set Port B: PAR: %08x DIR: %08x DAT: %08x\n",
1771                 cp->cp_pbpar, cp->cp_pbdir, cp->cp_pbdat);
1772 }
1773
1774 #endif  /* ICU862 */
1775
1776
1777 /* -------------------------------------------------------------------- */
1778 /* C2MON Boards by TTTech Computertechnik AG                            */
1779 /* -------------------------------------------------------------------- */
1780
1781 #if defined(CONFIG_C2MON)
1782
1783 #define PCMCIA_BOARD_MSG "C2MON"
1784
1785 static void cfg_ports (void);
1786
1787 static int hardware_enable(int slot)
1788 {
1789         volatile immap_t        *immap;
1790         volatile cpm8xx_t       *cp;
1791         volatile pcmconf8xx_t   *pcmp;
1792         volatile sysconf8xx_t   *sysp;
1793         uint reg, pipr, mask;
1794         ushort sreg;
1795         int i;
1796
1797         debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1798
1799         udelay(10000);
1800
1801         immap = (immap_t *)CFG_IMMR;
1802         sysp  = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
1803         pcmp  = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1804         cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1805
1806         /* Configure Ports for TPS2211A PC-Card Power-Interface Switch */
1807         cfg_ports ();
1808
1809         /*
1810          * Configure SIUMCR to enable PCMCIA port B
1811          * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
1812          */
1813         sysp->sc_siumcr &= ~SIUMCR_DBGC11;      /* set DBGC to 00 */
1814
1815         /* clear interrupt state, and disable interrupts */
1816         pcmp->pcmc_pscr =  PCMCIA_MASK(_slot_);
1817         pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
1818
1819         /*
1820          * Disable interrupts, DMA, and PCMCIA buffers
1821          * (isolate the interface) and assert RESET signal
1822          */
1823         debug ("Disable PCMCIA buffers and assert RESET\n");
1824         reg  = 0;
1825         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
1826         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
1827         PCMCIA_PGCRX(_slot_) = reg;
1828         udelay(500);
1829
1830         /*
1831          * Make sure there is a card in the slot, then configure the interface.
1832          */
1833         udelay(10000);
1834         debug ("[%d] %s: PIPR(%p)=0x%x\n",
1835                 __LINE__,__FUNCTION__,
1836                 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
1837         if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
1838                 printf ("   No Card found\n");
1839                 return (1);
1840         }
1841
1842         /*
1843          * Power On: Set VAVCC to 3.3V or 5V, set VAVPP to Hi-Z
1844          */
1845         mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
1846         pipr = pcmp->pcmc_pipr;
1847         debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
1848                 pipr,
1849                 (reg&PCMCIA_VS1(slot))?"n":"ff",
1850                 (reg&PCMCIA_VS2(slot))?"n":"ff");
1851
1852         sreg = immap->im_ioport.iop_pcdat;
1853         if ((pipr & mask) == mask) {
1854                 sreg |=  (TPS2211_VPPD0 | TPS2211_VPPD1 |       /* VAVPP => Hi-Z */
1855                           TPS2211_VCCD1);                       /* 5V on        */
1856                 sreg &= ~(TPS2211_VCCD0);                       /* 3V off       */
1857                 puts (" 5.0V card found: ");
1858         } else {
1859                 sreg |=  (TPS2211_VPPD0 | TPS2211_VPPD1 |       /* VAVPP => Hi-Z */
1860                           TPS2211_VCCD0);                       /* 3V on        */
1861                 sreg &= ~(TPS2211_VCCD1);                       /* 5V off       */
1862                 puts (" 3.3V card found: ");
1863         }
1864
1865         debug ("\nPC DAT: %04x -> 3.3V %s 5.0V %s\n",
1866                 sreg,
1867                 ( (sreg & TPS2211_VCCD0) && !(sreg & TPS2211_VCCD1)) ? "on" : "off",
1868                 (!(sreg & TPS2211_VCCD0) &&  (sreg & TPS2211_VCCD1)) ? "on" : "off"
1869         );
1870
1871         immap->im_ioport.iop_pcdat = sreg;
1872
1873         /*  Wait 500 ms; use this to check for over-current */
1874         for (i=0; i<5000; ++i) {
1875                 if ((cp->cp_pbdat & TPS2211_OC) == 0) {
1876                     printf ("   *** Overcurrent - Safety shutdown ***\n");
1877                     immap->im_ioport.iop_pcdat &= ~(TPS2211_VCCD0|TPS2211_VCCD1);
1878                     return (1);
1879                 }
1880                 udelay (100);
1881         }
1882
1883         debug ("Enable PCMCIA buffers and stop RESET\n");
1884         reg  =  PCMCIA_PGCRX(_slot_);
1885         reg &= ~__MY_PCMCIA_GCRX_CXRESET;       /* active high */
1886         reg &= ~__MY_PCMCIA_GCRX_CXOE;          /* active low  */
1887         PCMCIA_PGCRX(_slot_) = reg;
1888
1889         udelay(250000); /* some cards need >150 ms to come up :-( */
1890
1891         debug ("# hardware_enable done\n");
1892
1893         return (0);
1894 }
1895
1896
1897 #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
1898 static int hardware_disable(int slot)
1899 {
1900         volatile immap_t        *immap;
1901         volatile cpm8xx_t       *cp;
1902         volatile pcmconf8xx_t   *pcmp;
1903         u_long reg;
1904
1905         debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1906
1907         immap = (immap_t *)CFG_IMMR;
1908         pcmp  = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1909
1910         /* Configure PCMCIA General Control Register */
1911         debug ("Disable PCMCIA buffers and assert RESET\n");
1912         reg  = 0;
1913         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
1914         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
1915         PCMCIA_PGCRX(_slot_) = reg;
1916
1917         /* ALl voltages off / Hi-Z */
1918         immap->im_ioport.iop_pcdat |= (TPS2211_VPPD0 | TPS2211_VPPD1 |
1919                                        TPS2211_VCCD0 | TPS2211_VCCD1 );
1920
1921         udelay(10000);
1922
1923         return (0);
1924 }
1925 #endif  /* CFG_CMD_PCMCIA */
1926
1927
1928 static int voltage_set(int slot, int vcc, int vpp)
1929 {
1930         volatile immap_t        *immap;
1931         volatile cpm8xx_t       *cp;
1932         volatile pcmconf8xx_t   *pcmp;
1933         u_long reg;
1934         ushort sreg;
1935
1936         debug ("voltage_set: "
1937                 PCMCIA_BOARD_MSG
1938                 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
1939                 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
1940
1941         immap = (immap_t *)CFG_IMMR;
1942         cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1943         pcmp  = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1944         /*
1945          * Disable PCMCIA buffers (isolate the interface)
1946          * and assert RESET signal
1947          */
1948         debug ("Disable PCMCIA buffers and assert RESET\n");
1949         reg  = PCMCIA_PGCRX(_slot_);
1950         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
1951         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
1952         PCMCIA_PGCRX(_slot_) = reg;
1953         udelay(500);
1954
1955         /*
1956          * Configure Port C pins for
1957          * 5 Volts Enable and 3 Volts enable,
1958          * Turn all power pins to Hi-Z
1959          */
1960         debug ("PCMCIA power OFF\n");
1961         cfg_ports ();   /* Enables switch, but all in Hi-Z */
1962
1963         sreg  = immap->im_ioport.iop_pcdat;
1964         sreg |= TPS2211_VPPD0 | TPS2211_VPPD1;          /* VAVPP always Hi-Z */
1965
1966         switch(vcc) {
1967         case  0:                        break;  /* Switch off           */
1968         case 33: sreg |=  TPS2211_VCCD0;        /* Switch on 3.3V       */
1969                  sreg &= ~TPS2211_VCCD1;
1970                                         break;
1971         case 50: sreg &= ~TPS2211_VCCD0;        /* Switch on 5.0V       */
1972                  sreg |=  TPS2211_VCCD1;
1973                                         break;
1974         default:                        goto done;
1975         }
1976
1977         /* Checking supported voltages */
1978
1979         debug ("PIPR: 0x%x --> %s\n",
1980                 pcmp->pcmc_pipr,
1981                 (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
1982
1983         immap->im_ioport.iop_pcdat = sreg;
1984
1985 #ifdef DEBUG
1986     {
1987         char *s;
1988
1989         if ((sreg & TPS2211_VCCD0) && !(sreg & TPS2211_VCCD1)) {
1990                 s = "at 3.3V";
1991         } else if (!(sreg & TPS2211_VCCD0) &&  (sreg & TPS2211_VCCD1)) {
1992                 s = "at 5.0V";
1993         } else {
1994                 s = "down";
1995         }
1996         printf ("PCMCIA powered %s\n", s);
1997     }
1998 #endif
1999
2000 done:
2001         debug ("Enable PCMCIA buffers and stop RESET\n");
2002         reg  =  PCMCIA_PGCRX(_slot_);
2003         reg &= ~__MY_PCMCIA_GCRX_CXRESET;       /* active high */
2004         reg &= ~__MY_PCMCIA_GCRX_CXOE;          /* active low  */
2005         PCMCIA_PGCRX(_slot_) = reg;
2006         udelay(500);
2007
2008         debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
2009                 slot+'A');
2010         return (0);
2011 }
2012
2013 static void cfg_ports (void)
2014 {
2015         volatile immap_t        *immap;
2016         volatile cpm8xx_t       *cp;
2017         ushort sreg;
2018
2019         immap = (immap_t *)CFG_IMMR;
2020         cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
2021
2022         /*
2023          * Configure Port C for TPS2211 PC-Card Power-Interface Switch
2024          *
2025          * Switch off all voltages, assert shutdown
2026          */
2027         sreg = immap->im_ioport.iop_pcdat;
2028         sreg |=  (TPS2211_VPPD0 | TPS2211_VPPD1);       /* VAVPP => Hi-Z */
2029         sreg &= ~(TPS2211_VCCD0 | TPS2211_VCCD1);       /* 3V and 5V off */
2030         immap->im_ioport.iop_pcdat = sreg;
2031
2032         immap->im_ioport.iop_pcpar &= ~(TPS2211_OUTPUTS);
2033         immap->im_ioport.iop_pcdir |=   TPS2211_OUTPUTS;
2034
2035         debug ("Set Port C: PAR:     %04x DIR:     %04x DAT:     %04x\n",
2036                 immap->im_ioport.iop_pcpar,
2037                 immap->im_ioport.iop_pcdir,
2038                 immap->im_ioport.iop_pcdat);
2039
2040         /*
2041          * Configure Port B for TPS2211 PC-Card Power-Interface Switch
2042          *
2043          * Over-Current Input only
2044          */
2045         cp->cp_pbpar &= ~(TPS2211_INPUTS);
2046         cp->cp_pbdir &= ~(TPS2211_INPUTS);
2047
2048         debug ("Set Port B: PAR: %08x DIR: %08x DAT: %08x\n",
2049                 cp->cp_pbpar, cp->cp_pbdir, cp->cp_pbdat);
2050 }
2051
2052 #endif  /* C2MON */
2053
2054 /* -------------------------------------------------------------------- */
2055 /* MBX board from Morotola                                              */
2056 /* -------------------------------------------------------------------- */
2057
2058 #if defined( CONFIG_MBX )
2059 #include <../board/mbx8xx/csr.h>
2060
2061 /* A lot of this has been taken from the RPX code in this file it works from me.
2062    I have added the voltage selection for the MBX board. */
2063
2064 /* MBX voltage bit in control register #2 */
2065 #define CR2_VPP12       ((uchar)0x10)
2066 #define CR2_VPPVDD      ((uchar)0x20)
2067 #define CR2_VDD5        ((uchar)0x40)
2068 #define CR2_VDD3        ((uchar)0x80)
2069
2070 #define PCMCIA_BOARD_MSG "MBX860"
2071
2072 static int voltage_set (int slot, int vcc, int vpp)
2073 {
2074         uchar reg = 0;
2075
2076         debug ("voltage_set: PCMCIA_BOARD_MSG Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
2077                  'A' + slot, vcc / 10, vcc % 10, vpp / 10, vcc % 10);
2078
2079         switch (vcc) {
2080         case 0:
2081                 break;
2082         case 33:
2083                 reg |= CR2_VDD3;
2084                 break;
2085         case 50:
2086                 reg |= CR2_VDD5;
2087                 break;
2088         default:
2089                 return 1;
2090         }
2091
2092         switch (vpp) {
2093         case 0:
2094                 break;
2095         case 33:
2096         case 50:
2097                 if (vcc == vpp) {
2098                         reg |= CR2_VPPVDD;
2099                 } else {
2100                         return 1;
2101                 }
2102                 break;
2103         case 120:
2104                 reg |= CR2_VPP12;
2105                 break;
2106         default:
2107                 return 1;
2108         }
2109
2110         /* first, turn off all power */
2111         MBX_CSR2 &= ~(CR2_VDDSEL | CR2_VPPSEL);
2112
2113         /* enable new powersettings */
2114         MBX_CSR2 |= reg;
2115         debug ("MBX_CSR2 read = 0x%02x\n", MBX_CSR2);
2116
2117         return (0);
2118 }
2119
2120 static int hardware_enable (int slot)
2121 {
2122         volatile immap_t *immap;
2123         volatile cpm8xx_t *cp;
2124         volatile pcmconf8xx_t *pcmp;
2125         volatile sysconf8xx_t *sysp;
2126         uint reg, mask;
2127
2128         debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n",
2129                                   'A' + slot);
2130
2131         udelay (10000);
2132
2133         immap = (immap_t *) CFG_IMMR;
2134         sysp = (sysconf8xx_t *) (&(((immap_t *) CFG_IMMR)->im_siu_conf));
2135         pcmp = (pcmconf8xx_t *) (&(((immap_t *) CFG_IMMR)->im_pcmcia));
2136         cp = (cpm8xx_t *) (&(((immap_t *) CFG_IMMR)->im_cpm));
2137
2138         /* clear interrupt state, and disable interrupts */
2139         pcmp->pcmc_pscr = PCMCIA_MASK (_slot_);
2140         pcmp->pcmc_per &= ~PCMCIA_MASK (_slot_);
2141
2142         /*
2143          * Disable interrupts, DMA, and PCMCIA buffers
2144          * (isolate the interface) and assert RESET signal
2145          */
2146         debug ("Disable PCMCIA buffers and assert RESET\n");
2147         reg = 0;
2148         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
2149         reg |= __MY_PCMCIA_GCRX_CXOE;   /* active low  */
2150         PCMCIA_PGCRX (_slot_) = reg;
2151         udelay (500);
2152
2153         /* remove all power */
2154         voltage_set (slot, 0, 0);
2155         /*
2156          * Make sure there is a card in the slot, then configure the interface.
2157          */
2158         udelay(10000);
2159         debug ("[%d] %s: PIPR(%p)=0x%x\n",
2160                 __LINE__,__FUNCTION__,
2161                 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
2162 #ifndef CONFIG_HMI10
2163         if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
2164 #else
2165         if (pcmp->pcmc_pipr & (0x10000000 >> (slot << 4))) {
2166 #endif  /* CONFIG_HMI10 */
2167                 printf ("   No Card found\n");
2168                 return (1);
2169         }
2170
2171         /*
2172          * Power On.
2173          */
2174         mask = PCMCIA_VS1 (_slot_) | PCMCIA_VS2 (_slot_);
2175         reg = pcmp->pcmc_pipr;
2176         debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n", reg,
2177                   (reg & PCMCIA_VS1 (slot)) ? "n" : "ff",
2178                   (reg & PCMCIA_VS2 (slot)) ? "n" : "ff");
2179
2180         if ((reg & mask) == mask) {
2181                 voltage_set (_slot_, 50, 0);
2182                 printf (" 5.0V card found: ");
2183         } else {
2184                 voltage_set (_slot_, 33, 0);
2185                 printf (" 3.3V card found: ");
2186         }
2187
2188         debug ("Enable PCMCIA buffers and stop RESET\n");
2189         reg = PCMCIA_PGCRX (_slot_);
2190         reg &= ~__MY_PCMCIA_GCRX_CXRESET;       /* active high */
2191         reg &= ~__MY_PCMCIA_GCRX_CXOE;  /* active low  */
2192         PCMCIA_PGCRX (_slot_) = reg;
2193
2194         udelay (250000);        /* some cards need >150 ms to come up :-( */
2195
2196         debug ("# hardware_enable done\n");
2197
2198         return (0);
2199 }
2200
2201 #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
2202 static int hardware_disable (int slot)
2203 {
2204         return 0;       /* No hardware to disable */
2205 }
2206 #endif /* CFG_CMD_PCMCIA */
2207 #endif /* CONFIG_MBX */
2208 /* -------------------------------------------------------------------- */
2209 /* R360MPI Board                                                        */
2210 /* -------------------------------------------------------------------- */
2211
2212 #if defined(CONFIG_R360MPI)
2213
2214 #define PCMCIA_BOARD_MSG "R360MPI"
2215
2216
2217 static int hardware_enable(int slot)
2218 {
2219         volatile immap_t        *immap;
2220         volatile cpm8xx_t       *cp;
2221         volatile pcmconf8xx_t   *pcmp;
2222         volatile sysconf8xx_t   *sysp;
2223         uint reg, mask;
2224
2225         debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
2226
2227         udelay(10000);
2228
2229         immap = (immap_t *)CFG_IMMR;
2230         sysp  = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
2231         pcmp  = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
2232         cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
2233
2234         /*
2235          * Configure SIUMCR to enable PCMCIA port B
2236          * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
2237          */
2238         sysp->sc_siumcr &= ~SIUMCR_DBGC11;      /* set DBGC to 00 */
2239
2240         /* clear interrupt state, and disable interrupts */
2241         pcmp->pcmc_pscr =  PCMCIA_MASK(_slot_);
2242         pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
2243
2244         /*
2245          * Disable interrupts, DMA, and PCMCIA buffers
2246          * (isolate the interface) and assert RESET signal
2247          */
2248         debug ("Disable PCMCIA buffers and assert RESET\n");
2249         reg  = 0;
2250         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
2251         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
2252         PCMCIA_PGCRX(_slot_) = reg;
2253         udelay(500);
2254
2255         /*
2256          * Configure Ports A, B & C pins for
2257          * 5 Volts Enable and 3 Volts enable
2258          */
2259         immap->im_ioport.iop_pcpar &= ~(0x0400);
2260         immap->im_ioport.iop_pcso  &= ~(0x0400);/*
2261         immap->im_ioport.iop_pcdir |= 0x0400;*/
2262
2263         immap->im_ioport.iop_papar &= ~(0x0200);/*
2264         immap->im_ioport.iop_padir |= 0x0200;*/
2265 #if 0
2266         immap->im_ioport.iop_pbpar &= ~(0xC000);
2267         immap->im_ioport.iop_pbdir &= ~(0xC000);
2268 #endif
2269         /* remove all power */
2270
2271         immap->im_ioport.iop_pcdat |= 0x0400;
2272         immap->im_ioport.iop_padat |= 0x0200;
2273
2274         /*
2275          * Make sure there is a card in the slot, then configure the interface.
2276          */
2277         udelay(10000);
2278         debug ("[%d] %s: PIPR(%p)=0x%x\n",
2279                 __LINE__,__FUNCTION__,
2280                 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
2281         if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
2282                 printf ("   No Card found\n");
2283                 return (1);
2284         }
2285
2286         /*
2287          * Power On.
2288          */
2289         mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
2290         reg  = pcmp->pcmc_pipr;
2291         debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
2292                 reg,
2293                 (reg&PCMCIA_VS1(slot))?"n":"ff",
2294                 (reg&PCMCIA_VS2(slot))?"n":"ff");
2295         if ((reg & mask) == mask) {
2296                 immap->im_ioport.iop_pcdat &= ~(0x4000);
2297                 puts (" 5.0V card found: ");
2298         } else {
2299                 immap->im_ioport.iop_padat &= ~(0x0002);
2300                 puts (" 3.3V card found: ");
2301         }
2302         immap->im_ioport.iop_pcdir |= 0x0400;
2303         immap->im_ioport.iop_padir |= 0x0200;
2304 #if 0
2305         /*  VCC switch error flag, PCMCIA slot INPACK_ pin */
2306         cp->cp_pbdir &= ~(0x0020 | 0x0010);
2307         cp->cp_pbpar &= ~(0x0020 | 0x0010);
2308         udelay(500000);
2309 #endif
2310         debug ("Enable PCMCIA buffers and stop RESET\n");
2311         reg  =  PCMCIA_PGCRX(_slot_);
2312         reg &= ~__MY_PCMCIA_GCRX_CXRESET;       /* active high */
2313         reg &= ~__MY_PCMCIA_GCRX_CXOE;          /* active low  */
2314         PCMCIA_PGCRX(_slot_) = reg;
2315
2316         udelay(250000); /* some cards need >150 ms to come up :-( */
2317
2318         debug ("# hardware_enable done\n");
2319
2320         return (0);
2321 }
2322
2323
2324 #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
2325 static int hardware_disable(int slot)
2326 {
2327         volatile immap_t        *immap;
2328         volatile pcmconf8xx_t   *pcmp;
2329         u_long reg;
2330
2331         debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
2332
2333         immap = (immap_t *)CFG_IMMR;
2334         pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
2335
2336         /* remove all power */
2337         immap->im_ioport.iop_pcdat |= 0x0400;
2338         immap->im_ioport.iop_padat |= 0x0200;
2339
2340         /* Configure PCMCIA General Control Register */
2341         debug ("Disable PCMCIA buffers and assert RESET\n");
2342         reg  = 0;
2343         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
2344         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
2345         PCMCIA_PGCRX(_slot_) = reg;
2346
2347         udelay(10000);
2348
2349         return (0);
2350 }
2351 #endif  /* CFG_CMD_PCMCIA */
2352
2353
2354 static int voltage_set(int slot, int vcc, int vpp)
2355 {
2356         volatile immap_t        *immap;
2357         volatile pcmconf8xx_t   *pcmp;
2358         u_long reg;
2359
2360         debug ("voltage_set: "
2361                 PCMCIA_BOARD_MSG
2362                 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
2363                 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
2364
2365         immap = (immap_t *)CFG_IMMR;
2366         pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
2367         /*
2368          * Disable PCMCIA buffers (isolate the interface)
2369          * and assert RESET signal
2370          */
2371         debug ("Disable PCMCIA buffers and assert RESET\n");
2372         reg  = PCMCIA_PGCRX(_slot_);
2373         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
2374         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
2375         PCMCIA_PGCRX(_slot_) = reg;
2376         udelay(500);
2377
2378         /*
2379          * Configure Ports A & C pins for
2380          * 5 Volts Enable and 3 Volts enable,
2381          * Turn off all power
2382          */
2383         debug ("PCMCIA power OFF\n");
2384         immap->im_ioport.iop_pcpar &= ~(0x0400);
2385         immap->im_ioport.iop_pcso  &= ~(0x0400);/*
2386         immap->im_ioport.iop_pcdir |= 0x0400;*/
2387
2388         immap->im_ioport.iop_papar &= ~(0x0200);/*
2389         immap->im_ioport.iop_padir |= 0x0200;*/
2390
2391         immap->im_ioport.iop_pcdat |= 0x0400;
2392         immap->im_ioport.iop_padat |= 0x0200;
2393
2394         reg = 0;
2395         switch(vcc) {
2396         case  0:                break;
2397         case 33: reg |= 0x0200; break;
2398         case 50: reg |= 0x0400; break;
2399         default:                goto done;
2400         }
2401
2402         /* Checking supported voltages */
2403
2404         debug ("PIPR: 0x%x --> %s\n",
2405                 pcmp->pcmc_pipr,
2406                 (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
2407
2408         if (reg & 0x0200)
2409                 immap->im_ioport.iop_pcdat &= !reg;
2410         if (reg & 0x0400)
2411                 immap->im_ioport.iop_padat &= !reg;
2412         immap->im_ioport.iop_pcdir |= 0x0200;
2413         immap->im_ioport.iop_padir |= 0x0400;
2414         if (reg) {
2415                 debug ("PCMCIA powered at %sV\n",
2416                         (reg&0x0400) ? "5.0" : "3.3");
2417         } else {
2418                 debug ("PCMCIA powered down\n");
2419         }
2420
2421 done:
2422         debug ("Enable PCMCIA buffers and stop RESET\n");
2423         reg  =  PCMCIA_PGCRX(_slot_);
2424         reg &= ~__MY_PCMCIA_GCRX_CXRESET;       /* active high */
2425         reg &= ~__MY_PCMCIA_GCRX_CXOE;          /* active low  */
2426         PCMCIA_PGCRX(_slot_) = reg;
2427         udelay(500);
2428
2429         debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
2430                 slot+'A');
2431         return (0);
2432 }
2433
2434 #endif  /* R360MPI */
2435
2436 /* -------------------------------------------------------------------- */
2437 /* KUP4K and KUP4X Boards                                                               */
2438 /* -------------------------------------------------------------------- */
2439 #if defined(CONFIG_KUP4K) || defined(CONFIG_KUP4X)
2440
2441 #define PCMCIA_BOARD_MSG "KUP"
2442
2443 #define KUP4K_PCMCIA_B_3V3 (0x00020000)
2444
2445 static int hardware_enable(int slot)
2446 {
2447         volatile immap_t        *immap;
2448         volatile cpm8xx_t       *cp;
2449         volatile pcmconf8xx_t   *pcmp;
2450         volatile sysconf8xx_t   *sysp;
2451         uint reg, mask;
2452
2453         debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
2454
2455         udelay(10000);
2456
2457         immap = (immap_t *)CFG_IMMR;
2458         sysp  = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
2459         pcmp  = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
2460         cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
2461
2462         /*
2463          * Configure SIUMCR to enable PCMCIA port B
2464          * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
2465          */
2466         sysp->sc_siumcr &= ~SIUMCR_DBGC11;      /* set DBGC to 00 */
2467
2468         /* clear interrupt state, and disable interrupts */
2469         pcmp->pcmc_pscr =  PCMCIA_MASK(slot);
2470         pcmp->pcmc_per &= ~PCMCIA_MASK(slot);
2471
2472         /*
2473          * Disable interrupts, DMA, and PCMCIA buffers
2474          * (isolate the interface) and assert RESET signal
2475          */
2476         debug ("Disable PCMCIA buffers and assert RESET\n");
2477         reg  = 0;
2478         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
2479         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
2480         PCMCIA_PGCRX(slot) = reg;
2481         udelay(2500);
2482
2483         /*
2484          * Configure Port B pins for
2485          * 3 Volts enable
2486          */
2487         if (slot) { /* Slot A is built-in */
2488                 cp->cp_pbdir |=  KUP4K_PCMCIA_B_3V3;
2489                 cp->cp_pbpar &= ~KUP4K_PCMCIA_B_3V3;
2490                 /* remove all power */
2491                 cp->cp_pbdat |=  KUP4K_PCMCIA_B_3V3; /* active low */
2492         }
2493         /*
2494          * Make sure there is a card in the slot, then configure the interface.
2495          */
2496         udelay(10000);
2497         debug ("[%d] %s: PIPR(%p)=0x%x\n",
2498                 __LINE__,__FUNCTION__,
2499                 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
2500         if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
2501                 printf ("   No Card found\n");
2502                 return (1);
2503         }
2504
2505         /*
2506          * Power On.
2507          */
2508         printf("%s  Slot %c:", slot ? "" : "\n", 'A' + slot);
2509         mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
2510         reg  = pcmp->pcmc_pipr;
2511         debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
2512                 reg,
2513                 (reg&PCMCIA_VS1(slot))?"n":"ff",
2514                 (reg&PCMCIA_VS2(slot))?"n":"ff");
2515         if ((reg & mask) == mask) {
2516                 puts (" 5.0V card found: NOT SUPPORTED !!!\n");
2517         } else {
2518                 if(slot)
2519                         cp->cp_pbdat &= ~KUP4K_PCMCIA_B_3V3;
2520                 puts (" 3.3V card found: ");
2521         }
2522 #if 0
2523         /*  VCC switch error flag, PCMCIA slot INPACK_ pin */
2524         cp->cp_pbdir &= ~(0x0020 | 0x0010);
2525         cp->cp_pbpar &= ~(0x0020 | 0x0010);
2526         udelay(500000);
2527 #endif
2528         debug ("Enable PCMCIA buffers and stop RESET\n");
2529         reg  =  PCMCIA_PGCRX(slot);
2530         reg &= ~__MY_PCMCIA_GCRX_CXRESET;       /* active high */
2531         reg &= ~__MY_PCMCIA_GCRX_CXOE;          /* active low  */
2532         PCMCIA_PGCRX(slot) = reg;
2533
2534         udelay(250000); /* some cards need >150 ms to come up :-( */
2535
2536         debug ("# hardware_enable done\n");
2537
2538         return (0);
2539 }
2540
2541
2542 #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
2543 static int hardware_disable(int slot)
2544 {
2545         volatile immap_t        *immap;
2546         volatile cpm8xx_t       *cp;
2547         volatile pcmconf8xx_t   *pcmp;
2548         u_long reg;
2549
2550         debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
2551
2552         immap = (immap_t *)CFG_IMMR;
2553         pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
2554         cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
2555
2556         /* remove all power */
2557         if (slot)
2558                 cp->cp_pbdat |= KUP4K_PCMCIA_B_3V3;
2559
2560         /* Configure PCMCIA General Control Register */
2561         debug ("Disable PCMCIA buffers and assert RESET\n");
2562         reg  = 0;
2563         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
2564         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
2565         PCMCIA_PGCRX(slot) = reg;
2566
2567         udelay(10000);
2568
2569         return (0);
2570 }
2571 #endif  /* CFG_CMD_PCMCIA */
2572
2573
2574 static int voltage_set(int slot, int vcc, int vpp)
2575 {
2576         volatile immap_t        *immap;
2577         volatile cpm8xx_t       *cp;
2578         volatile pcmconf8xx_t   *pcmp;
2579         u_long reg;
2580
2581         debug ("voltage_set: "  \
2582                 PCMCIA_BOARD_MSG        \
2583                 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
2584                 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
2585
2586         if (!slot) /* Slot A is not configurable */
2587                 return 0;
2588
2589         immap = (immap_t *)CFG_IMMR;
2590         pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
2591         cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
2592
2593         /*
2594          * Disable PCMCIA buffers (isolate the interface)
2595          * and assert RESET signal
2596          */
2597         debug ("Disable PCMCIA buffers and assert RESET\n");
2598         reg  = PCMCIA_PGCRX(slot);
2599         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
2600         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
2601         PCMCIA_PGCRX(slot) = reg;
2602         udelay(500);
2603
2604         debug ("PCMCIA power OFF\n");
2605         /*
2606          * Configure Port B pins for
2607          * 3 Volts enable
2608          */
2609         cp->cp_pbdir |=  KUP4K_PCMCIA_B_3V3;
2610         cp->cp_pbpar &= ~KUP4K_PCMCIA_B_3V3;
2611         /* remove all power */
2612         cp->cp_pbdat |=  KUP4K_PCMCIA_B_3V3; /* active low */
2613
2614         switch(vcc) {
2615         case  0:                break;
2616         case 33:
2617                 cp->cp_pbdat &= ~KUP4K_PCMCIA_B_3V3;
2618                 debug ("PCMCIA powered at 3.3V\n");
2619                 break;
2620         case 50:
2621                 debug ("PCMCIA: 5Volt vcc not supported\n");
2622                 break;
2623         default:
2624                 puts("PCMCIA: vcc not supported");
2625                 break;
2626         }
2627         udelay(10000);
2628         /* Checking supported voltages */
2629
2630         debug ("PIPR: 0x%x --> %s\n",
2631                 pcmp->pcmc_pipr,
2632                    (pcmp->pcmc_pipr & (0x80000000 >> (slot << 4)))
2633                         ? "only 5 V --> NOT SUPPORTED"
2634                         : "can do 3.3V");
2635
2636
2637         debug ("Enable PCMCIA buffers and stop RESET\n");
2638         reg  =  PCMCIA_PGCRX(slot);
2639         reg &= ~__MY_PCMCIA_GCRX_CXRESET;       /* active high */
2640         reg &= ~__MY_PCMCIA_GCRX_CXOE;          /* active low  */
2641         PCMCIA_PGCRX(slot) = reg;
2642         udelay(500);
2643
2644         debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
2645                 slot+'A');
2646         return (0);
2647 }
2648
2649 #endif  /* KUP4K || KUP4X */
2650
2651
2652 /* -------------------------------------------------------------------- */
2653 /* End of Board Specific Stuff                                          */
2654 /* -------------------------------------------------------------------- */
2655
2656
2657 /* -------------------------------------------------------------------- */
2658 /* MPC8xx Specific Stuff - should go to MPC8xx directory                */
2659 /* -------------------------------------------------------------------- */
2660
2661 /*
2662  * Search this table to see if the windowsize is
2663  * supported...
2664  */
2665
2666 #define M8XX_SIZES_NO 32
2667
2668 static const u_int m8xx_size_to_gray[M8XX_SIZES_NO] =
2669 { 0x00000001, 0x00000002, 0x00000008, 0x00000004,
2670   0x00000080, 0x00000040, 0x00000010, 0x00000020,
2671   0x00008000, 0x00004000, 0x00001000, 0x00002000,
2672   0x00000100, 0x00000200, 0x00000800, 0x00000400,
2673
2674   0x0fffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2675   0x01000000, 0x02000000, 0xffffffff, 0x04000000,
2676   0x00010000, 0x00020000, 0x00080000, 0x00040000,
2677   0x00800000, 0x00400000, 0x00100000, 0x00200000 };
2678
2679
2680 /* -------------------------------------------------------------------- */
2681
2682 #if ( ! defined(CONFIG_I82365) && ! defined(CONFIG_PXA_PCMCIA) )
2683
2684 static u_int m8xx_get_graycode(u_int size)
2685 {
2686         u_int k;
2687
2688         for (k = 0; k < M8XX_SIZES_NO; k++) {
2689                 if(m8xx_size_to_gray[k] == size)
2690                         break;
2691         }
2692
2693         if((k == M8XX_SIZES_NO) || (m8xx_size_to_gray[k] == -1))
2694                 k = -1;
2695
2696         return k;
2697 }
2698
2699 #endif  /* CONFIG_I82365 */
2700
2701 /* -------------------------------------------------------------------- */
2702
2703 #if 0
2704 static u_int m8xx_get_speed(u_int ns, u_int is_io)
2705 {
2706         u_int reg, clocks, psst, psl, psht;
2707
2708         if(!ns) {
2709
2710                 /*
2711                  * We get called with IO maps setup to 0ns
2712                  * if not specified by the user.
2713                  * They should be 255ns.
2714                  */
2715
2716                 if(is_io)
2717                         ns = 255;
2718                 else
2719                         ns = 100;  /* fast memory if 0 */
2720         }
2721
2722         /*
2723          * In PSST, PSL, PSHT fields we tell the controller
2724          * timing parameters in CLKOUT clock cycles.
2725          * CLKOUT is the same as GCLK2_50.
2726          */
2727
2728 /* how we want to adjust the timing - in percent */
2729
2730 #define ADJ 180 /* 80 % longer accesstime - to be sure */
2731
2732         clocks = ((M8XX_BUSFREQ / 1000) * ns) / 1000;
2733         clocks = (clocks * ADJ) / (100*1000);
2734
2735         if(clocks >= PCMCIA_BMT_LIMIT) {
2736                 DEBUG(0, "Max access time limit reached\n");
2737                 clocks = PCMCIA_BMT_LIMIT-1;
2738         }
2739
2740         psst = clocks / 7;          /* setup time */
2741         psht = clocks / 7;          /* hold time */
2742         psl  = (clocks * 5) / 7;    /* strobe length */
2743
2744         psst += clocks - (psst + psht + psl);
2745
2746         reg =  psst << 12;
2747         reg |= psl  << 7;
2748         reg |= psht << 16;
2749
2750         return reg;
2751 }
2752 #endif
2753
2754 /* -------------------------------------------------------------------- */
2755
2756 #if defined(CONFIG_IDE_8xx_PCCARD) || defined(CONFIG_PXA_PCMCIA)
2757 static void print_funcid (int func)
2758 {
2759         puts (indent);
2760         switch (func) {
2761         case CISTPL_FUNCID_MULTI:
2762                 puts (" Multi-Function");
2763                 break;
2764         case CISTPL_FUNCID_MEMORY:
2765                 puts (" Memory");
2766                 break;
2767         case CISTPL_FUNCID_SERIAL:
2768                 puts (" Serial Port");
2769                 break;
2770         case CISTPL_FUNCID_PARALLEL:
2771                 puts (" Parallel Port");
2772                 break;
2773         case CISTPL_FUNCID_FIXED:
2774                 puts (" Fixed Disk");
2775                 break;
2776         case CISTPL_FUNCID_VIDEO:
2777                 puts (" Video Adapter");
2778                 break;
2779         case CISTPL_FUNCID_NETWORK:
2780                 puts (" Network Adapter");
2781                 break;
2782         case CISTPL_FUNCID_AIMS:
2783                 puts (" AIMS Card");
2784                 break;
2785         case CISTPL_FUNCID_SCSI:
2786                 puts (" SCSI Adapter");
2787                 break;
2788         default:
2789                 puts (" Unknown");
2790                 break;
2791         }
2792         puts (" Card\n");
2793 }
2794 #endif  /* CONFIG_IDE_8xx_PCCARD */
2795
2796 /* -------------------------------------------------------------------- */
2797
2798 #if defined(CONFIG_IDE_8xx_PCCARD) || defined(CONFIG_PXA_PCMCIA)
2799 static void print_fixed (volatile uchar *p)
2800 {
2801         if (p == NULL)
2802                 return;
2803
2804         puts(indent);
2805
2806         switch (*p) {
2807         case CISTPL_FUNCE_IDE_IFACE:
2808             {   uchar iface = *(p+2);
2809
2810                 puts ((iface == CISTPL_IDE_INTERFACE) ? " IDE" : " unknown");
2811                 puts (" interface ");
2812                 break;
2813             }
2814         case CISTPL_FUNCE_IDE_MASTER:
2815         case CISTPL_FUNCE_IDE_SLAVE:
2816             {   uchar f1 = *(p+2);
2817                 uchar f2 = *(p+4);
2818
2819                 puts ((f1 & CISTPL_IDE_SILICON) ? " [silicon]" : " [rotating]");
2820
2821                 if (f1 & CISTPL_IDE_UNIQUE)
2822                         puts (" [unique]");
2823
2824                 puts ((f1 & CISTPL_IDE_DUAL) ? " [dual]" : " [single]");
2825
2826                 if (f2 & CISTPL_IDE_HAS_SLEEP)
2827                         puts (" [sleep]");
2828
2829                 if (f2 & CISTPL_IDE_HAS_STANDBY)
2830                         puts (" [standby]");
2831
2832                 if (f2 & CISTPL_IDE_HAS_IDLE)
2833                         puts (" [idle]");
2834
2835                 if (f2 & CISTPL_IDE_LOW_POWER)
2836                         puts (" [low power]");
2837
2838                 if (f2 & CISTPL_IDE_REG_INHIBIT)
2839                         puts (" [reg inhibit]");
2840
2841                 if (f2 & CISTPL_IDE_HAS_INDEX)
2842                         puts (" [index]");
2843
2844                 if (f2 & CISTPL_IDE_IOIS16)
2845                         puts (" [IOis16]");
2846
2847                 break;
2848             }
2849         }
2850         putc ('\n');
2851 }
2852 #endif  /* CONFIG_IDE_8xx_PCCARD */
2853
2854 /* -------------------------------------------------------------------- */
2855
2856 #if defined(CONFIG_IDE_8xx_PCCARD) || defined(CONFIG_PXA_PCMCIA)
2857
2858 #define MAX_IDENT_CHARS         64
2859 #define MAX_IDENT_FIELDS        4
2860
2861 static uchar *known_cards[] = {
2862         (uchar *)"ARGOSY PnPIDE D5",
2863         NULL
2864 };
2865
2866 static int identify  (volatile uchar *p)
2867 {
2868         uchar id_str[MAX_IDENT_CHARS];
2869         uchar data;
2870         uchar *t;
2871         uchar **card;
2872         int i, done;
2873
2874         if (p == NULL)
2875                 return (0);     /* Don't know */
2876
2877         t = id_str;
2878         done =0;
2879
2880         for (i=0; i<=4 && !done; ++i, p+=2) {
2881                 while ((data = *p) != '\0') {
2882                         if (data == 0xFF) {
2883                                 done = 1;
2884                                 break;
2885                         }
2886                         *t++ = data;
2887                         if (t == &id_str[MAX_IDENT_CHARS-1]) {
2888                                 done = 1;
2889                                 break;
2890                         }
2891                         p += 2;
2892                 }
2893                 if (!done)
2894                         *t++ = ' ';
2895         }
2896         *t = '\0';
2897         while (--t > id_str) {
2898                 if (*t == ' ')
2899                         *t = '\0';
2900                 else
2901                         break;
2902         }
2903         puts ((char *)id_str);
2904         putc ('\n');
2905
2906         for (card=known_cards; *card; ++card) {
2907                 debug ("## Compare against \"%s\"\n", *card);
2908                 if (strcmp((char *)*card, (char *)id_str) == 0) {       /* found! */
2909                         debug ("## CARD FOUND ##\n");
2910                         return (1);
2911                 }
2912         }
2913
2914         return (0);     /* don't know */
2915 }
2916 #endif  /* CONFIG_IDE_8xx_PCCARD */
2917
2918 /* -------------------------------------------------------------------- */
2919 /* NETTA board by Intracom S.A.                                         */
2920 /* -------------------------------------------------------------------- */
2921
2922 #if defined(CONFIG_NETTA)
2923
2924 /* some sane bit macros */
2925 #define _BD(_b)                         (1U << (31-(_b)))
2926 #define _BDR(_l, _h)                    (((((1U << (31-(_l))) - 1) << 1) | 1) & ~((1U << (31-(_h))) - 1))
2927
2928 #define _BW(_b)                         (1U << (15-(_b)))
2929 #define _BWR(_l, _h)                    (((((1U << (15-(_l))) - 1) << 1) | 1) & ~((1U << (15-(_h))) - 1))
2930
2931 #define _BB(_b)                         (1U << (7-(_b)))
2932 #define _BBR(_l, _h)                    (((((1U << (7-(_l))) - 1) << 1) | 1) & ~((1U << (7-(_h))) - 1))
2933
2934 #define _B(_b)                          _BD(_b)
2935 #define _BR(_l, _h)                     _BDR(_l, _h)
2936
2937 #define PCMCIA_BOARD_MSG "NETTA"
2938
2939 static const unsigned short vppd_masks[2] = { _BW(14), _BW(15) };
2940
2941 static void cfg_vppd(int no)
2942 {
2943         volatile immap_t *immap = (immap_t *)CFG_IMMR;
2944         unsigned short mask;
2945
2946         if ((unsigned int)no >= sizeof(vppd_masks)/sizeof(vppd_masks[0]))
2947                 return;
2948
2949         mask = vppd_masks[no];
2950
2951         immap->im_ioport.iop_papar &= ~mask;
2952         immap->im_ioport.iop_paodr &= ~mask;
2953         immap->im_ioport.iop_padir |=  mask;
2954 }
2955
2956 static void set_vppd(int no, int what)
2957 {
2958         volatile immap_t *immap = (immap_t *)CFG_IMMR;
2959         unsigned short mask;
2960
2961         if ((unsigned int)no >= sizeof(vppd_masks)/sizeof(vppd_masks[0]))
2962                 return;
2963
2964         mask = vppd_masks[no];
2965
2966         if (what)
2967                 immap->im_ioport.iop_padat |= mask;
2968         else
2969                 immap->im_ioport.iop_padat &= ~mask;
2970 }
2971
2972 static const unsigned short vccd_masks[2] = { _BW(10), _BW(6) };
2973
2974 static void cfg_vccd(int no)
2975 {
2976         volatile immap_t *immap = (immap_t *)CFG_IMMR;
2977         unsigned short mask;
2978
2979         if ((unsigned int)no >= sizeof(vccd_masks)/sizeof(vccd_masks[0]))
2980                 return;
2981
2982         mask = vccd_masks[no];
2983
2984         immap->im_ioport.iop_papar &= ~mask;
2985         immap->im_ioport.iop_paodr &= ~mask;
2986         immap->im_ioport.iop_padir |=  mask;
2987 }
2988
2989 static void set_vccd(int no, int what)
2990 {
2991         volatile immap_t *immap = (immap_t *)CFG_IMMR;
2992         unsigned short mask;
2993
2994         if ((unsigned int)no >= sizeof(vccd_masks)/sizeof(vccd_masks[0]))
2995                 return;
2996
2997         mask = vccd_masks[no];
2998
2999         if (what)
3000                 immap->im_ioport.iop_padat |= mask;
3001         else
3002                 immap->im_ioport.iop_padat &= ~mask;
3003 }
3004
3005 static const unsigned short oc_mask = _BW(8);
3006
3007 static void cfg_oc(void)
3008 {
3009         volatile immap_t *immap = (immap_t *)CFG_IMMR;
3010         unsigned short mask = oc_mask;
3011
3012         immap->im_ioport.iop_pcdir &= ~mask;
3013         immap->im_ioport.iop_pcso  &= ~mask;
3014         immap->im_ioport.iop_pcint &= ~mask;
3015         immap->im_ioport.iop_pcpar &= ~mask;
3016 }
3017
3018 static int get_oc(void)
3019 {
3020         volatile immap_t *immap = (immap_t *)CFG_IMMR;
3021         unsigned short mask = oc_mask;
3022         int what;
3023
3024         what = !!(immap->im_ioport.iop_pcdat & mask);;
3025         return what;
3026 }
3027
3028 static const unsigned short shdn_mask = _BW(12);
3029
3030 static void cfg_shdn(void)
3031 {
3032         volatile immap_t *immap = (immap_t *)CFG_IMMR;
3033         unsigned short mask;
3034
3035         mask = shdn_mask;
3036
3037         immap->im_ioport.iop_papar &= ~mask;
3038         immap->im_ioport.iop_paodr &= ~mask;
3039         immap->im_ioport.iop_padir |=  mask;
3040 }
3041
3042 static void set_shdn(int what)
3043 {
3044         volatile immap_t *immap = (immap_t *)CFG_IMMR;
3045         unsigned short mask;
3046
3047         mask = shdn_mask;
3048
3049         if (what)
3050                 immap->im_ioport.iop_padat |= mask;
3051         else
3052                 immap->im_ioport.iop_padat &= ~mask;
3053 }
3054
3055 static void cfg_ports (void);
3056
3057 static int hardware_enable(int slot)
3058 {
3059         volatile immap_t        *immap;
3060         volatile cpm8xx_t       *cp;
3061         volatile pcmconf8xx_t   *pcmp;
3062         volatile sysconf8xx_t   *sysp;
3063         uint reg, pipr, mask;
3064         int i;
3065
3066         debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
3067
3068         udelay(10000);
3069
3070         immap = (immap_t *)CFG_IMMR;
3071         sysp  = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
3072         pcmp  = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
3073         cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
3074
3075         /* Configure Ports for TPS2211A PC-Card Power-Interface Switch */
3076         cfg_ports ();
3077
3078         /* clear interrupt state, and disable interrupts */
3079         pcmp->pcmc_pscr =  PCMCIA_MASK(_slot_);
3080         pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
3081
3082         /*
3083          * Disable interrupts, DMA, and PCMCIA buffers
3084          * (isolate the interface) and assert RESET signal
3085          */
3086         debug ("Disable PCMCIA buffers and assert RESET\n");
3087         reg  = 0;
3088         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
3089         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
3090         PCMCIA_PGCRX(_slot_) = reg;
3091
3092         udelay(500);
3093
3094         /*
3095          * Make sure there is a card in the slot, then configure the interface.
3096          */
3097         udelay(10000);
3098         debug ("[%d] %s: PIPR(%p)=0x%x\n",
3099                 __LINE__,__FUNCTION__,
3100                 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
3101         if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
3102                 printf ("   No Card found\n");
3103                 return (1);
3104         }
3105
3106         /*
3107          * Power On: Set VAVCC to 3.3V or 5V, set VAVPP to Hi-Z
3108          */
3109         mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
3110         pipr = pcmp->pcmc_pipr;
3111         debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
3112                 pipr,
3113                 (reg&PCMCIA_VS1(slot))?"n":"ff",
3114                 (reg&PCMCIA_VS2(slot))?"n":"ff");
3115
3116         if ((pipr & mask) == mask) {
3117                 set_vppd(0, 1); set_vppd(1, 1);                 /* VAVPP => Hi-Z */
3118                 set_vccd(0, 0); set_vccd(1, 1);                 /* 5V on, 3V off */
3119                 puts (" 5.0V card found: ");
3120         } else {
3121                 set_vppd(0, 1); set_vppd(1, 1);                 /* VAVPP => Hi-Z */
3122                 set_vccd(0, 1); set_vccd(1, 0);                 /* 5V off, 3V on */
3123                 puts (" 3.3V card found: ");
3124         }
3125
3126         /*  Wait 500 ms; use this to check for over-current */
3127         for (i=0; i<5000; ++i) {
3128                 if (!get_oc()) {
3129                         printf ("   *** Overcurrent - Safety shutdown ***\n");
3130                         set_vccd(0, 0); set_vccd(1, 0);                 /* VAVPP => Hi-Z */
3131                         return (1);
3132                 }
3133                 udelay (100);
3134         }
3135
3136         debug ("Enable PCMCIA buffers and stop RESET\n");
3137         reg  =  PCMCIA_PGCRX(_slot_);
3138         reg &= ~__MY_PCMCIA_GCRX_CXRESET;       /* active high */
3139         reg &= ~__MY_PCMCIA_GCRX_CXOE;          /* active low  */
3140         PCMCIA_PGCRX(_slot_) = reg;
3141
3142         udelay(250000); /* some cards need >150 ms to come up :-( */
3143
3144         debug ("# hardware_enable done\n");
3145
3146         return (0);
3147 }
3148
3149
3150 #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
3151 static int hardware_disable(int slot)
3152 {
3153         volatile immap_t        *immap;
3154         volatile pcmconf8xx_t   *pcmp;
3155         u_long reg;
3156
3157         debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
3158
3159         immap = (immap_t *)CFG_IMMR;
3160         pcmp  = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
3161
3162         /* Configure PCMCIA General Control Register */
3163         debug ("Disable PCMCIA buffers and assert RESET\n");
3164         reg  = 0;
3165         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
3166         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
3167         PCMCIA_PGCRX(_slot_) = reg;
3168
3169         /* All voltages off / Hi-Z */
3170                         set_vppd(0, 1); set_vppd(1, 1);
3171         set_vccd(0, 1); set_vccd(1, 1);
3172
3173         udelay(10000);
3174
3175         return (0);
3176 }
3177 #endif  /* CFG_CMD_PCMCIA */
3178
3179
3180 static int voltage_set(int slot, int vcc, int vpp)
3181 {
3182         volatile immap_t        *immap;
3183         volatile cpm8xx_t       *cp;
3184         volatile pcmconf8xx_t   *pcmp;
3185         u_long reg;
3186         ushort sreg;
3187
3188         debug ("voltage_set: "
3189                 PCMCIA_BOARD_MSG
3190                 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
3191                 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
3192
3193         immap = (immap_t *)CFG_IMMR;
3194         cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
3195         pcmp  = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
3196         /*
3197          * Disable PCMCIA buffers (isolate the interface)
3198          * and assert RESET signal
3199          */
3200         debug ("Disable PCMCIA buffers and assert RESET\n");
3201         reg  = PCMCIA_PGCRX(_slot_);
3202         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
3203         reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
3204         PCMCIA_PGCRX(_slot_) = reg;
3205         udelay(500);
3206
3207         /*
3208          * Configure Port C pins for
3209          * 5 Volts Enable and 3 Volts enable,
3210          * Turn all power pins to Hi-Z
3211          */
3212         debug ("PCMCIA power OFF\n");
3213         cfg_ports ();   /* Enables switch, but all in Hi-Z */
3214
3215         sreg  = immap->im_ioport.iop_pcdat;
3216         set_vppd(0, 1); set_vppd(1, 1);
3217
3218         switch(vcc) {
3219         case  0:
3220                 break;  /* Switch off           */
3221
3222         case 33:
3223                 set_vccd(0, 1); set_vccd(1, 0);
3224                 break;
3225
3226         case 50:
3227                 set_vccd(0, 0); set_vccd(1, 1);
3228                 break;
3229
3230         default:
3231                 goto done;
3232         }
3233
3234         /* Checking supported voltages */
3235
3236         debug ("PIPR: 0x%x --> %s\n",
3237                 pcmp->pcmc_pipr,
3238                 (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
3239
3240 done:
3241         debug ("Enable PCMCIA buffers and stop RESET\n");
3242         reg  =  PCMCIA_PGCRX(_slot_);
3243         reg &= ~__MY_PCMCIA_GCRX_CXRESET;       /* active high */
3244         reg &= ~__MY_PCMCIA_GCRX_CXOE;          /* active low  */
3245         PCMCIA_PGCRX(_slot_) = reg;
3246         udelay(500);
3247
3248         debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
3249                 slot+'A');
3250         return (0);
3251 }
3252
3253 static void cfg_ports (void)
3254 {
3255         volatile immap_t        *immap;
3256         volatile cpm8xx_t       *cp;
3257
3258         immap = (immap_t *)CFG_IMMR;
3259         cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
3260
3261
3262         cfg_vppd(0); cfg_vppd(1);       /* VPPD0,VPPD1 VAVPP => Hi-Z */
3263         cfg_vccd(0); cfg_vccd(1);       /* 3V and 5V off */
3264         cfg_shdn();
3265         cfg_oc();
3266
3267         /*
3268          * Configure Port A for TPS2211 PC-Card Power-Interface Switch
3269          *
3270          * Switch off all voltages, assert shutdown
3271          */
3272         set_vppd(0, 1); set_vppd(1, 1);
3273         set_vccd(0, 0); set_vccd(1, 0);
3274         set_shdn(1);
3275
3276         udelay(100000);
3277 }
3278
3279 #endif  /* NETTA */
3280
3281
3282 /* -------------------------------------------------------------------- */
3283 /* UC100 Boards                                                         */
3284 /* -------------------------------------------------------------------- */
3285
3286 #if defined(CONFIG_UC100)
3287
3288 #define PCMCIA_BOARD_MSG "UC100"
3289
3290 /*
3291  * Remark: don't turn off OE "__MY_PCMCIA_GCRX_CXOE" on UC100 board.
3292  *         This leads to board-hangup! (sr, 8 Dez. 2004)
3293  */
3294
3295 static void cfg_ports (void);
3296
3297 static int hardware_enable(int slot)
3298 {
3299         volatile immap_t        *immap;
3300         volatile cpm8xx_t       *cp;
3301         volatile pcmconf8xx_t   *pcmp;
3302         volatile sysconf8xx_t   *sysp;
3303         uint reg, mask;
3304
3305         debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
3306
3307         udelay(10000);
3308
3309         immap = (immap_t *)CFG_IMMR;
3310         sysp  = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
3311         pcmp  = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
3312         cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
3313
3314         /* Configure Ports for TPS2211A PC-Card Power-Interface Switch */
3315         cfg_ports ();
3316
3317         /*
3318          * Configure SIUMCR to enable PCMCIA port B
3319          * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
3320          */
3321         sysp->sc_siumcr &= ~SIUMCR_DBGC11;      /* set DBGC to 00 */
3322
3323         /* clear interrupt state, and disable interrupts */
3324         pcmp->pcmc_pscr =  PCMCIA_MASK(_slot_);
3325         pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
3326
3327         /*
3328          * Disable interrupts, DMA, and PCMCIA buffers
3329          * (isolate the interface) and assert RESET signal
3330          */
3331         debug ("Disable PCMCIA buffers and assert RESET\n");
3332         reg  = 0;
3333         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
3334         PCMCIA_PGCRX(_slot_) = reg;
3335         udelay(500);
3336
3337         /*
3338          * Make sure there is a card in the slot, then configure the interface.
3339          */
3340         udelay(10000);
3341         debug ("[%d] %s: PIPR(%p)=0x%x\n",
3342                 __LINE__,__FUNCTION__,
3343                 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
3344         if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
3345                 printf ("   No Card found\n");
3346                 return (1);
3347         }
3348
3349         /*
3350          * Power On.
3351          */
3352         mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
3353         reg  = pcmp->pcmc_pipr;
3354         debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
3355                 reg,
3356                 (reg&PCMCIA_VS1(slot))?"n":"ff",
3357                 (reg&PCMCIA_VS2(slot))?"n":"ff");
3358         if ((reg & mask) == mask) {
3359                 puts (" 5.0V card found: ");
3360         } else {
3361                 puts (" 3.3V card found: ");
3362         }
3363
3364         /*  switch VCC on */
3365         immap->im_ioport.iop_padat |= 0x8000; /* power enable 3.3V */
3366
3367         udelay(10000);
3368
3369         debug ("Enable PCMCIA buffers and stop RESET\n");
3370         reg  =  PCMCIA_PGCRX(_slot_);
3371         reg &= ~__MY_PCMCIA_GCRX_CXRESET;       /* active high */
3372         reg &= ~__MY_PCMCIA_GCRX_CXOE;          /* active low  */
3373         PCMCIA_PGCRX(_slot_) = reg;
3374
3375         udelay(250000); /* some cards need >150 ms to come up :-( */
3376
3377         debug ("# hardware_enable done\n");
3378
3379         return (0);
3380 }
3381
3382
3383 #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
3384 static int hardware_disable(int slot)
3385 {
3386         volatile immap_t        *immap;
3387         volatile cpm8xx_t       *cp;
3388         volatile pcmconf8xx_t   *pcmp;
3389         u_long reg;
3390
3391         debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
3392
3393         immap = (immap_t *)CFG_IMMR;
3394         pcmp  = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
3395
3396         /* switch VCC off */
3397         immap->im_ioport.iop_padat &= ~0x8000; /* power disable 3.3V */
3398
3399         /* Configure PCMCIA General Control Register */
3400         debug ("Disable PCMCIA buffers and assert RESET\n");
3401         reg  = 0;
3402         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
3403         PCMCIA_PGCRX(_slot_) = reg;
3404
3405         udelay(10000);
3406
3407         return (0);
3408 }
3409 #endif  /* CFG_CMD_PCMCIA */
3410
3411
3412 static int voltage_set(int slot, int vcc, int vpp)
3413 {
3414         volatile immap_t        *immap;
3415         volatile pcmconf8xx_t   *pcmp;
3416         u_long reg;
3417
3418         debug ("voltage_set: "
3419                 PCMCIA_BOARD_MSG
3420                 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
3421                 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
3422
3423         immap = (immap_t *)CFG_IMMR;
3424         pcmp  = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
3425         /*
3426          * Disable PCMCIA buffers (isolate the interface)
3427          * and assert RESET signal
3428          */
3429         debug ("Disable PCMCIA buffers and assert RESET\n");
3430         reg  = PCMCIA_PGCRX(_slot_);
3431         reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
3432         PCMCIA_PGCRX(_slot_) = reg;
3433         udelay(500);
3434
3435         /*
3436          * Configure Port C pins for
3437          * 5 Volts Enable and 3 Volts enable,
3438          * Turn all power pins to Hi-Z
3439          */
3440         debug ("PCMCIA power OFF\n");
3441         cfg_ports ();   /* Enables switch, but all in Hi-Z */
3442
3443         debug ("Enable PCMCIA buffers and stop RESET\n");
3444         reg  =  PCMCIA_PGCRX(_slot_);
3445         reg &= ~__MY_PCMCIA_GCRX_CXRESET;       /* active high */
3446         reg &= ~__MY_PCMCIA_GCRX_CXOE;          /* active low  */
3447         PCMCIA_PGCRX(_slot_) = reg;
3448         udelay(500);
3449
3450         debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
3451                 slot+'A');
3452         return (0);
3453 }
3454
3455 static void cfg_ports (void)
3456 {
3457         volatile immap_t        *immap;
3458
3459         immap = (immap_t *)CFG_IMMR;
3460
3461         /*
3462          * Configure Port A for MAX1602 PC-Card Power-Interface Switch
3463          */
3464         immap->im_ioport.iop_padat &= ~0x8000;  /* set port x output to low */
3465         immap->im_ioport.iop_padir |= 0x8000;   /* enable port x as output */
3466
3467         debug ("Set Port A: PAR: %08x DIR: %08x DAT: %08x\n",
3468                immap->im_ioport.iop_papar, immap->im_ioport.iop_padir,
3469                immap->im_ioport.iop_padat);
3470 }
3471
3472 #endif  /* UC100 */
3473
3474
3475 /* -------------------------------------------------------------------- */
3476
3477 #endif /* CFG_CMD_PCMCIA || (CFG_CMD_IDE && CONFIG_IDE_8xx_PCCARD) */
3478
3479 /**************************************************/
3480
3481 #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
3482 U_BOOT_CMD(
3483         pinit,  2,      1,      do_pinit,
3484         "pinit   - PCMCIA sub-system\n",
3485         "on  - power on PCMCIA socket\n"
3486         "pinit off - power off PCMCIA socket\n"
3487 );
3488 #endif