uboot/board/kup/common/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 "KUP"
  18
  19#define KUP4K_PCMCIA_B_3V3 (0x00020000)
  20
  21int pcmcia_hardware_enable(int slot)
  22{
  23        volatile cpm8xx_t       *cp;
  24        volatile pcmconf8xx_t   *pcmp;
  25        volatile sysconf8xx_t   *sysp;
  26        uint reg, mask;
  27
  28        debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
  29
  30        udelay(10000);
  31
  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(2500);
  56
  57        /*
  58         * Configure Port B pins for
  59         * 3 Volts enable
  60         */
  61        if (slot) { /* Slot A is built-in */
  62                cp->cp_pbdir |=  KUP4K_PCMCIA_B_3V3;
  63                cp->cp_pbpar &= ~KUP4K_PCMCIA_B_3V3;
  64                /* remove all power */
  65                cp->cp_pbdat |=  KUP4K_PCMCIA_B_3V3; /* active low */
  66        }
  67        /*
  68         * Make sure there is a card in the slot, then configure the interface.
  69         */
  70        udelay(10000);
  71        debug ("[%d] %s: PIPR(%p)=0x%x\n",
  72               __LINE__,__FUNCTION__,
  73               &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
  74        if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
  75                printf ("   No Card found\n");
  76                return (1);
  77        }
  78
  79        /*
  80         * Power On.
  81         */
  82        printf("%s  Slot %c:", slot ? "" : "\n", 'A' + slot);
  83        mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
  84        reg  = pcmp->pcmc_pipr;
  85        debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
  86               reg,
  87               (reg&PCMCIA_VS1(slot))?"n":"ff",
  88               (reg&PCMCIA_VS2(slot))?"n":"ff");
  89        if ((reg & mask) == mask) {
  90                puts (" 5.0V card found: NOT SUPPORTED !!!\n");
  91        } else {
  92                if(slot)
  93                        cp->cp_pbdat &= ~KUP4K_PCMCIA_B_3V3;
  94                puts (" 3.3V card found: ");
  95        }
  96#if 0
  97        /*  VCC switch error flag, PCMCIA slot INPACK_ pin */
  98        cp->cp_pbdir &= ~(0x0020 | 0x0010);
  99        cp->cp_pbpar &= ~(0x0020 | 0x0010);
 100        udelay(500000);
 101#endif
 102        debug ("Enable PCMCIA buffers and stop RESET\n");
 103        reg  =  PCMCIA_PGCRX(slot);
 104        reg &= ~__MY_PCMCIA_GCRX_CXRESET;       /* active high */
 105        reg &= ~__MY_PCMCIA_GCRX_CXOE;          /* active low  */
 106        PCMCIA_PGCRX(slot) = reg;
 107
 108        udelay(250000); /* some cards need >150 ms to come up :-( */
 109
 110        debug ("# hardware_enable done\n");
 111
 112        return (0);
 113}
 114
 115
 116#if defined(CONFIG_CMD_PCMCIA)
 117int pcmcia_hardware_disable(int slot)
 118{
 119        volatile immap_t        *immap;
 120        volatile cpm8xx_t       *cp;
 121        volatile pcmconf8xx_t   *pcmp;
 122        u_long reg;
 123
 124        debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
 125
 126        immap = (immap_t *)CONFIG_SYS_IMMR;
 127        pcmp = (pcmconf8xx_t *)(&(((immap_t *)CONFIG_SYS_IMMR)->im_pcmcia));
 128        cp    = (cpm8xx_t *)(&(((immap_t *)CONFIG_SYS_IMMR)->im_cpm));
 129
 130        /* remove all power */
 131        if (slot)
 132                cp->cp_pbdat |= KUP4K_PCMCIA_B_3V3;
 133
 134        /* Configure PCMCIA General Control Register */
 135        debug ("Disable PCMCIA buffers and assert RESET\n");
 136        reg  = 0;
 137        reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
 138        reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
 139        PCMCIA_PGCRX(slot) = reg;
 140
 141        udelay(10000);
 142
 143        return (0);
 144}
 145#endif
 146
 147
 148int pcmcia_voltage_set(int slot, int vcc, int vpp)
 149{
 150        volatile cpm8xx_t       *cp;
 151        volatile pcmconf8xx_t   *pcmp;
 152        u_long reg;
 153
 154        debug ("voltage_set: "  \
 155                        PCMCIA_BOARD_MSG        \
 156                        " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
 157        'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
 158
 159        if (!slot) /* Slot A is not configurable */
 160                return 0;
 161
 162        pcmp = (pcmconf8xx_t *)(&(((immap_t *)CONFIG_SYS_IMMR)->im_pcmcia));
 163        cp    = (cpm8xx_t *)(&(((immap_t *)CONFIG_SYS_IMMR)->im_cpm));
 164
 165        /*
 166         * Disable PCMCIA buffers (isolate the interface)
 167         * and assert RESET signal
 168         */
 169        debug ("Disable PCMCIA buffers and assert RESET\n");
 170        reg  = PCMCIA_PGCRX(slot);
 171        reg |= __MY_PCMCIA_GCRX_CXRESET;        /* active high */
 172        reg |= __MY_PCMCIA_GCRX_CXOE;           /* active low  */
 173        PCMCIA_PGCRX(slot) = reg;
 174        udelay(500);
 175
 176        debug ("PCMCIA power OFF\n");
 177        /*
 178         * Configure Port B pins for
 179         * 3 Volts enable
 180         */
 181        cp->cp_pbdir |=  KUP4K_PCMCIA_B_3V3;
 182        cp->cp_pbpar &= ~KUP4K_PCMCIA_B_3V3;
 183        /* remove all power */
 184        cp->cp_pbdat |=  KUP4K_PCMCIA_B_3V3; /* active low */
 185
 186        switch(vcc) {
 187                case  0:                break;
 188                case 33:
 189                        cp->cp_pbdat &= ~KUP4K_PCMCIA_B_3V3;
 190                        debug ("PCMCIA powered at 3.3V\n");
 191                        break;
 192                case 50:
 193                        debug ("PCMCIA: 5Volt vcc not supported\n");
 194                        break;
 195                default:
 196                        puts("PCMCIA: vcc not supported");
 197                        break;
 198        }
 199        udelay(10000);
 200        /* Checking supported voltages */
 201
 202        debug ("PIPR: 0x%x --> %s\n",
 203               pcmp->pcmc_pipr,
 204               (pcmp->pcmc_pipr & (0x80000000 >> (slot << 4)))
 205                               ? "only 5 V --> NOT SUPPORTED"
 206        : "can do 3.3V");
 207
 208
 209        debug ("Enable PCMCIA buffers and stop RESET\n");
 210        reg  =  PCMCIA_PGCRX(slot);
 211        reg &= ~__MY_PCMCIA_GCRX_CXRESET;       /* active high */
 212        reg &= ~__MY_PCMCIA_GCRX_CXOE;          /* active low  */
 213        PCMCIA_PGCRX(slot) = reg;
 214        udelay(500);
 215
 216        debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
 217               slot+'A');
 218        return (0);
 219}
 220
 221#endif  /* CONFIG_PCMCIA */
 222