cmd_pci405.c 23 KB

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