Blame view

common/cmd_pcmcia.c 7.19 KB
c609719b8   wdenk   Initial revision
1
  /*
8cba090c5   Wolfgang Denk   Add support for V...
2
   * (C) Copyright 2000-2006
c609719b8   wdenk   Initial revision
3
4
   * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
   *
1a4596601   Wolfgang Denk   Add GPL-2.0+ SPDX...
5
   * SPDX-License-Identifier:	GPL-2.0+
c609719b8   wdenk   Initial revision
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
   *
   ********************************************************************
   *
   * Lots of code copied from:
   *
   * m8xx_pcmcia.c - Linux PCMCIA socket driver for the mpc8xx series.
   * (C) 1999-2000 Magnus Damm <damm@bitsmart.com>
   *
   * "The ExCA standard specifies that socket controllers should provide
   * two IO and five memory windows per socket, which can be independently
   * configured and positioned in the host address space and mapped to
   * arbitrary segments of card address space. " - David A Hinds. 1999
   *
   * This controller does _not_ meet the ExCA standard.
   *
   * m8xx pcmcia controller brief info:
   * + 8 windows (attrib, mem, i/o)
   * + up to two slots (SLOT_A and SLOT_B)
   * + inputpins, outputpins, event and mask registers.
   * - no offset register. sigh.
   *
   * Because of the lacking offset register we must map the whole card.
   * We assign each memory window PCMCIA_MEM_WIN_SIZE address space.
   * Make sure there is (PCMCIA_MEM_WIN_SIZE * PCMCIA_MEM_WIN_NO
   * * PCMCIA_SOCKETS_NO) bytes at PCMCIA_MEM_WIN_BASE.
   * The i/o windows are dynamically allocated at PCMCIA_IO_WIN_BASE.
   * They are maximum 64KByte each...
   */
  
  /* #define DEBUG	1	*/
  
  /*
   * PCMCIA support
   */
  #include <common.h>
  #include <command.h>
  #include <config.h>
  #include <pcmcia.h>
e2ffd59b4   wdenk   * Code cleanup, m...
44
  #include <asm/io.h>
1f53a4160   wdenk   Add LED indicatio...
45
  /* -------------------------------------------------------------------- */
c609719b8   wdenk   Initial revision
46

fd9bcaa35   Jon Loeliger   common/cmd_[p-x]*...
47
  #if defined(CONFIG_CMD_PCMCIA)
db01a2ea9   wdenk   * Patch by Stephe...
48

9d4079955   Wolfgang Denk   Major PCMCIA Clea...
49
50
  extern int pcmcia_on (void);
  extern int pcmcia_off (void);
c609719b8   wdenk   Initial revision
51

54841ab50   Wolfgang Denk   Make sure that ar...
52
  int do_pinit (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
c609719b8   wdenk   Initial revision
53
54
55
56
57
58
59
60
61
  {
  	int rcode = 0;
  
  	if (argc != 2) {
  		printf ("Usage: pinit {on | off}
  ");
  		return 1;
  	}
  	if (strcmp(argv[1],"on") == 0) {
9d4079955   Wolfgang Denk   Major PCMCIA Clea...
62
  		rcode = pcmcia_on ();
c609719b8   wdenk   Initial revision
63
64
65
66
67
68
69
70
71
72
  	} else if (strcmp(argv[1],"off") == 0) {
  		rcode = pcmcia_off ();
  	} else {
  		printf ("Usage: pinit {on | off}
  ");
  		return 1;
  	}
  
  	return rcode;
  }
66fd3d1ce   wdenk   Add support for C...
73

9d4079955   Wolfgang Denk   Major PCMCIA Clea...
74
  U_BOOT_CMD(
9912121f7   Detlev Zundel   Change 'repeatabl...
75
  	pinit,	2,	0,	do_pinit,
2fb2604d5   Peter Tyser   Command usage cle...
76
  	"PCMCIA sub-system",
9d4079955   Wolfgang Denk   Major PCMCIA Clea...
77
78
  	"on  - power on PCMCIA socket
  "
a89c33db9   Wolfgang Denk   General help mess...
79
80
  	"pinit off - power off PCMCIA socket"
  );
66fd3d1ce   wdenk   Add support for C...
81

fd9bcaa35   Jon Loeliger   common/cmd_[p-x]*...
82
  #endif
66fd3d1ce   wdenk   Add support for C...
83

9d4079955   Wolfgang Denk   Major PCMCIA Clea...
84
  /* -------------------------------------------------------------------- */
66fd3d1ce   wdenk   Add support for C...
85

9d4079955   Wolfgang Denk   Major PCMCIA Clea...
86
  #undef	CHECK_IDE_DEVICE
db01a2ea9   wdenk   * Patch by Stephe...
87

fd9bcaa35   Jon Loeliger   common/cmd_[p-x]*...
88
  #if defined(CONFIG_CMD_IDE) && defined(CONFIG_IDE_8xx_PCCARD)
9d4079955   Wolfgang Denk   Major PCMCIA Clea...
89
  #define	CHECK_IDE_DEVICE
a6cccaea5   wdenk   * Patch by Wolter...
90
  #endif
9d4079955   Wolfgang Denk   Major PCMCIA Clea...
91
92
93
  
  #if	defined(CONFIG_PXA_PCMCIA)
  #define	CHECK_IDE_DEVICE
c609719b8   wdenk   Initial revision
94
  #endif
9d4079955   Wolfgang Denk   Major PCMCIA Clea...
95
  #ifdef	CHECK_IDE_DEVICE
c609719b8   wdenk   Initial revision
96

9d4079955   Wolfgang Denk   Major PCMCIA Clea...
97
98
99
100
101
  int		ide_devices_found;
  static uchar	*known_cards[] = {
  	(uchar *)"ARGOSY PnPIDE D5",
  	NULL
  };
c609719b8   wdenk   Initial revision
102

9d4079955   Wolfgang Denk   Major PCMCIA Clea...
103
104
  #define	MAX_TUPEL_SZ	512
  #define MAX_FEATURES	4
c609719b8   wdenk   Initial revision
105

9d4079955   Wolfgang Denk   Major PCMCIA Clea...
106
107
  #define MAX_IDENT_CHARS		64
  #define	MAX_IDENT_FIELDS	4
c609719b8   wdenk   Initial revision
108

9d4079955   Wolfgang Denk   Major PCMCIA Clea...
109
  #define	indent	"\t   "
c609719b8   wdenk   Initial revision
110

9d4079955   Wolfgang Denk   Major PCMCIA Clea...
111
112
113
114
115
116
  static void print_funcid (int func)
  {
  	puts (indent);
  	switch (func) {
  		case CISTPL_FUNCID_MULTI:
  			puts (" Multi-Function");
a6cccaea5   wdenk   * Patch by Wolter...
117
  			break;
9d4079955   Wolfgang Denk   Major PCMCIA Clea...
118
119
  		case CISTPL_FUNCID_MEMORY:
  			puts (" Memory");
c609719b8   wdenk   Initial revision
120
  			break;
9d4079955   Wolfgang Denk   Major PCMCIA Clea...
121
122
  		case CISTPL_FUNCID_SERIAL:
  			puts (" Serial Port");
c609719b8   wdenk   Initial revision
123
  			break;
9d4079955   Wolfgang Denk   Major PCMCIA Clea...
124
125
  		case CISTPL_FUNCID_PARALLEL:
  			puts (" Parallel Port");
c609719b8   wdenk   Initial revision
126
  			break;
9d4079955   Wolfgang Denk   Major PCMCIA Clea...
127
128
  		case CISTPL_FUNCID_FIXED:
  			puts (" Fixed Disk");
7cb22f97e   wdenk   * Make CPU clock ...
129
  			break;
9d4079955   Wolfgang Denk   Major PCMCIA Clea...
130
131
132
133
134
135
136
137
138
139
140
141
142
143
  		case CISTPL_FUNCID_VIDEO:
  			puts (" Video Adapter");
  			break;
  		case CISTPL_FUNCID_NETWORK:
  			puts (" Network Adapter");
  			break;
  		case CISTPL_FUNCID_AIMS:
  			puts (" AIMS Card");
  			break;
  		case CISTPL_FUNCID_SCSI:
  			puts (" SCSI Adapter");
  			break;
  		default:
  			puts (" Unknown");
c609719b8   wdenk   Initial revision
144
  			break;
ea909b760   wdenk   * Added support f...
145
  	}
9d4079955   Wolfgang Denk   Major PCMCIA Clea...
146
147
  	puts (" Card
  ");
db01a2ea9   wdenk   * Patch by Stephe...
148
  }
9d4079955   Wolfgang Denk   Major PCMCIA Clea...
149
  static void print_fixed (volatile uchar *p)
db01a2ea9   wdenk   * Patch by Stephe...
150
  {
9d4079955   Wolfgang Denk   Major PCMCIA Clea...
151
152
  	if (p == NULL)
  		return;
db01a2ea9   wdenk   * Patch by Stephe...
153

9d4079955   Wolfgang Denk   Major PCMCIA Clea...
154
  	puts(indent);
db01a2ea9   wdenk   * Patch by Stephe...
155

9d4079955   Wolfgang Denk   Major PCMCIA Clea...
156
157
158
  	switch (*p) {
  		case CISTPL_FUNCE_IDE_IFACE:
  		{   uchar iface = *(p+2);
db01a2ea9   wdenk   * Patch by Stephe...
159

9d4079955   Wolfgang Denk   Major PCMCIA Clea...
160
161
162
163
164
165
166
167
  		puts ((iface == CISTPL_IDE_INTERFACE) ? " IDE" : " unknown");
  		puts (" interface ");
  		break;
  		}
  		case CISTPL_FUNCE_IDE_MASTER:
  		case CISTPL_FUNCE_IDE_SLAVE:
  		{   uchar f1 = *(p+2);
  		uchar f2 = *(p+4);
db01a2ea9   wdenk   * Patch by Stephe...
168

9d4079955   Wolfgang Denk   Major PCMCIA Clea...
169
  		puts ((f1 & CISTPL_IDE_SILICON) ? " [silicon]" : " [rotating]");
db01a2ea9   wdenk   * Patch by Stephe...
170

9d4079955   Wolfgang Denk   Major PCMCIA Clea...
171
172
  		if (f1 & CISTPL_IDE_UNIQUE)
  			puts (" [unique]");
db01a2ea9   wdenk   * Patch by Stephe...
173

9d4079955   Wolfgang Denk   Major PCMCIA Clea...
174
  		puts ((f1 & CISTPL_IDE_DUAL) ? " [dual]" : " [single]");
db01a2ea9   wdenk   * Patch by Stephe...
175

9d4079955   Wolfgang Denk   Major PCMCIA Clea...
176
177
  		if (f2 & CISTPL_IDE_HAS_SLEEP)
  			puts (" [sleep]");
db01a2ea9   wdenk   * Patch by Stephe...
178

9d4079955   Wolfgang Denk   Major PCMCIA Clea...
179
180
  		if (f2 & CISTPL_IDE_HAS_STANDBY)
  			puts (" [standby]");
db01a2ea9   wdenk   * Patch by Stephe...
181

9d4079955   Wolfgang Denk   Major PCMCIA Clea...
182
183
  		if (f2 & CISTPL_IDE_HAS_IDLE)
  			puts (" [idle]");
db01a2ea9   wdenk   * Patch by Stephe...
184

9d4079955   Wolfgang Denk   Major PCMCIA Clea...
185
186
  		if (f2 & CISTPL_IDE_LOW_POWER)
  			puts (" [low power]");
c609719b8   wdenk   Initial revision
187

9d4079955   Wolfgang Denk   Major PCMCIA Clea...
188
189
  		if (f2 & CISTPL_IDE_REG_INHIBIT)
  			puts (" [reg inhibit]");
c609719b8   wdenk   Initial revision
190

9d4079955   Wolfgang Denk   Major PCMCIA Clea...
191
192
  		if (f2 & CISTPL_IDE_HAS_INDEX)
  			puts (" [index]");
66fd3d1ce   wdenk   Add support for C...
193

9d4079955   Wolfgang Denk   Major PCMCIA Clea...
194
195
  		if (f2 & CISTPL_IDE_IOIS16)
  			puts (" [IOis16]");
66fd3d1ce   wdenk   Add support for C...
196

9d4079955   Wolfgang Denk   Major PCMCIA Clea...
197
198
199
200
201
  		break;
  		}
  	}
  	putc ('
  ');
66fd3d1ce   wdenk   Add support for C...
202
  }
db01a2ea9   wdenk   * Patch by Stephe...
203

9d4079955   Wolfgang Denk   Major PCMCIA Clea...
204
  static int identify  (volatile uchar *p)
c609719b8   wdenk   Initial revision
205
  {
9d4079955   Wolfgang Denk   Major PCMCIA Clea...
206
207
208
209
210
  	uchar id_str[MAX_IDENT_CHARS];
  	uchar data;
  	uchar *t;
  	uchar **card;
  	int i, done;
c609719b8   wdenk   Initial revision
211

9d4079955   Wolfgang Denk   Major PCMCIA Clea...
212
213
  	if (p == NULL)
  		return (0);	/* Don't know */
c609719b8   wdenk   Initial revision
214

9d4079955   Wolfgang Denk   Major PCMCIA Clea...
215
216
  	t = id_str;
  	done =0;
c609719b8   wdenk   Initial revision
217

9d4079955   Wolfgang Denk   Major PCMCIA Clea...
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
  	for (i=0; i<=4 && !done; ++i, p+=2) {
  		while ((data = *p) != '\0') {
  			if (data == 0xFF) {
  				done = 1;
  				break;
  			}
  			*t++ = data;
  			if (t == &id_str[MAX_IDENT_CHARS-1]) {
  				done = 1;
  				break;
  			}
  			p += 2;
  		}
  		if (!done)
  			*t++ = ' ';
c609719b8   wdenk   Initial revision
233
  	}
9d4079955   Wolfgang Denk   Major PCMCIA Clea...
234
235
236
237
238
239
240
241
242
243
  	*t = '\0';
  	while (--t > id_str) {
  		if (*t == ' ')
  			*t = '\0';
  		else
  			break;
  	}
  	puts ((char *)id_str);
  	putc ('
  ');
c609719b8   wdenk   Initial revision
244

9d4079955   Wolfgang Denk   Major PCMCIA Clea...
245
246
247
248
249
250
251
252
253
  	for (card=known_cards; *card; ++card) {
  		debug ("## Compare against \"%s\"
  ", *card);
  		if (strcmp((char *)*card, (char *)id_str) == 0) {	/* found! */
  			debug ("## CARD FOUND ##
  ");
  			return (1);
  		}
  	}
c609719b8   wdenk   Initial revision
254

9d4079955   Wolfgang Denk   Major PCMCIA Clea...
255
  	return (0);	/* don't know */
db01a2ea9   wdenk   * Patch by Stephe...
256
  }
c609719b8   wdenk   Initial revision
257

9d4079955   Wolfgang Denk   Major PCMCIA Clea...
258
  int check_ide_device (int slot)
c609719b8   wdenk   Initial revision
259
260
261
  {
  	volatile uchar *ident = NULL;
  	volatile uchar *feature_p[MAX_FEATURES];
ea909b760   wdenk   * Added support f...
262
  	volatile uchar *p, *start, *addr;
c609719b8   wdenk   Initial revision
263
264
265
266
267
268
  	int n_features = 0;
  	uchar func_id = ~0;
  	uchar code, len;
  	ushort config_base = 0;
  	int found = 0;
  	int i;
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
269
270
  	addr = (volatile uchar *)(CONFIG_SYS_PCMCIA_MEM_ADDR +
  				  CONFIG_SYS_PCMCIA_MEM_SIZE * (slot * 4));
d0fb80c30   wdenk   * Restrict baudra...
271
272
  	debug ("PCMCIA MEM: %08lX
  ", (ulong)addr);
c609719b8   wdenk   Initial revision
273

ea909b760   wdenk   * Added support f...
274
  	start = p = (volatile uchar *) addr;
c609719b8   wdenk   Initial revision
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
  
  	while ((p - start) < MAX_TUPEL_SZ) {
  
  		code = *p; p += 2;
  
  		if (code == 0xFF) { /* End of chain */
  			break;
  		}
  
  		len = *p; p += 2;
  #if defined(DEBUG) && (DEBUG > 1)
  		{ volatile uchar *q = p;
  			printf ("
  Tuple code %02x  length %d
  \tData:",
  				code, len);
  
  			for (i = 0; i < len; ++i) {
  				printf (" %02x", *q);
  				q+= 2;
  			}
  		}
  #endif	/* DEBUG */
  		switch (code) {
  		case CISTPL_VERS_1:
  			ident = p + 4;
  			break;
  		case CISTPL_FUNCID:
  			/* Fix for broken SanDisk which may have 0x80 bit set */
  			func_id = *p & 0x7F;
  			break;
  		case CISTPL_FUNCE:
  			if (n_features < MAX_FEATURES)
  				feature_p[n_features++] = p;
  			break;
  		case CISTPL_CONFIG:
  			config_base = (*(p+6) << 8) + (*(p+4));
  			debug ("
  ## Config_base = %04x ###
  ", config_base);
  		default:
  			break;
  		}
  		p += 2 * len;
  	}
  
  	found = identify (ident);
  
  	if (func_id != ((uchar)~0)) {
  		print_funcid (func_id);
  
  		if (func_id == CISTPL_FUNCID_FIXED)
  			found = 1;
  		else
  			return (1);	/* no disk drive */
  	}
  
  	for (i=0; i<n_features; ++i) {
  		print_fixed (feature_p[i]);
  	}
  
  	if (!found) {
  		printf ("unknown card type
  ");
  		return (1);
  	}
6069ff265   wdenk   * Add support for...
341
  	ide_devices_found |= (1 << slot);
e2ffd59b4   wdenk   * Code cleanup, m...
342
343
  #if CONFIG_CPC45
  #else
c609719b8   wdenk   Initial revision
344
  	/* set I/O area in config reg -> only valid for ARGOSY D5!!! */
ea909b760   wdenk   * Added support f...
345
  	*((uchar *)(addr + config_base)) = 1;
e2ffd59b4   wdenk   * Code cleanup, m...
346
347
348
349
350
351
352
353
354
355
356
357
358
359
  #endif
  #if 0
  	printf("
  ## Config_base = %04x ###
  ", config_base);
  	printf("Configuration Option Register: %02x @ %x
  ", readb(addr + config_base), addr + config_base);
  	printf("Card Configuration and Status Register: %02x
  ", readb(addr + config_base + 2));
  	printf("Pin Replacement Register Register: %02x
  ", readb(addr + config_base + 4));
  	printf("Socket and Copy Register: %02x
  ", readb(addr + config_base + 6));
  #endif
c609719b8   wdenk   Initial revision
360
361
  	return (0);
  }
c609719b8   wdenk   Initial revision
362

9d4079955   Wolfgang Denk   Major PCMCIA Clea...
363
  #endif	/* CHECK_IDE_DEVICE */