uboot/drivers/pcmcia/tqm8xx_pcmcia.c
<<
>>
Prefs
   1/* -------------------------------------------------------------------- */
   2/* TQM8xxL Boards by TQ Components                                      */
   3/* SC8xx   Boards by SinoVee Microsystems                               */
   4/* -------------------------------------------------------------------- */
   5#include <common.h>
   6#ifdef CONFIG_8xx
   7#include <mpc8xx.h>
   8#endif
   9#include <pcmcia.h>
  10
  11#undef  CONFIG_PCMCIA
  12
  13#if defined(CONFIG_CMD_PCMCIA)
  14#define CONFIG_PCMCIA
  15#endif
  16
  17#if defined(CONFIG_CMD_IDE) && defined(CONFIG_IDE_8xx_PCCARD)
  18#define CONFIG_PCMCIA
  19#endif
  20
  21#if     defined(CONFIG_PCMCIA)  \
  22        && (defined(CONFIG_TQM8xxL) || defined(CONFIG_SVM_SC8xx))
  23
  24#if     defined(CONFIG_VIRTLAB2)
  25#define PCMCIA_BOARD_MSG        "Virtlab2"
  26#elif   defined(CONFIG_TQM8xxL)
  27#define PCMCIA_BOARD_MSG        "TQM8xxL"
  28#elif   defined(CONFIG_SVM_SC8xx)
  29#define PCMCIA_BOARD_MSG        "SC8xx"
  30#endif
  31
  32#if     defined(CONFIG_NSCU)
  33
  34#define power_config(slot)      do {} while (0)
  35#define power_off(slot)         do {} while (0)
  36#define power_on_5_0(slot)      do {} while (0)
  37#define power_on_3_3(slot)      do {} while (0)
  38
  39#elif   defined(CONFIG_HMI10)
  40
  41static inline void power_config(int slot)
  42{
  43        volatile immap_t *immap = (immap_t *)CONFIG_SYS_IMMR;
  44        /*
  45         * Configure Port B  pins for
  46         * 5 Volts Enable and 3 Volts enable
  47        */
  48        immap->im_cpm.cp_pbpar &= ~(0x00000300);
  49}
  50
  51static inline void power_off(int slot)
  52{
  53        volatile immap_t *immap = (immap_t *)CONFIG_SYS_IMMR;
  54        /* remove all power */
  55        immap->im_cpm.cp_pbdat |= 0x00000300;
  56}
  57
  58static inline void power_on_5_0(int slot)
  59{
  60        volatile immap_t *immap = (immap_t *)CONFIG_SYS_IMMR;
  61        immap->im_cpm.cp_pbdat &= ~(0x0000100);
  62        immap->im_cpm.cp_pbdir |= 0x00000300;
  63}
  64
  65static inline void power_on_3_3(int slot)
  66{
  67        volatile immap_t *immap = (immap_t *)CONFIG_SYS_IMMR;
  68        immap->im_cpm.cp_pbdat &= ~(0x0000200);
  69        immap->im_cpm.cp_pbdir |= 0x00000300;
  70}
  71
  72#elif   defined(CONFIG_VIRTLAB2)
  73
  74#define power_config(slot)      do {} while (0)
  75static inline void power_off(int slot)
  76{
  77        volatile unsigned char  *powerctl =
  78                        (volatile unsigned char *)PCMCIA_CTRL;
  79        *powerctl = 0;
  80}
  81
  82static inline void power_on_5_0(int slot)
  83{
  84        volatile unsigned char  *powerctl =
  85                        (volatile unsigned char *)PCMCIA_CTRL;
  86                        *powerctl = 2;  /* Enable 5V Vccout */
  87}
  88
  89static inline void power_on_3_3(int slot)
  90{
  91        volatile unsigned char  *powerctl =
  92                        (volatile unsigned char *)PCMCIA_CTRL;
  93                        *powerctl = 1;  /* Enable 3.3V Vccout */
  94}
  95
  96#else
  97
  98static inline void power_config(int slot)
  99{
 100        volatile immap_t *immap = (immap_t *)CONFIG_SYS_IMMR;
 101        /*
 102        * Configure Port C pins for
 103        * 5 Volts Enable and 3 Volts enable
 104        */
 105        immap->im_ioport.iop_pcpar &= ~(0x0002 | 0x0004);
 106        immap->im_ioport.iop_pcso  &= ~(0x0002 | 0x0004);
 107}
 108
 109static inline void power_off(int slot)
 110{
 111        volatile immap_t *immap = (immap_t *)CONFIG_SYS_IMMR;
 112        immap->im_ioport.iop_pcdat &= ~(0x0002 | 0x0004);
 113}
 114
 115static inline void power_on_5_0(int slot)
 116{
 117        volatile immap_t *immap = (immap_t *)CONFIG_SYS_IMMR;
 118        immap->im_ioport.iop_pcdat |= 0x0004;
 119        immap->im_ioport.iop_pcdir |= (0x0002 | 0x0004);
 120}
 121
 122static inline void power_on_3_3(int slot)
 123{
 124        volatile immap_t *immap = (immap_t *)CONFIG_SYS_IMMR;
 125        immap->im_ioport.iop_pcdat |= 0x0002;
 126        immap->im_ioport.iop_pcdir |= (0x0002 | 0x0004);
 127}
 128
 129#endif
 130
 131#ifdef  CONFIG_HMI10
 132static inline int check_card_is_absent(int slot)
 133{
 134        volatile pcmconf8xx_t *pcmp =
 135                (pcmconf8xx_t *)(&(((immap_t *)CONFIG_SYS_IMMR)->im_pcmcia));
 136        return pcmp->pcmc_pipr & (0x10000000 >> (slot << 4));
 137}
 138#else
 139static inline int check_card_is_absent(int slot)
 140{
 141        volatile pcmconf8xx_t *pcmp =
 142                (pcmconf8xx_t *)(&(((immap_t *)CONFIG_SYS_IMMR)->im_pcmcia));
 143        return pcmp->pcmc_pipr & (0x18000000 >> (slot << 4));
 144}
 145#endif
 146
 147#ifdef  NSCU_OE_INV
 148#define NSCU_GCRX_CXOE  0
 149#else
 150#define NSCU_GCRX_CXOE  __MY_PCMCIA_GCRX_CXOE
 151#endif
 152
 153int pcmcia_hardware_enable(int slot)
 154{
 155        volatile pcmconf8xx_t *pcmp =
 156                (pcmconf8xx_t *)(&(((immap_t *)CONFIG_SYS_IMMR)->im_pcmcia));
 157        volatile sysconf8xx_t *sysp =
 158                (sysconf8xx_t *)(&(((immap_t *)CONFIG_SYS_IMMR)->im_siu_conf));
 159        uint reg, mask;
 160
 161        debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
 162
 163        udelay(10000);
 164
 165        /*
 166        * Configure SIUMCR to enable PCMCIA port B
 167        * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
 168        */
 169        sysp->sc_siumcr &= ~SIUMCR_DBGC11;      /* set DBGC to 00 */
 170
 171        /* clear interrupt state, and disable interrupts */
 172        pcmp->pcmc_pscr =  PCMCIA_MASK(slot);
 173        pcmp->pcmc_per &= ~PCMCIA_MASK(slot);
 174
 175        /*
 176        * Disable interrupts, DMA, and PCMCIA buffers
 177        * (isolate the interface) and assert RESET signal
 178        */
 179        debug ("Disable PCMCIA buffers and assert RESET\n");
 180        reg  = 0;
 181        reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
 182        reg |= NSCU_GCRX_CXOE;
 183
 184        PCMCIA_PGCRX(slot) = reg;
 185        udelay(500);
 186
 187        power_config(slot);
 188        power_off(slot);
 189
 190        /*
 191         * Make sure there is a card in the slot, then configure the interface.
 192        */
 193        udelay(10000);
 194        debug ("[%d] %s: PIPR(%p)=0x%x\n", __LINE__,__FUNCTION__,
 195               &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
 196
 197        if (check_card_is_absent(slot)) {
 198                printf ("   No Card found\n");
 199                return (1);
 200        }
 201
 202        /*
 203        * Power On.
 204        */
 205        mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
 206        reg  = pcmp->pcmc_pipr;
 207        debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
 208               reg,
 209               (reg&PCMCIA_VS1(slot))?"n":"ff",
 210               (reg&PCMCIA_VS2(slot))?"n":"ff");
 211
 212        if ((reg & mask) == mask) {
 213                power_on_5_0(slot);
 214                puts (" 5.0V card found: ");
 215        } else {
 216                power_on_3_3(slot);
 217                puts (" 3.3V card found: ");
 218        }
 219
 220#if 0
 221        /*  VCC switch error flag, PCMCIA slot INPACK_ pin */
 222        cp->cp_pbdir &= ~(0x0020 | 0x0010);
 223        cp->cp_pbpar &= ~(0x0020 | 0x0010);
 224        udelay(500000);
 225#endif
 226
 227        udelay(1000);
 228        debug ("Enable PCMCIA buffers and stop RESET\n");
 229        reg  =  PCMCIA_PGCRX(slot);
 230        reg &= ~__MY_PCMCIA_GCRX_CXRESET;       /* active high */
 231        reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
 232        reg &= ~NSCU_GCRX_CXOE;
 233
 234        PCMCIA_PGCRX(slot) = reg;
 235
 236        udelay(250000); /* some cards need >150 ms to come up :-( */
 237
 238        debug ("# hardware_enable done\n");
 239
 240        return (0);
 241}
 242
 243
 244#if defined(CONFIG_CMD_PCMCIA)
 245int pcmcia_hardware_disable(int slot)
 246{
 247        u_long reg;
 248
 249        debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
 250
 251
 252        /* remove all power */
 253        power_off(slot);
 254
 255        debug ("Disable PCMCIA buffers and assert RESET\n");
 256        reg  = 0;
 257        reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
 258        reg |= NSCU_GCRX_CXOE;                  /* active low  */
 259
 260        PCMCIA_PGCRX(slot) = reg;
 261
 262        udelay(10000);
 263
 264        return (0);
 265}
 266#endif
 267
 268int pcmcia_voltage_set(int slot, int vcc, int vpp)
 269{
 270#ifndef CONFIG_NSCU
 271        u_long reg;
 272# ifdef DEBUG
 273        volatile pcmconf8xx_t *pcmp =
 274                (pcmconf8xx_t *)(&(((immap_t *)CONFIG_SYS_IMMR)->im_pcmcia));
 275# endif
 276
 277        debug ("voltage_set: " PCMCIA_BOARD_MSG
 278                " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
 279                'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
 280
 281        /*
 282        * Disable PCMCIA buffers (isolate the interface)
 283        * and assert RESET signal
 284        */
 285        debug ("Disable PCMCIA buffers and assert RESET\n");
 286        reg  = PCMCIA_PGCRX(slot);
 287        reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
 288        reg &= ~__MY_PCMCIA_GCRX_CXOE;          /* active low  */
 289        reg |= NSCU_GCRX_CXOE;                  /* active low  */
 290
 291        PCMCIA_PGCRX(slot) = reg;
 292        udelay(500);
 293
 294        debug ("PCMCIA power OFF\n");
 295        power_config(slot);
 296        power_off(slot);
 297
 298        switch(vcc) {
 299                case  0:                        break;
 300                case 33: power_on_3_3(slot);    break;
 301                case 50: power_on_5_0(slot);    break;
 302                default:                        goto done;
 303        }
 304
 305        /* Checking supported voltages */
 306
 307        debug("PIPR: 0x%x --> %s\n", pcmp->pcmc_pipr,
 308               (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
 309
 310        if (vcc)
 311                debug("PCMCIA powered at %sV\n", (vcc == 50) ? "5.0" : "3.3");
 312        else
 313                debug("PCMCIA powered down\n");
 314
 315done:
 316        debug("Enable PCMCIA buffers and stop RESET\n");
 317        reg  =  PCMCIA_PGCRX(slot);
 318        reg &= ~__MY_PCMCIA_GCRX_CXRESET;       /* active high */
 319        reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
 320        reg &= ~NSCU_GCRX_CXOE;                 /* active low  */
 321
 322        PCMCIA_PGCRX(slot) = reg;
 323        udelay(500);
 324
 325        debug("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n", slot+'A');
 326#endif  /* CONFIG_NSCU */
 327        return (0);
 328}
 329
 330#endif  /* CONFIG_PCMCIA && (CONFIG_TQM8xxL || CONFIG_SVM_SC8xx) */
 331