Skip to content
Snippets Groups Projects
cmd_pcmcia.c 60.2 KiB
Newer Older
  • Learn to ignore specific revisions
  • 	volatile immap_t	*immap;
    	volatile cpm8xx_t	*cp;
    	volatile pcmconf8xx_t	*pcmp;
    	volatile sysconf8xx_t	*sysp;
    	uint reg, mask;
    
    	debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
    
    	udelay(10000);
    
    	immap = (immap_t *)CFG_IMMR;
    	sysp  = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
    	pcmp  = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
    	cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
    
    	/*
    	 * Configure SIUMCR to enable PCMCIA port B
    	 * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
    	 */
    	sysp->sc_siumcr &= ~SIUMCR_DBGC11;	/* set DBGC to 00 */
    
    	/* clear interrupt state, and disable interrupts */
    
    	pcmp->pcmc_pscr =  PCMCIA_MASK(slot);
    	pcmp->pcmc_per &= ~PCMCIA_MASK(slot);
    
    
    	/*
    	 * Disable PCMCIA buffers (isolate the interface)
    	 * and assert RESET signal
    	 */
    	debug ("Disable PCMCIA buffers and assert RESET\n");
    
    	reg |=  __MY_PCMCIA_GCRX_CXRESET;	/* active high */
    	reg |=  __MY_PCMCIA_GCRX_CXOE;		/* active low  */
    
    	PCMCIA_PGCRX(slot) = reg;
    	udelay(2500);
    
    	if (slot) { /* Slot A is built-in */
    		cp->cp_pbdir |=  KUP4K_PCMCIA_B_3V3;
    		cp->cp_pbpar &= ~KUP4K_PCMCIA_B_3V3;
    		/* remove all power */
    		cp->cp_pbdat |=  KUP4K_PCMCIA_B_3V3; /* active low */
    	}
    
    	/*
    	 * Make sure there is a card in the slot, then configure the interface.
    	 */
    	udelay(10000);
    	debug ("[%d] %s: PIPR(%p)=0x%x\n",
    		__LINE__,__FUNCTION__,
    		&(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
    
    	if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
    
    	printf("%s  Slot %c:", slot ? "" : "\n", 'A' + slot);
    
    	mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
    	reg  = pcmp->pcmc_pipr;
    	debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
    		reg,
    		(reg&PCMCIA_VS1(slot))?"n":"ff",
    		(reg&PCMCIA_VS2(slot))?"n":"ff");
    	if ((reg & mask) == mask) {
    		puts (" 5.0V card found: NOT SUPPORTED !!!\n");
    	} else {
    
    		if(slot)
    			cp->cp_pbdat &= ~KUP4K_PCMCIA_B_3V3;
    
    		puts (" 3.3V card found: ");
    	}
    #if 0
    	/*  VCC switch error flag, PCMCIA slot INPACK_ pin */
    	cp->cp_pbdir &= ~(0x0020 | 0x0010);
    	cp->cp_pbpar &= ~(0x0020 | 0x0010);
    	udelay(500000);
    #endif
    	debug ("Enable PCMCIA buffers and stop RESET\n");
    
    	reg &= ~__MY_PCMCIA_GCRX_CXRESET;	/* active high */
    	reg &= ~__MY_PCMCIA_GCRX_CXOE;		/* active low  */
    
    
    	udelay(250000);	/* some cards need >150 ms to come up :-( */
    
    	debug ("# hardware_enable done\n");
    
    	return (0);
    }
    
    
    
    #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
    static int hardware_disable(int slot)
    {
    	volatile immap_t	*immap;
    	volatile cpm8xx_t	*cp;
    	volatile pcmconf8xx_t	*pcmp;
    	u_long reg;
    
    	debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
    
    	immap = (immap_t *)CFG_IMMR;
    	pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
    	cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
    	
    	/* remove all power */
    
    	if (slot)
    		cp->cp_pbdat |= KUP4K_PCMCIA_B_3V3;
    
    
    	/* Configure PCMCIA General Control Register */
    
    
    	debug ("Disable PCMCIA buffers and assert RESET\n");
    
    	reg |= __MY_PCMCIA_GCRX_CXRESET;	/* active high */
    	reg |= __MY_PCMCIA_GCRX_CXOE;		/* active low  */
    
    
    	udelay(10000);
    
    	return (0);
    }
    #endif	/* CFG_CMD_PCMCIA */
    
    
    
    static int voltage_set(int slot, int vcc, int vpp)
    {
    	volatile immap_t	*immap;
    	volatile cpm8xx_t	*cp;
    	volatile pcmconf8xx_t	*pcmp;
    	u_long reg;
    
    	debug ("voltage_set: "	\
    		PCMCIA_BOARD_MSG	\
    		" Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
    		'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
    
    
    	if (!slot) /* Slot A is not configurable */
    		return 0;
    
    
    	immap = (immap_t *)CFG_IMMR;
    	pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
    	cp    = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
    
    	/*
    	 * Disable PCMCIA buffers (isolate the interface)
    	 * and assert RESET signal
    	 */
    	debug ("Disable PCMCIA buffers and assert RESET\n");
    
    	reg |=  __MY_PCMCIA_GCRX_CXRESET;	/* active high */
    	reg |=  __MY_PCMCIA_GCRX_CXOE;		/* active low  */
    
    	udelay(500);
    
    	debug ("PCMCIA power OFF\n");
    	/*
    	 * Configure Port B pins for
    	 * 3 Volts enable
    	 */
    	cp->cp_pbdir |=  KUP4K_PCMCIA_B_3V3;
    	cp->cp_pbpar &= ~KUP4K_PCMCIA_B_3V3;
    	/* remove all power */
    	cp->cp_pbdat |=  KUP4K_PCMCIA_B_3V3; /* active low */
    
    	switch(vcc) {
    	case  0: 		break;
    	case 33:
    		cp->cp_pbdat &= ~KUP4K_PCMCIA_B_3V3;
    		debug ("PCMCIA powered at 3.3V\n");
    		break;
    	case 50:
    		debug ("PCMCIA: 5Volt vcc not supported\n");
    		break;
    	default:
    		puts("PCMCIA: vcc not supported");
    		break;
    	}
    
    	/* Checking supported voltages */
    
    	debug ("PIPR: 0x%x --> %s\n",
    		pcmp->pcmc_pipr,
    
    		   (pcmp->pcmc_pipr & (0x80000000 >> (slot << 4)))
    
    			? "only 5 V --> NOT SUPPORTED"
    			: "can do 3.3V");
    
    
    	debug ("Enable PCMCIA buffers and stop RESET\n");
    
    	reg &= ~__MY_PCMCIA_GCRX_CXRESET;	/* active high */
    	reg &= ~__MY_PCMCIA_GCRX_CXOE;		/* active low  */
    
    	udelay(500);
    
    	debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
    		slot+'A');
    	return (0);
    }
    
    #endif	/* KUP4K */
    
    
    
    
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    
    /* ---------------------------------------------------------------------------- */
    /* End of Board Specific Stuff							*/
    /* ---------------------------------------------------------------------------- */
    
    
    /* ---------------------------------------------------------------------------- */
    /* MPC8xx Specific Stuff - should go to MPC8xx directory			*/
    /* ---------------------------------------------------------------------------- */
    
    /*
     * Search this table to see if the windowsize is
     * supported...
     */
    
    #define M8XX_SIZES_NO 32
    
    static const u_int m8xx_size_to_gray[M8XX_SIZES_NO] =
    { 0x00000001, 0x00000002, 0x00000008, 0x00000004,
      0x00000080, 0x00000040, 0x00000010, 0x00000020,
      0x00008000, 0x00004000, 0x00001000, 0x00002000,
      0x00000100, 0x00000200, 0x00000800, 0x00000400,
    
      0x0fffffff, 0xffffffff, 0xffffffff, 0xffffffff,
      0x01000000, 0x02000000, 0xffffffff, 0x04000000,
      0x00010000, 0x00020000, 0x00080000, 0x00040000,
      0x00800000, 0x00400000, 0x00100000, 0x00200000 };
    
    
    /* ---------------------------------------------------------------------------- */
    
    static u_int m8xx_get_graycode(u_int size)
    {
    	u_int k;
    
    	for (k = 0; k < M8XX_SIZES_NO; k++) {
    		if(m8xx_size_to_gray[k] == size)
    			break;
    	}
    
    	if((k == M8XX_SIZES_NO) || (m8xx_size_to_gray[k] == -1))
    		k = -1;
    
    	return k;
    }
    
    /* ------------------------------------------------------------------------- */
    
    #if 0
    static u_int m8xx_get_speed(u_int ns, u_int is_io)
    {
    	u_int reg, clocks, psst, psl, psht;
    
    	if(!ns) {
    
    		/*
    		 * We get called with IO maps setup to 0ns
    		 * if not specified by the user.
    		 * They should be 255ns.
    		 */
    
    		if(is_io)
    			ns = 255;
    		else
    			ns = 100;  /* fast memory if 0 */
    	}
    
    	/*
    	 * In PSST, PSL, PSHT fields we tell the controller
    	 * timing parameters in CLKOUT clock cycles.
    	 * CLKOUT is the same as GCLK2_50.
    	 */
    
    /* how we want to adjust the timing - in percent */
    
    #define ADJ 180 /* 80 % longer accesstime - to be sure */
    
    	clocks = ((M8XX_BUSFREQ / 1000) * ns) / 1000;
    	clocks = (clocks * ADJ) / (100*1000);
    
    	if(clocks >= PCMCIA_BMT_LIMIT) {
    		DEBUG(0, "Max access time limit reached\n");
    		clocks = PCMCIA_BMT_LIMIT-1;
    	}
    
    	psst = clocks / 7;          /* setup time */
    	psht = clocks / 7;          /* hold time */
    	psl  = (clocks * 5) / 7;    /* strobe length */
    
    	psst += clocks - (psst + psht + psl);
    
    	reg =  psst << 12;
    	reg |= psl  << 7;
    	reg |= psht << 16;
    
    	return reg;
    }
    #endif
    
    /* ------------------------------------------------------------------------- */
    
    #ifdef CONFIG_IDE_8xx_PCCARD
    static void print_funcid (int func)
    {
    	puts (indent);
    	switch (func) {
    	case CISTPL_FUNCID_MULTI:
    		puts (" Multi-Function");
    		break;
    	case CISTPL_FUNCID_MEMORY:
    		puts (" Memory");
    		break;
    	case CISTPL_FUNCID_SERIAL:
    		puts (" Serial Port");
    		break;
    	case CISTPL_FUNCID_PARALLEL:
    		puts (" Parallel Port");
    		break;
    	case CISTPL_FUNCID_FIXED:
    		puts (" Fixed Disk");
    		break;
    	case CISTPL_FUNCID_VIDEO:
    		puts (" Video Adapter");
    		break;
    	case CISTPL_FUNCID_NETWORK:
    		puts (" Network Adapter");
    		break;
    	case CISTPL_FUNCID_AIMS:
    		puts (" AIMS Card");
    		break;
    	case CISTPL_FUNCID_SCSI:
    		puts (" SCSI Adapter");
    		break;
    	default:
    		puts (" Unknown");
    		break;
    	}
    	puts (" Card\n");
    }
    #endif	/* CONFIG_IDE_8xx_PCCARD */
    
    /* ------------------------------------------------------------------------- */
    
    #ifdef CONFIG_IDE_8xx_PCCARD
    static void print_fixed (volatile uchar *p)
    {
    	if (p == NULL)
    		return;
    
    	puts(indent);
    
    	switch (*p) {
    	case CISTPL_FUNCE_IDE_IFACE:
    	    {   uchar iface = *(p+2);
    
    		puts ((iface == CISTPL_IDE_INTERFACE) ? " IDE" : " unknown");
    		puts (" interface ");
    		break;
    	    }
    	case CISTPL_FUNCE_IDE_MASTER:
    	case CISTPL_FUNCE_IDE_SLAVE:
    	    {   uchar f1 = *(p+2);
    		uchar f2 = *(p+4);
    
    		puts ((f1 & CISTPL_IDE_SILICON) ? " [silicon]" : " [rotating]");
    
    		if (f1 & CISTPL_IDE_UNIQUE)
    			puts (" [unique]");
    
    		puts ((f1 & CISTPL_IDE_DUAL) ? " [dual]" : " [single]");
    
    		if (f2 & CISTPL_IDE_HAS_SLEEP)
    			puts (" [sleep]");
    
    		if (f2 & CISTPL_IDE_HAS_STANDBY)
    			puts (" [standby]");
    
    		if (f2 & CISTPL_IDE_HAS_IDLE)
    			puts (" [idle]");
    
    		if (f2 & CISTPL_IDE_LOW_POWER)
    			puts (" [low power]");
    
    		if (f2 & CISTPL_IDE_REG_INHIBIT)
    			puts (" [reg inhibit]");
    
    		if (f2 & CISTPL_IDE_HAS_INDEX)
    			puts (" [index]");
    
    		if (f2 & CISTPL_IDE_IOIS16)
    			puts (" [IOis16]");
    
    		break;
    	    }
    	}
    	putc ('\n');
    }
    #endif	/* CONFIG_IDE_8xx_PCCARD */
    
    /* ------------------------------------------------------------------------- */
    
    #ifdef CONFIG_IDE_8xx_PCCARD
    
    #define MAX_IDENT_CHARS		64
    #define	MAX_IDENT_FIELDS	4
    
    static uchar *known_cards[] = {
    	"ARGOSY PnPIDE D5",
    	NULL
    };
    
    static int identify  (volatile uchar *p)
    {
    	uchar id_str[MAX_IDENT_CHARS];
    	uchar data;
    	uchar *t;
    	uchar **card;
    	int i, done;
    
    	if (p == NULL)
    		return (0);	/* Don't know */
    
    	t = id_str;
    	done =0;
    
    	for (i=0; i<=4 && !done; ++i, p+=2) {
    		while ((data = *p) != '\0') {
    			if (data == 0xFF) {
    				done = 1;
    				break;
    			}
    			*t++ = data;
    			if (t == &id_str[MAX_IDENT_CHARS-1]) {
    				done = 1;
    				break;
    			}
    			p += 2;
    		}
    		if (!done)
    			*t++ = ' ';
    	}
    	*t = '\0';
    	while (--t > id_str) {
    		if (*t == ' ')
    			*t = '\0';
    		else
    			break;
    	}
    	puts (id_str);
    	putc ('\n');
    
    	for (card=known_cards; *card; ++card) {
    		debug ("## Compare against \"%s\"\n", *card);
    		if (strcmp(*card, id_str) == 0) {	/* found! */
    			debug ("## CARD FOUND ##\n");
    			return (1);
    		}
    	}
    
    	return (0);	/* don't know */
    }
    #endif	/* CONFIG_IDE_8xx_PCCARD */
    
    /* ------------------------------------------------------------------------- */
    
    #endif /* CFG_CMD_PCMCIA || (CFG_CMD_IDE && CONFIG_IDE_8xx_PCCARD) */