9a0bf1e360337ff730ddbc00290987da4cd44501
[platform/kernel/u-boot.git] / board / esd / pci405 / cmd_pci405.c
1 /*
2  * (C) Copyright 2002-2004
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>
25 #include <command.h>
26 #include <malloc.h>
27 #include <net.h>
28 #include <asm/io.h>
29 #include <pci.h>
30 #include <asm/4xx_pci.h>
31 #include <asm/processor.h>
32
33 #include "pci405.h"
34
35
36 #if defined(CONFIG_CMD_BSP)
37
38 extern int do_bootm (cmd_tbl_t *, int, int, char *[]);
39 extern int do_bootvx (cmd_tbl_t *, int, int, char *[]);
40 unsigned long get_dcr(unsigned short);
41
42
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
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;
94                 *ptr = crc32(0, (uchar *)PCI_REGS_ADDR+4, PCI_REGS_LEN-4);
95
96                 printf("\nStoring PCI Configuration Regs...\n");
97         } else {
98                 sprintf(addr, "%08x", *ptr);
99
100 #if 0
101                 /*
102                  * Boot image
103                  */
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);
131                 setenv("loadaddr", addr);
132
133                 local_args[0] = argv[0];
134                 local_args[1] = NULL;
135                 status = do_bootm (cmdtp, 0, 1, local_args);
136 #endif
137         }
138
139         return 0;
140 }
141 U_BOOT_CMD(
142         loadpci,        1,      1,      do_loadpci,
143         "loadpci - Wait for pci-image and boot it\n",
144         NULL
145 );
146
147 #endif
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
738 #define SECTOR_SIZE     32              /* 32 byte cache line */
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;
877         *ptr = crc32(0, (uchar *)PCI_REGS_ADDR+4, PCI_REGS_LEN-4);
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;
899         if (crc32(0, (uchar *)PCI_REGS_ADDR+4, PCI_REGS_LEN-4) == *ptr) {
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