]>
Commit | Line | Data |
---|---|---|
d69b100e | 1 | /* |
c2642d14 | 2 | * (C) Copyright 2002-2004 |
d69b100e SR |
3 | * Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.com |
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 | #include <common.h> | |
8bde7f77 | 25 | #include <command.h> |
d69b100e SR |
26 | #include <malloc.h> |
27 | #include <net.h> | |
28 | #include <asm/io.h> | |
29 | #include <pci.h> | |
3048bcbf | 30 | #include <asm/4xx_pci.h> |
c2642d14 | 31 | #include <asm/processor.h> |
d69b100e SR |
32 | |
33 | #include "pci405.h" | |
34 | ||
35 | ||
b9307262 | 36 | #if defined(CONFIG_CMD_BSP) |
d69b100e SR |
37 | |
38 | extern int do_bootm (cmd_tbl_t *, int, int, char *[]); | |
c2642d14 SR |
39 | extern int do_bootvx (cmd_tbl_t *, int, int, char *[]); |
40 | unsigned long get_dcr(unsigned short); | |
d69b100e | 41 | |
d69b100e | 42 | |
d69b100e SR |
43 | /* |
44 | * Command loadpci: wait for signal from host and boot image. | |
45 | */ | |
46 | int do_loadpci(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) | |
47 | { | |
48 | unsigned int *ptr = 0; | |
49 | int count = 0; | |
50 | int count2 = 0; | |
51 | int status; | |
52 | int i; | |
53 | char addr[16]; | |
54 | char str[] = "\\|/-"; | |
55 | char *local_args[2]; | |
56 | ||
d69b100e SR |
57 | /* |
58 | * Mark sync address | |
59 | */ | |
60 | ptr = 0; | |
61 | *ptr = 0xffffffff; | |
62 | puts("\nWaiting for image from pci host -"); | |
63 | ||
64 | /* | |
65 | * Wait for host to write the start address | |
66 | */ | |
67 | while (*ptr == 0xffffffff) { | |
68 | count++; | |
69 | if (!(count % 100)) { | |
70 | count2++; | |
71 | putc(0x08); /* backspace */ | |
72 | putc(str[count2 % 4]); | |
73 | } | |
74 | ||
75 | /* Abort if ctrl-c was pressed */ | |
76 | if (ctrlc()) { | |
77 | puts("\nAbort\n"); | |
78 | return 0; | |
79 | } | |
80 | ||
81 | udelay(1000); | |
82 | } | |
83 | ||
84 | if (*ptr == PCI_RECONFIG_MAGIC) { | |
85 | /* | |
86 | * Save own pci configuration in PRAM | |
87 | */ | |
88 | memset((char *)PCI_REGS_ADDR, 0, PCI_REGS_LEN); | |
89 | ptr = (unsigned int *)PCI_REGS_ADDR + 1; | |
90 | for (i=0; i<0x40; i+=4) { | |
91 | pci_read_config_dword(PCIDEVID_405GP, i, ptr++); | |
92 | } | |
93 | ptr = (unsigned int *)PCI_REGS_ADDR; | |
77ddac94 | 94 | *ptr = crc32(0, (uchar *)PCI_REGS_ADDR+4, PCI_REGS_LEN-4); |
d69b100e SR |
95 | |
96 | printf("\nStoring PCI Configuration Regs...\n"); | |
97 | } else { | |
98 | sprintf(addr, "%08x", *ptr); | |
38718425 | 99 | |
c2642d14 | 100 | #if 0 |
d69b100e SR |
101 | /* |
102 | * Boot image | |
103 | */ | |
c2642d14 SR |
104 | if (*ptr & 0x00000001) { |
105 | /* | |
106 | * Boot VxWorks image via bootvx | |
107 | */ | |
108 | addr[strlen(addr)-1] = '0'; | |
109 | printf("\nBooting VxWorks-Image at addr 0x%s ...\n", addr); | |
110 | setenv("loadaddr", addr); | |
111 | ||
112 | local_args[0] = argv[0]; | |
113 | local_args[1] = NULL; | |
114 | status = do_bootvx (cmdtp, 0, 1, local_args); | |
115 | } else { | |
116 | /* | |
117 | * Boot image via bootm (normally Linux) | |
118 | */ | |
119 | printf("\nBooting Image at addr 0x%s ...\n", addr); | |
120 | setenv("loadaddr", addr); | |
121 | ||
122 | local_args[0] = argv[0]; | |
123 | local_args[1] = NULL; | |
124 | status = do_bootm (cmdtp, 0, 1, local_args); | |
125 | } | |
126 | #else | |
127 | /* | |
128 | * Boot image via bootm | |
129 | */ | |
130 | printf("\nBooting Image at addr 0x%s ...\n", addr); | |
d69b100e | 131 | setenv("loadaddr", addr); |
38718425 | 132 | |
d69b100e SR |
133 | local_args[0] = argv[0]; |
134 | local_args[1] = NULL; | |
135 | status = do_bootm (cmdtp, 0, 1, local_args); | |
c2642d14 | 136 | #endif |
d69b100e SR |
137 | } |
138 | ||
139 | return 0; | |
140 | } | |
09433a78 SR |
141 | U_BOOT_CMD( |
142 | loadpci, 1, 1, do_loadpci, | |
143 | "loadpci - Wait for pci-image and boot it\n", | |
144 | NULL | |
145 | ); | |
d69b100e SR |
146 | |
147 | #endif | |
c2642d14 SR |
148 | |
149 | #if 1 /* test-only */ | |
150 | int do_getpci(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) | |
151 | { | |
152 | unsigned int val; | |
153 | int i; | |
154 | ||
155 | printf("\nPCI Configuration Regs for PPC405GP:"); | |
156 | for (i=0; i<0x64; i+=4) { | |
157 | pci_read_config_dword(PCIDEVID_405GP, i, &val); | |
158 | if (!(i % 0x10)) { | |
159 | printf("\n%02x: ", i); | |
160 | } | |
161 | printf("%08x ", val); | |
162 | } | |
163 | printf("\n"); | |
164 | ||
165 | return 0; | |
166 | } | |
167 | U_BOOT_CMD( | |
168 | getpci, 1, 1, do_getpci, | |
169 | "getpci - Print own pci configuration registers\n", | |
170 | NULL | |
171 | ); | |
172 | ||
173 | int do_setpci(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) | |
174 | { | |
175 | unsigned int addr; | |
176 | unsigned int val; | |
177 | ||
178 | addr = simple_strtol (argv[1], NULL, 16); | |
179 | val = simple_strtol (argv[2], NULL, 16); | |
180 | ||
181 | printf("\nWriting %08x to PCI reg %08x.\n", val, addr); | |
182 | pci_write_config_dword(PCIDEVID_405GP, addr, val); | |
183 | ||
184 | return 0; | |
185 | } | |
186 | U_BOOT_CMD( | |
187 | setpci, 3, 1, do_setpci, | |
188 | "setpci - Set one pci configuration lword\n", | |
189 | "<addr> <val>\n" | |
190 | " - Write pci configuration lword <val> to <addr>.\n" | |
191 | ); | |
192 | ||
193 | int do_dumpdcr(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) | |
194 | { | |
195 | int i; | |
196 | ||
197 | printf("\nDevice Configuration Registers (DCR's) for PPC405GP:"); | |
198 | for (i=0; i<=0x1e0; i++) { | |
199 | if (!(i % 0x8)) { | |
200 | printf("\n%04x ", i); | |
201 | } | |
202 | printf("%08lx ", get_dcr(i)); | |
203 | } | |
204 | printf("\n"); | |
205 | ||
206 | return 0; | |
207 | } | |
208 | U_BOOT_CMD( | |
209 | dumpdcr, 1, 1, do_dumpdcr, | |
210 | "dumpdcr - Dump all DCR registers\n", | |
211 | NULL | |
212 | ); | |
213 | ||
214 | ||
215 | int do_dumpspr(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) | |
216 | { | |
217 | printf("\nSpecial Purpose Registers (SPR's) for PPC405GP:"); | |
218 | printf("\n%04x %08x ", 947, mfspr(947)); | |
219 | printf("\n%04x %08x ", 9, mfspr(9)); | |
220 | printf("\n%04x %08x ", 1014, mfspr(1014)); | |
221 | printf("\n%04x %08x ", 1015, mfspr(1015)); | |
222 | printf("\n%04x %08x ", 1010, mfspr(1010)); | |
223 | printf("\n%04x %08x ", 957, mfspr(957)); | |
224 | printf("\n%04x %08x ", 1008, mfspr(1008)); | |
225 | printf("\n%04x %08x ", 1018, mfspr(1018)); | |
226 | printf("\n%04x %08x ", 954, mfspr(954)); | |
227 | printf("\n%04x %08x ", 950, mfspr(950)); | |
228 | printf("\n%04x %08x ", 951, mfspr(951)); | |
229 | printf("\n%04x %08x ", 981, mfspr(981)); | |
230 | printf("\n%04x %08x ", 980, mfspr(980)); | |
231 | printf("\n%04x %08x ", 982, mfspr(982)); | |
232 | printf("\n%04x %08x ", 1012, mfspr(1012)); | |
233 | printf("\n%04x %08x ", 1013, mfspr(1013)); | |
234 | printf("\n%04x %08x ", 948, mfspr(948)); | |
235 | printf("\n%04x %08x ", 949, mfspr(949)); | |
236 | printf("\n%04x %08x ", 1019, mfspr(1019)); | |
237 | printf("\n%04x %08x ", 979, mfspr(979)); | |
238 | printf("\n%04x %08x ", 8, mfspr(8)); | |
239 | printf("\n%04x %08x ", 945, mfspr(945)); | |
240 | printf("\n%04x %08x ", 987, mfspr(987)); | |
241 | printf("\n%04x %08x ", 287, mfspr(287)); | |
242 | printf("\n%04x %08x ", 953, mfspr(953)); | |
243 | printf("\n%04x %08x ", 955, mfspr(955)); | |
244 | printf("\n%04x %08x ", 272, mfspr(272)); | |
245 | printf("\n%04x %08x ", 273, mfspr(273)); | |
246 | printf("\n%04x %08x ", 274, mfspr(274)); | |
247 | printf("\n%04x %08x ", 275, mfspr(275)); | |
248 | printf("\n%04x %08x ", 260, mfspr(260)); | |
249 | printf("\n%04x %08x ", 276, mfspr(276)); | |
250 | printf("\n%04x %08x ", 261, mfspr(261)); | |
251 | printf("\n%04x %08x ", 277, mfspr(277)); | |
252 | printf("\n%04x %08x ", 262, mfspr(262)); | |
253 | printf("\n%04x %08x ", 278, mfspr(278)); | |
254 | printf("\n%04x %08x ", 263, mfspr(263)); | |
255 | printf("\n%04x %08x ", 279, mfspr(279)); | |
256 | printf("\n%04x %08x ", 26, mfspr(26)); | |
257 | printf("\n%04x %08x ", 27, mfspr(27)); | |
258 | printf("\n%04x %08x ", 990, mfspr(990)); | |
259 | printf("\n%04x %08x ", 991, mfspr(991)); | |
260 | printf("\n%04x %08x ", 956, mfspr(956)); | |
261 | printf("\n%04x %08x ", 284, mfspr(284)); | |
262 | printf("\n%04x %08x ", 285, mfspr(285)); | |
263 | printf("\n%04x %08x ", 986, mfspr(986)); | |
264 | printf("\n%04x %08x ", 984, mfspr(984)); | |
265 | printf("\n%04x %08x ", 256, mfspr(256)); | |
266 | printf("\n%04x %08x ", 1, mfspr(1)); | |
267 | printf("\n%04x %08x ", 944, mfspr(944)); | |
268 | printf("\n"); | |
269 | ||
270 | return 0; | |
271 | } | |
272 | U_BOOT_CMD( | |
273 | dumpspr, 1, 1, do_dumpspr, | |
274 | "dumpspr - Dump all SPR registers\n", | |
275 | NULL | |
276 | ); | |
277 | ||
278 | ||
279 | #define PCI0_BRDGOPT1 0x4a | |
280 | #define plb0_acr 0x87 | |
281 | ||
282 | int do_getplb(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) | |
283 | { | |
284 | unsigned short val; | |
285 | ||
286 | printf("PLB0_ACR=%08lx\n", get_dcr(0x87)); | |
287 | pci_read_config_word(PCIDEVID_405GP, PCI0_BRDGOPT1, &val); | |
288 | printf("PCI0_BRDGOPT1=%04x\n", val); | |
289 | printf("CCR0=%08x\n", mfspr(ccr0)); | |
290 | ||
291 | return 0; | |
292 | } | |
293 | U_BOOT_CMD( | |
294 | getplb, 1, 1, do_getplb, | |
295 | "getplb - Dump all plb arbiter registers\n", | |
296 | NULL | |
297 | ); | |
298 | ||
299 | int do_setplb(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) | |
300 | { | |
301 | unsigned int my_acr; | |
302 | unsigned int my_brdgopt1; | |
303 | unsigned int my_ccr0; | |
304 | ||
305 | my_acr = simple_strtol (argv[1], NULL, 16); | |
306 | my_brdgopt1 = simple_strtol (argv[2], NULL, 16); | |
307 | my_ccr0 = simple_strtol (argv[3], NULL, 16); | |
308 | ||
309 | mtdcr(plb0_acr, my_acr); | |
310 | pci_write_config_word(PCIDEVID_405GP, PCI0_BRDGOPT1, my_brdgopt1); | |
311 | mtspr(ccr0, my_ccr0); | |
312 | ||
313 | return 0; | |
314 | } | |
315 | U_BOOT_CMD( | |
316 | setplb, 4, 1, do_setplb, | |
317 | "setplb - Set all plb arbiter registers\n", | |
318 | "PLB0_ACR PCI0_BRDGOPT1 CCR0\n" | |
319 | " - Set all plb arbiter registers\n" | |
320 | ); | |
321 | ||
322 | ||
323 | /*********************************************************************** | |
324 | * | |
325 | * The following code is only for test purposes!!!! | |
326 | * Please ignore this ugly stuff!!!!!!!!!!!!!!!!!!! | |
327 | * | |
328 | ***********************************************************************/ | |
329 | ||
330 | #define PCI_ADDR 0xc0000000 | |
331 | ||
332 | int do_writepci(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) | |
333 | { | |
334 | unsigned int addr; | |
335 | unsigned int size; | |
336 | unsigned int countmax; | |
337 | int i; | |
338 | int max; | |
339 | volatile unsigned long *ptr; | |
340 | volatile unsigned long val; | |
341 | int loopcount = 0; | |
342 | int test_pci_read = 0; | |
343 | int test_pci_cfg_write = 0; | |
344 | int test_sync = 0; | |
345 | int test_pci_pre_read = 0; | |
346 | ||
347 | addr = simple_strtol (argv[1], NULL, 16); | |
348 | size = simple_strtol (argv[2], NULL, 16); | |
349 | countmax = simple_strtol (argv[3], NULL, 16); | |
350 | if (countmax == 0) | |
351 | countmax = 1000; | |
352 | ||
353 | do_getplb(NULL, 0, 0, NULL); | |
354 | ||
355 | #if 0 | |
356 | out32r(PMM0LA, 0); | |
357 | out32r(PMM0PCILA, 0); | |
358 | out32r(PMM0PCIHA, 0); | |
359 | out32r(PMM0MA, 0); | |
360 | out32r(PMM1LA, PCI_ADDR); | |
361 | out32r(PMM1PCILA, addr & 0xff000000); | |
362 | out32r(PMM1PCIHA, 0x00000000); | |
363 | out32r(PMM1MA, 0xff000001); | |
364 | #endif | |
365 | ||
366 | printf("PMM1LA =%08lx\n", in32r(PMM1LA)); | |
367 | printf("PMM1MA =%08lx\n", in32r(PMM1MA)); | |
368 | printf("PMM1PCILA =%08lx\n", in32r(PMM1PCILA)); | |
369 | printf("PMM1PCIHA =%08lx\n", in32r(PMM1PCIHA)); | |
370 | ||
371 | addr = PCI_ADDR | (addr & 0x00ffffff); | |
372 | printf("\nWriting at addr %08x, size %08x (countmax=%x)\n", addr, size, countmax); | |
373 | ||
374 | max = size >> 2; | |
375 | ||
376 | pci_write_config_word(PCIDEVID_405GP, 0x04, 0x0106); /* write command reg */ | |
377 | ||
378 | val = *(ulong *)0x00000000; | |
379 | if (val & 0x00000008) { | |
380 | test_pci_pre_read = 1; | |
381 | printf("Running test with pre pci-memory-read access!\n"); | |
382 | } | |
383 | if (val & 0x00000004) { | |
384 | test_sync = 1; | |
385 | printf("Running test with sync instruction!\n"); | |
386 | } | |
387 | if (val & 0x00000001) { | |
388 | test_pci_read = 1; | |
389 | printf("Running test with pci-memory-read access!\n"); | |
390 | } | |
391 | if (val & 0x00000002) { | |
392 | test_pci_cfg_write = 1; | |
393 | printf("Running test with pci-config-write access!\n"); | |
394 | } | |
395 | ||
396 | while (1) { | |
397 | ||
398 | if (test_pci_pre_read) { | |
399 | /* | |
400 | * Read one value back | |
401 | */ | |
402 | ptr = (volatile unsigned long *)addr; | |
403 | val = *ptr; | |
404 | } | |
405 | ||
406 | /* | |
407 | * Write some values to host via pci busmastering | |
408 | */ | |
409 | ptr = (volatile unsigned long *)addr; | |
410 | for (i=0; i<max; i++) { | |
411 | *ptr++ = i; | |
412 | } | |
413 | ||
414 | if (test_sync) { | |
415 | /* | |
416 | * Sync previous writes | |
417 | */ | |
418 | ppcSync(); | |
419 | } | |
420 | ||
421 | if (test_pci_read) { | |
422 | /* | |
423 | * Read one value back | |
424 | */ | |
425 | ptr = (volatile unsigned long *)addr; | |
426 | val = *ptr; | |
427 | } | |
428 | ||
429 | if (test_pci_cfg_write) { | |
430 | /* | |
431 | * Generate IRQ to host via config regs | |
432 | */ | |
433 | pci_write_config_byte(PCIDEVID_405GP, 0x44, 0x00); | |
434 | } | |
435 | ||
436 | if (loopcount++ > countmax) { | |
437 | /* Abort if ctrl-c was pressed */ | |
438 | if (ctrlc()) { | |
439 | puts("\nAbort\n"); | |
440 | return 0; | |
441 | } | |
442 | ||
443 | putc('.'); | |
444 | ||
445 | loopcount = 0; | |
446 | } | |
447 | } | |
448 | ||
449 | return 0; | |
450 | } | |
451 | U_BOOT_CMD( | |
452 | writepci, 4, 1, do_writepci, | |
453 | "writepci - Write some data to pcibus\n", | |
454 | "<addr> <size>\n" | |
455 | " - Write some data to pcibus.\n" | |
456 | ); | |
457 | ||
458 | #define PCI_CFGADDR 0xeec00000 | |
459 | #define PCI_CFGDATA 0xeec00004 | |
460 | ||
461 | int ibmPciConfigWrite | |
462 | ( | |
463 | int offset, /* offset into the configuration space */ | |
464 | int width, /* data width */ | |
465 | unsigned int data /* data to be written */ | |
466 | ) | |
467 | { | |
468 | /* | |
469 | * Write config register address to the PCI config address register | |
470 | * bit 31 must be 1 and bits 1:0 must be 0 (note LE bit notation) | |
471 | */ | |
472 | out32r(PCI_CFGADDR, 0x80000000 | (offset & 0xFFFFFFFC)); | |
473 | ||
474 | #if 0 /* test-only */ | |
475 | ppcSync(); | |
476 | #endif | |
477 | ||
478 | /* | |
479 | * Write value to be written to the PCI config data register | |
480 | */ | |
481 | switch ( width ) { | |
482 | case 1: out32r(PCI_CFGDATA | (offset & 0x3), (unsigned char)(data & 0xFF)); | |
483 | break; | |
484 | case 2: out32r(PCI_CFGDATA | (offset & 0x3), (unsigned short)(data & 0xFFFF)); | |
485 | break; | |
486 | case 4: out32r(PCI_CFGDATA | (offset & 0x3), data); | |
487 | break; | |
488 | } | |
489 | ||
490 | return (0); | |
491 | } | |
492 | ||
493 | int do_writepci2(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) | |
494 | { | |
495 | unsigned int addr; | |
496 | unsigned int size; | |
497 | unsigned int countmax; | |
498 | int max; | |
499 | volatile unsigned long *ptr; | |
500 | volatile unsigned long val; | |
501 | int loopcount = 0; | |
502 | ||
503 | addr = simple_strtol (argv[1], NULL, 16); | |
504 | size = simple_strtol (argv[2], NULL, 16); | |
505 | countmax = simple_strtol (argv[3], NULL, 16); | |
506 | if (countmax == 0) | |
507 | countmax = 1000; | |
508 | ||
509 | do_getplb(NULL, 0, 0, NULL); | |
510 | ||
511 | #if 0 | |
512 | out32r(PMM0LA, 0); | |
513 | out32r(PMM0PCILA, 0); | |
514 | out32r(PMM0PCIHA, 0); | |
515 | out32r(PMM0MA, 0); | |
516 | out32r(PMM1LA, PCI_ADDR); | |
517 | out32r(PMM1PCILA, addr & 0xff000000); | |
518 | out32r(PMM1PCIHA, 0x00000000); | |
519 | out32r(PMM1MA, 0xff000001); | |
520 | #endif | |
521 | ||
522 | printf("PMM1LA =%08lx\n", in32r(PMM1LA)); | |
523 | printf("PMM1MA =%08lx\n", in32r(PMM1MA)); | |
524 | printf("PMM1PCILA =%08lx\n", in32r(PMM1PCILA)); | |
525 | printf("PMM1PCIHA =%08lx\n", in32r(PMM1PCIHA)); | |
526 | ||
527 | addr = PCI_ADDR | (addr & 0x00ffffff); | |
528 | printf("\nWriting at addr %08x, size %08x (countmax=%x)\n", addr, size, countmax); | |
529 | ||
530 | max = size >> 2; | |
531 | ||
532 | pci_write_config_word(PCIDEVID_405GP, 0x04, 0x0106); /* write command reg */ | |
533 | ||
534 | while (1) { | |
535 | ||
536 | /* | |
537 | * Write one values to host via pci busmastering | |
538 | */ | |
539 | ptr = (volatile unsigned long *)addr; | |
540 | *ptr = 0x01234567; | |
541 | ||
542 | /* | |
543 | * Read one value back | |
544 | */ | |
545 | ptr = (volatile unsigned long *)addr; | |
546 | val = *ptr; | |
547 | ||
548 | /* | |
549 | * One pci config write | |
550 | */ | |
551 | /* pci_write_config_byte(PCIDEVID_405GP, 0x44, 0x00); */ | |
552 | /* ibmPciConfigWrite(0x44, 1, 0x00); */ | |
553 | ibmPciConfigWrite(0x2e, 2, 0x1234); /* subsystem id */ | |
554 | ||
555 | if (loopcount++ > countmax) { | |
556 | /* Abort if ctrl-c was pressed */ | |
557 | if (ctrlc()) { | |
558 | puts("\nAbort\n"); | |
559 | return 0; | |
560 | } | |
561 | ||
562 | putc('.'); | |
563 | ||
564 | loopcount = 0; | |
565 | } | |
566 | } | |
567 | ||
568 | return 0; | |
569 | } | |
570 | U_BOOT_CMD( | |
571 | writepci2, 4, 1, do_writepci2, | |
572 | "writepci2- Write some data to pcibus\n", | |
573 | "<addr> <size>\n" | |
574 | " - Write some data to pcibus.\n" | |
575 | ); | |
576 | ||
577 | int do_writepci22(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) | |
578 | { | |
579 | unsigned int addr; | |
580 | unsigned int size; | |
581 | unsigned int countmax = 0; | |
582 | volatile unsigned long *ptr; | |
583 | volatile unsigned long val; | |
584 | ||
585 | addr = simple_strtol (argv[1], NULL, 16); | |
586 | size = simple_strtol (argv[2], NULL, 16); | |
587 | ||
588 | addr = PCI_ADDR | (addr & 0x00ffffff); | |
589 | printf("\nWriting at addr %08x, size %08x (countmax=%x)\n", addr, size, countmax); | |
590 | pci_write_config_word(PCIDEVID_405GP, 0x04, 0x0106); /* write command reg */ | |
591 | ||
592 | while (1) { | |
593 | ||
594 | /* | |
595 | * Write one values to host via pci busmastering | |
596 | */ | |
597 | ptr = (volatile unsigned long *)addr; | |
598 | *ptr = 0x01234567; | |
599 | ||
600 | /* | |
601 | * Read one value back | |
602 | */ | |
603 | ptr = (volatile unsigned long *)addr; | |
604 | val = *ptr; | |
605 | ||
606 | /* | |
607 | * One pci config write | |
608 | */ | |
609 | ibmPciConfigWrite(0x2e, 2, 0x1234); /* subsystem id */ | |
610 | } | |
611 | ||
612 | return 0; | |
613 | } | |
614 | U_BOOT_CMD( | |
615 | writepci22, 4, 1, do_writepci22, | |
616 | "writepci22- Write some data to pcibus\n", | |
617 | "<addr> <size>\n" | |
618 | " - Write some data to pcibus.\n" | |
619 | ); | |
620 | ||
621 | int ibmPciConfigWrite3 | |
622 | ( | |
623 | int offset, /* offset into the configuration space */ | |
624 | int width, /* data width */ | |
625 | unsigned int data /* data to be written */ | |
626 | ) | |
627 | { | |
628 | /* | |
629 | * Write config register address to the PCI config address register | |
630 | * bit 31 must be 1 and bits 1:0 must be 0 (note LE bit notation) | |
631 | */ | |
632 | out32r(PCI_CFGADDR, 0x80000000 | (offset & 0xFFFFFFFC)); | |
633 | ||
634 | #if 1 /* test-only */ | |
635 | ppcSync(); | |
636 | #endif | |
637 | ||
638 | /* | |
639 | * Write value to be written to the PCI config data register | |
640 | */ | |
641 | switch ( width ) { | |
642 | case 1: out32r(PCI_CFGDATA | (offset & 0x3), (unsigned char)(data & 0xFF)); | |
643 | break; | |
644 | case 2: out32r(PCI_CFGDATA | (offset & 0x3), (unsigned short)(data & 0xFFFF)); | |
645 | break; | |
646 | case 4: out32r(PCI_CFGDATA | (offset & 0x3), data); | |
647 | break; | |
648 | } | |
649 | ||
650 | return (0); | |
651 | } | |
652 | ||
653 | int do_writepci3(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) | |
654 | { | |
655 | unsigned int addr; | |
656 | unsigned int size; | |
657 | unsigned int countmax; | |
658 | int max; | |
659 | volatile unsigned long *ptr; | |
660 | volatile unsigned long val; | |
661 | int loopcount = 0; | |
662 | ||
663 | addr = simple_strtol (argv[1], NULL, 16); | |
664 | size = simple_strtol (argv[2], NULL, 16); | |
665 | countmax = simple_strtol (argv[3], NULL, 16); | |
666 | if (countmax == 0) | |
667 | countmax = 1000; | |
668 | ||
669 | do_getplb(NULL, 0, 0, NULL); | |
670 | ||
671 | #if 0 | |
672 | out32r(PMM0LA, 0); | |
673 | out32r(PMM0PCILA, 0); | |
674 | out32r(PMM0PCIHA, 0); | |
675 | out32r(PMM0MA, 0); | |
676 | out32r(PMM1LA, PCI_ADDR); | |
677 | out32r(PMM1PCILA, addr & 0xff000000); | |
678 | out32r(PMM1PCIHA, 0x00000000); | |
679 | out32r(PMM1MA, 0xff000001); | |
680 | #endif | |
681 | ||
682 | printf("PMM1LA =%08lx\n", in32r(PMM1LA)); | |
683 | printf("PMM1MA =%08lx\n", in32r(PMM1MA)); | |
684 | printf("PMM1PCILA =%08lx\n", in32r(PMM1PCILA)); | |
685 | printf("PMM1PCIHA =%08lx\n", in32r(PMM1PCIHA)); | |
686 | ||
687 | addr = PCI_ADDR | (addr & 0x00ffffff); | |
688 | printf("\nWriting at addr %08x, size %08x (countmax=%x)\n", addr, size, countmax); | |
689 | ||
690 | max = size >> 2; | |
691 | ||
692 | pci_write_config_word(PCIDEVID_405GP, 0x04, 0x0106); /* write command reg */ | |
693 | ||
694 | while (1) { | |
695 | ||
696 | /* | |
697 | * Write one values to host via pci busmastering | |
698 | */ | |
699 | ptr = (volatile unsigned long *)addr; | |
700 | *ptr = 0x01234567; | |
701 | ||
702 | /* | |
703 | * Read one value back | |
704 | */ | |
705 | ptr = (volatile unsigned long *)addr; | |
706 | val = *ptr; | |
707 | ||
708 | /* | |
709 | * One pci config write | |
710 | */ | |
711 | /* pci_write_config_byte(PCIDEVID_405GP, 0x44, 0x00); */ | |
712 | /* ibmPciConfigWrite(0x44, 1, 0x00); */ | |
713 | ibmPciConfigWrite3(0x2e, 2, 0x1234); /* subsystem id */ | |
714 | ||
715 | if (loopcount++ > countmax) { | |
716 | /* Abort if ctrl-c was pressed */ | |
717 | if (ctrlc()) { | |
718 | puts("\nAbort\n"); | |
719 | return 0; | |
720 | } | |
721 | ||
722 | putc('.'); | |
723 | ||
724 | loopcount = 0; | |
725 | } | |
726 | } | |
727 | ||
728 | return 0; | |
729 | } | |
730 | U_BOOT_CMD( | |
731 | writepci3, 4, 1, do_writepci3, | |
732 | "writepci3- Write some data to pcibus\n", | |
733 | "<addr> <size>\n" | |
734 | " - Write some data to pcibus.\n" | |
735 | ); | |
736 | ||
737 | ||
53677ef1 | 738 | #define SECTOR_SIZE 32 /* 32 byte cache line */ |
c2642d14 SR |
739 | #define SECTOR_MASK 0x1F |
740 | ||
741 | void my_flush_dcache(ulong lcl_addr, ulong count) | |
742 | { | |
743 | unsigned int lcl_target; | |
744 | ||
745 | /* promote to nearest cache sector */ | |
746 | lcl_target = (lcl_addr + count + SECTOR_SIZE - 1) & ~SECTOR_MASK; | |
747 | lcl_addr &= ~SECTOR_MASK; | |
748 | while (lcl_addr != lcl_target) | |
749 | { | |
750 | /* ppcDcbf((void *)lcl_addr);*/ | |
751 | __asm__("dcbf 0,%0": :"r" (lcl_addr)); | |
752 | lcl_addr += SECTOR_SIZE; | |
753 | } | |
754 | __asm__("sync"); /* Always flush prefetch queue in any case */ | |
755 | } | |
756 | ||
757 | int do_writepci_cache(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) | |
758 | { | |
759 | unsigned int addr; | |
760 | unsigned int size; | |
761 | unsigned int countmax; | |
762 | int i; | |
763 | volatile unsigned long *ptr; | |
764 | volatile unsigned long val; | |
765 | int loopcount = 0; | |
766 | ||
767 | addr = simple_strtol (argv[1], NULL, 16); | |
768 | size = simple_strtol (argv[2], NULL, 16); | |
769 | countmax = simple_strtol (argv[3], NULL, 16); | |
770 | if (countmax == 0) | |
771 | countmax = 1000; | |
772 | ||
773 | do_getplb(NULL, 0, 0, NULL); | |
774 | ||
775 | #if 0 | |
776 | out32r(PMM0LA, 0); | |
777 | out32r(PMM0PCILA, 0); | |
778 | out32r(PMM0PCIHA, 0); | |
779 | out32r(PMM0MA, 0); | |
780 | out32r(PMM1LA, PCI_ADDR); | |
781 | out32r(PMM1PCILA, addr & 0xff000000); | |
782 | out32r(PMM1PCIHA, 0x00000000); | |
783 | out32r(PMM1MA, 0xff000001); | |
784 | #endif | |
785 | ||
786 | printf("PMM1LA =%08lx\n", in32r(PMM1LA)); | |
787 | printf("PMM1MA =%08lx\n", in32r(PMM1MA)); | |
788 | printf("PMM1PCILA =%08lx\n", in32r(PMM1PCILA)); | |
789 | printf("PMM1PCIHA =%08lx\n", in32r(PMM1PCIHA)); | |
790 | ||
791 | addr = PCI_ADDR | (addr & 0x00ffffff); | |
792 | printf("\nWriting at addr %08x, size %08x (countmax=%x)\n", addr, size, countmax); | |
793 | ||
794 | pci_write_config_word(PCIDEVID_405GP, 0x04, 0x0106); /* write command reg */ | |
795 | ||
796 | i = 0; | |
797 | ||
798 | /* | |
799 | * Set pci region as cachable | |
800 | */ | |
801 | ppcSync(); | |
802 | __asm__ volatile (" addis 4,0,0x0000 "); | |
803 | __asm__ volatile (" addi 4,4,0x0080 "); | |
804 | __asm__ volatile (" mtdccr 4 "); | |
805 | ppcSync(); | |
806 | ||
807 | while (1) { | |
808 | ||
809 | /* | |
810 | * Write one values to host via pci busmastering | |
811 | */ | |
812 | ptr = (volatile unsigned long *)addr; | |
813 | printf("A\n"); /* test-only */ | |
814 | *ptr++ = i++; | |
815 | *ptr++ = i++; | |
816 | *ptr++ = i++; | |
817 | *ptr++ = i++; | |
818 | *ptr++ = i++; | |
819 | *ptr++ = i++; | |
820 | *ptr++ = i++; | |
821 | *ptr++ = i++; | |
822 | printf("B\n"); /* test-only */ | |
823 | my_flush_dcache(addr, 32); | |
824 | printf("C\n"); /* test-only */ | |
825 | ||
826 | /* | |
827 | * Read one value back | |
828 | */ | |
829 | ptr = (volatile unsigned long *)addr; | |
830 | val = *ptr; | |
831 | printf("D\n"); /* test-only */ | |
832 | ||
833 | /* | |
834 | * One pci config write | |
835 | */ | |
836 | /* pci_write_config_byte(PCIDEVID_405GP, 0x44, 0x00); */ | |
837 | /* ibmPciConfigWrite(0x44, 1, 0x00); */ | |
838 | ibmPciConfigWrite3(0x2e, 2, 0x1234); /* subsystem id */ | |
839 | printf("E\n"); /* test-only */ | |
840 | ||
841 | if (loopcount++ > countmax) { | |
842 | /* Abort if ctrl-c was pressed */ | |
843 | if (ctrlc()) { | |
844 | puts("\nAbort\n"); | |
845 | return 0; | |
846 | } | |
847 | ||
848 | putc('.'); | |
849 | ||
850 | loopcount = 0; | |
851 | } | |
852 | } | |
853 | ||
854 | return 0; | |
855 | } | |
856 | U_BOOT_CMD( | |
857 | writepci_cache, 4, 1, do_writepci_cache, | |
858 | "writepci_cache - Write some data to pcibus\n", | |
859 | "<addr> <size>\n" | |
860 | " - Write some data to pcibus.\n" | |
861 | ); | |
862 | ||
863 | int do_savepci(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) | |
864 | { | |
865 | unsigned int *ptr; | |
866 | int i; | |
867 | ||
868 | /* | |
869 | * Save own pci configuration in PRAM | |
870 | */ | |
871 | memset((char *)PCI_REGS_ADDR, 0, PCI_REGS_LEN); | |
872 | ptr = (unsigned int *)PCI_REGS_ADDR + 1; | |
873 | for (i=0; i<0x40; i+=4) { | |
874 | pci_read_config_dword(PCIDEVID_405GP, i, ptr++); | |
875 | } | |
876 | ptr = (unsigned int *)PCI_REGS_ADDR; | |
77ddac94 | 877 | *ptr = crc32(0, (uchar *)PCI_REGS_ADDR+4, PCI_REGS_LEN-4); |
c2642d14 SR |
878 | |
879 | printf("\nStoring PCI Configuration Regs...\n"); | |
880 | ||
881 | return 0; | |
882 | } | |
883 | U_BOOT_CMD( | |
884 | savepci, 4, 1, do_savepci, | |
885 | "savepci - Save all pci regs\n", | |
886 | "<addr> <size>\n" | |
887 | " - Write some data to pcibus.\n" | |
888 | ); | |
889 | ||
890 | int do_restorepci(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) | |
891 | { | |
892 | unsigned int *ptr; | |
893 | int i; | |
894 | ||
895 | /* | |
896 | * Rewrite pci config regs (only after soft-reset with magic set) | |
897 | */ | |
898 | ptr = (unsigned int *)PCI_REGS_ADDR; | |
77ddac94 | 899 | if (crc32(0, (uchar *)PCI_REGS_ADDR+4, PCI_REGS_LEN-4) == *ptr) { |
c2642d14 SR |
900 | puts("Restoring PCI Configurations Regs!\n"); |
901 | ptr = (unsigned int *)PCI_REGS_ADDR + 1; | |
902 | for (i=0; i<0x40; i+=4) { | |
903 | pci_write_config_dword(PCIDEVID_405GP, i, *ptr++); | |
904 | } | |
905 | } | |
906 | mtdcr(uicsr, 0xFFFFFFFF); /* clear all ints */ | |
907 | ||
908 | return 0; | |
909 | } | |
910 | U_BOOT_CMD( | |
911 | restorepci, 4, 1, do_restorepci, | |
912 | "restorepci - Restore all pci regs\n", | |
913 | "<addr> <size>\n" | |
914 | " - Write some data to pcibus.\n" | |
915 | ); | |
916 | ||
917 | ||
918 | extern void write_without_sync(void); | |
919 | extern void write_with_sync(void); | |
920 | extern void write_with_less_sync(void); | |
921 | extern void write_with_more_sync(void); | |
922 | ||
923 | /* | |
924 | * code from IBM-PPCSUPP | |
925 | */ | |
926 | int do_writeibm1(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) | |
927 | { | |
928 | pci_write_config_word(PCIDEVID_405GP, 0x04, 0x0106); /* write command reg */ | |
929 | ||
930 | write_without_sync(); | |
931 | ||
932 | return 0; | |
933 | } | |
934 | U_BOOT_CMD( | |
935 | writeibm1, 4, 1, do_writeibm1, | |
936 | "writeibm1- Write some data to pcibus (without sync)\n", | |
937 | "<addr> <size>\n" | |
938 | " - Write some data to pcibus.\n" | |
939 | ); | |
940 | ||
941 | int do_writeibm2(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) | |
942 | { | |
943 | pci_write_config_word(PCIDEVID_405GP, 0x04, 0x0106); /* write command reg */ | |
944 | ||
945 | write_with_sync(); | |
946 | ||
947 | return 0; | |
948 | } | |
949 | U_BOOT_CMD( | |
950 | writeibm2, 4, 1, do_writeibm2, | |
951 | "writeibm2- Write some data to pcibus (with sync)\n", | |
952 | "<addr> <size>\n" | |
953 | " - Write some data to pcibus.\n" | |
954 | ); | |
955 | ||
956 | int do_writeibm22(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) | |
957 | { | |
958 | pci_write_config_word(PCIDEVID_405GP, 0x04, 0x0106); /* write command reg */ | |
959 | ||
960 | write_with_less_sync(); | |
961 | ||
962 | return 0; | |
963 | } | |
964 | U_BOOT_CMD( | |
965 | writeibm22, 4, 1, do_writeibm22, | |
966 | "writeibm22- Write some data to pcibus (with less sync)\n", | |
967 | "<addr> <size>\n" | |
968 | " - Write some data to pcibus.\n" | |
969 | ); | |
970 | ||
971 | int do_writeibm3(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) | |
972 | { | |
973 | pci_write_config_word(PCIDEVID_405GP, 0x04, 0x0106); /* write command reg */ | |
974 | ||
975 | write_with_more_sync(); | |
976 | ||
977 | return 0; | |
978 | } | |
979 | U_BOOT_CMD( | |
980 | writeibm3, 4, 1, do_writeibm3, | |
981 | "writeibm3- Write some data to pcibus (with more sync)\n", | |
982 | "<addr> <size>\n" | |
983 | " - Write some data to pcibus.\n" | |
984 | ); | |
985 | #endif |