blob: 8e3e84bed9b57076108e400877f59fb19591b490 [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;
Wolfgang Denk65165252006-05-15 13:52:51 +02001038 volatile sysconf8xx_t *sysp =
1039 (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
Wolfgang Denk8cba0902006-05-12 16:15:46 +02001040 unsigned int reg, mask;
1041
1042 debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1043
1044 udelay(10000);
1045
Wolfgang Denk65165252006-05-15 13:52:51 +02001046 /*
1047 * Configure SIUMCR to enable PCMCIA port B
1048 */
1049 sysp->sc_siumcr &= ~SIUMCR_DBGC11; /* set DBGC to 00 */
1050
Wolfgang Denk8cba0902006-05-12 16:15:46 +02001051 /* clear interrupt state, and disable interrupts */
1052 pcmp->pcmc_pscr = PCMCIA_MASK(slot);
1053 pcmp->pcmc_per &= ~PCMCIA_MASK(slot);
1054
1055 /*
1056 * Disable interrupts, DMA, and PCMCIA buffers
1057 * (isolate the interface) and assert RESET signal
1058 */
1059 debug ("Disable PCMCIA buffers and assert RESET\n");
1060 reg = __MY_PCMCIA_GCRX_CXRESET; /* active high */
1061 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
1062
1063 PCMCIA_PGCRX(slot) = reg;
1064 udelay(500);
1065
1066 /* remove all power */
1067 *powerctl = 0;
1068
1069 /*
1070 * Make sure there is a card in the slot, then configure the interface.
1071 */
1072 udelay(10000);
1073 debug ("[%d] %s: PIPR(%p)=0x%x\n", __LINE__,__FUNCTION__,
1074 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
1075
1076 if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
1077 printf (" No Card found\n");
1078 return (1);
1079 }
1080
1081 /*
1082 * Power On.
1083 */
1084 mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
1085 reg = pcmp->pcmc_pipr;
1086 debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n", reg,
1087 (reg&PCMCIA_VS1(slot))?"n":"ff",
1088 (reg&PCMCIA_VS2(slot))?"n":"ff");
1089
1090 if ((reg & mask) == mask) {
1091 *powerctl = 2; /* Enable 5V Vccout */
1092 puts (" 5.0V card found: ");
1093 } else {
1094 *powerctl = 1; /* Enable 3.3 V Vccout */
1095 puts (" 3.3V card found: ");
1096 }
1097
1098 udelay(1000);
1099 debug ("Enable PCMCIA buffers and stop RESET\n");
1100 reg = PCMCIA_PGCRX(slot);
1101 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
1102 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
1103
1104 PCMCIA_PGCRX(slot) = reg;
1105
1106 udelay(250000); /* some cards need >150 ms to come up :-( */
1107
1108 debug ("# hardware_enable done\n");
1109
1110 return (0);
1111}
1112
1113#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
1114static int hardware_disable(int slot)
1115{
1116 volatile unsigned char *powerctl =
1117 (volatile unsigned char *)PCMCIA_CTRL;
1118 unsigned long reg;
1119
1120 debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1121
1122 /* remove all power */
1123 *powerctl = 0;
1124
1125 debug ("Disable PCMCIA buffers and assert RESET\n");
1126 reg = __MY_PCMCIA_GCRX_CXRESET; /* active high */
1127 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
1128
1129 PCMCIA_PGCRX(slot) = reg;
1130
1131 udelay(10000);
1132
1133 return (0);
1134}
1135#endif
1136
1137static int voltage_set(int slot, int vcc, int vpp)
1138{
Wolfgang Denk319b9a52006-05-12 16:32:32 +02001139#ifdef DEBUG
Wolfgang Denk8cba0902006-05-12 16:15:46 +02001140 volatile pcmconf8xx_t *pcmp =
1141 (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
Wolfgang Denk319b9a52006-05-12 16:32:32 +02001142#endif
Wolfgang Denk8cba0902006-05-12 16:15:46 +02001143 volatile unsigned char *powerctl =
1144 (volatile unsigned char *)PCMCIA_CTRL;
1145 unsigned long reg;
1146
1147 debug ("voltage_set: " PCMCIA_BOARD_MSG
1148 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
1149 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
1150
1151 /*
1152 * Disable PCMCIA buffers (isolate the interface)
1153 * and assert RESET signal
1154 */
1155 debug ("Disable PCMCIA buffers and assert RESET\n");
1156 reg = PCMCIA_PGCRX(slot);
1157 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1158 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
1159
1160 PCMCIA_PGCRX(slot) = reg;
1161 udelay(500);
1162
1163 /*
1164 * Configure pins for 5 Volts Enable and 3 Volts enable,
1165 * Turn off all power.
1166 */
1167 debug ("PCMCIA power OFF\n");
1168 reg = 0;
1169 switch(vcc) {
1170 case 0: break;
1171 case 33: reg = 0x0001; break;
1172 case 50: reg = 0x0002; break;
1173 default: goto done;
1174 }
1175
1176 /* Checking supported voltages */
1177
1178 debug ("PIPR: 0x%x --> %s\n", pcmp->pcmc_pipr,
1179 (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
1180
1181 *powerctl = reg;
1182
1183 if (reg) {
1184 debug ("PCMCIA powered at %sV\n", (reg&0x0004) ? "5.0" : "3.3");
1185 } else {
1186 debug ("PCMCIA powered down\n");
1187 }
1188
1189done:
1190 debug ("Enable PCMCIA buffers and stop RESET\n");
1191 reg = PCMCIA_PGCRX(slot);
1192 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
1193 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
1194
1195 PCMCIA_PGCRX(slot) = reg;
1196 udelay(500);
1197
1198 debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n", slot+'A');
1199 return (0);
1200}
1201#endif /* CONFIG_VIRTLAB2 */
wdenkc6097192002-11-03 00:24:07 +00001202
wdenk1f53a412002-12-04 23:39:58 +00001203/* -------------------------------------------------------------------- */
1204/* LWMON Board */
1205/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00001206
1207#if defined(CONFIG_LWMON)
1208
1209#define PCMCIA_BOARD_MSG "LWMON"
1210
1211/* #define's for MAX1604 Power Switch */
1212#define MAX1604_OP_SUS 0x80
1213#define MAX1604_VCCBON 0x40
1214#define MAX1604_VCC_35 0x20
1215#define MAX1604_VCCBHIZ 0x10
1216#define MAX1604_VPPBON 0x08
1217#define MAX1604_VPPBPBPGM 0x04
1218#define MAX1604_VPPBHIZ 0x02
1219/* reserved 0x01 */
1220
1221static int hardware_enable(int slot)
1222{
1223 volatile immap_t *immap;
1224 volatile cpm8xx_t *cp;
1225 volatile pcmconf8xx_t *pcmp;
1226 volatile sysconf8xx_t *sysp;
1227 uint reg, mask;
1228 uchar val;
1229
1230
1231 debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1232
1233 /* Switch on PCMCIA port in PIC register 0x60 */
1234 reg = pic_read (0x60);
1235 debug ("[%d] PIC read: reg_60 = 0x%02x\n", __LINE__, reg);
1236 reg &= ~0x10;
wdenk1f53a412002-12-04 23:39:58 +00001237 /* reg |= 0x08; Vpp not needed */
wdenkc6097192002-11-03 00:24:07 +00001238 pic_write (0x60, reg);
1239#ifdef DEBUG
1240 reg = pic_read (0x60);
1241 printf ("[%d] PIC read: reg_60 = 0x%02x\n", __LINE__, reg);
1242#endif
1243 udelay(10000);
1244
1245 immap = (immap_t *)CFG_IMMR;
1246 sysp = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
1247 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1248 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1249
1250 /*
1251 * Configure SIUMCR to enable PCMCIA port B
1252 * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
1253 */
1254 sysp->sc_siumcr &= ~SIUMCR_DBGC11; /* set DBGC to 00 */
1255
1256 /* clear interrupt state, and disable interrupts */
1257 pcmp->pcmc_pscr = PCMCIA_MASK(_slot_);
1258 pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
1259
wdenkc6097192002-11-03 00:24:07 +00001260 /*
wdenk1f53a412002-12-04 23:39:58 +00001261 * Disable interrupts, DMA, and PCMCIA buffers
1262 * (isolate the interface) and assert RESET signal
wdenkc6097192002-11-03 00:24:07 +00001263 */
1264 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00001265 reg = 0;
1266 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1267 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkc6097192002-11-03 00:24:07 +00001268 PCMCIA_PGCRX(_slot_) = reg;
1269 udelay(500);
1270
1271 /*
1272 * Make sure there is a card in the slot, then configure the interface.
1273 */
1274 udelay(10000);
1275 debug ("[%d] %s: PIPR(%p)=0x%x\n",
1276 __LINE__,__FUNCTION__,
1277 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
wdenkea909b72002-11-21 23:11:29 +00001278 if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
wdenkc6097192002-11-03 00:24:07 +00001279 printf (" No Card found\n");
1280 return (1);
1281 }
1282
1283 /*
1284 * Power On.
1285 */
1286 mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
1287 reg = pcmp->pcmc_pipr;
1288 debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
1289 reg,
1290 (reg&PCMCIA_VS1(slot))?"n":"ff",
1291 (reg&PCMCIA_VS2(slot))?"n":"ff");
1292 if ((reg & mask) == mask) {
1293 val = 0; /* VCCB3/5 = 0 ==> use Vx = 5.0 V */
1294 puts (" 5.0V card found: ");
1295 } else {
1296 val = MAX1604_VCC_35; /* VCCB3/5 = 1 ==> use Vy = 3.3 V */
1297 puts (" 3.3V card found: ");
1298 }
1299
1300 /* switch VCC on */
wdenk1f53a412002-12-04 23:39:58 +00001301 val |= MAX1604_OP_SUS | MAX1604_VCCBON;
wdenkc6097192002-11-03 00:24:07 +00001302 i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE);
1303 i2c_write (CFG_I2C_POWER_A_ADDR, 0, 0, &val, 1);
1304
1305 udelay(500000);
1306
1307 debug ("Enable PCMCIA buffers and stop RESET\n");
1308 reg = PCMCIA_PGCRX(_slot_);
1309 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
1310 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
1311 PCMCIA_PGCRX(_slot_) = reg;
1312
1313 udelay(250000); /* some cards need >150 ms to come up :-( */
1314
1315 debug ("# hardware_enable done\n");
1316
1317 return (0);
1318}
1319
1320
wdenkc6097192002-11-03 00:24:07 +00001321#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
1322static int hardware_disable(int slot)
1323{
1324 volatile immap_t *immap;
1325 volatile pcmconf8xx_t *pcmp;
1326 u_long reg;
1327 uchar val;
1328
1329 debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1330
1331 immap = (immap_t *)CFG_IMMR;
1332 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1333
1334 /* remove all power, put output in high impedance state */
1335 val = MAX1604_VCCBHIZ | MAX1604_VPPBHIZ;
1336 i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE);
1337 i2c_write (CFG_I2C_POWER_A_ADDR, 0, 0, &val, 1);
1338
1339 /* Configure PCMCIA General Control Register */
wdenkc6097192002-11-03 00:24:07 +00001340 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00001341 reg = 0;
wdenkc6097192002-11-03 00:24:07 +00001342 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1343 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
1344 PCMCIA_PGCRX(_slot_) = reg;
1345
1346 /* Switch off PCMCIA port in PIC register 0x60 */
1347 reg = pic_read (0x60);
1348 debug ("[%d] PIC read: reg_60 = 0x%02x\n", __LINE__, reg);
1349 reg |= 0x10;
1350 reg &= ~0x08;
1351 pic_write (0x60, reg);
1352#ifdef DEBUG
1353 reg = pic_read (0x60);
1354 printf ("[%d] PIC read: reg_60 = 0x%02x\n", __LINE__, reg);
1355#endif
1356 udelay(10000);
1357
1358 return (0);
1359}
1360#endif /* CFG_CMD_PCMCIA */
1361
1362
wdenkc6097192002-11-03 00:24:07 +00001363static int voltage_set(int slot, int vcc, int vpp)
1364{
1365 volatile immap_t *immap;
1366 volatile pcmconf8xx_t *pcmp;
1367 u_long reg;
1368 uchar val;
1369
1370 debug ("voltage_set: "
1371 PCMCIA_BOARD_MSG
1372 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
1373 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
1374
1375 immap = (immap_t *)CFG_IMMR;
1376 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1377 /*
1378 * Disable PCMCIA buffers (isolate the interface)
1379 * and assert RESET signal
1380 */
1381 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00001382 reg = PCMCIA_PGCRX(_slot_);
1383 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1384 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkc6097192002-11-03 00:24:07 +00001385 PCMCIA_PGCRX(_slot_) = reg;
1386 udelay(500);
1387
1388 /*
1389 * Turn off all power (switch to high impedance)
1390 */
1391 debug ("PCMCIA power OFF\n");
1392 val = MAX1604_VCCBHIZ | MAX1604_VPPBHIZ;
1393 i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE);
1394 i2c_write (CFG_I2C_POWER_A_ADDR, 0, 0, &val, 1);
1395
1396 val = 0;
1397 switch(vcc) {
1398 case 0: break;
1399 case 33: val = MAX1604_VCC_35; break;
1400 case 50: break;
1401 default: goto done;
1402 }
1403
1404 /* Checking supported voltages */
1405
1406 debug ("PIPR: 0x%x --> %s\n",
1407 pcmp->pcmc_pipr,
1408 (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
1409
1410 i2c_write (CFG_I2C_POWER_A_ADDR, 0, 0, &val, 1);
1411 if (val) {
1412 debug ("PCMCIA powered at %sV\n",
1413 (val & MAX1604_VCC_35) ? "3.3" : "5.0");
1414 } else {
1415 debug ("PCMCIA powered down\n");
1416 }
1417
1418done:
1419 debug ("Enable PCMCIA buffers and stop RESET\n");
1420 reg = PCMCIA_PGCRX(_slot_);
1421 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
1422 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
1423 PCMCIA_PGCRX(_slot_) = reg;
1424 udelay(500);
1425
1426 debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
1427 slot+'A');
1428 return (0);
1429}
1430
1431#endif /* LWMON */
1432
wdenk1f53a412002-12-04 23:39:58 +00001433/* -------------------------------------------------------------------- */
1434/* GTH board by Corelatus AB */
1435/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00001436#if defined(CONFIG_GTH)
1437
1438#define PCMCIA_BOARD_MSG "GTH COMPACT FLASH"
1439
wdenk1f53a412002-12-04 23:39:58 +00001440static int voltage_set (int slot, int vcc, int vpp)
1441{ /* Do nothing */
1442 return 0;
wdenkc6097192002-11-03 00:24:07 +00001443}
1444
1445static int hardware_enable (int slot)
1446{
wdenk1f53a412002-12-04 23:39:58 +00001447 volatile immap_t *immap;
1448 volatile cpm8xx_t *cp;
1449 volatile pcmconf8xx_t *pcmp;
1450 volatile sysconf8xx_t *sysp;
1451 uint reg, mask;
wdenkc6097192002-11-03 00:24:07 +00001452
wdenk1f53a412002-12-04 23:39:58 +00001453 debug ("hardware_enable: GTH Slot %c\n", 'A' + slot);
wdenkc6097192002-11-03 00:24:07 +00001454
wdenk1f53a412002-12-04 23:39:58 +00001455 immap = (immap_t *) CFG_IMMR;
1456 sysp = (sysconf8xx_t *) (&(((immap_t *) CFG_IMMR)->im_siu_conf));
1457 pcmp = (pcmconf8xx_t *) (&(((immap_t *) CFG_IMMR)->im_pcmcia));
1458 cp = (cpm8xx_t *) (&(((immap_t *) CFG_IMMR)->im_cpm));
wdenkc6097192002-11-03 00:24:07 +00001459
wdenk1f53a412002-12-04 23:39:58 +00001460 /* clear interrupt state, and disable interrupts */
1461 pcmp->pcmc_pscr = PCMCIA_MASK (_slot_);
1462 pcmp->pcmc_per &= ~PCMCIA_MASK (_slot_);
wdenkc6097192002-11-03 00:24:07 +00001463
wdenk1f53a412002-12-04 23:39:58 +00001464 /*
1465 * Disable interrupts, DMA, and PCMCIA buffers
1466 * (isolate the interface) and assert RESET signal
1467 */
1468 debug ("Disable PCMCIA buffers and assert RESET\n");
1469 reg = 0;
1470 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1471 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
1472 PCMCIA_PGCRX (_slot_) = reg;
1473 udelay (500);
wdenkc6097192002-11-03 00:24:07 +00001474
wdenk1f53a412002-12-04 23:39:58 +00001475 /*
1476 * Make sure there is a card in the slot,
1477 * then configure the interface.
1478 */
1479 udelay (10000);
1480 debug ("[%d] %s: PIPR(%p)=0x%x\n",
1481 __LINE__, __FUNCTION__,
1482 &(pcmp->pcmc_pipr), pcmp->pcmc_pipr);
1483 if (pcmp->pcmc_pipr & 0x98000000) {
1484 printf (" No Card found\n");
1485 return (1);
1486 }
wdenkc6097192002-11-03 00:24:07 +00001487
wdenk1f53a412002-12-04 23:39:58 +00001488 mask = PCMCIA_VS1 (slot) | PCMCIA_VS2 (slot);
1489 reg = pcmp->pcmc_pipr;
1490 debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
1491 reg,
1492 (reg & PCMCIA_VS1 (slot)) ? "n" : "ff",
1493 (reg & PCMCIA_VS2 (slot)) ? "n" : "ff");
wdenkc6097192002-11-03 00:24:07 +00001494
wdenk1f53a412002-12-04 23:39:58 +00001495 debug ("Enable PCMCIA buffers and stop RESET\n");
1496 reg = PCMCIA_PGCRX (_slot_);
1497 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
1498 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
1499 PCMCIA_PGCRX (_slot_) = reg;
wdenkc6097192002-11-03 00:24:07 +00001500
wdenk1f53a412002-12-04 23:39:58 +00001501 udelay (250000); /* some cards need >150 ms to come up :-( */
wdenkc6097192002-11-03 00:24:07 +00001502
wdenk1f53a412002-12-04 23:39:58 +00001503 debug ("# hardware_enable done\n");
wdenkc6097192002-11-03 00:24:07 +00001504
wdenk1f53a412002-12-04 23:39:58 +00001505 return 0;
wdenkc6097192002-11-03 00:24:07 +00001506}
1507#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
1508static int hardware_disable(int slot)
1509{
1510 return 0; /* No hardware to disable */
1511}
1512#endif /* CFG_CMD_PCMCIA */
1513#endif /* CONFIG_GTH */
1514
wdenk1f53a412002-12-04 23:39:58 +00001515/* -------------------------------------------------------------------- */
1516/* ICU862 Boards by Cambridge Broadband Ltd. */
1517/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00001518
1519#if defined(CONFIG_ICU862)
1520
1521#define PCMCIA_BOARD_MSG "ICU862"
1522
1523static void cfg_port_B (void);
1524
1525static int hardware_enable(int slot)
1526{
1527 volatile immap_t *immap;
1528 volatile cpm8xx_t *cp;
1529 volatile pcmconf8xx_t *pcmp;
1530 volatile sysconf8xx_t *sysp;
1531 uint reg, pipr, mask;
1532 int i;
1533
1534 debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1535
1536 udelay(10000);
1537
1538 immap = (immap_t *)CFG_IMMR;
1539 sysp = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
1540 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1541 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1542
1543 /* Configure Port B for TPS2205 PC-Card Power-Interface Switch */
1544 cfg_port_B ();
1545
1546 /*
1547 * Configure SIUMCR to enable PCMCIA port B
1548 * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
1549 */
1550 sysp->sc_siumcr &= ~SIUMCR_DBGC11; /* set DBGC to 00 */
1551
1552 /* clear interrupt state, and disable interrupts */
1553 pcmp->pcmc_pscr = PCMCIA_MASK(_slot_);
1554 pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
1555
wdenkc6097192002-11-03 00:24:07 +00001556 /*
wdenk1f53a412002-12-04 23:39:58 +00001557 * Disable interrupts, DMA, and PCMCIA buffers
1558 * (isolate the interface) and assert RESET signal
wdenkc6097192002-11-03 00:24:07 +00001559 */
1560 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00001561 reg = 0;
1562 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1563 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkc6097192002-11-03 00:24:07 +00001564 PCMCIA_PGCRX(_slot_) = reg;
1565 udelay(500);
1566
1567 /*
1568 * Make sure there is a card in the slot, then configure the interface.
1569 */
1570 udelay(10000);
1571 debug ("[%d] %s: PIPR(%p)=0x%x\n",
1572 __LINE__,__FUNCTION__,
1573 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
wdenkea909b72002-11-21 23:11:29 +00001574 if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
wdenkc6097192002-11-03 00:24:07 +00001575 printf (" No Card found\n");
1576 return (1);
1577 }
1578
1579 /*
1580 * Power On: Set VAVCC to 3.3V or 5V, set VAVPP to Hi-Z
1581 */
1582 mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
1583 pipr = pcmp->pcmc_pipr;
1584 debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
1585 pipr,
1586 (reg&PCMCIA_VS1(slot))?"n":"ff",
1587 (reg&PCMCIA_VS2(slot))?"n":"ff");
1588
1589 reg = cp->cp_pbdat;
1590 if ((pipr & mask) == mask) {
wdenk1f53a412002-12-04 23:39:58 +00001591 reg |= (TPS2205_VPP_PGM | TPS2205_VPP_VCC | /* VAVPP => Hi-Z */
1592 TPS2205_VCC3); /* 3V off */
wdenkc6097192002-11-03 00:24:07 +00001593 reg &= ~(TPS2205_VCC5); /* 5V on */
1594 puts (" 5.0V card found: ");
1595 } else {
wdenk1f53a412002-12-04 23:39:58 +00001596 reg |= (TPS2205_VPP_PGM | TPS2205_VPP_VCC | /* VAVPP => Hi-Z */
1597 TPS2205_VCC5); /* 5V off */
wdenkc6097192002-11-03 00:24:07 +00001598 reg &= ~(TPS2205_VCC3); /* 3V on */
1599 puts (" 3.3V card found: ");
1600 }
1601
1602 debug ("\nPB DAT: %08x -> 3.3V %s 5.0V %s VPP_PGM %s VPP_VCC %s\n",
1603 reg,
1604 (reg & TPS2205_VCC3) ? "off" : "on",
1605 (reg & TPS2205_VCC5) ? "off" : "on",
1606 (reg & TPS2205_VPP_PGM) ? "off" : "on",
1607 (reg & TPS2205_VPP_VCC) ? "off" : "on" );
1608
1609 cp->cp_pbdat = reg;
1610
1611 /* Wait 500 ms; use this to check for over-current */
1612 for (i=0; i<5000; ++i) {
1613 if ((cp->cp_pbdat & TPS2205_OC) == 0) {
1614 printf (" *** Overcurrent - Safety shutdown ***\n");
1615 cp->cp_pbdat &= ~(TPS2205_SHDN);
1616 return (1);
1617 }
1618 udelay (100);
1619 }
1620
1621 debug ("Enable PCMCIA buffers and stop RESET\n");
1622 reg = PCMCIA_PGCRX(_slot_);
1623 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
1624 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
1625 PCMCIA_PGCRX(_slot_) = reg;
1626
1627 udelay(250000); /* some cards need >150 ms to come up :-( */
1628
1629 debug ("# hardware_enable done\n");
1630
1631 return (0);
1632}
1633
1634
wdenkc6097192002-11-03 00:24:07 +00001635#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
1636static int hardware_disable(int slot)
1637{
1638 volatile immap_t *immap;
1639 volatile cpm8xx_t *cp;
1640 volatile pcmconf8xx_t *pcmp;
1641 u_long reg;
1642
1643 debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1644
1645 immap = (immap_t *)CFG_IMMR;
1646 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1647 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1648
1649 /* Shut down */
1650 cp->cp_pbdat &= ~(TPS2205_SHDN);
1651
1652 /* Configure PCMCIA General Control Register */
wdenkc6097192002-11-03 00:24:07 +00001653 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00001654 reg = 0;
wdenkc6097192002-11-03 00:24:07 +00001655 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1656 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
1657 PCMCIA_PGCRX(_slot_) = reg;
1658
1659 udelay(10000);
1660
1661 return (0);
1662}
1663#endif /* CFG_CMD_PCMCIA */
1664
1665
wdenkc6097192002-11-03 00:24:07 +00001666static int voltage_set(int slot, int vcc, int vpp)
1667{
1668 volatile immap_t *immap;
1669 volatile cpm8xx_t *cp;
1670 volatile pcmconf8xx_t *pcmp;
1671 u_long reg;
1672
1673 debug ("voltage_set: "
1674 PCMCIA_BOARD_MSG
1675 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
1676 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
1677
1678 immap = (immap_t *)CFG_IMMR;
1679 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1680 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1681 /*
1682 * Disable PCMCIA buffers (isolate the interface)
1683 * and assert RESET signal
1684 */
1685 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00001686 reg = PCMCIA_PGCRX(_slot_);
1687 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1688 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkc6097192002-11-03 00:24:07 +00001689 PCMCIA_PGCRX(_slot_) = reg;
1690 udelay(500);
1691
1692 /*
1693 * Configure Port C pins for
1694 * 5 Volts Enable and 3 Volts enable,
1695 * Turn all power pins to Hi-Z
1696 */
1697 debug ("PCMCIA power OFF\n");
1698 cfg_port_B (); /* Enables switch, but all in Hi-Z */
1699
1700 reg = cp->cp_pbdat;
1701
1702 switch(vcc) {
1703 case 0: break; /* Switch off */
1704 case 33: reg &= ~TPS2205_VCC3; break; /* Switch on 3.3V */
1705 case 50: reg &= ~TPS2205_VCC5; break; /* Switch on 5.0V */
1706 default: goto done;
1707 }
1708
1709 /* Checking supported voltages */
1710
1711 debug ("PIPR: 0x%x --> %s\n",
1712 pcmp->pcmc_pipr,
1713 (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
1714
1715 cp->cp_pbdat = reg;
1716
1717#ifdef DEBUG
1718 {
1719 char *s;
1720
1721 if ((reg & TPS2205_VCC3) == 0) {
1722 s = "at 3.3V";
1723 } else if ((reg & TPS2205_VCC5) == 0) {
1724 s = "at 5.0V";
1725 } else {
1726 s = "down";
1727 }
1728 printf ("PCMCIA powered %s\n", s);
1729 }
1730#endif
1731
1732done:
1733 debug ("Enable PCMCIA buffers and stop RESET\n");
1734 reg = PCMCIA_PGCRX(_slot_);
1735 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
1736 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
1737 PCMCIA_PGCRX(_slot_) = reg;
1738 udelay(500);
1739
1740 debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
1741 slot+'A');
1742 return (0);
1743}
1744
1745static void cfg_port_B (void)
1746{
1747 volatile immap_t *immap;
1748 volatile cpm8xx_t *cp;
1749 uint reg;
1750
1751 immap = (immap_t *)CFG_IMMR;
1752 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1753
1754 /*
1755 * Configure Port B for TPS2205 PC-Card Power-Interface Switch
1756 *
1757 * Switch off all voltages, assert shutdown
1758 */
1759 reg = cp->cp_pbdat;
wdenk1f53a412002-12-04 23:39:58 +00001760 reg |= (TPS2205_VPP_PGM | TPS2205_VPP_VCC | /* VAVPP => Hi-Z */
1761 TPS2205_VCC3 | TPS2205_VCC5 | /* VAVCC => Hi-Z */
1762 TPS2205_SHDN); /* enable switch */
wdenkc6097192002-11-03 00:24:07 +00001763 cp->cp_pbdat = reg;
1764
1765 cp->cp_pbpar &= ~(TPS2205_INPUTS | TPS2205_OUTPUTS);
1766
1767 reg = cp->cp_pbdir & ~(TPS2205_INPUTS);
1768 cp->cp_pbdir = reg | TPS2205_OUTPUTS;
1769
1770 debug ("Set Port B: PAR: %08x DIR: %08x DAT: %08x\n",
1771 cp->cp_pbpar, cp->cp_pbdir, cp->cp_pbdat);
1772}
1773
1774#endif /* ICU862 */
1775
1776
wdenk1f53a412002-12-04 23:39:58 +00001777/* -------------------------------------------------------------------- */
1778/* C2MON Boards by TTTech Computertechnik AG */
1779/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00001780
1781#if defined(CONFIG_C2MON)
1782
1783#define PCMCIA_BOARD_MSG "C2MON"
1784
1785static void cfg_ports (void);
1786
1787static int hardware_enable(int slot)
1788{
1789 volatile immap_t *immap;
1790 volatile cpm8xx_t *cp;
1791 volatile pcmconf8xx_t *pcmp;
1792 volatile sysconf8xx_t *sysp;
1793 uint reg, pipr, mask;
1794 ushort sreg;
1795 int i;
1796
1797 debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1798
1799 udelay(10000);
1800
1801 immap = (immap_t *)CFG_IMMR;
1802 sysp = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
1803 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1804 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1805
1806 /* Configure Ports for TPS2211A PC-Card Power-Interface Switch */
1807 cfg_ports ();
1808
1809 /*
1810 * Configure SIUMCR to enable PCMCIA port B
1811 * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
1812 */
1813 sysp->sc_siumcr &= ~SIUMCR_DBGC11; /* set DBGC to 00 */
1814
1815 /* clear interrupt state, and disable interrupts */
1816 pcmp->pcmc_pscr = PCMCIA_MASK(_slot_);
1817 pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
1818
wdenkc6097192002-11-03 00:24:07 +00001819 /*
wdenk1f53a412002-12-04 23:39:58 +00001820 * Disable interrupts, DMA, and PCMCIA buffers
1821 * (isolate the interface) and assert RESET signal
wdenkc6097192002-11-03 00:24:07 +00001822 */
1823 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00001824 reg = 0;
1825 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1826 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkc6097192002-11-03 00:24:07 +00001827 PCMCIA_PGCRX(_slot_) = reg;
1828 udelay(500);
1829
1830 /*
1831 * Make sure there is a card in the slot, then configure the interface.
1832 */
1833 udelay(10000);
1834 debug ("[%d] %s: PIPR(%p)=0x%x\n",
1835 __LINE__,__FUNCTION__,
1836 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
wdenkea909b72002-11-21 23:11:29 +00001837 if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
wdenkc6097192002-11-03 00:24:07 +00001838 printf (" No Card found\n");
1839 return (1);
1840 }
1841
1842 /*
1843 * Power On: Set VAVCC to 3.3V or 5V, set VAVPP to Hi-Z
1844 */
1845 mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
1846 pipr = pcmp->pcmc_pipr;
1847 debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
1848 pipr,
1849 (reg&PCMCIA_VS1(slot))?"n":"ff",
1850 (reg&PCMCIA_VS2(slot))?"n":"ff");
1851
1852 sreg = immap->im_ioport.iop_pcdat;
1853 if ((pipr & mask) == mask) {
1854 sreg |= (TPS2211_VPPD0 | TPS2211_VPPD1 | /* VAVPP => Hi-Z */
1855 TPS2211_VCCD1); /* 5V on */
1856 sreg &= ~(TPS2211_VCCD0); /* 3V off */
1857 puts (" 5.0V card found: ");
1858 } else {
1859 sreg |= (TPS2211_VPPD0 | TPS2211_VPPD1 | /* VAVPP => Hi-Z */
1860 TPS2211_VCCD0); /* 3V on */
1861 sreg &= ~(TPS2211_VCCD1); /* 5V off */
1862 puts (" 3.3V card found: ");
1863 }
1864
1865 debug ("\nPC DAT: %04x -> 3.3V %s 5.0V %s\n",
1866 sreg,
1867 ( (sreg & TPS2211_VCCD0) && !(sreg & TPS2211_VCCD1)) ? "on" : "off",
1868 (!(sreg & TPS2211_VCCD0) && (sreg & TPS2211_VCCD1)) ? "on" : "off"
1869 );
1870
1871 immap->im_ioport.iop_pcdat = sreg;
1872
1873 /* Wait 500 ms; use this to check for over-current */
1874 for (i=0; i<5000; ++i) {
1875 if ((cp->cp_pbdat & TPS2211_OC) == 0) {
1876 printf (" *** Overcurrent - Safety shutdown ***\n");
1877 immap->im_ioport.iop_pcdat &= ~(TPS2211_VCCD0|TPS2211_VCCD1);
1878 return (1);
1879 }
1880 udelay (100);
1881 }
1882
1883 debug ("Enable PCMCIA buffers and stop RESET\n");
1884 reg = PCMCIA_PGCRX(_slot_);
1885 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
1886 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
1887 PCMCIA_PGCRX(_slot_) = reg;
1888
1889 udelay(250000); /* some cards need >150 ms to come up :-( */
1890
1891 debug ("# hardware_enable done\n");
1892
1893 return (0);
1894}
1895
1896
wdenkc6097192002-11-03 00:24:07 +00001897#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
1898static int hardware_disable(int slot)
1899{
1900 volatile immap_t *immap;
1901 volatile cpm8xx_t *cp;
1902 volatile pcmconf8xx_t *pcmp;
1903 u_long reg;
1904
1905 debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1906
1907 immap = (immap_t *)CFG_IMMR;
1908 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1909
1910 /* Configure PCMCIA General Control Register */
wdenkc6097192002-11-03 00:24:07 +00001911 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00001912 reg = 0;
wdenkc6097192002-11-03 00:24:07 +00001913 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1914 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
1915 PCMCIA_PGCRX(_slot_) = reg;
1916
1917 /* ALl voltages off / Hi-Z */
1918 immap->im_ioport.iop_pcdat |= (TPS2211_VPPD0 | TPS2211_VPPD1 |
1919 TPS2211_VCCD0 | TPS2211_VCCD1 );
1920
1921 udelay(10000);
1922
1923 return (0);
1924}
1925#endif /* CFG_CMD_PCMCIA */
1926
1927
wdenkc6097192002-11-03 00:24:07 +00001928static int voltage_set(int slot, int vcc, int vpp)
1929{
1930 volatile immap_t *immap;
1931 volatile cpm8xx_t *cp;
1932 volatile pcmconf8xx_t *pcmp;
1933 u_long reg;
1934 ushort sreg;
1935
1936 debug ("voltage_set: "
1937 PCMCIA_BOARD_MSG
1938 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
1939 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
1940
1941 immap = (immap_t *)CFG_IMMR;
1942 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1943 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1944 /*
1945 * Disable PCMCIA buffers (isolate the interface)
1946 * and assert RESET signal
1947 */
1948 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00001949 reg = PCMCIA_PGCRX(_slot_);
1950 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1951 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkc6097192002-11-03 00:24:07 +00001952 PCMCIA_PGCRX(_slot_) = reg;
1953 udelay(500);
1954
1955 /*
1956 * Configure Port C pins for
1957 * 5 Volts Enable and 3 Volts enable,
1958 * Turn all power pins to Hi-Z
1959 */
1960 debug ("PCMCIA power OFF\n");
1961 cfg_ports (); /* Enables switch, but all in Hi-Z */
1962
1963 sreg = immap->im_ioport.iop_pcdat;
1964 sreg |= TPS2211_VPPD0 | TPS2211_VPPD1; /* VAVPP always Hi-Z */
1965
1966 switch(vcc) {
1967 case 0: break; /* Switch off */
1968 case 33: sreg |= TPS2211_VCCD0; /* Switch on 3.3V */
1969 sreg &= ~TPS2211_VCCD1;
1970 break;
1971 case 50: sreg &= ~TPS2211_VCCD0; /* Switch on 5.0V */
1972 sreg |= TPS2211_VCCD1;
1973 break;
1974 default: goto done;
1975 }
1976
1977 /* Checking supported voltages */
1978
1979 debug ("PIPR: 0x%x --> %s\n",
1980 pcmp->pcmc_pipr,
1981 (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
1982
1983 immap->im_ioport.iop_pcdat = sreg;
1984
1985#ifdef DEBUG
1986 {
1987 char *s;
1988
1989 if ((sreg & TPS2211_VCCD0) && !(sreg & TPS2211_VCCD1)) {
1990 s = "at 3.3V";
1991 } else if (!(sreg & TPS2211_VCCD0) && (sreg & TPS2211_VCCD1)) {
1992 s = "at 5.0V";
1993 } else {
1994 s = "down";
1995 }
1996 printf ("PCMCIA powered %s\n", s);
1997 }
1998#endif
1999
2000done:
2001 debug ("Enable PCMCIA buffers and stop RESET\n");
2002 reg = PCMCIA_PGCRX(_slot_);
2003 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
2004 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
2005 PCMCIA_PGCRX(_slot_) = reg;
2006 udelay(500);
2007
2008 debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
2009 slot+'A');
2010 return (0);
2011}
2012
2013static void cfg_ports (void)
2014{
2015 volatile immap_t *immap;
2016 volatile cpm8xx_t *cp;
2017 ushort sreg;
2018
2019 immap = (immap_t *)CFG_IMMR;
2020 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
2021
2022 /*
2023 * Configure Port C for TPS2211 PC-Card Power-Interface Switch
2024 *
2025 * Switch off all voltages, assert shutdown
2026 */
2027 sreg = immap->im_ioport.iop_pcdat;
2028 sreg |= (TPS2211_VPPD0 | TPS2211_VPPD1); /* VAVPP => Hi-Z */
2029 sreg &= ~(TPS2211_VCCD0 | TPS2211_VCCD1); /* 3V and 5V off */
2030 immap->im_ioport.iop_pcdat = sreg;
2031
2032 immap->im_ioport.iop_pcpar &= ~(TPS2211_OUTPUTS);
2033 immap->im_ioport.iop_pcdir |= TPS2211_OUTPUTS;
2034
2035 debug ("Set Port C: PAR: %04x DIR: %04x DAT: %04x\n",
2036 immap->im_ioport.iop_pcpar,
2037 immap->im_ioport.iop_pcdir,
2038 immap->im_ioport.iop_pcdat);
2039
2040 /*
2041 * Configure Port B for TPS2211 PC-Card Power-Interface Switch
2042 *
2043 * Over-Current Input only
2044 */
2045 cp->cp_pbpar &= ~(TPS2211_INPUTS);
2046 cp->cp_pbdir &= ~(TPS2211_INPUTS);
2047
2048 debug ("Set Port B: PAR: %08x DIR: %08x DAT: %08x\n",
2049 cp->cp_pbpar, cp->cp_pbdir, cp->cp_pbdat);
2050}
2051
2052#endif /* C2MON */
2053
wdenk1f53a412002-12-04 23:39:58 +00002054/* -------------------------------------------------------------------- */
2055/* MBX board from Morotola */
2056/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00002057
2058#if defined( CONFIG_MBX )
2059#include <../board/mbx8xx/csr.h>
2060
2061/* A lot of this has been taken from the RPX code in this file it works from me.
2062 I have added the voltage selection for the MBX board. */
2063
2064/* MBX voltage bit in control register #2 */
2065#define CR2_VPP12 ((uchar)0x10)
2066#define CR2_VPPVDD ((uchar)0x20)
2067#define CR2_VDD5 ((uchar)0x40)
2068#define CR2_VDD3 ((uchar)0x80)
2069
2070#define PCMCIA_BOARD_MSG "MBX860"
2071
2072static int voltage_set (int slot, int vcc, int vpp)
2073{
2074 uchar reg = 0;
2075
2076 debug ("voltage_set: PCMCIA_BOARD_MSG Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
2077 'A' + slot, vcc / 10, vcc % 10, vpp / 10, vcc % 10);
2078
2079 switch (vcc) {
2080 case 0:
2081 break;
2082 case 33:
2083 reg |= CR2_VDD3;
2084 break;
2085 case 50:
2086 reg |= CR2_VDD5;
2087 break;
2088 default:
2089 return 1;
2090 }
2091
2092 switch (vpp) {
2093 case 0:
2094 break;
2095 case 33:
2096 case 50:
2097 if (vcc == vpp) {
2098 reg |= CR2_VPPVDD;
2099 } else {
2100 return 1;
2101 }
2102 break;
2103 case 120:
2104 reg |= CR2_VPP12;
2105 break;
2106 default:
2107 return 1;
2108 }
2109
2110 /* first, turn off all power */
2111 MBX_CSR2 &= ~(CR2_VDDSEL | CR2_VPPSEL);
2112
2113 /* enable new powersettings */
2114 MBX_CSR2 |= reg;
2115 debug ("MBX_CSR2 read = 0x%02x\n", MBX_CSR2);
2116
2117 return (0);
2118}
2119
2120static int hardware_enable (int slot)
2121{
2122 volatile immap_t *immap;
2123 volatile cpm8xx_t *cp;
2124 volatile pcmconf8xx_t *pcmp;
2125 volatile sysconf8xx_t *sysp;
2126 uint reg, mask;
2127
2128 debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n",
2129 'A' + slot);
2130
2131 udelay (10000);
2132
2133 immap = (immap_t *) CFG_IMMR;
2134 sysp = (sysconf8xx_t *) (&(((immap_t *) CFG_IMMR)->im_siu_conf));
2135 pcmp = (pcmconf8xx_t *) (&(((immap_t *) CFG_IMMR)->im_pcmcia));
2136 cp = (cpm8xx_t *) (&(((immap_t *) CFG_IMMR)->im_cpm));
2137
2138 /* clear interrupt state, and disable interrupts */
2139 pcmp->pcmc_pscr = PCMCIA_MASK (_slot_);
2140 pcmp->pcmc_per &= ~PCMCIA_MASK (_slot_);
2141
wdenkc6097192002-11-03 00:24:07 +00002142 /*
wdenk1f53a412002-12-04 23:39:58 +00002143 * Disable interrupts, DMA, and PCMCIA buffers
2144 * (isolate the interface) and assert RESET signal
wdenkc6097192002-11-03 00:24:07 +00002145 */
2146 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00002147 reg = 0;
wdenkc6097192002-11-03 00:24:07 +00002148 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
2149 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
2150 PCMCIA_PGCRX (_slot_) = reg;
2151 udelay (500);
2152
2153 /* remove all power */
2154 voltage_set (slot, 0, 0);
2155 /*
2156 * Make sure there is a card in the slot, then configure the interface.
2157 */
wdenkea909b72002-11-21 23:11:29 +00002158 udelay(10000);
2159 debug ("[%d] %s: PIPR(%p)=0x%x\n",
2160 __LINE__,__FUNCTION__,
2161 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
wdenkc40b2952004-03-13 23:29:43 +00002162#ifndef CONFIG_HMI10
wdenkea909b72002-11-21 23:11:29 +00002163 if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
wdenka522fa02004-01-04 22:51:12 +00002164#else
2165 if (pcmp->pcmc_pipr & (0x10000000 >> (slot << 4))) {
wdenkc40b2952004-03-13 23:29:43 +00002166#endif /* CONFIG_HMI10 */
wdenkc6097192002-11-03 00:24:07 +00002167 printf (" No Card found\n");
2168 return (1);
2169 }
2170
2171 /*
2172 * Power On.
2173 */
2174 mask = PCMCIA_VS1 (_slot_) | PCMCIA_VS2 (_slot_);
2175 reg = pcmp->pcmc_pipr;
2176 debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n", reg,
2177 (reg & PCMCIA_VS1 (slot)) ? "n" : "ff",
2178 (reg & PCMCIA_VS2 (slot)) ? "n" : "ff");
2179
2180 if ((reg & mask) == mask) {
2181 voltage_set (_slot_, 50, 0);
2182 printf (" 5.0V card found: ");
2183 } else {
2184 voltage_set (_slot_, 33, 0);
2185 printf (" 3.3V card found: ");
2186 }
2187
2188 debug ("Enable PCMCIA buffers and stop RESET\n");
2189 reg = PCMCIA_PGCRX (_slot_);
2190 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
2191 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
2192 PCMCIA_PGCRX (_slot_) = reg;
2193
2194 udelay (250000); /* some cards need >150 ms to come up :-( */
2195
2196 debug ("# hardware_enable done\n");
2197
2198 return (0);
2199}
2200
2201#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
2202static int hardware_disable (int slot)
2203{
2204 return 0; /* No hardware to disable */
2205}
2206#endif /* CFG_CMD_PCMCIA */
2207#endif /* CONFIG_MBX */
wdenk1f53a412002-12-04 23:39:58 +00002208/* -------------------------------------------------------------------- */
2209/* R360MPI Board */
2210/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00002211
2212#if defined(CONFIG_R360MPI)
2213
2214#define PCMCIA_BOARD_MSG "R360MPI"
2215
2216
2217static int hardware_enable(int slot)
2218{
2219 volatile immap_t *immap;
2220 volatile cpm8xx_t *cp;
2221 volatile pcmconf8xx_t *pcmp;
2222 volatile sysconf8xx_t *sysp;
2223 uint reg, mask;
2224
2225 debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
2226
2227 udelay(10000);
2228
2229 immap = (immap_t *)CFG_IMMR;
2230 sysp = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
2231 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
2232 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
2233
2234 /*
2235 * Configure SIUMCR to enable PCMCIA port B
2236 * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
2237 */
2238 sysp->sc_siumcr &= ~SIUMCR_DBGC11; /* set DBGC to 00 */
2239
2240 /* clear interrupt state, and disable interrupts */
2241 pcmp->pcmc_pscr = PCMCIA_MASK(_slot_);
2242 pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
2243
wdenkc6097192002-11-03 00:24:07 +00002244 /*
wdenk1f53a412002-12-04 23:39:58 +00002245 * Disable interrupts, DMA, and PCMCIA buffers
2246 * (isolate the interface) and assert RESET signal
wdenkc6097192002-11-03 00:24:07 +00002247 */
2248 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00002249 reg = 0;
2250 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
2251 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkc6097192002-11-03 00:24:07 +00002252 PCMCIA_PGCRX(_slot_) = reg;
2253 udelay(500);
2254
2255 /*
2256 * Configure Ports A, B & C pins for
2257 * 5 Volts Enable and 3 Volts enable
2258 */
2259 immap->im_ioport.iop_pcpar &= ~(0x0400);
2260 immap->im_ioport.iop_pcso &= ~(0x0400);/*
2261 immap->im_ioport.iop_pcdir |= 0x0400;*/
2262
2263 immap->im_ioport.iop_papar &= ~(0x0200);/*
2264 immap->im_ioport.iop_padir |= 0x0200;*/
2265#if 0
2266 immap->im_ioport.iop_pbpar &= ~(0xC000);
2267 immap->im_ioport.iop_pbdir &= ~(0xC000);
2268#endif
2269 /* remove all power */
2270
2271 immap->im_ioport.iop_pcdat |= 0x0400;
2272 immap->im_ioport.iop_padat |= 0x0200;
2273
2274 /*
2275 * Make sure there is a card in the slot, then configure the interface.
2276 */
2277 udelay(10000);
2278 debug ("[%d] %s: PIPR(%p)=0x%x\n",
2279 __LINE__,__FUNCTION__,
2280 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
wdenkea909b72002-11-21 23:11:29 +00002281 if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
wdenkc6097192002-11-03 00:24:07 +00002282 printf (" No Card found\n");
2283 return (1);
2284 }
2285
2286 /*
2287 * Power On.
2288 */
2289 mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
2290 reg = pcmp->pcmc_pipr;
2291 debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
2292 reg,
2293 (reg&PCMCIA_VS1(slot))?"n":"ff",
2294 (reg&PCMCIA_VS2(slot))?"n":"ff");
2295 if ((reg & mask) == mask) {
2296 immap->im_ioport.iop_pcdat &= ~(0x4000);
2297 puts (" 5.0V card found: ");
2298 } else {
2299 immap->im_ioport.iop_padat &= ~(0x0002);
2300 puts (" 3.3V card found: ");
2301 }
2302 immap->im_ioport.iop_pcdir |= 0x0400;
2303 immap->im_ioport.iop_padir |= 0x0200;
2304#if 0
2305 /* VCC switch error flag, PCMCIA slot INPACK_ pin */
2306 cp->cp_pbdir &= ~(0x0020 | 0x0010);
2307 cp->cp_pbpar &= ~(0x0020 | 0x0010);
2308 udelay(500000);
2309#endif
2310 debug ("Enable PCMCIA buffers and stop RESET\n");
2311 reg = PCMCIA_PGCRX(_slot_);
2312 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
2313 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
2314 PCMCIA_PGCRX(_slot_) = reg;
2315
2316 udelay(250000); /* some cards need >150 ms to come up :-( */
2317
2318 debug ("# hardware_enable done\n");
2319
2320 return (0);
2321}
2322
2323
wdenkc6097192002-11-03 00:24:07 +00002324#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
2325static int hardware_disable(int slot)
2326{
2327 volatile immap_t *immap;
2328 volatile pcmconf8xx_t *pcmp;
2329 u_long reg;
2330
2331 debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
2332
2333 immap = (immap_t *)CFG_IMMR;
2334 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
2335
2336 /* remove all power */
2337 immap->im_ioport.iop_pcdat |= 0x0400;
2338 immap->im_ioport.iop_padat |= 0x0200;
2339
2340 /* Configure PCMCIA General Control Register */
wdenkc6097192002-11-03 00:24:07 +00002341 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00002342 reg = 0;
wdenkc6097192002-11-03 00:24:07 +00002343 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
2344 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
2345 PCMCIA_PGCRX(_slot_) = reg;
2346
2347 udelay(10000);
2348
2349 return (0);
2350}
2351#endif /* CFG_CMD_PCMCIA */
2352
2353
wdenkc6097192002-11-03 00:24:07 +00002354static int voltage_set(int slot, int vcc, int vpp)
2355{
2356 volatile immap_t *immap;
2357 volatile pcmconf8xx_t *pcmp;
2358 u_long reg;
2359
2360 debug ("voltage_set: "
2361 PCMCIA_BOARD_MSG
2362 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
2363 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
2364
2365 immap = (immap_t *)CFG_IMMR;
2366 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
2367 /*
2368 * Disable PCMCIA buffers (isolate the interface)
2369 * and assert RESET signal
2370 */
2371 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00002372 reg = PCMCIA_PGCRX(_slot_);
2373 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
2374 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkc6097192002-11-03 00:24:07 +00002375 PCMCIA_PGCRX(_slot_) = reg;
2376 udelay(500);
2377
2378 /*
2379 * Configure Ports A & C pins for
2380 * 5 Volts Enable and 3 Volts enable,
2381 * Turn off all power
2382 */
2383 debug ("PCMCIA power OFF\n");
2384 immap->im_ioport.iop_pcpar &= ~(0x0400);
2385 immap->im_ioport.iop_pcso &= ~(0x0400);/*
2386 immap->im_ioport.iop_pcdir |= 0x0400;*/
2387
2388 immap->im_ioport.iop_papar &= ~(0x0200);/*
2389 immap->im_ioport.iop_padir |= 0x0200;*/
2390
2391 immap->im_ioport.iop_pcdat |= 0x0400;
2392 immap->im_ioport.iop_padat |= 0x0200;
2393
2394 reg = 0;
2395 switch(vcc) {
2396 case 0: break;
2397 case 33: reg |= 0x0200; break;
2398 case 50: reg |= 0x0400; break;
2399 default: goto done;
2400 }
2401
2402 /* Checking supported voltages */
2403
2404 debug ("PIPR: 0x%x --> %s\n",
2405 pcmp->pcmc_pipr,
2406 (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
2407
2408 if (reg & 0x0200)
2409 immap->im_ioport.iop_pcdat &= !reg;
2410 if (reg & 0x0400)
2411 immap->im_ioport.iop_padat &= !reg;
wdenk1f53a412002-12-04 23:39:58 +00002412 immap->im_ioport.iop_pcdir |= 0x0200;
2413 immap->im_ioport.iop_padir |= 0x0400;
wdenkc6097192002-11-03 00:24:07 +00002414 if (reg) {
2415 debug ("PCMCIA powered at %sV\n",
2416 (reg&0x0400) ? "5.0" : "3.3");
2417 } else {
2418 debug ("PCMCIA powered down\n");
2419 }
2420
2421done:
2422 debug ("Enable PCMCIA buffers and stop RESET\n");
2423 reg = PCMCIA_PGCRX(_slot_);
2424 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
2425 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
2426 PCMCIA_PGCRX(_slot_) = reg;
2427 udelay(500);
2428
2429 debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
2430 slot+'A');
2431 return (0);
2432}
2433
2434#endif /* R360MPI */
2435
wdenk1f53a412002-12-04 23:39:58 +00002436/* -------------------------------------------------------------------- */
wdenk0608e042004-03-25 19:29:38 +00002437/* KUP4K and KUP4X Boards */
wdenk1f53a412002-12-04 23:39:58 +00002438/* -------------------------------------------------------------------- */
wdenk0608e042004-03-25 19:29:38 +00002439#if defined(CONFIG_KUP4K) || defined(CONFIG_KUP4X)
wdenk56f94be2002-11-05 16:35:14 +00002440
wdenk0608e042004-03-25 19:29:38 +00002441#define PCMCIA_BOARD_MSG "KUP"
wdenk56f94be2002-11-05 16:35:14 +00002442
2443#define KUP4K_PCMCIA_B_3V3 (0x00020000)
2444
2445static int hardware_enable(int slot)
2446{
2447 volatile immap_t *immap;
2448 volatile cpm8xx_t *cp;
2449 volatile pcmconf8xx_t *pcmp;
2450 volatile sysconf8xx_t *sysp;
2451 uint reg, mask;
2452
2453 debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
2454
2455 udelay(10000);
2456
2457 immap = (immap_t *)CFG_IMMR;
2458 sysp = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
2459 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
2460 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
2461
2462 /*
2463 * Configure SIUMCR to enable PCMCIA port B
2464 * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
2465 */
2466 sysp->sc_siumcr &= ~SIUMCR_DBGC11; /* set DBGC to 00 */
2467
2468 /* clear interrupt state, and disable interrupts */
wdenkea909b72002-11-21 23:11:29 +00002469 pcmp->pcmc_pscr = PCMCIA_MASK(slot);
2470 pcmp->pcmc_per &= ~PCMCIA_MASK(slot);
wdenk56f94be2002-11-05 16:35:14 +00002471
wdenk56f94be2002-11-05 16:35:14 +00002472 /*
wdenk1f53a412002-12-04 23:39:58 +00002473 * Disable interrupts, DMA, and PCMCIA buffers
2474 * (isolate the interface) and assert RESET signal
wdenk56f94be2002-11-05 16:35:14 +00002475 */
2476 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00002477 reg = 0;
2478 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
2479 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkea909b72002-11-21 23:11:29 +00002480 PCMCIA_PGCRX(slot) = reg;
2481 udelay(2500);
wdenk56f94be2002-11-05 16:35:14 +00002482
2483 /*
2484 * Configure Port B pins for
2485 * 3 Volts enable
2486 */
wdenkea909b72002-11-21 23:11:29 +00002487 if (slot) { /* Slot A is built-in */
2488 cp->cp_pbdir |= KUP4K_PCMCIA_B_3V3;
2489 cp->cp_pbpar &= ~KUP4K_PCMCIA_B_3V3;
2490 /* remove all power */
2491 cp->cp_pbdat |= KUP4K_PCMCIA_B_3V3; /* active low */
2492 }
wdenk56f94be2002-11-05 16:35:14 +00002493 /*
2494 * Make sure there is a card in the slot, then configure the interface.
2495 */
2496 udelay(10000);
2497 debug ("[%d] %s: PIPR(%p)=0x%x\n",
2498 __LINE__,__FUNCTION__,
2499 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
wdenkea909b72002-11-21 23:11:29 +00002500 if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
wdenk56f94be2002-11-05 16:35:14 +00002501 printf (" No Card found\n");
2502 return (1);
2503 }
2504
2505 /*
2506 * Power On.
2507 */
wdenka6c7ad22002-12-03 21:28:10 +00002508 printf("%s Slot %c:", slot ? "" : "\n", 'A' + slot);
wdenk56f94be2002-11-05 16:35:14 +00002509 mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
2510 reg = pcmp->pcmc_pipr;
2511 debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
2512 reg,
2513 (reg&PCMCIA_VS1(slot))?"n":"ff",
2514 (reg&PCMCIA_VS2(slot))?"n":"ff");
2515 if ((reg & mask) == mask) {
2516 puts (" 5.0V card found: NOT SUPPORTED !!!\n");
2517 } else {
wdenkea909b72002-11-21 23:11:29 +00002518 if(slot)
2519 cp->cp_pbdat &= ~KUP4K_PCMCIA_B_3V3;
wdenk56f94be2002-11-05 16:35:14 +00002520 puts (" 3.3V card found: ");
2521 }
2522#if 0
2523 /* VCC switch error flag, PCMCIA slot INPACK_ pin */
2524 cp->cp_pbdir &= ~(0x0020 | 0x0010);
2525 cp->cp_pbpar &= ~(0x0020 | 0x0010);
2526 udelay(500000);
2527#endif
2528 debug ("Enable PCMCIA buffers and stop RESET\n");
wdenkea909b72002-11-21 23:11:29 +00002529 reg = PCMCIA_PGCRX(slot);
wdenk56f94be2002-11-05 16:35:14 +00002530 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
2531 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkea909b72002-11-21 23:11:29 +00002532 PCMCIA_PGCRX(slot) = reg;
wdenk56f94be2002-11-05 16:35:14 +00002533
2534 udelay(250000); /* some cards need >150 ms to come up :-( */
2535
2536 debug ("# hardware_enable done\n");
2537
2538 return (0);
2539}
2540
2541
wdenk56f94be2002-11-05 16:35:14 +00002542#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
2543static int hardware_disable(int slot)
2544{
2545 volatile immap_t *immap;
2546 volatile cpm8xx_t *cp;
2547 volatile pcmconf8xx_t *pcmp;
2548 u_long reg;
2549
2550 debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
2551
2552 immap = (immap_t *)CFG_IMMR;
2553 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
2554 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
wdenk1f53a412002-12-04 23:39:58 +00002555
wdenk56f94be2002-11-05 16:35:14 +00002556 /* remove all power */
wdenkea909b72002-11-21 23:11:29 +00002557 if (slot)
2558 cp->cp_pbdat |= KUP4K_PCMCIA_B_3V3;
wdenk56f94be2002-11-05 16:35:14 +00002559
2560 /* Configure PCMCIA General Control Register */
wdenk56f94be2002-11-05 16:35:14 +00002561 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00002562 reg = 0;
wdenk56f94be2002-11-05 16:35:14 +00002563 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
2564 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkea909b72002-11-21 23:11:29 +00002565 PCMCIA_PGCRX(slot) = reg;
wdenk56f94be2002-11-05 16:35:14 +00002566
2567 udelay(10000);
2568
2569 return (0);
2570}
2571#endif /* CFG_CMD_PCMCIA */
2572
2573
wdenk56f94be2002-11-05 16:35:14 +00002574static int voltage_set(int slot, int vcc, int vpp)
2575{
2576 volatile immap_t *immap;
2577 volatile cpm8xx_t *cp;
2578 volatile pcmconf8xx_t *pcmp;
2579 u_long reg;
2580
2581 debug ("voltage_set: " \
2582 PCMCIA_BOARD_MSG \
2583 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
2584 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
2585
wdenkea909b72002-11-21 23:11:29 +00002586 if (!slot) /* Slot A is not configurable */
2587 return 0;
2588
wdenk56f94be2002-11-05 16:35:14 +00002589 immap = (immap_t *)CFG_IMMR;
2590 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
2591 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
2592
2593 /*
2594 * Disable PCMCIA buffers (isolate the interface)
2595 * and assert RESET signal
2596 */
2597 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00002598 reg = PCMCIA_PGCRX(slot);
2599 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
2600 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkea909b72002-11-21 23:11:29 +00002601 PCMCIA_PGCRX(slot) = reg;
wdenk56f94be2002-11-05 16:35:14 +00002602 udelay(500);
2603
2604 debug ("PCMCIA power OFF\n");
2605 /*
2606 * Configure Port B pins for
2607 * 3 Volts enable
2608 */
2609 cp->cp_pbdir |= KUP4K_PCMCIA_B_3V3;
2610 cp->cp_pbpar &= ~KUP4K_PCMCIA_B_3V3;
2611 /* remove all power */
2612 cp->cp_pbdat |= KUP4K_PCMCIA_B_3V3; /* active low */
2613
2614 switch(vcc) {
2615 case 0: break;
2616 case 33:
2617 cp->cp_pbdat &= ~KUP4K_PCMCIA_B_3V3;
2618 debug ("PCMCIA powered at 3.3V\n");
2619 break;
2620 case 50:
2621 debug ("PCMCIA: 5Volt vcc not supported\n");
2622 break;
2623 default:
2624 puts("PCMCIA: vcc not supported");
2625 break;
2626 }
wdenkea909b72002-11-21 23:11:29 +00002627 udelay(10000);
wdenk56f94be2002-11-05 16:35:14 +00002628 /* Checking supported voltages */
2629
2630 debug ("PIPR: 0x%x --> %s\n",
2631 pcmp->pcmc_pipr,
wdenkea909b72002-11-21 23:11:29 +00002632 (pcmp->pcmc_pipr & (0x80000000 >> (slot << 4)))
wdenk56f94be2002-11-05 16:35:14 +00002633 ? "only 5 V --> NOT SUPPORTED"
2634 : "can do 3.3V");
2635
2636
2637 debug ("Enable PCMCIA buffers and stop RESET\n");
wdenkea909b72002-11-21 23:11:29 +00002638 reg = PCMCIA_PGCRX(slot);
wdenk56f94be2002-11-05 16:35:14 +00002639 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
2640 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkea909b72002-11-21 23:11:29 +00002641 PCMCIA_PGCRX(slot) = reg;
wdenk56f94be2002-11-05 16:35:14 +00002642 udelay(500);
2643
2644 debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
2645 slot+'A');
2646 return (0);
2647}
2648
wdenk0608e042004-03-25 19:29:38 +00002649#endif /* KUP4K || KUP4X */
wdenk56f94be2002-11-05 16:35:14 +00002650
2651
wdenk1f53a412002-12-04 23:39:58 +00002652/* -------------------------------------------------------------------- */
2653/* End of Board Specific Stuff */
2654/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00002655
2656
wdenk1f53a412002-12-04 23:39:58 +00002657/* -------------------------------------------------------------------- */
2658/* MPC8xx Specific Stuff - should go to MPC8xx directory */
2659/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00002660
2661/*
2662 * Search this table to see if the windowsize is
2663 * supported...
2664 */
2665
2666#define M8XX_SIZES_NO 32
2667
2668static const u_int m8xx_size_to_gray[M8XX_SIZES_NO] =
2669{ 0x00000001, 0x00000002, 0x00000008, 0x00000004,
2670 0x00000080, 0x00000040, 0x00000010, 0x00000020,
2671 0x00008000, 0x00004000, 0x00001000, 0x00002000,
2672 0x00000100, 0x00000200, 0x00000800, 0x00000400,
2673
2674 0x0fffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2675 0x01000000, 0x02000000, 0xffffffff, 0x04000000,
2676 0x00010000, 0x00020000, 0x00080000, 0x00040000,
2677 0x00800000, 0x00400000, 0x00100000, 0x00200000 };
2678
2679
wdenk1f53a412002-12-04 23:39:58 +00002680/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00002681
wdenkdb01a2e2004-04-15 23:14:49 +00002682#if ( ! defined(CONFIG_I82365) && ! defined(CONFIG_PXA_PCMCIA) )
wdenk7f70e852003-05-20 14:25:27 +00002683
wdenkc6097192002-11-03 00:24:07 +00002684static u_int m8xx_get_graycode(u_int size)
2685{
2686 u_int k;
2687
2688 for (k = 0; k < M8XX_SIZES_NO; k++) {
2689 if(m8xx_size_to_gray[k] == size)
2690 break;
2691 }
2692
2693 if((k == M8XX_SIZES_NO) || (m8xx_size_to_gray[k] == -1))
2694 k = -1;
2695
2696 return k;
2697}
2698
wdenk7f70e852003-05-20 14:25:27 +00002699#endif /* CONFIG_I82365 */
2700
wdenk1f53a412002-12-04 23:39:58 +00002701/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00002702
2703#if 0
2704static u_int m8xx_get_speed(u_int ns, u_int is_io)
2705{
2706 u_int reg, clocks, psst, psl, psht;
2707
2708 if(!ns) {
2709
2710 /*
2711 * We get called with IO maps setup to 0ns
2712 * if not specified by the user.
2713 * They should be 255ns.
2714 */
2715
2716 if(is_io)
2717 ns = 255;
2718 else
2719 ns = 100; /* fast memory if 0 */
2720 }
2721
2722 /*
2723 * In PSST, PSL, PSHT fields we tell the controller
2724 * timing parameters in CLKOUT clock cycles.
2725 * CLKOUT is the same as GCLK2_50.
2726 */
2727
2728/* how we want to adjust the timing - in percent */
2729
2730#define ADJ 180 /* 80 % longer accesstime - to be sure */
2731
2732 clocks = ((M8XX_BUSFREQ / 1000) * ns) / 1000;
2733 clocks = (clocks * ADJ) / (100*1000);
2734
2735 if(clocks >= PCMCIA_BMT_LIMIT) {
2736 DEBUG(0, "Max access time limit reached\n");
2737 clocks = PCMCIA_BMT_LIMIT-1;
2738 }
2739
2740 psst = clocks / 7; /* setup time */
2741 psht = clocks / 7; /* hold time */
2742 psl = (clocks * 5) / 7; /* strobe length */
2743
2744 psst += clocks - (psst + psht + psl);
2745
2746 reg = psst << 12;
2747 reg |= psl << 7;
2748 reg |= psht << 16;
2749
2750 return reg;
2751}
2752#endif
2753
wdenk1f53a412002-12-04 23:39:58 +00002754/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00002755
wdenkdb01a2e2004-04-15 23:14:49 +00002756#if defined(CONFIG_IDE_8xx_PCCARD) || defined(CONFIG_PXA_PCMCIA)
wdenkc6097192002-11-03 00:24:07 +00002757static void print_funcid (int func)
2758{
2759 puts (indent);
2760 switch (func) {
2761 case CISTPL_FUNCID_MULTI:
2762 puts (" Multi-Function");
2763 break;
2764 case CISTPL_FUNCID_MEMORY:
2765 puts (" Memory");
2766 break;
2767 case CISTPL_FUNCID_SERIAL:
2768 puts (" Serial Port");
2769 break;
2770 case CISTPL_FUNCID_PARALLEL:
2771 puts (" Parallel Port");
2772 break;
2773 case CISTPL_FUNCID_FIXED:
2774 puts (" Fixed Disk");
2775 break;
2776 case CISTPL_FUNCID_VIDEO:
2777 puts (" Video Adapter");
2778 break;
2779 case CISTPL_FUNCID_NETWORK:
2780 puts (" Network Adapter");
2781 break;
2782 case CISTPL_FUNCID_AIMS:
2783 puts (" AIMS Card");
2784 break;
2785 case CISTPL_FUNCID_SCSI:
2786 puts (" SCSI Adapter");
2787 break;
2788 default:
2789 puts (" Unknown");
2790 break;
2791 }
2792 puts (" Card\n");
2793}
2794#endif /* CONFIG_IDE_8xx_PCCARD */
2795
wdenk1f53a412002-12-04 23:39:58 +00002796/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00002797
wdenkdb01a2e2004-04-15 23:14:49 +00002798#if defined(CONFIG_IDE_8xx_PCCARD) || defined(CONFIG_PXA_PCMCIA)
wdenkc6097192002-11-03 00:24:07 +00002799static void print_fixed (volatile uchar *p)
2800{
2801 if (p == NULL)
2802 return;
2803
2804 puts(indent);
2805
2806 switch (*p) {
2807 case CISTPL_FUNCE_IDE_IFACE:
2808 { uchar iface = *(p+2);
2809
2810 puts ((iface == CISTPL_IDE_INTERFACE) ? " IDE" : " unknown");
2811 puts (" interface ");
2812 break;
2813 }
2814 case CISTPL_FUNCE_IDE_MASTER:
2815 case CISTPL_FUNCE_IDE_SLAVE:
2816 { uchar f1 = *(p+2);
2817 uchar f2 = *(p+4);
2818
2819 puts ((f1 & CISTPL_IDE_SILICON) ? " [silicon]" : " [rotating]");
2820
2821 if (f1 & CISTPL_IDE_UNIQUE)
2822 puts (" [unique]");
2823
2824 puts ((f1 & CISTPL_IDE_DUAL) ? " [dual]" : " [single]");
2825
2826 if (f2 & CISTPL_IDE_HAS_SLEEP)
2827 puts (" [sleep]");
2828
2829 if (f2 & CISTPL_IDE_HAS_STANDBY)
2830 puts (" [standby]");
2831
2832 if (f2 & CISTPL_IDE_HAS_IDLE)
2833 puts (" [idle]");
2834
2835 if (f2 & CISTPL_IDE_LOW_POWER)
2836 puts (" [low power]");
2837
2838 if (f2 & CISTPL_IDE_REG_INHIBIT)
2839 puts (" [reg inhibit]");
2840
2841 if (f2 & CISTPL_IDE_HAS_INDEX)
2842 puts (" [index]");
2843
2844 if (f2 & CISTPL_IDE_IOIS16)
2845 puts (" [IOis16]");
2846
2847 break;
2848 }
2849 }
2850 putc ('\n');
2851}
2852#endif /* CONFIG_IDE_8xx_PCCARD */
2853
wdenk1f53a412002-12-04 23:39:58 +00002854/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00002855
wdenkdb01a2e2004-04-15 23:14:49 +00002856#if defined(CONFIG_IDE_8xx_PCCARD) || defined(CONFIG_PXA_PCMCIA)
wdenkc6097192002-11-03 00:24:07 +00002857
2858#define MAX_IDENT_CHARS 64
2859#define MAX_IDENT_FIELDS 4
2860
2861static uchar *known_cards[] = {
Wolfgang Denk77ddac92005-10-13 16:45:02 +02002862 (uchar *)"ARGOSY PnPIDE D5",
wdenkc6097192002-11-03 00:24:07 +00002863 NULL
2864};
2865
2866static int identify (volatile uchar *p)
2867{
2868 uchar id_str[MAX_IDENT_CHARS];
2869 uchar data;
2870 uchar *t;
2871 uchar **card;
2872 int i, done;
2873
2874 if (p == NULL)
2875 return (0); /* Don't know */
2876
2877 t = id_str;
2878 done =0;
2879
2880 for (i=0; i<=4 && !done; ++i, p+=2) {
2881 while ((data = *p) != '\0') {
2882 if (data == 0xFF) {
2883 done = 1;
2884 break;
2885 }
2886 *t++ = data;
2887 if (t == &id_str[MAX_IDENT_CHARS-1]) {
2888 done = 1;
2889 break;
2890 }
2891 p += 2;
2892 }
2893 if (!done)
2894 *t++ = ' ';
2895 }
2896 *t = '\0';
2897 while (--t > id_str) {
2898 if (*t == ' ')
2899 *t = '\0';
2900 else
2901 break;
2902 }
Wolfgang Denk77ddac92005-10-13 16:45:02 +02002903 puts ((char *)id_str);
wdenkc6097192002-11-03 00:24:07 +00002904 putc ('\n');
2905
2906 for (card=known_cards; *card; ++card) {
2907 debug ("## Compare against \"%s\"\n", *card);
Wolfgang Denk77ddac92005-10-13 16:45:02 +02002908 if (strcmp((char *)*card, (char *)id_str) == 0) { /* found! */
wdenkc6097192002-11-03 00:24:07 +00002909 debug ("## CARD FOUND ##\n");
2910 return (1);
2911 }
2912 }
2913
2914 return (0); /* don't know */
2915}
2916#endif /* CONFIG_IDE_8xx_PCCARD */
2917
wdenk1f53a412002-12-04 23:39:58 +00002918/* -------------------------------------------------------------------- */
wdenk04a85b32004-04-15 18:22:41 +00002919/* NETTA board by Intracom S.A. */
2920/* -------------------------------------------------------------------- */
2921
2922#if defined(CONFIG_NETTA)
2923
2924/* some sane bit macros */
2925#define _BD(_b) (1U << (31-(_b)))
2926#define _BDR(_l, _h) (((((1U << (31-(_l))) - 1) << 1) | 1) & ~((1U << (31-(_h))) - 1))
2927
2928#define _BW(_b) (1U << (15-(_b)))
2929#define _BWR(_l, _h) (((((1U << (15-(_l))) - 1) << 1) | 1) & ~((1U << (15-(_h))) - 1))
2930
2931#define _BB(_b) (1U << (7-(_b)))
2932#define _BBR(_l, _h) (((((1U << (7-(_l))) - 1) << 1) | 1) & ~((1U << (7-(_h))) - 1))
2933
2934#define _B(_b) _BD(_b)
2935#define _BR(_l, _h) _BDR(_l, _h)
2936
2937#define PCMCIA_BOARD_MSG "NETTA"
2938
2939static const unsigned short vppd_masks[2] = { _BW(14), _BW(15) };
2940
2941static void cfg_vppd(int no)
2942{
2943 volatile immap_t *immap = (immap_t *)CFG_IMMR;
2944 unsigned short mask;
2945
2946 if ((unsigned int)no >= sizeof(vppd_masks)/sizeof(vppd_masks[0]))
2947 return;
2948
2949 mask = vppd_masks[no];
2950
2951 immap->im_ioport.iop_papar &= ~mask;
2952 immap->im_ioport.iop_paodr &= ~mask;
2953 immap->im_ioport.iop_padir |= mask;
2954}
2955
2956static void set_vppd(int no, int what)
2957{
2958 volatile immap_t *immap = (immap_t *)CFG_IMMR;
2959 unsigned short mask;
2960
2961 if ((unsigned int)no >= sizeof(vppd_masks)/sizeof(vppd_masks[0]))
2962 return;
2963
2964 mask = vppd_masks[no];
2965
2966 if (what)
2967 immap->im_ioport.iop_padat |= mask;
2968 else
2969 immap->im_ioport.iop_padat &= ~mask;
2970}
2971
2972static const unsigned short vccd_masks[2] = { _BW(10), _BW(6) };
2973
2974static void cfg_vccd(int no)
2975{
2976 volatile immap_t *immap = (immap_t *)CFG_IMMR;
2977 unsigned short mask;
2978
2979 if ((unsigned int)no >= sizeof(vccd_masks)/sizeof(vccd_masks[0]))
2980 return;
2981
2982 mask = vccd_masks[no];
2983
2984 immap->im_ioport.iop_papar &= ~mask;
2985 immap->im_ioport.iop_paodr &= ~mask;
2986 immap->im_ioport.iop_padir |= mask;
2987}
2988
2989static void set_vccd(int no, int what)
2990{
2991 volatile immap_t *immap = (immap_t *)CFG_IMMR;
2992 unsigned short mask;
2993
2994 if ((unsigned int)no >= sizeof(vccd_masks)/sizeof(vccd_masks[0]))
2995 return;
2996
2997 mask = vccd_masks[no];
2998
2999 if (what)
3000 immap->im_ioport.iop_padat |= mask;
3001 else
3002 immap->im_ioport.iop_padat &= ~mask;
3003}
3004
3005static const unsigned short oc_mask = _BW(8);
3006
3007static void cfg_oc(void)
3008{
3009 volatile immap_t *immap = (immap_t *)CFG_IMMR;
3010 unsigned short mask = oc_mask;
3011
3012 immap->im_ioport.iop_pcdir &= ~mask;
3013 immap->im_ioport.iop_pcso &= ~mask;
3014 immap->im_ioport.iop_pcint &= ~mask;
3015 immap->im_ioport.iop_pcpar &= ~mask;
3016}
3017
3018static int get_oc(void)
3019{
3020 volatile immap_t *immap = (immap_t *)CFG_IMMR;
3021 unsigned short mask = oc_mask;
3022 int what;
3023
3024 what = !!(immap->im_ioport.iop_pcdat & mask);;
3025 return what;
3026}
3027
3028static const unsigned short shdn_mask = _BW(12);
3029
3030static void cfg_shdn(void)
3031{
3032 volatile immap_t *immap = (immap_t *)CFG_IMMR;
3033 unsigned short mask;
3034
3035 mask = shdn_mask;
3036
3037 immap->im_ioport.iop_papar &= ~mask;
3038 immap->im_ioport.iop_paodr &= ~mask;
3039 immap->im_ioport.iop_padir |= mask;
3040}
3041
3042static void set_shdn(int what)
3043{
3044 volatile immap_t *immap = (immap_t *)CFG_IMMR;
3045 unsigned short mask;
3046
3047 mask = shdn_mask;
3048
3049 if (what)
3050 immap->im_ioport.iop_padat |= mask;
3051 else
3052 immap->im_ioport.iop_padat &= ~mask;
3053}
3054
3055static void cfg_ports (void);
3056
3057static int hardware_enable(int slot)
3058{
3059 volatile immap_t *immap;
3060 volatile cpm8xx_t *cp;
3061 volatile pcmconf8xx_t *pcmp;
3062 volatile sysconf8xx_t *sysp;
3063 uint reg, pipr, mask;
3064 int i;
3065
3066 debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
3067
3068 udelay(10000);
3069
3070 immap = (immap_t *)CFG_IMMR;
3071 sysp = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
3072 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
3073 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
3074
3075 /* Configure Ports for TPS2211A PC-Card Power-Interface Switch */
3076 cfg_ports ();
3077
3078 /* clear interrupt state, and disable interrupts */
3079 pcmp->pcmc_pscr = PCMCIA_MASK(_slot_);
3080 pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
3081
3082 /*
3083 * Disable interrupts, DMA, and PCMCIA buffers
3084 * (isolate the interface) and assert RESET signal
3085 */
3086 debug ("Disable PCMCIA buffers and assert RESET\n");
3087 reg = 0;
3088 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
3089 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
3090 PCMCIA_PGCRX(_slot_) = reg;
3091
3092 udelay(500);
3093
3094 /*
3095 * Make sure there is a card in the slot, then configure the interface.
3096 */
3097 udelay(10000);
3098 debug ("[%d] %s: PIPR(%p)=0x%x\n",
3099 __LINE__,__FUNCTION__,
3100 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
3101 if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
3102 printf (" No Card found\n");
3103 return (1);
3104 }
3105
3106 /*
3107 * Power On: Set VAVCC to 3.3V or 5V, set VAVPP to Hi-Z
3108 */
3109 mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
3110 pipr = pcmp->pcmc_pipr;
3111 debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
3112 pipr,
3113 (reg&PCMCIA_VS1(slot))?"n":"ff",
3114 (reg&PCMCIA_VS2(slot))?"n":"ff");
3115
3116 if ((pipr & mask) == mask) {
3117 set_vppd(0, 1); set_vppd(1, 1); /* VAVPP => Hi-Z */
3118 set_vccd(0, 0); set_vccd(1, 1); /* 5V on, 3V off */
3119 puts (" 5.0V card found: ");
3120 } else {
3121 set_vppd(0, 1); set_vppd(1, 1); /* VAVPP => Hi-Z */
3122 set_vccd(0, 1); set_vccd(1, 0); /* 5V off, 3V on */
3123 puts (" 3.3V card found: ");
3124 }
3125
3126 /* Wait 500 ms; use this to check for over-current */
3127 for (i=0; i<5000; ++i) {
3128 if (!get_oc()) {
3129 printf (" *** Overcurrent - Safety shutdown ***\n");
3130 set_vccd(0, 0); set_vccd(1, 0); /* VAVPP => Hi-Z */
3131 return (1);
3132 }
3133 udelay (100);
3134 }
3135
3136 debug ("Enable PCMCIA buffers and stop RESET\n");
3137 reg = PCMCIA_PGCRX(_slot_);
3138 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
3139 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
3140 PCMCIA_PGCRX(_slot_) = reg;
3141
3142 udelay(250000); /* some cards need >150 ms to come up :-( */
3143
3144 debug ("# hardware_enable done\n");
3145
3146 return (0);
3147}
3148
3149
3150#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
3151static int hardware_disable(int slot)
3152{
3153 volatile immap_t *immap;
3154 volatile pcmconf8xx_t *pcmp;
3155 u_long reg;
3156
3157 debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
3158
3159 immap = (immap_t *)CFG_IMMR;
3160 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
3161
3162 /* Configure PCMCIA General Control Register */
3163 debug ("Disable PCMCIA buffers and assert RESET\n");
3164 reg = 0;
3165 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
3166 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
3167 PCMCIA_PGCRX(_slot_) = reg;
3168
3169 /* All voltages off / Hi-Z */
3170 set_vppd(0, 1); set_vppd(1, 1);
3171 set_vccd(0, 1); set_vccd(1, 1);
3172
3173 udelay(10000);
3174
3175 return (0);
3176}
3177#endif /* CFG_CMD_PCMCIA */
3178
3179
3180static int voltage_set(int slot, int vcc, int vpp)
3181{
3182 volatile immap_t *immap;
3183 volatile cpm8xx_t *cp;
3184 volatile pcmconf8xx_t *pcmp;
3185 u_long reg;
3186 ushort sreg;
3187
3188 debug ("voltage_set: "
3189 PCMCIA_BOARD_MSG
3190 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
3191 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
3192
3193 immap = (immap_t *)CFG_IMMR;
3194 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
3195 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
3196 /*
3197 * Disable PCMCIA buffers (isolate the interface)
3198 * and assert RESET signal
3199 */
3200 debug ("Disable PCMCIA buffers and assert RESET\n");
3201 reg = PCMCIA_PGCRX(_slot_);
3202 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
3203 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
3204 PCMCIA_PGCRX(_slot_) = reg;
3205 udelay(500);
3206
3207 /*
3208 * Configure Port C pins for
3209 * 5 Volts Enable and 3 Volts enable,
3210 * Turn all power pins to Hi-Z
3211 */
3212 debug ("PCMCIA power OFF\n");
3213 cfg_ports (); /* Enables switch, but all in Hi-Z */
3214
3215 sreg = immap->im_ioport.iop_pcdat;
3216 set_vppd(0, 1); set_vppd(1, 1);
3217
3218 switch(vcc) {
3219 case 0:
3220 break; /* Switch off */
3221
3222 case 33:
3223 set_vccd(0, 1); set_vccd(1, 0);
3224 break;
3225
3226 case 50:
3227 set_vccd(0, 0); set_vccd(1, 1);
3228 break;
3229
3230 default:
3231 goto done;
3232 }
3233
3234 /* Checking supported voltages */
3235
3236 debug ("PIPR: 0x%x --> %s\n",
3237 pcmp->pcmc_pipr,
3238 (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
3239
3240done:
3241 debug ("Enable PCMCIA buffers and stop RESET\n");
3242 reg = PCMCIA_PGCRX(_slot_);
3243 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
3244 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
3245 PCMCIA_PGCRX(_slot_) = reg;
3246 udelay(500);
3247
3248 debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
3249 slot+'A');
3250 return (0);
3251}
3252
3253static void cfg_ports (void)
3254{
3255 volatile immap_t *immap;
3256 volatile cpm8xx_t *cp;
3257
3258 immap = (immap_t *)CFG_IMMR;
3259 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
3260
3261
3262 cfg_vppd(0); cfg_vppd(1); /* VPPD0,VPPD1 VAVPP => Hi-Z */
3263 cfg_vccd(0); cfg_vccd(1); /* 3V and 5V off */
3264 cfg_shdn();
3265 cfg_oc();
3266
3267 /*
3268 * Configure Port A for TPS2211 PC-Card Power-Interface Switch
3269 *
3270 * Switch off all voltages, assert shutdown
3271 */
3272 set_vppd(0, 1); set_vppd(1, 1);
3273 set_vccd(0, 0); set_vccd(1, 0);
3274 set_shdn(1);
3275
3276 udelay(100000);
3277}
3278
3279#endif /* NETTA */
3280
3281
3282/* -------------------------------------------------------------------- */
wdenkf7d15722004-12-18 22:35:43 +00003283/* UC100 Boards */
3284/* -------------------------------------------------------------------- */
3285
3286#if defined(CONFIG_UC100)
3287
3288#define PCMCIA_BOARD_MSG "UC100"
3289
3290/*
3291 * Remark: don't turn off OE "__MY_PCMCIA_GCRX_CXOE" on UC100 board.
3292 * This leads to board-hangup! (sr, 8 Dez. 2004)
3293 */
3294
3295static void cfg_ports (void);
3296
3297static int hardware_enable(int slot)
3298{
3299 volatile immap_t *immap;
3300 volatile cpm8xx_t *cp;
3301 volatile pcmconf8xx_t *pcmp;
3302 volatile sysconf8xx_t *sysp;
3303 uint reg, mask;
3304
3305 debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
3306
3307 udelay(10000);
3308
3309 immap = (immap_t *)CFG_IMMR;
3310 sysp = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
3311 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
3312 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
3313
3314 /* Configure Ports for TPS2211A PC-Card Power-Interface Switch */
3315 cfg_ports ();
3316
3317 /*
3318 * Configure SIUMCR to enable PCMCIA port B
3319 * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
3320 */
3321 sysp->sc_siumcr &= ~SIUMCR_DBGC11; /* set DBGC to 00 */
3322
3323 /* clear interrupt state, and disable interrupts */
3324 pcmp->pcmc_pscr = PCMCIA_MASK(_slot_);
3325 pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
3326
3327 /*
3328 * Disable interrupts, DMA, and PCMCIA buffers
3329 * (isolate the interface) and assert RESET signal
3330 */
3331 debug ("Disable PCMCIA buffers and assert RESET\n");
3332 reg = 0;
3333 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
3334 PCMCIA_PGCRX(_slot_) = reg;
3335 udelay(500);
3336
3337 /*
3338 * Make sure there is a card in the slot, then configure the interface.
3339 */
3340 udelay(10000);
3341 debug ("[%d] %s: PIPR(%p)=0x%x\n",
3342 __LINE__,__FUNCTION__,
3343 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
3344 if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
3345 printf (" No Card found\n");
3346 return (1);
3347 }
3348
3349 /*
3350 * Power On.
3351 */
3352 mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
3353 reg = pcmp->pcmc_pipr;
3354 debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
3355 reg,
3356 (reg&PCMCIA_VS1(slot))?"n":"ff",
3357 (reg&PCMCIA_VS2(slot))?"n":"ff");
3358 if ((reg & mask) == mask) {
3359 puts (" 5.0V card found: ");
3360 } else {
3361 puts (" 3.3V card found: ");
3362 }
3363
3364 /* switch VCC on */
3365 immap->im_ioport.iop_padat |= 0x8000; /* power enable 3.3V */
3366
3367 udelay(10000);
3368
3369 debug ("Enable PCMCIA buffers and stop RESET\n");
3370 reg = PCMCIA_PGCRX(_slot_);
3371 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
3372 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
3373 PCMCIA_PGCRX(_slot_) = reg;
3374
3375 udelay(250000); /* some cards need >150 ms to come up :-( */
3376
3377 debug ("# hardware_enable done\n");
3378
3379 return (0);
3380}
3381
3382
3383#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
3384static int hardware_disable(int slot)
3385{
3386 volatile immap_t *immap;
3387 volatile cpm8xx_t *cp;
3388 volatile pcmconf8xx_t *pcmp;
3389 u_long reg;
3390
3391 debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
3392
3393 immap = (immap_t *)CFG_IMMR;
3394 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
3395
3396 /* switch VCC off */
3397 immap->im_ioport.iop_padat &= ~0x8000; /* power disable 3.3V */
3398
3399 /* Configure PCMCIA General Control Register */
3400 debug ("Disable PCMCIA buffers and assert RESET\n");
3401 reg = 0;
3402 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
3403 PCMCIA_PGCRX(_slot_) = reg;
3404
3405 udelay(10000);
3406
3407 return (0);
3408}
3409#endif /* CFG_CMD_PCMCIA */
3410
3411
3412static int voltage_set(int slot, int vcc, int vpp)
3413{
3414 volatile immap_t *immap;
3415 volatile pcmconf8xx_t *pcmp;
3416 u_long reg;
3417
3418 debug ("voltage_set: "
3419 PCMCIA_BOARD_MSG
3420 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
3421 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
3422
3423 immap = (immap_t *)CFG_IMMR;
3424 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
3425 /*
3426 * Disable PCMCIA buffers (isolate the interface)
3427 * and assert RESET signal
3428 */
3429 debug ("Disable PCMCIA buffers and assert RESET\n");
3430 reg = PCMCIA_PGCRX(_slot_);
3431 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
3432 PCMCIA_PGCRX(_slot_) = reg;
3433 udelay(500);
3434
3435 /*
3436 * Configure Port C pins for
3437 * 5 Volts Enable and 3 Volts enable,
3438 * Turn all power pins to Hi-Z
3439 */
3440 debug ("PCMCIA power OFF\n");
3441 cfg_ports (); /* Enables switch, but all in Hi-Z */
3442
3443 debug ("Enable PCMCIA buffers and stop RESET\n");
3444 reg = PCMCIA_PGCRX(_slot_);
3445 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
3446 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
3447 PCMCIA_PGCRX(_slot_) = reg;
3448 udelay(500);
3449
3450 debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
3451 slot+'A');
3452 return (0);
3453}
3454
3455static void cfg_ports (void)
3456{
3457 volatile immap_t *immap;
3458
3459 immap = (immap_t *)CFG_IMMR;
3460
3461 /*
3462 * Configure Port A for MAX1602 PC-Card Power-Interface Switch
3463 */
3464 immap->im_ioport.iop_padat &= ~0x8000; /* set port x output to low */
3465 immap->im_ioport.iop_padir |= 0x8000; /* enable port x as output */
3466
3467 debug ("Set Port A: PAR: %08x DIR: %08x DAT: %08x\n",
3468 immap->im_ioport.iop_papar, immap->im_ioport.iop_padir,
3469 immap->im_ioport.iop_padat);
3470}
3471
3472#endif /* UC100 */
3473
3474
3475/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00003476
3477#endif /* CFG_CMD_PCMCIA || (CFG_CMD_IDE && CONFIG_IDE_8xx_PCCARD) */
wdenk8bde7f72003-06-27 21:31:46 +00003478
3479/**************************************************/
3480
3481#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
wdenk0d498392003-07-01 21:06:45 +00003482U_BOOT_CMD(
3483 pinit, 2, 1, do_pinit,
wdenk8bde7f72003-06-27 21:31:46 +00003484 "pinit - PCMCIA sub-system\n",
3485 "on - power on PCMCIA socket\n"
3486 "pinit off - power off PCMCIA socket\n"
3487);
3488#endif