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