|
|
|
@ -3,6 +3,7 @@ |
|
|
|
|
/* SC8xx Boards by SinoVee Microsystems */ |
|
|
|
|
/* -------------------------------------------------------------------- */ |
|
|
|
|
#include <common.h> |
|
|
|
|
#include <asm/io.h> |
|
|
|
|
#ifdef CONFIG_8xx |
|
|
|
|
#include <mpc8xx.h> |
|
|
|
|
#endif |
|
|
|
@ -31,75 +32,86 @@ |
|
|
|
|
|
|
|
|
|
#if defined(CONFIG_NSCU) |
|
|
|
|
|
|
|
|
|
#define power_config(slot) do {} while (0) |
|
|
|
|
#define power_off(slot) do {} while (0) |
|
|
|
|
#define power_on_5_0(slot) do {} while (0) |
|
|
|
|
#define power_on_3_3(slot) do {} while (0) |
|
|
|
|
static inline void power_config(int slot) {} |
|
|
|
|
static inline void power_off(int slot) {} |
|
|
|
|
static inline void power_on_5_0(int slot) {} |
|
|
|
|
static inline void power_on_3_3(int slot) {} |
|
|
|
|
|
|
|
|
|
#elif defined(CONFIG_VIRTLAB2) |
|
|
|
|
|
|
|
|
|
#define power_config(slot) do {} while (0) |
|
|
|
|
static inline void power_config(int slot) {} |
|
|
|
|
|
|
|
|
|
static inline void power_off(int slot) |
|
|
|
|
{ |
|
|
|
|
volatile unsigned char *powerctl = |
|
|
|
|
(volatile unsigned char *)PCMCIA_CTRL; |
|
|
|
|
*powerctl = 0; |
|
|
|
|
out_be32(PCMCIA_CTRL, 0); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static inline void power_on_5_0(int slot) |
|
|
|
|
{ |
|
|
|
|
volatile unsigned char *powerctl = |
|
|
|
|
(volatile unsigned char *)PCMCIA_CTRL; |
|
|
|
|
*powerctl = 2; /* Enable 5V Vccout */ |
|
|
|
|
/* Enable 5V Vccout */ |
|
|
|
|
out_be32(PCMCIA_CTRL, 2); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static inline void power_on_3_3(int slot) |
|
|
|
|
{ |
|
|
|
|
volatile unsigned char *powerctl = |
|
|
|
|
(volatile unsigned char *)PCMCIA_CTRL; |
|
|
|
|
*powerctl = 1; /* Enable 3.3V Vccout */ |
|
|
|
|
/* Enable 3.3V Vccout */ |
|
|
|
|
out_be32(PCMCIA_CTRL, 1); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#else |
|
|
|
|
|
|
|
|
|
static inline void power_config(int slot) |
|
|
|
|
{ |
|
|
|
|
volatile immap_t *immap = (immap_t *)CONFIG_SYS_IMMR; |
|
|
|
|
immap_t *immap = (immap_t *)CONFIG_SYS_IMMR; |
|
|
|
|
/*
|
|
|
|
|
* Configure Port C pins for |
|
|
|
|
* 5 Volts Enable and 3 Volts enable |
|
|
|
|
*/ |
|
|
|
|
immap->im_ioport.iop_pcpar &= ~(0x0002 | 0x0004); |
|
|
|
|
immap->im_ioport.iop_pcso &= ~(0x0002 | 0x0004); |
|
|
|
|
* Configure Port C pins for |
|
|
|
|
* 5 Volts Enable and 3 Volts enable |
|
|
|
|
*/ |
|
|
|
|
clrbits_be16(&immap->im_ioport.iop_pcpar, 0x0002 | 0x0004); |
|
|
|
|
clrbits_be16(&immap->im_ioport.iop_pcso, 0x0002 | 0x0004); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static inline void power_off(int slot) |
|
|
|
|
{ |
|
|
|
|
volatile immap_t *immap = (immap_t *)CONFIG_SYS_IMMR; |
|
|
|
|
immap->im_ioport.iop_pcdat &= ~(0x0002 | 0x0004); |
|
|
|
|
immap_t *immap = (immap_t *)CONFIG_SYS_IMMR; |
|
|
|
|
clrbits_be16(&immap->im_ioport.iop_pcdat, 0x0002 | 0x0004); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static inline void power_on_5_0(int slot) |
|
|
|
|
{ |
|
|
|
|
volatile immap_t *immap = (immap_t *)CONFIG_SYS_IMMR; |
|
|
|
|
immap->im_ioport.iop_pcdat |= 0x0004; |
|
|
|
|
immap->im_ioport.iop_pcdir |= (0x0002 | 0x0004); |
|
|
|
|
immap_t *immap = (immap_t *)CONFIG_SYS_IMMR; |
|
|
|
|
setbits_be16(&immap->im_ioport.iop_pcdat, 0x0004); |
|
|
|
|
setbits_be16(&immap->im_ioport.iop_pcdir, 0x0002 | 0x0004); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static inline void power_on_3_3(int slot) |
|
|
|
|
{ |
|
|
|
|
volatile immap_t *immap = (immap_t *)CONFIG_SYS_IMMR; |
|
|
|
|
immap->im_ioport.iop_pcdat |= 0x0002; |
|
|
|
|
immap->im_ioport.iop_pcdir |= (0x0002 | 0x0004); |
|
|
|
|
immap_t *immap = (immap_t *)CONFIG_SYS_IMMR; |
|
|
|
|
setbits_be16(&immap->im_ioport.iop_pcdat, 0x0002); |
|
|
|
|
setbits_be16(&immap->im_ioport.iop_pcdir, 0x0002 | 0x0004); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Function to retrieve the PIPR register, used for debuging purposes. |
|
|
|
|
*/ |
|
|
|
|
static inline uint32_t debug_get_pipr(void) |
|
|
|
|
{ |
|
|
|
|
uint32_t pipr = 0; |
|
|
|
|
#ifdef DEBUG |
|
|
|
|
immap_t *immap = (immap_t *)CONFIG_SYS_IMMR; |
|
|
|
|
pipr = in_be32(&immap->im_pcmcia.pcmc_pipr); |
|
|
|
|
#endif |
|
|
|
|
return pipr; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static inline int check_card_is_absent(int slot) |
|
|
|
|
{ |
|
|
|
|
volatile pcmconf8xx_t *pcmp = |
|
|
|
|
(pcmconf8xx_t *)(&(((immap_t *)CONFIG_SYS_IMMR)->im_pcmcia)); |
|
|
|
|
return pcmp->pcmc_pipr & (0x18000000 >> (slot << 4)); |
|
|
|
|
immap_t *immap = (immap_t *)CONFIG_SYS_IMMR; |
|
|
|
|
uint32_t pipr = in_be32(&immap->im_pcmcia.pcmc_pipr); |
|
|
|
|
return pipr & (0x18000000 >> (slot << 4)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#ifdef NSCU_OE_INV |
|
|
|
@ -110,31 +122,30 @@ static inline int check_card_is_absent(int slot) |
|
|
|
|
|
|
|
|
|
int pcmcia_hardware_enable(int slot) |
|
|
|
|
{ |
|
|
|
|
volatile pcmconf8xx_t *pcmp = |
|
|
|
|
(pcmconf8xx_t *)(&(((immap_t *)CONFIG_SYS_IMMR)->im_pcmcia)); |
|
|
|
|
volatile sysconf8xx_t *sysp = |
|
|
|
|
(sysconf8xx_t *)(&(((immap_t *)CONFIG_SYS_IMMR)->im_siu_conf)); |
|
|
|
|
immap_t *immap = (immap_t *)CONFIG_SYS_IMMR; |
|
|
|
|
uint reg, mask; |
|
|
|
|
|
|
|
|
|
debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot); |
|
|
|
|
debug("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot); |
|
|
|
|
|
|
|
|
|
udelay(10000); |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* 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 */ |
|
|
|
|
* Configure SIUMCR to enable PCMCIA port B |
|
|
|
|
* (VFLS[0:1] are not used for debugging, we connect FRZ# instead) |
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
/* clear interrupt state, and disable interrupts */ |
|
|
|
|
pcmp->pcmc_pscr = PCMCIA_MASK(slot); |
|
|
|
|
pcmp->pcmc_per &= ~PCMCIA_MASK(slot); |
|
|
|
|
/* Set DBGC to 00 */ |
|
|
|
|
clrbits_be32(&immap->im_siu_conf.sc_siumcr, SIUMCR_DBGC11); |
|
|
|
|
|
|
|
|
|
/* Clear interrupt state, and disable interrupts */ |
|
|
|
|
out_be32(&immap->im_pcmcia.pcmc_pscr, PCMCIA_MASK(slot)); |
|
|
|
|
clrbits_be32(&immap->im_pcmcia.pcmc_per, PCMCIA_MASK(slot)); |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Disable interrupts, DMA, and PCMCIA buffers |
|
|
|
|
* (isolate the interface) and assert RESET signal |
|
|
|
|
*/ |
|
|
|
|
debug ("Disable PCMCIA buffers and assert RESET\n"); |
|
|
|
|
* Disable interrupts, DMA, and PCMCIA buffers |
|
|
|
|
* (isolate the interface) and assert RESET signal |
|
|
|
|
*/ |
|
|
|
|
debug("Disable PCMCIA buffers and assert RESET\n"); |
|
|
|
|
reg = 0; |
|
|
|
|
reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */ |
|
|
|
|
reg |= NSCU_GCRX_CXOE; |
|
|
|
@ -149,8 +160,9 @@ int pcmcia_hardware_enable(int slot) |
|
|
|
|
* 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); |
|
|
|
|
reg = debug_get_pipr(); |
|
|
|
|
debug("[%d] %s: PIPR(%p)=0x%x\n", __LINE__, __FUNCTION__, |
|
|
|
|
&immap->im_pcmcia.pcmc_pipr, reg); |
|
|
|
|
|
|
|
|
|
if (check_card_is_absent(slot)) { |
|
|
|
|
printf (" No Card found\n"); |
|
|
|
@ -158,14 +170,14 @@ int pcmcia_hardware_enable(int slot) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Power On. |
|
|
|
|
*/ |
|
|
|
|
* Power On. |
|
|
|
|
*/ |
|
|
|
|
mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot); |
|
|
|
|
reg = pcmp->pcmc_pipr; |
|
|
|
|
reg = in_be32(&immap->im_pcmcia.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"); |
|
|
|
|
(reg & PCMCIA_VS1(slot)) ? "n" : "ff", |
|
|
|
|
(reg & PCMCIA_VS2(slot)) ? "n" : "ff"); |
|
|
|
|
|
|
|
|
|
if ((reg & mask) == mask) { |
|
|
|
|
power_on_5_0(slot); |
|
|
|
@ -183,7 +195,7 @@ int pcmcia_hardware_enable(int slot) |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
udelay(1000); |
|
|
|
|
debug ("Enable PCMCIA buffers and stop RESET\n"); |
|
|
|
|
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 */ |
|
|
|
@ -193,7 +205,7 @@ int pcmcia_hardware_enable(int slot) |
|
|
|
|
|
|
|
|
|
udelay(250000); /* some cards need >150 ms to come up :-( */ |
|
|
|
|
|
|
|
|
|
debug ("# hardware_enable done\n"); |
|
|
|
|
debug("# hardware_enable done\n"); |
|
|
|
|
|
|
|
|
|
return (0); |
|
|
|
|
} |
|
|
|
@ -204,13 +216,12 @@ int pcmcia_hardware_disable(int slot) |
|
|
|
|
{ |
|
|
|
|
u_long reg; |
|
|
|
|
|
|
|
|
|
debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot); |
|
|
|
|
|
|
|
|
|
debug("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot); |
|
|
|
|
|
|
|
|
|
/* remove all power */ |
|
|
|
|
power_off(slot); |
|
|
|
|
|
|
|
|
|
debug ("Disable PCMCIA buffers and assert RESET\n"); |
|
|
|
|
debug("Disable PCMCIA buffers and assert RESET\n"); |
|
|
|
|
reg = 0; |
|
|
|
|
reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */ |
|
|
|
|
reg |= NSCU_GCRX_CXOE; /* active low */ |
|
|
|
@ -227,20 +238,17 @@ int pcmcia_voltage_set(int slot, int vcc, int vpp) |
|
|
|
|
{ |
|
|
|
|
#ifndef CONFIG_NSCU |
|
|
|
|
u_long reg; |
|
|
|
|
# ifdef DEBUG |
|
|
|
|
volatile pcmconf8xx_t *pcmp = |
|
|
|
|
(pcmconf8xx_t *)(&(((immap_t *)CONFIG_SYS_IMMR)->im_pcmcia)); |
|
|
|
|
# endif |
|
|
|
|
uint32_t pipr = 0; |
|
|
|
|
|
|
|
|
|
debug ("voltage_set: " PCMCIA_BOARD_MSG |
|
|
|
|
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); |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Disable PCMCIA buffers (isolate the interface) |
|
|
|
|
* and assert RESET signal |
|
|
|
|
*/ |
|
|
|
|
debug ("Disable PCMCIA buffers and assert RESET\n"); |
|
|
|
|
* 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 */ |
|
|
|
@ -249,7 +257,7 @@ int pcmcia_voltage_set(int slot, int vcc, int vpp) |
|
|
|
|
PCMCIA_PGCRX(slot) = reg; |
|
|
|
|
udelay(500); |
|
|
|
|
|
|
|
|
|
debug ("PCMCIA power OFF\n"); |
|
|
|
|
debug("PCMCIA power OFF\n"); |
|
|
|
|
power_config(slot); |
|
|
|
|
power_off(slot); |
|
|
|
|
|
|
|
|
@ -261,9 +269,9 @@ int pcmcia_voltage_set(int slot, int vcc, int vpp) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* Checking supported voltages */ |
|
|
|
|
|
|
|
|
|
debug("PIPR: 0x%x --> %s\n", pcmp->pcmc_pipr, |
|
|
|
|
(pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V"); |
|
|
|
|
pipr = debug_get_pipr(); |
|
|
|
|
debug("PIPR: 0x%x --> %s\n", pipr, |
|
|
|
|
(pipr & 0x00008000) ? "only 5 V" : "can do 3.3V"); |
|
|
|
|
|
|
|
|
|
if (vcc) |
|
|
|
|
debug("PCMCIA powered at %sV\n", (vcc == 50) ? "5.0" : "3.3"); |
|
|
|
@ -282,7 +290,7 @@ done: |
|
|
|
|
|
|
|
|
|
debug("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n", slot+'A'); |
|
|
|
|
#endif /* CONFIG_NSCU */ |
|
|
|
|
return (0); |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#endif /* CONFIG_PCMCIA && (CONFIG_TQM8xxL || CONFIG_SVM_SC8xx) */ |
|
|
|
|