~pmdj/ubuntu/trusty/qemu/2.9+applesmc+fadtv3

« back to all changes in this revision

Viewing changes to roms/u-boot/drivers/pcmcia/tqm8xx_pcmcia.c

  • Committer: Phil Dennis-Jordan
  • Date: 2017-07-21 08:03:43 UTC
  • mfrom: (1.1.1)
  • Revision ID: phil@philjordan.eu-20170721080343-2yr2vdj7713czahv
New upstream release 2.9.0.

Show diffs side-by-side

added added

removed removed

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