diff options
Diffstat (limited to 'common/cmd_pcmcia.c')
| -rw-r--r-- | common/cmd_pcmcia.c | 218 | 
1 files changed, 218 insertions, 0 deletions
| diff --git a/common/cmd_pcmcia.c b/common/cmd_pcmcia.c index ccf21a994..6d01e70fc 100644 --- a/common/cmd_pcmcia.c +++ b/common/cmd_pcmcia.c @@ -1975,6 +1975,224 @@ done:  #endif	/* R360MPI */ +/* ---------------------------------------------------------------------------- */ +/* KUP4K Board						*/ +/* ---------------------------------------------------------------------------- */ +#if defined(CONFIG_KUP4K) + +#define PCMCIA_BOARD_MSG "KUP4K" + +#define KUP4K_PCMCIA_B_3V3 (0x00020000) + +static int hardware_enable(int slot) +{ +	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 interrupts & DMA */ +	PCMCIA_PGCRX(_slot_) = 0; + +	/* +	 * Disable PCMCIA buffers (isolate the interface) +	 * and assert RESET signal +	 */ +	debug ("Disable PCMCIA buffers and assert RESET\n"); +	reg  =  PCMCIA_PGCRX(_slot_); +	reg |=  __MY_PCMCIA_GCRX_CXRESET;	/* active high */ +	reg |=  __MY_PCMCIA_GCRX_CXOE;		/* active low  */ +	PCMCIA_PGCRX(_slot_) = reg; +	udelay(500); + +	/* +	 * 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 */ + +	/* +	 * 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 & 0x00001800) { +		printf ("   No Card found\n"); +		return (1); +	} + +	/* +	 * Power On. +	 */ +	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 { +		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  =  PCMCIA_PGCRX(_slot_); +	reg &= ~__MY_PCMCIA_GCRX_CXRESET;	/* active high */ +	reg &= ~__MY_PCMCIA_GCRX_CXOE;		/* active low  */ +	PCMCIA_PGCRX(_slot_) = reg; + +	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 */ +	cp->cp_pbdat |= DDC4000_PCMCIA_B_3V3; + +	/* Configure PCMCIA General Control Register */ +	PCMCIA_PGCRX(_slot_) = 0; + +	debug ("Disable PCMCIA buffers and assert RESET\n"); +	reg  =  PCMCIA_PGCRX(_slot_); +	reg |= __MY_PCMCIA_GCRX_CXRESET;	/* active high */ +	reg |= __MY_PCMCIA_GCRX_CXOE;		/* active low  */ +	PCMCIA_PGCRX(_slot_) = reg; + +	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); + +	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  =  PCMCIA_PGCRX(_slot_); +	reg |=  __MY_PCMCIA_GCRX_CXRESET;	/* active high */ +	reg |=  __MY_PCMCIA_GCRX_CXOE;		/* active low  */ +	PCMCIA_PGCRX(_slot_) = reg; +	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 & 0x00008000)  +			? "only 5 V --> NOT SUPPORTED" +			: "can do 3.3V"); + + +	debug ("Enable PCMCIA buffers and stop RESET\n"); +	reg  =  PCMCIA_PGCRX(_slot_); +	reg &= ~__MY_PCMCIA_GCRX_CXRESET;	/* active high */ +	reg &= ~__MY_PCMCIA_GCRX_CXOE;		/* active low  */ +	PCMCIA_PGCRX(_slot_) = reg; +	udelay(500); + +	debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n", +		slot+'A'); +	return (0); +} + +#endif	/* KUP4K */ + + + +  /* ---------------------------------------------------------------------------- */  /* End of Board Specific Stuff							*/ |