blob: 16d9d140945abe9fb97f1285aef1d247670ffa94 [file] [log] [blame]
wdenkc6097192002-11-03 00:24:07 +00001/*
Wolfgang Denk8cba0902006-05-12 16:15:46 +02002 * (C) Copyright 2000-2006
wdenkc6097192002-11-03 00:24:07 +00003 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
4 *
5 * See file CREDITS for list of people who contributed to this
6 * project.
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of
11 * the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21 * MA 02111-1307 USA
22 *
23 ********************************************************************
24 *
25 * Lots of code copied from:
26 *
27 * m8xx_pcmcia.c - Linux PCMCIA socket driver for the mpc8xx series.
28 * (C) 1999-2000 Magnus Damm <damm@bitsmart.com>
29 *
30 * "The ExCA standard specifies that socket controllers should provide
31 * two IO and five memory windows per socket, which can be independently
32 * configured and positioned in the host address space and mapped to
33 * arbitrary segments of card address space. " - David A Hinds. 1999
34 *
35 * This controller does _not_ meet the ExCA standard.
36 *
37 * m8xx pcmcia controller brief info:
38 * + 8 windows (attrib, mem, i/o)
39 * + up to two slots (SLOT_A and SLOT_B)
40 * + inputpins, outputpins, event and mask registers.
41 * - no offset register. sigh.
42 *
43 * Because of the lacking offset register we must map the whole card.
44 * We assign each memory window PCMCIA_MEM_WIN_SIZE address space.
45 * Make sure there is (PCMCIA_MEM_WIN_SIZE * PCMCIA_MEM_WIN_NO
46 * * PCMCIA_SOCKETS_NO) bytes at PCMCIA_MEM_WIN_BASE.
47 * The i/o windows are dynamically allocated at PCMCIA_IO_WIN_BASE.
48 * They are maximum 64KByte each...
49 */
50
51/* #define DEBUG 1 */
52
53/*
54 * PCMCIA support
55 */
56#include <common.h>
57#include <command.h>
58#include <config.h>
59#include <pcmcia.h>
wdenkb028f712003-12-07 21:39:28 +000060#if defined(CONFIG_8xx)
wdenkc6097192002-11-03 00:24:07 +000061#include <mpc8xx.h>
62#endif
63#if defined(CONFIG_LWMON)
64#include <i2c.h>
65#endif
wdenkdb01a2e2004-04-15 23:14:49 +000066#ifdef CONFIG_PXA_PCMCIA
67#include <asm/arch/pxa-regs.h>
68#endif
wdenkc6097192002-11-03 00:24:07 +000069
wdenke2ffd592004-12-31 09:32:47 +000070#include <asm/io.h>
71
wdenkc6097192002-11-03 00:24:07 +000072#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA) || \
73 ((CONFIG_COMMANDS & CFG_CMD_IDE) && defined(CONFIG_IDE_8xx_PCCARD))
74
75int pcmcia_on (void);
76
77#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
78static int pcmcia_off (void);
wdenk66fd3d12003-05-18 11:30:09 +000079#endif
80
81#ifdef CONFIG_I82365
82
83extern int i82365_init (void);
84extern void i82365_exit (void);
85
86#else /* ! CONFIG_I82365 */
87
88#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
wdenkc6097192002-11-03 00:24:07 +000089static int hardware_disable(int slot);
90#endif
91static int hardware_enable (int slot);
92static int voltage_set(int slot, int vcc, int vpp);
wdenkc6097192002-11-03 00:24:07 +000093
wdenkdb01a2e2004-04-15 23:14:49 +000094#if (! defined(CONFIG_I82365)) && (! defined(CONFIG_PXA_PCMCIA))
wdenkc6097192002-11-03 00:24:07 +000095static u_int m8xx_get_graycode(u_int size);
wdenk6e592382004-04-18 17:39:38 +000096#endif /* !CONFIG_I82365, !CONFIG_PXA_PCMCIA */
wdenkc6097192002-11-03 00:24:07 +000097#if 0
98static u_int m8xx_get_speed(u_int ns, u_int is_io);
99#endif
100
wdenk1f53a412002-12-04 23:39:58 +0000101/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +0000102
wdenkdb01a2e2004-04-15 23:14:49 +0000103#ifndef CONFIG_PXA_PCMCIA
104
wdenkc6097192002-11-03 00:24:07 +0000105/* look up table for pgcrx registers */
106
107static u_int *pcmcia_pgcrx[2] = {
108 &((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_pgcra,
109 &((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_pgcrb,
110};
wdenkc6097192002-11-03 00:24:07 +0000111#define PCMCIA_PGCRX(slot) (*pcmcia_pgcrx[slot])
112
wdenk6e592382004-04-18 17:39:38 +0000113#endif /* CONFIG_PXA_PCMCIA */
114
wdenk66fd3d12003-05-18 11:30:09 +0000115#endif /* CONFIG_I82365 */
116
wdenkdb01a2e2004-04-15 23:14:49 +0000117#if defined(CONFIG_IDE_8xx_PCCARD) || defined(CONFIG_PXA_PCMCIA)
wdenk66fd3d12003-05-18 11:30:09 +0000118static void print_funcid (int func);
119static void print_fixed (volatile uchar *p);
120static int identify (volatile uchar *p);
121static int check_ide_device (int slot);
wdenk6e592382004-04-18 17:39:38 +0000122#endif /* CONFIG_IDE_8xx_PCCARD, CONFIG_PXA_PCMCIA */
wdenkdb01a2e2004-04-15 23:14:49 +0000123
wdenkc6097192002-11-03 00:24:07 +0000124const char *indent = "\t ";
125
wdenk1f53a412002-12-04 23:39:58 +0000126/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +0000127
128#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
129
130int do_pinit (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
131{
132 int rcode = 0;
133
134 if (argc != 2) {
135 printf ("Usage: pinit {on | off}\n");
136 return 1;
137 }
138 if (strcmp(argv[1],"on") == 0) {
139 rcode = pcmcia_on ();
140 } else if (strcmp(argv[1],"off") == 0) {
141 rcode = pcmcia_off ();
142 } else {
143 printf ("Usage: pinit {on | off}\n");
144 return 1;
145 }
146
147 return rcode;
148}
149#endif /* CFG_CMD_PCMCIA */
150
wdenk1f53a412002-12-04 23:39:58 +0000151/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +0000152
wdenk66fd3d12003-05-18 11:30:09 +0000153#ifdef CONFIG_I82365
154int pcmcia_on (void)
155{
156 u_int rc;
157
158 debug ("Enable PCMCIA " PCMCIA_SLOT_MSG "\n");
159
160 rc = i82365_init();
161
wdenkdb01a2e2004-04-15 23:14:49 +0000162 if (rc == 0) {
wdenk66fd3d12003-05-18 11:30:09 +0000163 rc = check_ide_device(0);
164 }
165
166 return (rc);
167}
168#else
169
wdenkdb01a2e2004-04-15 23:14:49 +0000170#ifndef CONFIG_PXA_PCMCIA
171
wdenkc40b2952004-03-13 23:29:43 +0000172#ifdef CONFIG_HMI10
173# define HMI10_FRAM_TIMING (PCMCIA_SHT(2) | PCMCIA_SST(2) | PCMCIA_SL(4))
wdenka6cccae2004-02-06 21:48:22 +0000174#endif
dzue7df0292003-10-19 21:43:26 +0000175#if defined(CONFIG_LWMON) || defined(CONFIG_NSCU)
wdenkc6097192002-11-03 00:24:07 +0000176# define CFG_PCMCIA_TIMING (PCMCIA_SHT(9) | PCMCIA_SST(3) | PCMCIA_SL(12))
177#else
178# define CFG_PCMCIA_TIMING (PCMCIA_SHT(2) | PCMCIA_SST(4) | PCMCIA_SL(9))
179#endif
180
181int pcmcia_on (void)
182{
183 int i;
184 u_long reg, base;
185 pcmcia_win_t *win;
wdenkea909b72002-11-21 23:11:29 +0000186 u_int slotbit;
187 u_int rc, slot;
wdenkc6097192002-11-03 00:24:07 +0000188
189 debug ("Enable PCMCIA " PCMCIA_SLOT_MSG "\n");
190
191 /* intialize the fixed memory windows */
192 win = (pcmcia_win_t *)(&((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_pbr0);
193 base = CFG_PCMCIA_MEM_ADDR;
194
195 if((reg = m8xx_get_graycode(CFG_PCMCIA_MEM_SIZE)) == -1) {
196 printf ("Cannot set window size to 0x%08x\n",
197 CFG_PCMCIA_MEM_SIZE);
198 return (1);
199 }
200
wdenkea909b72002-11-21 23:11:29 +0000201 slotbit = PCMCIA_SLOT_x;
wdenkc6097192002-11-03 00:24:07 +0000202 for (i=0; i<PCMCIA_MEM_WIN_NO; ++i) {
203 win->br = base;
204
wdenkea909b72002-11-21 23:11:29 +0000205#if (PCMCIA_SOCKETS_NO == 2)
206 if (i == 4) /* Another slot starting from win 4 */
207 slotbit = (slotbit ? PCMCIA_PSLOT_A : PCMCIA_PSLOT_B);
208#endif
wdenkc6097192002-11-03 00:24:07 +0000209 switch (i) {
210#ifdef CONFIG_IDE_8xx_PCCARD
wdenkea909b72002-11-21 23:11:29 +0000211 case 4:
wdenkc40b2952004-03-13 23:29:43 +0000212#ifdef CONFIG_HMI10
wdenka6cccae2004-02-06 21:48:22 +0000213 { /* map FRAM area */
214 win->or = ( PCMCIA_BSIZE_256K
215 | PCMCIA_PPS_8
216 | PCMCIA_PRS_ATTR
217 | slotbit
218 | PCMCIA_PV
wdenkc40b2952004-03-13 23:29:43 +0000219 | HMI10_FRAM_TIMING );
wdenka6cccae2004-02-06 21:48:22 +0000220 break;
221 }
222#endif
wdenkc6097192002-11-03 00:24:07 +0000223 case 0: { /* map attribute memory */
224 win->or = ( PCMCIA_BSIZE_64M
225 | PCMCIA_PPS_8
226 | PCMCIA_PRS_ATTR
wdenkea909b72002-11-21 23:11:29 +0000227 | slotbit
wdenkc6097192002-11-03 00:24:07 +0000228 | PCMCIA_PV
229 | CFG_PCMCIA_TIMING );
230 break;
231 }
wdenkea909b72002-11-21 23:11:29 +0000232 case 5:
wdenkc6097192002-11-03 00:24:07 +0000233 case 1: { /* map I/O window for data reg */
234 win->or = ( PCMCIA_BSIZE_1K
235 | PCMCIA_PPS_16
236 | PCMCIA_PRS_IO
wdenkea909b72002-11-21 23:11:29 +0000237 | slotbit
wdenkc6097192002-11-03 00:24:07 +0000238 | PCMCIA_PV
239 | CFG_PCMCIA_TIMING );
240 break;
241 }
wdenkea909b72002-11-21 23:11:29 +0000242 case 6:
wdenk1f53a412002-12-04 23:39:58 +0000243 case 2: { /* map I/O window for cmd/ctrl reg block */
wdenkc6097192002-11-03 00:24:07 +0000244 win->or = ( PCMCIA_BSIZE_1K
245 | PCMCIA_PPS_8
246 | PCMCIA_PRS_IO
wdenkea909b72002-11-21 23:11:29 +0000247 | slotbit
wdenkc6097192002-11-03 00:24:07 +0000248 | PCMCIA_PV
249 | CFG_PCMCIA_TIMING );
250 break;
251 }
252#endif /* CONFIG_IDE_8xx_PCCARD */
wdenkc40b2952004-03-13 23:29:43 +0000253#ifdef CONFIG_HMI10
wdenk7cb22f92003-12-27 19:24:54 +0000254 case 3: { /* map I/O window for 4xUART data/ctrl */
wdenka522fa02004-01-04 22:51:12 +0000255 win->br += 0x40000;
wdenk7cb22f92003-12-27 19:24:54 +0000256 win->or = ( PCMCIA_BSIZE_256K
257 | PCMCIA_PPS_8
258 | PCMCIA_PRS_IO
259 | slotbit
260 | PCMCIA_PV
261 | CFG_PCMCIA_TIMING );
262 break;
263 }
wdenkc40b2952004-03-13 23:29:43 +0000264#endif /* CONFIG_HMI10 */
wdenkc6097192002-11-03 00:24:07 +0000265 default: /* set to not valid */
266 win->or = 0;
267 break;
268 }
269
270 debug ("MemWin %d: PBR 0x%08lX POR %08lX\n",
271 i, win->br, win->or);
272 base += CFG_PCMCIA_MEM_SIZE;
273 ++win;
274 }
275
wdenk1f53a412002-12-04 23:39:58 +0000276 for (i=0, rc=0, slot=_slot_; i<PCMCIA_SOCKETS_NO; i++, slot = !slot) {
wdenkea909b72002-11-21 23:11:29 +0000277 /* turn off voltage */
278 if ((rc = voltage_set(slot, 0, 0)))
279 continue;
wdenk1f53a412002-12-04 23:39:58 +0000280
wdenkea909b72002-11-21 23:11:29 +0000281 /* Enable external hardware */
282 if ((rc = hardware_enable(slot)))
283 continue;
wdenk1f53a412002-12-04 23:39:58 +0000284
wdenkc6097192002-11-03 00:24:07 +0000285#ifdef CONFIG_IDE_8xx_PCCARD
wdenkea909b72002-11-21 23:11:29 +0000286 if ((rc = check_ide_device(i)))
287 continue;
wdenkc6097192002-11-03 00:24:07 +0000288#endif
wdenkea909b72002-11-21 23:11:29 +0000289 }
290 return (rc);
wdenkc6097192002-11-03 00:24:07 +0000291}
wdenkdb01a2e2004-04-15 23:14:49 +0000292
wdenkc26e4542004-04-18 10:13:26 +0000293#endif /* CONFIG_PXA_PCMCIA */
wdenkdb01a2e2004-04-15 23:14:49 +0000294
wdenk66fd3d12003-05-18 11:30:09 +0000295#endif /* CONFIG_I82365 */
wdenkc6097192002-11-03 00:24:07 +0000296
wdenkdb01a2e2004-04-15 23:14:49 +0000297#ifdef CONFIG_PXA_PCMCIA
298
299static int hardware_enable (int slot)
300{
301 return 0; /* No hardware to enable */
302}
303
304static int hardware_disable(int slot)
305{
306 return 0; /* No hardware to disable */
307}
308
309static int voltage_set(int slot, int vcc, int vpp)
310{
311 return 0;
312}
313
314void msWait(unsigned msVal)
315{
316 udelay(msVal*1000);
317}
318
319int pcmcia_on (void)
320{
321 unsigned int reg_arr[] = {
322 0x48000028, CFG_MCMEM0_VAL,
323 0x4800002c, CFG_MCMEM1_VAL,
324 0x48000030, CFG_MCATT0_VAL,
325 0x48000034, CFG_MCATT1_VAL,
326 0x48000038, CFG_MCIO0_VAL,
327 0x4800003c, CFG_MCIO1_VAL,
328
329 0, 0
330 };
331 int i, rc;
332
333#ifdef CONFIG_EXADRON1
334 int cardDetect;
335 volatile unsigned int *v_pBCRReg =
336 (volatile unsigned int *) 0x08000000;
337#endif
338
339 debug ("%s\n", __FUNCTION__);
340
341 i = 0;
342 while (reg_arr[i])
343 *((volatile unsigned int *) reg_arr[i++]) |= reg_arr[i++];
344 udelay (1000);
345
346 debug ("%s: programmed mem controller \n", __FUNCTION__);
347
348#ifdef CONFIG_EXADRON1
349
350/*define useful BCR masks */
351#define BCR_CF_INIT_VAL 0x00007230
352#define BCR_CF_PWRON_BUSOFF_RESETOFF_VAL 0x00007231
353#define BCR_CF_PWRON_BUSOFF_RESETON_VAL 0x00007233
354#define BCR_CF_PWRON_BUSON_RESETON_VAL 0x00007213
355#define BCR_CF_PWRON_BUSON_RESETOFF_VAL 0x00007211
356
357 /* we see from the GPIO bit if the card is present */
358 cardDetect = !(GPLR0 & GPIO_bit (14));
359
360 if (cardDetect) {
361 printf ("No PCMCIA card found!\n");
362 }
363
364 /* reset the card via the BCR line */
365 *v_pBCRReg = (unsigned) BCR_CF_INIT_VAL;
366 msWait (500);
367
368 *v_pBCRReg = (unsigned) BCR_CF_PWRON_BUSOFF_RESETOFF_VAL;
369 msWait (500);
370
371 *v_pBCRReg = (unsigned) BCR_CF_PWRON_BUSOFF_RESETON_VAL;
372 msWait (500);
373
374 *v_pBCRReg = (unsigned) BCR_CF_PWRON_BUSON_RESETON_VAL;
375 msWait (500);
376
377 *v_pBCRReg = (unsigned) BCR_CF_PWRON_BUSON_RESETOFF_VAL;
378 msWait (1500);
379
380 /* enable address bus */
381 GPCR1 = 0x01;
382 /* and the first CF slot */
383 MECR = 0x00000002;
384
385#endif /* EXADRON 1 */
386
387 rc = check_ide_device (0); /* use just slot 0 */
388
389 return rc;
390}
391
392#endif /* CONFIG_PXA_PCMCIA */
393
wdenk1f53a412002-12-04 23:39:58 +0000394/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +0000395
396#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
397
wdenk66fd3d12003-05-18 11:30:09 +0000398#ifdef CONFIG_I82365
399static int pcmcia_off (void)
400{
401 printf ("Disable PCMCIA " PCMCIA_SLOT_MSG "\n");
402
403 i82365_exit();
404
405 return 0;
406}
407#else
wdenkdb01a2e2004-04-15 23:14:49 +0000408
409#ifndef CONFIG_PXA_PCMCIA
410
wdenkc6097192002-11-03 00:24:07 +0000411static int pcmcia_off (void)
412{
413 int i;
414 pcmcia_win_t *win;
415
416 printf ("Disable PCMCIA " PCMCIA_SLOT_MSG "\n");
417
418 /* clear interrupt state, and disable interrupts */
419 ((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_pscr = PCMCIA_MASK(_slot_);
420 ((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_per &= ~PCMCIA_MASK(_slot_);
421
422 /* turn off interrupt and disable CxOE */
423 PCMCIA_PGCRX(_slot_) = __MY_PCMCIA_GCRX_CXOE;
424
425 /* turn off memory windows */
426 win = (pcmcia_win_t *)(&((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_pbr0);
427
428 for (i=0; i<PCMCIA_MEM_WIN_NO; ++i) {
429 /* disable memory window */
430 win->or = 0;
431 ++win;
432 }
433
434 /* turn off voltage */
435 voltage_set(_slot_, 0, 0);
436
437 /* disable external hardware */
438 printf ("Shutdown and Poweroff " PCMCIA_SLOT_MSG "\n");
439 hardware_disable(_slot_);
440 return 0;
441}
wdenkdb01a2e2004-04-15 23:14:49 +0000442
443#endif /* CONFIG_PXA_PCMCIA */
444
wdenk66fd3d12003-05-18 11:30:09 +0000445#endif /* CONFIG_I82365 */
wdenkc6097192002-11-03 00:24:07 +0000446
wdenkdb01a2e2004-04-15 23:14:49 +0000447#ifdef CONFIG_PXA_PCMCIA
448static int pcmcia_off (void)
449{
450 return 0;
451}
452#endif
453
wdenkc6097192002-11-03 00:24:07 +0000454#endif /* CFG_CMD_PCMCIA */
455
wdenk1f53a412002-12-04 23:39:58 +0000456/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +0000457
wdenkdb01a2e2004-04-15 23:14:49 +0000458#if defined(CONFIG_IDE_8xx_PCCARD) || defined(CONFIG_PXA_PCMCIA)
wdenkc6097192002-11-03 00:24:07 +0000459
460#define MAX_TUPEL_SZ 512
461#define MAX_FEATURES 4
462
wdenk6069ff22003-02-28 00:49:47 +0000463int ide_devices_found;
wdenkea909b72002-11-21 23:11:29 +0000464static int check_ide_device (int slot)
wdenkc6097192002-11-03 00:24:07 +0000465{
466 volatile uchar *ident = NULL;
467 volatile uchar *feature_p[MAX_FEATURES];
wdenkea909b72002-11-21 23:11:29 +0000468 volatile uchar *p, *start, *addr;
wdenkc6097192002-11-03 00:24:07 +0000469 int n_features = 0;
470 uchar func_id = ~0;
471 uchar code, len;
472 ushort config_base = 0;
473 int found = 0;
474 int i;
475
wdenk1f53a412002-12-04 23:39:58 +0000476 addr = (volatile uchar *)(CFG_PCMCIA_MEM_ADDR +
477 CFG_PCMCIA_MEM_SIZE * (slot * 4));
wdenkd0fb80c2003-01-11 09:48:40 +0000478 debug ("PCMCIA MEM: %08lX\n", (ulong)addr);
wdenkc6097192002-11-03 00:24:07 +0000479
wdenkea909b72002-11-21 23:11:29 +0000480 start = p = (volatile uchar *) addr;
wdenkc6097192002-11-03 00:24:07 +0000481
482 while ((p - start) < MAX_TUPEL_SZ) {
483
484 code = *p; p += 2;
485
486 if (code == 0xFF) { /* End of chain */
487 break;
488 }
489
490 len = *p; p += 2;
491#if defined(DEBUG) && (DEBUG > 1)
492 { volatile uchar *q = p;
493 printf ("\nTuple code %02x length %d\n\tData:",
494 code, len);
495
496 for (i = 0; i < len; ++i) {
497 printf (" %02x", *q);
498 q+= 2;
499 }
500 }
501#endif /* DEBUG */
502 switch (code) {
503 case CISTPL_VERS_1:
504 ident = p + 4;
505 break;
506 case CISTPL_FUNCID:
507 /* Fix for broken SanDisk which may have 0x80 bit set */
508 func_id = *p & 0x7F;
509 break;
510 case CISTPL_FUNCE:
511 if (n_features < MAX_FEATURES)
512 feature_p[n_features++] = p;
513 break;
514 case CISTPL_CONFIG:
515 config_base = (*(p+6) << 8) + (*(p+4));
516 debug ("\n## Config_base = %04x ###\n", config_base);
517 default:
518 break;
519 }
520 p += 2 * len;
521 }
522
523 found = identify (ident);
524
525 if (func_id != ((uchar)~0)) {
526 print_funcid (func_id);
527
528 if (func_id == CISTPL_FUNCID_FIXED)
529 found = 1;
530 else
531 return (1); /* no disk drive */
532 }
533
534 for (i=0; i<n_features; ++i) {
535 print_fixed (feature_p[i]);
536 }
537
538 if (!found) {
539 printf ("unknown card type\n");
540 return (1);
541 }
542
wdenk6069ff22003-02-28 00:49:47 +0000543 ide_devices_found |= (1 << slot);
544
wdenke2ffd592004-12-31 09:32:47 +0000545#if CONFIG_CPC45
546#else
wdenkc6097192002-11-03 00:24:07 +0000547 /* set I/O area in config reg -> only valid for ARGOSY D5!!! */
wdenkea909b72002-11-21 23:11:29 +0000548 *((uchar *)(addr + config_base)) = 1;
wdenke2ffd592004-12-31 09:32:47 +0000549#endif
550#if 0
551 printf("\n## Config_base = %04x ###\n", config_base);
552 printf("Configuration Option Register: %02x @ %x\n", readb(addr + config_base), addr + config_base);
553 printf("Card Configuration and Status Register: %02x\n", readb(addr + config_base + 2));
554 printf("Pin Replacement Register Register: %02x\n", readb(addr + config_base + 4));
555 printf("Socket and Copy Register: %02x\n", readb(addr + config_base + 6));
556#endif
wdenkc6097192002-11-03 00:24:07 +0000557 return (0);
558}
559#endif /* CONFIG_IDE_8xx_PCCARD */
560
wdenk1f53a412002-12-04 23:39:58 +0000561/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +0000562
563
wdenk1f53a412002-12-04 23:39:58 +0000564/* -------------------------------------------------------------------- */
565/* board specific stuff: */
566/* voltage_set(), hardware_enable() and hardware_disable() */
567/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +0000568
wdenk1f53a412002-12-04 23:39:58 +0000569/* -------------------------------------------------------------------- */
570/* RPX Boards from Embedded Planet */
571/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +0000572
573#if defined(CONFIG_RPXCLASSIC) || defined(CONFIG_RPXLITE)
574
575/* The RPX boards seems to have it's bus monitor timeout set to 6*8 clocks.
576 * SYPCR is write once only, therefore must the slowest memory be faster
577 * than the bus monitor or we will get a machine check due to the bus timeout.
578 */
579
580#define PCMCIA_BOARD_MSG "RPX CLASSIC or RPX LITE"
581
582#undef PCMCIA_BMT_LIMIT
583#define PCMCIA_BMT_LIMIT (6*8)
584
585static int voltage_set(int slot, int vcc, int vpp)
586{
587 u_long reg = 0;
588
589 switch(vcc) {
590 case 0: break;
591 case 33: reg |= BCSR1_PCVCTL4; break;
592 case 50: reg |= BCSR1_PCVCTL5; break;
593 default: return 1;
594 }
595
596 switch(vpp) {
597 case 0: break;
598 case 33:
599 case 50:
600 if(vcc == vpp)
601 reg |= BCSR1_PCVCTL6;
602 else
603 return 1;
604 break;
605 case 120:
606 reg |= BCSR1_PCVCTL7;
607 default: return 1;
608 }
609
610 if(vcc == 120)
611 return 1;
612
613 /* first, turn off all power */
614
615 *((uint *)RPX_CSR_ADDR) &= ~(BCSR1_PCVCTL4 | BCSR1_PCVCTL5
616 | BCSR1_PCVCTL6 | BCSR1_PCVCTL7);
617
618 /* enable new powersettings */
619
620 *((uint *)RPX_CSR_ADDR) |= reg;
621
622 return 0;
623}
624
625#define socket_get(_slot_) PCMCIA_SOCKET_KEY_5V
626static int hardware_enable (int slot)
627{
628 return 0; /* No hardware to enable */
629}
630#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
631static int hardware_disable(int slot)
632{
633 return 0; /* No hardware to disable */
634}
635#endif /* CFG_CMD_PCMCIA */
636#endif /* CONFIG_RPXCLASSIC */
637
wdenk1f53a412002-12-04 23:39:58 +0000638/* -------------------------------------------------------------------- */
639/* (F)ADS Boards from Motorola */
640/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +0000641
642#if defined(CONFIG_ADS) || defined(CONFIG_FADS)
643
644#ifdef CONFIG_ADS
645#define PCMCIA_BOARD_MSG "ADS"
646#define PCMCIA_GLITCHY_CD /* My ADS board needs this */
647#else
648#define PCMCIA_BOARD_MSG "FADS"
649#endif
650
651static int voltage_set(int slot, int vcc, int vpp)
652{
653 u_long reg = 0;
654
655 switch(vpp) {
656 case 0: reg = 0; break;
657 case 50: reg = 1; break;
658 case 120: reg = 2; break;
659 default: return 1;
660 }
661
662 switch(vcc) {
663 case 0: reg = 0; break;
664#ifdef CONFIG_ADS
665 case 50: reg = BCSR1_PCCVCCON; break;
666#endif
667#ifdef CONFIG_FADS
668 case 33: reg = BCSR1_PCCVCC0 | BCSR1_PCCVCC1; break;
669 case 50: reg = BCSR1_PCCVCC1; break;
670#endif
671 default: return 1;
672 }
673
674 /* first, turn off all power */
675
676#ifdef CONFIG_ADS
677 *((uint *)BCSR1) |= BCSR1_PCCVCCON;
678#endif
679#ifdef CONFIG_FADS
680 *((uint *)BCSR1) &= ~(BCSR1_PCCVCC0 | BCSR1_PCCVCC1);
681#endif
682 *((uint *)BCSR1) &= ~BCSR1_PCCVPP_MASK;
683
684 /* enable new powersettings */
685
686#ifdef CONFIG_ADS
687 *((uint *)BCSR1) &= ~reg;
688#endif
689#ifdef CONFIG_FADS
690 *((uint *)BCSR1) |= reg;
691#endif
692
693 *((uint *)BCSR1) |= reg << 20;
694
695 return 0;
696}
697
698#define socket_get(_slot_) PCMCIA_SOCKET_KEY_5V
699
700static int hardware_enable(int slot)
701{
702 *((uint *)BCSR1) &= ~BCSR1_PCCEN;
703 return 0;
704}
705
706#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
707static int hardware_disable(int slot)
708{
709 *((uint *)BCSR1) &= ~BCSR1_PCCEN;
710 return 0;
711}
712#endif /* CFG_CMD_PCMCIA */
713
714#endif /* (F)ADS */
715
wdenk1f53a412002-12-04 23:39:58 +0000716/* -------------------------------------------------------------------- */
717/* TQM8xxL Boards by TQ Components */
wdenkdc7c9a12003-03-26 06:55:25 +0000718/* SC8xx Boards by SinoVee Microsystems */
wdenk1f53a412002-12-04 23:39:58 +0000719/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +0000720
Wolfgang Denk8cba0902006-05-12 16:15:46 +0200721#if (defined(CONFIG_TQM8xxL) || defined(CONFIG_SVM_SC8xx)) \
722 && !defined(CONFIG_VIRTLAB2)
wdenkdc7c9a12003-03-26 06:55:25 +0000723
wdenkc6097192002-11-03 00:24:07 +0000724#if defined(CONFIG_TQM8xxL)
wdenkc6097192002-11-03 00:24:07 +0000725#define PCMCIA_BOARD_MSG "TQM8xxL"
wdenkdc7c9a12003-03-26 06:55:25 +0000726#endif
727#if defined(CONFIG_SVM_SC8xx)
728#define PCMCIA_BOARD_MSG "SC8xx"
729#endif
wdenkc6097192002-11-03 00:24:07 +0000730
731static int hardware_enable(int slot)
732{
733 volatile immap_t *immap;
734 volatile cpm8xx_t *cp;
735 volatile pcmconf8xx_t *pcmp;
736 volatile sysconf8xx_t *sysp;
737 uint reg, mask;
738
739 debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
740
741 udelay(10000);
742
743 immap = (immap_t *)CFG_IMMR;
744 sysp = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
745 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
746 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
747
748 /*
749 * Configure SIUMCR to enable PCMCIA port B
750 * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
751 */
752 sysp->sc_siumcr &= ~SIUMCR_DBGC11; /* set DBGC to 00 */
753
754 /* clear interrupt state, and disable interrupts */
dzue7df0292003-10-19 21:43:26 +0000755 pcmp->pcmc_pscr = PCMCIA_MASK(slot);
756 pcmp->pcmc_per &= ~PCMCIA_MASK(slot);
wdenkc6097192002-11-03 00:24:07 +0000757
wdenkc6097192002-11-03 00:24:07 +0000758 /*
wdenk1f53a412002-12-04 23:39:58 +0000759 * Disable interrupts, DMA, and PCMCIA buffers
760 * (isolate the interface) and assert RESET signal
wdenkc6097192002-11-03 00:24:07 +0000761 */
762 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +0000763 reg = 0;
764 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
dzue7df0292003-10-19 21:43:26 +0000765#ifndef NSCU_OE_INV
wdenk1f53a412002-12-04 23:39:58 +0000766 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
dzue7df0292003-10-19 21:43:26 +0000767#endif
768 PCMCIA_PGCRX(slot) = reg;
wdenkc6097192002-11-03 00:24:07 +0000769 udelay(500);
770
wdenkc40b2952004-03-13 23:29:43 +0000771#ifndef CONFIG_HMI10
dzue7df0292003-10-19 21:43:26 +0000772#ifndef CONFIG_NSCU
wdenkc6097192002-11-03 00:24:07 +0000773 /*
774 * Configure Port C pins for
775 * 5 Volts Enable and 3 Volts enable
776 */
777 immap->im_ioport.iop_pcpar &= ~(0x0002 | 0x0004);
778 immap->im_ioport.iop_pcso &= ~(0x0002 | 0x0004);
779 /* remove all power */
780
781 immap->im_ioport.iop_pcdat &= ~(0x0002 | 0x0004);
dzue7df0292003-10-19 21:43:26 +0000782#endif
wdenkc40b2952004-03-13 23:29:43 +0000783#else /* CONFIG_HMI10 */
wdenka522fa02004-01-04 22:51:12 +0000784 /*
785 * Configure Port B pins for
786 * 5 Volts Enable and 3 Volts enable
787 */
788 immap->im_cpm.cp_pbpar &= ~(0x00000300);
789
790 /* remove all power */
791 immap->im_cpm.cp_pbdat |= 0x00000300;
wdenkc40b2952004-03-13 23:29:43 +0000792#endif /* CONFIG_HMI10 */
wdenkc6097192002-11-03 00:24:07 +0000793
794 /*
795 * Make sure there is a card in the slot, then configure the interface.
796 */
797 udelay(10000);
798 debug ("[%d] %s: PIPR(%p)=0x%x\n",
799 __LINE__,__FUNCTION__,
800 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
wdenkc40b2952004-03-13 23:29:43 +0000801#ifndef CONFIG_HMI10
wdenkea909b72002-11-21 23:11:29 +0000802 if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
wdenka522fa02004-01-04 22:51:12 +0000803#else
804 if (pcmp->pcmc_pipr & (0x10000000 >> (slot << 4))) {
wdenkc40b2952004-03-13 23:29:43 +0000805#endif /* CONFIG_HMI10 */
wdenkc6097192002-11-03 00:24:07 +0000806 printf (" No Card found\n");
807 return (1);
808 }
809
810 /*
811 * Power On.
812 */
813 mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
814 reg = pcmp->pcmc_pipr;
815 debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
816 reg,
817 (reg&PCMCIA_VS1(slot))?"n":"ff",
818 (reg&PCMCIA_VS2(slot))?"n":"ff");
dzue7df0292003-10-19 21:43:26 +0000819#ifndef CONFIG_NSCU
wdenkc6097192002-11-03 00:24:07 +0000820 if ((reg & mask) == mask) {
wdenkc40b2952004-03-13 23:29:43 +0000821#ifndef CONFIG_HMI10
wdenkc6097192002-11-03 00:24:07 +0000822 immap->im_ioport.iop_pcdat |= 0x0004;
wdenka522fa02004-01-04 22:51:12 +0000823#else
824 immap->im_cpm.cp_pbdat &= ~(0x0000100);
wdenkc40b2952004-03-13 23:29:43 +0000825#endif /* CONFIG_HMI10 */
wdenkc6097192002-11-03 00:24:07 +0000826 puts (" 5.0V card found: ");
827 } else {
wdenkc40b2952004-03-13 23:29:43 +0000828#ifndef CONFIG_HMI10
wdenkc6097192002-11-03 00:24:07 +0000829 immap->im_ioport.iop_pcdat |= 0x0002;
wdenka522fa02004-01-04 22:51:12 +0000830#else
831 immap->im_cpm.cp_pbdat &= ~(0x0000200);
wdenkc40b2952004-03-13 23:29:43 +0000832#endif /* CONFIG_HMI10 */
wdenkc6097192002-11-03 00:24:07 +0000833 puts (" 3.3V card found: ");
834 }
wdenkc40b2952004-03-13 23:29:43 +0000835#ifndef CONFIG_HMI10
wdenk1f53a412002-12-04 23:39:58 +0000836 immap->im_ioport.iop_pcdir |= (0x0002 | 0x0004);
dzue7df0292003-10-19 21:43:26 +0000837#else
wdenka522fa02004-01-04 22:51:12 +0000838 immap->im_cpm.cp_pbdir |= 0x00000300;
wdenkc40b2952004-03-13 23:29:43 +0000839#endif /* CONFIG_HMI10 */
wdenka522fa02004-01-04 22:51:12 +0000840#else
dzue7df0292003-10-19 21:43:26 +0000841 if ((reg & mask) == mask) {
842 puts (" 5.0V card found: ");
843 } else {
844 puts (" 3.3V card found: ");
845 }
846#endif
wdenkc6097192002-11-03 00:24:07 +0000847#if 0
848 /* VCC switch error flag, PCMCIA slot INPACK_ pin */
849 cp->cp_pbdir &= ~(0x0020 | 0x0010);
850 cp->cp_pbpar &= ~(0x0020 | 0x0010);
851 udelay(500000);
852#endif
853 udelay(1000);
854 debug ("Enable PCMCIA buffers and stop RESET\n");
dzue7df0292003-10-19 21:43:26 +0000855 reg = PCMCIA_PGCRX(slot);
wdenkc6097192002-11-03 00:24:07 +0000856 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
dzue7df0292003-10-19 21:43:26 +0000857#ifndef NSCU_OE_INV
wdenkc6097192002-11-03 00:24:07 +0000858 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
dzue7df0292003-10-19 21:43:26 +0000859#else
860 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
861#endif
862 PCMCIA_PGCRX(slot) = reg;
wdenkc6097192002-11-03 00:24:07 +0000863
864 udelay(250000); /* some cards need >150 ms to come up :-( */
865
866 debug ("# hardware_enable done\n");
867
868 return (0);
869}
870
871
wdenkc6097192002-11-03 00:24:07 +0000872#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
873static int hardware_disable(int slot)
874{
875 volatile immap_t *immap;
876 volatile pcmconf8xx_t *pcmp;
877 u_long reg;
878
879 debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
880
881 immap = (immap_t *)CFG_IMMR;
882 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
883
wdenkc40b2952004-03-13 23:29:43 +0000884#ifndef CONFIG_HMI10
dzue7df0292003-10-19 21:43:26 +0000885#ifndef CONFIG_NSCU
wdenkc6097192002-11-03 00:24:07 +0000886 /* remove all power */
887 immap->im_ioport.iop_pcdat &= ~(0x0002 | 0x0004);
dzue7df0292003-10-19 21:43:26 +0000888#endif
wdenkc40b2952004-03-13 23:29:43 +0000889#else /* CONFIG_HMI10 */
wdenka522fa02004-01-04 22:51:12 +0000890 immap->im_cpm.cp_pbdat |= 0x00000300;
wdenkc40b2952004-03-13 23:29:43 +0000891#endif /* CONFIG_HMI10 */
wdenkc6097192002-11-03 00:24:07 +0000892
wdenkc6097192002-11-03 00:24:07 +0000893 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +0000894 reg = 0;
wdenkc6097192002-11-03 00:24:07 +0000895 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
dzue7df0292003-10-19 21:43:26 +0000896#ifndef NSCU_OE_INV
wdenkc6097192002-11-03 00:24:07 +0000897 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
dzue7df0292003-10-19 21:43:26 +0000898#endif
899 PCMCIA_PGCRX(slot) = reg;
wdenkc6097192002-11-03 00:24:07 +0000900
901 udelay(10000);
902
903 return (0);
904}
905#endif /* CFG_CMD_PCMCIA */
906
dzue7df0292003-10-19 21:43:26 +0000907#ifdef CONFIG_NSCU
908static int voltage_set(int slot, int vcc, int vpp)
909{
910 return 0;
911}
912#else
wdenkc6097192002-11-03 00:24:07 +0000913static int voltage_set(int slot, int vcc, int vpp)
914{
915 volatile immap_t *immap;
916 volatile pcmconf8xx_t *pcmp;
917 u_long reg;
918
919 debug ("voltage_set: "
920 PCMCIA_BOARD_MSG
921 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
922 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
923
924 immap = (immap_t *)CFG_IMMR;
925 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
926 /*
927 * Disable PCMCIA buffers (isolate the interface)
928 * and assert RESET signal
929 */
930 debug ("Disable PCMCIA buffers and assert RESET\n");
dzue7df0292003-10-19 21:43:26 +0000931 reg = PCMCIA_PGCRX(slot);
wdenk1f53a412002-12-04 23:39:58 +0000932 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
dzue7df0292003-10-19 21:43:26 +0000933#ifndef NSCU_OE_INV
wdenk1f53a412002-12-04 23:39:58 +0000934 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
dzue7df0292003-10-19 21:43:26 +0000935#else
936 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
937#endif
938 PCMCIA_PGCRX(slot) = reg;
wdenkc6097192002-11-03 00:24:07 +0000939 udelay(500);
940
wdenkc40b2952004-03-13 23:29:43 +0000941#ifndef CONFIG_HMI10
wdenkc6097192002-11-03 00:24:07 +0000942 /*
943 * Configure Port C pins for
944 * 5 Volts Enable and 3 Volts enable,
945 * Turn off all power
946 */
947 debug ("PCMCIA power OFF\n");
948 immap->im_ioport.iop_pcpar &= ~(0x0002 | 0x0004);
949 immap->im_ioport.iop_pcso &= ~(0x0002 | 0x0004);
950 immap->im_ioport.iop_pcdat &= ~(0x0002 | 0x0004);
951
952 reg = 0;
953 switch(vcc) {
954 case 0: break;
955 case 33: reg |= 0x0002; break;
956 case 50: reg |= 0x0004; break;
957 default: goto done;
958 }
wdenkc40b2952004-03-13 23:29:43 +0000959#else /* CONFIG_HMI10 */
wdenka522fa02004-01-04 22:51:12 +0000960 /*
961 * Configure Port B pins for
962 * 5 Volts Enable and 3 Volts enable,
963 * Turn off all power
964 */
965 debug ("PCMCIA power OFF\n");
966 immap->im_cpm.cp_pbpar &= ~(0x00000300);
967 /* remove all power */
968
969 immap->im_cpm.cp_pbdat |= 0x00000300;
970
971 reg = 0;
972 switch(vcc) {
973 case 0: break;
974 case 33: reg |= 0x00000200; break;
975 case 50: reg |= 0x00000100; break;
976 default: goto done;
977}
wdenkc40b2952004-03-13 23:29:43 +0000978#endif /* CONFIG_HMI10 */
wdenkc6097192002-11-03 00:24:07 +0000979
980 /* Checking supported voltages */
981
982 debug ("PIPR: 0x%x --> %s\n",
983 pcmp->pcmc_pipr,
984 (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
985
wdenkc40b2952004-03-13 23:29:43 +0000986#ifndef CONFIG_HMI10
wdenkc6097192002-11-03 00:24:07 +0000987 immap->im_ioport.iop_pcdat |= reg;
wdenk1f53a412002-12-04 23:39:58 +0000988 immap->im_ioport.iop_pcdir |= (0x0002 | 0x0004);
wdenka522fa02004-01-04 22:51:12 +0000989#else
990 immap->im_cpm.cp_pbdat &= !reg;
991 immap->im_cpm.cp_pbdir |= 0x00000300;
wdenkc40b2952004-03-13 23:29:43 +0000992#endif /* CONFIG_HMI10 */
wdenkc6097192002-11-03 00:24:07 +0000993 if (reg) {
wdenkc40b2952004-03-13 23:29:43 +0000994#ifndef CONFIG_HMI10
wdenkc6097192002-11-03 00:24:07 +0000995 debug ("PCMCIA powered at %sV\n",
996 (reg&0x0004) ? "5.0" : "3.3");
wdenka522fa02004-01-04 22:51:12 +0000997#else
998 debug ("PCMCIA powered at %sV\n",
999 (reg&0x00000200) ? "5.0" : "3.3");
wdenkc40b2952004-03-13 23:29:43 +00001000#endif /* CONFIG_HMI10 */
wdenkc6097192002-11-03 00:24:07 +00001001 } else {
1002 debug ("PCMCIA powered down\n");
1003 }
1004
1005done:
1006 debug ("Enable PCMCIA buffers and stop RESET\n");
dzue7df0292003-10-19 21:43:26 +00001007 reg = PCMCIA_PGCRX(slot);
wdenkc6097192002-11-03 00:24:07 +00001008 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
dzue7df0292003-10-19 21:43:26 +00001009#ifndef NSCU_OE_INV
wdenkc6097192002-11-03 00:24:07 +00001010 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
dzue7df0292003-10-19 21:43:26 +00001011#else
1012 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
1013#endif
1014 PCMCIA_PGCRX(slot) = reg;
wdenkc6097192002-11-03 00:24:07 +00001015 udelay(500);
1016
1017 debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
1018 slot+'A');
1019 return (0);
1020}
dzue7df0292003-10-19 21:43:26 +00001021#endif
wdenkc6097192002-11-03 00:24:07 +00001022
1023#endif /* TQM8xxL */
1024
Wolfgang Denk8cba0902006-05-12 16:15:46 +02001025/* -------------------------------------------------------------------- */
1026/* Virtlab2 Board by TQ Components */
1027/* -------------------------------------------------------------------- */
1028
1029#if defined(CONFIG_VIRTLAB2)
1030#define PCMCIA_BOARD_MSG "Virtlab2"
1031
1032static int hardware_enable(int slot)
1033{
1034 volatile pcmconf8xx_t *pcmp =
1035 (pcmconf8xx_t *)&(((immap_t *)CFG_IMMR)->im_pcmcia);
1036 volatile unsigned char *powerctl =
1037 (volatile unsigned char *)PCMCIA_CTRL;
1038 unsigned int reg, mask;
1039
1040 debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1041
1042 udelay(10000);
1043
1044 /* clear interrupt state, and disable interrupts */
1045 pcmp->pcmc_pscr = PCMCIA_MASK(slot);
1046 pcmp->pcmc_per &= ~PCMCIA_MASK(slot);
1047
1048 /*
1049 * Disable interrupts, DMA, and PCMCIA buffers
1050 * (isolate the interface) and assert RESET signal
1051 */
1052 debug ("Disable PCMCIA buffers and assert RESET\n");
1053 reg = __MY_PCMCIA_GCRX_CXRESET; /* active high */
1054 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
1055
1056 PCMCIA_PGCRX(slot) = reg;
1057 udelay(500);
1058
1059 /* remove all power */
1060 *powerctl = 0;
1061
1062 /*
1063 * Make sure there is a card in the slot, then configure the interface.
1064 */
1065 udelay(10000);
1066 debug ("[%d] %s: PIPR(%p)=0x%x\n", __LINE__,__FUNCTION__,
1067 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
1068
1069 if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
1070 printf (" No Card found\n");
1071 return (1);
1072 }
1073
1074 /*
1075 * Power On.
1076 */
1077 mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
1078 reg = pcmp->pcmc_pipr;
1079 debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n", reg,
1080 (reg&PCMCIA_VS1(slot))?"n":"ff",
1081 (reg&PCMCIA_VS2(slot))?"n":"ff");
1082
1083 if ((reg & mask) == mask) {
1084 *powerctl = 2; /* Enable 5V Vccout */
1085 puts (" 5.0V card found: ");
1086 } else {
1087 *powerctl = 1; /* Enable 3.3 V Vccout */
1088 puts (" 3.3V card found: ");
1089 }
1090
1091 udelay(1000);
1092 debug ("Enable PCMCIA buffers and stop RESET\n");
1093 reg = PCMCIA_PGCRX(slot);
1094 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
1095 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
1096
1097 PCMCIA_PGCRX(slot) = reg;
1098
1099 udelay(250000); /* some cards need >150 ms to come up :-( */
1100
1101 debug ("# hardware_enable done\n");
1102
1103 return (0);
1104}
1105
1106#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
1107static int hardware_disable(int slot)
1108{
1109 volatile unsigned char *powerctl =
1110 (volatile unsigned char *)PCMCIA_CTRL;
1111 unsigned long reg;
1112
1113 debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1114
1115 /* remove all power */
1116 *powerctl = 0;
1117
1118 debug ("Disable PCMCIA buffers and assert RESET\n");
1119 reg = __MY_PCMCIA_GCRX_CXRESET; /* active high */
1120 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
1121
1122 PCMCIA_PGCRX(slot) = reg;
1123
1124 udelay(10000);
1125
1126 return (0);
1127}
1128#endif
1129
1130static int voltage_set(int slot, int vcc, int vpp)
1131{
1132 volatile pcmconf8xx_t *pcmp =
1133 (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1134 volatile unsigned char *powerctl =
1135 (volatile unsigned char *)PCMCIA_CTRL;
1136 unsigned long reg;
1137
1138 debug ("voltage_set: " PCMCIA_BOARD_MSG
1139 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
1140 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
1141
1142 /*
1143 * Disable PCMCIA buffers (isolate the interface)
1144 * and assert RESET signal
1145 */
1146 debug ("Disable PCMCIA buffers and assert RESET\n");
1147 reg = PCMCIA_PGCRX(slot);
1148 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1149 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
1150
1151 PCMCIA_PGCRX(slot) = reg;
1152 udelay(500);
1153
1154 /*
1155 * Configure pins for 5 Volts Enable and 3 Volts enable,
1156 * Turn off all power.
1157 */
1158 debug ("PCMCIA power OFF\n");
1159 reg = 0;
1160 switch(vcc) {
1161 case 0: break;
1162 case 33: reg = 0x0001; break;
1163 case 50: reg = 0x0002; break;
1164 default: goto done;
1165 }
1166
1167 /* Checking supported voltages */
1168
1169 debug ("PIPR: 0x%x --> %s\n", pcmp->pcmc_pipr,
1170 (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
1171
1172 *powerctl = reg;
1173
1174 if (reg) {
1175 debug ("PCMCIA powered at %sV\n", (reg&0x0004) ? "5.0" : "3.3");
1176 } else {
1177 debug ("PCMCIA powered down\n");
1178 }
1179
1180done:
1181 debug ("Enable PCMCIA buffers and stop RESET\n");
1182 reg = PCMCIA_PGCRX(slot);
1183 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
1184 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
1185
1186 PCMCIA_PGCRX(slot) = reg;
1187 udelay(500);
1188
1189 debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n", slot+'A');
1190 return (0);
1191}
1192#endif /* CONFIG_VIRTLAB2 */
wdenkc6097192002-11-03 00:24:07 +00001193
wdenk1f53a412002-12-04 23:39:58 +00001194/* -------------------------------------------------------------------- */
1195/* LWMON Board */
1196/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00001197
1198#if defined(CONFIG_LWMON)
1199
1200#define PCMCIA_BOARD_MSG "LWMON"
1201
1202/* #define's for MAX1604 Power Switch */
1203#define MAX1604_OP_SUS 0x80
1204#define MAX1604_VCCBON 0x40
1205#define MAX1604_VCC_35 0x20
1206#define MAX1604_VCCBHIZ 0x10
1207#define MAX1604_VPPBON 0x08
1208#define MAX1604_VPPBPBPGM 0x04
1209#define MAX1604_VPPBHIZ 0x02
1210/* reserved 0x01 */
1211
1212static int hardware_enable(int slot)
1213{
1214 volatile immap_t *immap;
1215 volatile cpm8xx_t *cp;
1216 volatile pcmconf8xx_t *pcmp;
1217 volatile sysconf8xx_t *sysp;
1218 uint reg, mask;
1219 uchar val;
1220
1221
1222 debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1223
1224 /* Switch on PCMCIA port in PIC register 0x60 */
1225 reg = pic_read (0x60);
1226 debug ("[%d] PIC read: reg_60 = 0x%02x\n", __LINE__, reg);
1227 reg &= ~0x10;
wdenk1f53a412002-12-04 23:39:58 +00001228 /* reg |= 0x08; Vpp not needed */
wdenkc6097192002-11-03 00:24:07 +00001229 pic_write (0x60, reg);
1230#ifdef DEBUG
1231 reg = pic_read (0x60);
1232 printf ("[%d] PIC read: reg_60 = 0x%02x\n", __LINE__, reg);
1233#endif
1234 udelay(10000);
1235
1236 immap = (immap_t *)CFG_IMMR;
1237 sysp = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
1238 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1239 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1240
1241 /*
1242 * Configure SIUMCR to enable PCMCIA port B
1243 * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
1244 */
1245 sysp->sc_siumcr &= ~SIUMCR_DBGC11; /* set DBGC to 00 */
1246
1247 /* clear interrupt state, and disable interrupts */
1248 pcmp->pcmc_pscr = PCMCIA_MASK(_slot_);
1249 pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
1250
wdenkc6097192002-11-03 00:24:07 +00001251 /*
wdenk1f53a412002-12-04 23:39:58 +00001252 * Disable interrupts, DMA, and PCMCIA buffers
1253 * (isolate the interface) and assert RESET signal
wdenkc6097192002-11-03 00:24:07 +00001254 */
1255 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00001256 reg = 0;
1257 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1258 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkc6097192002-11-03 00:24:07 +00001259 PCMCIA_PGCRX(_slot_) = reg;
1260 udelay(500);
1261
1262 /*
1263 * Make sure there is a card in the slot, then configure the interface.
1264 */
1265 udelay(10000);
1266 debug ("[%d] %s: PIPR(%p)=0x%x\n",
1267 __LINE__,__FUNCTION__,
1268 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
wdenkea909b72002-11-21 23:11:29 +00001269 if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
wdenkc6097192002-11-03 00:24:07 +00001270 printf (" No Card found\n");
1271 return (1);
1272 }
1273
1274 /*
1275 * Power On.
1276 */
1277 mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
1278 reg = pcmp->pcmc_pipr;
1279 debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
1280 reg,
1281 (reg&PCMCIA_VS1(slot))?"n":"ff",
1282 (reg&PCMCIA_VS2(slot))?"n":"ff");
1283 if ((reg & mask) == mask) {
1284 val = 0; /* VCCB3/5 = 0 ==> use Vx = 5.0 V */
1285 puts (" 5.0V card found: ");
1286 } else {
1287 val = MAX1604_VCC_35; /* VCCB3/5 = 1 ==> use Vy = 3.3 V */
1288 puts (" 3.3V card found: ");
1289 }
1290
1291 /* switch VCC on */
wdenk1f53a412002-12-04 23:39:58 +00001292 val |= MAX1604_OP_SUS | MAX1604_VCCBON;
wdenkc6097192002-11-03 00:24:07 +00001293 i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE);
1294 i2c_write (CFG_I2C_POWER_A_ADDR, 0, 0, &val, 1);
1295
1296 udelay(500000);
1297
1298 debug ("Enable PCMCIA buffers and stop RESET\n");
1299 reg = PCMCIA_PGCRX(_slot_);
1300 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
1301 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
1302 PCMCIA_PGCRX(_slot_) = reg;
1303
1304 udelay(250000); /* some cards need >150 ms to come up :-( */
1305
1306 debug ("# hardware_enable done\n");
1307
1308 return (0);
1309}
1310
1311
wdenkc6097192002-11-03 00:24:07 +00001312#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
1313static int hardware_disable(int slot)
1314{
1315 volatile immap_t *immap;
1316 volatile pcmconf8xx_t *pcmp;
1317 u_long reg;
1318 uchar val;
1319
1320 debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1321
1322 immap = (immap_t *)CFG_IMMR;
1323 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1324
1325 /* remove all power, put output in high impedance state */
1326 val = MAX1604_VCCBHIZ | MAX1604_VPPBHIZ;
1327 i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE);
1328 i2c_write (CFG_I2C_POWER_A_ADDR, 0, 0, &val, 1);
1329
1330 /* Configure PCMCIA General Control Register */
wdenkc6097192002-11-03 00:24:07 +00001331 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00001332 reg = 0;
wdenkc6097192002-11-03 00:24:07 +00001333 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1334 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
1335 PCMCIA_PGCRX(_slot_) = reg;
1336
1337 /* Switch off PCMCIA port in PIC register 0x60 */
1338 reg = pic_read (0x60);
1339 debug ("[%d] PIC read: reg_60 = 0x%02x\n", __LINE__, reg);
1340 reg |= 0x10;
1341 reg &= ~0x08;
1342 pic_write (0x60, reg);
1343#ifdef DEBUG
1344 reg = pic_read (0x60);
1345 printf ("[%d] PIC read: reg_60 = 0x%02x\n", __LINE__, reg);
1346#endif
1347 udelay(10000);
1348
1349 return (0);
1350}
1351#endif /* CFG_CMD_PCMCIA */
1352
1353
wdenkc6097192002-11-03 00:24:07 +00001354static int voltage_set(int slot, int vcc, int vpp)
1355{
1356 volatile immap_t *immap;
1357 volatile pcmconf8xx_t *pcmp;
1358 u_long reg;
1359 uchar val;
1360
1361 debug ("voltage_set: "
1362 PCMCIA_BOARD_MSG
1363 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
1364 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
1365
1366 immap = (immap_t *)CFG_IMMR;
1367 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1368 /*
1369 * Disable PCMCIA buffers (isolate the interface)
1370 * and assert RESET signal
1371 */
1372 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00001373 reg = PCMCIA_PGCRX(_slot_);
1374 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1375 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkc6097192002-11-03 00:24:07 +00001376 PCMCIA_PGCRX(_slot_) = reg;
1377 udelay(500);
1378
1379 /*
1380 * Turn off all power (switch to high impedance)
1381 */
1382 debug ("PCMCIA power OFF\n");
1383 val = MAX1604_VCCBHIZ | MAX1604_VPPBHIZ;
1384 i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE);
1385 i2c_write (CFG_I2C_POWER_A_ADDR, 0, 0, &val, 1);
1386
1387 val = 0;
1388 switch(vcc) {
1389 case 0: break;
1390 case 33: val = MAX1604_VCC_35; break;
1391 case 50: break;
1392 default: goto done;
1393 }
1394
1395 /* Checking supported voltages */
1396
1397 debug ("PIPR: 0x%x --> %s\n",
1398 pcmp->pcmc_pipr,
1399 (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
1400
1401 i2c_write (CFG_I2C_POWER_A_ADDR, 0, 0, &val, 1);
1402 if (val) {
1403 debug ("PCMCIA powered at %sV\n",
1404 (val & MAX1604_VCC_35) ? "3.3" : "5.0");
1405 } else {
1406 debug ("PCMCIA powered down\n");
1407 }
1408
1409done:
1410 debug ("Enable PCMCIA buffers and stop RESET\n");
1411 reg = PCMCIA_PGCRX(_slot_);
1412 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
1413 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
1414 PCMCIA_PGCRX(_slot_) = reg;
1415 udelay(500);
1416
1417 debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
1418 slot+'A');
1419 return (0);
1420}
1421
1422#endif /* LWMON */
1423
wdenk1f53a412002-12-04 23:39:58 +00001424/* -------------------------------------------------------------------- */
1425/* GTH board by Corelatus AB */
1426/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00001427#if defined(CONFIG_GTH)
1428
1429#define PCMCIA_BOARD_MSG "GTH COMPACT FLASH"
1430
wdenk1f53a412002-12-04 23:39:58 +00001431static int voltage_set (int slot, int vcc, int vpp)
1432{ /* Do nothing */
1433 return 0;
wdenkc6097192002-11-03 00:24:07 +00001434}
1435
1436static int hardware_enable (int slot)
1437{
wdenk1f53a412002-12-04 23:39:58 +00001438 volatile immap_t *immap;
1439 volatile cpm8xx_t *cp;
1440 volatile pcmconf8xx_t *pcmp;
1441 volatile sysconf8xx_t *sysp;
1442 uint reg, mask;
wdenkc6097192002-11-03 00:24:07 +00001443
wdenk1f53a412002-12-04 23:39:58 +00001444 debug ("hardware_enable: GTH Slot %c\n", 'A' + slot);
wdenkc6097192002-11-03 00:24:07 +00001445
wdenk1f53a412002-12-04 23:39:58 +00001446 immap = (immap_t *) CFG_IMMR;
1447 sysp = (sysconf8xx_t *) (&(((immap_t *) CFG_IMMR)->im_siu_conf));
1448 pcmp = (pcmconf8xx_t *) (&(((immap_t *) CFG_IMMR)->im_pcmcia));
1449 cp = (cpm8xx_t *) (&(((immap_t *) CFG_IMMR)->im_cpm));
wdenkc6097192002-11-03 00:24:07 +00001450
wdenk1f53a412002-12-04 23:39:58 +00001451 /* clear interrupt state, and disable interrupts */
1452 pcmp->pcmc_pscr = PCMCIA_MASK (_slot_);
1453 pcmp->pcmc_per &= ~PCMCIA_MASK (_slot_);
wdenkc6097192002-11-03 00:24:07 +00001454
wdenk1f53a412002-12-04 23:39:58 +00001455 /*
1456 * Disable interrupts, DMA, and PCMCIA buffers
1457 * (isolate the interface) and assert RESET signal
1458 */
1459 debug ("Disable PCMCIA buffers and assert RESET\n");
1460 reg = 0;
1461 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1462 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
1463 PCMCIA_PGCRX (_slot_) = reg;
1464 udelay (500);
wdenkc6097192002-11-03 00:24:07 +00001465
wdenk1f53a412002-12-04 23:39:58 +00001466 /*
1467 * Make sure there is a card in the slot,
1468 * then configure the interface.
1469 */
1470 udelay (10000);
1471 debug ("[%d] %s: PIPR(%p)=0x%x\n",
1472 __LINE__, __FUNCTION__,
1473 &(pcmp->pcmc_pipr), pcmp->pcmc_pipr);
1474 if (pcmp->pcmc_pipr & 0x98000000) {
1475 printf (" No Card found\n");
1476 return (1);
1477 }
wdenkc6097192002-11-03 00:24:07 +00001478
wdenk1f53a412002-12-04 23:39:58 +00001479 mask = PCMCIA_VS1 (slot) | PCMCIA_VS2 (slot);
1480 reg = pcmp->pcmc_pipr;
1481 debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
1482 reg,
1483 (reg & PCMCIA_VS1 (slot)) ? "n" : "ff",
1484 (reg & PCMCIA_VS2 (slot)) ? "n" : "ff");
wdenkc6097192002-11-03 00:24:07 +00001485
wdenk1f53a412002-12-04 23:39:58 +00001486 debug ("Enable PCMCIA buffers and stop RESET\n");
1487 reg = PCMCIA_PGCRX (_slot_);
1488 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
1489 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
1490 PCMCIA_PGCRX (_slot_) = reg;
wdenkc6097192002-11-03 00:24:07 +00001491
wdenk1f53a412002-12-04 23:39:58 +00001492 udelay (250000); /* some cards need >150 ms to come up :-( */
wdenkc6097192002-11-03 00:24:07 +00001493
wdenk1f53a412002-12-04 23:39:58 +00001494 debug ("# hardware_enable done\n");
wdenkc6097192002-11-03 00:24:07 +00001495
wdenk1f53a412002-12-04 23:39:58 +00001496 return 0;
wdenkc6097192002-11-03 00:24:07 +00001497}
1498#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
1499static int hardware_disable(int slot)
1500{
1501 return 0; /* No hardware to disable */
1502}
1503#endif /* CFG_CMD_PCMCIA */
1504#endif /* CONFIG_GTH */
1505
wdenk1f53a412002-12-04 23:39:58 +00001506/* -------------------------------------------------------------------- */
1507/* ICU862 Boards by Cambridge Broadband Ltd. */
1508/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00001509
1510#if defined(CONFIG_ICU862)
1511
1512#define PCMCIA_BOARD_MSG "ICU862"
1513
1514static void cfg_port_B (void);
1515
1516static int hardware_enable(int slot)
1517{
1518 volatile immap_t *immap;
1519 volatile cpm8xx_t *cp;
1520 volatile pcmconf8xx_t *pcmp;
1521 volatile sysconf8xx_t *sysp;
1522 uint reg, pipr, mask;
1523 int i;
1524
1525 debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1526
1527 udelay(10000);
1528
1529 immap = (immap_t *)CFG_IMMR;
1530 sysp = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
1531 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1532 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1533
1534 /* Configure Port B for TPS2205 PC-Card Power-Interface Switch */
1535 cfg_port_B ();
1536
1537 /*
1538 * Configure SIUMCR to enable PCMCIA port B
1539 * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
1540 */
1541 sysp->sc_siumcr &= ~SIUMCR_DBGC11; /* set DBGC to 00 */
1542
1543 /* clear interrupt state, and disable interrupts */
1544 pcmp->pcmc_pscr = PCMCIA_MASK(_slot_);
1545 pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
1546
wdenkc6097192002-11-03 00:24:07 +00001547 /*
wdenk1f53a412002-12-04 23:39:58 +00001548 * Disable interrupts, DMA, and PCMCIA buffers
1549 * (isolate the interface) and assert RESET signal
wdenkc6097192002-11-03 00:24:07 +00001550 */
1551 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00001552 reg = 0;
1553 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1554 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkc6097192002-11-03 00:24:07 +00001555 PCMCIA_PGCRX(_slot_) = reg;
1556 udelay(500);
1557
1558 /*
1559 * Make sure there is a card in the slot, then configure the interface.
1560 */
1561 udelay(10000);
1562 debug ("[%d] %s: PIPR(%p)=0x%x\n",
1563 __LINE__,__FUNCTION__,
1564 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
wdenkea909b72002-11-21 23:11:29 +00001565 if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
wdenkc6097192002-11-03 00:24:07 +00001566 printf (" No Card found\n");
1567 return (1);
1568 }
1569
1570 /*
1571 * Power On: Set VAVCC to 3.3V or 5V, set VAVPP to Hi-Z
1572 */
1573 mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
1574 pipr = pcmp->pcmc_pipr;
1575 debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
1576 pipr,
1577 (reg&PCMCIA_VS1(slot))?"n":"ff",
1578 (reg&PCMCIA_VS2(slot))?"n":"ff");
1579
1580 reg = cp->cp_pbdat;
1581 if ((pipr & mask) == mask) {
wdenk1f53a412002-12-04 23:39:58 +00001582 reg |= (TPS2205_VPP_PGM | TPS2205_VPP_VCC | /* VAVPP => Hi-Z */
1583 TPS2205_VCC3); /* 3V off */
wdenkc6097192002-11-03 00:24:07 +00001584 reg &= ~(TPS2205_VCC5); /* 5V on */
1585 puts (" 5.0V card found: ");
1586 } else {
wdenk1f53a412002-12-04 23:39:58 +00001587 reg |= (TPS2205_VPP_PGM | TPS2205_VPP_VCC | /* VAVPP => Hi-Z */
1588 TPS2205_VCC5); /* 5V off */
wdenkc6097192002-11-03 00:24:07 +00001589 reg &= ~(TPS2205_VCC3); /* 3V on */
1590 puts (" 3.3V card found: ");
1591 }
1592
1593 debug ("\nPB DAT: %08x -> 3.3V %s 5.0V %s VPP_PGM %s VPP_VCC %s\n",
1594 reg,
1595 (reg & TPS2205_VCC3) ? "off" : "on",
1596 (reg & TPS2205_VCC5) ? "off" : "on",
1597 (reg & TPS2205_VPP_PGM) ? "off" : "on",
1598 (reg & TPS2205_VPP_VCC) ? "off" : "on" );
1599
1600 cp->cp_pbdat = reg;
1601
1602 /* Wait 500 ms; use this to check for over-current */
1603 for (i=0; i<5000; ++i) {
1604 if ((cp->cp_pbdat & TPS2205_OC) == 0) {
1605 printf (" *** Overcurrent - Safety shutdown ***\n");
1606 cp->cp_pbdat &= ~(TPS2205_SHDN);
1607 return (1);
1608 }
1609 udelay (100);
1610 }
1611
1612 debug ("Enable PCMCIA buffers and stop RESET\n");
1613 reg = PCMCIA_PGCRX(_slot_);
1614 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
1615 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
1616 PCMCIA_PGCRX(_slot_) = reg;
1617
1618 udelay(250000); /* some cards need >150 ms to come up :-( */
1619
1620 debug ("# hardware_enable done\n");
1621
1622 return (0);
1623}
1624
1625
wdenkc6097192002-11-03 00:24:07 +00001626#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
1627static int hardware_disable(int slot)
1628{
1629 volatile immap_t *immap;
1630 volatile cpm8xx_t *cp;
1631 volatile pcmconf8xx_t *pcmp;
1632 u_long reg;
1633
1634 debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1635
1636 immap = (immap_t *)CFG_IMMR;
1637 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1638 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1639
1640 /* Shut down */
1641 cp->cp_pbdat &= ~(TPS2205_SHDN);
1642
1643 /* Configure PCMCIA General Control Register */
wdenkc6097192002-11-03 00:24:07 +00001644 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00001645 reg = 0;
wdenkc6097192002-11-03 00:24:07 +00001646 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1647 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
1648 PCMCIA_PGCRX(_slot_) = reg;
1649
1650 udelay(10000);
1651
1652 return (0);
1653}
1654#endif /* CFG_CMD_PCMCIA */
1655
1656
wdenkc6097192002-11-03 00:24:07 +00001657static int voltage_set(int slot, int vcc, int vpp)
1658{
1659 volatile immap_t *immap;
1660 volatile cpm8xx_t *cp;
1661 volatile pcmconf8xx_t *pcmp;
1662 u_long reg;
1663
1664 debug ("voltage_set: "
1665 PCMCIA_BOARD_MSG
1666 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
1667 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
1668
1669 immap = (immap_t *)CFG_IMMR;
1670 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1671 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1672 /*
1673 * Disable PCMCIA buffers (isolate the interface)
1674 * and assert RESET signal
1675 */
1676 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00001677 reg = PCMCIA_PGCRX(_slot_);
1678 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1679 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkc6097192002-11-03 00:24:07 +00001680 PCMCIA_PGCRX(_slot_) = reg;
1681 udelay(500);
1682
1683 /*
1684 * Configure Port C pins for
1685 * 5 Volts Enable and 3 Volts enable,
1686 * Turn all power pins to Hi-Z
1687 */
1688 debug ("PCMCIA power OFF\n");
1689 cfg_port_B (); /* Enables switch, but all in Hi-Z */
1690
1691 reg = cp->cp_pbdat;
1692
1693 switch(vcc) {
1694 case 0: break; /* Switch off */
1695 case 33: reg &= ~TPS2205_VCC3; break; /* Switch on 3.3V */
1696 case 50: reg &= ~TPS2205_VCC5; break; /* Switch on 5.0V */
1697 default: goto done;
1698 }
1699
1700 /* Checking supported voltages */
1701
1702 debug ("PIPR: 0x%x --> %s\n",
1703 pcmp->pcmc_pipr,
1704 (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
1705
1706 cp->cp_pbdat = reg;
1707
1708#ifdef DEBUG
1709 {
1710 char *s;
1711
1712 if ((reg & TPS2205_VCC3) == 0) {
1713 s = "at 3.3V";
1714 } else if ((reg & TPS2205_VCC5) == 0) {
1715 s = "at 5.0V";
1716 } else {
1717 s = "down";
1718 }
1719 printf ("PCMCIA powered %s\n", s);
1720 }
1721#endif
1722
1723done:
1724 debug ("Enable PCMCIA buffers and stop RESET\n");
1725 reg = PCMCIA_PGCRX(_slot_);
1726 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
1727 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
1728 PCMCIA_PGCRX(_slot_) = reg;
1729 udelay(500);
1730
1731 debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
1732 slot+'A');
1733 return (0);
1734}
1735
1736static void cfg_port_B (void)
1737{
1738 volatile immap_t *immap;
1739 volatile cpm8xx_t *cp;
1740 uint reg;
1741
1742 immap = (immap_t *)CFG_IMMR;
1743 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1744
1745 /*
1746 * Configure Port B for TPS2205 PC-Card Power-Interface Switch
1747 *
1748 * Switch off all voltages, assert shutdown
1749 */
1750 reg = cp->cp_pbdat;
wdenk1f53a412002-12-04 23:39:58 +00001751 reg |= (TPS2205_VPP_PGM | TPS2205_VPP_VCC | /* VAVPP => Hi-Z */
1752 TPS2205_VCC3 | TPS2205_VCC5 | /* VAVCC => Hi-Z */
1753 TPS2205_SHDN); /* enable switch */
wdenkc6097192002-11-03 00:24:07 +00001754 cp->cp_pbdat = reg;
1755
1756 cp->cp_pbpar &= ~(TPS2205_INPUTS | TPS2205_OUTPUTS);
1757
1758 reg = cp->cp_pbdir & ~(TPS2205_INPUTS);
1759 cp->cp_pbdir = reg | TPS2205_OUTPUTS;
1760
1761 debug ("Set Port B: PAR: %08x DIR: %08x DAT: %08x\n",
1762 cp->cp_pbpar, cp->cp_pbdir, cp->cp_pbdat);
1763}
1764
1765#endif /* ICU862 */
1766
1767
wdenk1f53a412002-12-04 23:39:58 +00001768/* -------------------------------------------------------------------- */
1769/* C2MON Boards by TTTech Computertechnik AG */
1770/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00001771
1772#if defined(CONFIG_C2MON)
1773
1774#define PCMCIA_BOARD_MSG "C2MON"
1775
1776static void cfg_ports (void);
1777
1778static int hardware_enable(int slot)
1779{
1780 volatile immap_t *immap;
1781 volatile cpm8xx_t *cp;
1782 volatile pcmconf8xx_t *pcmp;
1783 volatile sysconf8xx_t *sysp;
1784 uint reg, pipr, mask;
1785 ushort sreg;
1786 int i;
1787
1788 debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1789
1790 udelay(10000);
1791
1792 immap = (immap_t *)CFG_IMMR;
1793 sysp = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
1794 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1795 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1796
1797 /* Configure Ports for TPS2211A PC-Card Power-Interface Switch */
1798 cfg_ports ();
1799
1800 /*
1801 * Configure SIUMCR to enable PCMCIA port B
1802 * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
1803 */
1804 sysp->sc_siumcr &= ~SIUMCR_DBGC11; /* set DBGC to 00 */
1805
1806 /* clear interrupt state, and disable interrupts */
1807 pcmp->pcmc_pscr = PCMCIA_MASK(_slot_);
1808 pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
1809
wdenkc6097192002-11-03 00:24:07 +00001810 /*
wdenk1f53a412002-12-04 23:39:58 +00001811 * Disable interrupts, DMA, and PCMCIA buffers
1812 * (isolate the interface) and assert RESET signal
wdenkc6097192002-11-03 00:24:07 +00001813 */
1814 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00001815 reg = 0;
1816 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1817 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkc6097192002-11-03 00:24:07 +00001818 PCMCIA_PGCRX(_slot_) = reg;
1819 udelay(500);
1820
1821 /*
1822 * Make sure there is a card in the slot, then configure the interface.
1823 */
1824 udelay(10000);
1825 debug ("[%d] %s: PIPR(%p)=0x%x\n",
1826 __LINE__,__FUNCTION__,
1827 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
wdenkea909b72002-11-21 23:11:29 +00001828 if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
wdenkc6097192002-11-03 00:24:07 +00001829 printf (" No Card found\n");
1830 return (1);
1831 }
1832
1833 /*
1834 * Power On: Set VAVCC to 3.3V or 5V, set VAVPP to Hi-Z
1835 */
1836 mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
1837 pipr = pcmp->pcmc_pipr;
1838 debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
1839 pipr,
1840 (reg&PCMCIA_VS1(slot))?"n":"ff",
1841 (reg&PCMCIA_VS2(slot))?"n":"ff");
1842
1843 sreg = immap->im_ioport.iop_pcdat;
1844 if ((pipr & mask) == mask) {
1845 sreg |= (TPS2211_VPPD0 | TPS2211_VPPD1 | /* VAVPP => Hi-Z */
1846 TPS2211_VCCD1); /* 5V on */
1847 sreg &= ~(TPS2211_VCCD0); /* 3V off */
1848 puts (" 5.0V card found: ");
1849 } else {
1850 sreg |= (TPS2211_VPPD0 | TPS2211_VPPD1 | /* VAVPP => Hi-Z */
1851 TPS2211_VCCD0); /* 3V on */
1852 sreg &= ~(TPS2211_VCCD1); /* 5V off */
1853 puts (" 3.3V card found: ");
1854 }
1855
1856 debug ("\nPC DAT: %04x -> 3.3V %s 5.0V %s\n",
1857 sreg,
1858 ( (sreg & TPS2211_VCCD0) && !(sreg & TPS2211_VCCD1)) ? "on" : "off",
1859 (!(sreg & TPS2211_VCCD0) && (sreg & TPS2211_VCCD1)) ? "on" : "off"
1860 );
1861
1862 immap->im_ioport.iop_pcdat = sreg;
1863
1864 /* Wait 500 ms; use this to check for over-current */
1865 for (i=0; i<5000; ++i) {
1866 if ((cp->cp_pbdat & TPS2211_OC) == 0) {
1867 printf (" *** Overcurrent - Safety shutdown ***\n");
1868 immap->im_ioport.iop_pcdat &= ~(TPS2211_VCCD0|TPS2211_VCCD1);
1869 return (1);
1870 }
1871 udelay (100);
1872 }
1873
1874 debug ("Enable PCMCIA buffers and stop RESET\n");
1875 reg = PCMCIA_PGCRX(_slot_);
1876 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
1877 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
1878 PCMCIA_PGCRX(_slot_) = reg;
1879
1880 udelay(250000); /* some cards need >150 ms to come up :-( */
1881
1882 debug ("# hardware_enable done\n");
1883
1884 return (0);
1885}
1886
1887
wdenkc6097192002-11-03 00:24:07 +00001888#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
1889static int hardware_disable(int slot)
1890{
1891 volatile immap_t *immap;
1892 volatile cpm8xx_t *cp;
1893 volatile pcmconf8xx_t *pcmp;
1894 u_long reg;
1895
1896 debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1897
1898 immap = (immap_t *)CFG_IMMR;
1899 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1900
1901 /* Configure PCMCIA General Control Register */
wdenkc6097192002-11-03 00:24:07 +00001902 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00001903 reg = 0;
wdenkc6097192002-11-03 00:24:07 +00001904 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1905 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
1906 PCMCIA_PGCRX(_slot_) = reg;
1907
1908 /* ALl voltages off / Hi-Z */
1909 immap->im_ioport.iop_pcdat |= (TPS2211_VPPD0 | TPS2211_VPPD1 |
1910 TPS2211_VCCD0 | TPS2211_VCCD1 );
1911
1912 udelay(10000);
1913
1914 return (0);
1915}
1916#endif /* CFG_CMD_PCMCIA */
1917
1918
wdenkc6097192002-11-03 00:24:07 +00001919static int voltage_set(int slot, int vcc, int vpp)
1920{
1921 volatile immap_t *immap;
1922 volatile cpm8xx_t *cp;
1923 volatile pcmconf8xx_t *pcmp;
1924 u_long reg;
1925 ushort sreg;
1926
1927 debug ("voltage_set: "
1928 PCMCIA_BOARD_MSG
1929 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
1930 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
1931
1932 immap = (immap_t *)CFG_IMMR;
1933 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1934 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1935 /*
1936 * Disable PCMCIA buffers (isolate the interface)
1937 * and assert RESET signal
1938 */
1939 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00001940 reg = PCMCIA_PGCRX(_slot_);
1941 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1942 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkc6097192002-11-03 00:24:07 +00001943 PCMCIA_PGCRX(_slot_) = reg;
1944 udelay(500);
1945
1946 /*
1947 * Configure Port C pins for
1948 * 5 Volts Enable and 3 Volts enable,
1949 * Turn all power pins to Hi-Z
1950 */
1951 debug ("PCMCIA power OFF\n");
1952 cfg_ports (); /* Enables switch, but all in Hi-Z */
1953
1954 sreg = immap->im_ioport.iop_pcdat;
1955 sreg |= TPS2211_VPPD0 | TPS2211_VPPD1; /* VAVPP always Hi-Z */
1956
1957 switch(vcc) {
1958 case 0: break; /* Switch off */
1959 case 33: sreg |= TPS2211_VCCD0; /* Switch on 3.3V */
1960 sreg &= ~TPS2211_VCCD1;
1961 break;
1962 case 50: sreg &= ~TPS2211_VCCD0; /* Switch on 5.0V */
1963 sreg |= TPS2211_VCCD1;
1964 break;
1965 default: goto done;
1966 }
1967
1968 /* Checking supported voltages */
1969
1970 debug ("PIPR: 0x%x --> %s\n",
1971 pcmp->pcmc_pipr,
1972 (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
1973
1974 immap->im_ioport.iop_pcdat = sreg;
1975
1976#ifdef DEBUG
1977 {
1978 char *s;
1979
1980 if ((sreg & TPS2211_VCCD0) && !(sreg & TPS2211_VCCD1)) {
1981 s = "at 3.3V";
1982 } else if (!(sreg & TPS2211_VCCD0) && (sreg & TPS2211_VCCD1)) {
1983 s = "at 5.0V";
1984 } else {
1985 s = "down";
1986 }
1987 printf ("PCMCIA powered %s\n", s);
1988 }
1989#endif
1990
1991done:
1992 debug ("Enable PCMCIA buffers and stop RESET\n");
1993 reg = PCMCIA_PGCRX(_slot_);
1994 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
1995 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
1996 PCMCIA_PGCRX(_slot_) = reg;
1997 udelay(500);
1998
1999 debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
2000 slot+'A');
2001 return (0);
2002}
2003
2004static void cfg_ports (void)
2005{
2006 volatile immap_t *immap;
2007 volatile cpm8xx_t *cp;
2008 ushort sreg;
2009
2010 immap = (immap_t *)CFG_IMMR;
2011 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
2012
2013 /*
2014 * Configure Port C for TPS2211 PC-Card Power-Interface Switch
2015 *
2016 * Switch off all voltages, assert shutdown
2017 */
2018 sreg = immap->im_ioport.iop_pcdat;
2019 sreg |= (TPS2211_VPPD0 | TPS2211_VPPD1); /* VAVPP => Hi-Z */
2020 sreg &= ~(TPS2211_VCCD0 | TPS2211_VCCD1); /* 3V and 5V off */
2021 immap->im_ioport.iop_pcdat = sreg;
2022
2023 immap->im_ioport.iop_pcpar &= ~(TPS2211_OUTPUTS);
2024 immap->im_ioport.iop_pcdir |= TPS2211_OUTPUTS;
2025
2026 debug ("Set Port C: PAR: %04x DIR: %04x DAT: %04x\n",
2027 immap->im_ioport.iop_pcpar,
2028 immap->im_ioport.iop_pcdir,
2029 immap->im_ioport.iop_pcdat);
2030
2031 /*
2032 * Configure Port B for TPS2211 PC-Card Power-Interface Switch
2033 *
2034 * Over-Current Input only
2035 */
2036 cp->cp_pbpar &= ~(TPS2211_INPUTS);
2037 cp->cp_pbdir &= ~(TPS2211_INPUTS);
2038
2039 debug ("Set Port B: PAR: %08x DIR: %08x DAT: %08x\n",
2040 cp->cp_pbpar, cp->cp_pbdir, cp->cp_pbdat);
2041}
2042
2043#endif /* C2MON */
2044
wdenk1f53a412002-12-04 23:39:58 +00002045/* -------------------------------------------------------------------- */
2046/* MBX board from Morotola */
2047/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00002048
2049#if defined( CONFIG_MBX )
2050#include <../board/mbx8xx/csr.h>
2051
2052/* A lot of this has been taken from the RPX code in this file it works from me.
2053 I have added the voltage selection for the MBX board. */
2054
2055/* MBX voltage bit in control register #2 */
2056#define CR2_VPP12 ((uchar)0x10)
2057#define CR2_VPPVDD ((uchar)0x20)
2058#define CR2_VDD5 ((uchar)0x40)
2059#define CR2_VDD3 ((uchar)0x80)
2060
2061#define PCMCIA_BOARD_MSG "MBX860"
2062
2063static int voltage_set (int slot, int vcc, int vpp)
2064{
2065 uchar reg = 0;
2066
2067 debug ("voltage_set: PCMCIA_BOARD_MSG Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
2068 'A' + slot, vcc / 10, vcc % 10, vpp / 10, vcc % 10);
2069
2070 switch (vcc) {
2071 case 0:
2072 break;
2073 case 33:
2074 reg |= CR2_VDD3;
2075 break;
2076 case 50:
2077 reg |= CR2_VDD5;
2078 break;
2079 default:
2080 return 1;
2081 }
2082
2083 switch (vpp) {
2084 case 0:
2085 break;
2086 case 33:
2087 case 50:
2088 if (vcc == vpp) {
2089 reg |= CR2_VPPVDD;
2090 } else {
2091 return 1;
2092 }
2093 break;
2094 case 120:
2095 reg |= CR2_VPP12;
2096 break;
2097 default:
2098 return 1;
2099 }
2100
2101 /* first, turn off all power */
2102 MBX_CSR2 &= ~(CR2_VDDSEL | CR2_VPPSEL);
2103
2104 /* enable new powersettings */
2105 MBX_CSR2 |= reg;
2106 debug ("MBX_CSR2 read = 0x%02x\n", MBX_CSR2);
2107
2108 return (0);
2109}
2110
2111static int hardware_enable (int slot)
2112{
2113 volatile immap_t *immap;
2114 volatile cpm8xx_t *cp;
2115 volatile pcmconf8xx_t *pcmp;
2116 volatile sysconf8xx_t *sysp;
2117 uint reg, mask;
2118
2119 debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n",
2120 'A' + slot);
2121
2122 udelay (10000);
2123
2124 immap = (immap_t *) CFG_IMMR;
2125 sysp = (sysconf8xx_t *) (&(((immap_t *) CFG_IMMR)->im_siu_conf));
2126 pcmp = (pcmconf8xx_t *) (&(((immap_t *) CFG_IMMR)->im_pcmcia));
2127 cp = (cpm8xx_t *) (&(((immap_t *) CFG_IMMR)->im_cpm));
2128
2129 /* clear interrupt state, and disable interrupts */
2130 pcmp->pcmc_pscr = PCMCIA_MASK (_slot_);
2131 pcmp->pcmc_per &= ~PCMCIA_MASK (_slot_);
2132
wdenkc6097192002-11-03 00:24:07 +00002133 /*
wdenk1f53a412002-12-04 23:39:58 +00002134 * Disable interrupts, DMA, and PCMCIA buffers
2135 * (isolate the interface) and assert RESET signal
wdenkc6097192002-11-03 00:24:07 +00002136 */
2137 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00002138 reg = 0;
wdenkc6097192002-11-03 00:24:07 +00002139 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
2140 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
2141 PCMCIA_PGCRX (_slot_) = reg;
2142 udelay (500);
2143
2144 /* remove all power */
2145 voltage_set (slot, 0, 0);
2146 /*
2147 * Make sure there is a card in the slot, then configure the interface.
2148 */
wdenkea909b72002-11-21 23:11:29 +00002149 udelay(10000);
2150 debug ("[%d] %s: PIPR(%p)=0x%x\n",
2151 __LINE__,__FUNCTION__,
2152 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
wdenkc40b2952004-03-13 23:29:43 +00002153#ifndef CONFIG_HMI10
wdenkea909b72002-11-21 23:11:29 +00002154 if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
wdenka522fa02004-01-04 22:51:12 +00002155#else
2156 if (pcmp->pcmc_pipr & (0x10000000 >> (slot << 4))) {
wdenkc40b2952004-03-13 23:29:43 +00002157#endif /* CONFIG_HMI10 */
wdenkc6097192002-11-03 00:24:07 +00002158 printf (" No Card found\n");
2159 return (1);
2160 }
2161
2162 /*
2163 * Power On.
2164 */
2165 mask = PCMCIA_VS1 (_slot_) | PCMCIA_VS2 (_slot_);
2166 reg = pcmp->pcmc_pipr;
2167 debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n", reg,
2168 (reg & PCMCIA_VS1 (slot)) ? "n" : "ff",
2169 (reg & PCMCIA_VS2 (slot)) ? "n" : "ff");
2170
2171 if ((reg & mask) == mask) {
2172 voltage_set (_slot_, 50, 0);
2173 printf (" 5.0V card found: ");
2174 } else {
2175 voltage_set (_slot_, 33, 0);
2176 printf (" 3.3V card found: ");
2177 }
2178
2179 debug ("Enable PCMCIA buffers and stop RESET\n");
2180 reg = PCMCIA_PGCRX (_slot_);
2181 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
2182 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
2183 PCMCIA_PGCRX (_slot_) = reg;
2184
2185 udelay (250000); /* some cards need >150 ms to come up :-( */
2186
2187 debug ("# hardware_enable done\n");
2188
2189 return (0);
2190}
2191
2192#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
2193static int hardware_disable (int slot)
2194{
2195 return 0; /* No hardware to disable */
2196}
2197#endif /* CFG_CMD_PCMCIA */
2198#endif /* CONFIG_MBX */
wdenk1f53a412002-12-04 23:39:58 +00002199/* -------------------------------------------------------------------- */
2200/* R360MPI Board */
2201/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00002202
2203#if defined(CONFIG_R360MPI)
2204
2205#define PCMCIA_BOARD_MSG "R360MPI"
2206
2207
2208static int hardware_enable(int slot)
2209{
2210 volatile immap_t *immap;
2211 volatile cpm8xx_t *cp;
2212 volatile pcmconf8xx_t *pcmp;
2213 volatile sysconf8xx_t *sysp;
2214 uint reg, mask;
2215
2216 debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
2217
2218 udelay(10000);
2219
2220 immap = (immap_t *)CFG_IMMR;
2221 sysp = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
2222 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
2223 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
2224
2225 /*
2226 * Configure SIUMCR to enable PCMCIA port B
2227 * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
2228 */
2229 sysp->sc_siumcr &= ~SIUMCR_DBGC11; /* set DBGC to 00 */
2230
2231 /* clear interrupt state, and disable interrupts */
2232 pcmp->pcmc_pscr = PCMCIA_MASK(_slot_);
2233 pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
2234
wdenkc6097192002-11-03 00:24:07 +00002235 /*
wdenk1f53a412002-12-04 23:39:58 +00002236 * Disable interrupts, DMA, and PCMCIA buffers
2237 * (isolate the interface) and assert RESET signal
wdenkc6097192002-11-03 00:24:07 +00002238 */
2239 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00002240 reg = 0;
2241 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
2242 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkc6097192002-11-03 00:24:07 +00002243 PCMCIA_PGCRX(_slot_) = reg;
2244 udelay(500);
2245
2246 /*
2247 * Configure Ports A, B & C pins for
2248 * 5 Volts Enable and 3 Volts enable
2249 */
2250 immap->im_ioport.iop_pcpar &= ~(0x0400);
2251 immap->im_ioport.iop_pcso &= ~(0x0400);/*
2252 immap->im_ioport.iop_pcdir |= 0x0400;*/
2253
2254 immap->im_ioport.iop_papar &= ~(0x0200);/*
2255 immap->im_ioport.iop_padir |= 0x0200;*/
2256#if 0
2257 immap->im_ioport.iop_pbpar &= ~(0xC000);
2258 immap->im_ioport.iop_pbdir &= ~(0xC000);
2259#endif
2260 /* remove all power */
2261
2262 immap->im_ioport.iop_pcdat |= 0x0400;
2263 immap->im_ioport.iop_padat |= 0x0200;
2264
2265 /*
2266 * Make sure there is a card in the slot, then configure the interface.
2267 */
2268 udelay(10000);
2269 debug ("[%d] %s: PIPR(%p)=0x%x\n",
2270 __LINE__,__FUNCTION__,
2271 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
wdenkea909b72002-11-21 23:11:29 +00002272 if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
wdenkc6097192002-11-03 00:24:07 +00002273 printf (" No Card found\n");
2274 return (1);
2275 }
2276
2277 /*
2278 * Power On.
2279 */
2280 mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
2281 reg = pcmp->pcmc_pipr;
2282 debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
2283 reg,
2284 (reg&PCMCIA_VS1(slot))?"n":"ff",
2285 (reg&PCMCIA_VS2(slot))?"n":"ff");
2286 if ((reg & mask) == mask) {
2287 immap->im_ioport.iop_pcdat &= ~(0x4000);
2288 puts (" 5.0V card found: ");
2289 } else {
2290 immap->im_ioport.iop_padat &= ~(0x0002);
2291 puts (" 3.3V card found: ");
2292 }
2293 immap->im_ioport.iop_pcdir |= 0x0400;
2294 immap->im_ioport.iop_padir |= 0x0200;
2295#if 0
2296 /* VCC switch error flag, PCMCIA slot INPACK_ pin */
2297 cp->cp_pbdir &= ~(0x0020 | 0x0010);
2298 cp->cp_pbpar &= ~(0x0020 | 0x0010);
2299 udelay(500000);
2300#endif
2301 debug ("Enable PCMCIA buffers and stop RESET\n");
2302 reg = PCMCIA_PGCRX(_slot_);
2303 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
2304 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
2305 PCMCIA_PGCRX(_slot_) = reg;
2306
2307 udelay(250000); /* some cards need >150 ms to come up :-( */
2308
2309 debug ("# hardware_enable done\n");
2310
2311 return (0);
2312}
2313
2314
wdenkc6097192002-11-03 00:24:07 +00002315#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
2316static int hardware_disable(int slot)
2317{
2318 volatile immap_t *immap;
2319 volatile pcmconf8xx_t *pcmp;
2320 u_long reg;
2321
2322 debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
2323
2324 immap = (immap_t *)CFG_IMMR;
2325 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
2326
2327 /* remove all power */
2328 immap->im_ioport.iop_pcdat |= 0x0400;
2329 immap->im_ioport.iop_padat |= 0x0200;
2330
2331 /* Configure PCMCIA General Control Register */
wdenkc6097192002-11-03 00:24:07 +00002332 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00002333 reg = 0;
wdenkc6097192002-11-03 00:24:07 +00002334 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
2335 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
2336 PCMCIA_PGCRX(_slot_) = reg;
2337
2338 udelay(10000);
2339
2340 return (0);
2341}
2342#endif /* CFG_CMD_PCMCIA */
2343
2344
wdenkc6097192002-11-03 00:24:07 +00002345static int voltage_set(int slot, int vcc, int vpp)
2346{
2347 volatile immap_t *immap;
2348 volatile pcmconf8xx_t *pcmp;
2349 u_long reg;
2350
2351 debug ("voltage_set: "
2352 PCMCIA_BOARD_MSG
2353 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
2354 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
2355
2356 immap = (immap_t *)CFG_IMMR;
2357 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
2358 /*
2359 * Disable PCMCIA buffers (isolate the interface)
2360 * and assert RESET signal
2361 */
2362 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00002363 reg = PCMCIA_PGCRX(_slot_);
2364 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
2365 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkc6097192002-11-03 00:24:07 +00002366 PCMCIA_PGCRX(_slot_) = reg;
2367 udelay(500);
2368
2369 /*
2370 * Configure Ports A & C pins for
2371 * 5 Volts Enable and 3 Volts enable,
2372 * Turn off all power
2373 */
2374 debug ("PCMCIA power OFF\n");
2375 immap->im_ioport.iop_pcpar &= ~(0x0400);
2376 immap->im_ioport.iop_pcso &= ~(0x0400);/*
2377 immap->im_ioport.iop_pcdir |= 0x0400;*/
2378
2379 immap->im_ioport.iop_papar &= ~(0x0200);/*
2380 immap->im_ioport.iop_padir |= 0x0200;*/
2381
2382 immap->im_ioport.iop_pcdat |= 0x0400;
2383 immap->im_ioport.iop_padat |= 0x0200;
2384
2385 reg = 0;
2386 switch(vcc) {
2387 case 0: break;
2388 case 33: reg |= 0x0200; break;
2389 case 50: reg |= 0x0400; break;
2390 default: goto done;
2391 }
2392
2393 /* Checking supported voltages */
2394
2395 debug ("PIPR: 0x%x --> %s\n",
2396 pcmp->pcmc_pipr,
2397 (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
2398
2399 if (reg & 0x0200)
2400 immap->im_ioport.iop_pcdat &= !reg;
2401 if (reg & 0x0400)
2402 immap->im_ioport.iop_padat &= !reg;
wdenk1f53a412002-12-04 23:39:58 +00002403 immap->im_ioport.iop_pcdir |= 0x0200;
2404 immap->im_ioport.iop_padir |= 0x0400;
wdenkc6097192002-11-03 00:24:07 +00002405 if (reg) {
2406 debug ("PCMCIA powered at %sV\n",
2407 (reg&0x0400) ? "5.0" : "3.3");
2408 } else {
2409 debug ("PCMCIA powered down\n");
2410 }
2411
2412done:
2413 debug ("Enable PCMCIA buffers and stop RESET\n");
2414 reg = PCMCIA_PGCRX(_slot_);
2415 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
2416 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
2417 PCMCIA_PGCRX(_slot_) = reg;
2418 udelay(500);
2419
2420 debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
2421 slot+'A');
2422 return (0);
2423}
2424
2425#endif /* R360MPI */
2426
wdenk1f53a412002-12-04 23:39:58 +00002427/* -------------------------------------------------------------------- */
wdenk0608e042004-03-25 19:29:38 +00002428/* KUP4K and KUP4X Boards */
wdenk1f53a412002-12-04 23:39:58 +00002429/* -------------------------------------------------------------------- */
wdenk0608e042004-03-25 19:29:38 +00002430#if defined(CONFIG_KUP4K) || defined(CONFIG_KUP4X)
wdenk56f94be2002-11-05 16:35:14 +00002431
wdenk0608e042004-03-25 19:29:38 +00002432#define PCMCIA_BOARD_MSG "KUP"
wdenk56f94be2002-11-05 16:35:14 +00002433
2434#define KUP4K_PCMCIA_B_3V3 (0x00020000)
2435
2436static int hardware_enable(int slot)
2437{
2438 volatile immap_t *immap;
2439 volatile cpm8xx_t *cp;
2440 volatile pcmconf8xx_t *pcmp;
2441 volatile sysconf8xx_t *sysp;
2442 uint reg, mask;
2443
2444 debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
2445
2446 udelay(10000);
2447
2448 immap = (immap_t *)CFG_IMMR;
2449 sysp = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
2450 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
2451 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
2452
2453 /*
2454 * Configure SIUMCR to enable PCMCIA port B
2455 * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
2456 */
2457 sysp->sc_siumcr &= ~SIUMCR_DBGC11; /* set DBGC to 00 */
2458
2459 /* clear interrupt state, and disable interrupts */
wdenkea909b72002-11-21 23:11:29 +00002460 pcmp->pcmc_pscr = PCMCIA_MASK(slot);
2461 pcmp->pcmc_per &= ~PCMCIA_MASK(slot);
wdenk56f94be2002-11-05 16:35:14 +00002462
wdenk56f94be2002-11-05 16:35:14 +00002463 /*
wdenk1f53a412002-12-04 23:39:58 +00002464 * Disable interrupts, DMA, and PCMCIA buffers
2465 * (isolate the interface) and assert RESET signal
wdenk56f94be2002-11-05 16:35:14 +00002466 */
2467 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00002468 reg = 0;
2469 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
2470 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkea909b72002-11-21 23:11:29 +00002471 PCMCIA_PGCRX(slot) = reg;
2472 udelay(2500);
wdenk56f94be2002-11-05 16:35:14 +00002473
2474 /*
2475 * Configure Port B pins for
2476 * 3 Volts enable
2477 */
wdenkea909b72002-11-21 23:11:29 +00002478 if (slot) { /* Slot A is built-in */
2479 cp->cp_pbdir |= KUP4K_PCMCIA_B_3V3;
2480 cp->cp_pbpar &= ~KUP4K_PCMCIA_B_3V3;
2481 /* remove all power */
2482 cp->cp_pbdat |= KUP4K_PCMCIA_B_3V3; /* active low */
2483 }
wdenk56f94be2002-11-05 16:35:14 +00002484 /*
2485 * Make sure there is a card in the slot, then configure the interface.
2486 */
2487 udelay(10000);
2488 debug ("[%d] %s: PIPR(%p)=0x%x\n",
2489 __LINE__,__FUNCTION__,
2490 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
wdenkea909b72002-11-21 23:11:29 +00002491 if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
wdenk56f94be2002-11-05 16:35:14 +00002492 printf (" No Card found\n");
2493 return (1);
2494 }
2495
2496 /*
2497 * Power On.
2498 */
wdenka6c7ad22002-12-03 21:28:10 +00002499 printf("%s Slot %c:", slot ? "" : "\n", 'A' + slot);
wdenk56f94be2002-11-05 16:35:14 +00002500 mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
2501 reg = pcmp->pcmc_pipr;
2502 debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
2503 reg,
2504 (reg&PCMCIA_VS1(slot))?"n":"ff",
2505 (reg&PCMCIA_VS2(slot))?"n":"ff");
2506 if ((reg & mask) == mask) {
2507 puts (" 5.0V card found: NOT SUPPORTED !!!\n");
2508 } else {
wdenkea909b72002-11-21 23:11:29 +00002509 if(slot)
2510 cp->cp_pbdat &= ~KUP4K_PCMCIA_B_3V3;
wdenk56f94be2002-11-05 16:35:14 +00002511 puts (" 3.3V card found: ");
2512 }
2513#if 0
2514 /* VCC switch error flag, PCMCIA slot INPACK_ pin */
2515 cp->cp_pbdir &= ~(0x0020 | 0x0010);
2516 cp->cp_pbpar &= ~(0x0020 | 0x0010);
2517 udelay(500000);
2518#endif
2519 debug ("Enable PCMCIA buffers and stop RESET\n");
wdenkea909b72002-11-21 23:11:29 +00002520 reg = PCMCIA_PGCRX(slot);
wdenk56f94be2002-11-05 16:35:14 +00002521 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
2522 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkea909b72002-11-21 23:11:29 +00002523 PCMCIA_PGCRX(slot) = reg;
wdenk56f94be2002-11-05 16:35:14 +00002524
2525 udelay(250000); /* some cards need >150 ms to come up :-( */
2526
2527 debug ("# hardware_enable done\n");
2528
2529 return (0);
2530}
2531
2532
wdenk56f94be2002-11-05 16:35:14 +00002533#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
2534static int hardware_disable(int slot)
2535{
2536 volatile immap_t *immap;
2537 volatile cpm8xx_t *cp;
2538 volatile pcmconf8xx_t *pcmp;
2539 u_long reg;
2540
2541 debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
2542
2543 immap = (immap_t *)CFG_IMMR;
2544 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
2545 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
wdenk1f53a412002-12-04 23:39:58 +00002546
wdenk56f94be2002-11-05 16:35:14 +00002547 /* remove all power */
wdenkea909b72002-11-21 23:11:29 +00002548 if (slot)
2549 cp->cp_pbdat |= KUP4K_PCMCIA_B_3V3;
wdenk56f94be2002-11-05 16:35:14 +00002550
2551 /* Configure PCMCIA General Control Register */
wdenk56f94be2002-11-05 16:35:14 +00002552 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00002553 reg = 0;
wdenk56f94be2002-11-05 16:35:14 +00002554 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
2555 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkea909b72002-11-21 23:11:29 +00002556 PCMCIA_PGCRX(slot) = reg;
wdenk56f94be2002-11-05 16:35:14 +00002557
2558 udelay(10000);
2559
2560 return (0);
2561}
2562#endif /* CFG_CMD_PCMCIA */
2563
2564
wdenk56f94be2002-11-05 16:35:14 +00002565static int voltage_set(int slot, int vcc, int vpp)
2566{
2567 volatile immap_t *immap;
2568 volatile cpm8xx_t *cp;
2569 volatile pcmconf8xx_t *pcmp;
2570 u_long reg;
2571
2572 debug ("voltage_set: " \
2573 PCMCIA_BOARD_MSG \
2574 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
2575 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
2576
wdenkea909b72002-11-21 23:11:29 +00002577 if (!slot) /* Slot A is not configurable */
2578 return 0;
2579
wdenk56f94be2002-11-05 16:35:14 +00002580 immap = (immap_t *)CFG_IMMR;
2581 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
2582 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
2583
2584 /*
2585 * Disable PCMCIA buffers (isolate the interface)
2586 * and assert RESET signal
2587 */
2588 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00002589 reg = PCMCIA_PGCRX(slot);
2590 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
2591 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkea909b72002-11-21 23:11:29 +00002592 PCMCIA_PGCRX(slot) = reg;
wdenk56f94be2002-11-05 16:35:14 +00002593 udelay(500);
2594
2595 debug ("PCMCIA power OFF\n");
2596 /*
2597 * Configure Port B pins for
2598 * 3 Volts enable
2599 */
2600 cp->cp_pbdir |= KUP4K_PCMCIA_B_3V3;
2601 cp->cp_pbpar &= ~KUP4K_PCMCIA_B_3V3;
2602 /* remove all power */
2603 cp->cp_pbdat |= KUP4K_PCMCIA_B_3V3; /* active low */
2604
2605 switch(vcc) {
2606 case 0: break;
2607 case 33:
2608 cp->cp_pbdat &= ~KUP4K_PCMCIA_B_3V3;
2609 debug ("PCMCIA powered at 3.3V\n");
2610 break;
2611 case 50:
2612 debug ("PCMCIA: 5Volt vcc not supported\n");
2613 break;
2614 default:
2615 puts("PCMCIA: vcc not supported");
2616 break;
2617 }
wdenkea909b72002-11-21 23:11:29 +00002618 udelay(10000);
wdenk56f94be2002-11-05 16:35:14 +00002619 /* Checking supported voltages */
2620
2621 debug ("PIPR: 0x%x --> %s\n",
2622 pcmp->pcmc_pipr,
wdenkea909b72002-11-21 23:11:29 +00002623 (pcmp->pcmc_pipr & (0x80000000 >> (slot << 4)))
wdenk56f94be2002-11-05 16:35:14 +00002624 ? "only 5 V --> NOT SUPPORTED"
2625 : "can do 3.3V");
2626
2627
2628 debug ("Enable PCMCIA buffers and stop RESET\n");
wdenkea909b72002-11-21 23:11:29 +00002629 reg = PCMCIA_PGCRX(slot);
wdenk56f94be2002-11-05 16:35:14 +00002630 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
2631 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkea909b72002-11-21 23:11:29 +00002632 PCMCIA_PGCRX(slot) = reg;
wdenk56f94be2002-11-05 16:35:14 +00002633 udelay(500);
2634
2635 debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
2636 slot+'A');
2637 return (0);
2638}
2639
wdenk0608e042004-03-25 19:29:38 +00002640#endif /* KUP4K || KUP4X */
wdenk56f94be2002-11-05 16:35:14 +00002641
2642
wdenk1f53a412002-12-04 23:39:58 +00002643/* -------------------------------------------------------------------- */
2644/* End of Board Specific Stuff */
2645/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00002646
2647
wdenk1f53a412002-12-04 23:39:58 +00002648/* -------------------------------------------------------------------- */
2649/* MPC8xx Specific Stuff - should go to MPC8xx directory */
2650/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00002651
2652/*
2653 * Search this table to see if the windowsize is
2654 * supported...
2655 */
2656
2657#define M8XX_SIZES_NO 32
2658
2659static const u_int m8xx_size_to_gray[M8XX_SIZES_NO] =
2660{ 0x00000001, 0x00000002, 0x00000008, 0x00000004,
2661 0x00000080, 0x00000040, 0x00000010, 0x00000020,
2662 0x00008000, 0x00004000, 0x00001000, 0x00002000,
2663 0x00000100, 0x00000200, 0x00000800, 0x00000400,
2664
2665 0x0fffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2666 0x01000000, 0x02000000, 0xffffffff, 0x04000000,
2667 0x00010000, 0x00020000, 0x00080000, 0x00040000,
2668 0x00800000, 0x00400000, 0x00100000, 0x00200000 };
2669
2670
wdenk1f53a412002-12-04 23:39:58 +00002671/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00002672
wdenkdb01a2e2004-04-15 23:14:49 +00002673#if ( ! defined(CONFIG_I82365) && ! defined(CONFIG_PXA_PCMCIA) )
wdenk7f70e852003-05-20 14:25:27 +00002674
wdenkc6097192002-11-03 00:24:07 +00002675static u_int m8xx_get_graycode(u_int size)
2676{
2677 u_int k;
2678
2679 for (k = 0; k < M8XX_SIZES_NO; k++) {
2680 if(m8xx_size_to_gray[k] == size)
2681 break;
2682 }
2683
2684 if((k == M8XX_SIZES_NO) || (m8xx_size_to_gray[k] == -1))
2685 k = -1;
2686
2687 return k;
2688}
2689
wdenk7f70e852003-05-20 14:25:27 +00002690#endif /* CONFIG_I82365 */
2691
wdenk1f53a412002-12-04 23:39:58 +00002692/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00002693
2694#if 0
2695static u_int m8xx_get_speed(u_int ns, u_int is_io)
2696{
2697 u_int reg, clocks, psst, psl, psht;
2698
2699 if(!ns) {
2700
2701 /*
2702 * We get called with IO maps setup to 0ns
2703 * if not specified by the user.
2704 * They should be 255ns.
2705 */
2706
2707 if(is_io)
2708 ns = 255;
2709 else
2710 ns = 100; /* fast memory if 0 */
2711 }
2712
2713 /*
2714 * In PSST, PSL, PSHT fields we tell the controller
2715 * timing parameters in CLKOUT clock cycles.
2716 * CLKOUT is the same as GCLK2_50.
2717 */
2718
2719/* how we want to adjust the timing - in percent */
2720
2721#define ADJ 180 /* 80 % longer accesstime - to be sure */
2722
2723 clocks = ((M8XX_BUSFREQ / 1000) * ns) / 1000;
2724 clocks = (clocks * ADJ) / (100*1000);
2725
2726 if(clocks >= PCMCIA_BMT_LIMIT) {
2727 DEBUG(0, "Max access time limit reached\n");
2728 clocks = PCMCIA_BMT_LIMIT-1;
2729 }
2730
2731 psst = clocks / 7; /* setup time */
2732 psht = clocks / 7; /* hold time */
2733 psl = (clocks * 5) / 7; /* strobe length */
2734
2735 psst += clocks - (psst + psht + psl);
2736
2737 reg = psst << 12;
2738 reg |= psl << 7;
2739 reg |= psht << 16;
2740
2741 return reg;
2742}
2743#endif
2744
wdenk1f53a412002-12-04 23:39:58 +00002745/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00002746
wdenkdb01a2e2004-04-15 23:14:49 +00002747#if defined(CONFIG_IDE_8xx_PCCARD) || defined(CONFIG_PXA_PCMCIA)
wdenkc6097192002-11-03 00:24:07 +00002748static void print_funcid (int func)
2749{
2750 puts (indent);
2751 switch (func) {
2752 case CISTPL_FUNCID_MULTI:
2753 puts (" Multi-Function");
2754 break;
2755 case CISTPL_FUNCID_MEMORY:
2756 puts (" Memory");
2757 break;
2758 case CISTPL_FUNCID_SERIAL:
2759 puts (" Serial Port");
2760 break;
2761 case CISTPL_FUNCID_PARALLEL:
2762 puts (" Parallel Port");
2763 break;
2764 case CISTPL_FUNCID_FIXED:
2765 puts (" Fixed Disk");
2766 break;
2767 case CISTPL_FUNCID_VIDEO:
2768 puts (" Video Adapter");
2769 break;
2770 case CISTPL_FUNCID_NETWORK:
2771 puts (" Network Adapter");
2772 break;
2773 case CISTPL_FUNCID_AIMS:
2774 puts (" AIMS Card");
2775 break;
2776 case CISTPL_FUNCID_SCSI:
2777 puts (" SCSI Adapter");
2778 break;
2779 default:
2780 puts (" Unknown");
2781 break;
2782 }
2783 puts (" Card\n");
2784}
2785#endif /* CONFIG_IDE_8xx_PCCARD */
2786
wdenk1f53a412002-12-04 23:39:58 +00002787/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00002788
wdenkdb01a2e2004-04-15 23:14:49 +00002789#if defined(CONFIG_IDE_8xx_PCCARD) || defined(CONFIG_PXA_PCMCIA)
wdenkc6097192002-11-03 00:24:07 +00002790static void print_fixed (volatile uchar *p)
2791{
2792 if (p == NULL)
2793 return;
2794
2795 puts(indent);
2796
2797 switch (*p) {
2798 case CISTPL_FUNCE_IDE_IFACE:
2799 { uchar iface = *(p+2);
2800
2801 puts ((iface == CISTPL_IDE_INTERFACE) ? " IDE" : " unknown");
2802 puts (" interface ");
2803 break;
2804 }
2805 case CISTPL_FUNCE_IDE_MASTER:
2806 case CISTPL_FUNCE_IDE_SLAVE:
2807 { uchar f1 = *(p+2);
2808 uchar f2 = *(p+4);
2809
2810 puts ((f1 & CISTPL_IDE_SILICON) ? " [silicon]" : " [rotating]");
2811
2812 if (f1 & CISTPL_IDE_UNIQUE)
2813 puts (" [unique]");
2814
2815 puts ((f1 & CISTPL_IDE_DUAL) ? " [dual]" : " [single]");
2816
2817 if (f2 & CISTPL_IDE_HAS_SLEEP)
2818 puts (" [sleep]");
2819
2820 if (f2 & CISTPL_IDE_HAS_STANDBY)
2821 puts (" [standby]");
2822
2823 if (f2 & CISTPL_IDE_HAS_IDLE)
2824 puts (" [idle]");
2825
2826 if (f2 & CISTPL_IDE_LOW_POWER)
2827 puts (" [low power]");
2828
2829 if (f2 & CISTPL_IDE_REG_INHIBIT)
2830 puts (" [reg inhibit]");
2831
2832 if (f2 & CISTPL_IDE_HAS_INDEX)
2833 puts (" [index]");
2834
2835 if (f2 & CISTPL_IDE_IOIS16)
2836 puts (" [IOis16]");
2837
2838 break;
2839 }
2840 }
2841 putc ('\n');
2842}
2843#endif /* CONFIG_IDE_8xx_PCCARD */
2844
wdenk1f53a412002-12-04 23:39:58 +00002845/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00002846
wdenkdb01a2e2004-04-15 23:14:49 +00002847#if defined(CONFIG_IDE_8xx_PCCARD) || defined(CONFIG_PXA_PCMCIA)
wdenkc6097192002-11-03 00:24:07 +00002848
2849#define MAX_IDENT_CHARS 64
2850#define MAX_IDENT_FIELDS 4
2851
2852static uchar *known_cards[] = {
Wolfgang Denk77ddac92005-10-13 16:45:02 +02002853 (uchar *)"ARGOSY PnPIDE D5",
wdenkc6097192002-11-03 00:24:07 +00002854 NULL
2855};
2856
2857static int identify (volatile uchar *p)
2858{
2859 uchar id_str[MAX_IDENT_CHARS];
2860 uchar data;
2861 uchar *t;
2862 uchar **card;
2863 int i, done;
2864
2865 if (p == NULL)
2866 return (0); /* Don't know */
2867
2868 t = id_str;
2869 done =0;
2870
2871 for (i=0; i<=4 && !done; ++i, p+=2) {
2872 while ((data = *p) != '\0') {
2873 if (data == 0xFF) {
2874 done = 1;
2875 break;
2876 }
2877 *t++ = data;
2878 if (t == &id_str[MAX_IDENT_CHARS-1]) {
2879 done = 1;
2880 break;
2881 }
2882 p += 2;
2883 }
2884 if (!done)
2885 *t++ = ' ';
2886 }
2887 *t = '\0';
2888 while (--t > id_str) {
2889 if (*t == ' ')
2890 *t = '\0';
2891 else
2892 break;
2893 }
Wolfgang Denk77ddac92005-10-13 16:45:02 +02002894 puts ((char *)id_str);
wdenkc6097192002-11-03 00:24:07 +00002895 putc ('\n');
2896
2897 for (card=known_cards; *card; ++card) {
2898 debug ("## Compare against \"%s\"\n", *card);
Wolfgang Denk77ddac92005-10-13 16:45:02 +02002899 if (strcmp((char *)*card, (char *)id_str) == 0) { /* found! */
wdenkc6097192002-11-03 00:24:07 +00002900 debug ("## CARD FOUND ##\n");
2901 return (1);
2902 }
2903 }
2904
2905 return (0); /* don't know */
2906}
2907#endif /* CONFIG_IDE_8xx_PCCARD */
2908
wdenk1f53a412002-12-04 23:39:58 +00002909/* -------------------------------------------------------------------- */
wdenk04a85b32004-04-15 18:22:41 +00002910/* NETTA board by Intracom S.A. */
2911/* -------------------------------------------------------------------- */
2912
2913#if defined(CONFIG_NETTA)
2914
2915/* some sane bit macros */
2916#define _BD(_b) (1U << (31-(_b)))
2917#define _BDR(_l, _h) (((((1U << (31-(_l))) - 1) << 1) | 1) & ~((1U << (31-(_h))) - 1))
2918
2919#define _BW(_b) (1U << (15-(_b)))
2920#define _BWR(_l, _h) (((((1U << (15-(_l))) - 1) << 1) | 1) & ~((1U << (15-(_h))) - 1))
2921
2922#define _BB(_b) (1U << (7-(_b)))
2923#define _BBR(_l, _h) (((((1U << (7-(_l))) - 1) << 1) | 1) & ~((1U << (7-(_h))) - 1))
2924
2925#define _B(_b) _BD(_b)
2926#define _BR(_l, _h) _BDR(_l, _h)
2927
2928#define PCMCIA_BOARD_MSG "NETTA"
2929
2930static const unsigned short vppd_masks[2] = { _BW(14), _BW(15) };
2931
2932static void cfg_vppd(int no)
2933{
2934 volatile immap_t *immap = (immap_t *)CFG_IMMR;
2935 unsigned short mask;
2936
2937 if ((unsigned int)no >= sizeof(vppd_masks)/sizeof(vppd_masks[0]))
2938 return;
2939
2940 mask = vppd_masks[no];
2941
2942 immap->im_ioport.iop_papar &= ~mask;
2943 immap->im_ioport.iop_paodr &= ~mask;
2944 immap->im_ioport.iop_padir |= mask;
2945}
2946
2947static void set_vppd(int no, int what)
2948{
2949 volatile immap_t *immap = (immap_t *)CFG_IMMR;
2950 unsigned short mask;
2951
2952 if ((unsigned int)no >= sizeof(vppd_masks)/sizeof(vppd_masks[0]))
2953 return;
2954
2955 mask = vppd_masks[no];
2956
2957 if (what)
2958 immap->im_ioport.iop_padat |= mask;
2959 else
2960 immap->im_ioport.iop_padat &= ~mask;
2961}
2962
2963static const unsigned short vccd_masks[2] = { _BW(10), _BW(6) };
2964
2965static void cfg_vccd(int no)
2966{
2967 volatile immap_t *immap = (immap_t *)CFG_IMMR;
2968 unsigned short mask;
2969
2970 if ((unsigned int)no >= sizeof(vccd_masks)/sizeof(vccd_masks[0]))
2971 return;
2972
2973 mask = vccd_masks[no];
2974
2975 immap->im_ioport.iop_papar &= ~mask;
2976 immap->im_ioport.iop_paodr &= ~mask;
2977 immap->im_ioport.iop_padir |= mask;
2978}
2979
2980static void set_vccd(int no, int what)
2981{
2982 volatile immap_t *immap = (immap_t *)CFG_IMMR;
2983 unsigned short mask;
2984
2985 if ((unsigned int)no >= sizeof(vccd_masks)/sizeof(vccd_masks[0]))
2986 return;
2987
2988 mask = vccd_masks[no];
2989
2990 if (what)
2991 immap->im_ioport.iop_padat |= mask;
2992 else
2993 immap->im_ioport.iop_padat &= ~mask;
2994}
2995
2996static const unsigned short oc_mask = _BW(8);
2997
2998static void cfg_oc(void)
2999{
3000 volatile immap_t *immap = (immap_t *)CFG_IMMR;
3001 unsigned short mask = oc_mask;
3002
3003 immap->im_ioport.iop_pcdir &= ~mask;
3004 immap->im_ioport.iop_pcso &= ~mask;
3005 immap->im_ioport.iop_pcint &= ~mask;
3006 immap->im_ioport.iop_pcpar &= ~mask;
3007}
3008
3009static int get_oc(void)
3010{
3011 volatile immap_t *immap = (immap_t *)CFG_IMMR;
3012 unsigned short mask = oc_mask;
3013 int what;
3014
3015 what = !!(immap->im_ioport.iop_pcdat & mask);;
3016 return what;
3017}
3018
3019static const unsigned short shdn_mask = _BW(12);
3020
3021static void cfg_shdn(void)
3022{
3023 volatile immap_t *immap = (immap_t *)CFG_IMMR;
3024 unsigned short mask;
3025
3026 mask = shdn_mask;
3027
3028 immap->im_ioport.iop_papar &= ~mask;
3029 immap->im_ioport.iop_paodr &= ~mask;
3030 immap->im_ioport.iop_padir |= mask;
3031}
3032
3033static void set_shdn(int what)
3034{
3035 volatile immap_t *immap = (immap_t *)CFG_IMMR;
3036 unsigned short mask;
3037
3038 mask = shdn_mask;
3039
3040 if (what)
3041 immap->im_ioport.iop_padat |= mask;
3042 else
3043 immap->im_ioport.iop_padat &= ~mask;
3044}
3045
3046static void cfg_ports (void);
3047
3048static int hardware_enable(int slot)
3049{
3050 volatile immap_t *immap;
3051 volatile cpm8xx_t *cp;
3052 volatile pcmconf8xx_t *pcmp;
3053 volatile sysconf8xx_t *sysp;
3054 uint reg, pipr, mask;
3055 int i;
3056
3057 debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
3058
3059 udelay(10000);
3060
3061 immap = (immap_t *)CFG_IMMR;
3062 sysp = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
3063 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
3064 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
3065
3066 /* Configure Ports for TPS2211A PC-Card Power-Interface Switch */
3067 cfg_ports ();
3068
3069 /* clear interrupt state, and disable interrupts */
3070 pcmp->pcmc_pscr = PCMCIA_MASK(_slot_);
3071 pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
3072
3073 /*
3074 * Disable interrupts, DMA, and PCMCIA buffers
3075 * (isolate the interface) and assert RESET signal
3076 */
3077 debug ("Disable PCMCIA buffers and assert RESET\n");
3078 reg = 0;
3079 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
3080 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
3081 PCMCIA_PGCRX(_slot_) = reg;
3082
3083 udelay(500);
3084
3085 /*
3086 * Make sure there is a card in the slot, then configure the interface.
3087 */
3088 udelay(10000);
3089 debug ("[%d] %s: PIPR(%p)=0x%x\n",
3090 __LINE__,__FUNCTION__,
3091 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
3092 if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
3093 printf (" No Card found\n");
3094 return (1);
3095 }
3096
3097 /*
3098 * Power On: Set VAVCC to 3.3V or 5V, set VAVPP to Hi-Z
3099 */
3100 mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
3101 pipr = pcmp->pcmc_pipr;
3102 debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
3103 pipr,
3104 (reg&PCMCIA_VS1(slot))?"n":"ff",
3105 (reg&PCMCIA_VS2(slot))?"n":"ff");
3106
3107 if ((pipr & mask) == mask) {
3108 set_vppd(0, 1); set_vppd(1, 1); /* VAVPP => Hi-Z */
3109 set_vccd(0, 0); set_vccd(1, 1); /* 5V on, 3V off */
3110 puts (" 5.0V card found: ");
3111 } else {
3112 set_vppd(0, 1); set_vppd(1, 1); /* VAVPP => Hi-Z */
3113 set_vccd(0, 1); set_vccd(1, 0); /* 5V off, 3V on */
3114 puts (" 3.3V card found: ");
3115 }
3116
3117 /* Wait 500 ms; use this to check for over-current */
3118 for (i=0; i<5000; ++i) {
3119 if (!get_oc()) {
3120 printf (" *** Overcurrent - Safety shutdown ***\n");
3121 set_vccd(0, 0); set_vccd(1, 0); /* VAVPP => Hi-Z */
3122 return (1);
3123 }
3124 udelay (100);
3125 }
3126
3127 debug ("Enable PCMCIA buffers and stop RESET\n");
3128 reg = PCMCIA_PGCRX(_slot_);
3129 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
3130 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
3131 PCMCIA_PGCRX(_slot_) = reg;
3132
3133 udelay(250000); /* some cards need >150 ms to come up :-( */
3134
3135 debug ("# hardware_enable done\n");
3136
3137 return (0);
3138}
3139
3140
3141#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
3142static int hardware_disable(int slot)
3143{
3144 volatile immap_t *immap;
3145 volatile pcmconf8xx_t *pcmp;
3146 u_long reg;
3147
3148 debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
3149
3150 immap = (immap_t *)CFG_IMMR;
3151 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
3152
3153 /* Configure PCMCIA General Control Register */
3154 debug ("Disable PCMCIA buffers and assert RESET\n");
3155 reg = 0;
3156 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
3157 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
3158 PCMCIA_PGCRX(_slot_) = reg;
3159
3160 /* All voltages off / Hi-Z */
3161 set_vppd(0, 1); set_vppd(1, 1);
3162 set_vccd(0, 1); set_vccd(1, 1);
3163
3164 udelay(10000);
3165
3166 return (0);
3167}
3168#endif /* CFG_CMD_PCMCIA */
3169
3170
3171static int voltage_set(int slot, int vcc, int vpp)
3172{
3173 volatile immap_t *immap;
3174 volatile cpm8xx_t *cp;
3175 volatile pcmconf8xx_t *pcmp;
3176 u_long reg;
3177 ushort sreg;
3178
3179 debug ("voltage_set: "
3180 PCMCIA_BOARD_MSG
3181 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
3182 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
3183
3184 immap = (immap_t *)CFG_IMMR;
3185 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
3186 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
3187 /*
3188 * Disable PCMCIA buffers (isolate the interface)
3189 * and assert RESET signal
3190 */
3191 debug ("Disable PCMCIA buffers and assert RESET\n");
3192 reg = PCMCIA_PGCRX(_slot_);
3193 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
3194 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
3195 PCMCIA_PGCRX(_slot_) = reg;
3196 udelay(500);
3197
3198 /*
3199 * Configure Port C pins for
3200 * 5 Volts Enable and 3 Volts enable,
3201 * Turn all power pins to Hi-Z
3202 */
3203 debug ("PCMCIA power OFF\n");
3204 cfg_ports (); /* Enables switch, but all in Hi-Z */
3205
3206 sreg = immap->im_ioport.iop_pcdat;
3207 set_vppd(0, 1); set_vppd(1, 1);
3208
3209 switch(vcc) {
3210 case 0:
3211 break; /* Switch off */
3212
3213 case 33:
3214 set_vccd(0, 1); set_vccd(1, 0);
3215 break;
3216
3217 case 50:
3218 set_vccd(0, 0); set_vccd(1, 1);
3219 break;
3220
3221 default:
3222 goto done;
3223 }
3224
3225 /* Checking supported voltages */
3226
3227 debug ("PIPR: 0x%x --> %s\n",
3228 pcmp->pcmc_pipr,
3229 (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
3230
3231done:
3232 debug ("Enable PCMCIA buffers and stop RESET\n");
3233 reg = PCMCIA_PGCRX(_slot_);
3234 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
3235 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
3236 PCMCIA_PGCRX(_slot_) = reg;
3237 udelay(500);
3238
3239 debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
3240 slot+'A');
3241 return (0);
3242}
3243
3244static void cfg_ports (void)
3245{
3246 volatile immap_t *immap;
3247 volatile cpm8xx_t *cp;
3248
3249 immap = (immap_t *)CFG_IMMR;
3250 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
3251
3252
3253 cfg_vppd(0); cfg_vppd(1); /* VPPD0,VPPD1 VAVPP => Hi-Z */
3254 cfg_vccd(0); cfg_vccd(1); /* 3V and 5V off */
3255 cfg_shdn();
3256 cfg_oc();
3257
3258 /*
3259 * Configure Port A for TPS2211 PC-Card Power-Interface Switch
3260 *
3261 * Switch off all voltages, assert shutdown
3262 */
3263 set_vppd(0, 1); set_vppd(1, 1);
3264 set_vccd(0, 0); set_vccd(1, 0);
3265 set_shdn(1);
3266
3267 udelay(100000);
3268}
3269
3270#endif /* NETTA */
3271
3272
3273/* -------------------------------------------------------------------- */
wdenkf7d15722004-12-18 22:35:43 +00003274/* UC100 Boards */
3275/* -------------------------------------------------------------------- */
3276
3277#if defined(CONFIG_UC100)
3278
3279#define PCMCIA_BOARD_MSG "UC100"
3280
3281/*
3282 * Remark: don't turn off OE "__MY_PCMCIA_GCRX_CXOE" on UC100 board.
3283 * This leads to board-hangup! (sr, 8 Dez. 2004)
3284 */
3285
3286static void cfg_ports (void);
3287
3288static int hardware_enable(int slot)
3289{
3290 volatile immap_t *immap;
3291 volatile cpm8xx_t *cp;
3292 volatile pcmconf8xx_t *pcmp;
3293 volatile sysconf8xx_t *sysp;
3294 uint reg, mask;
3295
3296 debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
3297
3298 udelay(10000);
3299
3300 immap = (immap_t *)CFG_IMMR;
3301 sysp = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
3302 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
3303 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
3304
3305 /* Configure Ports for TPS2211A PC-Card Power-Interface Switch */
3306 cfg_ports ();
3307
3308 /*
3309 * Configure SIUMCR to enable PCMCIA port B
3310 * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
3311 */
3312 sysp->sc_siumcr &= ~SIUMCR_DBGC11; /* set DBGC to 00 */
3313
3314 /* clear interrupt state, and disable interrupts */
3315 pcmp->pcmc_pscr = PCMCIA_MASK(_slot_);
3316 pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
3317
3318 /*
3319 * Disable interrupts, DMA, and PCMCIA buffers
3320 * (isolate the interface) and assert RESET signal
3321 */
3322 debug ("Disable PCMCIA buffers and assert RESET\n");
3323 reg = 0;
3324 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
3325 PCMCIA_PGCRX(_slot_) = reg;
3326 udelay(500);
3327
3328 /*
3329 * Make sure there is a card in the slot, then configure the interface.
3330 */
3331 udelay(10000);
3332 debug ("[%d] %s: PIPR(%p)=0x%x\n",
3333 __LINE__,__FUNCTION__,
3334 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
3335 if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
3336 printf (" No Card found\n");
3337 return (1);
3338 }
3339
3340 /*
3341 * Power On.
3342 */
3343 mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
3344 reg = pcmp->pcmc_pipr;
3345 debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
3346 reg,
3347 (reg&PCMCIA_VS1(slot))?"n":"ff",
3348 (reg&PCMCIA_VS2(slot))?"n":"ff");
3349 if ((reg & mask) == mask) {
3350 puts (" 5.0V card found: ");
3351 } else {
3352 puts (" 3.3V card found: ");
3353 }
3354
3355 /* switch VCC on */
3356 immap->im_ioport.iop_padat |= 0x8000; /* power enable 3.3V */
3357
3358 udelay(10000);
3359
3360 debug ("Enable PCMCIA buffers and stop RESET\n");
3361 reg = PCMCIA_PGCRX(_slot_);
3362 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
3363 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
3364 PCMCIA_PGCRX(_slot_) = reg;
3365
3366 udelay(250000); /* some cards need >150 ms to come up :-( */
3367
3368 debug ("# hardware_enable done\n");
3369
3370 return (0);
3371}
3372
3373
3374#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
3375static int hardware_disable(int slot)
3376{
3377 volatile immap_t *immap;
3378 volatile cpm8xx_t *cp;
3379 volatile pcmconf8xx_t *pcmp;
3380 u_long reg;
3381
3382 debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
3383
3384 immap = (immap_t *)CFG_IMMR;
3385 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
3386
3387 /* switch VCC off */
3388 immap->im_ioport.iop_padat &= ~0x8000; /* power disable 3.3V */
3389
3390 /* Configure PCMCIA General Control Register */
3391 debug ("Disable PCMCIA buffers and assert RESET\n");
3392 reg = 0;
3393 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
3394 PCMCIA_PGCRX(_slot_) = reg;
3395
3396 udelay(10000);
3397
3398 return (0);
3399}
3400#endif /* CFG_CMD_PCMCIA */
3401
3402
3403static int voltage_set(int slot, int vcc, int vpp)
3404{
3405 volatile immap_t *immap;
3406 volatile pcmconf8xx_t *pcmp;
3407 u_long reg;
3408
3409 debug ("voltage_set: "
3410 PCMCIA_BOARD_MSG
3411 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
3412 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
3413
3414 immap = (immap_t *)CFG_IMMR;
3415 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
3416 /*
3417 * Disable PCMCIA buffers (isolate the interface)
3418 * and assert RESET signal
3419 */
3420 debug ("Disable PCMCIA buffers and assert RESET\n");
3421 reg = PCMCIA_PGCRX(_slot_);
3422 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
3423 PCMCIA_PGCRX(_slot_) = reg;
3424 udelay(500);
3425
3426 /*
3427 * Configure Port C pins for
3428 * 5 Volts Enable and 3 Volts enable,
3429 * Turn all power pins to Hi-Z
3430 */
3431 debug ("PCMCIA power OFF\n");
3432 cfg_ports (); /* Enables switch, but all in Hi-Z */
3433
3434 debug ("Enable PCMCIA buffers and stop RESET\n");
3435 reg = PCMCIA_PGCRX(_slot_);
3436 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
3437 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
3438 PCMCIA_PGCRX(_slot_) = reg;
3439 udelay(500);
3440
3441 debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
3442 slot+'A');
3443 return (0);
3444}
3445
3446static void cfg_ports (void)
3447{
3448 volatile immap_t *immap;
3449
3450 immap = (immap_t *)CFG_IMMR;
3451
3452 /*
3453 * Configure Port A for MAX1602 PC-Card Power-Interface Switch
3454 */
3455 immap->im_ioport.iop_padat &= ~0x8000; /* set port x output to low */
3456 immap->im_ioport.iop_padir |= 0x8000; /* enable port x as output */
3457
3458 debug ("Set Port A: PAR: %08x DIR: %08x DAT: %08x\n",
3459 immap->im_ioport.iop_papar, immap->im_ioport.iop_padir,
3460 immap->im_ioport.iop_padat);
3461}
3462
3463#endif /* UC100 */
3464
3465
3466/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00003467
3468#endif /* CFG_CMD_PCMCIA || (CFG_CMD_IDE && CONFIG_IDE_8xx_PCCARD) */
wdenk8bde7f72003-06-27 21:31:46 +00003469
3470/**************************************************/
3471
3472#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
wdenk0d498392003-07-01 21:06:45 +00003473U_BOOT_CMD(
3474 pinit, 2, 1, do_pinit,
wdenk8bde7f72003-06-27 21:31:46 +00003475 "pinit - PCMCIA sub-system\n",
3476 "on - power on PCMCIA socket\n"
3477 "pinit off - power off PCMCIA socket\n"
3478);
3479#endif