blob: 62446d4efebb2fdff4a3fe819895673e4212b08f [file] [log] [blame]
wdenkc6097192002-11-03 00:24:07 +00001/*
wdenk6e592382004-04-18 17:39:38 +00002 * (C) Copyright 2000-2004
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
wdenkdc7c9a12003-03-26 06:55:25 +0000721#if defined(CONFIG_TQM8xxL) || defined(CONFIG_SVM_SC8xx)
722
wdenkc6097192002-11-03 00:24:07 +0000723#if defined(CONFIG_TQM8xxL)
wdenkc6097192002-11-03 00:24:07 +0000724#define PCMCIA_BOARD_MSG "TQM8xxL"
wdenkdc7c9a12003-03-26 06:55:25 +0000725#endif
726#if defined(CONFIG_SVM_SC8xx)
727#define PCMCIA_BOARD_MSG "SC8xx"
728#endif
wdenkc6097192002-11-03 00:24:07 +0000729
730static int hardware_enable(int slot)
731{
732 volatile immap_t *immap;
733 volatile cpm8xx_t *cp;
734 volatile pcmconf8xx_t *pcmp;
735 volatile sysconf8xx_t *sysp;
736 uint reg, mask;
737
738 debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
739
740 udelay(10000);
741
742 immap = (immap_t *)CFG_IMMR;
743 sysp = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
744 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
745 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
746
747 /*
748 * Configure SIUMCR to enable PCMCIA port B
749 * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
750 */
751 sysp->sc_siumcr &= ~SIUMCR_DBGC11; /* set DBGC to 00 */
752
753 /* clear interrupt state, and disable interrupts */
dzue7df0292003-10-19 21:43:26 +0000754 pcmp->pcmc_pscr = PCMCIA_MASK(slot);
755 pcmp->pcmc_per &= ~PCMCIA_MASK(slot);
wdenkc6097192002-11-03 00:24:07 +0000756
wdenkc6097192002-11-03 00:24:07 +0000757 /*
wdenk1f53a412002-12-04 23:39:58 +0000758 * Disable interrupts, DMA, and PCMCIA buffers
759 * (isolate the interface) and assert RESET signal
wdenkc6097192002-11-03 00:24:07 +0000760 */
761 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +0000762 reg = 0;
763 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
dzue7df0292003-10-19 21:43:26 +0000764#ifndef NSCU_OE_INV
wdenk1f53a412002-12-04 23:39:58 +0000765 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
dzue7df0292003-10-19 21:43:26 +0000766#endif
767 PCMCIA_PGCRX(slot) = reg;
wdenkc6097192002-11-03 00:24:07 +0000768 udelay(500);
769
wdenkc40b2952004-03-13 23:29:43 +0000770#ifndef CONFIG_HMI10
dzue7df0292003-10-19 21:43:26 +0000771#ifndef CONFIG_NSCU
wdenkc6097192002-11-03 00:24:07 +0000772 /*
773 * Configure Port C pins for
774 * 5 Volts Enable and 3 Volts enable
775 */
776 immap->im_ioport.iop_pcpar &= ~(0x0002 | 0x0004);
777 immap->im_ioport.iop_pcso &= ~(0x0002 | 0x0004);
778 /* remove all power */
779
780 immap->im_ioport.iop_pcdat &= ~(0x0002 | 0x0004);
dzue7df0292003-10-19 21:43:26 +0000781#endif
wdenkc40b2952004-03-13 23:29:43 +0000782#else /* CONFIG_HMI10 */
wdenka522fa02004-01-04 22:51:12 +0000783 /*
784 * Configure Port B pins for
785 * 5 Volts Enable and 3 Volts enable
786 */
787 immap->im_cpm.cp_pbpar &= ~(0x00000300);
788
789 /* remove all power */
790 immap->im_cpm.cp_pbdat |= 0x00000300;
wdenkc40b2952004-03-13 23:29:43 +0000791#endif /* CONFIG_HMI10 */
wdenkc6097192002-11-03 00:24:07 +0000792
793 /*
794 * Make sure there is a card in the slot, then configure the interface.
795 */
796 udelay(10000);
797 debug ("[%d] %s: PIPR(%p)=0x%x\n",
798 __LINE__,__FUNCTION__,
799 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
wdenkc40b2952004-03-13 23:29:43 +0000800#ifndef CONFIG_HMI10
wdenkea909b72002-11-21 23:11:29 +0000801 if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
wdenka522fa02004-01-04 22:51:12 +0000802#else
803 if (pcmp->pcmc_pipr & (0x10000000 >> (slot << 4))) {
wdenkc40b2952004-03-13 23:29:43 +0000804#endif /* CONFIG_HMI10 */
wdenkc6097192002-11-03 00:24:07 +0000805 printf (" No Card found\n");
806 return (1);
807 }
808
809 /*
810 * Power On.
811 */
812 mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
813 reg = pcmp->pcmc_pipr;
814 debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
815 reg,
816 (reg&PCMCIA_VS1(slot))?"n":"ff",
817 (reg&PCMCIA_VS2(slot))?"n":"ff");
dzue7df0292003-10-19 21:43:26 +0000818#ifndef CONFIG_NSCU
wdenkc6097192002-11-03 00:24:07 +0000819 if ((reg & mask) == mask) {
wdenkc40b2952004-03-13 23:29:43 +0000820#ifndef CONFIG_HMI10
wdenkc6097192002-11-03 00:24:07 +0000821 immap->im_ioport.iop_pcdat |= 0x0004;
wdenka522fa02004-01-04 22:51:12 +0000822#else
823 immap->im_cpm.cp_pbdat &= ~(0x0000100);
wdenkc40b2952004-03-13 23:29:43 +0000824#endif /* CONFIG_HMI10 */
wdenkc6097192002-11-03 00:24:07 +0000825 puts (" 5.0V card found: ");
826 } else {
wdenkc40b2952004-03-13 23:29:43 +0000827#ifndef CONFIG_HMI10
wdenkc6097192002-11-03 00:24:07 +0000828 immap->im_ioport.iop_pcdat |= 0x0002;
wdenka522fa02004-01-04 22:51:12 +0000829#else
830 immap->im_cpm.cp_pbdat &= ~(0x0000200);
wdenkc40b2952004-03-13 23:29:43 +0000831#endif /* CONFIG_HMI10 */
wdenkc6097192002-11-03 00:24:07 +0000832 puts (" 3.3V card found: ");
833 }
wdenkc40b2952004-03-13 23:29:43 +0000834#ifndef CONFIG_HMI10
wdenk1f53a412002-12-04 23:39:58 +0000835 immap->im_ioport.iop_pcdir |= (0x0002 | 0x0004);
dzue7df0292003-10-19 21:43:26 +0000836#else
wdenka522fa02004-01-04 22:51:12 +0000837 immap->im_cpm.cp_pbdir |= 0x00000300;
wdenkc40b2952004-03-13 23:29:43 +0000838#endif /* CONFIG_HMI10 */
wdenka522fa02004-01-04 22:51:12 +0000839#else
dzue7df0292003-10-19 21:43:26 +0000840 if ((reg & mask) == mask) {
841 puts (" 5.0V card found: ");
842 } else {
843 puts (" 3.3V card found: ");
844 }
845#endif
wdenkc6097192002-11-03 00:24:07 +0000846#if 0
847 /* VCC switch error flag, PCMCIA slot INPACK_ pin */
848 cp->cp_pbdir &= ~(0x0020 | 0x0010);
849 cp->cp_pbpar &= ~(0x0020 | 0x0010);
850 udelay(500000);
851#endif
852 udelay(1000);
853 debug ("Enable PCMCIA buffers and stop RESET\n");
dzue7df0292003-10-19 21:43:26 +0000854 reg = PCMCIA_PGCRX(slot);
wdenkc6097192002-11-03 00:24:07 +0000855 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
dzue7df0292003-10-19 21:43:26 +0000856#ifndef NSCU_OE_INV
wdenkc6097192002-11-03 00:24:07 +0000857 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
dzue7df0292003-10-19 21:43:26 +0000858#else
859 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
860#endif
861 PCMCIA_PGCRX(slot) = reg;
wdenkc6097192002-11-03 00:24:07 +0000862
863 udelay(250000); /* some cards need >150 ms to come up :-( */
864
865 debug ("# hardware_enable done\n");
866
867 return (0);
868}
869
870
wdenkc6097192002-11-03 00:24:07 +0000871#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
872static int hardware_disable(int slot)
873{
874 volatile immap_t *immap;
875 volatile pcmconf8xx_t *pcmp;
876 u_long reg;
877
878 debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
879
880 immap = (immap_t *)CFG_IMMR;
881 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
882
wdenkc40b2952004-03-13 23:29:43 +0000883#ifndef CONFIG_HMI10
dzue7df0292003-10-19 21:43:26 +0000884#ifndef CONFIG_NSCU
wdenkc6097192002-11-03 00:24:07 +0000885 /* remove all power */
886 immap->im_ioport.iop_pcdat &= ~(0x0002 | 0x0004);
dzue7df0292003-10-19 21:43:26 +0000887#endif
wdenkc40b2952004-03-13 23:29:43 +0000888#else /* CONFIG_HMI10 */
wdenka522fa02004-01-04 22:51:12 +0000889 immap->im_cpm.cp_pbdat |= 0x00000300;
wdenkc40b2952004-03-13 23:29:43 +0000890#endif /* CONFIG_HMI10 */
wdenkc6097192002-11-03 00:24:07 +0000891
wdenkc6097192002-11-03 00:24:07 +0000892 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +0000893 reg = 0;
wdenkc6097192002-11-03 00:24:07 +0000894 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
dzue7df0292003-10-19 21:43:26 +0000895#ifndef NSCU_OE_INV
wdenkc6097192002-11-03 00:24:07 +0000896 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
dzue7df0292003-10-19 21:43:26 +0000897#endif
898 PCMCIA_PGCRX(slot) = reg;
wdenkc6097192002-11-03 00:24:07 +0000899
900 udelay(10000);
901
902 return (0);
903}
904#endif /* CFG_CMD_PCMCIA */
905
dzue7df0292003-10-19 21:43:26 +0000906#ifdef CONFIG_NSCU
907static int voltage_set(int slot, int vcc, int vpp)
908{
909 return 0;
910}
911#else
wdenkc6097192002-11-03 00:24:07 +0000912static int voltage_set(int slot, int vcc, int vpp)
913{
914 volatile immap_t *immap;
915 volatile pcmconf8xx_t *pcmp;
916 u_long reg;
917
918 debug ("voltage_set: "
919 PCMCIA_BOARD_MSG
920 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
921 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
922
923 immap = (immap_t *)CFG_IMMR;
924 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
925 /*
926 * Disable PCMCIA buffers (isolate the interface)
927 * and assert RESET signal
928 */
929 debug ("Disable PCMCIA buffers and assert RESET\n");
dzue7df0292003-10-19 21:43:26 +0000930 reg = PCMCIA_PGCRX(slot);
wdenk1f53a412002-12-04 23:39:58 +0000931 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
dzue7df0292003-10-19 21:43:26 +0000932#ifndef NSCU_OE_INV
wdenk1f53a412002-12-04 23:39:58 +0000933 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
dzue7df0292003-10-19 21:43:26 +0000934#else
935 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
936#endif
937 PCMCIA_PGCRX(slot) = reg;
wdenkc6097192002-11-03 00:24:07 +0000938 udelay(500);
939
wdenkc40b2952004-03-13 23:29:43 +0000940#ifndef CONFIG_HMI10
wdenkc6097192002-11-03 00:24:07 +0000941 /*
942 * Configure Port C pins for
943 * 5 Volts Enable and 3 Volts enable,
944 * Turn off all power
945 */
946 debug ("PCMCIA power OFF\n");
947 immap->im_ioport.iop_pcpar &= ~(0x0002 | 0x0004);
948 immap->im_ioport.iop_pcso &= ~(0x0002 | 0x0004);
949 immap->im_ioport.iop_pcdat &= ~(0x0002 | 0x0004);
950
951 reg = 0;
952 switch(vcc) {
953 case 0: break;
954 case 33: reg |= 0x0002; break;
955 case 50: reg |= 0x0004; break;
956 default: goto done;
957 }
wdenkc40b2952004-03-13 23:29:43 +0000958#else /* CONFIG_HMI10 */
wdenka522fa02004-01-04 22:51:12 +0000959 /*
960 * Configure Port B pins for
961 * 5 Volts Enable and 3 Volts enable,
962 * Turn off all power
963 */
964 debug ("PCMCIA power OFF\n");
965 immap->im_cpm.cp_pbpar &= ~(0x00000300);
966 /* remove all power */
967
968 immap->im_cpm.cp_pbdat |= 0x00000300;
969
970 reg = 0;
971 switch(vcc) {
972 case 0: break;
973 case 33: reg |= 0x00000200; break;
974 case 50: reg |= 0x00000100; break;
975 default: goto done;
976}
wdenkc40b2952004-03-13 23:29:43 +0000977#endif /* CONFIG_HMI10 */
wdenkc6097192002-11-03 00:24:07 +0000978
979 /* Checking supported voltages */
980
981 debug ("PIPR: 0x%x --> %s\n",
982 pcmp->pcmc_pipr,
983 (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
984
wdenkc40b2952004-03-13 23:29:43 +0000985#ifndef CONFIG_HMI10
wdenkc6097192002-11-03 00:24:07 +0000986 immap->im_ioport.iop_pcdat |= reg;
wdenk1f53a412002-12-04 23:39:58 +0000987 immap->im_ioport.iop_pcdir |= (0x0002 | 0x0004);
wdenka522fa02004-01-04 22:51:12 +0000988#else
989 immap->im_cpm.cp_pbdat &= !reg;
990 immap->im_cpm.cp_pbdir |= 0x00000300;
wdenkc40b2952004-03-13 23:29:43 +0000991#endif /* CONFIG_HMI10 */
wdenkc6097192002-11-03 00:24:07 +0000992 if (reg) {
wdenkc40b2952004-03-13 23:29:43 +0000993#ifndef CONFIG_HMI10
wdenkc6097192002-11-03 00:24:07 +0000994 debug ("PCMCIA powered at %sV\n",
995 (reg&0x0004) ? "5.0" : "3.3");
wdenka522fa02004-01-04 22:51:12 +0000996#else
997 debug ("PCMCIA powered at %sV\n",
998 (reg&0x00000200) ? "5.0" : "3.3");
wdenkc40b2952004-03-13 23:29:43 +0000999#endif /* CONFIG_HMI10 */
wdenkc6097192002-11-03 00:24:07 +00001000 } else {
1001 debug ("PCMCIA powered down\n");
1002 }
1003
1004done:
1005 debug ("Enable PCMCIA buffers and stop RESET\n");
dzue7df0292003-10-19 21:43:26 +00001006 reg = PCMCIA_PGCRX(slot);
wdenkc6097192002-11-03 00:24:07 +00001007 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
dzue7df0292003-10-19 21:43:26 +00001008#ifndef NSCU_OE_INV
wdenkc6097192002-11-03 00:24:07 +00001009 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
dzue7df0292003-10-19 21:43:26 +00001010#else
1011 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
1012#endif
1013 PCMCIA_PGCRX(slot) = reg;
wdenkc6097192002-11-03 00:24:07 +00001014 udelay(500);
1015
1016 debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
1017 slot+'A');
1018 return (0);
1019}
dzue7df0292003-10-19 21:43:26 +00001020#endif
wdenkc6097192002-11-03 00:24:07 +00001021
1022#endif /* TQM8xxL */
1023
1024
wdenk1f53a412002-12-04 23:39:58 +00001025/* -------------------------------------------------------------------- */
1026/* LWMON Board */
1027/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00001028
1029#if defined(CONFIG_LWMON)
1030
1031#define PCMCIA_BOARD_MSG "LWMON"
1032
1033/* #define's for MAX1604 Power Switch */
1034#define MAX1604_OP_SUS 0x80
1035#define MAX1604_VCCBON 0x40
1036#define MAX1604_VCC_35 0x20
1037#define MAX1604_VCCBHIZ 0x10
1038#define MAX1604_VPPBON 0x08
1039#define MAX1604_VPPBPBPGM 0x04
1040#define MAX1604_VPPBHIZ 0x02
1041/* reserved 0x01 */
1042
1043static int hardware_enable(int slot)
1044{
1045 volatile immap_t *immap;
1046 volatile cpm8xx_t *cp;
1047 volatile pcmconf8xx_t *pcmp;
1048 volatile sysconf8xx_t *sysp;
1049 uint reg, mask;
1050 uchar val;
1051
1052
1053 debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1054
1055 /* Switch on PCMCIA port in PIC register 0x60 */
1056 reg = pic_read (0x60);
1057 debug ("[%d] PIC read: reg_60 = 0x%02x\n", __LINE__, reg);
1058 reg &= ~0x10;
wdenk1f53a412002-12-04 23:39:58 +00001059 /* reg |= 0x08; Vpp not needed */
wdenkc6097192002-11-03 00:24:07 +00001060 pic_write (0x60, reg);
1061#ifdef DEBUG
1062 reg = pic_read (0x60);
1063 printf ("[%d] PIC read: reg_60 = 0x%02x\n", __LINE__, reg);
1064#endif
1065 udelay(10000);
1066
1067 immap = (immap_t *)CFG_IMMR;
1068 sysp = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
1069 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1070 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1071
1072 /*
1073 * Configure SIUMCR to enable PCMCIA port B
1074 * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
1075 */
1076 sysp->sc_siumcr &= ~SIUMCR_DBGC11; /* set DBGC to 00 */
1077
1078 /* clear interrupt state, and disable interrupts */
1079 pcmp->pcmc_pscr = PCMCIA_MASK(_slot_);
1080 pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
1081
wdenkc6097192002-11-03 00:24:07 +00001082 /*
wdenk1f53a412002-12-04 23:39:58 +00001083 * Disable interrupts, DMA, and PCMCIA buffers
1084 * (isolate the interface) and assert RESET signal
wdenkc6097192002-11-03 00:24:07 +00001085 */
1086 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00001087 reg = 0;
1088 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1089 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkc6097192002-11-03 00:24:07 +00001090 PCMCIA_PGCRX(_slot_) = reg;
1091 udelay(500);
1092
1093 /*
1094 * Make sure there is a card in the slot, then configure the interface.
1095 */
1096 udelay(10000);
1097 debug ("[%d] %s: PIPR(%p)=0x%x\n",
1098 __LINE__,__FUNCTION__,
1099 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
wdenkea909b72002-11-21 23:11:29 +00001100 if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
wdenkc6097192002-11-03 00:24:07 +00001101 printf (" No Card found\n");
1102 return (1);
1103 }
1104
1105 /*
1106 * Power On.
1107 */
1108 mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
1109 reg = pcmp->pcmc_pipr;
1110 debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
1111 reg,
1112 (reg&PCMCIA_VS1(slot))?"n":"ff",
1113 (reg&PCMCIA_VS2(slot))?"n":"ff");
1114 if ((reg & mask) == mask) {
1115 val = 0; /* VCCB3/5 = 0 ==> use Vx = 5.0 V */
1116 puts (" 5.0V card found: ");
1117 } else {
1118 val = MAX1604_VCC_35; /* VCCB3/5 = 1 ==> use Vy = 3.3 V */
1119 puts (" 3.3V card found: ");
1120 }
1121
1122 /* switch VCC on */
wdenk1f53a412002-12-04 23:39:58 +00001123 val |= MAX1604_OP_SUS | MAX1604_VCCBON;
wdenkc6097192002-11-03 00:24:07 +00001124 i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE);
1125 i2c_write (CFG_I2C_POWER_A_ADDR, 0, 0, &val, 1);
1126
1127 udelay(500000);
1128
1129 debug ("Enable PCMCIA buffers and stop RESET\n");
1130 reg = PCMCIA_PGCRX(_slot_);
1131 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
1132 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
1133 PCMCIA_PGCRX(_slot_) = reg;
1134
1135 udelay(250000); /* some cards need >150 ms to come up :-( */
1136
1137 debug ("# hardware_enable done\n");
1138
1139 return (0);
1140}
1141
1142
wdenkc6097192002-11-03 00:24:07 +00001143#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
1144static int hardware_disable(int slot)
1145{
1146 volatile immap_t *immap;
1147 volatile pcmconf8xx_t *pcmp;
1148 u_long reg;
1149 uchar val;
1150
1151 debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1152
1153 immap = (immap_t *)CFG_IMMR;
1154 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1155
1156 /* remove all power, put output in high impedance state */
1157 val = MAX1604_VCCBHIZ | MAX1604_VPPBHIZ;
1158 i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE);
1159 i2c_write (CFG_I2C_POWER_A_ADDR, 0, 0, &val, 1);
1160
1161 /* Configure PCMCIA General Control Register */
wdenkc6097192002-11-03 00:24:07 +00001162 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00001163 reg = 0;
wdenkc6097192002-11-03 00:24:07 +00001164 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1165 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
1166 PCMCIA_PGCRX(_slot_) = reg;
1167
1168 /* Switch off PCMCIA port in PIC register 0x60 */
1169 reg = pic_read (0x60);
1170 debug ("[%d] PIC read: reg_60 = 0x%02x\n", __LINE__, reg);
1171 reg |= 0x10;
1172 reg &= ~0x08;
1173 pic_write (0x60, reg);
1174#ifdef DEBUG
1175 reg = pic_read (0x60);
1176 printf ("[%d] PIC read: reg_60 = 0x%02x\n", __LINE__, reg);
1177#endif
1178 udelay(10000);
1179
1180 return (0);
1181}
1182#endif /* CFG_CMD_PCMCIA */
1183
1184
wdenkc6097192002-11-03 00:24:07 +00001185static int voltage_set(int slot, int vcc, int vpp)
1186{
1187 volatile immap_t *immap;
1188 volatile pcmconf8xx_t *pcmp;
1189 u_long reg;
1190 uchar val;
1191
1192 debug ("voltage_set: "
1193 PCMCIA_BOARD_MSG
1194 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
1195 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
1196
1197 immap = (immap_t *)CFG_IMMR;
1198 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1199 /*
1200 * Disable PCMCIA buffers (isolate the interface)
1201 * and assert RESET signal
1202 */
1203 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00001204 reg = PCMCIA_PGCRX(_slot_);
1205 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1206 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkc6097192002-11-03 00:24:07 +00001207 PCMCIA_PGCRX(_slot_) = reg;
1208 udelay(500);
1209
1210 /*
1211 * Turn off all power (switch to high impedance)
1212 */
1213 debug ("PCMCIA power OFF\n");
1214 val = MAX1604_VCCBHIZ | MAX1604_VPPBHIZ;
1215 i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE);
1216 i2c_write (CFG_I2C_POWER_A_ADDR, 0, 0, &val, 1);
1217
1218 val = 0;
1219 switch(vcc) {
1220 case 0: break;
1221 case 33: val = MAX1604_VCC_35; break;
1222 case 50: break;
1223 default: goto done;
1224 }
1225
1226 /* Checking supported voltages */
1227
1228 debug ("PIPR: 0x%x --> %s\n",
1229 pcmp->pcmc_pipr,
1230 (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
1231
1232 i2c_write (CFG_I2C_POWER_A_ADDR, 0, 0, &val, 1);
1233 if (val) {
1234 debug ("PCMCIA powered at %sV\n",
1235 (val & MAX1604_VCC_35) ? "3.3" : "5.0");
1236 } else {
1237 debug ("PCMCIA powered down\n");
1238 }
1239
1240done:
1241 debug ("Enable PCMCIA buffers and stop RESET\n");
1242 reg = PCMCIA_PGCRX(_slot_);
1243 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
1244 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
1245 PCMCIA_PGCRX(_slot_) = reg;
1246 udelay(500);
1247
1248 debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
1249 slot+'A');
1250 return (0);
1251}
1252
1253#endif /* LWMON */
1254
wdenk1f53a412002-12-04 23:39:58 +00001255/* -------------------------------------------------------------------- */
1256/* GTH board by Corelatus AB */
1257/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00001258#if defined(CONFIG_GTH)
1259
1260#define PCMCIA_BOARD_MSG "GTH COMPACT FLASH"
1261
wdenk1f53a412002-12-04 23:39:58 +00001262static int voltage_set (int slot, int vcc, int vpp)
1263{ /* Do nothing */
1264 return 0;
wdenkc6097192002-11-03 00:24:07 +00001265}
1266
1267static int hardware_enable (int slot)
1268{
wdenk1f53a412002-12-04 23:39:58 +00001269 volatile immap_t *immap;
1270 volatile cpm8xx_t *cp;
1271 volatile pcmconf8xx_t *pcmp;
1272 volatile sysconf8xx_t *sysp;
1273 uint reg, mask;
wdenkc6097192002-11-03 00:24:07 +00001274
wdenk1f53a412002-12-04 23:39:58 +00001275 debug ("hardware_enable: GTH Slot %c\n", 'A' + slot);
wdenkc6097192002-11-03 00:24:07 +00001276
wdenk1f53a412002-12-04 23:39:58 +00001277 immap = (immap_t *) CFG_IMMR;
1278 sysp = (sysconf8xx_t *) (&(((immap_t *) CFG_IMMR)->im_siu_conf));
1279 pcmp = (pcmconf8xx_t *) (&(((immap_t *) CFG_IMMR)->im_pcmcia));
1280 cp = (cpm8xx_t *) (&(((immap_t *) CFG_IMMR)->im_cpm));
wdenkc6097192002-11-03 00:24:07 +00001281
wdenk1f53a412002-12-04 23:39:58 +00001282 /* clear interrupt state, and disable interrupts */
1283 pcmp->pcmc_pscr = PCMCIA_MASK (_slot_);
1284 pcmp->pcmc_per &= ~PCMCIA_MASK (_slot_);
wdenkc6097192002-11-03 00:24:07 +00001285
wdenk1f53a412002-12-04 23:39:58 +00001286 /*
1287 * Disable interrupts, DMA, and PCMCIA buffers
1288 * (isolate the interface) and assert RESET signal
1289 */
1290 debug ("Disable PCMCIA buffers and assert RESET\n");
1291 reg = 0;
1292 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1293 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
1294 PCMCIA_PGCRX (_slot_) = reg;
1295 udelay (500);
wdenkc6097192002-11-03 00:24:07 +00001296
wdenk1f53a412002-12-04 23:39:58 +00001297 /*
1298 * Make sure there is a card in the slot,
1299 * then configure the interface.
1300 */
1301 udelay (10000);
1302 debug ("[%d] %s: PIPR(%p)=0x%x\n",
1303 __LINE__, __FUNCTION__,
1304 &(pcmp->pcmc_pipr), pcmp->pcmc_pipr);
1305 if (pcmp->pcmc_pipr & 0x98000000) {
1306 printf (" No Card found\n");
1307 return (1);
1308 }
wdenkc6097192002-11-03 00:24:07 +00001309
wdenk1f53a412002-12-04 23:39:58 +00001310 mask = PCMCIA_VS1 (slot) | PCMCIA_VS2 (slot);
1311 reg = pcmp->pcmc_pipr;
1312 debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
1313 reg,
1314 (reg & PCMCIA_VS1 (slot)) ? "n" : "ff",
1315 (reg & PCMCIA_VS2 (slot)) ? "n" : "ff");
wdenkc6097192002-11-03 00:24:07 +00001316
wdenk1f53a412002-12-04 23:39:58 +00001317 debug ("Enable PCMCIA buffers and stop RESET\n");
1318 reg = PCMCIA_PGCRX (_slot_);
1319 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
1320 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
1321 PCMCIA_PGCRX (_slot_) = reg;
wdenkc6097192002-11-03 00:24:07 +00001322
wdenk1f53a412002-12-04 23:39:58 +00001323 udelay (250000); /* some cards need >150 ms to come up :-( */
wdenkc6097192002-11-03 00:24:07 +00001324
wdenk1f53a412002-12-04 23:39:58 +00001325 debug ("# hardware_enable done\n");
wdenkc6097192002-11-03 00:24:07 +00001326
wdenk1f53a412002-12-04 23:39:58 +00001327 return 0;
wdenkc6097192002-11-03 00:24:07 +00001328}
1329#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
1330static int hardware_disable(int slot)
1331{
1332 return 0; /* No hardware to disable */
1333}
1334#endif /* CFG_CMD_PCMCIA */
1335#endif /* CONFIG_GTH */
1336
wdenk1f53a412002-12-04 23:39:58 +00001337/* -------------------------------------------------------------------- */
1338/* ICU862 Boards by Cambridge Broadband Ltd. */
1339/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00001340
1341#if defined(CONFIG_ICU862)
1342
1343#define PCMCIA_BOARD_MSG "ICU862"
1344
1345static void cfg_port_B (void);
1346
1347static int hardware_enable(int slot)
1348{
1349 volatile immap_t *immap;
1350 volatile cpm8xx_t *cp;
1351 volatile pcmconf8xx_t *pcmp;
1352 volatile sysconf8xx_t *sysp;
1353 uint reg, pipr, mask;
1354 int i;
1355
1356 debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1357
1358 udelay(10000);
1359
1360 immap = (immap_t *)CFG_IMMR;
1361 sysp = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
1362 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1363 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1364
1365 /* Configure Port B for TPS2205 PC-Card Power-Interface Switch */
1366 cfg_port_B ();
1367
1368 /*
1369 * Configure SIUMCR to enable PCMCIA port B
1370 * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
1371 */
1372 sysp->sc_siumcr &= ~SIUMCR_DBGC11; /* set DBGC to 00 */
1373
1374 /* clear interrupt state, and disable interrupts */
1375 pcmp->pcmc_pscr = PCMCIA_MASK(_slot_);
1376 pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
1377
wdenkc6097192002-11-03 00:24:07 +00001378 /*
wdenk1f53a412002-12-04 23:39:58 +00001379 * Disable interrupts, DMA, and PCMCIA buffers
1380 * (isolate the interface) and assert RESET signal
wdenkc6097192002-11-03 00:24:07 +00001381 */
1382 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00001383 reg = 0;
1384 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1385 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkc6097192002-11-03 00:24:07 +00001386 PCMCIA_PGCRX(_slot_) = reg;
1387 udelay(500);
1388
1389 /*
1390 * Make sure there is a card in the slot, then configure the interface.
1391 */
1392 udelay(10000);
1393 debug ("[%d] %s: PIPR(%p)=0x%x\n",
1394 __LINE__,__FUNCTION__,
1395 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
wdenkea909b72002-11-21 23:11:29 +00001396 if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
wdenkc6097192002-11-03 00:24:07 +00001397 printf (" No Card found\n");
1398 return (1);
1399 }
1400
1401 /*
1402 * Power On: Set VAVCC to 3.3V or 5V, set VAVPP to Hi-Z
1403 */
1404 mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
1405 pipr = pcmp->pcmc_pipr;
1406 debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
1407 pipr,
1408 (reg&PCMCIA_VS1(slot))?"n":"ff",
1409 (reg&PCMCIA_VS2(slot))?"n":"ff");
1410
1411 reg = cp->cp_pbdat;
1412 if ((pipr & mask) == mask) {
wdenk1f53a412002-12-04 23:39:58 +00001413 reg |= (TPS2205_VPP_PGM | TPS2205_VPP_VCC | /* VAVPP => Hi-Z */
1414 TPS2205_VCC3); /* 3V off */
wdenkc6097192002-11-03 00:24:07 +00001415 reg &= ~(TPS2205_VCC5); /* 5V on */
1416 puts (" 5.0V card found: ");
1417 } else {
wdenk1f53a412002-12-04 23:39:58 +00001418 reg |= (TPS2205_VPP_PGM | TPS2205_VPP_VCC | /* VAVPP => Hi-Z */
1419 TPS2205_VCC5); /* 5V off */
wdenkc6097192002-11-03 00:24:07 +00001420 reg &= ~(TPS2205_VCC3); /* 3V on */
1421 puts (" 3.3V card found: ");
1422 }
1423
1424 debug ("\nPB DAT: %08x -> 3.3V %s 5.0V %s VPP_PGM %s VPP_VCC %s\n",
1425 reg,
1426 (reg & TPS2205_VCC3) ? "off" : "on",
1427 (reg & TPS2205_VCC5) ? "off" : "on",
1428 (reg & TPS2205_VPP_PGM) ? "off" : "on",
1429 (reg & TPS2205_VPP_VCC) ? "off" : "on" );
1430
1431 cp->cp_pbdat = reg;
1432
1433 /* Wait 500 ms; use this to check for over-current */
1434 for (i=0; i<5000; ++i) {
1435 if ((cp->cp_pbdat & TPS2205_OC) == 0) {
1436 printf (" *** Overcurrent - Safety shutdown ***\n");
1437 cp->cp_pbdat &= ~(TPS2205_SHDN);
1438 return (1);
1439 }
1440 udelay (100);
1441 }
1442
1443 debug ("Enable PCMCIA buffers and stop RESET\n");
1444 reg = PCMCIA_PGCRX(_slot_);
1445 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
1446 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
1447 PCMCIA_PGCRX(_slot_) = reg;
1448
1449 udelay(250000); /* some cards need >150 ms to come up :-( */
1450
1451 debug ("# hardware_enable done\n");
1452
1453 return (0);
1454}
1455
1456
wdenkc6097192002-11-03 00:24:07 +00001457#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
1458static int hardware_disable(int slot)
1459{
1460 volatile immap_t *immap;
1461 volatile cpm8xx_t *cp;
1462 volatile pcmconf8xx_t *pcmp;
1463 u_long reg;
1464
1465 debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1466
1467 immap = (immap_t *)CFG_IMMR;
1468 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1469 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1470
1471 /* Shut down */
1472 cp->cp_pbdat &= ~(TPS2205_SHDN);
1473
1474 /* Configure PCMCIA General Control Register */
wdenkc6097192002-11-03 00:24:07 +00001475 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00001476 reg = 0;
wdenkc6097192002-11-03 00:24:07 +00001477 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1478 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
1479 PCMCIA_PGCRX(_slot_) = reg;
1480
1481 udelay(10000);
1482
1483 return (0);
1484}
1485#endif /* CFG_CMD_PCMCIA */
1486
1487
wdenkc6097192002-11-03 00:24:07 +00001488static int voltage_set(int slot, int vcc, int vpp)
1489{
1490 volatile immap_t *immap;
1491 volatile cpm8xx_t *cp;
1492 volatile pcmconf8xx_t *pcmp;
1493 u_long reg;
1494
1495 debug ("voltage_set: "
1496 PCMCIA_BOARD_MSG
1497 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
1498 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
1499
1500 immap = (immap_t *)CFG_IMMR;
1501 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1502 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1503 /*
1504 * Disable PCMCIA buffers (isolate the interface)
1505 * and assert RESET signal
1506 */
1507 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00001508 reg = PCMCIA_PGCRX(_slot_);
1509 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1510 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkc6097192002-11-03 00:24:07 +00001511 PCMCIA_PGCRX(_slot_) = reg;
1512 udelay(500);
1513
1514 /*
1515 * Configure Port C pins for
1516 * 5 Volts Enable and 3 Volts enable,
1517 * Turn all power pins to Hi-Z
1518 */
1519 debug ("PCMCIA power OFF\n");
1520 cfg_port_B (); /* Enables switch, but all in Hi-Z */
1521
1522 reg = cp->cp_pbdat;
1523
1524 switch(vcc) {
1525 case 0: break; /* Switch off */
1526 case 33: reg &= ~TPS2205_VCC3; break; /* Switch on 3.3V */
1527 case 50: reg &= ~TPS2205_VCC5; break; /* Switch on 5.0V */
1528 default: goto done;
1529 }
1530
1531 /* Checking supported voltages */
1532
1533 debug ("PIPR: 0x%x --> %s\n",
1534 pcmp->pcmc_pipr,
1535 (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
1536
1537 cp->cp_pbdat = reg;
1538
1539#ifdef DEBUG
1540 {
1541 char *s;
1542
1543 if ((reg & TPS2205_VCC3) == 0) {
1544 s = "at 3.3V";
1545 } else if ((reg & TPS2205_VCC5) == 0) {
1546 s = "at 5.0V";
1547 } else {
1548 s = "down";
1549 }
1550 printf ("PCMCIA powered %s\n", s);
1551 }
1552#endif
1553
1554done:
1555 debug ("Enable PCMCIA buffers and stop RESET\n");
1556 reg = PCMCIA_PGCRX(_slot_);
1557 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
1558 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
1559 PCMCIA_PGCRX(_slot_) = reg;
1560 udelay(500);
1561
1562 debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
1563 slot+'A');
1564 return (0);
1565}
1566
1567static void cfg_port_B (void)
1568{
1569 volatile immap_t *immap;
1570 volatile cpm8xx_t *cp;
1571 uint reg;
1572
1573 immap = (immap_t *)CFG_IMMR;
1574 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1575
1576 /*
1577 * Configure Port B for TPS2205 PC-Card Power-Interface Switch
1578 *
1579 * Switch off all voltages, assert shutdown
1580 */
1581 reg = cp->cp_pbdat;
wdenk1f53a412002-12-04 23:39:58 +00001582 reg |= (TPS2205_VPP_PGM | TPS2205_VPP_VCC | /* VAVPP => Hi-Z */
1583 TPS2205_VCC3 | TPS2205_VCC5 | /* VAVCC => Hi-Z */
1584 TPS2205_SHDN); /* enable switch */
wdenkc6097192002-11-03 00:24:07 +00001585 cp->cp_pbdat = reg;
1586
1587 cp->cp_pbpar &= ~(TPS2205_INPUTS | TPS2205_OUTPUTS);
1588
1589 reg = cp->cp_pbdir & ~(TPS2205_INPUTS);
1590 cp->cp_pbdir = reg | TPS2205_OUTPUTS;
1591
1592 debug ("Set Port B: PAR: %08x DIR: %08x DAT: %08x\n",
1593 cp->cp_pbpar, cp->cp_pbdir, cp->cp_pbdat);
1594}
1595
1596#endif /* ICU862 */
1597
1598
wdenk1f53a412002-12-04 23:39:58 +00001599/* -------------------------------------------------------------------- */
1600/* C2MON Boards by TTTech Computertechnik AG */
1601/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00001602
1603#if defined(CONFIG_C2MON)
1604
1605#define PCMCIA_BOARD_MSG "C2MON"
1606
1607static void cfg_ports (void);
1608
1609static int hardware_enable(int slot)
1610{
1611 volatile immap_t *immap;
1612 volatile cpm8xx_t *cp;
1613 volatile pcmconf8xx_t *pcmp;
1614 volatile sysconf8xx_t *sysp;
1615 uint reg, pipr, mask;
1616 ushort sreg;
1617 int i;
1618
1619 debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1620
1621 udelay(10000);
1622
1623 immap = (immap_t *)CFG_IMMR;
1624 sysp = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
1625 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1626 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1627
1628 /* Configure Ports for TPS2211A PC-Card Power-Interface Switch */
1629 cfg_ports ();
1630
1631 /*
1632 * Configure SIUMCR to enable PCMCIA port B
1633 * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
1634 */
1635 sysp->sc_siumcr &= ~SIUMCR_DBGC11; /* set DBGC to 00 */
1636
1637 /* clear interrupt state, and disable interrupts */
1638 pcmp->pcmc_pscr = PCMCIA_MASK(_slot_);
1639 pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
1640
wdenkc6097192002-11-03 00:24:07 +00001641 /*
wdenk1f53a412002-12-04 23:39:58 +00001642 * Disable interrupts, DMA, and PCMCIA buffers
1643 * (isolate the interface) and assert RESET signal
wdenkc6097192002-11-03 00:24:07 +00001644 */
1645 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00001646 reg = 0;
1647 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1648 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkc6097192002-11-03 00:24:07 +00001649 PCMCIA_PGCRX(_slot_) = reg;
1650 udelay(500);
1651
1652 /*
1653 * Make sure there is a card in the slot, then configure the interface.
1654 */
1655 udelay(10000);
1656 debug ("[%d] %s: PIPR(%p)=0x%x\n",
1657 __LINE__,__FUNCTION__,
1658 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
wdenkea909b72002-11-21 23:11:29 +00001659 if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
wdenkc6097192002-11-03 00:24:07 +00001660 printf (" No Card found\n");
1661 return (1);
1662 }
1663
1664 /*
1665 * Power On: Set VAVCC to 3.3V or 5V, set VAVPP to Hi-Z
1666 */
1667 mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
1668 pipr = pcmp->pcmc_pipr;
1669 debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
1670 pipr,
1671 (reg&PCMCIA_VS1(slot))?"n":"ff",
1672 (reg&PCMCIA_VS2(slot))?"n":"ff");
1673
1674 sreg = immap->im_ioport.iop_pcdat;
1675 if ((pipr & mask) == mask) {
1676 sreg |= (TPS2211_VPPD0 | TPS2211_VPPD1 | /* VAVPP => Hi-Z */
1677 TPS2211_VCCD1); /* 5V on */
1678 sreg &= ~(TPS2211_VCCD0); /* 3V off */
1679 puts (" 5.0V card found: ");
1680 } else {
1681 sreg |= (TPS2211_VPPD0 | TPS2211_VPPD1 | /* VAVPP => Hi-Z */
1682 TPS2211_VCCD0); /* 3V on */
1683 sreg &= ~(TPS2211_VCCD1); /* 5V off */
1684 puts (" 3.3V card found: ");
1685 }
1686
1687 debug ("\nPC DAT: %04x -> 3.3V %s 5.0V %s\n",
1688 sreg,
1689 ( (sreg & TPS2211_VCCD0) && !(sreg & TPS2211_VCCD1)) ? "on" : "off",
1690 (!(sreg & TPS2211_VCCD0) && (sreg & TPS2211_VCCD1)) ? "on" : "off"
1691 );
1692
1693 immap->im_ioport.iop_pcdat = sreg;
1694
1695 /* Wait 500 ms; use this to check for over-current */
1696 for (i=0; i<5000; ++i) {
1697 if ((cp->cp_pbdat & TPS2211_OC) == 0) {
1698 printf (" *** Overcurrent - Safety shutdown ***\n");
1699 immap->im_ioport.iop_pcdat &= ~(TPS2211_VCCD0|TPS2211_VCCD1);
1700 return (1);
1701 }
1702 udelay (100);
1703 }
1704
1705 debug ("Enable PCMCIA buffers and stop RESET\n");
1706 reg = PCMCIA_PGCRX(_slot_);
1707 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
1708 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
1709 PCMCIA_PGCRX(_slot_) = reg;
1710
1711 udelay(250000); /* some cards need >150 ms to come up :-( */
1712
1713 debug ("# hardware_enable done\n");
1714
1715 return (0);
1716}
1717
1718
wdenkc6097192002-11-03 00:24:07 +00001719#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
1720static int hardware_disable(int slot)
1721{
1722 volatile immap_t *immap;
1723 volatile cpm8xx_t *cp;
1724 volatile pcmconf8xx_t *pcmp;
1725 u_long reg;
1726
1727 debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1728
1729 immap = (immap_t *)CFG_IMMR;
1730 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1731
1732 /* Configure PCMCIA General Control Register */
wdenkc6097192002-11-03 00:24:07 +00001733 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00001734 reg = 0;
wdenkc6097192002-11-03 00:24:07 +00001735 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1736 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
1737 PCMCIA_PGCRX(_slot_) = reg;
1738
1739 /* ALl voltages off / Hi-Z */
1740 immap->im_ioport.iop_pcdat |= (TPS2211_VPPD0 | TPS2211_VPPD1 |
1741 TPS2211_VCCD0 | TPS2211_VCCD1 );
1742
1743 udelay(10000);
1744
1745 return (0);
1746}
1747#endif /* CFG_CMD_PCMCIA */
1748
1749
wdenkc6097192002-11-03 00:24:07 +00001750static int voltage_set(int slot, int vcc, int vpp)
1751{
1752 volatile immap_t *immap;
1753 volatile cpm8xx_t *cp;
1754 volatile pcmconf8xx_t *pcmp;
1755 u_long reg;
1756 ushort sreg;
1757
1758 debug ("voltage_set: "
1759 PCMCIA_BOARD_MSG
1760 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
1761 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
1762
1763 immap = (immap_t *)CFG_IMMR;
1764 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1765 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1766 /*
1767 * Disable PCMCIA buffers (isolate the interface)
1768 * and assert RESET signal
1769 */
1770 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00001771 reg = PCMCIA_PGCRX(_slot_);
1772 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1773 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkc6097192002-11-03 00:24:07 +00001774 PCMCIA_PGCRX(_slot_) = reg;
1775 udelay(500);
1776
1777 /*
1778 * Configure Port C pins for
1779 * 5 Volts Enable and 3 Volts enable,
1780 * Turn all power pins to Hi-Z
1781 */
1782 debug ("PCMCIA power OFF\n");
1783 cfg_ports (); /* Enables switch, but all in Hi-Z */
1784
1785 sreg = immap->im_ioport.iop_pcdat;
1786 sreg |= TPS2211_VPPD0 | TPS2211_VPPD1; /* VAVPP always Hi-Z */
1787
1788 switch(vcc) {
1789 case 0: break; /* Switch off */
1790 case 33: sreg |= TPS2211_VCCD0; /* Switch on 3.3V */
1791 sreg &= ~TPS2211_VCCD1;
1792 break;
1793 case 50: sreg &= ~TPS2211_VCCD0; /* Switch on 5.0V */
1794 sreg |= TPS2211_VCCD1;
1795 break;
1796 default: goto done;
1797 }
1798
1799 /* Checking supported voltages */
1800
1801 debug ("PIPR: 0x%x --> %s\n",
1802 pcmp->pcmc_pipr,
1803 (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
1804
1805 immap->im_ioport.iop_pcdat = sreg;
1806
1807#ifdef DEBUG
1808 {
1809 char *s;
1810
1811 if ((sreg & TPS2211_VCCD0) && !(sreg & TPS2211_VCCD1)) {
1812 s = "at 3.3V";
1813 } else if (!(sreg & TPS2211_VCCD0) && (sreg & TPS2211_VCCD1)) {
1814 s = "at 5.0V";
1815 } else {
1816 s = "down";
1817 }
1818 printf ("PCMCIA powered %s\n", s);
1819 }
1820#endif
1821
1822done:
1823 debug ("Enable PCMCIA buffers and stop RESET\n");
1824 reg = PCMCIA_PGCRX(_slot_);
1825 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
1826 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
1827 PCMCIA_PGCRX(_slot_) = reg;
1828 udelay(500);
1829
1830 debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
1831 slot+'A');
1832 return (0);
1833}
1834
1835static void cfg_ports (void)
1836{
1837 volatile immap_t *immap;
1838 volatile cpm8xx_t *cp;
1839 ushort sreg;
1840
1841 immap = (immap_t *)CFG_IMMR;
1842 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1843
1844 /*
1845 * Configure Port C for TPS2211 PC-Card Power-Interface Switch
1846 *
1847 * Switch off all voltages, assert shutdown
1848 */
1849 sreg = immap->im_ioport.iop_pcdat;
1850 sreg |= (TPS2211_VPPD0 | TPS2211_VPPD1); /* VAVPP => Hi-Z */
1851 sreg &= ~(TPS2211_VCCD0 | TPS2211_VCCD1); /* 3V and 5V off */
1852 immap->im_ioport.iop_pcdat = sreg;
1853
1854 immap->im_ioport.iop_pcpar &= ~(TPS2211_OUTPUTS);
1855 immap->im_ioport.iop_pcdir |= TPS2211_OUTPUTS;
1856
1857 debug ("Set Port C: PAR: %04x DIR: %04x DAT: %04x\n",
1858 immap->im_ioport.iop_pcpar,
1859 immap->im_ioport.iop_pcdir,
1860 immap->im_ioport.iop_pcdat);
1861
1862 /*
1863 * Configure Port B for TPS2211 PC-Card Power-Interface Switch
1864 *
1865 * Over-Current Input only
1866 */
1867 cp->cp_pbpar &= ~(TPS2211_INPUTS);
1868 cp->cp_pbdir &= ~(TPS2211_INPUTS);
1869
1870 debug ("Set Port B: PAR: %08x DIR: %08x DAT: %08x\n",
1871 cp->cp_pbpar, cp->cp_pbdir, cp->cp_pbdat);
1872}
1873
1874#endif /* C2MON */
1875
wdenk1f53a412002-12-04 23:39:58 +00001876/* -------------------------------------------------------------------- */
1877/* MBX board from Morotola */
1878/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00001879
1880#if defined( CONFIG_MBX )
1881#include <../board/mbx8xx/csr.h>
1882
1883/* A lot of this has been taken from the RPX code in this file it works from me.
1884 I have added the voltage selection for the MBX board. */
1885
1886/* MBX voltage bit in control register #2 */
1887#define CR2_VPP12 ((uchar)0x10)
1888#define CR2_VPPVDD ((uchar)0x20)
1889#define CR2_VDD5 ((uchar)0x40)
1890#define CR2_VDD3 ((uchar)0x80)
1891
1892#define PCMCIA_BOARD_MSG "MBX860"
1893
1894static int voltage_set (int slot, int vcc, int vpp)
1895{
1896 uchar reg = 0;
1897
1898 debug ("voltage_set: PCMCIA_BOARD_MSG Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
1899 'A' + slot, vcc / 10, vcc % 10, vpp / 10, vcc % 10);
1900
1901 switch (vcc) {
1902 case 0:
1903 break;
1904 case 33:
1905 reg |= CR2_VDD3;
1906 break;
1907 case 50:
1908 reg |= CR2_VDD5;
1909 break;
1910 default:
1911 return 1;
1912 }
1913
1914 switch (vpp) {
1915 case 0:
1916 break;
1917 case 33:
1918 case 50:
1919 if (vcc == vpp) {
1920 reg |= CR2_VPPVDD;
1921 } else {
1922 return 1;
1923 }
1924 break;
1925 case 120:
1926 reg |= CR2_VPP12;
1927 break;
1928 default:
1929 return 1;
1930 }
1931
1932 /* first, turn off all power */
1933 MBX_CSR2 &= ~(CR2_VDDSEL | CR2_VPPSEL);
1934
1935 /* enable new powersettings */
1936 MBX_CSR2 |= reg;
1937 debug ("MBX_CSR2 read = 0x%02x\n", MBX_CSR2);
1938
1939 return (0);
1940}
1941
1942static int hardware_enable (int slot)
1943{
1944 volatile immap_t *immap;
1945 volatile cpm8xx_t *cp;
1946 volatile pcmconf8xx_t *pcmp;
1947 volatile sysconf8xx_t *sysp;
1948 uint reg, mask;
1949
1950 debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n",
1951 'A' + slot);
1952
1953 udelay (10000);
1954
1955 immap = (immap_t *) CFG_IMMR;
1956 sysp = (sysconf8xx_t *) (&(((immap_t *) CFG_IMMR)->im_siu_conf));
1957 pcmp = (pcmconf8xx_t *) (&(((immap_t *) CFG_IMMR)->im_pcmcia));
1958 cp = (cpm8xx_t *) (&(((immap_t *) CFG_IMMR)->im_cpm));
1959
1960 /* clear interrupt state, and disable interrupts */
1961 pcmp->pcmc_pscr = PCMCIA_MASK (_slot_);
1962 pcmp->pcmc_per &= ~PCMCIA_MASK (_slot_);
1963
wdenkc6097192002-11-03 00:24:07 +00001964 /*
wdenk1f53a412002-12-04 23:39:58 +00001965 * Disable interrupts, DMA, and PCMCIA buffers
1966 * (isolate the interface) and assert RESET signal
wdenkc6097192002-11-03 00:24:07 +00001967 */
1968 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00001969 reg = 0;
wdenkc6097192002-11-03 00:24:07 +00001970 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1971 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
1972 PCMCIA_PGCRX (_slot_) = reg;
1973 udelay (500);
1974
1975 /* remove all power */
1976 voltage_set (slot, 0, 0);
1977 /*
1978 * Make sure there is a card in the slot, then configure the interface.
1979 */
wdenkea909b72002-11-21 23:11:29 +00001980 udelay(10000);
1981 debug ("[%d] %s: PIPR(%p)=0x%x\n",
1982 __LINE__,__FUNCTION__,
1983 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
wdenkc40b2952004-03-13 23:29:43 +00001984#ifndef CONFIG_HMI10
wdenkea909b72002-11-21 23:11:29 +00001985 if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
wdenka522fa02004-01-04 22:51:12 +00001986#else
1987 if (pcmp->pcmc_pipr & (0x10000000 >> (slot << 4))) {
wdenkc40b2952004-03-13 23:29:43 +00001988#endif /* CONFIG_HMI10 */
wdenkc6097192002-11-03 00:24:07 +00001989 printf (" No Card found\n");
1990 return (1);
1991 }
1992
1993 /*
1994 * Power On.
1995 */
1996 mask = PCMCIA_VS1 (_slot_) | PCMCIA_VS2 (_slot_);
1997 reg = pcmp->pcmc_pipr;
1998 debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n", reg,
1999 (reg & PCMCIA_VS1 (slot)) ? "n" : "ff",
2000 (reg & PCMCIA_VS2 (slot)) ? "n" : "ff");
2001
2002 if ((reg & mask) == mask) {
2003 voltage_set (_slot_, 50, 0);
2004 printf (" 5.0V card found: ");
2005 } else {
2006 voltage_set (_slot_, 33, 0);
2007 printf (" 3.3V card found: ");
2008 }
2009
2010 debug ("Enable PCMCIA buffers and stop RESET\n");
2011 reg = PCMCIA_PGCRX (_slot_);
2012 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
2013 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
2014 PCMCIA_PGCRX (_slot_) = reg;
2015
2016 udelay (250000); /* some cards need >150 ms to come up :-( */
2017
2018 debug ("# hardware_enable done\n");
2019
2020 return (0);
2021}
2022
2023#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
2024static int hardware_disable (int slot)
2025{
2026 return 0; /* No hardware to disable */
2027}
2028#endif /* CFG_CMD_PCMCIA */
2029#endif /* CONFIG_MBX */
wdenk1f53a412002-12-04 23:39:58 +00002030/* -------------------------------------------------------------------- */
2031/* R360MPI Board */
2032/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00002033
2034#if defined(CONFIG_R360MPI)
2035
2036#define PCMCIA_BOARD_MSG "R360MPI"
2037
2038
2039static int hardware_enable(int slot)
2040{
2041 volatile immap_t *immap;
2042 volatile cpm8xx_t *cp;
2043 volatile pcmconf8xx_t *pcmp;
2044 volatile sysconf8xx_t *sysp;
2045 uint reg, mask;
2046
2047 debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
2048
2049 udelay(10000);
2050
2051 immap = (immap_t *)CFG_IMMR;
2052 sysp = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
2053 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
2054 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
2055
2056 /*
2057 * Configure SIUMCR to enable PCMCIA port B
2058 * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
2059 */
2060 sysp->sc_siumcr &= ~SIUMCR_DBGC11; /* set DBGC to 00 */
2061
2062 /* clear interrupt state, and disable interrupts */
2063 pcmp->pcmc_pscr = PCMCIA_MASK(_slot_);
2064 pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
2065
wdenkc6097192002-11-03 00:24:07 +00002066 /*
wdenk1f53a412002-12-04 23:39:58 +00002067 * Disable interrupts, DMA, and PCMCIA buffers
2068 * (isolate the interface) and assert RESET signal
wdenkc6097192002-11-03 00:24:07 +00002069 */
2070 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00002071 reg = 0;
2072 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
2073 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkc6097192002-11-03 00:24:07 +00002074 PCMCIA_PGCRX(_slot_) = reg;
2075 udelay(500);
2076
2077 /*
2078 * Configure Ports A, B & C pins for
2079 * 5 Volts Enable and 3 Volts enable
2080 */
2081 immap->im_ioport.iop_pcpar &= ~(0x0400);
2082 immap->im_ioport.iop_pcso &= ~(0x0400);/*
2083 immap->im_ioport.iop_pcdir |= 0x0400;*/
2084
2085 immap->im_ioport.iop_papar &= ~(0x0200);/*
2086 immap->im_ioport.iop_padir |= 0x0200;*/
2087#if 0
2088 immap->im_ioport.iop_pbpar &= ~(0xC000);
2089 immap->im_ioport.iop_pbdir &= ~(0xC000);
2090#endif
2091 /* remove all power */
2092
2093 immap->im_ioport.iop_pcdat |= 0x0400;
2094 immap->im_ioport.iop_padat |= 0x0200;
2095
2096 /*
2097 * Make sure there is a card in the slot, then configure the interface.
2098 */
2099 udelay(10000);
2100 debug ("[%d] %s: PIPR(%p)=0x%x\n",
2101 __LINE__,__FUNCTION__,
2102 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
wdenkea909b72002-11-21 23:11:29 +00002103 if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
wdenkc6097192002-11-03 00:24:07 +00002104 printf (" No Card found\n");
2105 return (1);
2106 }
2107
2108 /*
2109 * Power On.
2110 */
2111 mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
2112 reg = pcmp->pcmc_pipr;
2113 debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
2114 reg,
2115 (reg&PCMCIA_VS1(slot))?"n":"ff",
2116 (reg&PCMCIA_VS2(slot))?"n":"ff");
2117 if ((reg & mask) == mask) {
2118 immap->im_ioport.iop_pcdat &= ~(0x4000);
2119 puts (" 5.0V card found: ");
2120 } else {
2121 immap->im_ioport.iop_padat &= ~(0x0002);
2122 puts (" 3.3V card found: ");
2123 }
2124 immap->im_ioport.iop_pcdir |= 0x0400;
2125 immap->im_ioport.iop_padir |= 0x0200;
2126#if 0
2127 /* VCC switch error flag, PCMCIA slot INPACK_ pin */
2128 cp->cp_pbdir &= ~(0x0020 | 0x0010);
2129 cp->cp_pbpar &= ~(0x0020 | 0x0010);
2130 udelay(500000);
2131#endif
2132 debug ("Enable PCMCIA buffers and stop RESET\n");
2133 reg = PCMCIA_PGCRX(_slot_);
2134 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
2135 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
2136 PCMCIA_PGCRX(_slot_) = reg;
2137
2138 udelay(250000); /* some cards need >150 ms to come up :-( */
2139
2140 debug ("# hardware_enable done\n");
2141
2142 return (0);
2143}
2144
2145
wdenkc6097192002-11-03 00:24:07 +00002146#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
2147static int hardware_disable(int slot)
2148{
2149 volatile immap_t *immap;
2150 volatile pcmconf8xx_t *pcmp;
2151 u_long reg;
2152
2153 debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
2154
2155 immap = (immap_t *)CFG_IMMR;
2156 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
2157
2158 /* remove all power */
2159 immap->im_ioport.iop_pcdat |= 0x0400;
2160 immap->im_ioport.iop_padat |= 0x0200;
2161
2162 /* Configure PCMCIA General Control Register */
wdenkc6097192002-11-03 00:24:07 +00002163 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00002164 reg = 0;
wdenkc6097192002-11-03 00:24:07 +00002165 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
2166 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
2167 PCMCIA_PGCRX(_slot_) = reg;
2168
2169 udelay(10000);
2170
2171 return (0);
2172}
2173#endif /* CFG_CMD_PCMCIA */
2174
2175
wdenkc6097192002-11-03 00:24:07 +00002176static int voltage_set(int slot, int vcc, int vpp)
2177{
2178 volatile immap_t *immap;
2179 volatile pcmconf8xx_t *pcmp;
2180 u_long reg;
2181
2182 debug ("voltage_set: "
2183 PCMCIA_BOARD_MSG
2184 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
2185 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
2186
2187 immap = (immap_t *)CFG_IMMR;
2188 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
2189 /*
2190 * Disable PCMCIA buffers (isolate the interface)
2191 * and assert RESET signal
2192 */
2193 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00002194 reg = PCMCIA_PGCRX(_slot_);
2195 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
2196 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkc6097192002-11-03 00:24:07 +00002197 PCMCIA_PGCRX(_slot_) = reg;
2198 udelay(500);
2199
2200 /*
2201 * Configure Ports A & C pins for
2202 * 5 Volts Enable and 3 Volts enable,
2203 * Turn off all power
2204 */
2205 debug ("PCMCIA power OFF\n");
2206 immap->im_ioport.iop_pcpar &= ~(0x0400);
2207 immap->im_ioport.iop_pcso &= ~(0x0400);/*
2208 immap->im_ioport.iop_pcdir |= 0x0400;*/
2209
2210 immap->im_ioport.iop_papar &= ~(0x0200);/*
2211 immap->im_ioport.iop_padir |= 0x0200;*/
2212
2213 immap->im_ioport.iop_pcdat |= 0x0400;
2214 immap->im_ioport.iop_padat |= 0x0200;
2215
2216 reg = 0;
2217 switch(vcc) {
2218 case 0: break;
2219 case 33: reg |= 0x0200; break;
2220 case 50: reg |= 0x0400; break;
2221 default: goto done;
2222 }
2223
2224 /* Checking supported voltages */
2225
2226 debug ("PIPR: 0x%x --> %s\n",
2227 pcmp->pcmc_pipr,
2228 (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
2229
2230 if (reg & 0x0200)
2231 immap->im_ioport.iop_pcdat &= !reg;
2232 if (reg & 0x0400)
2233 immap->im_ioport.iop_padat &= !reg;
wdenk1f53a412002-12-04 23:39:58 +00002234 immap->im_ioport.iop_pcdir |= 0x0200;
2235 immap->im_ioport.iop_padir |= 0x0400;
wdenkc6097192002-11-03 00:24:07 +00002236 if (reg) {
2237 debug ("PCMCIA powered at %sV\n",
2238 (reg&0x0400) ? "5.0" : "3.3");
2239 } else {
2240 debug ("PCMCIA powered down\n");
2241 }
2242
2243done:
2244 debug ("Enable PCMCIA buffers and stop RESET\n");
2245 reg = PCMCIA_PGCRX(_slot_);
2246 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
2247 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
2248 PCMCIA_PGCRX(_slot_) = reg;
2249 udelay(500);
2250
2251 debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
2252 slot+'A');
2253 return (0);
2254}
2255
2256#endif /* R360MPI */
2257
wdenk1f53a412002-12-04 23:39:58 +00002258/* -------------------------------------------------------------------- */
wdenk0608e042004-03-25 19:29:38 +00002259/* KUP4K and KUP4X Boards */
wdenk1f53a412002-12-04 23:39:58 +00002260/* -------------------------------------------------------------------- */
wdenk0608e042004-03-25 19:29:38 +00002261#if defined(CONFIG_KUP4K) || defined(CONFIG_KUP4X)
wdenk56f94be2002-11-05 16:35:14 +00002262
wdenk0608e042004-03-25 19:29:38 +00002263#define PCMCIA_BOARD_MSG "KUP"
wdenk56f94be2002-11-05 16:35:14 +00002264
2265#define KUP4K_PCMCIA_B_3V3 (0x00020000)
2266
2267static int hardware_enable(int slot)
2268{
2269 volatile immap_t *immap;
2270 volatile cpm8xx_t *cp;
2271 volatile pcmconf8xx_t *pcmp;
2272 volatile sysconf8xx_t *sysp;
2273 uint reg, mask;
2274
2275 debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
2276
2277 udelay(10000);
2278
2279 immap = (immap_t *)CFG_IMMR;
2280 sysp = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
2281 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
2282 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
2283
2284 /*
2285 * Configure SIUMCR to enable PCMCIA port B
2286 * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
2287 */
2288 sysp->sc_siumcr &= ~SIUMCR_DBGC11; /* set DBGC to 00 */
2289
2290 /* clear interrupt state, and disable interrupts */
wdenkea909b72002-11-21 23:11:29 +00002291 pcmp->pcmc_pscr = PCMCIA_MASK(slot);
2292 pcmp->pcmc_per &= ~PCMCIA_MASK(slot);
wdenk56f94be2002-11-05 16:35:14 +00002293
wdenk56f94be2002-11-05 16:35:14 +00002294 /*
wdenk1f53a412002-12-04 23:39:58 +00002295 * Disable interrupts, DMA, and PCMCIA buffers
2296 * (isolate the interface) and assert RESET signal
wdenk56f94be2002-11-05 16:35:14 +00002297 */
2298 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00002299 reg = 0;
2300 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
2301 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkea909b72002-11-21 23:11:29 +00002302 PCMCIA_PGCRX(slot) = reg;
2303 udelay(2500);
wdenk56f94be2002-11-05 16:35:14 +00002304
2305 /*
2306 * Configure Port B pins for
2307 * 3 Volts enable
2308 */
wdenkea909b72002-11-21 23:11:29 +00002309 if (slot) { /* Slot A is built-in */
2310 cp->cp_pbdir |= KUP4K_PCMCIA_B_3V3;
2311 cp->cp_pbpar &= ~KUP4K_PCMCIA_B_3V3;
2312 /* remove all power */
2313 cp->cp_pbdat |= KUP4K_PCMCIA_B_3V3; /* active low */
2314 }
wdenk56f94be2002-11-05 16:35:14 +00002315 /*
2316 * Make sure there is a card in the slot, then configure the interface.
2317 */
2318 udelay(10000);
2319 debug ("[%d] %s: PIPR(%p)=0x%x\n",
2320 __LINE__,__FUNCTION__,
2321 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
wdenkea909b72002-11-21 23:11:29 +00002322 if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
wdenk56f94be2002-11-05 16:35:14 +00002323 printf (" No Card found\n");
2324 return (1);
2325 }
2326
2327 /*
2328 * Power On.
2329 */
wdenka6c7ad22002-12-03 21:28:10 +00002330 printf("%s Slot %c:", slot ? "" : "\n", 'A' + slot);
wdenk56f94be2002-11-05 16:35:14 +00002331 mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
2332 reg = pcmp->pcmc_pipr;
2333 debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
2334 reg,
2335 (reg&PCMCIA_VS1(slot))?"n":"ff",
2336 (reg&PCMCIA_VS2(slot))?"n":"ff");
2337 if ((reg & mask) == mask) {
2338 puts (" 5.0V card found: NOT SUPPORTED !!!\n");
2339 } else {
wdenkea909b72002-11-21 23:11:29 +00002340 if(slot)
2341 cp->cp_pbdat &= ~KUP4K_PCMCIA_B_3V3;
wdenk56f94be2002-11-05 16:35:14 +00002342 puts (" 3.3V card found: ");
2343 }
2344#if 0
2345 /* VCC switch error flag, PCMCIA slot INPACK_ pin */
2346 cp->cp_pbdir &= ~(0x0020 | 0x0010);
2347 cp->cp_pbpar &= ~(0x0020 | 0x0010);
2348 udelay(500000);
2349#endif
2350 debug ("Enable PCMCIA buffers and stop RESET\n");
wdenkea909b72002-11-21 23:11:29 +00002351 reg = PCMCIA_PGCRX(slot);
wdenk56f94be2002-11-05 16:35:14 +00002352 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
2353 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkea909b72002-11-21 23:11:29 +00002354 PCMCIA_PGCRX(slot) = reg;
wdenk56f94be2002-11-05 16:35:14 +00002355
2356 udelay(250000); /* some cards need >150 ms to come up :-( */
2357
2358 debug ("# hardware_enable done\n");
2359
2360 return (0);
2361}
2362
2363
wdenk56f94be2002-11-05 16:35:14 +00002364#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
2365static int hardware_disable(int slot)
2366{
2367 volatile immap_t *immap;
2368 volatile cpm8xx_t *cp;
2369 volatile pcmconf8xx_t *pcmp;
2370 u_long reg;
2371
2372 debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
2373
2374 immap = (immap_t *)CFG_IMMR;
2375 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
2376 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
wdenk1f53a412002-12-04 23:39:58 +00002377
wdenk56f94be2002-11-05 16:35:14 +00002378 /* remove all power */
wdenkea909b72002-11-21 23:11:29 +00002379 if (slot)
2380 cp->cp_pbdat |= KUP4K_PCMCIA_B_3V3;
wdenk56f94be2002-11-05 16:35:14 +00002381
2382 /* Configure PCMCIA General Control Register */
wdenk56f94be2002-11-05 16:35:14 +00002383 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00002384 reg = 0;
wdenk56f94be2002-11-05 16:35:14 +00002385 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
2386 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkea909b72002-11-21 23:11:29 +00002387 PCMCIA_PGCRX(slot) = reg;
wdenk56f94be2002-11-05 16:35:14 +00002388
2389 udelay(10000);
2390
2391 return (0);
2392}
2393#endif /* CFG_CMD_PCMCIA */
2394
2395
wdenk56f94be2002-11-05 16:35:14 +00002396static int voltage_set(int slot, int vcc, int vpp)
2397{
2398 volatile immap_t *immap;
2399 volatile cpm8xx_t *cp;
2400 volatile pcmconf8xx_t *pcmp;
2401 u_long reg;
2402
2403 debug ("voltage_set: " \
2404 PCMCIA_BOARD_MSG \
2405 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
2406 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
2407
wdenkea909b72002-11-21 23:11:29 +00002408 if (!slot) /* Slot A is not configurable */
2409 return 0;
2410
wdenk56f94be2002-11-05 16:35:14 +00002411 immap = (immap_t *)CFG_IMMR;
2412 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
2413 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
2414
2415 /*
2416 * Disable PCMCIA buffers (isolate the interface)
2417 * and assert RESET signal
2418 */
2419 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00002420 reg = PCMCIA_PGCRX(slot);
2421 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
2422 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkea909b72002-11-21 23:11:29 +00002423 PCMCIA_PGCRX(slot) = reg;
wdenk56f94be2002-11-05 16:35:14 +00002424 udelay(500);
2425
2426 debug ("PCMCIA power OFF\n");
2427 /*
2428 * Configure Port B pins for
2429 * 3 Volts enable
2430 */
2431 cp->cp_pbdir |= KUP4K_PCMCIA_B_3V3;
2432 cp->cp_pbpar &= ~KUP4K_PCMCIA_B_3V3;
2433 /* remove all power */
2434 cp->cp_pbdat |= KUP4K_PCMCIA_B_3V3; /* active low */
2435
2436 switch(vcc) {
2437 case 0: break;
2438 case 33:
2439 cp->cp_pbdat &= ~KUP4K_PCMCIA_B_3V3;
2440 debug ("PCMCIA powered at 3.3V\n");
2441 break;
2442 case 50:
2443 debug ("PCMCIA: 5Volt vcc not supported\n");
2444 break;
2445 default:
2446 puts("PCMCIA: vcc not supported");
2447 break;
2448 }
wdenkea909b72002-11-21 23:11:29 +00002449 udelay(10000);
wdenk56f94be2002-11-05 16:35:14 +00002450 /* Checking supported voltages */
2451
2452 debug ("PIPR: 0x%x --> %s\n",
2453 pcmp->pcmc_pipr,
wdenkea909b72002-11-21 23:11:29 +00002454 (pcmp->pcmc_pipr & (0x80000000 >> (slot << 4)))
wdenk56f94be2002-11-05 16:35:14 +00002455 ? "only 5 V --> NOT SUPPORTED"
2456 : "can do 3.3V");
2457
2458
2459 debug ("Enable PCMCIA buffers and stop RESET\n");
wdenkea909b72002-11-21 23:11:29 +00002460 reg = PCMCIA_PGCRX(slot);
wdenk56f94be2002-11-05 16:35:14 +00002461 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
2462 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkea909b72002-11-21 23:11:29 +00002463 PCMCIA_PGCRX(slot) = reg;
wdenk56f94be2002-11-05 16:35:14 +00002464 udelay(500);
2465
2466 debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
2467 slot+'A');
2468 return (0);
2469}
2470
wdenk0608e042004-03-25 19:29:38 +00002471#endif /* KUP4K || KUP4X */
wdenk56f94be2002-11-05 16:35:14 +00002472
2473
wdenk1f53a412002-12-04 23:39:58 +00002474/* -------------------------------------------------------------------- */
2475/* End of Board Specific Stuff */
2476/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00002477
2478
wdenk1f53a412002-12-04 23:39:58 +00002479/* -------------------------------------------------------------------- */
2480/* MPC8xx Specific Stuff - should go to MPC8xx directory */
2481/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00002482
2483/*
2484 * Search this table to see if the windowsize is
2485 * supported...
2486 */
2487
2488#define M8XX_SIZES_NO 32
2489
2490static const u_int m8xx_size_to_gray[M8XX_SIZES_NO] =
2491{ 0x00000001, 0x00000002, 0x00000008, 0x00000004,
2492 0x00000080, 0x00000040, 0x00000010, 0x00000020,
2493 0x00008000, 0x00004000, 0x00001000, 0x00002000,
2494 0x00000100, 0x00000200, 0x00000800, 0x00000400,
2495
2496 0x0fffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2497 0x01000000, 0x02000000, 0xffffffff, 0x04000000,
2498 0x00010000, 0x00020000, 0x00080000, 0x00040000,
2499 0x00800000, 0x00400000, 0x00100000, 0x00200000 };
2500
2501
wdenk1f53a412002-12-04 23:39:58 +00002502/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00002503
wdenkdb01a2e2004-04-15 23:14:49 +00002504#if ( ! defined(CONFIG_I82365) && ! defined(CONFIG_PXA_PCMCIA) )
wdenk7f70e852003-05-20 14:25:27 +00002505
wdenkc6097192002-11-03 00:24:07 +00002506static u_int m8xx_get_graycode(u_int size)
2507{
2508 u_int k;
2509
2510 for (k = 0; k < M8XX_SIZES_NO; k++) {
2511 if(m8xx_size_to_gray[k] == size)
2512 break;
2513 }
2514
2515 if((k == M8XX_SIZES_NO) || (m8xx_size_to_gray[k] == -1))
2516 k = -1;
2517
2518 return k;
2519}
2520
wdenk7f70e852003-05-20 14:25:27 +00002521#endif /* CONFIG_I82365 */
2522
wdenk1f53a412002-12-04 23:39:58 +00002523/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00002524
2525#if 0
2526static u_int m8xx_get_speed(u_int ns, u_int is_io)
2527{
2528 u_int reg, clocks, psst, psl, psht;
2529
2530 if(!ns) {
2531
2532 /*
2533 * We get called with IO maps setup to 0ns
2534 * if not specified by the user.
2535 * They should be 255ns.
2536 */
2537
2538 if(is_io)
2539 ns = 255;
2540 else
2541 ns = 100; /* fast memory if 0 */
2542 }
2543
2544 /*
2545 * In PSST, PSL, PSHT fields we tell the controller
2546 * timing parameters in CLKOUT clock cycles.
2547 * CLKOUT is the same as GCLK2_50.
2548 */
2549
2550/* how we want to adjust the timing - in percent */
2551
2552#define ADJ 180 /* 80 % longer accesstime - to be sure */
2553
2554 clocks = ((M8XX_BUSFREQ / 1000) * ns) / 1000;
2555 clocks = (clocks * ADJ) / (100*1000);
2556
2557 if(clocks >= PCMCIA_BMT_LIMIT) {
2558 DEBUG(0, "Max access time limit reached\n");
2559 clocks = PCMCIA_BMT_LIMIT-1;
2560 }
2561
2562 psst = clocks / 7; /* setup time */
2563 psht = clocks / 7; /* hold time */
2564 psl = (clocks * 5) / 7; /* strobe length */
2565
2566 psst += clocks - (psst + psht + psl);
2567
2568 reg = psst << 12;
2569 reg |= psl << 7;
2570 reg |= psht << 16;
2571
2572 return reg;
2573}
2574#endif
2575
wdenk1f53a412002-12-04 23:39:58 +00002576/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00002577
wdenkdb01a2e2004-04-15 23:14:49 +00002578#if defined(CONFIG_IDE_8xx_PCCARD) || defined(CONFIG_PXA_PCMCIA)
wdenkc6097192002-11-03 00:24:07 +00002579static void print_funcid (int func)
2580{
2581 puts (indent);
2582 switch (func) {
2583 case CISTPL_FUNCID_MULTI:
2584 puts (" Multi-Function");
2585 break;
2586 case CISTPL_FUNCID_MEMORY:
2587 puts (" Memory");
2588 break;
2589 case CISTPL_FUNCID_SERIAL:
2590 puts (" Serial Port");
2591 break;
2592 case CISTPL_FUNCID_PARALLEL:
2593 puts (" Parallel Port");
2594 break;
2595 case CISTPL_FUNCID_FIXED:
2596 puts (" Fixed Disk");
2597 break;
2598 case CISTPL_FUNCID_VIDEO:
2599 puts (" Video Adapter");
2600 break;
2601 case CISTPL_FUNCID_NETWORK:
2602 puts (" Network Adapter");
2603 break;
2604 case CISTPL_FUNCID_AIMS:
2605 puts (" AIMS Card");
2606 break;
2607 case CISTPL_FUNCID_SCSI:
2608 puts (" SCSI Adapter");
2609 break;
2610 default:
2611 puts (" Unknown");
2612 break;
2613 }
2614 puts (" Card\n");
2615}
2616#endif /* CONFIG_IDE_8xx_PCCARD */
2617
wdenk1f53a412002-12-04 23:39:58 +00002618/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00002619
wdenkdb01a2e2004-04-15 23:14:49 +00002620#if defined(CONFIG_IDE_8xx_PCCARD) || defined(CONFIG_PXA_PCMCIA)
wdenkc6097192002-11-03 00:24:07 +00002621static void print_fixed (volatile uchar *p)
2622{
2623 if (p == NULL)
2624 return;
2625
2626 puts(indent);
2627
2628 switch (*p) {
2629 case CISTPL_FUNCE_IDE_IFACE:
2630 { uchar iface = *(p+2);
2631
2632 puts ((iface == CISTPL_IDE_INTERFACE) ? " IDE" : " unknown");
2633 puts (" interface ");
2634 break;
2635 }
2636 case CISTPL_FUNCE_IDE_MASTER:
2637 case CISTPL_FUNCE_IDE_SLAVE:
2638 { uchar f1 = *(p+2);
2639 uchar f2 = *(p+4);
2640
2641 puts ((f1 & CISTPL_IDE_SILICON) ? " [silicon]" : " [rotating]");
2642
2643 if (f1 & CISTPL_IDE_UNIQUE)
2644 puts (" [unique]");
2645
2646 puts ((f1 & CISTPL_IDE_DUAL) ? " [dual]" : " [single]");
2647
2648 if (f2 & CISTPL_IDE_HAS_SLEEP)
2649 puts (" [sleep]");
2650
2651 if (f2 & CISTPL_IDE_HAS_STANDBY)
2652 puts (" [standby]");
2653
2654 if (f2 & CISTPL_IDE_HAS_IDLE)
2655 puts (" [idle]");
2656
2657 if (f2 & CISTPL_IDE_LOW_POWER)
2658 puts (" [low power]");
2659
2660 if (f2 & CISTPL_IDE_REG_INHIBIT)
2661 puts (" [reg inhibit]");
2662
2663 if (f2 & CISTPL_IDE_HAS_INDEX)
2664 puts (" [index]");
2665
2666 if (f2 & CISTPL_IDE_IOIS16)
2667 puts (" [IOis16]");
2668
2669 break;
2670 }
2671 }
2672 putc ('\n');
2673}
2674#endif /* CONFIG_IDE_8xx_PCCARD */
2675
wdenk1f53a412002-12-04 23:39:58 +00002676/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00002677
wdenkdb01a2e2004-04-15 23:14:49 +00002678#if defined(CONFIG_IDE_8xx_PCCARD) || defined(CONFIG_PXA_PCMCIA)
wdenkc6097192002-11-03 00:24:07 +00002679
2680#define MAX_IDENT_CHARS 64
2681#define MAX_IDENT_FIELDS 4
2682
2683static uchar *known_cards[] = {
Wolfgang Denk77ddac92005-10-13 16:45:02 +02002684 (uchar *)"ARGOSY PnPIDE D5",
wdenkc6097192002-11-03 00:24:07 +00002685 NULL
2686};
2687
2688static int identify (volatile uchar *p)
2689{
2690 uchar id_str[MAX_IDENT_CHARS];
2691 uchar data;
2692 uchar *t;
2693 uchar **card;
2694 int i, done;
2695
2696 if (p == NULL)
2697 return (0); /* Don't know */
2698
2699 t = id_str;
2700 done =0;
2701
2702 for (i=0; i<=4 && !done; ++i, p+=2) {
2703 while ((data = *p) != '\0') {
2704 if (data == 0xFF) {
2705 done = 1;
2706 break;
2707 }
2708 *t++ = data;
2709 if (t == &id_str[MAX_IDENT_CHARS-1]) {
2710 done = 1;
2711 break;
2712 }
2713 p += 2;
2714 }
2715 if (!done)
2716 *t++ = ' ';
2717 }
2718 *t = '\0';
2719 while (--t > id_str) {
2720 if (*t == ' ')
2721 *t = '\0';
2722 else
2723 break;
2724 }
Wolfgang Denk77ddac92005-10-13 16:45:02 +02002725 puts ((char *)id_str);
wdenkc6097192002-11-03 00:24:07 +00002726 putc ('\n');
2727
2728 for (card=known_cards; *card; ++card) {
2729 debug ("## Compare against \"%s\"\n", *card);
Wolfgang Denk77ddac92005-10-13 16:45:02 +02002730 if (strcmp((char *)*card, (char *)id_str) == 0) { /* found! */
wdenkc6097192002-11-03 00:24:07 +00002731 debug ("## CARD FOUND ##\n");
2732 return (1);
2733 }
2734 }
2735
2736 return (0); /* don't know */
2737}
2738#endif /* CONFIG_IDE_8xx_PCCARD */
2739
wdenk1f53a412002-12-04 23:39:58 +00002740/* -------------------------------------------------------------------- */
wdenk04a85b32004-04-15 18:22:41 +00002741/* NETTA board by Intracom S.A. */
2742/* -------------------------------------------------------------------- */
2743
2744#if defined(CONFIG_NETTA)
2745
2746/* some sane bit macros */
2747#define _BD(_b) (1U << (31-(_b)))
2748#define _BDR(_l, _h) (((((1U << (31-(_l))) - 1) << 1) | 1) & ~((1U << (31-(_h))) - 1))
2749
2750#define _BW(_b) (1U << (15-(_b)))
2751#define _BWR(_l, _h) (((((1U << (15-(_l))) - 1) << 1) | 1) & ~((1U << (15-(_h))) - 1))
2752
2753#define _BB(_b) (1U << (7-(_b)))
2754#define _BBR(_l, _h) (((((1U << (7-(_l))) - 1) << 1) | 1) & ~((1U << (7-(_h))) - 1))
2755
2756#define _B(_b) _BD(_b)
2757#define _BR(_l, _h) _BDR(_l, _h)
2758
2759#define PCMCIA_BOARD_MSG "NETTA"
2760
2761static const unsigned short vppd_masks[2] = { _BW(14), _BW(15) };
2762
2763static void cfg_vppd(int no)
2764{
2765 volatile immap_t *immap = (immap_t *)CFG_IMMR;
2766 unsigned short mask;
2767
2768 if ((unsigned int)no >= sizeof(vppd_masks)/sizeof(vppd_masks[0]))
2769 return;
2770
2771 mask = vppd_masks[no];
2772
2773 immap->im_ioport.iop_papar &= ~mask;
2774 immap->im_ioport.iop_paodr &= ~mask;
2775 immap->im_ioport.iop_padir |= mask;
2776}
2777
2778static void set_vppd(int no, int what)
2779{
2780 volatile immap_t *immap = (immap_t *)CFG_IMMR;
2781 unsigned short mask;
2782
2783 if ((unsigned int)no >= sizeof(vppd_masks)/sizeof(vppd_masks[0]))
2784 return;
2785
2786 mask = vppd_masks[no];
2787
2788 if (what)
2789 immap->im_ioport.iop_padat |= mask;
2790 else
2791 immap->im_ioport.iop_padat &= ~mask;
2792}
2793
2794static const unsigned short vccd_masks[2] = { _BW(10), _BW(6) };
2795
2796static void cfg_vccd(int no)
2797{
2798 volatile immap_t *immap = (immap_t *)CFG_IMMR;
2799 unsigned short mask;
2800
2801 if ((unsigned int)no >= sizeof(vccd_masks)/sizeof(vccd_masks[0]))
2802 return;
2803
2804 mask = vccd_masks[no];
2805
2806 immap->im_ioport.iop_papar &= ~mask;
2807 immap->im_ioport.iop_paodr &= ~mask;
2808 immap->im_ioport.iop_padir |= mask;
2809}
2810
2811static void set_vccd(int no, int what)
2812{
2813 volatile immap_t *immap = (immap_t *)CFG_IMMR;
2814 unsigned short mask;
2815
2816 if ((unsigned int)no >= sizeof(vccd_masks)/sizeof(vccd_masks[0]))
2817 return;
2818
2819 mask = vccd_masks[no];
2820
2821 if (what)
2822 immap->im_ioport.iop_padat |= mask;
2823 else
2824 immap->im_ioport.iop_padat &= ~mask;
2825}
2826
2827static const unsigned short oc_mask = _BW(8);
2828
2829static void cfg_oc(void)
2830{
2831 volatile immap_t *immap = (immap_t *)CFG_IMMR;
2832 unsigned short mask = oc_mask;
2833
2834 immap->im_ioport.iop_pcdir &= ~mask;
2835 immap->im_ioport.iop_pcso &= ~mask;
2836 immap->im_ioport.iop_pcint &= ~mask;
2837 immap->im_ioport.iop_pcpar &= ~mask;
2838}
2839
2840static int get_oc(void)
2841{
2842 volatile immap_t *immap = (immap_t *)CFG_IMMR;
2843 unsigned short mask = oc_mask;
2844 int what;
2845
2846 what = !!(immap->im_ioport.iop_pcdat & mask);;
2847 return what;
2848}
2849
2850static const unsigned short shdn_mask = _BW(12);
2851
2852static void cfg_shdn(void)
2853{
2854 volatile immap_t *immap = (immap_t *)CFG_IMMR;
2855 unsigned short mask;
2856
2857 mask = shdn_mask;
2858
2859 immap->im_ioport.iop_papar &= ~mask;
2860 immap->im_ioport.iop_paodr &= ~mask;
2861 immap->im_ioport.iop_padir |= mask;
2862}
2863
2864static void set_shdn(int what)
2865{
2866 volatile immap_t *immap = (immap_t *)CFG_IMMR;
2867 unsigned short mask;
2868
2869 mask = shdn_mask;
2870
2871 if (what)
2872 immap->im_ioport.iop_padat |= mask;
2873 else
2874 immap->im_ioport.iop_padat &= ~mask;
2875}
2876
2877static void cfg_ports (void);
2878
2879static int hardware_enable(int slot)
2880{
2881 volatile immap_t *immap;
2882 volatile cpm8xx_t *cp;
2883 volatile pcmconf8xx_t *pcmp;
2884 volatile sysconf8xx_t *sysp;
2885 uint reg, pipr, mask;
2886 int i;
2887
2888 debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
2889
2890 udelay(10000);
2891
2892 immap = (immap_t *)CFG_IMMR;
2893 sysp = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
2894 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
2895 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
2896
2897 /* Configure Ports for TPS2211A PC-Card Power-Interface Switch */
2898 cfg_ports ();
2899
2900 /* clear interrupt state, and disable interrupts */
2901 pcmp->pcmc_pscr = PCMCIA_MASK(_slot_);
2902 pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
2903
2904 /*
2905 * Disable interrupts, DMA, and PCMCIA buffers
2906 * (isolate the interface) and assert RESET signal
2907 */
2908 debug ("Disable PCMCIA buffers and assert RESET\n");
2909 reg = 0;
2910 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
2911 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
2912 PCMCIA_PGCRX(_slot_) = reg;
2913
2914 udelay(500);
2915
2916 /*
2917 * Make sure there is a card in the slot, then configure the interface.
2918 */
2919 udelay(10000);
2920 debug ("[%d] %s: PIPR(%p)=0x%x\n",
2921 __LINE__,__FUNCTION__,
2922 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
2923 if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
2924 printf (" No Card found\n");
2925 return (1);
2926 }
2927
2928 /*
2929 * Power On: Set VAVCC to 3.3V or 5V, set VAVPP to Hi-Z
2930 */
2931 mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
2932 pipr = pcmp->pcmc_pipr;
2933 debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
2934 pipr,
2935 (reg&PCMCIA_VS1(slot))?"n":"ff",
2936 (reg&PCMCIA_VS2(slot))?"n":"ff");
2937
2938 if ((pipr & mask) == mask) {
2939 set_vppd(0, 1); set_vppd(1, 1); /* VAVPP => Hi-Z */
2940 set_vccd(0, 0); set_vccd(1, 1); /* 5V on, 3V off */
2941 puts (" 5.0V card found: ");
2942 } else {
2943 set_vppd(0, 1); set_vppd(1, 1); /* VAVPP => Hi-Z */
2944 set_vccd(0, 1); set_vccd(1, 0); /* 5V off, 3V on */
2945 puts (" 3.3V card found: ");
2946 }
2947
2948 /* Wait 500 ms; use this to check for over-current */
2949 for (i=0; i<5000; ++i) {
2950 if (!get_oc()) {
2951 printf (" *** Overcurrent - Safety shutdown ***\n");
2952 set_vccd(0, 0); set_vccd(1, 0); /* VAVPP => Hi-Z */
2953 return (1);
2954 }
2955 udelay (100);
2956 }
2957
2958 debug ("Enable PCMCIA buffers and stop RESET\n");
2959 reg = PCMCIA_PGCRX(_slot_);
2960 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
2961 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
2962 PCMCIA_PGCRX(_slot_) = reg;
2963
2964 udelay(250000); /* some cards need >150 ms to come up :-( */
2965
2966 debug ("# hardware_enable done\n");
2967
2968 return (0);
2969}
2970
2971
2972#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
2973static int hardware_disable(int slot)
2974{
2975 volatile immap_t *immap;
2976 volatile pcmconf8xx_t *pcmp;
2977 u_long reg;
2978
2979 debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
2980
2981 immap = (immap_t *)CFG_IMMR;
2982 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
2983
2984 /* Configure PCMCIA General Control Register */
2985 debug ("Disable PCMCIA buffers and assert RESET\n");
2986 reg = 0;
2987 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
2988 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
2989 PCMCIA_PGCRX(_slot_) = reg;
2990
2991 /* All voltages off / Hi-Z */
2992 set_vppd(0, 1); set_vppd(1, 1);
2993 set_vccd(0, 1); set_vccd(1, 1);
2994
2995 udelay(10000);
2996
2997 return (0);
2998}
2999#endif /* CFG_CMD_PCMCIA */
3000
3001
3002static int voltage_set(int slot, int vcc, int vpp)
3003{
3004 volatile immap_t *immap;
3005 volatile cpm8xx_t *cp;
3006 volatile pcmconf8xx_t *pcmp;
3007 u_long reg;
3008 ushort sreg;
3009
3010 debug ("voltage_set: "
3011 PCMCIA_BOARD_MSG
3012 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
3013 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
3014
3015 immap = (immap_t *)CFG_IMMR;
3016 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
3017 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
3018 /*
3019 * Disable PCMCIA buffers (isolate the interface)
3020 * and assert RESET signal
3021 */
3022 debug ("Disable PCMCIA buffers and assert RESET\n");
3023 reg = PCMCIA_PGCRX(_slot_);
3024 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
3025 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
3026 PCMCIA_PGCRX(_slot_) = reg;
3027 udelay(500);
3028
3029 /*
3030 * Configure Port C pins for
3031 * 5 Volts Enable and 3 Volts enable,
3032 * Turn all power pins to Hi-Z
3033 */
3034 debug ("PCMCIA power OFF\n");
3035 cfg_ports (); /* Enables switch, but all in Hi-Z */
3036
3037 sreg = immap->im_ioport.iop_pcdat;
3038 set_vppd(0, 1); set_vppd(1, 1);
3039
3040 switch(vcc) {
3041 case 0:
3042 break; /* Switch off */
3043
3044 case 33:
3045 set_vccd(0, 1); set_vccd(1, 0);
3046 break;
3047
3048 case 50:
3049 set_vccd(0, 0); set_vccd(1, 1);
3050 break;
3051
3052 default:
3053 goto done;
3054 }
3055
3056 /* Checking supported voltages */
3057
3058 debug ("PIPR: 0x%x --> %s\n",
3059 pcmp->pcmc_pipr,
3060 (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
3061
3062done:
3063 debug ("Enable PCMCIA buffers and stop RESET\n");
3064 reg = PCMCIA_PGCRX(_slot_);
3065 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
3066 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
3067 PCMCIA_PGCRX(_slot_) = reg;
3068 udelay(500);
3069
3070 debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
3071 slot+'A');
3072 return (0);
3073}
3074
3075static void cfg_ports (void)
3076{
3077 volatile immap_t *immap;
3078 volatile cpm8xx_t *cp;
3079
3080 immap = (immap_t *)CFG_IMMR;
3081 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
3082
3083
3084 cfg_vppd(0); cfg_vppd(1); /* VPPD0,VPPD1 VAVPP => Hi-Z */
3085 cfg_vccd(0); cfg_vccd(1); /* 3V and 5V off */
3086 cfg_shdn();
3087 cfg_oc();
3088
3089 /*
3090 * Configure Port A for TPS2211 PC-Card Power-Interface Switch
3091 *
3092 * Switch off all voltages, assert shutdown
3093 */
3094 set_vppd(0, 1); set_vppd(1, 1);
3095 set_vccd(0, 0); set_vccd(1, 0);
3096 set_shdn(1);
3097
3098 udelay(100000);
3099}
3100
3101#endif /* NETTA */
3102
3103
3104/* -------------------------------------------------------------------- */
wdenkf7d15722004-12-18 22:35:43 +00003105/* UC100 Boards */
3106/* -------------------------------------------------------------------- */
3107
3108#if defined(CONFIG_UC100)
3109
3110#define PCMCIA_BOARD_MSG "UC100"
3111
3112/*
3113 * Remark: don't turn off OE "__MY_PCMCIA_GCRX_CXOE" on UC100 board.
3114 * This leads to board-hangup! (sr, 8 Dez. 2004)
3115 */
3116
3117static void cfg_ports (void);
3118
3119static int hardware_enable(int slot)
3120{
3121 volatile immap_t *immap;
3122 volatile cpm8xx_t *cp;
3123 volatile pcmconf8xx_t *pcmp;
3124 volatile sysconf8xx_t *sysp;
3125 uint reg, mask;
3126
3127 debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
3128
3129 udelay(10000);
3130
3131 immap = (immap_t *)CFG_IMMR;
3132 sysp = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
3133 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
3134 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
3135
3136 /* Configure Ports for TPS2211A PC-Card Power-Interface Switch */
3137 cfg_ports ();
3138
3139 /*
3140 * Configure SIUMCR to enable PCMCIA port B
3141 * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
3142 */
3143 sysp->sc_siumcr &= ~SIUMCR_DBGC11; /* set DBGC to 00 */
3144
3145 /* clear interrupt state, and disable interrupts */
3146 pcmp->pcmc_pscr = PCMCIA_MASK(_slot_);
3147 pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
3148
3149 /*
3150 * Disable interrupts, DMA, and PCMCIA buffers
3151 * (isolate the interface) and assert RESET signal
3152 */
3153 debug ("Disable PCMCIA buffers and assert RESET\n");
3154 reg = 0;
3155 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
3156 PCMCIA_PGCRX(_slot_) = reg;
3157 udelay(500);
3158
3159 /*
3160 * Make sure there is a card in the slot, then configure the interface.
3161 */
3162 udelay(10000);
3163 debug ("[%d] %s: PIPR(%p)=0x%x\n",
3164 __LINE__,__FUNCTION__,
3165 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
3166 if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
3167 printf (" No Card found\n");
3168 return (1);
3169 }
3170
3171 /*
3172 * Power On.
3173 */
3174 mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
3175 reg = pcmp->pcmc_pipr;
3176 debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
3177 reg,
3178 (reg&PCMCIA_VS1(slot))?"n":"ff",
3179 (reg&PCMCIA_VS2(slot))?"n":"ff");
3180 if ((reg & mask) == mask) {
3181 puts (" 5.0V card found: ");
3182 } else {
3183 puts (" 3.3V card found: ");
3184 }
3185
3186 /* switch VCC on */
3187 immap->im_ioport.iop_padat |= 0x8000; /* power enable 3.3V */
3188
3189 udelay(10000);
3190
3191 debug ("Enable PCMCIA buffers and stop RESET\n");
3192 reg = PCMCIA_PGCRX(_slot_);
3193 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
3194 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
3195 PCMCIA_PGCRX(_slot_) = reg;
3196
3197 udelay(250000); /* some cards need >150 ms to come up :-( */
3198
3199 debug ("# hardware_enable done\n");
3200
3201 return (0);
3202}
3203
3204
3205#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
3206static int hardware_disable(int slot)
3207{
3208 volatile immap_t *immap;
3209 volatile cpm8xx_t *cp;
3210 volatile pcmconf8xx_t *pcmp;
3211 u_long reg;
3212
3213 debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
3214
3215 immap = (immap_t *)CFG_IMMR;
3216 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
3217
3218 /* switch VCC off */
3219 immap->im_ioport.iop_padat &= ~0x8000; /* power disable 3.3V */
3220
3221 /* Configure PCMCIA General Control Register */
3222 debug ("Disable PCMCIA buffers and assert RESET\n");
3223 reg = 0;
3224 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
3225 PCMCIA_PGCRX(_slot_) = reg;
3226
3227 udelay(10000);
3228
3229 return (0);
3230}
3231#endif /* CFG_CMD_PCMCIA */
3232
3233
3234static int voltage_set(int slot, int vcc, int vpp)
3235{
3236 volatile immap_t *immap;
3237 volatile pcmconf8xx_t *pcmp;
3238 u_long reg;
3239
3240 debug ("voltage_set: "
3241 PCMCIA_BOARD_MSG
3242 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
3243 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
3244
3245 immap = (immap_t *)CFG_IMMR;
3246 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
3247 /*
3248 * Disable PCMCIA buffers (isolate the interface)
3249 * and assert RESET signal
3250 */
3251 debug ("Disable PCMCIA buffers and assert RESET\n");
3252 reg = PCMCIA_PGCRX(_slot_);
3253 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
3254 PCMCIA_PGCRX(_slot_) = reg;
3255 udelay(500);
3256
3257 /*
3258 * Configure Port C pins for
3259 * 5 Volts Enable and 3 Volts enable,
3260 * Turn all power pins to Hi-Z
3261 */
3262 debug ("PCMCIA power OFF\n");
3263 cfg_ports (); /* Enables switch, but all in Hi-Z */
3264
3265 debug ("Enable PCMCIA buffers and stop RESET\n");
3266 reg = PCMCIA_PGCRX(_slot_);
3267 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
3268 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
3269 PCMCIA_PGCRX(_slot_) = reg;
3270 udelay(500);
3271
3272 debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
3273 slot+'A');
3274 return (0);
3275}
3276
3277static void cfg_ports (void)
3278{
3279 volatile immap_t *immap;
3280
3281 immap = (immap_t *)CFG_IMMR;
3282
3283 /*
3284 * Configure Port A for MAX1602 PC-Card Power-Interface Switch
3285 */
3286 immap->im_ioport.iop_padat &= ~0x8000; /* set port x output to low */
3287 immap->im_ioport.iop_padir |= 0x8000; /* enable port x as output */
3288
3289 debug ("Set Port A: PAR: %08x DIR: %08x DAT: %08x\n",
3290 immap->im_ioport.iop_papar, immap->im_ioport.iop_padir,
3291 immap->im_ioport.iop_padat);
3292}
3293
3294#endif /* UC100 */
3295
3296
3297/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00003298
3299#endif /* CFG_CMD_PCMCIA || (CFG_CMD_IDE && CONFIG_IDE_8xx_PCCARD) */
wdenk8bde7f72003-06-27 21:31:46 +00003300
3301/**************************************************/
3302
3303#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
wdenk0d498392003-07-01 21:06:45 +00003304U_BOOT_CMD(
3305 pinit, 2, 1, do_pinit,
wdenk8bde7f72003-06-27 21:31:46 +00003306 "pinit - PCMCIA sub-system\n",
3307 "on - power on PCMCIA socket\n"
3308 "pinit off - power off PCMCIA socket\n"
3309);
3310#endif