2 * (C) Copyright 2000-2002
3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
5 * See file CREDITS for list of people who contributed to this
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.
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.
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,
23 ********************************************************************
25 * Lots of code copied from:
27 * m8xx_pcmcia.c - Linux PCMCIA socket driver for the mpc8xx series.
28 * (C) 1999-2000 Magnus Damm <damm@bitsmart.com>
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
35 * This controller does _not_ meet the ExCA standard.
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.
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...
60 #include <cmd_pcmcia.h>
61 #if defined(CONFIG_IDE_8xx_PCCARD) && defined(CONFIG_8xx)
64 #if defined(CONFIG_LWMON)
68 #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA) || \
69 ((CONFIG_COMMANDS & CFG_CMD_IDE) && defined(CONFIG_IDE_8xx_PCCARD))
73 #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
74 static int pcmcia_off (void);
75 static int hardware_disable(int slot);
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 */
86 static u_int m8xx_get_graycode(u_int size);
88 static u_int m8xx_get_speed(u_int ns, u_int is_io);
91 /* ------------------------------------------------------------------------- */
93 /* look up table for pgcrx registers */
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,
100 #define PCMCIA_PGCRX(slot) (*pcmcia_pgcrx[slot])
102 const char *indent = "\t ";
104 /* ------------------------------------------------------------------------- */
106 #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
108 int do_pinit (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
113 printf ("Usage: pinit {on | off}\n");
116 if (strcmp(argv[1],"on") == 0) {
117 rcode = pcmcia_on ();
118 } else if (strcmp(argv[1],"off") == 0) {
119 rcode = pcmcia_off ();
121 printf ("Usage: pinit {on | off}\n");
127 #endif /* CFG_CMD_PCMCIA */
129 /* ------------------------------------------------------------------------- */
131 #if defined(CONFIG_LWMON)
132 # define CFG_PCMCIA_TIMING (PCMCIA_SHT(9) | PCMCIA_SST(3) | PCMCIA_SL(12))
134 # define CFG_PCMCIA_TIMING (PCMCIA_SHT(2) | PCMCIA_SST(4) | PCMCIA_SL(9))
143 debug ("Enable PCMCIA " PCMCIA_SLOT_MSG "\n");
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;
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);
155 for (i=0; i<PCMCIA_MEM_WIN_NO; ++i) {
159 #ifdef CONFIG_IDE_8xx_PCCARD
160 case 0: { /* map attribute memory */
161 win->or = ( PCMCIA_BSIZE_64M
166 | CFG_PCMCIA_TIMING );
170 case 1: { /* map I/O window for data reg */
171 win->or = ( PCMCIA_BSIZE_1K
176 | CFG_PCMCIA_TIMING );
180 case 2: { /* map I/O window for command/ctrl reg block */
181 win->or = ( PCMCIA_BSIZE_1K
186 | CFG_PCMCIA_TIMING );
189 #endif /* CONFIG_IDE_8xx_PCCARD */
190 default: /* set to not valid */
195 debug ("MemWin %d: PBR 0x%08lX POR %08lX\n",
196 i, win->br, win->or);
197 base += CFG_PCMCIA_MEM_SIZE;
201 /* turn off voltage */
202 if (voltage_set(_slot_, 0, 0))
205 /* Enable external hardware */
206 if (hardware_enable(_slot_))
209 #ifdef CONFIG_IDE_8xx_PCCARD
210 if (check_ide_device())
216 /* ------------------------------------------------------------------------- */
218 #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
220 static int pcmcia_off (void)
225 printf ("Disable PCMCIA " PCMCIA_SLOT_MSG "\n");
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_);
231 /* turn off interrupt and disable CxOE */
232 PCMCIA_PGCRX(_slot_) = __MY_PCMCIA_GCRX_CXOE;
234 /* turn off memory windows */
235 win = (pcmcia_win_t *)(&((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_pbr0);
237 for (i=0; i<PCMCIA_MEM_WIN_NO; ++i) {
238 /* disable memory window */
243 /* turn off voltage */
244 voltage_set(_slot_, 0, 0);
246 /* disable external hardware */
247 printf ("Shutdown and Poweroff " PCMCIA_SLOT_MSG "\n");
248 hardware_disable(_slot_);
252 #endif /* CFG_CMD_PCMCIA */
254 /* ------------------------------------------------------------------------- */
256 #ifdef CONFIG_IDE_8xx_PCCARD
258 #define MAX_TUPEL_SZ 512
259 #define MAX_FEATURES 4
261 static int check_ide_device (void)
263 volatile uchar *ident = NULL;
264 volatile uchar *feature_p[MAX_FEATURES];
265 volatile uchar *p, *start;
269 ushort config_base = 0;
273 debug ("PCMCIA MEM: %08X\n", CFG_PCMCIA_MEM_ADDR);
275 start = p = (volatile uchar *) CFG_PCMCIA_MEM_ADDR;
277 while ((p - start) < MAX_TUPEL_SZ) {
281 if (code == 0xFF) { /* End of chain */
286 #if defined(DEBUG) && (DEBUG > 1)
287 { volatile uchar *q = p;
288 printf ("\nTuple code %02x length %d\n\tData:",
291 for (i = 0; i < len; ++i) {
292 printf (" %02x", *q);
302 /* Fix for broken SanDisk which may have 0x80 bit set */
306 if (n_features < MAX_FEATURES)
307 feature_p[n_features++] = p;
310 config_base = (*(p+6) << 8) + (*(p+4));
311 debug ("\n## Config_base = %04x ###\n", config_base);
318 found = identify (ident);
320 if (func_id != ((uchar)~0)) {
321 print_funcid (func_id);
323 if (func_id == CISTPL_FUNCID_FIXED)
326 return (1); /* no disk drive */
329 for (i=0; i<n_features; ++i) {
330 print_fixed (feature_p[i]);
334 printf ("unknown card type\n");
338 /* set I/O area in config reg -> only valid for ARGOSY D5!!! */
339 *((uchar *)(CFG_PCMCIA_MEM_ADDR + config_base)) = 1;
343 #endif /* CONFIG_IDE_8xx_PCCARD */
345 /* ------------------------------------------------------------------------- */
348 /* ---------------------------------------------------------------------------- */
349 /* board specific stuff: */
350 /* voltage_set(), hardware_enable() and hardware_disable() */
351 /* ---------------------------------------------------------------------------- */
353 /* ---------------------------------------------------------------------------- */
354 /* RPX Boards from Embedded Planet */
355 /* ---------------------------------------------------------------------------- */
357 #if defined(CONFIG_RPXCLASSIC) || defined(CONFIG_RPXLITE)
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.
364 #define PCMCIA_BOARD_MSG "RPX CLASSIC or RPX LITE"
366 #undef PCMCIA_BMT_LIMIT
367 #define PCMCIA_BMT_LIMIT (6*8)
369 static int voltage_set(int slot, int vcc, int vpp)
375 case 33: reg |= BCSR1_PCVCTL4; break;
376 case 50: reg |= BCSR1_PCVCTL5; break;
385 reg |= BCSR1_PCVCTL6;
390 reg |= BCSR1_PCVCTL7;
397 /* first, turn off all power */
399 *((uint *)RPX_CSR_ADDR) &= ~(BCSR1_PCVCTL4 | BCSR1_PCVCTL5
400 | BCSR1_PCVCTL6 | BCSR1_PCVCTL7);
402 /* enable new powersettings */
404 *((uint *)RPX_CSR_ADDR) |= reg;
409 #define socket_get(_slot_) PCMCIA_SOCKET_KEY_5V
410 static int hardware_enable (int slot)
412 return 0; /* No hardware to enable */
414 #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
415 static int hardware_disable(int slot)
417 return 0; /* No hardware to disable */
419 #endif /* CFG_CMD_PCMCIA */
420 #endif /* CONFIG_RPXCLASSIC */
422 /* ---------------------------------------------------------------------------- */
423 /* (F)ADS Boards from Motorola */
424 /* ---------------------------------------------------------------------------- */
426 #if defined(CONFIG_ADS) || defined(CONFIG_FADS)
429 #define PCMCIA_BOARD_MSG "ADS"
430 #define PCMCIA_GLITCHY_CD /* My ADS board needs this */
432 #define PCMCIA_BOARD_MSG "FADS"
435 static int voltage_set(int slot, int vcc, int vpp)
440 case 0: reg = 0; break;
441 case 50: reg = 1; break;
442 case 120: reg = 2; break;
447 case 0: reg = 0; break;
449 case 50: reg = BCSR1_PCCVCCON; break;
452 case 33: reg = BCSR1_PCCVCC0 | BCSR1_PCCVCC1; break;
453 case 50: reg = BCSR1_PCCVCC1; break;
458 /* first, turn off all power */
461 *((uint *)BCSR1) |= BCSR1_PCCVCCON;
464 *((uint *)BCSR1) &= ~(BCSR1_PCCVCC0 | BCSR1_PCCVCC1);
466 *((uint *)BCSR1) &= ~BCSR1_PCCVPP_MASK;
468 /* enable new powersettings */
471 *((uint *)BCSR1) &= ~reg;
474 *((uint *)BCSR1) |= reg;
477 *((uint *)BCSR1) |= reg << 20;
482 #define socket_get(_slot_) PCMCIA_SOCKET_KEY_5V
484 static int hardware_enable(int slot)
486 *((uint *)BCSR1) &= ~BCSR1_PCCEN;
490 #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
491 static int hardware_disable(int slot)
493 *((uint *)BCSR1) &= ~BCSR1_PCCEN;
496 #endif /* CFG_CMD_PCMCIA */
500 /* ---------------------------------------------------------------------------- */
501 /* TQM8xxL Boards by TQ Components */
502 /* ---------------------------------------------------------------------------- */
504 #if defined(CONFIG_TQM8xxL)
506 #define PCMCIA_BOARD_MSG "TQM8xxL"
509 static int hardware_enable(int slot)
511 volatile immap_t *immap;
512 volatile cpm8xx_t *cp;
513 volatile pcmconf8xx_t *pcmp;
514 volatile sysconf8xx_t *sysp;
517 debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
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));
527 * Configure SIUMCR to enable PCMCIA port B
528 * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
530 sysp->sc_siumcr &= ~SIUMCR_DBGC11; /* set DBGC to 00 */
532 /* clear interrupt state, and disable interrupts */
533 pcmp->pcmc_pscr = PCMCIA_MASK(_slot_);
534 pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
536 /* disable interrupts & DMA */
537 PCMCIA_PGCRX(_slot_) = 0;
540 * Disable PCMCIA buffers (isolate the interface)
541 * and assert RESET signal
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;
551 * Configure Port C pins for
552 * 5 Volts Enable and 3 Volts enable
554 immap->im_ioport.iop_pcpar &= ~(0x0002 | 0x0004);
555 immap->im_ioport.iop_pcso &= ~(0x0002 | 0x0004);
556 /* remove all power */
558 immap->im_ioport.iop_pcdat &= ~(0x0002 | 0x0004);
561 * Make sure there is a card in the slot, then configure the interface.
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");
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",
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: ");
585 immap->im_ioport.iop_pcdat |= 0x0002;
586 puts (" 3.3V card found: ");
588 immap->im_ioport.iop_pcdir |= (0x0002 | 0x0004);
590 /* VCC switch error flag, PCMCIA slot INPACK_ pin */
591 cp->cp_pbdir &= ~(0x0020 | 0x0010);
592 cp->cp_pbpar &= ~(0x0020 | 0x0010);
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;
602 udelay(250000); /* some cards need >150 ms to come up :-( */
604 debug ("# hardware_enable done\n");
611 #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
612 static int hardware_disable(int slot)
614 volatile immap_t *immap;
615 volatile pcmconf8xx_t *pcmp;
618 debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
620 immap = (immap_t *)CFG_IMMR;
621 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
623 /* remove all power */
624 immap->im_ioport.iop_pcdat &= ~(0x0002 | 0x0004);
626 /* Configure PCMCIA General Control Register */
627 PCMCIA_PGCRX(_slot_) = 0;
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;
639 #endif /* CFG_CMD_PCMCIA */
643 static int voltage_set(int slot, int vcc, int vpp)
645 volatile immap_t *immap;
646 volatile pcmconf8xx_t *pcmp;
649 debug ("voltage_set: "
651 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
652 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
654 immap = (immap_t *)CFG_IMMR;
655 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
657 * Disable PCMCIA buffers (isolate the interface)
658 * and assert RESET signal
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;
668 * Configure Port C pins for
669 * 5 Volts Enable and 3 Volts enable,
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);
680 case 33: reg |= 0x0002; break;
681 case 50: reg |= 0x0004; break;
685 /* Checking supported voltages */
687 debug ("PIPR: 0x%x --> %s\n",
689 (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
691 immap->im_ioport.iop_pcdat |= reg;
692 immap->im_ioport.iop_pcdir |= (0x0002 | 0x0004);
694 debug ("PCMCIA powered at %sV\n",
695 (reg&0x0004) ? "5.0" : "3.3");
697 debug ("PCMCIA powered down\n");
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;
708 debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
716 /* ---------------------------------------------------------------------------- */
718 /* ---------------------------------------------------------------------------- */
720 #if defined(CONFIG_LWMON)
722 #define PCMCIA_BOARD_MSG "LWMON"
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
734 static int hardware_enable(int slot)
736 volatile immap_t *immap;
737 volatile cpm8xx_t *cp;
738 volatile pcmconf8xx_t *pcmp;
739 volatile sysconf8xx_t *sysp;
744 debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
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);
750 /* reg |= 0x08; Vpp not needed */
751 pic_write (0x60, reg);
753 reg = pic_read (0x60);
754 printf ("[%d] PIC read: reg_60 = 0x%02x\n", __LINE__, reg);
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));
764 * Configure SIUMCR to enable PCMCIA port B
765 * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
767 sysp->sc_siumcr &= ~SIUMCR_DBGC11; /* set DBGC to 00 */
769 /* clear interrupt state, and disable interrupts */
770 pcmp->pcmc_pscr = PCMCIA_MASK(_slot_);
771 pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
773 /* disable interrupts & DMA */
774 PCMCIA_PGCRX(_slot_) = 0;
777 * Disable PCMCIA buffers (isolate the interface)
778 * and assert RESET signal
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;
788 * Make sure there is a card in the slot, then configure the interface.
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");
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",
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: ");
812 val = MAX1604_VCC_35; /* VCCB3/5 = 1 ==> use Vy = 3.3 V */
813 puts (" 3.3V card found: ");
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);
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;
829 udelay(250000); /* some cards need >150 ms to come up :-( */
831 debug ("# hardware_enable done\n");
838 #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
839 static int hardware_disable(int slot)
841 volatile immap_t *immap;
842 volatile pcmconf8xx_t *pcmp;
846 debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
848 immap = (immap_t *)CFG_IMMR;
849 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
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);
856 /* Configure PCMCIA General Control Register */
857 PCMCIA_PGCRX(_slot_) = 0;
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;
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);
870 pic_write (0x60, reg);
872 reg = pic_read (0x60);
873 printf ("[%d] PIC read: reg_60 = 0x%02x\n", __LINE__, reg);
879 #endif /* CFG_CMD_PCMCIA */
883 static int voltage_set(int slot, int vcc, int vpp)
885 volatile immap_t *immap;
886 volatile pcmconf8xx_t *pcmp;
890 debug ("voltage_set: "
892 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
893 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
895 immap = (immap_t *)CFG_IMMR;
896 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
898 * Disable PCMCIA buffers (isolate the interface)
899 * and assert RESET signal
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;
909 * Turn off all power (switch to high impedance)
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);
919 case 33: val = MAX1604_VCC_35; break;
924 /* Checking supported voltages */
926 debug ("PIPR: 0x%x --> %s\n",
928 (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
930 i2c_write (CFG_I2C_POWER_A_ADDR, 0, 0, &val, 1);
932 debug ("PCMCIA powered at %sV\n",
933 (val & MAX1604_VCC_35) ? "3.3" : "5.0");
935 debug ("PCMCIA powered down\n");
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;
946 debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
953 /* ---------------------------------------------------------------------------- */
954 /* GTH board by Corelatus AB */
955 /* ---------------------------------------------------------------------------- */
956 #if defined(CONFIG_GTH)
958 #define PCMCIA_BOARD_MSG "GTH COMPACT FLASH"
960 static int voltage_set(int slot, int vcc, int vpp)
965 static int hardware_enable (int slot)
967 volatile immap_t *immap;
968 volatile cpm8xx_t *cp;
969 volatile pcmconf8xx_t *pcmp;
970 volatile sysconf8xx_t *sysp;
973 debug ("hardware_enable: GTH Slot %c\n", 'A'+slot);
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));
980 /* clear interrupt state, and disable interrupts */
981 pcmp->pcmc_pscr = PCMCIA_MASK(_slot_);
982 pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
984 /* disable interrupts & DMA */
985 PCMCIA_PGCRX(_slot_) = 0;
988 * Disable PCMCIA buffers (isolate the interface)
989 * and assert RESET signal
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;
999 * Make sure there is a card in the slot, then configure the interface.
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");
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",
1014 (reg&PCMCIA_VS1(slot))?"n":"ff",
1015 (reg&PCMCIA_VS2(slot))?"n":"ff");
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;
1023 udelay(250000); /* some cards need >150 ms to come up :-( */
1025 debug ("# hardware_enable done\n");
1029 #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
1030 static int hardware_disable(int slot)
1032 return 0; /* No hardware to disable */
1034 #endif /* CFG_CMD_PCMCIA */
1035 #endif /* CONFIG_GTH */
1037 /* ---------------------------------------------------------------------------- */
1038 /* ICU862 Boards by Cambridge Broadband Ltd. */
1039 /* ---------------------------------------------------------------------------- */
1041 #if defined(CONFIG_ICU862)
1043 #define PCMCIA_BOARD_MSG "ICU862"
1045 static void cfg_port_B (void);
1047 static int hardware_enable(int slot)
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;
1056 debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
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));
1065 /* Configure Port B for TPS2205 PC-Card Power-Interface Switch */
1069 * Configure SIUMCR to enable PCMCIA port B
1070 * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
1072 sysp->sc_siumcr &= ~SIUMCR_DBGC11; /* set DBGC to 00 */
1074 /* clear interrupt state, and disable interrupts */
1075 pcmp->pcmc_pscr = PCMCIA_MASK(_slot_);
1076 pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
1078 /* disable interrupts & DMA */
1079 PCMCIA_PGCRX(_slot_) = 0;
1082 * Disable PCMCIA buffers (isolate the interface)
1083 * and assert RESET signal
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;
1093 * Make sure there is a card in the slot, then configure the interface.
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");
1105 * Power On: Set VAVCC to 3.3V or 5V, set VAVPP to Hi-Z
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",
1111 (reg&PCMCIA_VS1(slot))?"n":"ff",
1112 (reg&PCMCIA_VS2(slot))?"n":"ff");
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: ");
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: ");
1127 debug ("\nPB DAT: %08x -> 3.3V %s 5.0V %s VPP_PGM %s VPP_VCC %s\n",
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" );
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);
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;
1152 udelay(250000); /* some cards need >150 ms to come up :-( */
1154 debug ("# hardware_enable done\n");
1161 #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
1162 static int hardware_disable(int slot)
1164 volatile immap_t *immap;
1165 volatile cpm8xx_t *cp;
1166 volatile pcmconf8xx_t *pcmp;
1169 debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
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));
1176 cp->cp_pbdat &= ~(TPS2205_SHDN);
1178 /* Configure PCMCIA General Control Register */
1179 PCMCIA_PGCRX(_slot_) = 0;
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;
1191 #endif /* CFG_CMD_PCMCIA */
1195 static int voltage_set(int slot, int vcc, int vpp)
1197 volatile immap_t *immap;
1198 volatile cpm8xx_t *cp;
1199 volatile pcmconf8xx_t *pcmp;
1202 debug ("voltage_set: "
1204 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
1205 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
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));
1211 * Disable PCMCIA buffers (isolate the interface)
1212 * and assert RESET signal
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;
1222 * Configure Port C pins for
1223 * 5 Volts Enable and 3 Volts enable,
1224 * Turn all power pins to Hi-Z
1226 debug ("PCMCIA power OFF\n");
1227 cfg_port_B (); /* Enables switch, but all in Hi-Z */
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 */
1238 /* Checking supported voltages */
1240 debug ("PIPR: 0x%x --> %s\n",
1242 (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
1250 if ((reg & TPS2205_VCC3) == 0) {
1252 } else if ((reg & TPS2205_VCC5) == 0) {
1257 printf ("PCMCIA powered %s\n", s);
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;
1269 debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
1274 static void cfg_port_B (void)
1276 volatile immap_t *immap;
1277 volatile cpm8xx_t *cp;
1280 immap = (immap_t *)CFG_IMMR;
1281 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1284 * Configure Port B for TPS2205 PC-Card Power-Interface Switch
1286 * Switch off all voltages, assert shutdown
1289 reg |= (TPS2205_VPP_PGM | TPS2205_VPP_VCC | /* VAVPP => Hi-Z */
1290 TPS2205_VCC3 | TPS2205_VCC5 | /* VAVCC => Hi-Z */
1291 TPS2205_SHDN); /* enable switch */
1294 cp->cp_pbpar &= ~(TPS2205_INPUTS | TPS2205_OUTPUTS);
1296 reg = cp->cp_pbdir & ~(TPS2205_INPUTS);
1297 cp->cp_pbdir = reg | TPS2205_OUTPUTS;
1299 debug ("Set Port B: PAR: %08x DIR: %08x DAT: %08x\n",
1300 cp->cp_pbpar, cp->cp_pbdir, cp->cp_pbdat);
1306 /* ---------------------------------------------------------------------------- */
1307 /* C2MON Boards by TTTech Computertechnik AG */
1308 /* ---------------------------------------------------------------------------- */
1310 #if defined(CONFIG_C2MON)
1312 #define PCMCIA_BOARD_MSG "C2MON"
1314 static void cfg_ports (void);
1316 static int hardware_enable(int slot)
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;
1326 debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
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));
1335 /* Configure Ports for TPS2211A PC-Card Power-Interface Switch */
1339 * Configure SIUMCR to enable PCMCIA port B
1340 * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
1342 sysp->sc_siumcr &= ~SIUMCR_DBGC11; /* set DBGC to 00 */
1344 /* clear interrupt state, and disable interrupts */
1345 pcmp->pcmc_pscr = PCMCIA_MASK(_slot_);
1346 pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
1348 /* disable interrupts & DMA */
1349 PCMCIA_PGCRX(_slot_) = 0;
1352 * Disable PCMCIA buffers (isolate the interface)
1353 * and assert RESET signal
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;
1363 * Make sure there is a card in the slot, then configure the interface.
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");
1375 * Power On: Set VAVCC to 3.3V or 5V, set VAVPP to Hi-Z
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",
1381 (reg&PCMCIA_VS1(slot))?"n":"ff",
1382 (reg&PCMCIA_VS2(slot))?"n":"ff");
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: ");
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: ");
1397 debug ("\nPC DAT: %04x -> 3.3V %s 5.0V %s\n",
1399 ( (sreg & TPS2211_VCCD0) && !(sreg & TPS2211_VCCD1)) ? "on" : "off",
1400 (!(sreg & TPS2211_VCCD0) && (sreg & TPS2211_VCCD1)) ? "on" : "off"
1403 immap->im_ioport.iop_pcdat = sreg;
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);
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;
1421 udelay(250000); /* some cards need >150 ms to come up :-( */
1423 debug ("# hardware_enable done\n");
1430 #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
1431 static int hardware_disable(int slot)
1433 volatile immap_t *immap;
1434 volatile cpm8xx_t *cp;
1435 volatile pcmconf8xx_t *pcmp;
1438 debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1440 immap = (immap_t *)CFG_IMMR;
1441 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1443 /* Configure PCMCIA General Control Register */
1444 PCMCIA_PGCRX(_slot_) = 0;
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;
1452 /* ALl voltages off / Hi-Z */
1453 immap->im_ioport.iop_pcdat |= (TPS2211_VPPD0 | TPS2211_VPPD1 |
1454 TPS2211_VCCD0 | TPS2211_VCCD1 );
1460 #endif /* CFG_CMD_PCMCIA */
1464 static int voltage_set(int slot, int vcc, int vpp)
1466 volatile immap_t *immap;
1467 volatile cpm8xx_t *cp;
1468 volatile pcmconf8xx_t *pcmp;
1472 debug ("voltage_set: "
1474 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
1475 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
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));
1481 * Disable PCMCIA buffers (isolate the interface)
1482 * and assert RESET signal
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;
1492 * Configure Port C pins for
1493 * 5 Volts Enable and 3 Volts enable,
1494 * Turn all power pins to Hi-Z
1496 debug ("PCMCIA power OFF\n");
1497 cfg_ports (); /* Enables switch, but all in Hi-Z */
1499 sreg = immap->im_ioport.iop_pcdat;
1500 sreg |= TPS2211_VPPD0 | TPS2211_VPPD1; /* VAVPP always Hi-Z */
1503 case 0: break; /* Switch off */
1504 case 33: sreg |= TPS2211_VCCD0; /* Switch on 3.3V */
1505 sreg &= ~TPS2211_VCCD1;
1507 case 50: sreg &= ~TPS2211_VCCD0; /* Switch on 5.0V */
1508 sreg |= TPS2211_VCCD1;
1513 /* Checking supported voltages */
1515 debug ("PIPR: 0x%x --> %s\n",
1517 (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
1519 immap->im_ioport.iop_pcdat = sreg;
1525 if ((sreg & TPS2211_VCCD0) && !(sreg & TPS2211_VCCD1)) {
1527 } else if (!(sreg & TPS2211_VCCD0) && (sreg & TPS2211_VCCD1)) {
1532 printf ("PCMCIA powered %s\n", s);
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;
1544 debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
1549 static void cfg_ports (void)
1551 volatile immap_t *immap;
1552 volatile cpm8xx_t *cp;
1555 immap = (immap_t *)CFG_IMMR;
1556 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1559 * Configure Port C for TPS2211 PC-Card Power-Interface Switch
1561 * Switch off all voltages, assert shutdown
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;
1568 immap->im_ioport.iop_pcpar &= ~(TPS2211_OUTPUTS);
1569 immap->im_ioport.iop_pcdir |= TPS2211_OUTPUTS;
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);
1577 * Configure Port B for TPS2211 PC-Card Power-Interface Switch
1579 * Over-Current Input only
1581 cp->cp_pbpar &= ~(TPS2211_INPUTS);
1582 cp->cp_pbdir &= ~(TPS2211_INPUTS);
1584 debug ("Set Port B: PAR: %08x DIR: %08x DAT: %08x\n",
1585 cp->cp_pbpar, cp->cp_pbdir, cp->cp_pbdat);
1590 /* ----------------------------------------------------------------------------
1591 MBX board from Morotola
1592 ---------------------------------------------------------------------------- */
1594 #if defined( CONFIG_MBX )
1595 #include <../board/mbx8xx/csr.h>
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. */
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)
1606 #define PCMCIA_BOARD_MSG "MBX860"
1608 static int voltage_set (int slot, int vcc, int vpp)
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);
1646 /* first, turn off all power */
1647 MBX_CSR2 &= ~(CR2_VDDSEL | CR2_VPPSEL);
1649 /* enable new powersettings */
1651 debug ("MBX_CSR2 read = 0x%02x\n", MBX_CSR2);
1656 static int hardware_enable (int slot)
1658 volatile immap_t *immap;
1659 volatile cpm8xx_t *cp;
1660 volatile pcmconf8xx_t *pcmp;
1661 volatile sysconf8xx_t *sysp;
1664 debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n",
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));
1674 /* clear interrupt state, and disable interrupts */
1675 pcmp->pcmc_pscr = PCMCIA_MASK (_slot_);
1676 pcmp->pcmc_per &= ~PCMCIA_MASK (_slot_);
1678 /* disable interrupts & DMA */
1679 PCMCIA_PGCRX (_slot_) = 0;
1682 * Disable PCMCIA buffers (isolate the interface)
1683 * and assert RESET signal
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;
1692 /* remove all power */
1693 voltage_set (slot, 0, 0);
1695 * Make sure there is a card in the slot, then configure the interface.
1698 debug ("[%d] %s: PIPR(%p)=0x%x\n", __LINE__, __FUNCTION__,
1699 &(pcmp->pcmc_pipr), pcmp->pcmc_pipr);
1701 if (pcmp->pcmc_pipr & 0x00001800) {
1702 printf (" No Card found\n");
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");
1715 if ((reg & mask) == mask) {
1716 voltage_set (_slot_, 50, 0);
1717 printf (" 5.0V card found: ");
1719 voltage_set (_slot_, 33, 0);
1720 printf (" 3.3V card found: ");
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;
1729 udelay (250000); /* some cards need >150 ms to come up :-( */
1731 debug ("# hardware_enable done\n");
1736 #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
1737 static int hardware_disable (int slot)
1739 return 0; /* No hardware to disable */
1741 #endif /* CFG_CMD_PCMCIA */
1742 #endif /* CONFIG_MBX */
1743 /* ---------------------------------------------------------------------------- */
1745 /* ---------------------------------------------------------------------------- */
1747 #if defined(CONFIG_R360MPI)
1749 #define PCMCIA_BOARD_MSG "R360MPI"
1752 static int hardware_enable(int slot)
1754 volatile immap_t *immap;
1755 volatile cpm8xx_t *cp;
1756 volatile pcmconf8xx_t *pcmp;
1757 volatile sysconf8xx_t *sysp;
1760 debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
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));
1770 * Configure SIUMCR to enable PCMCIA port B
1771 * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
1773 sysp->sc_siumcr &= ~SIUMCR_DBGC11; /* set DBGC to 00 */
1775 /* clear interrupt state, and disable interrupts */
1776 pcmp->pcmc_pscr = PCMCIA_MASK(_slot_);
1777 pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
1779 /* disable interrupts & DMA */
1780 PCMCIA_PGCRX(_slot_) = 0;
1783 * Disable PCMCIA buffers (isolate the interface)
1784 * and assert RESET signal
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;
1794 * Configure Ports A, B & C pins for
1795 * 5 Volts Enable and 3 Volts enable
1797 immap->im_ioport.iop_pcpar &= ~(0x0400);
1798 immap->im_ioport.iop_pcso &= ~(0x0400);/*
1799 immap->im_ioport.iop_pcdir |= 0x0400;*/
1801 immap->im_ioport.iop_papar &= ~(0x0200);/*
1802 immap->im_ioport.iop_padir |= 0x0200;*/
1804 immap->im_ioport.iop_pbpar &= ~(0xC000);
1805 immap->im_ioport.iop_pbdir &= ~(0xC000);
1807 /* remove all power */
1809 immap->im_ioport.iop_pcdat |= 0x0400;
1810 immap->im_ioport.iop_padat |= 0x0200;
1813 * Make sure there is a card in the slot, then configure the interface.
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");
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",
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: ");
1837 immap->im_ioport.iop_padat &= ~(0x0002);
1838 puts (" 3.3V card found: ");
1840 immap->im_ioport.iop_pcdir |= 0x0400;
1841 immap->im_ioport.iop_padir |= 0x0200;
1843 /* VCC switch error flag, PCMCIA slot INPACK_ pin */
1844 cp->cp_pbdir &= ~(0x0020 | 0x0010);
1845 cp->cp_pbpar &= ~(0x0020 | 0x0010);
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;
1854 udelay(250000); /* some cards need >150 ms to come up :-( */
1856 debug ("# hardware_enable done\n");
1863 #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
1864 static int hardware_disable(int slot)
1866 volatile immap_t *immap;
1867 volatile pcmconf8xx_t *pcmp;
1870 debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1872 immap = (immap_t *)CFG_IMMR;
1873 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1875 /* remove all power */
1876 immap->im_ioport.iop_pcdat |= 0x0400;
1877 immap->im_ioport.iop_padat |= 0x0200;
1879 /* Configure PCMCIA General Control Register */
1880 PCMCIA_PGCRX(_slot_) = 0;
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;
1892 #endif /* CFG_CMD_PCMCIA */
1896 static int voltage_set(int slot, int vcc, int vpp)
1898 volatile immap_t *immap;
1899 volatile pcmconf8xx_t *pcmp;
1902 debug ("voltage_set: "
1904 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
1905 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
1907 immap = (immap_t *)CFG_IMMR;
1908 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1910 * Disable PCMCIA buffers (isolate the interface)
1911 * and assert RESET signal
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;
1921 * Configure Ports A & C pins for
1922 * 5 Volts Enable and 3 Volts enable,
1923 * Turn off all power
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;*/
1930 immap->im_ioport.iop_papar &= ~(0x0200);/*
1931 immap->im_ioport.iop_padir |= 0x0200;*/
1933 immap->im_ioport.iop_pcdat |= 0x0400;
1934 immap->im_ioport.iop_padat |= 0x0200;
1939 case 33: reg |= 0x0200; break;
1940 case 50: reg |= 0x0400; break;
1944 /* Checking supported voltages */
1946 debug ("PIPR: 0x%x --> %s\n",
1948 (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
1951 immap->im_ioport.iop_pcdat &= !reg;
1953 immap->im_ioport.iop_padat &= !reg;
1954 immap->im_ioport.iop_pcdir |= 0x0200;
1955 immap->im_ioport.iop_padir |= 0x0400;
1957 debug ("PCMCIA powered at %sV\n",
1958 (reg&0x0400) ? "5.0" : "3.3");
1960 debug ("PCMCIA powered down\n");
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;
1971 debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
1976 #endif /* R360MPI */
1979 /* ---------------------------------------------------------------------------- */
1980 /* End of Board Specific Stuff */
1981 /* ---------------------------------------------------------------------------- */
1984 /* ---------------------------------------------------------------------------- */
1985 /* MPC8xx Specific Stuff - should go to MPC8xx directory */
1986 /* ---------------------------------------------------------------------------- */
1989 * Search this table to see if the windowsize is
1993 #define M8XX_SIZES_NO 32
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,
2001 0x0fffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2002 0x01000000, 0x02000000, 0xffffffff, 0x04000000,
2003 0x00010000, 0x00020000, 0x00080000, 0x00040000,
2004 0x00800000, 0x00400000, 0x00100000, 0x00200000 };
2007 /* ---------------------------------------------------------------------------- */
2009 static u_int m8xx_get_graycode(u_int size)
2013 for (k = 0; k < M8XX_SIZES_NO; k++) {
2014 if(m8xx_size_to_gray[k] == size)
2018 if((k == M8XX_SIZES_NO) || (m8xx_size_to_gray[k] == -1))
2024 /* ------------------------------------------------------------------------- */
2027 static u_int m8xx_get_speed(u_int ns, u_int is_io)
2029 u_int reg, clocks, psst, psl, psht;
2034 * We get called with IO maps setup to 0ns
2035 * if not specified by the user.
2036 * They should be 255ns.
2042 ns = 100; /* fast memory if 0 */
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.
2051 /* how we want to adjust the timing - in percent */
2053 #define ADJ 180 /* 80 % longer accesstime - to be sure */
2055 clocks = ((M8XX_BUSFREQ / 1000) * ns) / 1000;
2056 clocks = (clocks * ADJ) / (100*1000);
2058 if(clocks >= PCMCIA_BMT_LIMIT) {
2059 DEBUG(0, "Max access time limit reached\n");
2060 clocks = PCMCIA_BMT_LIMIT-1;
2063 psst = clocks / 7; /* setup time */
2064 psht = clocks / 7; /* hold time */
2065 psl = (clocks * 5) / 7; /* strobe length */
2067 psst += clocks - (psst + psht + psl);
2077 /* ------------------------------------------------------------------------- */
2079 #ifdef CONFIG_IDE_8xx_PCCARD
2080 static void print_funcid (int func)
2084 case CISTPL_FUNCID_MULTI:
2085 puts (" Multi-Function");
2087 case CISTPL_FUNCID_MEMORY:
2090 case CISTPL_FUNCID_SERIAL:
2091 puts (" Serial Port");
2093 case CISTPL_FUNCID_PARALLEL:
2094 puts (" Parallel Port");
2096 case CISTPL_FUNCID_FIXED:
2097 puts (" Fixed Disk");
2099 case CISTPL_FUNCID_VIDEO:
2100 puts (" Video Adapter");
2102 case CISTPL_FUNCID_NETWORK:
2103 puts (" Network Adapter");
2105 case CISTPL_FUNCID_AIMS:
2106 puts (" AIMS Card");
2108 case CISTPL_FUNCID_SCSI:
2109 puts (" SCSI Adapter");
2117 #endif /* CONFIG_IDE_8xx_PCCARD */
2119 /* ------------------------------------------------------------------------- */
2121 #ifdef CONFIG_IDE_8xx_PCCARD
2122 static void print_fixed (volatile uchar *p)
2130 case CISTPL_FUNCE_IDE_IFACE:
2131 { uchar iface = *(p+2);
2133 puts ((iface == CISTPL_IDE_INTERFACE) ? " IDE" : " unknown");
2134 puts (" interface ");
2137 case CISTPL_FUNCE_IDE_MASTER:
2138 case CISTPL_FUNCE_IDE_SLAVE:
2139 { uchar f1 = *(p+2);
2142 puts ((f1 & CISTPL_IDE_SILICON) ? " [silicon]" : " [rotating]");
2144 if (f1 & CISTPL_IDE_UNIQUE)
2147 puts ((f1 & CISTPL_IDE_DUAL) ? " [dual]" : " [single]");
2149 if (f2 & CISTPL_IDE_HAS_SLEEP)
2152 if (f2 & CISTPL_IDE_HAS_STANDBY)
2153 puts (" [standby]");
2155 if (f2 & CISTPL_IDE_HAS_IDLE)
2158 if (f2 & CISTPL_IDE_LOW_POWER)
2159 puts (" [low power]");
2161 if (f2 & CISTPL_IDE_REG_INHIBIT)
2162 puts (" [reg inhibit]");
2164 if (f2 & CISTPL_IDE_HAS_INDEX)
2167 if (f2 & CISTPL_IDE_IOIS16)
2175 #endif /* CONFIG_IDE_8xx_PCCARD */
2177 /* ------------------------------------------------------------------------- */
2179 #ifdef CONFIG_IDE_8xx_PCCARD
2181 #define MAX_IDENT_CHARS 64
2182 #define MAX_IDENT_FIELDS 4
2184 static uchar *known_cards[] = {
2189 static int identify (volatile uchar *p)
2191 uchar id_str[MAX_IDENT_CHARS];
2198 return (0); /* Don't know */
2203 for (i=0; i<=4 && !done; ++i, p+=2) {
2204 while ((data = *p) != '\0') {
2210 if (t == &id_str[MAX_IDENT_CHARS-1]) {
2220 while (--t > id_str) {
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");
2237 return (0); /* don't know */
2239 #endif /* CONFIG_IDE_8xx_PCCARD */
2241 /* ------------------------------------------------------------------------- */
2243 #endif /* CFG_CMD_PCMCIA || (CFG_CMD_IDE && CONFIG_IDE_8xx_PCCARD) */