blob: 9ff0949608e44f52937fbae6dc79729dd6abd63e [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
70#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA) || \
71 ((CONFIG_COMMANDS & CFG_CMD_IDE) && defined(CONFIG_IDE_8xx_PCCARD))
72
73int pcmcia_on (void);
74
75#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
76static int pcmcia_off (void);
wdenk66fd3d12003-05-18 11:30:09 +000077#endif
78
79#ifdef CONFIG_I82365
80
81extern int i82365_init (void);
82extern void i82365_exit (void);
83
84#else /* ! CONFIG_I82365 */
85
86#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
wdenkc6097192002-11-03 00:24:07 +000087static int hardware_disable(int slot);
88#endif
89static int hardware_enable (int slot);
90static int voltage_set(int slot, int vcc, int vpp);
wdenkc6097192002-11-03 00:24:07 +000091
wdenkdb01a2e2004-04-15 23:14:49 +000092#if (! defined(CONFIG_I82365)) && (! defined(CONFIG_PXA_PCMCIA))
wdenkc6097192002-11-03 00:24:07 +000093static u_int m8xx_get_graycode(u_int size);
wdenk6e592382004-04-18 17:39:38 +000094#endif /* !CONFIG_I82365, !CONFIG_PXA_PCMCIA */
wdenkc6097192002-11-03 00:24:07 +000095#if 0
96static u_int m8xx_get_speed(u_int ns, u_int is_io);
97#endif
98
wdenk1f53a412002-12-04 23:39:58 +000099/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +0000100
wdenkdb01a2e2004-04-15 23:14:49 +0000101#ifndef CONFIG_PXA_PCMCIA
102
wdenkc6097192002-11-03 00:24:07 +0000103/* look up table for pgcrx registers */
104
105static u_int *pcmcia_pgcrx[2] = {
106 &((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_pgcra,
107 &((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_pgcrb,
108};
wdenkc6097192002-11-03 00:24:07 +0000109#define PCMCIA_PGCRX(slot) (*pcmcia_pgcrx[slot])
110
wdenk6e592382004-04-18 17:39:38 +0000111#endif /* CONFIG_PXA_PCMCIA */
112
wdenk66fd3d12003-05-18 11:30:09 +0000113#endif /* CONFIG_I82365 */
114
wdenkdb01a2e2004-04-15 23:14:49 +0000115#if defined(CONFIG_IDE_8xx_PCCARD) || defined(CONFIG_PXA_PCMCIA)
wdenk66fd3d12003-05-18 11:30:09 +0000116static void print_funcid (int func);
117static void print_fixed (volatile uchar *p);
118static int identify (volatile uchar *p);
119static int check_ide_device (int slot);
wdenk6e592382004-04-18 17:39:38 +0000120#endif /* CONFIG_IDE_8xx_PCCARD, CONFIG_PXA_PCMCIA */
wdenkdb01a2e2004-04-15 23:14:49 +0000121
wdenkc6097192002-11-03 00:24:07 +0000122const char *indent = "\t ";
123
wdenk1f53a412002-12-04 23:39:58 +0000124/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +0000125
126#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
127
128int do_pinit (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
129{
130 int rcode = 0;
131
132 if (argc != 2) {
133 printf ("Usage: pinit {on | off}\n");
134 return 1;
135 }
136 if (strcmp(argv[1],"on") == 0) {
137 rcode = pcmcia_on ();
138 } else if (strcmp(argv[1],"off") == 0) {
139 rcode = pcmcia_off ();
140 } else {
141 printf ("Usage: pinit {on | off}\n");
142 return 1;
143 }
144
145 return rcode;
146}
147#endif /* CFG_CMD_PCMCIA */
148
wdenk1f53a412002-12-04 23:39:58 +0000149/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +0000150
wdenk66fd3d12003-05-18 11:30:09 +0000151#ifdef CONFIG_I82365
152int pcmcia_on (void)
153{
154 u_int rc;
155
156 debug ("Enable PCMCIA " PCMCIA_SLOT_MSG "\n");
157
158 rc = i82365_init();
159
wdenkdb01a2e2004-04-15 23:14:49 +0000160 if (rc == 0) {
wdenk66fd3d12003-05-18 11:30:09 +0000161 rc = check_ide_device(0);
162 }
163
164 return (rc);
165}
166#else
167
wdenkdb01a2e2004-04-15 23:14:49 +0000168#ifndef CONFIG_PXA_PCMCIA
169
wdenkc40b2952004-03-13 23:29:43 +0000170#ifdef CONFIG_HMI10
171# define HMI10_FRAM_TIMING (PCMCIA_SHT(2) | PCMCIA_SST(2) | PCMCIA_SL(4))
wdenka6cccae2004-02-06 21:48:22 +0000172#endif
dzue7df0292003-10-19 21:43:26 +0000173#if defined(CONFIG_LWMON) || defined(CONFIG_NSCU)
wdenkc6097192002-11-03 00:24:07 +0000174# define CFG_PCMCIA_TIMING (PCMCIA_SHT(9) | PCMCIA_SST(3) | PCMCIA_SL(12))
175#else
176# define CFG_PCMCIA_TIMING (PCMCIA_SHT(2) | PCMCIA_SST(4) | PCMCIA_SL(9))
177#endif
178
179int pcmcia_on (void)
180{
181 int i;
182 u_long reg, base;
183 pcmcia_win_t *win;
wdenkea909b72002-11-21 23:11:29 +0000184 u_int slotbit;
185 u_int rc, slot;
wdenkc6097192002-11-03 00:24:07 +0000186
187 debug ("Enable PCMCIA " PCMCIA_SLOT_MSG "\n");
188
189 /* intialize the fixed memory windows */
190 win = (pcmcia_win_t *)(&((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_pbr0);
191 base = CFG_PCMCIA_MEM_ADDR;
192
193 if((reg = m8xx_get_graycode(CFG_PCMCIA_MEM_SIZE)) == -1) {
194 printf ("Cannot set window size to 0x%08x\n",
195 CFG_PCMCIA_MEM_SIZE);
196 return (1);
197 }
198
wdenkea909b72002-11-21 23:11:29 +0000199 slotbit = PCMCIA_SLOT_x;
wdenkc6097192002-11-03 00:24:07 +0000200 for (i=0; i<PCMCIA_MEM_WIN_NO; ++i) {
201 win->br = base;
202
wdenkea909b72002-11-21 23:11:29 +0000203#if (PCMCIA_SOCKETS_NO == 2)
204 if (i == 4) /* Another slot starting from win 4 */
205 slotbit = (slotbit ? PCMCIA_PSLOT_A : PCMCIA_PSLOT_B);
206#endif
wdenkc6097192002-11-03 00:24:07 +0000207 switch (i) {
208#ifdef CONFIG_IDE_8xx_PCCARD
wdenkea909b72002-11-21 23:11:29 +0000209 case 4:
wdenkc40b2952004-03-13 23:29:43 +0000210#ifdef CONFIG_HMI10
wdenka6cccae2004-02-06 21:48:22 +0000211 { /* map FRAM area */
212 win->or = ( PCMCIA_BSIZE_256K
213 | PCMCIA_PPS_8
214 | PCMCIA_PRS_ATTR
215 | slotbit
216 | PCMCIA_PV
wdenkc40b2952004-03-13 23:29:43 +0000217 | HMI10_FRAM_TIMING );
wdenka6cccae2004-02-06 21:48:22 +0000218 break;
219 }
220#endif
wdenkc6097192002-11-03 00:24:07 +0000221 case 0: { /* map attribute memory */
222 win->or = ( PCMCIA_BSIZE_64M
223 | PCMCIA_PPS_8
224 | PCMCIA_PRS_ATTR
wdenkea909b72002-11-21 23:11:29 +0000225 | slotbit
wdenkc6097192002-11-03 00:24:07 +0000226 | PCMCIA_PV
227 | CFG_PCMCIA_TIMING );
228 break;
229 }
wdenkea909b72002-11-21 23:11:29 +0000230 case 5:
wdenkc6097192002-11-03 00:24:07 +0000231 case 1: { /* map I/O window for data reg */
232 win->or = ( PCMCIA_BSIZE_1K
233 | PCMCIA_PPS_16
234 | PCMCIA_PRS_IO
wdenkea909b72002-11-21 23:11:29 +0000235 | slotbit
wdenkc6097192002-11-03 00:24:07 +0000236 | PCMCIA_PV
237 | CFG_PCMCIA_TIMING );
238 break;
239 }
wdenkea909b72002-11-21 23:11:29 +0000240 case 6:
wdenk1f53a412002-12-04 23:39:58 +0000241 case 2: { /* map I/O window for cmd/ctrl reg block */
wdenkc6097192002-11-03 00:24:07 +0000242 win->or = ( PCMCIA_BSIZE_1K
243 | PCMCIA_PPS_8
244 | PCMCIA_PRS_IO
wdenkea909b72002-11-21 23:11:29 +0000245 | slotbit
wdenkc6097192002-11-03 00:24:07 +0000246 | PCMCIA_PV
247 | CFG_PCMCIA_TIMING );
248 break;
249 }
250#endif /* CONFIG_IDE_8xx_PCCARD */
wdenkc40b2952004-03-13 23:29:43 +0000251#ifdef CONFIG_HMI10
wdenk7cb22f92003-12-27 19:24:54 +0000252 case 3: { /* map I/O window for 4xUART data/ctrl */
wdenka522fa02004-01-04 22:51:12 +0000253 win->br += 0x40000;
wdenk7cb22f92003-12-27 19:24:54 +0000254 win->or = ( PCMCIA_BSIZE_256K
255 | PCMCIA_PPS_8
256 | PCMCIA_PRS_IO
257 | slotbit
258 | PCMCIA_PV
259 | CFG_PCMCIA_TIMING );
260 break;
261 }
wdenkc40b2952004-03-13 23:29:43 +0000262#endif /* CONFIG_HMI10 */
wdenkc6097192002-11-03 00:24:07 +0000263 default: /* set to not valid */
264 win->or = 0;
265 break;
266 }
267
268 debug ("MemWin %d: PBR 0x%08lX POR %08lX\n",
269 i, win->br, win->or);
270 base += CFG_PCMCIA_MEM_SIZE;
271 ++win;
272 }
273
wdenk1f53a412002-12-04 23:39:58 +0000274 for (i=0, rc=0, slot=_slot_; i<PCMCIA_SOCKETS_NO; i++, slot = !slot) {
wdenkea909b72002-11-21 23:11:29 +0000275 /* turn off voltage */
276 if ((rc = voltage_set(slot, 0, 0)))
277 continue;
wdenk1f53a412002-12-04 23:39:58 +0000278
wdenkea909b72002-11-21 23:11:29 +0000279 /* Enable external hardware */
280 if ((rc = hardware_enable(slot)))
281 continue;
wdenk1f53a412002-12-04 23:39:58 +0000282
wdenkc6097192002-11-03 00:24:07 +0000283#ifdef CONFIG_IDE_8xx_PCCARD
wdenkea909b72002-11-21 23:11:29 +0000284 if ((rc = check_ide_device(i)))
285 continue;
wdenkc6097192002-11-03 00:24:07 +0000286#endif
wdenkea909b72002-11-21 23:11:29 +0000287 }
288 return (rc);
wdenkc6097192002-11-03 00:24:07 +0000289}
wdenkdb01a2e2004-04-15 23:14:49 +0000290
wdenkc26e4542004-04-18 10:13:26 +0000291#endif /* CONFIG_PXA_PCMCIA */
wdenkdb01a2e2004-04-15 23:14:49 +0000292
wdenk66fd3d12003-05-18 11:30:09 +0000293#endif /* CONFIG_I82365 */
wdenkc6097192002-11-03 00:24:07 +0000294
wdenkdb01a2e2004-04-15 23:14:49 +0000295#ifdef CONFIG_PXA_PCMCIA
296
297static int hardware_enable (int slot)
298{
299 return 0; /* No hardware to enable */
300}
301
302static int hardware_disable(int slot)
303{
304 return 0; /* No hardware to disable */
305}
306
307static int voltage_set(int slot, int vcc, int vpp)
308{
309 return 0;
310}
311
312void msWait(unsigned msVal)
313{
314 udelay(msVal*1000);
315}
316
317int pcmcia_on (void)
318{
319 unsigned int reg_arr[] = {
320 0x48000028, CFG_MCMEM0_VAL,
321 0x4800002c, CFG_MCMEM1_VAL,
322 0x48000030, CFG_MCATT0_VAL,
323 0x48000034, CFG_MCATT1_VAL,
324 0x48000038, CFG_MCIO0_VAL,
325 0x4800003c, CFG_MCIO1_VAL,
326
327 0, 0
328 };
329 int i, rc;
330
331#ifdef CONFIG_EXADRON1
332 int cardDetect;
333 volatile unsigned int *v_pBCRReg =
334 (volatile unsigned int *) 0x08000000;
335#endif
336
337 debug ("%s\n", __FUNCTION__);
338
339 i = 0;
340 while (reg_arr[i])
341 *((volatile unsigned int *) reg_arr[i++]) |= reg_arr[i++];
342 udelay (1000);
343
344 debug ("%s: programmed mem controller \n", __FUNCTION__);
345
346#ifdef CONFIG_EXADRON1
347
348/*define useful BCR masks */
349#define BCR_CF_INIT_VAL 0x00007230
350#define BCR_CF_PWRON_BUSOFF_RESETOFF_VAL 0x00007231
351#define BCR_CF_PWRON_BUSOFF_RESETON_VAL 0x00007233
352#define BCR_CF_PWRON_BUSON_RESETON_VAL 0x00007213
353#define BCR_CF_PWRON_BUSON_RESETOFF_VAL 0x00007211
354
355 /* we see from the GPIO bit if the card is present */
356 cardDetect = !(GPLR0 & GPIO_bit (14));
357
358 if (cardDetect) {
359 printf ("No PCMCIA card found!\n");
360 }
361
362 /* reset the card via the BCR line */
363 *v_pBCRReg = (unsigned) BCR_CF_INIT_VAL;
364 msWait (500);
365
366 *v_pBCRReg = (unsigned) BCR_CF_PWRON_BUSOFF_RESETOFF_VAL;
367 msWait (500);
368
369 *v_pBCRReg = (unsigned) BCR_CF_PWRON_BUSOFF_RESETON_VAL;
370 msWait (500);
371
372 *v_pBCRReg = (unsigned) BCR_CF_PWRON_BUSON_RESETON_VAL;
373 msWait (500);
374
375 *v_pBCRReg = (unsigned) BCR_CF_PWRON_BUSON_RESETOFF_VAL;
376 msWait (1500);
377
378 /* enable address bus */
379 GPCR1 = 0x01;
380 /* and the first CF slot */
381 MECR = 0x00000002;
382
383#endif /* EXADRON 1 */
384
385 rc = check_ide_device (0); /* use just slot 0 */
386
387 return rc;
388}
389
390#endif /* CONFIG_PXA_PCMCIA */
391
wdenk1f53a412002-12-04 23:39:58 +0000392/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +0000393
394#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
395
wdenk66fd3d12003-05-18 11:30:09 +0000396#ifdef CONFIG_I82365
397static int pcmcia_off (void)
398{
399 printf ("Disable PCMCIA " PCMCIA_SLOT_MSG "\n");
400
401 i82365_exit();
402
403 return 0;
404}
405#else
wdenkdb01a2e2004-04-15 23:14:49 +0000406
407#ifndef CONFIG_PXA_PCMCIA
408
wdenkc6097192002-11-03 00:24:07 +0000409static int pcmcia_off (void)
410{
411 int i;
412 pcmcia_win_t *win;
413
414 printf ("Disable PCMCIA " PCMCIA_SLOT_MSG "\n");
415
416 /* clear interrupt state, and disable interrupts */
417 ((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_pscr = PCMCIA_MASK(_slot_);
418 ((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_per &= ~PCMCIA_MASK(_slot_);
419
420 /* turn off interrupt and disable CxOE */
421 PCMCIA_PGCRX(_slot_) = __MY_PCMCIA_GCRX_CXOE;
422
423 /* turn off memory windows */
424 win = (pcmcia_win_t *)(&((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_pbr0);
425
426 for (i=0; i<PCMCIA_MEM_WIN_NO; ++i) {
427 /* disable memory window */
428 win->or = 0;
429 ++win;
430 }
431
432 /* turn off voltage */
433 voltage_set(_slot_, 0, 0);
434
435 /* disable external hardware */
436 printf ("Shutdown and Poweroff " PCMCIA_SLOT_MSG "\n");
437 hardware_disable(_slot_);
438 return 0;
439}
wdenkdb01a2e2004-04-15 23:14:49 +0000440
441#endif /* CONFIG_PXA_PCMCIA */
442
wdenk66fd3d12003-05-18 11:30:09 +0000443#endif /* CONFIG_I82365 */
wdenkc6097192002-11-03 00:24:07 +0000444
wdenkdb01a2e2004-04-15 23:14:49 +0000445#ifdef CONFIG_PXA_PCMCIA
446static int pcmcia_off (void)
447{
448 return 0;
449}
450#endif
451
wdenkc6097192002-11-03 00:24:07 +0000452#endif /* CFG_CMD_PCMCIA */
453
wdenk1f53a412002-12-04 23:39:58 +0000454/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +0000455
wdenkdb01a2e2004-04-15 23:14:49 +0000456#if defined(CONFIG_IDE_8xx_PCCARD) || defined(CONFIG_PXA_PCMCIA)
wdenkc6097192002-11-03 00:24:07 +0000457
458#define MAX_TUPEL_SZ 512
459#define MAX_FEATURES 4
460
wdenk6069ff22003-02-28 00:49:47 +0000461int ide_devices_found;
wdenkea909b72002-11-21 23:11:29 +0000462static int check_ide_device (int slot)
wdenkc6097192002-11-03 00:24:07 +0000463{
464 volatile uchar *ident = NULL;
465 volatile uchar *feature_p[MAX_FEATURES];
wdenkea909b72002-11-21 23:11:29 +0000466 volatile uchar *p, *start, *addr;
wdenkc6097192002-11-03 00:24:07 +0000467 int n_features = 0;
468 uchar func_id = ~0;
469 uchar code, len;
470 ushort config_base = 0;
471 int found = 0;
472 int i;
473
wdenk1f53a412002-12-04 23:39:58 +0000474 addr = (volatile uchar *)(CFG_PCMCIA_MEM_ADDR +
475 CFG_PCMCIA_MEM_SIZE * (slot * 4));
wdenkd0fb80c2003-01-11 09:48:40 +0000476 debug ("PCMCIA MEM: %08lX\n", (ulong)addr);
wdenkc6097192002-11-03 00:24:07 +0000477
wdenkea909b72002-11-21 23:11:29 +0000478 start = p = (volatile uchar *) addr;
wdenkc6097192002-11-03 00:24:07 +0000479
480 while ((p - start) < MAX_TUPEL_SZ) {
481
482 code = *p; p += 2;
483
484 if (code == 0xFF) { /* End of chain */
485 break;
486 }
487
488 len = *p; p += 2;
489#if defined(DEBUG) && (DEBUG > 1)
490 { volatile uchar *q = p;
491 printf ("\nTuple code %02x length %d\n\tData:",
492 code, len);
493
494 for (i = 0; i < len; ++i) {
495 printf (" %02x", *q);
496 q+= 2;
497 }
498 }
499#endif /* DEBUG */
500 switch (code) {
501 case CISTPL_VERS_1:
502 ident = p + 4;
503 break;
504 case CISTPL_FUNCID:
505 /* Fix for broken SanDisk which may have 0x80 bit set */
506 func_id = *p & 0x7F;
507 break;
508 case CISTPL_FUNCE:
509 if (n_features < MAX_FEATURES)
510 feature_p[n_features++] = p;
511 break;
512 case CISTPL_CONFIG:
513 config_base = (*(p+6) << 8) + (*(p+4));
514 debug ("\n## Config_base = %04x ###\n", config_base);
515 default:
516 break;
517 }
518 p += 2 * len;
519 }
520
521 found = identify (ident);
522
523 if (func_id != ((uchar)~0)) {
524 print_funcid (func_id);
525
526 if (func_id == CISTPL_FUNCID_FIXED)
527 found = 1;
528 else
529 return (1); /* no disk drive */
530 }
531
532 for (i=0; i<n_features; ++i) {
533 print_fixed (feature_p[i]);
534 }
535
536 if (!found) {
537 printf ("unknown card type\n");
538 return (1);
539 }
540
wdenk6069ff22003-02-28 00:49:47 +0000541 ide_devices_found |= (1 << slot);
542
wdenkc6097192002-11-03 00:24:07 +0000543 /* set I/O area in config reg -> only valid for ARGOSY D5!!! */
wdenkea909b72002-11-21 23:11:29 +0000544 *((uchar *)(addr + config_base)) = 1;
wdenkc6097192002-11-03 00:24:07 +0000545
546 return (0);
547}
548#endif /* CONFIG_IDE_8xx_PCCARD */
549
wdenk1f53a412002-12-04 23:39:58 +0000550/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +0000551
552
wdenk1f53a412002-12-04 23:39:58 +0000553/* -------------------------------------------------------------------- */
554/* board specific stuff: */
555/* voltage_set(), hardware_enable() and hardware_disable() */
556/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +0000557
wdenk1f53a412002-12-04 23:39:58 +0000558/* -------------------------------------------------------------------- */
559/* RPX Boards from Embedded Planet */
560/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +0000561
562#if defined(CONFIG_RPXCLASSIC) || defined(CONFIG_RPXLITE)
563
564/* The RPX boards seems to have it's bus monitor timeout set to 6*8 clocks.
565 * SYPCR is write once only, therefore must the slowest memory be faster
566 * than the bus monitor or we will get a machine check due to the bus timeout.
567 */
568
569#define PCMCIA_BOARD_MSG "RPX CLASSIC or RPX LITE"
570
571#undef PCMCIA_BMT_LIMIT
572#define PCMCIA_BMT_LIMIT (6*8)
573
574static int voltage_set(int slot, int vcc, int vpp)
575{
576 u_long reg = 0;
577
578 switch(vcc) {
579 case 0: break;
580 case 33: reg |= BCSR1_PCVCTL4; break;
581 case 50: reg |= BCSR1_PCVCTL5; break;
582 default: return 1;
583 }
584
585 switch(vpp) {
586 case 0: break;
587 case 33:
588 case 50:
589 if(vcc == vpp)
590 reg |= BCSR1_PCVCTL6;
591 else
592 return 1;
593 break;
594 case 120:
595 reg |= BCSR1_PCVCTL7;
596 default: return 1;
597 }
598
599 if(vcc == 120)
600 return 1;
601
602 /* first, turn off all power */
603
604 *((uint *)RPX_CSR_ADDR) &= ~(BCSR1_PCVCTL4 | BCSR1_PCVCTL5
605 | BCSR1_PCVCTL6 | BCSR1_PCVCTL7);
606
607 /* enable new powersettings */
608
609 *((uint *)RPX_CSR_ADDR) |= reg;
610
611 return 0;
612}
613
614#define socket_get(_slot_) PCMCIA_SOCKET_KEY_5V
615static int hardware_enable (int slot)
616{
617 return 0; /* No hardware to enable */
618}
619#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
620static int hardware_disable(int slot)
621{
622 return 0; /* No hardware to disable */
623}
624#endif /* CFG_CMD_PCMCIA */
625#endif /* CONFIG_RPXCLASSIC */
626
wdenk1f53a412002-12-04 23:39:58 +0000627/* -------------------------------------------------------------------- */
628/* (F)ADS Boards from Motorola */
629/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +0000630
631#if defined(CONFIG_ADS) || defined(CONFIG_FADS)
632
633#ifdef CONFIG_ADS
634#define PCMCIA_BOARD_MSG "ADS"
635#define PCMCIA_GLITCHY_CD /* My ADS board needs this */
636#else
637#define PCMCIA_BOARD_MSG "FADS"
638#endif
639
640static int voltage_set(int slot, int vcc, int vpp)
641{
642 u_long reg = 0;
643
644 switch(vpp) {
645 case 0: reg = 0; break;
646 case 50: reg = 1; break;
647 case 120: reg = 2; break;
648 default: return 1;
649 }
650
651 switch(vcc) {
652 case 0: reg = 0; break;
653#ifdef CONFIG_ADS
654 case 50: reg = BCSR1_PCCVCCON; break;
655#endif
656#ifdef CONFIG_FADS
657 case 33: reg = BCSR1_PCCVCC0 | BCSR1_PCCVCC1; break;
658 case 50: reg = BCSR1_PCCVCC1; break;
659#endif
660 default: return 1;
661 }
662
663 /* first, turn off all power */
664
665#ifdef CONFIG_ADS
666 *((uint *)BCSR1) |= BCSR1_PCCVCCON;
667#endif
668#ifdef CONFIG_FADS
669 *((uint *)BCSR1) &= ~(BCSR1_PCCVCC0 | BCSR1_PCCVCC1);
670#endif
671 *((uint *)BCSR1) &= ~BCSR1_PCCVPP_MASK;
672
673 /* enable new powersettings */
674
675#ifdef CONFIG_ADS
676 *((uint *)BCSR1) &= ~reg;
677#endif
678#ifdef CONFIG_FADS
679 *((uint *)BCSR1) |= reg;
680#endif
681
682 *((uint *)BCSR1) |= reg << 20;
683
684 return 0;
685}
686
687#define socket_get(_slot_) PCMCIA_SOCKET_KEY_5V
688
689static int hardware_enable(int slot)
690{
691 *((uint *)BCSR1) &= ~BCSR1_PCCEN;
692 return 0;
693}
694
695#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
696static int hardware_disable(int slot)
697{
698 *((uint *)BCSR1) &= ~BCSR1_PCCEN;
699 return 0;
700}
701#endif /* CFG_CMD_PCMCIA */
702
703#endif /* (F)ADS */
704
wdenk1f53a412002-12-04 23:39:58 +0000705/* -------------------------------------------------------------------- */
706/* TQM8xxL Boards by TQ Components */
wdenkdc7c9a12003-03-26 06:55:25 +0000707/* SC8xx Boards by SinoVee Microsystems */
wdenk1f53a412002-12-04 23:39:58 +0000708/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +0000709
wdenkdc7c9a12003-03-26 06:55:25 +0000710#if defined(CONFIG_TQM8xxL) || defined(CONFIG_SVM_SC8xx)
711
wdenkc6097192002-11-03 00:24:07 +0000712#if defined(CONFIG_TQM8xxL)
wdenkc6097192002-11-03 00:24:07 +0000713#define PCMCIA_BOARD_MSG "TQM8xxL"
wdenkdc7c9a12003-03-26 06:55:25 +0000714#endif
715#if defined(CONFIG_SVM_SC8xx)
716#define PCMCIA_BOARD_MSG "SC8xx"
717#endif
wdenkc6097192002-11-03 00:24:07 +0000718
719static int hardware_enable(int slot)
720{
721 volatile immap_t *immap;
722 volatile cpm8xx_t *cp;
723 volatile pcmconf8xx_t *pcmp;
724 volatile sysconf8xx_t *sysp;
725 uint reg, mask;
726
727 debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
728
729 udelay(10000);
730
731 immap = (immap_t *)CFG_IMMR;
732 sysp = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
733 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
734 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
735
736 /*
737 * Configure SIUMCR to enable PCMCIA port B
738 * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
739 */
740 sysp->sc_siumcr &= ~SIUMCR_DBGC11; /* set DBGC to 00 */
741
742 /* clear interrupt state, and disable interrupts */
dzue7df0292003-10-19 21:43:26 +0000743 pcmp->pcmc_pscr = PCMCIA_MASK(slot);
744 pcmp->pcmc_per &= ~PCMCIA_MASK(slot);
wdenkc6097192002-11-03 00:24:07 +0000745
wdenkc6097192002-11-03 00:24:07 +0000746 /*
wdenk1f53a412002-12-04 23:39:58 +0000747 * Disable interrupts, DMA, and PCMCIA buffers
748 * (isolate the interface) and assert RESET signal
wdenkc6097192002-11-03 00:24:07 +0000749 */
750 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +0000751 reg = 0;
752 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
dzue7df0292003-10-19 21:43:26 +0000753#ifndef NSCU_OE_INV
wdenk1f53a412002-12-04 23:39:58 +0000754 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
dzue7df0292003-10-19 21:43:26 +0000755#endif
756 PCMCIA_PGCRX(slot) = reg;
wdenkc6097192002-11-03 00:24:07 +0000757 udelay(500);
758
wdenkc40b2952004-03-13 23:29:43 +0000759#ifndef CONFIG_HMI10
dzue7df0292003-10-19 21:43:26 +0000760#ifndef CONFIG_NSCU
wdenkc6097192002-11-03 00:24:07 +0000761 /*
762 * Configure Port C pins for
763 * 5 Volts Enable and 3 Volts enable
764 */
765 immap->im_ioport.iop_pcpar &= ~(0x0002 | 0x0004);
766 immap->im_ioport.iop_pcso &= ~(0x0002 | 0x0004);
767 /* remove all power */
768
769 immap->im_ioport.iop_pcdat &= ~(0x0002 | 0x0004);
dzue7df0292003-10-19 21:43:26 +0000770#endif
wdenkc40b2952004-03-13 23:29:43 +0000771#else /* CONFIG_HMI10 */
wdenka522fa02004-01-04 22:51:12 +0000772 /*
773 * Configure Port B pins for
774 * 5 Volts Enable and 3 Volts enable
775 */
776 immap->im_cpm.cp_pbpar &= ~(0x00000300);
777
778 /* remove all power */
779 immap->im_cpm.cp_pbdat |= 0x00000300;
wdenkc40b2952004-03-13 23:29:43 +0000780#endif /* CONFIG_HMI10 */
wdenkc6097192002-11-03 00:24:07 +0000781
782 /*
783 * Make sure there is a card in the slot, then configure the interface.
784 */
785 udelay(10000);
786 debug ("[%d] %s: PIPR(%p)=0x%x\n",
787 __LINE__,__FUNCTION__,
788 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
wdenkc40b2952004-03-13 23:29:43 +0000789#ifndef CONFIG_HMI10
wdenkea909b72002-11-21 23:11:29 +0000790 if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
wdenka522fa02004-01-04 22:51:12 +0000791#else
792 if (pcmp->pcmc_pipr & (0x10000000 >> (slot << 4))) {
wdenkc40b2952004-03-13 23:29:43 +0000793#endif /* CONFIG_HMI10 */
wdenkc6097192002-11-03 00:24:07 +0000794 printf (" No Card found\n");
795 return (1);
796 }
797
798 /*
799 * Power On.
800 */
801 mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
802 reg = pcmp->pcmc_pipr;
803 debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
804 reg,
805 (reg&PCMCIA_VS1(slot))?"n":"ff",
806 (reg&PCMCIA_VS2(slot))?"n":"ff");
dzue7df0292003-10-19 21:43:26 +0000807#ifndef CONFIG_NSCU
wdenkc6097192002-11-03 00:24:07 +0000808 if ((reg & mask) == mask) {
wdenkc40b2952004-03-13 23:29:43 +0000809#ifndef CONFIG_HMI10
wdenkc6097192002-11-03 00:24:07 +0000810 immap->im_ioport.iop_pcdat |= 0x0004;
wdenka522fa02004-01-04 22:51:12 +0000811#else
812 immap->im_cpm.cp_pbdat &= ~(0x0000100);
wdenkc40b2952004-03-13 23:29:43 +0000813#endif /* CONFIG_HMI10 */
wdenkc6097192002-11-03 00:24:07 +0000814 puts (" 5.0V card found: ");
815 } else {
wdenkc40b2952004-03-13 23:29:43 +0000816#ifndef CONFIG_HMI10
wdenkc6097192002-11-03 00:24:07 +0000817 immap->im_ioport.iop_pcdat |= 0x0002;
wdenka522fa02004-01-04 22:51:12 +0000818#else
819 immap->im_cpm.cp_pbdat &= ~(0x0000200);
wdenkc40b2952004-03-13 23:29:43 +0000820#endif /* CONFIG_HMI10 */
wdenkc6097192002-11-03 00:24:07 +0000821 puts (" 3.3V card found: ");
822 }
wdenkc40b2952004-03-13 23:29:43 +0000823#ifndef CONFIG_HMI10
wdenk1f53a412002-12-04 23:39:58 +0000824 immap->im_ioport.iop_pcdir |= (0x0002 | 0x0004);
dzue7df0292003-10-19 21:43:26 +0000825#else
wdenka522fa02004-01-04 22:51:12 +0000826 immap->im_cpm.cp_pbdir |= 0x00000300;
wdenkc40b2952004-03-13 23:29:43 +0000827#endif /* CONFIG_HMI10 */
wdenka522fa02004-01-04 22:51:12 +0000828#else
dzue7df0292003-10-19 21:43:26 +0000829 if ((reg & mask) == mask) {
830 puts (" 5.0V card found: ");
831 } else {
832 puts (" 3.3V card found: ");
833 }
834#endif
wdenkc6097192002-11-03 00:24:07 +0000835#if 0
836 /* VCC switch error flag, PCMCIA slot INPACK_ pin */
837 cp->cp_pbdir &= ~(0x0020 | 0x0010);
838 cp->cp_pbpar &= ~(0x0020 | 0x0010);
839 udelay(500000);
840#endif
841 udelay(1000);
842 debug ("Enable PCMCIA buffers and stop RESET\n");
dzue7df0292003-10-19 21:43:26 +0000843 reg = PCMCIA_PGCRX(slot);
wdenkc6097192002-11-03 00:24:07 +0000844 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
dzue7df0292003-10-19 21:43:26 +0000845#ifndef NSCU_OE_INV
wdenkc6097192002-11-03 00:24:07 +0000846 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
dzue7df0292003-10-19 21:43:26 +0000847#else
848 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
849#endif
850 PCMCIA_PGCRX(slot) = reg;
wdenkc6097192002-11-03 00:24:07 +0000851
852 udelay(250000); /* some cards need >150 ms to come up :-( */
853
854 debug ("# hardware_enable done\n");
855
856 return (0);
857}
858
859
wdenkc6097192002-11-03 00:24:07 +0000860#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
861static int hardware_disable(int slot)
862{
863 volatile immap_t *immap;
864 volatile pcmconf8xx_t *pcmp;
865 u_long reg;
866
867 debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
868
869 immap = (immap_t *)CFG_IMMR;
870 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
871
wdenkc40b2952004-03-13 23:29:43 +0000872#ifndef CONFIG_HMI10
dzue7df0292003-10-19 21:43:26 +0000873#ifndef CONFIG_NSCU
wdenkc6097192002-11-03 00:24:07 +0000874 /* remove all power */
875 immap->im_ioport.iop_pcdat &= ~(0x0002 | 0x0004);
dzue7df0292003-10-19 21:43:26 +0000876#endif
wdenkc40b2952004-03-13 23:29:43 +0000877#else /* CONFIG_HMI10 */
wdenka522fa02004-01-04 22:51:12 +0000878 immap->im_cpm.cp_pbdat |= 0x00000300;
wdenkc40b2952004-03-13 23:29:43 +0000879#endif /* CONFIG_HMI10 */
wdenkc6097192002-11-03 00:24:07 +0000880
wdenkc6097192002-11-03 00:24:07 +0000881 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +0000882 reg = 0;
wdenkc6097192002-11-03 00:24:07 +0000883 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
dzue7df0292003-10-19 21:43:26 +0000884#ifndef NSCU_OE_INV
wdenkc6097192002-11-03 00:24:07 +0000885 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
dzue7df0292003-10-19 21:43:26 +0000886#endif
887 PCMCIA_PGCRX(slot) = reg;
wdenkc6097192002-11-03 00:24:07 +0000888
889 udelay(10000);
890
891 return (0);
892}
893#endif /* CFG_CMD_PCMCIA */
894
dzue7df0292003-10-19 21:43:26 +0000895#ifdef CONFIG_NSCU
896static int voltage_set(int slot, int vcc, int vpp)
897{
898 return 0;
899}
900#else
wdenkc6097192002-11-03 00:24:07 +0000901static int voltage_set(int slot, int vcc, int vpp)
902{
903 volatile immap_t *immap;
904 volatile pcmconf8xx_t *pcmp;
905 u_long reg;
906
907 debug ("voltage_set: "
908 PCMCIA_BOARD_MSG
909 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
910 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
911
912 immap = (immap_t *)CFG_IMMR;
913 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
914 /*
915 * Disable PCMCIA buffers (isolate the interface)
916 * and assert RESET signal
917 */
918 debug ("Disable PCMCIA buffers and assert RESET\n");
dzue7df0292003-10-19 21:43:26 +0000919 reg = PCMCIA_PGCRX(slot);
wdenk1f53a412002-12-04 23:39:58 +0000920 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
dzue7df0292003-10-19 21:43:26 +0000921#ifndef NSCU_OE_INV
wdenk1f53a412002-12-04 23:39:58 +0000922 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
dzue7df0292003-10-19 21:43:26 +0000923#else
924 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
925#endif
926 PCMCIA_PGCRX(slot) = reg;
wdenkc6097192002-11-03 00:24:07 +0000927 udelay(500);
928
wdenkc40b2952004-03-13 23:29:43 +0000929#ifndef CONFIG_HMI10
wdenkc6097192002-11-03 00:24:07 +0000930 /*
931 * Configure Port C pins for
932 * 5 Volts Enable and 3 Volts enable,
933 * Turn off all power
934 */
935 debug ("PCMCIA power OFF\n");
936 immap->im_ioport.iop_pcpar &= ~(0x0002 | 0x0004);
937 immap->im_ioport.iop_pcso &= ~(0x0002 | 0x0004);
938 immap->im_ioport.iop_pcdat &= ~(0x0002 | 0x0004);
939
940 reg = 0;
941 switch(vcc) {
942 case 0: break;
943 case 33: reg |= 0x0002; break;
944 case 50: reg |= 0x0004; break;
945 default: goto done;
946 }
wdenkc40b2952004-03-13 23:29:43 +0000947#else /* CONFIG_HMI10 */
wdenka522fa02004-01-04 22:51:12 +0000948 /*
949 * Configure Port B pins for
950 * 5 Volts Enable and 3 Volts enable,
951 * Turn off all power
952 */
953 debug ("PCMCIA power OFF\n");
954 immap->im_cpm.cp_pbpar &= ~(0x00000300);
955 /* remove all power */
956
957 immap->im_cpm.cp_pbdat |= 0x00000300;
958
959 reg = 0;
960 switch(vcc) {
961 case 0: break;
962 case 33: reg |= 0x00000200; break;
963 case 50: reg |= 0x00000100; break;
964 default: goto done;
965}
wdenkc40b2952004-03-13 23:29:43 +0000966#endif /* CONFIG_HMI10 */
wdenkc6097192002-11-03 00:24:07 +0000967
968 /* Checking supported voltages */
969
970 debug ("PIPR: 0x%x --> %s\n",
971 pcmp->pcmc_pipr,
972 (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
973
wdenkc40b2952004-03-13 23:29:43 +0000974#ifndef CONFIG_HMI10
wdenkc6097192002-11-03 00:24:07 +0000975 immap->im_ioport.iop_pcdat |= reg;
wdenk1f53a412002-12-04 23:39:58 +0000976 immap->im_ioport.iop_pcdir |= (0x0002 | 0x0004);
wdenka522fa02004-01-04 22:51:12 +0000977#else
978 immap->im_cpm.cp_pbdat &= !reg;
979 immap->im_cpm.cp_pbdir |= 0x00000300;
wdenkc40b2952004-03-13 23:29:43 +0000980#endif /* CONFIG_HMI10 */
wdenkc6097192002-11-03 00:24:07 +0000981 if (reg) {
wdenkc40b2952004-03-13 23:29:43 +0000982#ifndef CONFIG_HMI10
wdenkc6097192002-11-03 00:24:07 +0000983 debug ("PCMCIA powered at %sV\n",
984 (reg&0x0004) ? "5.0" : "3.3");
wdenka522fa02004-01-04 22:51:12 +0000985#else
986 debug ("PCMCIA powered at %sV\n",
987 (reg&0x00000200) ? "5.0" : "3.3");
wdenkc40b2952004-03-13 23:29:43 +0000988#endif /* CONFIG_HMI10 */
wdenkc6097192002-11-03 00:24:07 +0000989 } else {
990 debug ("PCMCIA powered down\n");
991 }
992
993done:
994 debug ("Enable PCMCIA buffers and stop RESET\n");
dzue7df0292003-10-19 21:43:26 +0000995 reg = PCMCIA_PGCRX(slot);
wdenkc6097192002-11-03 00:24:07 +0000996 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
dzue7df0292003-10-19 21:43:26 +0000997#ifndef NSCU_OE_INV
wdenkc6097192002-11-03 00:24:07 +0000998 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
dzue7df0292003-10-19 21:43:26 +0000999#else
1000 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
1001#endif
1002 PCMCIA_PGCRX(slot) = reg;
wdenkc6097192002-11-03 00:24:07 +00001003 udelay(500);
1004
1005 debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
1006 slot+'A');
1007 return (0);
1008}
dzue7df0292003-10-19 21:43:26 +00001009#endif
wdenkc6097192002-11-03 00:24:07 +00001010
1011#endif /* TQM8xxL */
1012
1013
wdenk1f53a412002-12-04 23:39:58 +00001014/* -------------------------------------------------------------------- */
1015/* LWMON Board */
1016/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00001017
1018#if defined(CONFIG_LWMON)
1019
1020#define PCMCIA_BOARD_MSG "LWMON"
1021
1022/* #define's for MAX1604 Power Switch */
1023#define MAX1604_OP_SUS 0x80
1024#define MAX1604_VCCBON 0x40
1025#define MAX1604_VCC_35 0x20
1026#define MAX1604_VCCBHIZ 0x10
1027#define MAX1604_VPPBON 0x08
1028#define MAX1604_VPPBPBPGM 0x04
1029#define MAX1604_VPPBHIZ 0x02
1030/* reserved 0x01 */
1031
1032static int hardware_enable(int slot)
1033{
1034 volatile immap_t *immap;
1035 volatile cpm8xx_t *cp;
1036 volatile pcmconf8xx_t *pcmp;
1037 volatile sysconf8xx_t *sysp;
1038 uint reg, mask;
1039 uchar val;
1040
1041
1042 debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1043
1044 /* Switch on PCMCIA port in PIC register 0x60 */
1045 reg = pic_read (0x60);
1046 debug ("[%d] PIC read: reg_60 = 0x%02x\n", __LINE__, reg);
1047 reg &= ~0x10;
wdenk1f53a412002-12-04 23:39:58 +00001048 /* reg |= 0x08; Vpp not needed */
wdenkc6097192002-11-03 00:24:07 +00001049 pic_write (0x60, reg);
1050#ifdef DEBUG
1051 reg = pic_read (0x60);
1052 printf ("[%d] PIC read: reg_60 = 0x%02x\n", __LINE__, reg);
1053#endif
1054 udelay(10000);
1055
1056 immap = (immap_t *)CFG_IMMR;
1057 sysp = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
1058 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1059 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1060
1061 /*
1062 * Configure SIUMCR to enable PCMCIA port B
1063 * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
1064 */
1065 sysp->sc_siumcr &= ~SIUMCR_DBGC11; /* set DBGC to 00 */
1066
1067 /* clear interrupt state, and disable interrupts */
1068 pcmp->pcmc_pscr = PCMCIA_MASK(_slot_);
1069 pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
1070
wdenkc6097192002-11-03 00:24:07 +00001071 /*
wdenk1f53a412002-12-04 23:39:58 +00001072 * Disable interrupts, DMA, and PCMCIA buffers
1073 * (isolate the interface) and assert RESET signal
wdenkc6097192002-11-03 00:24:07 +00001074 */
1075 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00001076 reg = 0;
1077 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1078 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkc6097192002-11-03 00:24:07 +00001079 PCMCIA_PGCRX(_slot_) = reg;
1080 udelay(500);
1081
1082 /*
1083 * Make sure there is a card in the slot, then configure the interface.
1084 */
1085 udelay(10000);
1086 debug ("[%d] %s: PIPR(%p)=0x%x\n",
1087 __LINE__,__FUNCTION__,
1088 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
wdenkea909b72002-11-21 23:11:29 +00001089 if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
wdenkc6097192002-11-03 00:24:07 +00001090 printf (" No Card found\n");
1091 return (1);
1092 }
1093
1094 /*
1095 * Power On.
1096 */
1097 mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
1098 reg = pcmp->pcmc_pipr;
1099 debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
1100 reg,
1101 (reg&PCMCIA_VS1(slot))?"n":"ff",
1102 (reg&PCMCIA_VS2(slot))?"n":"ff");
1103 if ((reg & mask) == mask) {
1104 val = 0; /* VCCB3/5 = 0 ==> use Vx = 5.0 V */
1105 puts (" 5.0V card found: ");
1106 } else {
1107 val = MAX1604_VCC_35; /* VCCB3/5 = 1 ==> use Vy = 3.3 V */
1108 puts (" 3.3V card found: ");
1109 }
1110
1111 /* switch VCC on */
wdenk1f53a412002-12-04 23:39:58 +00001112 val |= MAX1604_OP_SUS | MAX1604_VCCBON;
wdenkc6097192002-11-03 00:24:07 +00001113 i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE);
1114 i2c_write (CFG_I2C_POWER_A_ADDR, 0, 0, &val, 1);
1115
1116 udelay(500000);
1117
1118 debug ("Enable PCMCIA buffers and stop RESET\n");
1119 reg = PCMCIA_PGCRX(_slot_);
1120 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
1121 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
1122 PCMCIA_PGCRX(_slot_) = reg;
1123
1124 udelay(250000); /* some cards need >150 ms to come up :-( */
1125
1126 debug ("# hardware_enable done\n");
1127
1128 return (0);
1129}
1130
1131
wdenkc6097192002-11-03 00:24:07 +00001132#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
1133static int hardware_disable(int slot)
1134{
1135 volatile immap_t *immap;
1136 volatile pcmconf8xx_t *pcmp;
1137 u_long reg;
1138 uchar val;
1139
1140 debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1141
1142 immap = (immap_t *)CFG_IMMR;
1143 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1144
1145 /* remove all power, put output in high impedance state */
1146 val = MAX1604_VCCBHIZ | MAX1604_VPPBHIZ;
1147 i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE);
1148 i2c_write (CFG_I2C_POWER_A_ADDR, 0, 0, &val, 1);
1149
1150 /* Configure PCMCIA General Control Register */
wdenkc6097192002-11-03 00:24:07 +00001151 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00001152 reg = 0;
wdenkc6097192002-11-03 00:24:07 +00001153 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1154 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
1155 PCMCIA_PGCRX(_slot_) = reg;
1156
1157 /* Switch off PCMCIA port in PIC register 0x60 */
1158 reg = pic_read (0x60);
1159 debug ("[%d] PIC read: reg_60 = 0x%02x\n", __LINE__, reg);
1160 reg |= 0x10;
1161 reg &= ~0x08;
1162 pic_write (0x60, reg);
1163#ifdef DEBUG
1164 reg = pic_read (0x60);
1165 printf ("[%d] PIC read: reg_60 = 0x%02x\n", __LINE__, reg);
1166#endif
1167 udelay(10000);
1168
1169 return (0);
1170}
1171#endif /* CFG_CMD_PCMCIA */
1172
1173
wdenkc6097192002-11-03 00:24:07 +00001174static int voltage_set(int slot, int vcc, int vpp)
1175{
1176 volatile immap_t *immap;
1177 volatile pcmconf8xx_t *pcmp;
1178 u_long reg;
1179 uchar val;
1180
1181 debug ("voltage_set: "
1182 PCMCIA_BOARD_MSG
1183 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
1184 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
1185
1186 immap = (immap_t *)CFG_IMMR;
1187 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1188 /*
1189 * Disable PCMCIA buffers (isolate the interface)
1190 * and assert RESET signal
1191 */
1192 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00001193 reg = PCMCIA_PGCRX(_slot_);
1194 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1195 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkc6097192002-11-03 00:24:07 +00001196 PCMCIA_PGCRX(_slot_) = reg;
1197 udelay(500);
1198
1199 /*
1200 * Turn off all power (switch to high impedance)
1201 */
1202 debug ("PCMCIA power OFF\n");
1203 val = MAX1604_VCCBHIZ | MAX1604_VPPBHIZ;
1204 i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE);
1205 i2c_write (CFG_I2C_POWER_A_ADDR, 0, 0, &val, 1);
1206
1207 val = 0;
1208 switch(vcc) {
1209 case 0: break;
1210 case 33: val = MAX1604_VCC_35; break;
1211 case 50: break;
1212 default: goto done;
1213 }
1214
1215 /* Checking supported voltages */
1216
1217 debug ("PIPR: 0x%x --> %s\n",
1218 pcmp->pcmc_pipr,
1219 (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
1220
1221 i2c_write (CFG_I2C_POWER_A_ADDR, 0, 0, &val, 1);
1222 if (val) {
1223 debug ("PCMCIA powered at %sV\n",
1224 (val & MAX1604_VCC_35) ? "3.3" : "5.0");
1225 } else {
1226 debug ("PCMCIA powered down\n");
1227 }
1228
1229done:
1230 debug ("Enable PCMCIA buffers and stop RESET\n");
1231 reg = PCMCIA_PGCRX(_slot_);
1232 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
1233 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
1234 PCMCIA_PGCRX(_slot_) = reg;
1235 udelay(500);
1236
1237 debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
1238 slot+'A');
1239 return (0);
1240}
1241
1242#endif /* LWMON */
1243
wdenk1f53a412002-12-04 23:39:58 +00001244/* -------------------------------------------------------------------- */
1245/* GTH board by Corelatus AB */
1246/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00001247#if defined(CONFIG_GTH)
1248
1249#define PCMCIA_BOARD_MSG "GTH COMPACT FLASH"
1250
wdenk1f53a412002-12-04 23:39:58 +00001251static int voltage_set (int slot, int vcc, int vpp)
1252{ /* Do nothing */
1253 return 0;
wdenkc6097192002-11-03 00:24:07 +00001254}
1255
1256static int hardware_enable (int slot)
1257{
wdenk1f53a412002-12-04 23:39:58 +00001258 volatile immap_t *immap;
1259 volatile cpm8xx_t *cp;
1260 volatile pcmconf8xx_t *pcmp;
1261 volatile sysconf8xx_t *sysp;
1262 uint reg, mask;
wdenkc6097192002-11-03 00:24:07 +00001263
wdenk1f53a412002-12-04 23:39:58 +00001264 debug ("hardware_enable: GTH Slot %c\n", 'A' + slot);
wdenkc6097192002-11-03 00:24:07 +00001265
wdenk1f53a412002-12-04 23:39:58 +00001266 immap = (immap_t *) CFG_IMMR;
1267 sysp = (sysconf8xx_t *) (&(((immap_t *) CFG_IMMR)->im_siu_conf));
1268 pcmp = (pcmconf8xx_t *) (&(((immap_t *) CFG_IMMR)->im_pcmcia));
1269 cp = (cpm8xx_t *) (&(((immap_t *) CFG_IMMR)->im_cpm));
wdenkc6097192002-11-03 00:24:07 +00001270
wdenk1f53a412002-12-04 23:39:58 +00001271 /* clear interrupt state, and disable interrupts */
1272 pcmp->pcmc_pscr = PCMCIA_MASK (_slot_);
1273 pcmp->pcmc_per &= ~PCMCIA_MASK (_slot_);
wdenkc6097192002-11-03 00:24:07 +00001274
wdenk1f53a412002-12-04 23:39:58 +00001275 /*
1276 * Disable interrupts, DMA, and PCMCIA buffers
1277 * (isolate the interface) and assert RESET signal
1278 */
1279 debug ("Disable PCMCIA buffers and assert RESET\n");
1280 reg = 0;
1281 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1282 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
1283 PCMCIA_PGCRX (_slot_) = reg;
1284 udelay (500);
wdenkc6097192002-11-03 00:24:07 +00001285
wdenk1f53a412002-12-04 23:39:58 +00001286 /*
1287 * Make sure there is a card in the slot,
1288 * then configure the interface.
1289 */
1290 udelay (10000);
1291 debug ("[%d] %s: PIPR(%p)=0x%x\n",
1292 __LINE__, __FUNCTION__,
1293 &(pcmp->pcmc_pipr), pcmp->pcmc_pipr);
1294 if (pcmp->pcmc_pipr & 0x98000000) {
1295 printf (" No Card found\n");
1296 return (1);
1297 }
wdenkc6097192002-11-03 00:24:07 +00001298
wdenk1f53a412002-12-04 23:39:58 +00001299 mask = PCMCIA_VS1 (slot) | PCMCIA_VS2 (slot);
1300 reg = pcmp->pcmc_pipr;
1301 debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
1302 reg,
1303 (reg & PCMCIA_VS1 (slot)) ? "n" : "ff",
1304 (reg & PCMCIA_VS2 (slot)) ? "n" : "ff");
wdenkc6097192002-11-03 00:24:07 +00001305
wdenk1f53a412002-12-04 23:39:58 +00001306 debug ("Enable PCMCIA buffers and stop RESET\n");
1307 reg = PCMCIA_PGCRX (_slot_);
1308 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
1309 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
1310 PCMCIA_PGCRX (_slot_) = reg;
wdenkc6097192002-11-03 00:24:07 +00001311
wdenk1f53a412002-12-04 23:39:58 +00001312 udelay (250000); /* some cards need >150 ms to come up :-( */
wdenkc6097192002-11-03 00:24:07 +00001313
wdenk1f53a412002-12-04 23:39:58 +00001314 debug ("# hardware_enable done\n");
wdenkc6097192002-11-03 00:24:07 +00001315
wdenk1f53a412002-12-04 23:39:58 +00001316 return 0;
wdenkc6097192002-11-03 00:24:07 +00001317}
1318#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
1319static int hardware_disable(int slot)
1320{
1321 return 0; /* No hardware to disable */
1322}
1323#endif /* CFG_CMD_PCMCIA */
1324#endif /* CONFIG_GTH */
1325
wdenk1f53a412002-12-04 23:39:58 +00001326/* -------------------------------------------------------------------- */
1327/* ICU862 Boards by Cambridge Broadband Ltd. */
1328/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00001329
1330#if defined(CONFIG_ICU862)
1331
1332#define PCMCIA_BOARD_MSG "ICU862"
1333
1334static void cfg_port_B (void);
1335
1336static int hardware_enable(int slot)
1337{
1338 volatile immap_t *immap;
1339 volatile cpm8xx_t *cp;
1340 volatile pcmconf8xx_t *pcmp;
1341 volatile sysconf8xx_t *sysp;
1342 uint reg, pipr, mask;
1343 int i;
1344
1345 debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1346
1347 udelay(10000);
1348
1349 immap = (immap_t *)CFG_IMMR;
1350 sysp = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
1351 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1352 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1353
1354 /* Configure Port B for TPS2205 PC-Card Power-Interface Switch */
1355 cfg_port_B ();
1356
1357 /*
1358 * Configure SIUMCR to enable PCMCIA port B
1359 * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
1360 */
1361 sysp->sc_siumcr &= ~SIUMCR_DBGC11; /* set DBGC to 00 */
1362
1363 /* clear interrupt state, and disable interrupts */
1364 pcmp->pcmc_pscr = PCMCIA_MASK(_slot_);
1365 pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
1366
wdenkc6097192002-11-03 00:24:07 +00001367 /*
wdenk1f53a412002-12-04 23:39:58 +00001368 * Disable interrupts, DMA, and PCMCIA buffers
1369 * (isolate the interface) and assert RESET signal
wdenkc6097192002-11-03 00:24:07 +00001370 */
1371 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00001372 reg = 0;
1373 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1374 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkc6097192002-11-03 00:24:07 +00001375 PCMCIA_PGCRX(_slot_) = reg;
1376 udelay(500);
1377
1378 /*
1379 * Make sure there is a card in the slot, then configure the interface.
1380 */
1381 udelay(10000);
1382 debug ("[%d] %s: PIPR(%p)=0x%x\n",
1383 __LINE__,__FUNCTION__,
1384 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
wdenkea909b72002-11-21 23:11:29 +00001385 if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
wdenkc6097192002-11-03 00:24:07 +00001386 printf (" No Card found\n");
1387 return (1);
1388 }
1389
1390 /*
1391 * Power On: Set VAVCC to 3.3V or 5V, set VAVPP to Hi-Z
1392 */
1393 mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
1394 pipr = pcmp->pcmc_pipr;
1395 debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
1396 pipr,
1397 (reg&PCMCIA_VS1(slot))?"n":"ff",
1398 (reg&PCMCIA_VS2(slot))?"n":"ff");
1399
1400 reg = cp->cp_pbdat;
1401 if ((pipr & mask) == mask) {
wdenk1f53a412002-12-04 23:39:58 +00001402 reg |= (TPS2205_VPP_PGM | TPS2205_VPP_VCC | /* VAVPP => Hi-Z */
1403 TPS2205_VCC3); /* 3V off */
wdenkc6097192002-11-03 00:24:07 +00001404 reg &= ~(TPS2205_VCC5); /* 5V on */
1405 puts (" 5.0V card found: ");
1406 } else {
wdenk1f53a412002-12-04 23:39:58 +00001407 reg |= (TPS2205_VPP_PGM | TPS2205_VPP_VCC | /* VAVPP => Hi-Z */
1408 TPS2205_VCC5); /* 5V off */
wdenkc6097192002-11-03 00:24:07 +00001409 reg &= ~(TPS2205_VCC3); /* 3V on */
1410 puts (" 3.3V card found: ");
1411 }
1412
1413 debug ("\nPB DAT: %08x -> 3.3V %s 5.0V %s VPP_PGM %s VPP_VCC %s\n",
1414 reg,
1415 (reg & TPS2205_VCC3) ? "off" : "on",
1416 (reg & TPS2205_VCC5) ? "off" : "on",
1417 (reg & TPS2205_VPP_PGM) ? "off" : "on",
1418 (reg & TPS2205_VPP_VCC) ? "off" : "on" );
1419
1420 cp->cp_pbdat = reg;
1421
1422 /* Wait 500 ms; use this to check for over-current */
1423 for (i=0; i<5000; ++i) {
1424 if ((cp->cp_pbdat & TPS2205_OC) == 0) {
1425 printf (" *** Overcurrent - Safety shutdown ***\n");
1426 cp->cp_pbdat &= ~(TPS2205_SHDN);
1427 return (1);
1428 }
1429 udelay (100);
1430 }
1431
1432 debug ("Enable PCMCIA buffers and stop RESET\n");
1433 reg = PCMCIA_PGCRX(_slot_);
1434 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
1435 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
1436 PCMCIA_PGCRX(_slot_) = reg;
1437
1438 udelay(250000); /* some cards need >150 ms to come up :-( */
1439
1440 debug ("# hardware_enable done\n");
1441
1442 return (0);
1443}
1444
1445
wdenkc6097192002-11-03 00:24:07 +00001446#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
1447static int hardware_disable(int slot)
1448{
1449 volatile immap_t *immap;
1450 volatile cpm8xx_t *cp;
1451 volatile pcmconf8xx_t *pcmp;
1452 u_long reg;
1453
1454 debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1455
1456 immap = (immap_t *)CFG_IMMR;
1457 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1458 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1459
1460 /* Shut down */
1461 cp->cp_pbdat &= ~(TPS2205_SHDN);
1462
1463 /* Configure PCMCIA General Control Register */
wdenkc6097192002-11-03 00:24:07 +00001464 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00001465 reg = 0;
wdenkc6097192002-11-03 00:24:07 +00001466 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1467 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
1468 PCMCIA_PGCRX(_slot_) = reg;
1469
1470 udelay(10000);
1471
1472 return (0);
1473}
1474#endif /* CFG_CMD_PCMCIA */
1475
1476
wdenkc6097192002-11-03 00:24:07 +00001477static int voltage_set(int slot, int vcc, int vpp)
1478{
1479 volatile immap_t *immap;
1480 volatile cpm8xx_t *cp;
1481 volatile pcmconf8xx_t *pcmp;
1482 u_long reg;
1483
1484 debug ("voltage_set: "
1485 PCMCIA_BOARD_MSG
1486 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
1487 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
1488
1489 immap = (immap_t *)CFG_IMMR;
1490 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1491 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1492 /*
1493 * Disable PCMCIA buffers (isolate the interface)
1494 * and assert RESET signal
1495 */
1496 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00001497 reg = PCMCIA_PGCRX(_slot_);
1498 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1499 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkc6097192002-11-03 00:24:07 +00001500 PCMCIA_PGCRX(_slot_) = reg;
1501 udelay(500);
1502
1503 /*
1504 * Configure Port C pins for
1505 * 5 Volts Enable and 3 Volts enable,
1506 * Turn all power pins to Hi-Z
1507 */
1508 debug ("PCMCIA power OFF\n");
1509 cfg_port_B (); /* Enables switch, but all in Hi-Z */
1510
1511 reg = cp->cp_pbdat;
1512
1513 switch(vcc) {
1514 case 0: break; /* Switch off */
1515 case 33: reg &= ~TPS2205_VCC3; break; /* Switch on 3.3V */
1516 case 50: reg &= ~TPS2205_VCC5; break; /* Switch on 5.0V */
1517 default: goto done;
1518 }
1519
1520 /* Checking supported voltages */
1521
1522 debug ("PIPR: 0x%x --> %s\n",
1523 pcmp->pcmc_pipr,
1524 (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
1525
1526 cp->cp_pbdat = reg;
1527
1528#ifdef DEBUG
1529 {
1530 char *s;
1531
1532 if ((reg & TPS2205_VCC3) == 0) {
1533 s = "at 3.3V";
1534 } else if ((reg & TPS2205_VCC5) == 0) {
1535 s = "at 5.0V";
1536 } else {
1537 s = "down";
1538 }
1539 printf ("PCMCIA powered %s\n", s);
1540 }
1541#endif
1542
1543done:
1544 debug ("Enable PCMCIA buffers and stop RESET\n");
1545 reg = PCMCIA_PGCRX(_slot_);
1546 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
1547 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
1548 PCMCIA_PGCRX(_slot_) = reg;
1549 udelay(500);
1550
1551 debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
1552 slot+'A');
1553 return (0);
1554}
1555
1556static void cfg_port_B (void)
1557{
1558 volatile immap_t *immap;
1559 volatile cpm8xx_t *cp;
1560 uint reg;
1561
1562 immap = (immap_t *)CFG_IMMR;
1563 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1564
1565 /*
1566 * Configure Port B for TPS2205 PC-Card Power-Interface Switch
1567 *
1568 * Switch off all voltages, assert shutdown
1569 */
1570 reg = cp->cp_pbdat;
wdenk1f53a412002-12-04 23:39:58 +00001571 reg |= (TPS2205_VPP_PGM | TPS2205_VPP_VCC | /* VAVPP => Hi-Z */
1572 TPS2205_VCC3 | TPS2205_VCC5 | /* VAVCC => Hi-Z */
1573 TPS2205_SHDN); /* enable switch */
wdenkc6097192002-11-03 00:24:07 +00001574 cp->cp_pbdat = reg;
1575
1576 cp->cp_pbpar &= ~(TPS2205_INPUTS | TPS2205_OUTPUTS);
1577
1578 reg = cp->cp_pbdir & ~(TPS2205_INPUTS);
1579 cp->cp_pbdir = reg | TPS2205_OUTPUTS;
1580
1581 debug ("Set Port B: PAR: %08x DIR: %08x DAT: %08x\n",
1582 cp->cp_pbpar, cp->cp_pbdir, cp->cp_pbdat);
1583}
1584
1585#endif /* ICU862 */
1586
1587
wdenk1f53a412002-12-04 23:39:58 +00001588/* -------------------------------------------------------------------- */
1589/* C2MON Boards by TTTech Computertechnik AG */
1590/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00001591
1592#if defined(CONFIG_C2MON)
1593
1594#define PCMCIA_BOARD_MSG "C2MON"
1595
1596static void cfg_ports (void);
1597
1598static int hardware_enable(int slot)
1599{
1600 volatile immap_t *immap;
1601 volatile cpm8xx_t *cp;
1602 volatile pcmconf8xx_t *pcmp;
1603 volatile sysconf8xx_t *sysp;
1604 uint reg, pipr, mask;
1605 ushort sreg;
1606 int i;
1607
1608 debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1609
1610 udelay(10000);
1611
1612 immap = (immap_t *)CFG_IMMR;
1613 sysp = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
1614 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1615 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1616
1617 /* Configure Ports for TPS2211A PC-Card Power-Interface Switch */
1618 cfg_ports ();
1619
1620 /*
1621 * Configure SIUMCR to enable PCMCIA port B
1622 * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
1623 */
1624 sysp->sc_siumcr &= ~SIUMCR_DBGC11; /* set DBGC to 00 */
1625
1626 /* clear interrupt state, and disable interrupts */
1627 pcmp->pcmc_pscr = PCMCIA_MASK(_slot_);
1628 pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
1629
wdenkc6097192002-11-03 00:24:07 +00001630 /*
wdenk1f53a412002-12-04 23:39:58 +00001631 * Disable interrupts, DMA, and PCMCIA buffers
1632 * (isolate the interface) and assert RESET signal
wdenkc6097192002-11-03 00:24:07 +00001633 */
1634 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00001635 reg = 0;
1636 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1637 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkc6097192002-11-03 00:24:07 +00001638 PCMCIA_PGCRX(_slot_) = reg;
1639 udelay(500);
1640
1641 /*
1642 * Make sure there is a card in the slot, then configure the interface.
1643 */
1644 udelay(10000);
1645 debug ("[%d] %s: PIPR(%p)=0x%x\n",
1646 __LINE__,__FUNCTION__,
1647 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
wdenkea909b72002-11-21 23:11:29 +00001648 if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
wdenkc6097192002-11-03 00:24:07 +00001649 printf (" No Card found\n");
1650 return (1);
1651 }
1652
1653 /*
1654 * Power On: Set VAVCC to 3.3V or 5V, set VAVPP to Hi-Z
1655 */
1656 mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
1657 pipr = pcmp->pcmc_pipr;
1658 debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
1659 pipr,
1660 (reg&PCMCIA_VS1(slot))?"n":"ff",
1661 (reg&PCMCIA_VS2(slot))?"n":"ff");
1662
1663 sreg = immap->im_ioport.iop_pcdat;
1664 if ((pipr & mask) == mask) {
1665 sreg |= (TPS2211_VPPD0 | TPS2211_VPPD1 | /* VAVPP => Hi-Z */
1666 TPS2211_VCCD1); /* 5V on */
1667 sreg &= ~(TPS2211_VCCD0); /* 3V off */
1668 puts (" 5.0V card found: ");
1669 } else {
1670 sreg |= (TPS2211_VPPD0 | TPS2211_VPPD1 | /* VAVPP => Hi-Z */
1671 TPS2211_VCCD0); /* 3V on */
1672 sreg &= ~(TPS2211_VCCD1); /* 5V off */
1673 puts (" 3.3V card found: ");
1674 }
1675
1676 debug ("\nPC DAT: %04x -> 3.3V %s 5.0V %s\n",
1677 sreg,
1678 ( (sreg & TPS2211_VCCD0) && !(sreg & TPS2211_VCCD1)) ? "on" : "off",
1679 (!(sreg & TPS2211_VCCD0) && (sreg & TPS2211_VCCD1)) ? "on" : "off"
1680 );
1681
1682 immap->im_ioport.iop_pcdat = sreg;
1683
1684 /* Wait 500 ms; use this to check for over-current */
1685 for (i=0; i<5000; ++i) {
1686 if ((cp->cp_pbdat & TPS2211_OC) == 0) {
1687 printf (" *** Overcurrent - Safety shutdown ***\n");
1688 immap->im_ioport.iop_pcdat &= ~(TPS2211_VCCD0|TPS2211_VCCD1);
1689 return (1);
1690 }
1691 udelay (100);
1692 }
1693
1694 debug ("Enable PCMCIA buffers and stop RESET\n");
1695 reg = PCMCIA_PGCRX(_slot_);
1696 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
1697 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
1698 PCMCIA_PGCRX(_slot_) = reg;
1699
1700 udelay(250000); /* some cards need >150 ms to come up :-( */
1701
1702 debug ("# hardware_enable done\n");
1703
1704 return (0);
1705}
1706
1707
wdenkc6097192002-11-03 00:24:07 +00001708#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
1709static int hardware_disable(int slot)
1710{
1711 volatile immap_t *immap;
1712 volatile cpm8xx_t *cp;
1713 volatile pcmconf8xx_t *pcmp;
1714 u_long reg;
1715
1716 debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1717
1718 immap = (immap_t *)CFG_IMMR;
1719 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1720
1721 /* Configure PCMCIA General Control Register */
wdenkc6097192002-11-03 00:24:07 +00001722 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00001723 reg = 0;
wdenkc6097192002-11-03 00:24:07 +00001724 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1725 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
1726 PCMCIA_PGCRX(_slot_) = reg;
1727
1728 /* ALl voltages off / Hi-Z */
1729 immap->im_ioport.iop_pcdat |= (TPS2211_VPPD0 | TPS2211_VPPD1 |
1730 TPS2211_VCCD0 | TPS2211_VCCD1 );
1731
1732 udelay(10000);
1733
1734 return (0);
1735}
1736#endif /* CFG_CMD_PCMCIA */
1737
1738
wdenkc6097192002-11-03 00:24:07 +00001739static int voltage_set(int slot, int vcc, int vpp)
1740{
1741 volatile immap_t *immap;
1742 volatile cpm8xx_t *cp;
1743 volatile pcmconf8xx_t *pcmp;
1744 u_long reg;
1745 ushort sreg;
1746
1747 debug ("voltage_set: "
1748 PCMCIA_BOARD_MSG
1749 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
1750 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
1751
1752 immap = (immap_t *)CFG_IMMR;
1753 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1754 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1755 /*
1756 * Disable PCMCIA buffers (isolate the interface)
1757 * and assert RESET signal
1758 */
1759 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00001760 reg = PCMCIA_PGCRX(_slot_);
1761 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1762 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkc6097192002-11-03 00:24:07 +00001763 PCMCIA_PGCRX(_slot_) = reg;
1764 udelay(500);
1765
1766 /*
1767 * Configure Port C pins for
1768 * 5 Volts Enable and 3 Volts enable,
1769 * Turn all power pins to Hi-Z
1770 */
1771 debug ("PCMCIA power OFF\n");
1772 cfg_ports (); /* Enables switch, but all in Hi-Z */
1773
1774 sreg = immap->im_ioport.iop_pcdat;
1775 sreg |= TPS2211_VPPD0 | TPS2211_VPPD1; /* VAVPP always Hi-Z */
1776
1777 switch(vcc) {
1778 case 0: break; /* Switch off */
1779 case 33: sreg |= TPS2211_VCCD0; /* Switch on 3.3V */
1780 sreg &= ~TPS2211_VCCD1;
1781 break;
1782 case 50: sreg &= ~TPS2211_VCCD0; /* Switch on 5.0V */
1783 sreg |= TPS2211_VCCD1;
1784 break;
1785 default: goto done;
1786 }
1787
1788 /* Checking supported voltages */
1789
1790 debug ("PIPR: 0x%x --> %s\n",
1791 pcmp->pcmc_pipr,
1792 (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
1793
1794 immap->im_ioport.iop_pcdat = sreg;
1795
1796#ifdef DEBUG
1797 {
1798 char *s;
1799
1800 if ((sreg & TPS2211_VCCD0) && !(sreg & TPS2211_VCCD1)) {
1801 s = "at 3.3V";
1802 } else if (!(sreg & TPS2211_VCCD0) && (sreg & TPS2211_VCCD1)) {
1803 s = "at 5.0V";
1804 } else {
1805 s = "down";
1806 }
1807 printf ("PCMCIA powered %s\n", s);
1808 }
1809#endif
1810
1811done:
1812 debug ("Enable PCMCIA buffers and stop RESET\n");
1813 reg = PCMCIA_PGCRX(_slot_);
1814 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
1815 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
1816 PCMCIA_PGCRX(_slot_) = reg;
1817 udelay(500);
1818
1819 debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
1820 slot+'A');
1821 return (0);
1822}
1823
1824static void cfg_ports (void)
1825{
1826 volatile immap_t *immap;
1827 volatile cpm8xx_t *cp;
1828 ushort sreg;
1829
1830 immap = (immap_t *)CFG_IMMR;
1831 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1832
1833 /*
1834 * Configure Port C for TPS2211 PC-Card Power-Interface Switch
1835 *
1836 * Switch off all voltages, assert shutdown
1837 */
1838 sreg = immap->im_ioport.iop_pcdat;
1839 sreg |= (TPS2211_VPPD0 | TPS2211_VPPD1); /* VAVPP => Hi-Z */
1840 sreg &= ~(TPS2211_VCCD0 | TPS2211_VCCD1); /* 3V and 5V off */
1841 immap->im_ioport.iop_pcdat = sreg;
1842
1843 immap->im_ioport.iop_pcpar &= ~(TPS2211_OUTPUTS);
1844 immap->im_ioport.iop_pcdir |= TPS2211_OUTPUTS;
1845
1846 debug ("Set Port C: PAR: %04x DIR: %04x DAT: %04x\n",
1847 immap->im_ioport.iop_pcpar,
1848 immap->im_ioport.iop_pcdir,
1849 immap->im_ioport.iop_pcdat);
1850
1851 /*
1852 * Configure Port B for TPS2211 PC-Card Power-Interface Switch
1853 *
1854 * Over-Current Input only
1855 */
1856 cp->cp_pbpar &= ~(TPS2211_INPUTS);
1857 cp->cp_pbdir &= ~(TPS2211_INPUTS);
1858
1859 debug ("Set Port B: PAR: %08x DIR: %08x DAT: %08x\n",
1860 cp->cp_pbpar, cp->cp_pbdir, cp->cp_pbdat);
1861}
1862
1863#endif /* C2MON */
1864
wdenk1f53a412002-12-04 23:39:58 +00001865/* -------------------------------------------------------------------- */
1866/* MBX board from Morotola */
1867/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00001868
1869#if defined( CONFIG_MBX )
1870#include <../board/mbx8xx/csr.h>
1871
1872/* A lot of this has been taken from the RPX code in this file it works from me.
1873 I have added the voltage selection for the MBX board. */
1874
1875/* MBX voltage bit in control register #2 */
1876#define CR2_VPP12 ((uchar)0x10)
1877#define CR2_VPPVDD ((uchar)0x20)
1878#define CR2_VDD5 ((uchar)0x40)
1879#define CR2_VDD3 ((uchar)0x80)
1880
1881#define PCMCIA_BOARD_MSG "MBX860"
1882
1883static int voltage_set (int slot, int vcc, int vpp)
1884{
1885 uchar reg = 0;
1886
1887 debug ("voltage_set: PCMCIA_BOARD_MSG Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
1888 'A' + slot, vcc / 10, vcc % 10, vpp / 10, vcc % 10);
1889
1890 switch (vcc) {
1891 case 0:
1892 break;
1893 case 33:
1894 reg |= CR2_VDD3;
1895 break;
1896 case 50:
1897 reg |= CR2_VDD5;
1898 break;
1899 default:
1900 return 1;
1901 }
1902
1903 switch (vpp) {
1904 case 0:
1905 break;
1906 case 33:
1907 case 50:
1908 if (vcc == vpp) {
1909 reg |= CR2_VPPVDD;
1910 } else {
1911 return 1;
1912 }
1913 break;
1914 case 120:
1915 reg |= CR2_VPP12;
1916 break;
1917 default:
1918 return 1;
1919 }
1920
1921 /* first, turn off all power */
1922 MBX_CSR2 &= ~(CR2_VDDSEL | CR2_VPPSEL);
1923
1924 /* enable new powersettings */
1925 MBX_CSR2 |= reg;
1926 debug ("MBX_CSR2 read = 0x%02x\n", MBX_CSR2);
1927
1928 return (0);
1929}
1930
1931static int hardware_enable (int slot)
1932{
1933 volatile immap_t *immap;
1934 volatile cpm8xx_t *cp;
1935 volatile pcmconf8xx_t *pcmp;
1936 volatile sysconf8xx_t *sysp;
1937 uint reg, mask;
1938
1939 debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n",
1940 'A' + slot);
1941
1942 udelay (10000);
1943
1944 immap = (immap_t *) CFG_IMMR;
1945 sysp = (sysconf8xx_t *) (&(((immap_t *) CFG_IMMR)->im_siu_conf));
1946 pcmp = (pcmconf8xx_t *) (&(((immap_t *) CFG_IMMR)->im_pcmcia));
1947 cp = (cpm8xx_t *) (&(((immap_t *) CFG_IMMR)->im_cpm));
1948
1949 /* clear interrupt state, and disable interrupts */
1950 pcmp->pcmc_pscr = PCMCIA_MASK (_slot_);
1951 pcmp->pcmc_per &= ~PCMCIA_MASK (_slot_);
1952
wdenkc6097192002-11-03 00:24:07 +00001953 /*
wdenk1f53a412002-12-04 23:39:58 +00001954 * Disable interrupts, DMA, and PCMCIA buffers
1955 * (isolate the interface) and assert RESET signal
wdenkc6097192002-11-03 00:24:07 +00001956 */
1957 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00001958 reg = 0;
wdenkc6097192002-11-03 00:24:07 +00001959 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1960 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
1961 PCMCIA_PGCRX (_slot_) = reg;
1962 udelay (500);
1963
1964 /* remove all power */
1965 voltage_set (slot, 0, 0);
1966 /*
1967 * Make sure there is a card in the slot, then configure the interface.
1968 */
wdenkea909b72002-11-21 23:11:29 +00001969 udelay(10000);
1970 debug ("[%d] %s: PIPR(%p)=0x%x\n",
1971 __LINE__,__FUNCTION__,
1972 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
wdenkc40b2952004-03-13 23:29:43 +00001973#ifndef CONFIG_HMI10
wdenkea909b72002-11-21 23:11:29 +00001974 if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
wdenka522fa02004-01-04 22:51:12 +00001975#else
1976 if (pcmp->pcmc_pipr & (0x10000000 >> (slot << 4))) {
wdenkc40b2952004-03-13 23:29:43 +00001977#endif /* CONFIG_HMI10 */
wdenkc6097192002-11-03 00:24:07 +00001978 printf (" No Card found\n");
1979 return (1);
1980 }
1981
1982 /*
1983 * Power On.
1984 */
1985 mask = PCMCIA_VS1 (_slot_) | PCMCIA_VS2 (_slot_);
1986 reg = pcmp->pcmc_pipr;
1987 debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n", reg,
1988 (reg & PCMCIA_VS1 (slot)) ? "n" : "ff",
1989 (reg & PCMCIA_VS2 (slot)) ? "n" : "ff");
1990
1991 if ((reg & mask) == mask) {
1992 voltage_set (_slot_, 50, 0);
1993 printf (" 5.0V card found: ");
1994 } else {
1995 voltage_set (_slot_, 33, 0);
1996 printf (" 3.3V card found: ");
1997 }
1998
1999 debug ("Enable PCMCIA buffers and stop RESET\n");
2000 reg = PCMCIA_PGCRX (_slot_);
2001 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
2002 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
2003 PCMCIA_PGCRX (_slot_) = reg;
2004
2005 udelay (250000); /* some cards need >150 ms to come up :-( */
2006
2007 debug ("# hardware_enable done\n");
2008
2009 return (0);
2010}
2011
2012#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
2013static int hardware_disable (int slot)
2014{
2015 return 0; /* No hardware to disable */
2016}
2017#endif /* CFG_CMD_PCMCIA */
2018#endif /* CONFIG_MBX */
wdenk1f53a412002-12-04 23:39:58 +00002019/* -------------------------------------------------------------------- */
2020/* R360MPI Board */
2021/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00002022
2023#if defined(CONFIG_R360MPI)
2024
2025#define PCMCIA_BOARD_MSG "R360MPI"
2026
2027
2028static int hardware_enable(int slot)
2029{
2030 volatile immap_t *immap;
2031 volatile cpm8xx_t *cp;
2032 volatile pcmconf8xx_t *pcmp;
2033 volatile sysconf8xx_t *sysp;
2034 uint reg, mask;
2035
2036 debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
2037
2038 udelay(10000);
2039
2040 immap = (immap_t *)CFG_IMMR;
2041 sysp = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
2042 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
2043 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
2044
2045 /*
2046 * Configure SIUMCR to enable PCMCIA port B
2047 * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
2048 */
2049 sysp->sc_siumcr &= ~SIUMCR_DBGC11; /* set DBGC to 00 */
2050
2051 /* clear interrupt state, and disable interrupts */
2052 pcmp->pcmc_pscr = PCMCIA_MASK(_slot_);
2053 pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
2054
wdenkc6097192002-11-03 00:24:07 +00002055 /*
wdenk1f53a412002-12-04 23:39:58 +00002056 * Disable interrupts, DMA, and PCMCIA buffers
2057 * (isolate the interface) and assert RESET signal
wdenkc6097192002-11-03 00:24:07 +00002058 */
2059 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00002060 reg = 0;
2061 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
2062 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkc6097192002-11-03 00:24:07 +00002063 PCMCIA_PGCRX(_slot_) = reg;
2064 udelay(500);
2065
2066 /*
2067 * Configure Ports A, B & C pins for
2068 * 5 Volts Enable and 3 Volts enable
2069 */
2070 immap->im_ioport.iop_pcpar &= ~(0x0400);
2071 immap->im_ioport.iop_pcso &= ~(0x0400);/*
2072 immap->im_ioport.iop_pcdir |= 0x0400;*/
2073
2074 immap->im_ioport.iop_papar &= ~(0x0200);/*
2075 immap->im_ioport.iop_padir |= 0x0200;*/
2076#if 0
2077 immap->im_ioport.iop_pbpar &= ~(0xC000);
2078 immap->im_ioport.iop_pbdir &= ~(0xC000);
2079#endif
2080 /* remove all power */
2081
2082 immap->im_ioport.iop_pcdat |= 0x0400;
2083 immap->im_ioport.iop_padat |= 0x0200;
2084
2085 /*
2086 * Make sure there is a card in the slot, then configure the interface.
2087 */
2088 udelay(10000);
2089 debug ("[%d] %s: PIPR(%p)=0x%x\n",
2090 __LINE__,__FUNCTION__,
2091 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
wdenkea909b72002-11-21 23:11:29 +00002092 if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
wdenkc6097192002-11-03 00:24:07 +00002093 printf (" No Card found\n");
2094 return (1);
2095 }
2096
2097 /*
2098 * Power On.
2099 */
2100 mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
2101 reg = pcmp->pcmc_pipr;
2102 debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
2103 reg,
2104 (reg&PCMCIA_VS1(slot))?"n":"ff",
2105 (reg&PCMCIA_VS2(slot))?"n":"ff");
2106 if ((reg & mask) == mask) {
2107 immap->im_ioport.iop_pcdat &= ~(0x4000);
2108 puts (" 5.0V card found: ");
2109 } else {
2110 immap->im_ioport.iop_padat &= ~(0x0002);
2111 puts (" 3.3V card found: ");
2112 }
2113 immap->im_ioport.iop_pcdir |= 0x0400;
2114 immap->im_ioport.iop_padir |= 0x0200;
2115#if 0
2116 /* VCC switch error flag, PCMCIA slot INPACK_ pin */
2117 cp->cp_pbdir &= ~(0x0020 | 0x0010);
2118 cp->cp_pbpar &= ~(0x0020 | 0x0010);
2119 udelay(500000);
2120#endif
2121 debug ("Enable PCMCIA buffers and stop RESET\n");
2122 reg = PCMCIA_PGCRX(_slot_);
2123 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
2124 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
2125 PCMCIA_PGCRX(_slot_) = reg;
2126
2127 udelay(250000); /* some cards need >150 ms to come up :-( */
2128
2129 debug ("# hardware_enable done\n");
2130
2131 return (0);
2132}
2133
2134
wdenkc6097192002-11-03 00:24:07 +00002135#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
2136static int hardware_disable(int slot)
2137{
2138 volatile immap_t *immap;
2139 volatile pcmconf8xx_t *pcmp;
2140 u_long reg;
2141
2142 debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
2143
2144 immap = (immap_t *)CFG_IMMR;
2145 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
2146
2147 /* remove all power */
2148 immap->im_ioport.iop_pcdat |= 0x0400;
2149 immap->im_ioport.iop_padat |= 0x0200;
2150
2151 /* Configure PCMCIA General Control Register */
wdenkc6097192002-11-03 00:24:07 +00002152 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00002153 reg = 0;
wdenkc6097192002-11-03 00:24:07 +00002154 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
2155 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
2156 PCMCIA_PGCRX(_slot_) = reg;
2157
2158 udelay(10000);
2159
2160 return (0);
2161}
2162#endif /* CFG_CMD_PCMCIA */
2163
2164
wdenkc6097192002-11-03 00:24:07 +00002165static int voltage_set(int slot, int vcc, int vpp)
2166{
2167 volatile immap_t *immap;
2168 volatile pcmconf8xx_t *pcmp;
2169 u_long reg;
2170
2171 debug ("voltage_set: "
2172 PCMCIA_BOARD_MSG
2173 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
2174 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
2175
2176 immap = (immap_t *)CFG_IMMR;
2177 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
2178 /*
2179 * Disable PCMCIA buffers (isolate the interface)
2180 * and assert RESET signal
2181 */
2182 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00002183 reg = PCMCIA_PGCRX(_slot_);
2184 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
2185 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkc6097192002-11-03 00:24:07 +00002186 PCMCIA_PGCRX(_slot_) = reg;
2187 udelay(500);
2188
2189 /*
2190 * Configure Ports A & C pins for
2191 * 5 Volts Enable and 3 Volts enable,
2192 * Turn off all power
2193 */
2194 debug ("PCMCIA power OFF\n");
2195 immap->im_ioport.iop_pcpar &= ~(0x0400);
2196 immap->im_ioport.iop_pcso &= ~(0x0400);/*
2197 immap->im_ioport.iop_pcdir |= 0x0400;*/
2198
2199 immap->im_ioport.iop_papar &= ~(0x0200);/*
2200 immap->im_ioport.iop_padir |= 0x0200;*/
2201
2202 immap->im_ioport.iop_pcdat |= 0x0400;
2203 immap->im_ioport.iop_padat |= 0x0200;
2204
2205 reg = 0;
2206 switch(vcc) {
2207 case 0: break;
2208 case 33: reg |= 0x0200; break;
2209 case 50: reg |= 0x0400; break;
2210 default: goto done;
2211 }
2212
2213 /* Checking supported voltages */
2214
2215 debug ("PIPR: 0x%x --> %s\n",
2216 pcmp->pcmc_pipr,
2217 (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
2218
2219 if (reg & 0x0200)
2220 immap->im_ioport.iop_pcdat &= !reg;
2221 if (reg & 0x0400)
2222 immap->im_ioport.iop_padat &= !reg;
wdenk1f53a412002-12-04 23:39:58 +00002223 immap->im_ioport.iop_pcdir |= 0x0200;
2224 immap->im_ioport.iop_padir |= 0x0400;
wdenkc6097192002-11-03 00:24:07 +00002225 if (reg) {
2226 debug ("PCMCIA powered at %sV\n",
2227 (reg&0x0400) ? "5.0" : "3.3");
2228 } else {
2229 debug ("PCMCIA powered down\n");
2230 }
2231
2232done:
2233 debug ("Enable PCMCIA buffers and stop RESET\n");
2234 reg = PCMCIA_PGCRX(_slot_);
2235 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
2236 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
2237 PCMCIA_PGCRX(_slot_) = reg;
2238 udelay(500);
2239
2240 debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
2241 slot+'A');
2242 return (0);
2243}
2244
2245#endif /* R360MPI */
2246
wdenk1f53a412002-12-04 23:39:58 +00002247/* -------------------------------------------------------------------- */
wdenk0608e042004-03-25 19:29:38 +00002248/* KUP4K and KUP4X Boards */
wdenk1f53a412002-12-04 23:39:58 +00002249/* -------------------------------------------------------------------- */
wdenk0608e042004-03-25 19:29:38 +00002250#if defined(CONFIG_KUP4K) || defined(CONFIG_KUP4X)
wdenk56f94be2002-11-05 16:35:14 +00002251
wdenk0608e042004-03-25 19:29:38 +00002252#define PCMCIA_BOARD_MSG "KUP"
wdenk56f94be2002-11-05 16:35:14 +00002253
2254#define KUP4K_PCMCIA_B_3V3 (0x00020000)
2255
2256static int hardware_enable(int slot)
2257{
2258 volatile immap_t *immap;
2259 volatile cpm8xx_t *cp;
2260 volatile pcmconf8xx_t *pcmp;
2261 volatile sysconf8xx_t *sysp;
2262 uint reg, mask;
2263
2264 debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
2265
2266 udelay(10000);
2267
2268 immap = (immap_t *)CFG_IMMR;
2269 sysp = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
2270 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
2271 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
2272
2273 /*
2274 * Configure SIUMCR to enable PCMCIA port B
2275 * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
2276 */
2277 sysp->sc_siumcr &= ~SIUMCR_DBGC11; /* set DBGC to 00 */
2278
2279 /* clear interrupt state, and disable interrupts */
wdenkea909b72002-11-21 23:11:29 +00002280 pcmp->pcmc_pscr = PCMCIA_MASK(slot);
2281 pcmp->pcmc_per &= ~PCMCIA_MASK(slot);
wdenk56f94be2002-11-05 16:35:14 +00002282
wdenk56f94be2002-11-05 16:35:14 +00002283 /*
wdenk1f53a412002-12-04 23:39:58 +00002284 * Disable interrupts, DMA, and PCMCIA buffers
2285 * (isolate the interface) and assert RESET signal
wdenk56f94be2002-11-05 16:35:14 +00002286 */
2287 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00002288 reg = 0;
2289 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
2290 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkea909b72002-11-21 23:11:29 +00002291 PCMCIA_PGCRX(slot) = reg;
2292 udelay(2500);
wdenk56f94be2002-11-05 16:35:14 +00002293
2294 /*
2295 * Configure Port B pins for
2296 * 3 Volts enable
2297 */
wdenkea909b72002-11-21 23:11:29 +00002298 if (slot) { /* Slot A is built-in */
2299 cp->cp_pbdir |= KUP4K_PCMCIA_B_3V3;
2300 cp->cp_pbpar &= ~KUP4K_PCMCIA_B_3V3;
2301 /* remove all power */
2302 cp->cp_pbdat |= KUP4K_PCMCIA_B_3V3; /* active low */
2303 }
wdenk56f94be2002-11-05 16:35:14 +00002304 /*
2305 * Make sure there is a card in the slot, then configure the interface.
2306 */
2307 udelay(10000);
2308 debug ("[%d] %s: PIPR(%p)=0x%x\n",
2309 __LINE__,__FUNCTION__,
2310 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
wdenkea909b72002-11-21 23:11:29 +00002311 if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
wdenk56f94be2002-11-05 16:35:14 +00002312 printf (" No Card found\n");
2313 return (1);
2314 }
2315
2316 /*
2317 * Power On.
2318 */
wdenka6c7ad22002-12-03 21:28:10 +00002319 printf("%s Slot %c:", slot ? "" : "\n", 'A' + slot);
wdenk56f94be2002-11-05 16:35:14 +00002320 mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
2321 reg = pcmp->pcmc_pipr;
2322 debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
2323 reg,
2324 (reg&PCMCIA_VS1(slot))?"n":"ff",
2325 (reg&PCMCIA_VS2(slot))?"n":"ff");
2326 if ((reg & mask) == mask) {
2327 puts (" 5.0V card found: NOT SUPPORTED !!!\n");
2328 } else {
wdenkea909b72002-11-21 23:11:29 +00002329 if(slot)
2330 cp->cp_pbdat &= ~KUP4K_PCMCIA_B_3V3;
wdenk56f94be2002-11-05 16:35:14 +00002331 puts (" 3.3V card found: ");
2332 }
2333#if 0
2334 /* VCC switch error flag, PCMCIA slot INPACK_ pin */
2335 cp->cp_pbdir &= ~(0x0020 | 0x0010);
2336 cp->cp_pbpar &= ~(0x0020 | 0x0010);
2337 udelay(500000);
2338#endif
2339 debug ("Enable PCMCIA buffers and stop RESET\n");
wdenkea909b72002-11-21 23:11:29 +00002340 reg = PCMCIA_PGCRX(slot);
wdenk56f94be2002-11-05 16:35:14 +00002341 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
2342 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkea909b72002-11-21 23:11:29 +00002343 PCMCIA_PGCRX(slot) = reg;
wdenk56f94be2002-11-05 16:35:14 +00002344
2345 udelay(250000); /* some cards need >150 ms to come up :-( */
2346
2347 debug ("# hardware_enable done\n");
2348
2349 return (0);
2350}
2351
2352
wdenk56f94be2002-11-05 16:35:14 +00002353#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
2354static int hardware_disable(int slot)
2355{
2356 volatile immap_t *immap;
2357 volatile cpm8xx_t *cp;
2358 volatile pcmconf8xx_t *pcmp;
2359 u_long reg;
2360
2361 debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
2362
2363 immap = (immap_t *)CFG_IMMR;
2364 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
2365 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
wdenk1f53a412002-12-04 23:39:58 +00002366
wdenk56f94be2002-11-05 16:35:14 +00002367 /* remove all power */
wdenkea909b72002-11-21 23:11:29 +00002368 if (slot)
2369 cp->cp_pbdat |= KUP4K_PCMCIA_B_3V3;
wdenk56f94be2002-11-05 16:35:14 +00002370
2371 /* Configure PCMCIA General Control Register */
wdenk56f94be2002-11-05 16:35:14 +00002372 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00002373 reg = 0;
wdenk56f94be2002-11-05 16:35:14 +00002374 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
2375 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkea909b72002-11-21 23:11:29 +00002376 PCMCIA_PGCRX(slot) = reg;
wdenk56f94be2002-11-05 16:35:14 +00002377
2378 udelay(10000);
2379
2380 return (0);
2381}
2382#endif /* CFG_CMD_PCMCIA */
2383
2384
wdenk56f94be2002-11-05 16:35:14 +00002385static int voltage_set(int slot, int vcc, int vpp)
2386{
2387 volatile immap_t *immap;
2388 volatile cpm8xx_t *cp;
2389 volatile pcmconf8xx_t *pcmp;
2390 u_long reg;
2391
2392 debug ("voltage_set: " \
2393 PCMCIA_BOARD_MSG \
2394 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
2395 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
2396
wdenkea909b72002-11-21 23:11:29 +00002397 if (!slot) /* Slot A is not configurable */
2398 return 0;
2399
wdenk56f94be2002-11-05 16:35:14 +00002400 immap = (immap_t *)CFG_IMMR;
2401 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
2402 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
2403
2404 /*
2405 * Disable PCMCIA buffers (isolate the interface)
2406 * and assert RESET signal
2407 */
2408 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk1f53a412002-12-04 23:39:58 +00002409 reg = PCMCIA_PGCRX(slot);
2410 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
2411 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkea909b72002-11-21 23:11:29 +00002412 PCMCIA_PGCRX(slot) = reg;
wdenk56f94be2002-11-05 16:35:14 +00002413 udelay(500);
2414
2415 debug ("PCMCIA power OFF\n");
2416 /*
2417 * Configure Port B pins for
2418 * 3 Volts enable
2419 */
2420 cp->cp_pbdir |= KUP4K_PCMCIA_B_3V3;
2421 cp->cp_pbpar &= ~KUP4K_PCMCIA_B_3V3;
2422 /* remove all power */
2423 cp->cp_pbdat |= KUP4K_PCMCIA_B_3V3; /* active low */
2424
2425 switch(vcc) {
2426 case 0: break;
2427 case 33:
2428 cp->cp_pbdat &= ~KUP4K_PCMCIA_B_3V3;
2429 debug ("PCMCIA powered at 3.3V\n");
2430 break;
2431 case 50:
2432 debug ("PCMCIA: 5Volt vcc not supported\n");
2433 break;
2434 default:
2435 puts("PCMCIA: vcc not supported");
2436 break;
2437 }
wdenkea909b72002-11-21 23:11:29 +00002438 udelay(10000);
wdenk56f94be2002-11-05 16:35:14 +00002439 /* Checking supported voltages */
2440
2441 debug ("PIPR: 0x%x --> %s\n",
2442 pcmp->pcmc_pipr,
wdenkea909b72002-11-21 23:11:29 +00002443 (pcmp->pcmc_pipr & (0x80000000 >> (slot << 4)))
wdenk56f94be2002-11-05 16:35:14 +00002444 ? "only 5 V --> NOT SUPPORTED"
2445 : "can do 3.3V");
2446
2447
2448 debug ("Enable PCMCIA buffers and stop RESET\n");
wdenkea909b72002-11-21 23:11:29 +00002449 reg = PCMCIA_PGCRX(slot);
wdenk56f94be2002-11-05 16:35:14 +00002450 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
2451 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkea909b72002-11-21 23:11:29 +00002452 PCMCIA_PGCRX(slot) = reg;
wdenk56f94be2002-11-05 16:35:14 +00002453 udelay(500);
2454
2455 debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
2456 slot+'A');
2457 return (0);
2458}
2459
wdenk0608e042004-03-25 19:29:38 +00002460#endif /* KUP4K || KUP4X */
wdenk56f94be2002-11-05 16:35:14 +00002461
2462
wdenk1f53a412002-12-04 23:39:58 +00002463/* -------------------------------------------------------------------- */
2464/* End of Board Specific Stuff */
2465/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00002466
2467
wdenk1f53a412002-12-04 23:39:58 +00002468/* -------------------------------------------------------------------- */
2469/* MPC8xx Specific Stuff - should go to MPC8xx directory */
2470/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00002471
2472/*
2473 * Search this table to see if the windowsize is
2474 * supported...
2475 */
2476
2477#define M8XX_SIZES_NO 32
2478
2479static const u_int m8xx_size_to_gray[M8XX_SIZES_NO] =
2480{ 0x00000001, 0x00000002, 0x00000008, 0x00000004,
2481 0x00000080, 0x00000040, 0x00000010, 0x00000020,
2482 0x00008000, 0x00004000, 0x00001000, 0x00002000,
2483 0x00000100, 0x00000200, 0x00000800, 0x00000400,
2484
2485 0x0fffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2486 0x01000000, 0x02000000, 0xffffffff, 0x04000000,
2487 0x00010000, 0x00020000, 0x00080000, 0x00040000,
2488 0x00800000, 0x00400000, 0x00100000, 0x00200000 };
2489
2490
wdenk1f53a412002-12-04 23:39:58 +00002491/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00002492
wdenkdb01a2e2004-04-15 23:14:49 +00002493#if ( ! defined(CONFIG_I82365) && ! defined(CONFIG_PXA_PCMCIA) )
wdenk7f70e852003-05-20 14:25:27 +00002494
wdenkc6097192002-11-03 00:24:07 +00002495static u_int m8xx_get_graycode(u_int size)
2496{
2497 u_int k;
2498
2499 for (k = 0; k < M8XX_SIZES_NO; k++) {
2500 if(m8xx_size_to_gray[k] == size)
2501 break;
2502 }
2503
2504 if((k == M8XX_SIZES_NO) || (m8xx_size_to_gray[k] == -1))
2505 k = -1;
2506
2507 return k;
2508}
2509
wdenk7f70e852003-05-20 14:25:27 +00002510#endif /* CONFIG_I82365 */
2511
wdenk1f53a412002-12-04 23:39:58 +00002512/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00002513
2514#if 0
2515static u_int m8xx_get_speed(u_int ns, u_int is_io)
2516{
2517 u_int reg, clocks, psst, psl, psht;
2518
2519 if(!ns) {
2520
2521 /*
2522 * We get called with IO maps setup to 0ns
2523 * if not specified by the user.
2524 * They should be 255ns.
2525 */
2526
2527 if(is_io)
2528 ns = 255;
2529 else
2530 ns = 100; /* fast memory if 0 */
2531 }
2532
2533 /*
2534 * In PSST, PSL, PSHT fields we tell the controller
2535 * timing parameters in CLKOUT clock cycles.
2536 * CLKOUT is the same as GCLK2_50.
2537 */
2538
2539/* how we want to adjust the timing - in percent */
2540
2541#define ADJ 180 /* 80 % longer accesstime - to be sure */
2542
2543 clocks = ((M8XX_BUSFREQ / 1000) * ns) / 1000;
2544 clocks = (clocks * ADJ) / (100*1000);
2545
2546 if(clocks >= PCMCIA_BMT_LIMIT) {
2547 DEBUG(0, "Max access time limit reached\n");
2548 clocks = PCMCIA_BMT_LIMIT-1;
2549 }
2550
2551 psst = clocks / 7; /* setup time */
2552 psht = clocks / 7; /* hold time */
2553 psl = (clocks * 5) / 7; /* strobe length */
2554
2555 psst += clocks - (psst + psht + psl);
2556
2557 reg = psst << 12;
2558 reg |= psl << 7;
2559 reg |= psht << 16;
2560
2561 return reg;
2562}
2563#endif
2564
wdenk1f53a412002-12-04 23:39:58 +00002565/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00002566
wdenkdb01a2e2004-04-15 23:14:49 +00002567#if defined(CONFIG_IDE_8xx_PCCARD) || defined(CONFIG_PXA_PCMCIA)
wdenkc6097192002-11-03 00:24:07 +00002568static void print_funcid (int func)
2569{
2570 puts (indent);
2571 switch (func) {
2572 case CISTPL_FUNCID_MULTI:
2573 puts (" Multi-Function");
2574 break;
2575 case CISTPL_FUNCID_MEMORY:
2576 puts (" Memory");
2577 break;
2578 case CISTPL_FUNCID_SERIAL:
2579 puts (" Serial Port");
2580 break;
2581 case CISTPL_FUNCID_PARALLEL:
2582 puts (" Parallel Port");
2583 break;
2584 case CISTPL_FUNCID_FIXED:
2585 puts (" Fixed Disk");
2586 break;
2587 case CISTPL_FUNCID_VIDEO:
2588 puts (" Video Adapter");
2589 break;
2590 case CISTPL_FUNCID_NETWORK:
2591 puts (" Network Adapter");
2592 break;
2593 case CISTPL_FUNCID_AIMS:
2594 puts (" AIMS Card");
2595 break;
2596 case CISTPL_FUNCID_SCSI:
2597 puts (" SCSI Adapter");
2598 break;
2599 default:
2600 puts (" Unknown");
2601 break;
2602 }
2603 puts (" Card\n");
2604}
2605#endif /* CONFIG_IDE_8xx_PCCARD */
2606
wdenk1f53a412002-12-04 23:39:58 +00002607/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00002608
wdenkdb01a2e2004-04-15 23:14:49 +00002609#if defined(CONFIG_IDE_8xx_PCCARD) || defined(CONFIG_PXA_PCMCIA)
wdenkc6097192002-11-03 00:24:07 +00002610static void print_fixed (volatile uchar *p)
2611{
2612 if (p == NULL)
2613 return;
2614
2615 puts(indent);
2616
2617 switch (*p) {
2618 case CISTPL_FUNCE_IDE_IFACE:
2619 { uchar iface = *(p+2);
2620
2621 puts ((iface == CISTPL_IDE_INTERFACE) ? " IDE" : " unknown");
2622 puts (" interface ");
2623 break;
2624 }
2625 case CISTPL_FUNCE_IDE_MASTER:
2626 case CISTPL_FUNCE_IDE_SLAVE:
2627 { uchar f1 = *(p+2);
2628 uchar f2 = *(p+4);
2629
2630 puts ((f1 & CISTPL_IDE_SILICON) ? " [silicon]" : " [rotating]");
2631
2632 if (f1 & CISTPL_IDE_UNIQUE)
2633 puts (" [unique]");
2634
2635 puts ((f1 & CISTPL_IDE_DUAL) ? " [dual]" : " [single]");
2636
2637 if (f2 & CISTPL_IDE_HAS_SLEEP)
2638 puts (" [sleep]");
2639
2640 if (f2 & CISTPL_IDE_HAS_STANDBY)
2641 puts (" [standby]");
2642
2643 if (f2 & CISTPL_IDE_HAS_IDLE)
2644 puts (" [idle]");
2645
2646 if (f2 & CISTPL_IDE_LOW_POWER)
2647 puts (" [low power]");
2648
2649 if (f2 & CISTPL_IDE_REG_INHIBIT)
2650 puts (" [reg inhibit]");
2651
2652 if (f2 & CISTPL_IDE_HAS_INDEX)
2653 puts (" [index]");
2654
2655 if (f2 & CISTPL_IDE_IOIS16)
2656 puts (" [IOis16]");
2657
2658 break;
2659 }
2660 }
2661 putc ('\n');
2662}
2663#endif /* CONFIG_IDE_8xx_PCCARD */
2664
wdenk1f53a412002-12-04 23:39:58 +00002665/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00002666
wdenkdb01a2e2004-04-15 23:14:49 +00002667#if defined(CONFIG_IDE_8xx_PCCARD) || defined(CONFIG_PXA_PCMCIA)
wdenkc6097192002-11-03 00:24:07 +00002668
2669#define MAX_IDENT_CHARS 64
2670#define MAX_IDENT_FIELDS 4
2671
2672static uchar *known_cards[] = {
2673 "ARGOSY PnPIDE D5",
2674 NULL
2675};
2676
2677static int identify (volatile uchar *p)
2678{
2679 uchar id_str[MAX_IDENT_CHARS];
2680 uchar data;
2681 uchar *t;
2682 uchar **card;
2683 int i, done;
2684
2685 if (p == NULL)
2686 return (0); /* Don't know */
2687
2688 t = id_str;
2689 done =0;
2690
2691 for (i=0; i<=4 && !done; ++i, p+=2) {
2692 while ((data = *p) != '\0') {
2693 if (data == 0xFF) {
2694 done = 1;
2695 break;
2696 }
2697 *t++ = data;
2698 if (t == &id_str[MAX_IDENT_CHARS-1]) {
2699 done = 1;
2700 break;
2701 }
2702 p += 2;
2703 }
2704 if (!done)
2705 *t++ = ' ';
2706 }
2707 *t = '\0';
2708 while (--t > id_str) {
2709 if (*t == ' ')
2710 *t = '\0';
2711 else
2712 break;
2713 }
2714 puts (id_str);
2715 putc ('\n');
2716
2717 for (card=known_cards; *card; ++card) {
2718 debug ("## Compare against \"%s\"\n", *card);
2719 if (strcmp(*card, id_str) == 0) { /* found! */
2720 debug ("## CARD FOUND ##\n");
2721 return (1);
2722 }
2723 }
2724
2725 return (0); /* don't know */
2726}
2727#endif /* CONFIG_IDE_8xx_PCCARD */
2728
wdenk1f53a412002-12-04 23:39:58 +00002729/* -------------------------------------------------------------------- */
wdenk04a85b32004-04-15 18:22:41 +00002730/* NETTA board by Intracom S.A. */
2731/* -------------------------------------------------------------------- */
2732
2733#if defined(CONFIG_NETTA)
2734
2735/* some sane bit macros */
2736#define _BD(_b) (1U << (31-(_b)))
2737#define _BDR(_l, _h) (((((1U << (31-(_l))) - 1) << 1) | 1) & ~((1U << (31-(_h))) - 1))
2738
2739#define _BW(_b) (1U << (15-(_b)))
2740#define _BWR(_l, _h) (((((1U << (15-(_l))) - 1) << 1) | 1) & ~((1U << (15-(_h))) - 1))
2741
2742#define _BB(_b) (1U << (7-(_b)))
2743#define _BBR(_l, _h) (((((1U << (7-(_l))) - 1) << 1) | 1) & ~((1U << (7-(_h))) - 1))
2744
2745#define _B(_b) _BD(_b)
2746#define _BR(_l, _h) _BDR(_l, _h)
2747
2748#define PCMCIA_BOARD_MSG "NETTA"
2749
2750static const unsigned short vppd_masks[2] = { _BW(14), _BW(15) };
2751
2752static void cfg_vppd(int no)
2753{
2754 volatile immap_t *immap = (immap_t *)CFG_IMMR;
2755 unsigned short mask;
2756
2757 if ((unsigned int)no >= sizeof(vppd_masks)/sizeof(vppd_masks[0]))
2758 return;
2759
2760 mask = vppd_masks[no];
2761
2762 immap->im_ioport.iop_papar &= ~mask;
2763 immap->im_ioport.iop_paodr &= ~mask;
2764 immap->im_ioport.iop_padir |= mask;
2765}
2766
2767static void set_vppd(int no, int what)
2768{
2769 volatile immap_t *immap = (immap_t *)CFG_IMMR;
2770 unsigned short mask;
2771
2772 if ((unsigned int)no >= sizeof(vppd_masks)/sizeof(vppd_masks[0]))
2773 return;
2774
2775 mask = vppd_masks[no];
2776
2777 if (what)
2778 immap->im_ioport.iop_padat |= mask;
2779 else
2780 immap->im_ioport.iop_padat &= ~mask;
2781}
2782
2783static const unsigned short vccd_masks[2] = { _BW(10), _BW(6) };
2784
2785static void cfg_vccd(int no)
2786{
2787 volatile immap_t *immap = (immap_t *)CFG_IMMR;
2788 unsigned short mask;
2789
2790 if ((unsigned int)no >= sizeof(vccd_masks)/sizeof(vccd_masks[0]))
2791 return;
2792
2793 mask = vccd_masks[no];
2794
2795 immap->im_ioport.iop_papar &= ~mask;
2796 immap->im_ioport.iop_paodr &= ~mask;
2797 immap->im_ioport.iop_padir |= mask;
2798}
2799
2800static void set_vccd(int no, int what)
2801{
2802 volatile immap_t *immap = (immap_t *)CFG_IMMR;
2803 unsigned short mask;
2804
2805 if ((unsigned int)no >= sizeof(vccd_masks)/sizeof(vccd_masks[0]))
2806 return;
2807
2808 mask = vccd_masks[no];
2809
2810 if (what)
2811 immap->im_ioport.iop_padat |= mask;
2812 else
2813 immap->im_ioport.iop_padat &= ~mask;
2814}
2815
2816static const unsigned short oc_mask = _BW(8);
2817
2818static void cfg_oc(void)
2819{
2820 volatile immap_t *immap = (immap_t *)CFG_IMMR;
2821 unsigned short mask = oc_mask;
2822
2823 immap->im_ioport.iop_pcdir &= ~mask;
2824 immap->im_ioport.iop_pcso &= ~mask;
2825 immap->im_ioport.iop_pcint &= ~mask;
2826 immap->im_ioport.iop_pcpar &= ~mask;
2827}
2828
2829static int get_oc(void)
2830{
2831 volatile immap_t *immap = (immap_t *)CFG_IMMR;
2832 unsigned short mask = oc_mask;
2833 int what;
2834
2835 what = !!(immap->im_ioport.iop_pcdat & mask);;
2836 return what;
2837}
2838
2839static const unsigned short shdn_mask = _BW(12);
2840
2841static void cfg_shdn(void)
2842{
2843 volatile immap_t *immap = (immap_t *)CFG_IMMR;
2844 unsigned short mask;
2845
2846 mask = shdn_mask;
2847
2848 immap->im_ioport.iop_papar &= ~mask;
2849 immap->im_ioport.iop_paodr &= ~mask;
2850 immap->im_ioport.iop_padir |= mask;
2851}
2852
2853static void set_shdn(int what)
2854{
2855 volatile immap_t *immap = (immap_t *)CFG_IMMR;
2856 unsigned short mask;
2857
2858 mask = shdn_mask;
2859
2860 if (what)
2861 immap->im_ioport.iop_padat |= mask;
2862 else
2863 immap->im_ioport.iop_padat &= ~mask;
2864}
2865
2866static void cfg_ports (void);
2867
2868static int hardware_enable(int slot)
2869{
2870 volatile immap_t *immap;
2871 volatile cpm8xx_t *cp;
2872 volatile pcmconf8xx_t *pcmp;
2873 volatile sysconf8xx_t *sysp;
2874 uint reg, pipr, mask;
2875 int i;
2876
2877 debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
2878
2879 udelay(10000);
2880
2881 immap = (immap_t *)CFG_IMMR;
2882 sysp = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
2883 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
2884 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
2885
2886 /* Configure Ports for TPS2211A PC-Card Power-Interface Switch */
2887 cfg_ports ();
2888
2889 /* clear interrupt state, and disable interrupts */
2890 pcmp->pcmc_pscr = PCMCIA_MASK(_slot_);
2891 pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
2892
2893 /*
2894 * Disable interrupts, DMA, and PCMCIA buffers
2895 * (isolate the interface) and assert RESET signal
2896 */
2897 debug ("Disable PCMCIA buffers and assert RESET\n");
2898 reg = 0;
2899 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
2900 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
2901 PCMCIA_PGCRX(_slot_) = reg;
2902
2903 udelay(500);
2904
2905 /*
2906 * Make sure there is a card in the slot, then configure the interface.
2907 */
2908 udelay(10000);
2909 debug ("[%d] %s: PIPR(%p)=0x%x\n",
2910 __LINE__,__FUNCTION__,
2911 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
2912 if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
2913 printf (" No Card found\n");
2914 return (1);
2915 }
2916
2917 /*
2918 * Power On: Set VAVCC to 3.3V or 5V, set VAVPP to Hi-Z
2919 */
2920 mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
2921 pipr = pcmp->pcmc_pipr;
2922 debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
2923 pipr,
2924 (reg&PCMCIA_VS1(slot))?"n":"ff",
2925 (reg&PCMCIA_VS2(slot))?"n":"ff");
2926
2927 if ((pipr & mask) == mask) {
2928 set_vppd(0, 1); set_vppd(1, 1); /* VAVPP => Hi-Z */
2929 set_vccd(0, 0); set_vccd(1, 1); /* 5V on, 3V off */
2930 puts (" 5.0V card found: ");
2931 } else {
2932 set_vppd(0, 1); set_vppd(1, 1); /* VAVPP => Hi-Z */
2933 set_vccd(0, 1); set_vccd(1, 0); /* 5V off, 3V on */
2934 puts (" 3.3V card found: ");
2935 }
2936
2937 /* Wait 500 ms; use this to check for over-current */
2938 for (i=0; i<5000; ++i) {
2939 if (!get_oc()) {
2940 printf (" *** Overcurrent - Safety shutdown ***\n");
2941 set_vccd(0, 0); set_vccd(1, 0); /* VAVPP => Hi-Z */
2942 return (1);
2943 }
2944 udelay (100);
2945 }
2946
2947 debug ("Enable PCMCIA buffers and stop RESET\n");
2948 reg = PCMCIA_PGCRX(_slot_);
2949 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
2950 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
2951 PCMCIA_PGCRX(_slot_) = reg;
2952
2953 udelay(250000); /* some cards need >150 ms to come up :-( */
2954
2955 debug ("# hardware_enable done\n");
2956
2957 return (0);
2958}
2959
2960
2961#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
2962static int hardware_disable(int slot)
2963{
2964 volatile immap_t *immap;
2965 volatile pcmconf8xx_t *pcmp;
2966 u_long reg;
2967
2968 debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
2969
2970 immap = (immap_t *)CFG_IMMR;
2971 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
2972
2973 /* Configure PCMCIA General Control Register */
2974 debug ("Disable PCMCIA buffers and assert RESET\n");
2975 reg = 0;
2976 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
2977 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
2978 PCMCIA_PGCRX(_slot_) = reg;
2979
2980 /* All voltages off / Hi-Z */
2981 set_vppd(0, 1); set_vppd(1, 1);
2982 set_vccd(0, 1); set_vccd(1, 1);
2983
2984 udelay(10000);
2985
2986 return (0);
2987}
2988#endif /* CFG_CMD_PCMCIA */
2989
2990
2991static int voltage_set(int slot, int vcc, int vpp)
2992{
2993 volatile immap_t *immap;
2994 volatile cpm8xx_t *cp;
2995 volatile pcmconf8xx_t *pcmp;
2996 u_long reg;
2997 ushort sreg;
2998
2999 debug ("voltage_set: "
3000 PCMCIA_BOARD_MSG
3001 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
3002 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
3003
3004 immap = (immap_t *)CFG_IMMR;
3005 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
3006 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
3007 /*
3008 * Disable PCMCIA buffers (isolate the interface)
3009 * and assert RESET signal
3010 */
3011 debug ("Disable PCMCIA buffers and assert RESET\n");
3012 reg = PCMCIA_PGCRX(_slot_);
3013 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
3014 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
3015 PCMCIA_PGCRX(_slot_) = reg;
3016 udelay(500);
3017
3018 /*
3019 * Configure Port C pins for
3020 * 5 Volts Enable and 3 Volts enable,
3021 * Turn all power pins to Hi-Z
3022 */
3023 debug ("PCMCIA power OFF\n");
3024 cfg_ports (); /* Enables switch, but all in Hi-Z */
3025
3026 sreg = immap->im_ioport.iop_pcdat;
3027 set_vppd(0, 1); set_vppd(1, 1);
3028
3029 switch(vcc) {
3030 case 0:
3031 break; /* Switch off */
3032
3033 case 33:
3034 set_vccd(0, 1); set_vccd(1, 0);
3035 break;
3036
3037 case 50:
3038 set_vccd(0, 0); set_vccd(1, 1);
3039 break;
3040
3041 default:
3042 goto done;
3043 }
3044
3045 /* Checking supported voltages */
3046
3047 debug ("PIPR: 0x%x --> %s\n",
3048 pcmp->pcmc_pipr,
3049 (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
3050
3051done:
3052 debug ("Enable PCMCIA buffers and stop RESET\n");
3053 reg = PCMCIA_PGCRX(_slot_);
3054 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
3055 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
3056 PCMCIA_PGCRX(_slot_) = reg;
3057 udelay(500);
3058
3059 debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
3060 slot+'A');
3061 return (0);
3062}
3063
3064static void cfg_ports (void)
3065{
3066 volatile immap_t *immap;
3067 volatile cpm8xx_t *cp;
3068
3069 immap = (immap_t *)CFG_IMMR;
3070 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
3071
3072
3073 cfg_vppd(0); cfg_vppd(1); /* VPPD0,VPPD1 VAVPP => Hi-Z */
3074 cfg_vccd(0); cfg_vccd(1); /* 3V and 5V off */
3075 cfg_shdn();
3076 cfg_oc();
3077
3078 /*
3079 * Configure Port A for TPS2211 PC-Card Power-Interface Switch
3080 *
3081 * Switch off all voltages, assert shutdown
3082 */
3083 set_vppd(0, 1); set_vppd(1, 1);
3084 set_vccd(0, 0); set_vccd(1, 0);
3085 set_shdn(1);
3086
3087 udelay(100000);
3088}
3089
3090#endif /* NETTA */
3091
3092
3093/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00003094
3095#endif /* CFG_CMD_PCMCIA || (CFG_CMD_IDE && CONFIG_IDE_8xx_PCCARD) */
wdenk8bde7f72003-06-27 21:31:46 +00003096
3097/**************************************************/
3098
3099#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
wdenk0d498392003-07-01 21:06:45 +00003100U_BOOT_CMD(
3101 pinit, 2, 1, do_pinit,
wdenk8bde7f72003-06-27 21:31:46 +00003102 "pinit - PCMCIA sub-system\n",
3103 "on - power on PCMCIA socket\n"
3104 "pinit off - power off PCMCIA socket\n"
3105);
3106#endif