blob: 7a2ca9e456b1cc3546ff10f459ff45510a654b0f [file] [log] [blame]
wdenkc6097192002-11-03 00:24:07 +00001/*
2 * (C) Copyright 2000-2002
3 * 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>
wdenk444f22b2003-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
wdenk634d2f72004-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);
wdenke5d61c72003-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
wdenk634d2f72004-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);
wdenk0893c472003-05-20 14:25:27 +000094#endif /* CONFIG_I82365 */
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
wdenk90e7e422002-12-04 23:39:58 +000099/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +0000100
wdenk634d2f72004-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};
109
110#define PCMCIA_PGCRX(slot) (*pcmcia_pgcrx[slot])
111
wdenke5d61c72003-05-18 11:30:09 +0000112#endif /* CONFIG_I82365 */
113
wdenk634d2f72004-04-15 23:14:49 +0000114#if defined(CONFIG_IDE_8xx_PCCARD) || defined(CONFIG_PXA_PCMCIA)
wdenke5d61c72003-05-18 11:30:09 +0000115static void print_funcid (int func);
116static void print_fixed (volatile uchar *p);
117static int identify (volatile uchar *p);
118static int check_ide_device (int slot);
119#endif /* CONFIG_IDE_8xx_PCCARD */
120
wdenk634d2f72004-04-15 23:14:49 +0000121#endif
122
wdenkc6097192002-11-03 00:24:07 +0000123const char *indent = "\t ";
124
wdenk90e7e422002-12-04 23:39:58 +0000125/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +0000126
127#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
128
129int do_pinit (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
130{
131 int rcode = 0;
132
133 if (argc != 2) {
134 printf ("Usage: pinit {on | off}\n");
135 return 1;
136 }
137 if (strcmp(argv[1],"on") == 0) {
138 rcode = pcmcia_on ();
139 } else if (strcmp(argv[1],"off") == 0) {
140 rcode = pcmcia_off ();
141 } else {
142 printf ("Usage: pinit {on | off}\n");
143 return 1;
144 }
145
146 return rcode;
147}
148#endif /* CFG_CMD_PCMCIA */
149
wdenk90e7e422002-12-04 23:39:58 +0000150/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +0000151
wdenke5d61c72003-05-18 11:30:09 +0000152#ifdef CONFIG_I82365
153int pcmcia_on (void)
154{
155 u_int rc;
156
157 debug ("Enable PCMCIA " PCMCIA_SLOT_MSG "\n");
158
159 rc = i82365_init();
160
wdenk634d2f72004-04-15 23:14:49 +0000161 if (rc == 0) {
wdenke5d61c72003-05-18 11:30:09 +0000162 rc = check_ide_device(0);
163 }
164
165 return (rc);
166}
167#else
168
wdenk634d2f72004-04-15 23:14:49 +0000169#ifndef CONFIG_PXA_PCMCIA
170
wdenkf602aa02004-03-13 23:29:43 +0000171#ifdef CONFIG_HMI10
172# define HMI10_FRAM_TIMING (PCMCIA_SHT(2) | PCMCIA_SST(2) | PCMCIA_SL(4))
wdenk4b6e9052004-02-06 21:48:22 +0000173#endif
dzub02ed682003-10-19 21:43:26 +0000174#if defined(CONFIG_LWMON) || defined(CONFIG_NSCU)
wdenkc6097192002-11-03 00:24:07 +0000175# define CFG_PCMCIA_TIMING (PCMCIA_SHT(9) | PCMCIA_SST(3) | PCMCIA_SL(12))
176#else
177# define CFG_PCMCIA_TIMING (PCMCIA_SHT(2) | PCMCIA_SST(4) | PCMCIA_SL(9))
178#endif
179
180int pcmcia_on (void)
181{
182 int i;
183 u_long reg, base;
184 pcmcia_win_t *win;
wdenk2029f4d2002-11-21 23:11:29 +0000185 u_int slotbit;
186 u_int rc, slot;
wdenkc6097192002-11-03 00:24:07 +0000187
188 debug ("Enable PCMCIA " PCMCIA_SLOT_MSG "\n");
189
190 /* intialize the fixed memory windows */
191 win = (pcmcia_win_t *)(&((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_pbr0);
192 base = CFG_PCMCIA_MEM_ADDR;
193
194 if((reg = m8xx_get_graycode(CFG_PCMCIA_MEM_SIZE)) == -1) {
195 printf ("Cannot set window size to 0x%08x\n",
196 CFG_PCMCIA_MEM_SIZE);
197 return (1);
198 }
199
wdenk2029f4d2002-11-21 23:11:29 +0000200 slotbit = PCMCIA_SLOT_x;
wdenkc6097192002-11-03 00:24:07 +0000201 for (i=0; i<PCMCIA_MEM_WIN_NO; ++i) {
202 win->br = base;
203
wdenk2029f4d2002-11-21 23:11:29 +0000204#if (PCMCIA_SOCKETS_NO == 2)
205 if (i == 4) /* Another slot starting from win 4 */
206 slotbit = (slotbit ? PCMCIA_PSLOT_A : PCMCIA_PSLOT_B);
207#endif
wdenkc6097192002-11-03 00:24:07 +0000208 switch (i) {
209#ifdef CONFIG_IDE_8xx_PCCARD
wdenk2029f4d2002-11-21 23:11:29 +0000210 case 4:
wdenkf602aa02004-03-13 23:29:43 +0000211#ifdef CONFIG_HMI10
wdenk4b6e9052004-02-06 21:48:22 +0000212 { /* map FRAM area */
213 win->or = ( PCMCIA_BSIZE_256K
214 | PCMCIA_PPS_8
215 | PCMCIA_PRS_ATTR
216 | slotbit
217 | PCMCIA_PV
wdenkf602aa02004-03-13 23:29:43 +0000218 | HMI10_FRAM_TIMING );
wdenk4b6e9052004-02-06 21:48:22 +0000219 break;
220 }
221#endif
wdenkc6097192002-11-03 00:24:07 +0000222 case 0: { /* map attribute memory */
223 win->or = ( PCMCIA_BSIZE_64M
224 | PCMCIA_PPS_8
225 | PCMCIA_PRS_ATTR
wdenk2029f4d2002-11-21 23:11:29 +0000226 | slotbit
wdenkc6097192002-11-03 00:24:07 +0000227 | PCMCIA_PV
228 | CFG_PCMCIA_TIMING );
229 break;
230 }
wdenk2029f4d2002-11-21 23:11:29 +0000231 case 5:
wdenkc6097192002-11-03 00:24:07 +0000232 case 1: { /* map I/O window for data reg */
233 win->or = ( PCMCIA_BSIZE_1K
234 | PCMCIA_PPS_16
235 | PCMCIA_PRS_IO
wdenk2029f4d2002-11-21 23:11:29 +0000236 | slotbit
wdenkc6097192002-11-03 00:24:07 +0000237 | PCMCIA_PV
238 | CFG_PCMCIA_TIMING );
239 break;
240 }
wdenk2029f4d2002-11-21 23:11:29 +0000241 case 6:
wdenk90e7e422002-12-04 23:39:58 +0000242 case 2: { /* map I/O window for cmd/ctrl reg block */
wdenkc6097192002-11-03 00:24:07 +0000243 win->or = ( PCMCIA_BSIZE_1K
244 | PCMCIA_PPS_8
245 | PCMCIA_PRS_IO
wdenk2029f4d2002-11-21 23:11:29 +0000246 | slotbit
wdenkc6097192002-11-03 00:24:07 +0000247 | PCMCIA_PV
248 | CFG_PCMCIA_TIMING );
249 break;
250 }
251#endif /* CONFIG_IDE_8xx_PCCARD */
wdenkf602aa02004-03-13 23:29:43 +0000252#ifdef CONFIG_HMI10
wdenk67f13362003-12-27 19:24:54 +0000253 case 3: { /* map I/O window for 4xUART data/ctrl */
wdenk2f99a692004-01-04 22:51:12 +0000254 win->br += 0x40000;
wdenk67f13362003-12-27 19:24:54 +0000255 win->or = ( PCMCIA_BSIZE_256K
256 | PCMCIA_PPS_8
257 | PCMCIA_PRS_IO
258 | slotbit
259 | PCMCIA_PV
260 | CFG_PCMCIA_TIMING );
261 break;
262 }
wdenkf602aa02004-03-13 23:29:43 +0000263#endif /* CONFIG_HMI10 */
wdenkc6097192002-11-03 00:24:07 +0000264 default: /* set to not valid */
265 win->or = 0;
266 break;
267 }
268
269 debug ("MemWin %d: PBR 0x%08lX POR %08lX\n",
270 i, win->br, win->or);
271 base += CFG_PCMCIA_MEM_SIZE;
272 ++win;
273 }
274
wdenk90e7e422002-12-04 23:39:58 +0000275 for (i=0, rc=0, slot=_slot_; i<PCMCIA_SOCKETS_NO; i++, slot = !slot) {
wdenk2029f4d2002-11-21 23:11:29 +0000276 /* turn off voltage */
277 if ((rc = voltage_set(slot, 0, 0)))
278 continue;
wdenk90e7e422002-12-04 23:39:58 +0000279
wdenk2029f4d2002-11-21 23:11:29 +0000280 /* Enable external hardware */
281 if ((rc = hardware_enable(slot)))
282 continue;
wdenk90e7e422002-12-04 23:39:58 +0000283
wdenkc6097192002-11-03 00:24:07 +0000284#ifdef CONFIG_IDE_8xx_PCCARD
wdenk2029f4d2002-11-21 23:11:29 +0000285 if ((rc = check_ide_device(i)))
286 continue;
wdenkc6097192002-11-03 00:24:07 +0000287#endif
wdenk2029f4d2002-11-21 23:11:29 +0000288 }
289 return (rc);
wdenkc6097192002-11-03 00:24:07 +0000290}
wdenk634d2f72004-04-15 23:14:49 +0000291
wdenk6203e402004-04-18 10:13:26 +0000292#endif /* CONFIG_PXA_PCMCIA */
wdenk634d2f72004-04-15 23:14:49 +0000293
wdenke5d61c72003-05-18 11:30:09 +0000294#endif /* CONFIG_I82365 */
wdenkc6097192002-11-03 00:24:07 +0000295
wdenk634d2f72004-04-15 23:14:49 +0000296#ifdef CONFIG_PXA_PCMCIA
297
298static int hardware_enable (int slot)
299{
300 return 0; /* No hardware to enable */
301}
302
303static int hardware_disable(int slot)
304{
305 return 0; /* No hardware to disable */
306}
307
308static int voltage_set(int slot, int vcc, int vpp)
309{
310 return 0;
311}
312
313void msWait(unsigned msVal)
314{
315 udelay(msVal*1000);
316}
317
318int pcmcia_on (void)
319{
320 unsigned int reg_arr[] = {
321 0x48000028, CFG_MCMEM0_VAL,
322 0x4800002c, CFG_MCMEM1_VAL,
323 0x48000030, CFG_MCATT0_VAL,
324 0x48000034, CFG_MCATT1_VAL,
325 0x48000038, CFG_MCIO0_VAL,
326 0x4800003c, CFG_MCIO1_VAL,
327
328 0, 0
329 };
330 int i, rc;
331
332#ifdef CONFIG_EXADRON1
333 int cardDetect;
334 volatile unsigned int *v_pBCRReg =
335 (volatile unsigned int *) 0x08000000;
336#endif
337
338 debug ("%s\n", __FUNCTION__);
339
340 i = 0;
341 while (reg_arr[i])
342 *((volatile unsigned int *) reg_arr[i++]) |= reg_arr[i++];
343 udelay (1000);
344
345 debug ("%s: programmed mem controller \n", __FUNCTION__);
346
347#ifdef CONFIG_EXADRON1
348
349/*define useful BCR masks */
350#define BCR_CF_INIT_VAL 0x00007230
351#define BCR_CF_PWRON_BUSOFF_RESETOFF_VAL 0x00007231
352#define BCR_CF_PWRON_BUSOFF_RESETON_VAL 0x00007233
353#define BCR_CF_PWRON_BUSON_RESETON_VAL 0x00007213
354#define BCR_CF_PWRON_BUSON_RESETOFF_VAL 0x00007211
355
356 /* we see from the GPIO bit if the card is present */
357 cardDetect = !(GPLR0 & GPIO_bit (14));
358
359 if (cardDetect) {
360 printf ("No PCMCIA card found!\n");
361 }
362
363 /* reset the card via the BCR line */
364 *v_pBCRReg = (unsigned) BCR_CF_INIT_VAL;
365 msWait (500);
366
367 *v_pBCRReg = (unsigned) BCR_CF_PWRON_BUSOFF_RESETOFF_VAL;
368 msWait (500);
369
370 *v_pBCRReg = (unsigned) BCR_CF_PWRON_BUSOFF_RESETON_VAL;
371 msWait (500);
372
373 *v_pBCRReg = (unsigned) BCR_CF_PWRON_BUSON_RESETON_VAL;
374 msWait (500);
375
376 *v_pBCRReg = (unsigned) BCR_CF_PWRON_BUSON_RESETOFF_VAL;
377 msWait (1500);
378
379 /* enable address bus */
380 GPCR1 = 0x01;
381 /* and the first CF slot */
382 MECR = 0x00000002;
383
384#endif /* EXADRON 1 */
385
386 rc = check_ide_device (0); /* use just slot 0 */
387
388 return rc;
389}
390
391#endif /* CONFIG_PXA_PCMCIA */
392
wdenk90e7e422002-12-04 23:39:58 +0000393/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +0000394
395#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
396
wdenke5d61c72003-05-18 11:30:09 +0000397#ifdef CONFIG_I82365
398static int pcmcia_off (void)
399{
400 printf ("Disable PCMCIA " PCMCIA_SLOT_MSG "\n");
401
402 i82365_exit();
403
404 return 0;
405}
406#else
wdenk634d2f72004-04-15 23:14:49 +0000407
408#ifndef CONFIG_PXA_PCMCIA
409
wdenkc6097192002-11-03 00:24:07 +0000410static int pcmcia_off (void)
411{
412 int i;
413 pcmcia_win_t *win;
414
415 printf ("Disable PCMCIA " PCMCIA_SLOT_MSG "\n");
416
417 /* clear interrupt state, and disable interrupts */
418 ((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_pscr = PCMCIA_MASK(_slot_);
419 ((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_per &= ~PCMCIA_MASK(_slot_);
420
421 /* turn off interrupt and disable CxOE */
422 PCMCIA_PGCRX(_slot_) = __MY_PCMCIA_GCRX_CXOE;
423
424 /* turn off memory windows */
425 win = (pcmcia_win_t *)(&((immap_t *)CFG_IMMR)->im_pcmcia.pcmc_pbr0);
426
427 for (i=0; i<PCMCIA_MEM_WIN_NO; ++i) {
428 /* disable memory window */
429 win->or = 0;
430 ++win;
431 }
432
433 /* turn off voltage */
434 voltage_set(_slot_, 0, 0);
435
436 /* disable external hardware */
437 printf ("Shutdown and Poweroff " PCMCIA_SLOT_MSG "\n");
438 hardware_disable(_slot_);
439 return 0;
440}
wdenk634d2f72004-04-15 23:14:49 +0000441
442#endif /* CONFIG_PXA_PCMCIA */
443
wdenke5d61c72003-05-18 11:30:09 +0000444#endif /* CONFIG_I82365 */
wdenkc6097192002-11-03 00:24:07 +0000445
wdenk634d2f72004-04-15 23:14:49 +0000446#ifdef CONFIG_PXA_PCMCIA
447static int pcmcia_off (void)
448{
449 return 0;
450}
451#endif
452
wdenkc6097192002-11-03 00:24:07 +0000453#endif /* CFG_CMD_PCMCIA */
454
wdenk90e7e422002-12-04 23:39:58 +0000455/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +0000456
wdenk634d2f72004-04-15 23:14:49 +0000457#if defined(CONFIG_IDE_8xx_PCCARD) || defined(CONFIG_PXA_PCMCIA)
wdenkc6097192002-11-03 00:24:07 +0000458
459#define MAX_TUPEL_SZ 512
460#define MAX_FEATURES 4
461
wdenk4fc95692003-02-28 00:49:47 +0000462int ide_devices_found;
wdenk2029f4d2002-11-21 23:11:29 +0000463static int check_ide_device (int slot)
wdenkc6097192002-11-03 00:24:07 +0000464{
465 volatile uchar *ident = NULL;
466 volatile uchar *feature_p[MAX_FEATURES];
wdenk2029f4d2002-11-21 23:11:29 +0000467 volatile uchar *p, *start, *addr;
wdenkc6097192002-11-03 00:24:07 +0000468 int n_features = 0;
469 uchar func_id = ~0;
470 uchar code, len;
471 ushort config_base = 0;
472 int found = 0;
473 int i;
474
wdenk90e7e422002-12-04 23:39:58 +0000475 addr = (volatile uchar *)(CFG_PCMCIA_MEM_ADDR +
476 CFG_PCMCIA_MEM_SIZE * (slot * 4));
wdenke7f34c62003-01-11 09:48:40 +0000477 debug ("PCMCIA MEM: %08lX\n", (ulong)addr);
wdenkc6097192002-11-03 00:24:07 +0000478
wdenk2029f4d2002-11-21 23:11:29 +0000479 start = p = (volatile uchar *) addr;
wdenkc6097192002-11-03 00:24:07 +0000480
481 while ((p - start) < MAX_TUPEL_SZ) {
482
483 code = *p; p += 2;
484
485 if (code == 0xFF) { /* End of chain */
486 break;
487 }
488
489 len = *p; p += 2;
490#if defined(DEBUG) && (DEBUG > 1)
491 { volatile uchar *q = p;
492 printf ("\nTuple code %02x length %d\n\tData:",
493 code, len);
494
495 for (i = 0; i < len; ++i) {
496 printf (" %02x", *q);
497 q+= 2;
498 }
499 }
500#endif /* DEBUG */
501 switch (code) {
502 case CISTPL_VERS_1:
503 ident = p + 4;
504 break;
505 case CISTPL_FUNCID:
506 /* Fix for broken SanDisk which may have 0x80 bit set */
507 func_id = *p & 0x7F;
508 break;
509 case CISTPL_FUNCE:
510 if (n_features < MAX_FEATURES)
511 feature_p[n_features++] = p;
512 break;
513 case CISTPL_CONFIG:
514 config_base = (*(p+6) << 8) + (*(p+4));
515 debug ("\n## Config_base = %04x ###\n", config_base);
516 default:
517 break;
518 }
519 p += 2 * len;
520 }
521
522 found = identify (ident);
523
524 if (func_id != ((uchar)~0)) {
525 print_funcid (func_id);
526
527 if (func_id == CISTPL_FUNCID_FIXED)
528 found = 1;
529 else
530 return (1); /* no disk drive */
531 }
532
533 for (i=0; i<n_features; ++i) {
534 print_fixed (feature_p[i]);
535 }
536
537 if (!found) {
538 printf ("unknown card type\n");
539 return (1);
540 }
541
wdenk4fc95692003-02-28 00:49:47 +0000542 ide_devices_found |= (1 << slot);
543
wdenkc6097192002-11-03 00:24:07 +0000544 /* set I/O area in config reg -> only valid for ARGOSY D5!!! */
wdenk2029f4d2002-11-21 23:11:29 +0000545 *((uchar *)(addr + config_base)) = 1;
wdenkc6097192002-11-03 00:24:07 +0000546
547 return (0);
548}
549#endif /* CONFIG_IDE_8xx_PCCARD */
550
wdenk90e7e422002-12-04 23:39:58 +0000551/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +0000552
553
wdenk90e7e422002-12-04 23:39:58 +0000554/* -------------------------------------------------------------------- */
555/* board specific stuff: */
556/* voltage_set(), hardware_enable() and hardware_disable() */
557/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +0000558
wdenk90e7e422002-12-04 23:39:58 +0000559/* -------------------------------------------------------------------- */
560/* RPX Boards from Embedded Planet */
561/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +0000562
563#if defined(CONFIG_RPXCLASSIC) || defined(CONFIG_RPXLITE)
564
565/* The RPX boards seems to have it's bus monitor timeout set to 6*8 clocks.
566 * SYPCR is write once only, therefore must the slowest memory be faster
567 * than the bus monitor or we will get a machine check due to the bus timeout.
568 */
569
570#define PCMCIA_BOARD_MSG "RPX CLASSIC or RPX LITE"
571
572#undef PCMCIA_BMT_LIMIT
573#define PCMCIA_BMT_LIMIT (6*8)
574
575static int voltage_set(int slot, int vcc, int vpp)
576{
577 u_long reg = 0;
578
579 switch(vcc) {
580 case 0: break;
581 case 33: reg |= BCSR1_PCVCTL4; break;
582 case 50: reg |= BCSR1_PCVCTL5; break;
583 default: return 1;
584 }
585
586 switch(vpp) {
587 case 0: break;
588 case 33:
589 case 50:
590 if(vcc == vpp)
591 reg |= BCSR1_PCVCTL6;
592 else
593 return 1;
594 break;
595 case 120:
596 reg |= BCSR1_PCVCTL7;
597 default: return 1;
598 }
599
600 if(vcc == 120)
601 return 1;
602
603 /* first, turn off all power */
604
605 *((uint *)RPX_CSR_ADDR) &= ~(BCSR1_PCVCTL4 | BCSR1_PCVCTL5
606 | BCSR1_PCVCTL6 | BCSR1_PCVCTL7);
607
608 /* enable new powersettings */
609
610 *((uint *)RPX_CSR_ADDR) |= reg;
611
612 return 0;
613}
614
615#define socket_get(_slot_) PCMCIA_SOCKET_KEY_5V
616static int hardware_enable (int slot)
617{
618 return 0; /* No hardware to enable */
619}
620#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
621static int hardware_disable(int slot)
622{
623 return 0; /* No hardware to disable */
624}
625#endif /* CFG_CMD_PCMCIA */
626#endif /* CONFIG_RPXCLASSIC */
627
wdenk90e7e422002-12-04 23:39:58 +0000628/* -------------------------------------------------------------------- */
629/* (F)ADS Boards from Motorola */
630/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +0000631
632#if defined(CONFIG_ADS) || defined(CONFIG_FADS)
633
634#ifdef CONFIG_ADS
635#define PCMCIA_BOARD_MSG "ADS"
636#define PCMCIA_GLITCHY_CD /* My ADS board needs this */
637#else
638#define PCMCIA_BOARD_MSG "FADS"
639#endif
640
641static int voltage_set(int slot, int vcc, int vpp)
642{
643 u_long reg = 0;
644
645 switch(vpp) {
646 case 0: reg = 0; break;
647 case 50: reg = 1; break;
648 case 120: reg = 2; break;
649 default: return 1;
650 }
651
652 switch(vcc) {
653 case 0: reg = 0; break;
654#ifdef CONFIG_ADS
655 case 50: reg = BCSR1_PCCVCCON; break;
656#endif
657#ifdef CONFIG_FADS
658 case 33: reg = BCSR1_PCCVCC0 | BCSR1_PCCVCC1; break;
659 case 50: reg = BCSR1_PCCVCC1; break;
660#endif
661 default: return 1;
662 }
663
664 /* first, turn off all power */
665
666#ifdef CONFIG_ADS
667 *((uint *)BCSR1) |= BCSR1_PCCVCCON;
668#endif
669#ifdef CONFIG_FADS
670 *((uint *)BCSR1) &= ~(BCSR1_PCCVCC0 | BCSR1_PCCVCC1);
671#endif
672 *((uint *)BCSR1) &= ~BCSR1_PCCVPP_MASK;
673
674 /* enable new powersettings */
675
676#ifdef CONFIG_ADS
677 *((uint *)BCSR1) &= ~reg;
678#endif
679#ifdef CONFIG_FADS
680 *((uint *)BCSR1) |= reg;
681#endif
682
683 *((uint *)BCSR1) |= reg << 20;
684
685 return 0;
686}
687
688#define socket_get(_slot_) PCMCIA_SOCKET_KEY_5V
689
690static int hardware_enable(int slot)
691{
692 *((uint *)BCSR1) &= ~BCSR1_PCCEN;
693 return 0;
694}
695
696#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
697static int hardware_disable(int slot)
698{
699 *((uint *)BCSR1) &= ~BCSR1_PCCEN;
700 return 0;
701}
702#endif /* CFG_CMD_PCMCIA */
703
704#endif /* (F)ADS */
705
wdenk90e7e422002-12-04 23:39:58 +0000706/* -------------------------------------------------------------------- */
707/* TQM8xxL Boards by TQ Components */
wdenkc8434db2003-03-26 06:55:25 +0000708/* SC8xx Boards by SinoVee Microsystems */
wdenk90e7e422002-12-04 23:39:58 +0000709/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +0000710
wdenkc8434db2003-03-26 06:55:25 +0000711#if defined(CONFIG_TQM8xxL) || defined(CONFIG_SVM_SC8xx)
wdenkc6097192002-11-03 00:24:07 +0000712
wdenkc8434db2003-03-26 06:55:25 +0000713#if defined(CONFIG_TQM8xxL)
wdenkc6097192002-11-03 00:24:07 +0000714#define PCMCIA_BOARD_MSG "TQM8xxL"
wdenkc8434db2003-03-26 06:55:25 +0000715#endif
716#if defined(CONFIG_SVM_SC8xx)
717#define PCMCIA_BOARD_MSG "SC8xx"
718#endif
wdenkc6097192002-11-03 00:24:07 +0000719
720static int hardware_enable(int slot)
721{
722 volatile immap_t *immap;
723 volatile cpm8xx_t *cp;
724 volatile pcmconf8xx_t *pcmp;
725 volatile sysconf8xx_t *sysp;
726 uint reg, mask;
727
728 debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
729
730 udelay(10000);
731
732 immap = (immap_t *)CFG_IMMR;
733 sysp = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
734 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
735 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
736
737 /*
738 * Configure SIUMCR to enable PCMCIA port B
739 * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
740 */
741 sysp->sc_siumcr &= ~SIUMCR_DBGC11; /* set DBGC to 00 */
742
743 /* clear interrupt state, and disable interrupts */
dzub02ed682003-10-19 21:43:26 +0000744 pcmp->pcmc_pscr = PCMCIA_MASK(slot);
745 pcmp->pcmc_per &= ~PCMCIA_MASK(slot);
wdenkc6097192002-11-03 00:24:07 +0000746
wdenkc6097192002-11-03 00:24:07 +0000747 /*
wdenk90e7e422002-12-04 23:39:58 +0000748 * Disable interrupts, DMA, and PCMCIA buffers
749 * (isolate the interface) and assert RESET signal
wdenkc6097192002-11-03 00:24:07 +0000750 */
751 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk90e7e422002-12-04 23:39:58 +0000752 reg = 0;
753 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
dzub02ed682003-10-19 21:43:26 +0000754#ifndef NSCU_OE_INV
wdenk90e7e422002-12-04 23:39:58 +0000755 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
dzub02ed682003-10-19 21:43:26 +0000756#endif
757 PCMCIA_PGCRX(slot) = reg;
wdenkc6097192002-11-03 00:24:07 +0000758 udelay(500);
759
wdenkf602aa02004-03-13 23:29:43 +0000760#ifndef CONFIG_HMI10
dzub02ed682003-10-19 21:43:26 +0000761#ifndef CONFIG_NSCU
wdenkc6097192002-11-03 00:24:07 +0000762 /*
763 * Configure Port C pins for
764 * 5 Volts Enable and 3 Volts enable
765 */
766 immap->im_ioport.iop_pcpar &= ~(0x0002 | 0x0004);
767 immap->im_ioport.iop_pcso &= ~(0x0002 | 0x0004);
768 /* remove all power */
769
770 immap->im_ioport.iop_pcdat &= ~(0x0002 | 0x0004);
dzub02ed682003-10-19 21:43:26 +0000771#endif
wdenkf602aa02004-03-13 23:29:43 +0000772#else /* CONFIG_HMI10 */
wdenk2f99a692004-01-04 22:51:12 +0000773 /*
774 * Configure Port B pins for
775 * 5 Volts Enable and 3 Volts enable
776 */
777 immap->im_cpm.cp_pbpar &= ~(0x00000300);
778
779 /* remove all power */
780 immap->im_cpm.cp_pbdat |= 0x00000300;
wdenkf602aa02004-03-13 23:29:43 +0000781#endif /* CONFIG_HMI10 */
wdenkc6097192002-11-03 00:24:07 +0000782
783 /*
784 * Make sure there is a card in the slot, then configure the interface.
785 */
786 udelay(10000);
787 debug ("[%d] %s: PIPR(%p)=0x%x\n",
788 __LINE__,__FUNCTION__,
789 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
wdenkf602aa02004-03-13 23:29:43 +0000790#ifndef CONFIG_HMI10
wdenk2029f4d2002-11-21 23:11:29 +0000791 if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
wdenk2f99a692004-01-04 22:51:12 +0000792#else
793 if (pcmp->pcmc_pipr & (0x10000000 >> (slot << 4))) {
wdenkf602aa02004-03-13 23:29:43 +0000794#endif /* CONFIG_HMI10 */
wdenkc6097192002-11-03 00:24:07 +0000795 printf (" No Card found\n");
796 return (1);
797 }
798
799 /*
800 * Power On.
801 */
802 mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
803 reg = pcmp->pcmc_pipr;
804 debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
805 reg,
806 (reg&PCMCIA_VS1(slot))?"n":"ff",
807 (reg&PCMCIA_VS2(slot))?"n":"ff");
dzub02ed682003-10-19 21:43:26 +0000808#ifndef CONFIG_NSCU
wdenkc6097192002-11-03 00:24:07 +0000809 if ((reg & mask) == mask) {
wdenkf602aa02004-03-13 23:29:43 +0000810#ifndef CONFIG_HMI10
wdenkc6097192002-11-03 00:24:07 +0000811 immap->im_ioport.iop_pcdat |= 0x0004;
wdenk2f99a692004-01-04 22:51:12 +0000812#else
813 immap->im_cpm.cp_pbdat &= ~(0x0000100);
wdenkf602aa02004-03-13 23:29:43 +0000814#endif /* CONFIG_HMI10 */
wdenkc6097192002-11-03 00:24:07 +0000815 puts (" 5.0V card found: ");
816 } else {
wdenkf602aa02004-03-13 23:29:43 +0000817#ifndef CONFIG_HMI10
wdenkc6097192002-11-03 00:24:07 +0000818 immap->im_ioport.iop_pcdat |= 0x0002;
wdenk2f99a692004-01-04 22:51:12 +0000819#else
820 immap->im_cpm.cp_pbdat &= ~(0x0000200);
wdenkf602aa02004-03-13 23:29:43 +0000821#endif /* CONFIG_HMI10 */
wdenkc6097192002-11-03 00:24:07 +0000822 puts (" 3.3V card found: ");
823 }
wdenkf602aa02004-03-13 23:29:43 +0000824#ifndef CONFIG_HMI10
wdenk90e7e422002-12-04 23:39:58 +0000825 immap->im_ioport.iop_pcdir |= (0x0002 | 0x0004);
dzub02ed682003-10-19 21:43:26 +0000826#else
wdenk2f99a692004-01-04 22:51:12 +0000827 immap->im_cpm.cp_pbdir |= 0x00000300;
wdenkf602aa02004-03-13 23:29:43 +0000828#endif /* CONFIG_HMI10 */
wdenk2f99a692004-01-04 22:51:12 +0000829#else
dzub02ed682003-10-19 21:43:26 +0000830 if ((reg & mask) == mask) {
831 puts (" 5.0V card found: ");
832 } else {
833 puts (" 3.3V card found: ");
834 }
835#endif
wdenkc6097192002-11-03 00:24:07 +0000836#if 0
837 /* VCC switch error flag, PCMCIA slot INPACK_ pin */
838 cp->cp_pbdir &= ~(0x0020 | 0x0010);
839 cp->cp_pbpar &= ~(0x0020 | 0x0010);
840 udelay(500000);
841#endif
842 udelay(1000);
843 debug ("Enable PCMCIA buffers and stop RESET\n");
dzub02ed682003-10-19 21:43:26 +0000844 reg = PCMCIA_PGCRX(slot);
wdenkc6097192002-11-03 00:24:07 +0000845 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
dzub02ed682003-10-19 21:43:26 +0000846#ifndef NSCU_OE_INV
wdenkc6097192002-11-03 00:24:07 +0000847 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
dzub02ed682003-10-19 21:43:26 +0000848#else
849 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
850#endif
851 PCMCIA_PGCRX(slot) = reg;
wdenkc6097192002-11-03 00:24:07 +0000852
853 udelay(250000); /* some cards need >150 ms to come up :-( */
854
855 debug ("# hardware_enable done\n");
856
857 return (0);
858}
859
860
wdenkc6097192002-11-03 00:24:07 +0000861#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
862static int hardware_disable(int slot)
863{
864 volatile immap_t *immap;
865 volatile pcmconf8xx_t *pcmp;
866 u_long reg;
867
868 debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
869
870 immap = (immap_t *)CFG_IMMR;
871 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
872
wdenkf602aa02004-03-13 23:29:43 +0000873#ifndef CONFIG_HMI10
dzub02ed682003-10-19 21:43:26 +0000874#ifndef CONFIG_NSCU
wdenkc6097192002-11-03 00:24:07 +0000875 /* remove all power */
876 immap->im_ioport.iop_pcdat &= ~(0x0002 | 0x0004);
dzub02ed682003-10-19 21:43:26 +0000877#endif
wdenkf602aa02004-03-13 23:29:43 +0000878#else /* CONFIG_HMI10 */
wdenk2f99a692004-01-04 22:51:12 +0000879 immap->im_cpm.cp_pbdat |= 0x00000300;
wdenkf602aa02004-03-13 23:29:43 +0000880#endif /* CONFIG_HMI10 */
wdenkc6097192002-11-03 00:24:07 +0000881
wdenkc6097192002-11-03 00:24:07 +0000882 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk90e7e422002-12-04 23:39:58 +0000883 reg = 0;
wdenkc6097192002-11-03 00:24:07 +0000884 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
dzub02ed682003-10-19 21:43:26 +0000885#ifndef NSCU_OE_INV
wdenkc6097192002-11-03 00:24:07 +0000886 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
dzub02ed682003-10-19 21:43:26 +0000887#endif
888 PCMCIA_PGCRX(slot) = reg;
wdenkc6097192002-11-03 00:24:07 +0000889
890 udelay(10000);
891
892 return (0);
893}
894#endif /* CFG_CMD_PCMCIA */
895
dzub02ed682003-10-19 21:43:26 +0000896#ifdef CONFIG_NSCU
wdenkc6097192002-11-03 00:24:07 +0000897static int voltage_set(int slot, int vcc, int vpp)
898{
dzub02ed682003-10-19 21:43:26 +0000899 return 0;
900}
901#else
902static int voltage_set(int slot, int vcc, int vpp)
903{
wdenkc6097192002-11-03 00:24:07 +0000904 volatile immap_t *immap;
905 volatile pcmconf8xx_t *pcmp;
906 u_long reg;
907
908 debug ("voltage_set: "
909 PCMCIA_BOARD_MSG
910 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
911 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
912
913 immap = (immap_t *)CFG_IMMR;
914 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
915 /*
916 * Disable PCMCIA buffers (isolate the interface)
917 * and assert RESET signal
918 */
919 debug ("Disable PCMCIA buffers and assert RESET\n");
dzub02ed682003-10-19 21:43:26 +0000920 reg = PCMCIA_PGCRX(slot);
wdenk90e7e422002-12-04 23:39:58 +0000921 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
dzub02ed682003-10-19 21:43:26 +0000922#ifndef NSCU_OE_INV
wdenk90e7e422002-12-04 23:39:58 +0000923 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
dzub02ed682003-10-19 21:43:26 +0000924#else
925 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
926#endif
927 PCMCIA_PGCRX(slot) = reg;
wdenkc6097192002-11-03 00:24:07 +0000928 udelay(500);
929
wdenkf602aa02004-03-13 23:29:43 +0000930#ifndef CONFIG_HMI10
wdenkc6097192002-11-03 00:24:07 +0000931 /*
932 * Configure Port C pins for
933 * 5 Volts Enable and 3 Volts enable,
934 * Turn off all power
935 */
936 debug ("PCMCIA power OFF\n");
937 immap->im_ioport.iop_pcpar &= ~(0x0002 | 0x0004);
938 immap->im_ioport.iop_pcso &= ~(0x0002 | 0x0004);
939 immap->im_ioport.iop_pcdat &= ~(0x0002 | 0x0004);
940
941 reg = 0;
942 switch(vcc) {
943 case 0: break;
944 case 33: reg |= 0x0002; break;
945 case 50: reg |= 0x0004; break;
946 default: goto done;
947 }
wdenkf602aa02004-03-13 23:29:43 +0000948#else /* CONFIG_HMI10 */
wdenk2f99a692004-01-04 22:51:12 +0000949 /*
950 * Configure Port B pins for
951 * 5 Volts Enable and 3 Volts enable,
952 * Turn off all power
953 */
954 debug ("PCMCIA power OFF\n");
955 immap->im_cpm.cp_pbpar &= ~(0x00000300);
956 /* remove all power */
957
958 immap->im_cpm.cp_pbdat |= 0x00000300;
959
960 reg = 0;
961 switch(vcc) {
962 case 0: break;
963 case 33: reg |= 0x00000200; break;
964 case 50: reg |= 0x00000100; break;
965 default: goto done;
966}
wdenkf602aa02004-03-13 23:29:43 +0000967#endif /* CONFIG_HMI10 */
wdenkc6097192002-11-03 00:24:07 +0000968
969 /* Checking supported voltages */
970
971 debug ("PIPR: 0x%x --> %s\n",
972 pcmp->pcmc_pipr,
973 (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
974
wdenkf602aa02004-03-13 23:29:43 +0000975#ifndef CONFIG_HMI10
wdenkc6097192002-11-03 00:24:07 +0000976 immap->im_ioport.iop_pcdat |= reg;
wdenk90e7e422002-12-04 23:39:58 +0000977 immap->im_ioport.iop_pcdir |= (0x0002 | 0x0004);
wdenk2f99a692004-01-04 22:51:12 +0000978#else
979 immap->im_cpm.cp_pbdat &= !reg;
980 immap->im_cpm.cp_pbdir |= 0x00000300;
wdenkf602aa02004-03-13 23:29:43 +0000981#endif /* CONFIG_HMI10 */
wdenkc6097192002-11-03 00:24:07 +0000982 if (reg) {
wdenkf602aa02004-03-13 23:29:43 +0000983#ifndef CONFIG_HMI10
wdenkc6097192002-11-03 00:24:07 +0000984 debug ("PCMCIA powered at %sV\n",
985 (reg&0x0004) ? "5.0" : "3.3");
wdenk2f99a692004-01-04 22:51:12 +0000986#else
987 debug ("PCMCIA powered at %sV\n",
988 (reg&0x00000200) ? "5.0" : "3.3");
wdenkf602aa02004-03-13 23:29:43 +0000989#endif /* CONFIG_HMI10 */
wdenkc6097192002-11-03 00:24:07 +0000990 } else {
991 debug ("PCMCIA powered down\n");
992 }
993
994done:
995 debug ("Enable PCMCIA buffers and stop RESET\n");
dzub02ed682003-10-19 21:43:26 +0000996 reg = PCMCIA_PGCRX(slot);
wdenkc6097192002-11-03 00:24:07 +0000997 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
dzub02ed682003-10-19 21:43:26 +0000998#ifndef NSCU_OE_INV
wdenkc6097192002-11-03 00:24:07 +0000999 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
dzub02ed682003-10-19 21:43:26 +00001000#else
1001 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
1002#endif
1003 PCMCIA_PGCRX(slot) = reg;
wdenkc6097192002-11-03 00:24:07 +00001004 udelay(500);
1005
1006 debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
1007 slot+'A');
1008 return (0);
1009}
dzub02ed682003-10-19 21:43:26 +00001010#endif
wdenkc6097192002-11-03 00:24:07 +00001011
1012#endif /* TQM8xxL */
1013
1014
wdenk90e7e422002-12-04 23:39:58 +00001015/* -------------------------------------------------------------------- */
1016/* LWMON Board */
1017/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00001018
1019#if defined(CONFIG_LWMON)
1020
1021#define PCMCIA_BOARD_MSG "LWMON"
1022
1023/* #define's for MAX1604 Power Switch */
1024#define MAX1604_OP_SUS 0x80
1025#define MAX1604_VCCBON 0x40
1026#define MAX1604_VCC_35 0x20
1027#define MAX1604_VCCBHIZ 0x10
1028#define MAX1604_VPPBON 0x08
1029#define MAX1604_VPPBPBPGM 0x04
1030#define MAX1604_VPPBHIZ 0x02
1031/* reserved 0x01 */
1032
1033static int hardware_enable(int slot)
1034{
1035 volatile immap_t *immap;
1036 volatile cpm8xx_t *cp;
1037 volatile pcmconf8xx_t *pcmp;
1038 volatile sysconf8xx_t *sysp;
1039 uint reg, mask;
1040 uchar val;
1041
1042
1043 debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1044
1045 /* Switch on PCMCIA port in PIC register 0x60 */
1046 reg = pic_read (0x60);
1047 debug ("[%d] PIC read: reg_60 = 0x%02x\n", __LINE__, reg);
1048 reg &= ~0x10;
wdenk90e7e422002-12-04 23:39:58 +00001049 /* reg |= 0x08; Vpp not needed */
wdenkc6097192002-11-03 00:24:07 +00001050 pic_write (0x60, reg);
1051#ifdef DEBUG
1052 reg = pic_read (0x60);
1053 printf ("[%d] PIC read: reg_60 = 0x%02x\n", __LINE__, reg);
1054#endif
1055 udelay(10000);
1056
1057 immap = (immap_t *)CFG_IMMR;
1058 sysp = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
1059 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1060 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1061
1062 /*
1063 * Configure SIUMCR to enable PCMCIA port B
1064 * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
1065 */
1066 sysp->sc_siumcr &= ~SIUMCR_DBGC11; /* set DBGC to 00 */
1067
1068 /* clear interrupt state, and disable interrupts */
1069 pcmp->pcmc_pscr = PCMCIA_MASK(_slot_);
1070 pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
1071
wdenkc6097192002-11-03 00:24:07 +00001072 /*
wdenk90e7e422002-12-04 23:39:58 +00001073 * Disable interrupts, DMA, and PCMCIA buffers
1074 * (isolate the interface) and assert RESET signal
wdenkc6097192002-11-03 00:24:07 +00001075 */
1076 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk90e7e422002-12-04 23:39:58 +00001077 reg = 0;
1078 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1079 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkc6097192002-11-03 00:24:07 +00001080 PCMCIA_PGCRX(_slot_) = reg;
1081 udelay(500);
1082
1083 /*
1084 * Make sure there is a card in the slot, then configure the interface.
1085 */
1086 udelay(10000);
1087 debug ("[%d] %s: PIPR(%p)=0x%x\n",
1088 __LINE__,__FUNCTION__,
1089 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
wdenk2029f4d2002-11-21 23:11:29 +00001090 if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
wdenkc6097192002-11-03 00:24:07 +00001091 printf (" No Card found\n");
1092 return (1);
1093 }
1094
1095 /*
1096 * Power On.
1097 */
1098 mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
1099 reg = pcmp->pcmc_pipr;
1100 debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
1101 reg,
1102 (reg&PCMCIA_VS1(slot))?"n":"ff",
1103 (reg&PCMCIA_VS2(slot))?"n":"ff");
1104 if ((reg & mask) == mask) {
1105 val = 0; /* VCCB3/5 = 0 ==> use Vx = 5.0 V */
1106 puts (" 5.0V card found: ");
1107 } else {
1108 val = MAX1604_VCC_35; /* VCCB3/5 = 1 ==> use Vy = 3.3 V */
1109 puts (" 3.3V card found: ");
1110 }
1111
1112 /* switch VCC on */
wdenk90e7e422002-12-04 23:39:58 +00001113 val |= MAX1604_OP_SUS | MAX1604_VCCBON;
wdenkc6097192002-11-03 00:24:07 +00001114 i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE);
1115 i2c_write (CFG_I2C_POWER_A_ADDR, 0, 0, &val, 1);
1116
1117 udelay(500000);
1118
1119 debug ("Enable PCMCIA buffers and stop RESET\n");
1120 reg = PCMCIA_PGCRX(_slot_);
1121 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
1122 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
1123 PCMCIA_PGCRX(_slot_) = reg;
1124
1125 udelay(250000); /* some cards need >150 ms to come up :-( */
1126
1127 debug ("# hardware_enable done\n");
1128
1129 return (0);
1130}
1131
1132
wdenkc6097192002-11-03 00:24:07 +00001133#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
1134static int hardware_disable(int slot)
1135{
1136 volatile immap_t *immap;
1137 volatile pcmconf8xx_t *pcmp;
1138 u_long reg;
1139 uchar val;
1140
1141 debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1142
1143 immap = (immap_t *)CFG_IMMR;
1144 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1145
1146 /* remove all power, put output in high impedance state */
1147 val = MAX1604_VCCBHIZ | MAX1604_VPPBHIZ;
1148 i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE);
1149 i2c_write (CFG_I2C_POWER_A_ADDR, 0, 0, &val, 1);
1150
1151 /* Configure PCMCIA General Control Register */
wdenkc6097192002-11-03 00:24:07 +00001152 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk90e7e422002-12-04 23:39:58 +00001153 reg = 0;
wdenkc6097192002-11-03 00:24:07 +00001154 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1155 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
1156 PCMCIA_PGCRX(_slot_) = reg;
1157
1158 /* Switch off PCMCIA port in PIC register 0x60 */
1159 reg = pic_read (0x60);
1160 debug ("[%d] PIC read: reg_60 = 0x%02x\n", __LINE__, reg);
1161 reg |= 0x10;
1162 reg &= ~0x08;
1163 pic_write (0x60, reg);
1164#ifdef DEBUG
1165 reg = pic_read (0x60);
1166 printf ("[%d] PIC read: reg_60 = 0x%02x\n", __LINE__, reg);
1167#endif
1168 udelay(10000);
1169
1170 return (0);
1171}
1172#endif /* CFG_CMD_PCMCIA */
1173
1174
wdenkc6097192002-11-03 00:24:07 +00001175static int voltage_set(int slot, int vcc, int vpp)
1176{
1177 volatile immap_t *immap;
1178 volatile pcmconf8xx_t *pcmp;
1179 u_long reg;
1180 uchar val;
1181
1182 debug ("voltage_set: "
1183 PCMCIA_BOARD_MSG
1184 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
1185 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
1186
1187 immap = (immap_t *)CFG_IMMR;
1188 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1189 /*
1190 * Disable PCMCIA buffers (isolate the interface)
1191 * and assert RESET signal
1192 */
1193 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk90e7e422002-12-04 23:39:58 +00001194 reg = PCMCIA_PGCRX(_slot_);
1195 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1196 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkc6097192002-11-03 00:24:07 +00001197 PCMCIA_PGCRX(_slot_) = reg;
1198 udelay(500);
1199
1200 /*
1201 * Turn off all power (switch to high impedance)
1202 */
1203 debug ("PCMCIA power OFF\n");
1204 val = MAX1604_VCCBHIZ | MAX1604_VPPBHIZ;
1205 i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE);
1206 i2c_write (CFG_I2C_POWER_A_ADDR, 0, 0, &val, 1);
1207
1208 val = 0;
1209 switch(vcc) {
1210 case 0: break;
1211 case 33: val = MAX1604_VCC_35; break;
1212 case 50: break;
1213 default: goto done;
1214 }
1215
1216 /* Checking supported voltages */
1217
1218 debug ("PIPR: 0x%x --> %s\n",
1219 pcmp->pcmc_pipr,
1220 (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
1221
1222 i2c_write (CFG_I2C_POWER_A_ADDR, 0, 0, &val, 1);
1223 if (val) {
1224 debug ("PCMCIA powered at %sV\n",
1225 (val & MAX1604_VCC_35) ? "3.3" : "5.0");
1226 } else {
1227 debug ("PCMCIA powered down\n");
1228 }
1229
1230done:
1231 debug ("Enable PCMCIA buffers and stop RESET\n");
1232 reg = PCMCIA_PGCRX(_slot_);
1233 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
1234 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
1235 PCMCIA_PGCRX(_slot_) = reg;
1236 udelay(500);
1237
1238 debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
1239 slot+'A');
1240 return (0);
1241}
1242
1243#endif /* LWMON */
1244
wdenk90e7e422002-12-04 23:39:58 +00001245/* -------------------------------------------------------------------- */
1246/* GTH board by Corelatus AB */
1247/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00001248#if defined(CONFIG_GTH)
1249
1250#define PCMCIA_BOARD_MSG "GTH COMPACT FLASH"
1251
wdenk90e7e422002-12-04 23:39:58 +00001252static int voltage_set (int slot, int vcc, int vpp)
1253{ /* Do nothing */
1254 return 0;
wdenkc6097192002-11-03 00:24:07 +00001255}
1256
1257static int hardware_enable (int slot)
1258{
wdenk90e7e422002-12-04 23:39:58 +00001259 volatile immap_t *immap;
1260 volatile cpm8xx_t *cp;
1261 volatile pcmconf8xx_t *pcmp;
1262 volatile sysconf8xx_t *sysp;
1263 uint reg, mask;
wdenkc6097192002-11-03 00:24:07 +00001264
wdenk90e7e422002-12-04 23:39:58 +00001265 debug ("hardware_enable: GTH Slot %c\n", 'A' + slot);
wdenkc6097192002-11-03 00:24:07 +00001266
wdenk90e7e422002-12-04 23:39:58 +00001267 immap = (immap_t *) CFG_IMMR;
1268 sysp = (sysconf8xx_t *) (&(((immap_t *) CFG_IMMR)->im_siu_conf));
1269 pcmp = (pcmconf8xx_t *) (&(((immap_t *) CFG_IMMR)->im_pcmcia));
1270 cp = (cpm8xx_t *) (&(((immap_t *) CFG_IMMR)->im_cpm));
wdenkc6097192002-11-03 00:24:07 +00001271
wdenk90e7e422002-12-04 23:39:58 +00001272 /* clear interrupt state, and disable interrupts */
1273 pcmp->pcmc_pscr = PCMCIA_MASK (_slot_);
1274 pcmp->pcmc_per &= ~PCMCIA_MASK (_slot_);
wdenkc6097192002-11-03 00:24:07 +00001275
wdenk90e7e422002-12-04 23:39:58 +00001276 /*
1277 * Disable interrupts, DMA, and PCMCIA buffers
1278 * (isolate the interface) and assert RESET signal
1279 */
1280 debug ("Disable PCMCIA buffers and assert RESET\n");
1281 reg = 0;
1282 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1283 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
1284 PCMCIA_PGCRX (_slot_) = reg;
1285 udelay (500);
wdenkc6097192002-11-03 00:24:07 +00001286
wdenk90e7e422002-12-04 23:39:58 +00001287 /*
1288 * Make sure there is a card in the slot,
1289 * then configure the interface.
1290 */
1291 udelay (10000);
1292 debug ("[%d] %s: PIPR(%p)=0x%x\n",
1293 __LINE__, __FUNCTION__,
1294 &(pcmp->pcmc_pipr), pcmp->pcmc_pipr);
1295 if (pcmp->pcmc_pipr & 0x98000000) {
1296 printf (" No Card found\n");
1297 return (1);
1298 }
wdenkc6097192002-11-03 00:24:07 +00001299
wdenk90e7e422002-12-04 23:39:58 +00001300 mask = PCMCIA_VS1 (slot) | PCMCIA_VS2 (slot);
1301 reg = pcmp->pcmc_pipr;
1302 debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
1303 reg,
1304 (reg & PCMCIA_VS1 (slot)) ? "n" : "ff",
1305 (reg & PCMCIA_VS2 (slot)) ? "n" : "ff");
wdenkc6097192002-11-03 00:24:07 +00001306
wdenk90e7e422002-12-04 23:39:58 +00001307 debug ("Enable PCMCIA buffers and stop RESET\n");
1308 reg = PCMCIA_PGCRX (_slot_);
1309 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
1310 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
1311 PCMCIA_PGCRX (_slot_) = reg;
wdenkc6097192002-11-03 00:24:07 +00001312
wdenk90e7e422002-12-04 23:39:58 +00001313 udelay (250000); /* some cards need >150 ms to come up :-( */
wdenkc6097192002-11-03 00:24:07 +00001314
wdenk90e7e422002-12-04 23:39:58 +00001315 debug ("# hardware_enable done\n");
wdenkc6097192002-11-03 00:24:07 +00001316
wdenk90e7e422002-12-04 23:39:58 +00001317 return 0;
wdenkc6097192002-11-03 00:24:07 +00001318}
1319#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
1320static int hardware_disable(int slot)
1321{
1322 return 0; /* No hardware to disable */
1323}
1324#endif /* CFG_CMD_PCMCIA */
1325#endif /* CONFIG_GTH */
1326
wdenk90e7e422002-12-04 23:39:58 +00001327/* -------------------------------------------------------------------- */
1328/* ICU862 Boards by Cambridge Broadband Ltd. */
1329/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00001330
1331#if defined(CONFIG_ICU862)
1332
1333#define PCMCIA_BOARD_MSG "ICU862"
1334
1335static void cfg_port_B (void);
1336
1337static int hardware_enable(int slot)
1338{
1339 volatile immap_t *immap;
1340 volatile cpm8xx_t *cp;
1341 volatile pcmconf8xx_t *pcmp;
1342 volatile sysconf8xx_t *sysp;
1343 uint reg, pipr, mask;
1344 int i;
1345
1346 debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1347
1348 udelay(10000);
1349
1350 immap = (immap_t *)CFG_IMMR;
1351 sysp = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
1352 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1353 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1354
1355 /* Configure Port B for TPS2205 PC-Card Power-Interface Switch */
1356 cfg_port_B ();
1357
1358 /*
1359 * Configure SIUMCR to enable PCMCIA port B
1360 * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
1361 */
1362 sysp->sc_siumcr &= ~SIUMCR_DBGC11; /* set DBGC to 00 */
1363
1364 /* clear interrupt state, and disable interrupts */
1365 pcmp->pcmc_pscr = PCMCIA_MASK(_slot_);
1366 pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
1367
wdenkc6097192002-11-03 00:24:07 +00001368 /*
wdenk90e7e422002-12-04 23:39:58 +00001369 * Disable interrupts, DMA, and PCMCIA buffers
1370 * (isolate the interface) and assert RESET signal
wdenkc6097192002-11-03 00:24:07 +00001371 */
1372 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk90e7e422002-12-04 23:39:58 +00001373 reg = 0;
1374 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1375 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkc6097192002-11-03 00:24:07 +00001376 PCMCIA_PGCRX(_slot_) = reg;
1377 udelay(500);
1378
1379 /*
1380 * Make sure there is a card in the slot, then configure the interface.
1381 */
1382 udelay(10000);
1383 debug ("[%d] %s: PIPR(%p)=0x%x\n",
1384 __LINE__,__FUNCTION__,
1385 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
wdenk2029f4d2002-11-21 23:11:29 +00001386 if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
wdenkc6097192002-11-03 00:24:07 +00001387 printf (" No Card found\n");
1388 return (1);
1389 }
1390
1391 /*
1392 * Power On: Set VAVCC to 3.3V or 5V, set VAVPP to Hi-Z
1393 */
1394 mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
1395 pipr = pcmp->pcmc_pipr;
1396 debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
1397 pipr,
1398 (reg&PCMCIA_VS1(slot))?"n":"ff",
1399 (reg&PCMCIA_VS2(slot))?"n":"ff");
1400
1401 reg = cp->cp_pbdat;
1402 if ((pipr & mask) == mask) {
wdenk90e7e422002-12-04 23:39:58 +00001403 reg |= (TPS2205_VPP_PGM | TPS2205_VPP_VCC | /* VAVPP => Hi-Z */
1404 TPS2205_VCC3); /* 3V off */
wdenkc6097192002-11-03 00:24:07 +00001405 reg &= ~(TPS2205_VCC5); /* 5V on */
1406 puts (" 5.0V card found: ");
1407 } else {
wdenk90e7e422002-12-04 23:39:58 +00001408 reg |= (TPS2205_VPP_PGM | TPS2205_VPP_VCC | /* VAVPP => Hi-Z */
1409 TPS2205_VCC5); /* 5V off */
wdenkc6097192002-11-03 00:24:07 +00001410 reg &= ~(TPS2205_VCC3); /* 3V on */
1411 puts (" 3.3V card found: ");
1412 }
1413
1414 debug ("\nPB DAT: %08x -> 3.3V %s 5.0V %s VPP_PGM %s VPP_VCC %s\n",
1415 reg,
1416 (reg & TPS2205_VCC3) ? "off" : "on",
1417 (reg & TPS2205_VCC5) ? "off" : "on",
1418 (reg & TPS2205_VPP_PGM) ? "off" : "on",
1419 (reg & TPS2205_VPP_VCC) ? "off" : "on" );
1420
1421 cp->cp_pbdat = reg;
1422
1423 /* Wait 500 ms; use this to check for over-current */
1424 for (i=0; i<5000; ++i) {
1425 if ((cp->cp_pbdat & TPS2205_OC) == 0) {
1426 printf (" *** Overcurrent - Safety shutdown ***\n");
1427 cp->cp_pbdat &= ~(TPS2205_SHDN);
1428 return (1);
1429 }
1430 udelay (100);
1431 }
1432
1433 debug ("Enable PCMCIA buffers and stop RESET\n");
1434 reg = PCMCIA_PGCRX(_slot_);
1435 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
1436 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
1437 PCMCIA_PGCRX(_slot_) = reg;
1438
1439 udelay(250000); /* some cards need >150 ms to come up :-( */
1440
1441 debug ("# hardware_enable done\n");
1442
1443 return (0);
1444}
1445
1446
wdenkc6097192002-11-03 00:24:07 +00001447#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
1448static int hardware_disable(int slot)
1449{
1450 volatile immap_t *immap;
1451 volatile cpm8xx_t *cp;
1452 volatile pcmconf8xx_t *pcmp;
1453 u_long reg;
1454
1455 debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1456
1457 immap = (immap_t *)CFG_IMMR;
1458 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1459 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1460
1461 /* Shut down */
1462 cp->cp_pbdat &= ~(TPS2205_SHDN);
1463
1464 /* Configure PCMCIA General Control Register */
wdenkc6097192002-11-03 00:24:07 +00001465 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk90e7e422002-12-04 23:39:58 +00001466 reg = 0;
wdenkc6097192002-11-03 00:24:07 +00001467 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1468 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
1469 PCMCIA_PGCRX(_slot_) = reg;
1470
1471 udelay(10000);
1472
1473 return (0);
1474}
1475#endif /* CFG_CMD_PCMCIA */
1476
1477
wdenkc6097192002-11-03 00:24:07 +00001478static int voltage_set(int slot, int vcc, int vpp)
1479{
1480 volatile immap_t *immap;
1481 volatile cpm8xx_t *cp;
1482 volatile pcmconf8xx_t *pcmp;
1483 u_long reg;
1484
1485 debug ("voltage_set: "
1486 PCMCIA_BOARD_MSG
1487 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
1488 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
1489
1490 immap = (immap_t *)CFG_IMMR;
1491 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1492 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1493 /*
1494 * Disable PCMCIA buffers (isolate the interface)
1495 * and assert RESET signal
1496 */
1497 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk90e7e422002-12-04 23:39:58 +00001498 reg = PCMCIA_PGCRX(_slot_);
1499 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1500 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkc6097192002-11-03 00:24:07 +00001501 PCMCIA_PGCRX(_slot_) = reg;
1502 udelay(500);
1503
1504 /*
1505 * Configure Port C pins for
1506 * 5 Volts Enable and 3 Volts enable,
1507 * Turn all power pins to Hi-Z
1508 */
1509 debug ("PCMCIA power OFF\n");
1510 cfg_port_B (); /* Enables switch, but all in Hi-Z */
1511
1512 reg = cp->cp_pbdat;
1513
1514 switch(vcc) {
1515 case 0: break; /* Switch off */
1516 case 33: reg &= ~TPS2205_VCC3; break; /* Switch on 3.3V */
1517 case 50: reg &= ~TPS2205_VCC5; break; /* Switch on 5.0V */
1518 default: goto done;
1519 }
1520
1521 /* Checking supported voltages */
1522
1523 debug ("PIPR: 0x%x --> %s\n",
1524 pcmp->pcmc_pipr,
1525 (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
1526
1527 cp->cp_pbdat = reg;
1528
1529#ifdef DEBUG
1530 {
1531 char *s;
1532
1533 if ((reg & TPS2205_VCC3) == 0) {
1534 s = "at 3.3V";
1535 } else if ((reg & TPS2205_VCC5) == 0) {
1536 s = "at 5.0V";
1537 } else {
1538 s = "down";
1539 }
1540 printf ("PCMCIA powered %s\n", s);
1541 }
1542#endif
1543
1544done:
1545 debug ("Enable PCMCIA buffers and stop RESET\n");
1546 reg = PCMCIA_PGCRX(_slot_);
1547 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
1548 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
1549 PCMCIA_PGCRX(_slot_) = reg;
1550 udelay(500);
1551
1552 debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
1553 slot+'A');
1554 return (0);
1555}
1556
1557static void cfg_port_B (void)
1558{
1559 volatile immap_t *immap;
1560 volatile cpm8xx_t *cp;
1561 uint reg;
1562
1563 immap = (immap_t *)CFG_IMMR;
1564 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1565
1566 /*
1567 * Configure Port B for TPS2205 PC-Card Power-Interface Switch
1568 *
1569 * Switch off all voltages, assert shutdown
1570 */
1571 reg = cp->cp_pbdat;
wdenk90e7e422002-12-04 23:39:58 +00001572 reg |= (TPS2205_VPP_PGM | TPS2205_VPP_VCC | /* VAVPP => Hi-Z */
1573 TPS2205_VCC3 | TPS2205_VCC5 | /* VAVCC => Hi-Z */
1574 TPS2205_SHDN); /* enable switch */
wdenkc6097192002-11-03 00:24:07 +00001575 cp->cp_pbdat = reg;
1576
1577 cp->cp_pbpar &= ~(TPS2205_INPUTS | TPS2205_OUTPUTS);
1578
1579 reg = cp->cp_pbdir & ~(TPS2205_INPUTS);
1580 cp->cp_pbdir = reg | TPS2205_OUTPUTS;
1581
1582 debug ("Set Port B: PAR: %08x DIR: %08x DAT: %08x\n",
1583 cp->cp_pbpar, cp->cp_pbdir, cp->cp_pbdat);
1584}
1585
1586#endif /* ICU862 */
1587
1588
wdenk90e7e422002-12-04 23:39:58 +00001589/* -------------------------------------------------------------------- */
1590/* C2MON Boards by TTTech Computertechnik AG */
1591/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00001592
1593#if defined(CONFIG_C2MON)
1594
1595#define PCMCIA_BOARD_MSG "C2MON"
1596
1597static void cfg_ports (void);
1598
1599static int hardware_enable(int slot)
1600{
1601 volatile immap_t *immap;
1602 volatile cpm8xx_t *cp;
1603 volatile pcmconf8xx_t *pcmp;
1604 volatile sysconf8xx_t *sysp;
1605 uint reg, pipr, mask;
1606 ushort sreg;
1607 int i;
1608
1609 debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1610
1611 udelay(10000);
1612
1613 immap = (immap_t *)CFG_IMMR;
1614 sysp = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
1615 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1616 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1617
1618 /* Configure Ports for TPS2211A PC-Card Power-Interface Switch */
1619 cfg_ports ();
1620
1621 /*
1622 * Configure SIUMCR to enable PCMCIA port B
1623 * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
1624 */
1625 sysp->sc_siumcr &= ~SIUMCR_DBGC11; /* set DBGC to 00 */
1626
1627 /* clear interrupt state, and disable interrupts */
1628 pcmp->pcmc_pscr = PCMCIA_MASK(_slot_);
1629 pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
1630
wdenkc6097192002-11-03 00:24:07 +00001631 /*
wdenk90e7e422002-12-04 23:39:58 +00001632 * Disable interrupts, DMA, and PCMCIA buffers
1633 * (isolate the interface) and assert RESET signal
wdenkc6097192002-11-03 00:24:07 +00001634 */
1635 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk90e7e422002-12-04 23:39:58 +00001636 reg = 0;
1637 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1638 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkc6097192002-11-03 00:24:07 +00001639 PCMCIA_PGCRX(_slot_) = reg;
1640 udelay(500);
1641
1642 /*
1643 * Make sure there is a card in the slot, then configure the interface.
1644 */
1645 udelay(10000);
1646 debug ("[%d] %s: PIPR(%p)=0x%x\n",
1647 __LINE__,__FUNCTION__,
1648 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
wdenk2029f4d2002-11-21 23:11:29 +00001649 if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
wdenkc6097192002-11-03 00:24:07 +00001650 printf (" No Card found\n");
1651 return (1);
1652 }
1653
1654 /*
1655 * Power On: Set VAVCC to 3.3V or 5V, set VAVPP to Hi-Z
1656 */
1657 mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
1658 pipr = pcmp->pcmc_pipr;
1659 debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
1660 pipr,
1661 (reg&PCMCIA_VS1(slot))?"n":"ff",
1662 (reg&PCMCIA_VS2(slot))?"n":"ff");
1663
1664 sreg = immap->im_ioport.iop_pcdat;
1665 if ((pipr & mask) == mask) {
1666 sreg |= (TPS2211_VPPD0 | TPS2211_VPPD1 | /* VAVPP => Hi-Z */
1667 TPS2211_VCCD1); /* 5V on */
1668 sreg &= ~(TPS2211_VCCD0); /* 3V off */
1669 puts (" 5.0V card found: ");
1670 } else {
1671 sreg |= (TPS2211_VPPD0 | TPS2211_VPPD1 | /* VAVPP => Hi-Z */
1672 TPS2211_VCCD0); /* 3V on */
1673 sreg &= ~(TPS2211_VCCD1); /* 5V off */
1674 puts (" 3.3V card found: ");
1675 }
1676
1677 debug ("\nPC DAT: %04x -> 3.3V %s 5.0V %s\n",
1678 sreg,
1679 ( (sreg & TPS2211_VCCD0) && !(sreg & TPS2211_VCCD1)) ? "on" : "off",
1680 (!(sreg & TPS2211_VCCD0) && (sreg & TPS2211_VCCD1)) ? "on" : "off"
1681 );
1682
1683 immap->im_ioport.iop_pcdat = sreg;
1684
1685 /* Wait 500 ms; use this to check for over-current */
1686 for (i=0; i<5000; ++i) {
1687 if ((cp->cp_pbdat & TPS2211_OC) == 0) {
1688 printf (" *** Overcurrent - Safety shutdown ***\n");
1689 immap->im_ioport.iop_pcdat &= ~(TPS2211_VCCD0|TPS2211_VCCD1);
1690 return (1);
1691 }
1692 udelay (100);
1693 }
1694
1695 debug ("Enable PCMCIA buffers and stop RESET\n");
1696 reg = PCMCIA_PGCRX(_slot_);
1697 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
1698 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
1699 PCMCIA_PGCRX(_slot_) = reg;
1700
1701 udelay(250000); /* some cards need >150 ms to come up :-( */
1702
1703 debug ("# hardware_enable done\n");
1704
1705 return (0);
1706}
1707
1708
wdenkc6097192002-11-03 00:24:07 +00001709#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
1710static int hardware_disable(int slot)
1711{
1712 volatile immap_t *immap;
1713 volatile cpm8xx_t *cp;
1714 volatile pcmconf8xx_t *pcmp;
1715 u_long reg;
1716
1717 debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
1718
1719 immap = (immap_t *)CFG_IMMR;
1720 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1721
1722 /* Configure PCMCIA General Control Register */
wdenkc6097192002-11-03 00:24:07 +00001723 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk90e7e422002-12-04 23:39:58 +00001724 reg = 0;
wdenkc6097192002-11-03 00:24:07 +00001725 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1726 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
1727 PCMCIA_PGCRX(_slot_) = reg;
1728
1729 /* ALl voltages off / Hi-Z */
1730 immap->im_ioport.iop_pcdat |= (TPS2211_VPPD0 | TPS2211_VPPD1 |
1731 TPS2211_VCCD0 | TPS2211_VCCD1 );
1732
1733 udelay(10000);
1734
1735 return (0);
1736}
1737#endif /* CFG_CMD_PCMCIA */
1738
1739
wdenkc6097192002-11-03 00:24:07 +00001740static int voltage_set(int slot, int vcc, int vpp)
1741{
1742 volatile immap_t *immap;
1743 volatile cpm8xx_t *cp;
1744 volatile pcmconf8xx_t *pcmp;
1745 u_long reg;
1746 ushort sreg;
1747
1748 debug ("voltage_set: "
1749 PCMCIA_BOARD_MSG
1750 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
1751 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
1752
1753 immap = (immap_t *)CFG_IMMR;
1754 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1755 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
1756 /*
1757 * Disable PCMCIA buffers (isolate the interface)
1758 * and assert RESET signal
1759 */
1760 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk90e7e422002-12-04 23:39:58 +00001761 reg = PCMCIA_PGCRX(_slot_);
1762 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1763 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkc6097192002-11-03 00:24:07 +00001764 PCMCIA_PGCRX(_slot_) = reg;
1765 udelay(500);
1766
1767 /*
1768 * Configure Port C pins for
1769 * 5 Volts Enable and 3 Volts enable,
1770 * Turn all power pins to Hi-Z
1771 */
1772 debug ("PCMCIA power OFF\n");
1773 cfg_ports (); /* Enables switch, but all in Hi-Z */
1774
1775 sreg = immap->im_ioport.iop_pcdat;
1776 sreg |= TPS2211_VPPD0 | TPS2211_VPPD1; /* VAVPP always Hi-Z */
1777
1778 switch(vcc) {
1779 case 0: break; /* Switch off */
1780 case 33: sreg |= TPS2211_VCCD0; /* Switch on 3.3V */
1781 sreg &= ~TPS2211_VCCD1;
1782 break;
1783 case 50: sreg &= ~TPS2211_VCCD0; /* Switch on 5.0V */
1784 sreg |= TPS2211_VCCD1;
1785 break;
1786 default: goto done;
1787 }
1788
1789 /* Checking supported voltages */
1790
1791 debug ("PIPR: 0x%x --> %s\n",
1792 pcmp->pcmc_pipr,
1793 (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
1794
1795 immap->im_ioport.iop_pcdat = sreg;
1796
1797#ifdef DEBUG
1798 {
1799 char *s;
1800
1801 if ((sreg & TPS2211_VCCD0) && !(sreg & TPS2211_VCCD1)) {
1802 s = "at 3.3V";
1803 } else if (!(sreg & TPS2211_VCCD0) && (sreg & TPS2211_VCCD1)) {
1804 s = "at 5.0V";
1805 } else {
1806 s = "down";
1807 }
1808 printf ("PCMCIA powered %s\n", s);
1809 }
1810#endif
1811
1812done:
1813 debug ("Enable PCMCIA buffers and stop RESET\n");
1814 reg = PCMCIA_PGCRX(_slot_);
1815 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
1816 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
1817 PCMCIA_PGCRX(_slot_) = reg;
1818 udelay(500);
1819
1820 debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
1821 slot+'A');
1822 return (0);
1823}
1824
1825static void cfg_ports (void)
1826{
1827 volatile immap_t *immap;
1828 volatile cpm8xx_t *cp;
1829 ushort sreg;
1830
1831 immap = (immap_t *)CFG_IMMR;
1832 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
1833
1834 /*
1835 * Configure Port C for TPS2211 PC-Card Power-Interface Switch
1836 *
1837 * Switch off all voltages, assert shutdown
1838 */
1839 sreg = immap->im_ioport.iop_pcdat;
1840 sreg |= (TPS2211_VPPD0 | TPS2211_VPPD1); /* VAVPP => Hi-Z */
1841 sreg &= ~(TPS2211_VCCD0 | TPS2211_VCCD1); /* 3V and 5V off */
1842 immap->im_ioport.iop_pcdat = sreg;
1843
1844 immap->im_ioport.iop_pcpar &= ~(TPS2211_OUTPUTS);
1845 immap->im_ioport.iop_pcdir |= TPS2211_OUTPUTS;
1846
1847 debug ("Set Port C: PAR: %04x DIR: %04x DAT: %04x\n",
1848 immap->im_ioport.iop_pcpar,
1849 immap->im_ioport.iop_pcdir,
1850 immap->im_ioport.iop_pcdat);
1851
1852 /*
1853 * Configure Port B for TPS2211 PC-Card Power-Interface Switch
1854 *
1855 * Over-Current Input only
1856 */
1857 cp->cp_pbpar &= ~(TPS2211_INPUTS);
1858 cp->cp_pbdir &= ~(TPS2211_INPUTS);
1859
1860 debug ("Set Port B: PAR: %08x DIR: %08x DAT: %08x\n",
1861 cp->cp_pbpar, cp->cp_pbdir, cp->cp_pbdat);
1862}
1863
1864#endif /* C2MON */
1865
wdenk90e7e422002-12-04 23:39:58 +00001866/* -------------------------------------------------------------------- */
1867/* MBX board from Morotola */
1868/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00001869
1870#if defined( CONFIG_MBX )
1871#include <../board/mbx8xx/csr.h>
1872
1873/* A lot of this has been taken from the RPX code in this file it works from me.
1874 I have added the voltage selection for the MBX board. */
1875
1876/* MBX voltage bit in control register #2 */
1877#define CR2_VPP12 ((uchar)0x10)
1878#define CR2_VPPVDD ((uchar)0x20)
1879#define CR2_VDD5 ((uchar)0x40)
1880#define CR2_VDD3 ((uchar)0x80)
1881
1882#define PCMCIA_BOARD_MSG "MBX860"
1883
1884static int voltage_set (int slot, int vcc, int vpp)
1885{
1886 uchar reg = 0;
1887
1888 debug ("voltage_set: PCMCIA_BOARD_MSG Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
1889 'A' + slot, vcc / 10, vcc % 10, vpp / 10, vcc % 10);
1890
1891 switch (vcc) {
1892 case 0:
1893 break;
1894 case 33:
1895 reg |= CR2_VDD3;
1896 break;
1897 case 50:
1898 reg |= CR2_VDD5;
1899 break;
1900 default:
1901 return 1;
1902 }
1903
1904 switch (vpp) {
1905 case 0:
1906 break;
1907 case 33:
1908 case 50:
1909 if (vcc == vpp) {
1910 reg |= CR2_VPPVDD;
1911 } else {
1912 return 1;
1913 }
1914 break;
1915 case 120:
1916 reg |= CR2_VPP12;
1917 break;
1918 default:
1919 return 1;
1920 }
1921
1922 /* first, turn off all power */
1923 MBX_CSR2 &= ~(CR2_VDDSEL | CR2_VPPSEL);
1924
1925 /* enable new powersettings */
1926 MBX_CSR2 |= reg;
1927 debug ("MBX_CSR2 read = 0x%02x\n", MBX_CSR2);
1928
1929 return (0);
1930}
1931
1932static int hardware_enable (int slot)
1933{
1934 volatile immap_t *immap;
1935 volatile cpm8xx_t *cp;
1936 volatile pcmconf8xx_t *pcmp;
1937 volatile sysconf8xx_t *sysp;
1938 uint reg, mask;
1939
1940 debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n",
1941 'A' + slot);
1942
1943 udelay (10000);
1944
1945 immap = (immap_t *) CFG_IMMR;
1946 sysp = (sysconf8xx_t *) (&(((immap_t *) CFG_IMMR)->im_siu_conf));
1947 pcmp = (pcmconf8xx_t *) (&(((immap_t *) CFG_IMMR)->im_pcmcia));
1948 cp = (cpm8xx_t *) (&(((immap_t *) CFG_IMMR)->im_cpm));
1949
1950 /* clear interrupt state, and disable interrupts */
1951 pcmp->pcmc_pscr = PCMCIA_MASK (_slot_);
1952 pcmp->pcmc_per &= ~PCMCIA_MASK (_slot_);
1953
wdenkc6097192002-11-03 00:24:07 +00001954 /*
wdenk90e7e422002-12-04 23:39:58 +00001955 * Disable interrupts, DMA, and PCMCIA buffers
1956 * (isolate the interface) and assert RESET signal
wdenkc6097192002-11-03 00:24:07 +00001957 */
1958 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk90e7e422002-12-04 23:39:58 +00001959 reg = 0;
wdenkc6097192002-11-03 00:24:07 +00001960 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
1961 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
1962 PCMCIA_PGCRX (_slot_) = reg;
1963 udelay (500);
1964
1965 /* remove all power */
1966 voltage_set (slot, 0, 0);
1967 /*
1968 * Make sure there is a card in the slot, then configure the interface.
1969 */
wdenk2029f4d2002-11-21 23:11:29 +00001970 udelay(10000);
1971 debug ("[%d] %s: PIPR(%p)=0x%x\n",
1972 __LINE__,__FUNCTION__,
1973 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
wdenkf602aa02004-03-13 23:29:43 +00001974#ifndef CONFIG_HMI10
wdenk2029f4d2002-11-21 23:11:29 +00001975 if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
wdenk2f99a692004-01-04 22:51:12 +00001976#else
1977 if (pcmp->pcmc_pipr & (0x10000000 >> (slot << 4))) {
wdenkf602aa02004-03-13 23:29:43 +00001978#endif /* CONFIG_HMI10 */
wdenkc6097192002-11-03 00:24:07 +00001979 printf (" No Card found\n");
1980 return (1);
1981 }
1982
1983 /*
1984 * Power On.
1985 */
1986 mask = PCMCIA_VS1 (_slot_) | PCMCIA_VS2 (_slot_);
1987 reg = pcmp->pcmc_pipr;
1988 debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n", reg,
1989 (reg & PCMCIA_VS1 (slot)) ? "n" : "ff",
1990 (reg & PCMCIA_VS2 (slot)) ? "n" : "ff");
1991
1992 if ((reg & mask) == mask) {
1993 voltage_set (_slot_, 50, 0);
1994 printf (" 5.0V card found: ");
1995 } else {
1996 voltage_set (_slot_, 33, 0);
1997 printf (" 3.3V card found: ");
1998 }
1999
2000 debug ("Enable PCMCIA buffers and stop RESET\n");
2001 reg = PCMCIA_PGCRX (_slot_);
2002 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
2003 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
2004 PCMCIA_PGCRX (_slot_) = reg;
2005
2006 udelay (250000); /* some cards need >150 ms to come up :-( */
2007
2008 debug ("# hardware_enable done\n");
2009
2010 return (0);
2011}
2012
2013#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
2014static int hardware_disable (int slot)
2015{
2016 return 0; /* No hardware to disable */
2017}
2018#endif /* CFG_CMD_PCMCIA */
2019#endif /* CONFIG_MBX */
wdenk90e7e422002-12-04 23:39:58 +00002020/* -------------------------------------------------------------------- */
2021/* R360MPI Board */
2022/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00002023
2024#if defined(CONFIG_R360MPI)
2025
2026#define PCMCIA_BOARD_MSG "R360MPI"
2027
2028
2029static int hardware_enable(int slot)
2030{
2031 volatile immap_t *immap;
2032 volatile cpm8xx_t *cp;
2033 volatile pcmconf8xx_t *pcmp;
2034 volatile sysconf8xx_t *sysp;
2035 uint reg, mask;
2036
2037 debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
2038
2039 udelay(10000);
2040
2041 immap = (immap_t *)CFG_IMMR;
2042 sysp = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
2043 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
2044 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
2045
2046 /*
2047 * Configure SIUMCR to enable PCMCIA port B
2048 * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
2049 */
2050 sysp->sc_siumcr &= ~SIUMCR_DBGC11; /* set DBGC to 00 */
2051
2052 /* clear interrupt state, and disable interrupts */
2053 pcmp->pcmc_pscr = PCMCIA_MASK(_slot_);
2054 pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
2055
wdenkc6097192002-11-03 00:24:07 +00002056 /*
wdenk90e7e422002-12-04 23:39:58 +00002057 * Disable interrupts, DMA, and PCMCIA buffers
2058 * (isolate the interface) and assert RESET signal
wdenkc6097192002-11-03 00:24:07 +00002059 */
2060 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk90e7e422002-12-04 23:39:58 +00002061 reg = 0;
2062 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
2063 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkc6097192002-11-03 00:24:07 +00002064 PCMCIA_PGCRX(_slot_) = reg;
2065 udelay(500);
2066
2067 /*
2068 * Configure Ports A, B & C pins for
2069 * 5 Volts Enable and 3 Volts enable
2070 */
2071 immap->im_ioport.iop_pcpar &= ~(0x0400);
2072 immap->im_ioport.iop_pcso &= ~(0x0400);/*
2073 immap->im_ioport.iop_pcdir |= 0x0400;*/
2074
2075 immap->im_ioport.iop_papar &= ~(0x0200);/*
2076 immap->im_ioport.iop_padir |= 0x0200;*/
2077#if 0
2078 immap->im_ioport.iop_pbpar &= ~(0xC000);
2079 immap->im_ioport.iop_pbdir &= ~(0xC000);
2080#endif
2081 /* remove all power */
2082
2083 immap->im_ioport.iop_pcdat |= 0x0400;
2084 immap->im_ioport.iop_padat |= 0x0200;
2085
2086 /*
2087 * Make sure there is a card in the slot, then configure the interface.
2088 */
2089 udelay(10000);
2090 debug ("[%d] %s: PIPR(%p)=0x%x\n",
2091 __LINE__,__FUNCTION__,
2092 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
wdenk2029f4d2002-11-21 23:11:29 +00002093 if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
wdenkc6097192002-11-03 00:24:07 +00002094 printf (" No Card found\n");
2095 return (1);
2096 }
2097
2098 /*
2099 * Power On.
2100 */
2101 mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
2102 reg = pcmp->pcmc_pipr;
2103 debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
2104 reg,
2105 (reg&PCMCIA_VS1(slot))?"n":"ff",
2106 (reg&PCMCIA_VS2(slot))?"n":"ff");
2107 if ((reg & mask) == mask) {
2108 immap->im_ioport.iop_pcdat &= ~(0x4000);
2109 puts (" 5.0V card found: ");
2110 } else {
2111 immap->im_ioport.iop_padat &= ~(0x0002);
2112 puts (" 3.3V card found: ");
2113 }
2114 immap->im_ioport.iop_pcdir |= 0x0400;
2115 immap->im_ioport.iop_padir |= 0x0200;
2116#if 0
2117 /* VCC switch error flag, PCMCIA slot INPACK_ pin */
2118 cp->cp_pbdir &= ~(0x0020 | 0x0010);
2119 cp->cp_pbpar &= ~(0x0020 | 0x0010);
2120 udelay(500000);
2121#endif
2122 debug ("Enable PCMCIA buffers and stop RESET\n");
2123 reg = PCMCIA_PGCRX(_slot_);
2124 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
2125 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
2126 PCMCIA_PGCRX(_slot_) = reg;
2127
2128 udelay(250000); /* some cards need >150 ms to come up :-( */
2129
2130 debug ("# hardware_enable done\n");
2131
2132 return (0);
2133}
2134
2135
wdenkc6097192002-11-03 00:24:07 +00002136#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
2137static int hardware_disable(int slot)
2138{
2139 volatile immap_t *immap;
2140 volatile pcmconf8xx_t *pcmp;
2141 u_long reg;
2142
2143 debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
2144
2145 immap = (immap_t *)CFG_IMMR;
2146 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
2147
2148 /* remove all power */
2149 immap->im_ioport.iop_pcdat |= 0x0400;
2150 immap->im_ioport.iop_padat |= 0x0200;
2151
2152 /* Configure PCMCIA General Control Register */
wdenkc6097192002-11-03 00:24:07 +00002153 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk90e7e422002-12-04 23:39:58 +00002154 reg = 0;
wdenkc6097192002-11-03 00:24:07 +00002155 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
2156 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
2157 PCMCIA_PGCRX(_slot_) = reg;
2158
2159 udelay(10000);
2160
2161 return (0);
2162}
2163#endif /* CFG_CMD_PCMCIA */
2164
2165
wdenkc6097192002-11-03 00:24:07 +00002166static int voltage_set(int slot, int vcc, int vpp)
2167{
2168 volatile immap_t *immap;
2169 volatile pcmconf8xx_t *pcmp;
2170 u_long reg;
2171
2172 debug ("voltage_set: "
2173 PCMCIA_BOARD_MSG
2174 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
2175 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
2176
2177 immap = (immap_t *)CFG_IMMR;
2178 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
2179 /*
2180 * Disable PCMCIA buffers (isolate the interface)
2181 * and assert RESET signal
2182 */
2183 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk90e7e422002-12-04 23:39:58 +00002184 reg = PCMCIA_PGCRX(_slot_);
2185 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
2186 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenkc6097192002-11-03 00:24:07 +00002187 PCMCIA_PGCRX(_slot_) = reg;
2188 udelay(500);
2189
2190 /*
2191 * Configure Ports A & C pins for
2192 * 5 Volts Enable and 3 Volts enable,
2193 * Turn off all power
2194 */
2195 debug ("PCMCIA power OFF\n");
2196 immap->im_ioport.iop_pcpar &= ~(0x0400);
2197 immap->im_ioport.iop_pcso &= ~(0x0400);/*
2198 immap->im_ioport.iop_pcdir |= 0x0400;*/
2199
2200 immap->im_ioport.iop_papar &= ~(0x0200);/*
2201 immap->im_ioport.iop_padir |= 0x0200;*/
2202
2203 immap->im_ioport.iop_pcdat |= 0x0400;
2204 immap->im_ioport.iop_padat |= 0x0200;
2205
2206 reg = 0;
2207 switch(vcc) {
2208 case 0: break;
2209 case 33: reg |= 0x0200; break;
2210 case 50: reg |= 0x0400; break;
2211 default: goto done;
2212 }
2213
2214 /* Checking supported voltages */
2215
2216 debug ("PIPR: 0x%x --> %s\n",
2217 pcmp->pcmc_pipr,
2218 (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
2219
2220 if (reg & 0x0200)
2221 immap->im_ioport.iop_pcdat &= !reg;
2222 if (reg & 0x0400)
2223 immap->im_ioport.iop_padat &= !reg;
wdenk90e7e422002-12-04 23:39:58 +00002224 immap->im_ioport.iop_pcdir |= 0x0200;
2225 immap->im_ioport.iop_padir |= 0x0400;
wdenkc6097192002-11-03 00:24:07 +00002226 if (reg) {
2227 debug ("PCMCIA powered at %sV\n",
2228 (reg&0x0400) ? "5.0" : "3.3");
2229 } else {
2230 debug ("PCMCIA powered down\n");
2231 }
2232
2233done:
2234 debug ("Enable PCMCIA buffers and stop RESET\n");
2235 reg = PCMCIA_PGCRX(_slot_);
2236 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
2237 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
2238 PCMCIA_PGCRX(_slot_) = reg;
2239 udelay(500);
2240
2241 debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
2242 slot+'A');
2243 return (0);
2244}
2245
2246#endif /* R360MPI */
2247
wdenk90e7e422002-12-04 23:39:58 +00002248/* -------------------------------------------------------------------- */
wdenk65faef92004-03-25 19:29:38 +00002249/* KUP4K and KUP4X Boards */
wdenk90e7e422002-12-04 23:39:58 +00002250/* -------------------------------------------------------------------- */
wdenk65faef92004-03-25 19:29:38 +00002251#if defined(CONFIG_KUP4K) || defined(CONFIG_KUP4X)
wdenk56f94be2002-11-05 16:35:14 +00002252
wdenk65faef92004-03-25 19:29:38 +00002253#define PCMCIA_BOARD_MSG "KUP"
wdenk56f94be2002-11-05 16:35:14 +00002254
2255#define KUP4K_PCMCIA_B_3V3 (0x00020000)
2256
2257static int hardware_enable(int slot)
2258{
2259 volatile immap_t *immap;
2260 volatile cpm8xx_t *cp;
2261 volatile pcmconf8xx_t *pcmp;
2262 volatile sysconf8xx_t *sysp;
2263 uint reg, mask;
2264
2265 debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
2266
2267 udelay(10000);
2268
2269 immap = (immap_t *)CFG_IMMR;
2270 sysp = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
2271 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
2272 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
2273
2274 /*
2275 * Configure SIUMCR to enable PCMCIA port B
2276 * (VFLS[0:1] are not used for debugging, we connect FRZ# instead)
2277 */
2278 sysp->sc_siumcr &= ~SIUMCR_DBGC11; /* set DBGC to 00 */
2279
2280 /* clear interrupt state, and disable interrupts */
wdenk2029f4d2002-11-21 23:11:29 +00002281 pcmp->pcmc_pscr = PCMCIA_MASK(slot);
2282 pcmp->pcmc_per &= ~PCMCIA_MASK(slot);
wdenk56f94be2002-11-05 16:35:14 +00002283
wdenk56f94be2002-11-05 16:35:14 +00002284 /*
wdenk90e7e422002-12-04 23:39:58 +00002285 * Disable interrupts, DMA, and PCMCIA buffers
2286 * (isolate the interface) and assert RESET signal
wdenk56f94be2002-11-05 16:35:14 +00002287 */
2288 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk90e7e422002-12-04 23:39:58 +00002289 reg = 0;
2290 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
2291 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenk2029f4d2002-11-21 23:11:29 +00002292 PCMCIA_PGCRX(slot) = reg;
2293 udelay(2500);
wdenk56f94be2002-11-05 16:35:14 +00002294
2295 /*
2296 * Configure Port B pins for
2297 * 3 Volts enable
2298 */
wdenk2029f4d2002-11-21 23:11:29 +00002299 if (slot) { /* Slot A is built-in */
2300 cp->cp_pbdir |= KUP4K_PCMCIA_B_3V3;
2301 cp->cp_pbpar &= ~KUP4K_PCMCIA_B_3V3;
2302 /* remove all power */
2303 cp->cp_pbdat |= KUP4K_PCMCIA_B_3V3; /* active low */
2304 }
wdenk56f94be2002-11-05 16:35:14 +00002305 /*
2306 * Make sure there is a card in the slot, then configure the interface.
2307 */
2308 udelay(10000);
2309 debug ("[%d] %s: PIPR(%p)=0x%x\n",
2310 __LINE__,__FUNCTION__,
2311 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
wdenk2029f4d2002-11-21 23:11:29 +00002312 if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
wdenk56f94be2002-11-05 16:35:14 +00002313 printf (" No Card found\n");
2314 return (1);
2315 }
2316
2317 /*
2318 * Power On.
2319 */
wdenk9dd2b882002-12-03 21:28:10 +00002320 printf("%s Slot %c:", slot ? "" : "\n", 'A' + slot);
wdenk56f94be2002-11-05 16:35:14 +00002321 mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
2322 reg = pcmp->pcmc_pipr;
2323 debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
2324 reg,
2325 (reg&PCMCIA_VS1(slot))?"n":"ff",
2326 (reg&PCMCIA_VS2(slot))?"n":"ff");
2327 if ((reg & mask) == mask) {
2328 puts (" 5.0V card found: NOT SUPPORTED !!!\n");
2329 } else {
wdenk2029f4d2002-11-21 23:11:29 +00002330 if(slot)
2331 cp->cp_pbdat &= ~KUP4K_PCMCIA_B_3V3;
wdenk56f94be2002-11-05 16:35:14 +00002332 puts (" 3.3V card found: ");
2333 }
2334#if 0
2335 /* VCC switch error flag, PCMCIA slot INPACK_ pin */
2336 cp->cp_pbdir &= ~(0x0020 | 0x0010);
2337 cp->cp_pbpar &= ~(0x0020 | 0x0010);
2338 udelay(500000);
2339#endif
2340 debug ("Enable PCMCIA buffers and stop RESET\n");
wdenk2029f4d2002-11-21 23:11:29 +00002341 reg = PCMCIA_PGCRX(slot);
wdenk56f94be2002-11-05 16:35:14 +00002342 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
2343 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
wdenk2029f4d2002-11-21 23:11:29 +00002344 PCMCIA_PGCRX(slot) = reg;
wdenk56f94be2002-11-05 16:35:14 +00002345
2346 udelay(250000); /* some cards need >150 ms to come up :-( */
2347
2348 debug ("# hardware_enable done\n");
2349
2350 return (0);
2351}
2352
2353
wdenk56f94be2002-11-05 16:35:14 +00002354#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
2355static int hardware_disable(int slot)
2356{
2357 volatile immap_t *immap;
2358 volatile cpm8xx_t *cp;
2359 volatile pcmconf8xx_t *pcmp;
2360 u_long reg;
2361
2362 debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
2363
2364 immap = (immap_t *)CFG_IMMR;
2365 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
2366 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
wdenk90e7e422002-12-04 23:39:58 +00002367
wdenk56f94be2002-11-05 16:35:14 +00002368 /* remove all power */
wdenk2029f4d2002-11-21 23:11:29 +00002369 if (slot)
2370 cp->cp_pbdat |= KUP4K_PCMCIA_B_3V3;
wdenk56f94be2002-11-05 16:35:14 +00002371
2372 /* Configure PCMCIA General Control Register */
wdenk56f94be2002-11-05 16:35:14 +00002373 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk90e7e422002-12-04 23:39:58 +00002374 reg = 0;
wdenk56f94be2002-11-05 16:35:14 +00002375 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
2376 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenk2029f4d2002-11-21 23:11:29 +00002377 PCMCIA_PGCRX(slot) = reg;
wdenk56f94be2002-11-05 16:35:14 +00002378
2379 udelay(10000);
2380
2381 return (0);
2382}
2383#endif /* CFG_CMD_PCMCIA */
2384
2385
wdenk56f94be2002-11-05 16:35:14 +00002386static int voltage_set(int slot, int vcc, int vpp)
2387{
2388 volatile immap_t *immap;
2389 volatile cpm8xx_t *cp;
2390 volatile pcmconf8xx_t *pcmp;
2391 u_long reg;
2392
2393 debug ("voltage_set: " \
2394 PCMCIA_BOARD_MSG \
2395 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
2396 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
2397
wdenk2029f4d2002-11-21 23:11:29 +00002398 if (!slot) /* Slot A is not configurable */
2399 return 0;
2400
wdenk56f94be2002-11-05 16:35:14 +00002401 immap = (immap_t *)CFG_IMMR;
2402 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
2403 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
2404
2405 /*
2406 * Disable PCMCIA buffers (isolate the interface)
2407 * and assert RESET signal
2408 */
2409 debug ("Disable PCMCIA buffers and assert RESET\n");
wdenk90e7e422002-12-04 23:39:58 +00002410 reg = PCMCIA_PGCRX(slot);
2411 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
2412 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
wdenk2029f4d2002-11-21 23:11:29 +00002413 PCMCIA_PGCRX(slot) = reg;
wdenk56f94be2002-11-05 16:35:14 +00002414 udelay(500);
2415
2416 debug ("PCMCIA power OFF\n");
2417 /*
2418 * Configure Port B pins for
2419 * 3 Volts enable
2420 */
2421 cp->cp_pbdir |= KUP4K_PCMCIA_B_3V3;
2422 cp->cp_pbpar &= ~KUP4K_PCMCIA_B_3V3;
2423 /* remove all power */
2424 cp->cp_pbdat |= KUP4K_PCMCIA_B_3V3; /* active low */
2425
2426 switch(vcc) {
2427 case 0: break;
2428 case 33:
2429 cp->cp_pbdat &= ~KUP4K_PCMCIA_B_3V3;
2430 debug ("PCMCIA powered at 3.3V\n");
2431 break;
2432 case 50:
2433 debug ("PCMCIA: 5Volt vcc not supported\n");
2434 break;
2435 default:
2436 puts("PCMCIA: vcc not supported");
2437 break;
2438 }
wdenk2029f4d2002-11-21 23:11:29 +00002439 udelay(10000);
wdenk56f94be2002-11-05 16:35:14 +00002440 /* Checking supported voltages */
2441
2442 debug ("PIPR: 0x%x --> %s\n",
2443 pcmp->pcmc_pipr,
wdenk2029f4d2002-11-21 23:11:29 +00002444 (pcmp->pcmc_pipr & (0x80000000 >> (slot << 4)))
wdenk56f94be2002-11-05 16:35:14 +00002445 ? "only 5 V --> NOT SUPPORTED"
2446 : "can do 3.3V");
2447
2448
2449 debug ("Enable PCMCIA buffers and stop RESET\n");
wdenk2029f4d2002-11-21 23:11:29 +00002450 reg = PCMCIA_PGCRX(slot);
wdenk56f94be2002-11-05 16:35:14 +00002451 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
2452 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
wdenk2029f4d2002-11-21 23:11:29 +00002453 PCMCIA_PGCRX(slot) = reg;
wdenk56f94be2002-11-05 16:35:14 +00002454 udelay(500);
2455
2456 debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
2457 slot+'A');
2458 return (0);
2459}
2460
wdenk65faef92004-03-25 19:29:38 +00002461#endif /* KUP4K || KUP4X */
wdenk56f94be2002-11-05 16:35:14 +00002462
2463
wdenk90e7e422002-12-04 23:39:58 +00002464/* -------------------------------------------------------------------- */
2465/* End of Board Specific Stuff */
2466/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00002467
2468
wdenk90e7e422002-12-04 23:39:58 +00002469/* -------------------------------------------------------------------- */
2470/* MPC8xx Specific Stuff - should go to MPC8xx directory */
2471/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00002472
2473/*
2474 * Search this table to see if the windowsize is
2475 * supported...
2476 */
2477
2478#define M8XX_SIZES_NO 32
2479
2480static const u_int m8xx_size_to_gray[M8XX_SIZES_NO] =
2481{ 0x00000001, 0x00000002, 0x00000008, 0x00000004,
2482 0x00000080, 0x00000040, 0x00000010, 0x00000020,
2483 0x00008000, 0x00004000, 0x00001000, 0x00002000,
2484 0x00000100, 0x00000200, 0x00000800, 0x00000400,
2485
2486 0x0fffffff, 0xffffffff, 0xffffffff, 0xffffffff,
2487 0x01000000, 0x02000000, 0xffffffff, 0x04000000,
2488 0x00010000, 0x00020000, 0x00080000, 0x00040000,
2489 0x00800000, 0x00400000, 0x00100000, 0x00200000 };
2490
2491
wdenk90e7e422002-12-04 23:39:58 +00002492/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00002493
wdenk634d2f72004-04-15 23:14:49 +00002494#if ( ! defined(CONFIG_I82365) && ! defined(CONFIG_PXA_PCMCIA) )
wdenk0893c472003-05-20 14:25:27 +00002495
wdenkc6097192002-11-03 00:24:07 +00002496static u_int m8xx_get_graycode(u_int size)
2497{
2498 u_int k;
2499
2500 for (k = 0; k < M8XX_SIZES_NO; k++) {
2501 if(m8xx_size_to_gray[k] == size)
2502 break;
2503 }
2504
2505 if((k == M8XX_SIZES_NO) || (m8xx_size_to_gray[k] == -1))
2506 k = -1;
2507
2508 return k;
2509}
2510
wdenk0893c472003-05-20 14:25:27 +00002511#endif /* CONFIG_I82365 */
2512
wdenk90e7e422002-12-04 23:39:58 +00002513/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00002514
2515#if 0
2516static u_int m8xx_get_speed(u_int ns, u_int is_io)
2517{
2518 u_int reg, clocks, psst, psl, psht;
2519
2520 if(!ns) {
2521
2522 /*
2523 * We get called with IO maps setup to 0ns
2524 * if not specified by the user.
2525 * They should be 255ns.
2526 */
2527
2528 if(is_io)
2529 ns = 255;
2530 else
2531 ns = 100; /* fast memory if 0 */
2532 }
2533
2534 /*
2535 * In PSST, PSL, PSHT fields we tell the controller
2536 * timing parameters in CLKOUT clock cycles.
2537 * CLKOUT is the same as GCLK2_50.
2538 */
2539
2540/* how we want to adjust the timing - in percent */
2541
2542#define ADJ 180 /* 80 % longer accesstime - to be sure */
2543
2544 clocks = ((M8XX_BUSFREQ / 1000) * ns) / 1000;
2545 clocks = (clocks * ADJ) / (100*1000);
2546
2547 if(clocks >= PCMCIA_BMT_LIMIT) {
2548 DEBUG(0, "Max access time limit reached\n");
2549 clocks = PCMCIA_BMT_LIMIT-1;
2550 }
2551
2552 psst = clocks / 7; /* setup time */
2553 psht = clocks / 7; /* hold time */
2554 psl = (clocks * 5) / 7; /* strobe length */
2555
2556 psst += clocks - (psst + psht + psl);
2557
2558 reg = psst << 12;
2559 reg |= psl << 7;
2560 reg |= psht << 16;
2561
2562 return reg;
2563}
2564#endif
2565
wdenk90e7e422002-12-04 23:39:58 +00002566/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00002567
wdenk634d2f72004-04-15 23:14:49 +00002568#if defined(CONFIG_IDE_8xx_PCCARD) || defined(CONFIG_PXA_PCMCIA)
wdenkc6097192002-11-03 00:24:07 +00002569static void print_funcid (int func)
2570{
2571 puts (indent);
2572 switch (func) {
2573 case CISTPL_FUNCID_MULTI:
2574 puts (" Multi-Function");
2575 break;
2576 case CISTPL_FUNCID_MEMORY:
2577 puts (" Memory");
2578 break;
2579 case CISTPL_FUNCID_SERIAL:
2580 puts (" Serial Port");
2581 break;
2582 case CISTPL_FUNCID_PARALLEL:
2583 puts (" Parallel Port");
2584 break;
2585 case CISTPL_FUNCID_FIXED:
2586 puts (" Fixed Disk");
2587 break;
2588 case CISTPL_FUNCID_VIDEO:
2589 puts (" Video Adapter");
2590 break;
2591 case CISTPL_FUNCID_NETWORK:
2592 puts (" Network Adapter");
2593 break;
2594 case CISTPL_FUNCID_AIMS:
2595 puts (" AIMS Card");
2596 break;
2597 case CISTPL_FUNCID_SCSI:
2598 puts (" SCSI Adapter");
2599 break;
2600 default:
2601 puts (" Unknown");
2602 break;
2603 }
2604 puts (" Card\n");
2605}
2606#endif /* CONFIG_IDE_8xx_PCCARD */
2607
wdenk90e7e422002-12-04 23:39:58 +00002608/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00002609
wdenk634d2f72004-04-15 23:14:49 +00002610#if defined(CONFIG_IDE_8xx_PCCARD) || defined(CONFIG_PXA_PCMCIA)
wdenkc6097192002-11-03 00:24:07 +00002611static void print_fixed (volatile uchar *p)
2612{
2613 if (p == NULL)
2614 return;
2615
2616 puts(indent);
2617
2618 switch (*p) {
2619 case CISTPL_FUNCE_IDE_IFACE:
2620 { uchar iface = *(p+2);
2621
2622 puts ((iface == CISTPL_IDE_INTERFACE) ? " IDE" : " unknown");
2623 puts (" interface ");
2624 break;
2625 }
2626 case CISTPL_FUNCE_IDE_MASTER:
2627 case CISTPL_FUNCE_IDE_SLAVE:
2628 { uchar f1 = *(p+2);
2629 uchar f2 = *(p+4);
2630
2631 puts ((f1 & CISTPL_IDE_SILICON) ? " [silicon]" : " [rotating]");
2632
2633 if (f1 & CISTPL_IDE_UNIQUE)
2634 puts (" [unique]");
2635
2636 puts ((f1 & CISTPL_IDE_DUAL) ? " [dual]" : " [single]");
2637
2638 if (f2 & CISTPL_IDE_HAS_SLEEP)
2639 puts (" [sleep]");
2640
2641 if (f2 & CISTPL_IDE_HAS_STANDBY)
2642 puts (" [standby]");
2643
2644 if (f2 & CISTPL_IDE_HAS_IDLE)
2645 puts (" [idle]");
2646
2647 if (f2 & CISTPL_IDE_LOW_POWER)
2648 puts (" [low power]");
2649
2650 if (f2 & CISTPL_IDE_REG_INHIBIT)
2651 puts (" [reg inhibit]");
2652
2653 if (f2 & CISTPL_IDE_HAS_INDEX)
2654 puts (" [index]");
2655
2656 if (f2 & CISTPL_IDE_IOIS16)
2657 puts (" [IOis16]");
2658
2659 break;
2660 }
2661 }
2662 putc ('\n');
2663}
2664#endif /* CONFIG_IDE_8xx_PCCARD */
2665
wdenk90e7e422002-12-04 23:39:58 +00002666/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00002667
wdenk634d2f72004-04-15 23:14:49 +00002668#if defined(CONFIG_IDE_8xx_PCCARD) || defined(CONFIG_PXA_PCMCIA)
wdenkc6097192002-11-03 00:24:07 +00002669
2670#define MAX_IDENT_CHARS 64
2671#define MAX_IDENT_FIELDS 4
2672
2673static uchar *known_cards[] = {
2674 "ARGOSY PnPIDE D5",
2675 NULL
2676};
2677
2678static int identify (volatile uchar *p)
2679{
2680 uchar id_str[MAX_IDENT_CHARS];
2681 uchar data;
2682 uchar *t;
2683 uchar **card;
2684 int i, done;
2685
2686 if (p == NULL)
2687 return (0); /* Don't know */
2688
2689 t = id_str;
2690 done =0;
2691
2692 for (i=0; i<=4 && !done; ++i, p+=2) {
2693 while ((data = *p) != '\0') {
2694 if (data == 0xFF) {
2695 done = 1;
2696 break;
2697 }
2698 *t++ = data;
2699 if (t == &id_str[MAX_IDENT_CHARS-1]) {
2700 done = 1;
2701 break;
2702 }
2703 p += 2;
2704 }
2705 if (!done)
2706 *t++ = ' ';
2707 }
2708 *t = '\0';
2709 while (--t > id_str) {
2710 if (*t == ' ')
2711 *t = '\0';
2712 else
2713 break;
2714 }
2715 puts (id_str);
2716 putc ('\n');
2717
2718 for (card=known_cards; *card; ++card) {
2719 debug ("## Compare against \"%s\"\n", *card);
2720 if (strcmp(*card, id_str) == 0) { /* found! */
2721 debug ("## CARD FOUND ##\n");
2722 return (1);
2723 }
2724 }
2725
2726 return (0); /* don't know */
2727}
2728#endif /* CONFIG_IDE_8xx_PCCARD */
2729
wdenk90e7e422002-12-04 23:39:58 +00002730/* -------------------------------------------------------------------- */
wdenk3902d702004-04-15 18:22:41 +00002731/* NETTA board by Intracom S.A. */
2732/* -------------------------------------------------------------------- */
2733
2734#if defined(CONFIG_NETTA)
2735
2736/* some sane bit macros */
2737#define _BD(_b) (1U << (31-(_b)))
2738#define _BDR(_l, _h) (((((1U << (31-(_l))) - 1) << 1) | 1) & ~((1U << (31-(_h))) - 1))
2739
2740#define _BW(_b) (1U << (15-(_b)))
2741#define _BWR(_l, _h) (((((1U << (15-(_l))) - 1) << 1) | 1) & ~((1U << (15-(_h))) - 1))
2742
2743#define _BB(_b) (1U << (7-(_b)))
2744#define _BBR(_l, _h) (((((1U << (7-(_l))) - 1) << 1) | 1) & ~((1U << (7-(_h))) - 1))
2745
2746#define _B(_b) _BD(_b)
2747#define _BR(_l, _h) _BDR(_l, _h)
2748
2749#define PCMCIA_BOARD_MSG "NETTA"
2750
2751static const unsigned short vppd_masks[2] = { _BW(14), _BW(15) };
2752
2753static void cfg_vppd(int no)
2754{
2755 volatile immap_t *immap = (immap_t *)CFG_IMMR;
2756 unsigned short mask;
2757
2758 if ((unsigned int)no >= sizeof(vppd_masks)/sizeof(vppd_masks[0]))
2759 return;
2760
2761 mask = vppd_masks[no];
2762
2763 immap->im_ioport.iop_papar &= ~mask;
2764 immap->im_ioport.iop_paodr &= ~mask;
2765 immap->im_ioport.iop_padir |= mask;
2766}
2767
2768static void set_vppd(int no, int what)
2769{
2770 volatile immap_t *immap = (immap_t *)CFG_IMMR;
2771 unsigned short mask;
2772
2773 if ((unsigned int)no >= sizeof(vppd_masks)/sizeof(vppd_masks[0]))
2774 return;
2775
2776 mask = vppd_masks[no];
2777
2778 if (what)
2779 immap->im_ioport.iop_padat |= mask;
2780 else
2781 immap->im_ioport.iop_padat &= ~mask;
2782}
2783
2784static const unsigned short vccd_masks[2] = { _BW(10), _BW(6) };
2785
2786static void cfg_vccd(int no)
2787{
2788 volatile immap_t *immap = (immap_t *)CFG_IMMR;
2789 unsigned short mask;
2790
2791 if ((unsigned int)no >= sizeof(vccd_masks)/sizeof(vccd_masks[0]))
2792 return;
2793
2794 mask = vccd_masks[no];
2795
2796 immap->im_ioport.iop_papar &= ~mask;
2797 immap->im_ioport.iop_paodr &= ~mask;
2798 immap->im_ioport.iop_padir |= mask;
2799}
2800
2801static void set_vccd(int no, int what)
2802{
2803 volatile immap_t *immap = (immap_t *)CFG_IMMR;
2804 unsigned short mask;
2805
2806 if ((unsigned int)no >= sizeof(vccd_masks)/sizeof(vccd_masks[0]))
2807 return;
2808
2809 mask = vccd_masks[no];
2810
2811 if (what)
2812 immap->im_ioport.iop_padat |= mask;
2813 else
2814 immap->im_ioport.iop_padat &= ~mask;
2815}
2816
2817static const unsigned short oc_mask = _BW(8);
2818
2819static void cfg_oc(void)
2820{
2821 volatile immap_t *immap = (immap_t *)CFG_IMMR;
2822 unsigned short mask = oc_mask;
2823
2824 immap->im_ioport.iop_pcdir &= ~mask;
2825 immap->im_ioport.iop_pcso &= ~mask;
2826 immap->im_ioport.iop_pcint &= ~mask;
2827 immap->im_ioport.iop_pcpar &= ~mask;
2828}
2829
2830static int get_oc(void)
2831{
2832 volatile immap_t *immap = (immap_t *)CFG_IMMR;
2833 unsigned short mask = oc_mask;
2834 int what;
2835
2836 what = !!(immap->im_ioport.iop_pcdat & mask);;
2837 return what;
2838}
2839
2840static const unsigned short shdn_mask = _BW(12);
2841
2842static void cfg_shdn(void)
2843{
2844 volatile immap_t *immap = (immap_t *)CFG_IMMR;
2845 unsigned short mask;
2846
2847 mask = shdn_mask;
2848
2849 immap->im_ioport.iop_papar &= ~mask;
2850 immap->im_ioport.iop_paodr &= ~mask;
2851 immap->im_ioport.iop_padir |= mask;
2852}
2853
2854static void set_shdn(int what)
2855{
2856 volatile immap_t *immap = (immap_t *)CFG_IMMR;
2857 unsigned short mask;
2858
2859 mask = shdn_mask;
2860
2861 if (what)
2862 immap->im_ioport.iop_padat |= mask;
2863 else
2864 immap->im_ioport.iop_padat &= ~mask;
2865}
2866
2867static void cfg_ports (void);
2868
2869static int hardware_enable(int slot)
2870{
2871 volatile immap_t *immap;
2872 volatile cpm8xx_t *cp;
2873 volatile pcmconf8xx_t *pcmp;
2874 volatile sysconf8xx_t *sysp;
2875 uint reg, pipr, mask;
2876 int i;
2877
2878 debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
2879
2880 udelay(10000);
2881
2882 immap = (immap_t *)CFG_IMMR;
2883 sysp = (sysconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_siu_conf));
2884 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
2885 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
2886
2887 /* Configure Ports for TPS2211A PC-Card Power-Interface Switch */
2888 cfg_ports ();
2889
2890 /* clear interrupt state, and disable interrupts */
2891 pcmp->pcmc_pscr = PCMCIA_MASK(_slot_);
2892 pcmp->pcmc_per &= ~PCMCIA_MASK(_slot_);
2893
2894 /*
2895 * Disable interrupts, DMA, and PCMCIA buffers
2896 * (isolate the interface) and assert RESET signal
2897 */
2898 debug ("Disable PCMCIA buffers and assert RESET\n");
2899 reg = 0;
2900 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
2901 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
2902 PCMCIA_PGCRX(_slot_) = reg;
2903
2904 udelay(500);
2905
2906 /*
2907 * Make sure there is a card in the slot, then configure the interface.
2908 */
2909 udelay(10000);
2910 debug ("[%d] %s: PIPR(%p)=0x%x\n",
2911 __LINE__,__FUNCTION__,
2912 &(pcmp->pcmc_pipr),pcmp->pcmc_pipr);
2913 if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) {
2914 printf (" No Card found\n");
2915 return (1);
2916 }
2917
2918 /*
2919 * Power On: Set VAVCC to 3.3V or 5V, set VAVPP to Hi-Z
2920 */
2921 mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot);
2922 pipr = pcmp->pcmc_pipr;
2923 debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n",
2924 pipr,
2925 (reg&PCMCIA_VS1(slot))?"n":"ff",
2926 (reg&PCMCIA_VS2(slot))?"n":"ff");
2927
2928 if ((pipr & mask) == mask) {
2929 set_vppd(0, 1); set_vppd(1, 1); /* VAVPP => Hi-Z */
2930 set_vccd(0, 0); set_vccd(1, 1); /* 5V on, 3V off */
2931 puts (" 5.0V card found: ");
2932 } else {
2933 set_vppd(0, 1); set_vppd(1, 1); /* VAVPP => Hi-Z */
2934 set_vccd(0, 1); set_vccd(1, 0); /* 5V off, 3V on */
2935 puts (" 3.3V card found: ");
2936 }
2937
2938 /* Wait 500 ms; use this to check for over-current */
2939 for (i=0; i<5000; ++i) {
2940 if (!get_oc()) {
2941 printf (" *** Overcurrent - Safety shutdown ***\n");
2942 set_vccd(0, 0); set_vccd(1, 0); /* VAVPP => Hi-Z */
2943 return (1);
2944 }
2945 udelay (100);
2946 }
2947
2948 debug ("Enable PCMCIA buffers and stop RESET\n");
2949 reg = PCMCIA_PGCRX(_slot_);
2950 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
2951 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
2952 PCMCIA_PGCRX(_slot_) = reg;
2953
2954 udelay(250000); /* some cards need >150 ms to come up :-( */
2955
2956 debug ("# hardware_enable done\n");
2957
2958 return (0);
2959}
2960
2961
2962#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
2963static int hardware_disable(int slot)
2964{
2965 volatile immap_t *immap;
2966 volatile pcmconf8xx_t *pcmp;
2967 u_long reg;
2968
2969 debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
2970
2971 immap = (immap_t *)CFG_IMMR;
2972 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
2973
2974 /* Configure PCMCIA General Control Register */
2975 debug ("Disable PCMCIA buffers and assert RESET\n");
2976 reg = 0;
2977 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
2978 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
2979 PCMCIA_PGCRX(_slot_) = reg;
2980
2981 /* All voltages off / Hi-Z */
2982 set_vppd(0, 1); set_vppd(1, 1);
2983 set_vccd(0, 1); set_vccd(1, 1);
2984
2985 udelay(10000);
2986
2987 return (0);
2988}
2989#endif /* CFG_CMD_PCMCIA */
2990
2991
2992static int voltage_set(int slot, int vcc, int vpp)
2993{
2994 volatile immap_t *immap;
2995 volatile cpm8xx_t *cp;
2996 volatile pcmconf8xx_t *pcmp;
2997 u_long reg;
2998 ushort sreg;
2999
3000 debug ("voltage_set: "
3001 PCMCIA_BOARD_MSG
3002 " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n",
3003 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10);
3004
3005 immap = (immap_t *)CFG_IMMR;
3006 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
3007 pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
3008 /*
3009 * Disable PCMCIA buffers (isolate the interface)
3010 * and assert RESET signal
3011 */
3012 debug ("Disable PCMCIA buffers and assert RESET\n");
3013 reg = PCMCIA_PGCRX(_slot_);
3014 reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */
3015 reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */
3016 PCMCIA_PGCRX(_slot_) = reg;
3017 udelay(500);
3018
3019 /*
3020 * Configure Port C pins for
3021 * 5 Volts Enable and 3 Volts enable,
3022 * Turn all power pins to Hi-Z
3023 */
3024 debug ("PCMCIA power OFF\n");
3025 cfg_ports (); /* Enables switch, but all in Hi-Z */
3026
3027 sreg = immap->im_ioport.iop_pcdat;
3028 set_vppd(0, 1); set_vppd(1, 1);
3029
3030 switch(vcc) {
3031 case 0:
3032 break; /* Switch off */
3033
3034 case 33:
3035 set_vccd(0, 1); set_vccd(1, 0);
3036 break;
3037
3038 case 50:
3039 set_vccd(0, 0); set_vccd(1, 1);
3040 break;
3041
3042 default:
3043 goto done;
3044 }
3045
3046 /* Checking supported voltages */
3047
3048 debug ("PIPR: 0x%x --> %s\n",
3049 pcmp->pcmc_pipr,
3050 (pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
3051
3052done:
3053 debug ("Enable PCMCIA buffers and stop RESET\n");
3054 reg = PCMCIA_PGCRX(_slot_);
3055 reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */
3056 reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */
3057 PCMCIA_PGCRX(_slot_) = reg;
3058 udelay(500);
3059
3060 debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n",
3061 slot+'A');
3062 return (0);
3063}
3064
3065static void cfg_ports (void)
3066{
3067 volatile immap_t *immap;
3068 volatile cpm8xx_t *cp;
3069
3070 immap = (immap_t *)CFG_IMMR;
3071 cp = (cpm8xx_t *)(&(((immap_t *)CFG_IMMR)->im_cpm));
3072
3073
3074 cfg_vppd(0); cfg_vppd(1); /* VPPD0,VPPD1 VAVPP => Hi-Z */
3075 cfg_vccd(0); cfg_vccd(1); /* 3V and 5V off */
3076 cfg_shdn();
3077 cfg_oc();
3078
3079 /*
3080 * Configure Port A for TPS2211 PC-Card Power-Interface Switch
3081 *
3082 * Switch off all voltages, assert shutdown
3083 */
3084 set_vppd(0, 1); set_vppd(1, 1);
3085 set_vccd(0, 0); set_vccd(1, 0);
3086 set_shdn(1);
3087
3088 udelay(100000);
3089}
3090
3091#endif /* NETTA */
3092
3093
3094/* -------------------------------------------------------------------- */
wdenkc6097192002-11-03 00:24:07 +00003095
3096#endif /* CFG_CMD_PCMCIA || (CFG_CMD_IDE && CONFIG_IDE_8xx_PCCARD) */
wdenk57b2d802003-06-27 21:31:46 +00003097
3098/**************************************************/
3099
3100#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
wdenkf287a242003-07-01 21:06:45 +00003101U_BOOT_CMD(
3102 pinit, 2, 1, do_pinit,
wdenk57b2d802003-06-27 21:31:46 +00003103 "pinit - PCMCIA sub-system\n",
3104 "on - power on PCMCIA socket\n"
3105 "pinit off - power off PCMCIA socket\n"
3106);
3107#endif