uboot/board/r360mpi/pcmcia.c
<<
>>
Prefs
   1#include <common.h>
   2#include <mpc8xx.h>
   3#include <pcmcia.h>
   4
   5#undef  CONFIG_PCMCIA
   6
   7#if defined(CONFIG_CMD_PCMCIA)
   8#define CONFIG_PCMCIA
   9#endif
  10
  11#if defined(CONFIG_CMD_IDE) && defined(CONFIG_IDE_8xx_PCCARD)
  12#define CONFIG_PCMCIA
  13#endif
  14
  15#ifdef  CONFIG_PCMCIA
  16
  17#define PCMCIA_BOARD_MSG "R360MPI"
  18
  19int pcmcia_hardware_enable(int slot)
  20{
  21        volatile immap_t        *immap;
  22        volatile cpm8xx_t       *cp;
  23        volatile pcmconf8xx_t   *pcmp;
  24        volatile sysconf8xx_t   *sysp;
  25        uint reg, mask;
  26
  27        debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
  28
  29        udelay(10000);
  30
  31        immap = (immap_t *)CONFIG_SYS_IMMR;
  32        sysp  = (sysconf8xx_t *)(&(((immap_t *)CONFIG_SYS_IMMR)->im_siu_conf));
  33        pcmp  = (pcmconf8xx_t *)(&(((immap_t *)CONFIG_SYS_IMMR)->im_pcmcia));
  34        cp    = (cpm8xx_t *)(&(((immap_t *)CONFIG_SYS_IMMR)->im_cpm));
  35
  36        /*
  37        * Configure SIUMCR to enable PCMCIA port B
  38        * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
  39        */
  40        sysp->sc_siumcr &= ~SIUMCR_DBGC11;      /* set DBGC to 00 */
  41
  42        /* clear interrupt state, and disable interrupts */
  43        pcmp->pcmc_pscr =  PCMCIA_MASK(_slot_);
  44        pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
  45
  46        /*
  47        * Disable interrupts, DMA, and PCMCIA buffers
  48        * (isolate the interface) and assert RESET signal
  49        */
  50        debug ("Disable PCMCIA buffers and assert RESET\n");
  51        reg  = 0;
  52        reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
  53        reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
  54        PCMCIA_PGCRX(_slot_) = reg;
  55        udelay(500);
  56
  57        /*
  58        * Configure Ports A, B & C pins for
  59        * 5 Volts Enable and 3 Volts enable
  60        */
  61        immap->im_ioport.iop_pcpar &= ~(0x0400);
  62        immap->im_ioport.iop_pcso  &= ~(0x0400);/*
  63        immap->im_ioport.iop_pcdir |= 0x0400;*/
  64
  65        immap->im_ioport.iop_papar &= ~(0x0200);/*
  66        immap->im_ioport.iop_padir |= 0x0200;*/
  67#if 0
  68        immap->im_ioport.iop_pbpar &= ~(0xC000);
  69        immap->im_ioport.iop_pbdir &= ~(0xC000);
  70#endif
  71        /* remove all power */
  72
  73        immap->im_ioport.iop_pcdat |= 0x0400;
  74        immap->im_ioport.iop_padat |= 0x0200;
  75
  76        /*
  77        * Make sure there is a card in the slot, then configure the interface.
  78        */
  79        udelay(10000);
  80        debug ("[%d] %s: PIPR(%p)=0x%x\n",
  81               __LINE__,__FUNCTION__,
  82               &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
  83        if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
  84                printf ("   No Card found\n");
  85                return (1);
  86        }
  87
  88        /*
  89        * Power On.
  90        */
  91        mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
  92        reg  = pcmp->pcmc_pipr;
  93        debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
  94               reg,
  95               (reg&PCMCIA_VS1(slot))?"n":"ff",
  96               (reg&PCMCIA_VS2(slot))?"n":"ff");
  97        if ((reg & mask) == mask) {
  98                immap->im_ioport.iop_pcdat &= ~(0x4000);
  99                puts (" 5.0V card found: ");
 100        } else {
 101                immap->im_ioport.iop_padat &= ~(0x0002);
 102                puts (" 3.3V card found: ");
 103        }
 104        immap->im_ioport.iop_pcdir |= 0x0400;
 105        immap->im_ioport.iop_padir |= 0x0200;
 106#if 0
 107        /*  VCC switch error flag, PCMCIA slot INPACK_ pin */
 108        cp->cp_pbdir &= ~(0x0020 | 0x0010);
 109        cp->cp_pbpar &= ~(0x0020 | 0x0010);
 110        udelay(500000);
 111#endif
 112        debug ("Enable PCMCIA buffers and stop RESET\n");
 113        reg  =  PCMCIA_PGCRX(_slot_);
 114        reg &= ~__MY_PCMCIA_GCRX_CXRESET;       /* active high */
 115        reg &= ~__MY_PCMCIA_GCRX_CXOE;          /* active low  */
 116        PCMCIA_PGCRX(_slot_) = reg;
 117
 118        udelay(250000); /* some cards need >150 ms to come up :-( */
 119
 120        debug ("# hardware_enable done\n");
 121
 122        return (0);
 123}
 124
 125
 126#if defined(CONFIG_CMD_PCMCIA)
 127int pcmcia_hardware_disable(int slot)
 128{
 129        volatile immap_t        *immap;
 130        volatile pcmconf8xx_t   *pcmp;
 131        u_long reg;
 132
 133        debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
 134
 135        immap = (immap_t *)CONFIG_SYS_IMMR;
 136        pcmp = (pcmconf8xx_t *)(&(((immap_t *)CONFIG_SYS_IMMR)->im_pcmcia));
 137
 138        /* remove all power */
 139        immap->im_ioport.iop_pcdat |= 0x0400;
 140        immap->im_ioport.iop_padat |= 0x0200;
 141
 142        /* Configure PCMCIA General Control Register */
 143        debug ("Disable PCMCIA buffers and assert RESET\n");
 144        reg  = 0;
 145        reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
 146        reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
 147        PCMCIA_PGCRX(_slot_) = reg;
 148
 149        udelay(10000);
 150
 151        return (0);
 152}
 153#endif
 154
 155
 156int pcmcia_voltage_set(int slot, int vcc, int vpp)
 157{
 158        volatile immap_t        *immap;
 159        volatile pcmconf8xx_t   *pcmp;
 160        u_long reg;
 161
 162        debug ("voltage_set: "
 163                        PCMCIA_BOARD_MSG
 164                        " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
 165        'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
 166
 167        immap = (immap_t *)CONFIG_SYS_IMMR;
 168        pcmp = (pcmconf8xx_t *)(&(((immap_t *)CONFIG_SYS_IMMR)->im_pcmcia));
 169        /*
 170        * Disable PCMCIA buffers (isolate the interface)
 171        * and assert RESET signal
 172        */
 173        debug ("Disable PCMCIA buffers and assert RESET\n");
 174        reg  = PCMCIA_PGCRX(_slot_);
 175        reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
 176        reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
 177        PCMCIA_PGCRX(_slot_) = reg;
 178        udelay(500);
 179
 180        /*
 181        * Configure Ports A & C pins for
 182        * 5 Volts Enable and 3 Volts enable,
 183        * Turn off all power
 184        */
 185        debug ("PCMCIA power OFF\n");
 186        immap->im_ioport.iop_pcpar &= ~(0x0400);
 187        immap->im_ioport.iop_pcso  &= ~(0x0400);/*
 188        immap->im_ioport.iop_pcdir |= 0x0400;*/
 189
 190        immap->im_ioport.iop_papar &= ~(0x0200);/*
 191        immap->im_ioport.iop_padir |= 0x0200;*/
 192
 193        immap->im_ioport.iop_pcdat |= 0x0400;
 194        immap->im_ioport.iop_padat |= 0x0200;
 195
 196        reg = 0;
 197        switch(vcc) {
 198                case  0:                break;
 199                case 33: reg |= 0x0200; break;
 200                case 50: reg |= 0x0400; break;
 201                default:                goto done;
 202        }
 203
 204        /* Checking supported voltages */
 205
 206        debug ("PIPR: 0x%x --> %s\n",
 207               pcmp->pcmc_pipr,
 208               (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
 209
 210        if (reg & 0x0200)
 211                immap->im_ioport.iop_pcdat &= !reg;
 212        if (reg & 0x0400)
 213                immap->im_ioport.iop_padat &= !reg;
 214        immap->im_ioport.iop_pcdir |= 0x0200;
 215        immap->im_ioport.iop_padir |= 0x0400;
 216        if (reg) {
 217                debug ("PCMCIA powered at %sV\n",
 218                       (reg&0x0400) ? "5.0" : "3.3");
 219        } else {
 220                debug ("PCMCIA powered down\n");
 221        }
 222
 223done:
 224                        debug ("Enable PCMCIA buffers and stop RESET\n");
 225        reg  =  PCMCIA_PGCRX(_slot_);
 226        reg &= ~__MY_PCMCIA_GCRX_CXRESET;       /* active high */
 227        reg &= ~__MY_PCMCIA_GCRX_CXOE;          /* active low  */
 228        PCMCIA_PGCRX(_slot_) = reg;
 229        udelay(500);
 230
 231        debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
 232               slot+'A');
 233        return (0);
 234}
 235
 236#endif  /* CCONFIG_PCMCIA */
 237