powerspan.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750
  1. /**
  2. * @file powerspan.c Source file for PowerSpan II code.
  3. */
  4. /*
  5. * (C) Copyright 2005
  6. * AMIRIX Systems Inc.
  7. *
  8. * See file CREDITS for list of people who contributed to this
  9. * project.
  10. *
  11. * This program is free software; you can redistribute it and/or
  12. * modify it under the terms of the GNU General Public License as
  13. * published by the Free Software Foundation; either version 2 of
  14. * the License, or (at your option) any later version.
  15. *
  16. * This program is distributed in the hope that it will be useful,
  17. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  19. * GNU General Public License for more details.
  20. *
  21. * You should have received a copy of the GNU General Public License
  22. * along with this program; if not, write to the Free Software
  23. * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  24. * MA 02111-1307 USA
  25. */
  26. #include <common.h>
  27. #include <command.h>
  28. #include <asm/processor.h>
  29. #include "powerspan.h"
  30. #define tolower(x) x
  31. #include "ap1000.h"
  32. #ifdef INCLUDE_PCI
  33. /** Write one byte with byte swapping.
  34. * @param addr [IN] the address to write to
  35. * @param val [IN] the value to write
  36. */
  37. void write1 (unsigned long addr, unsigned char val)
  38. {
  39. volatile unsigned char *p = (volatile unsigned char *) addr;
  40. #ifdef VERBOSITY
  41. if (gVerbosityLevel > 1) {
  42. printf ("write1: addr=%08x val=%02x\n", addr, val);
  43. }
  44. #endif
  45. *p = val;
  46. PSII_SYNC ();
  47. }
  48. /** Read one byte with byte swapping.
  49. * @param addr [IN] the address to read from
  50. * @return the value at addr
  51. */
  52. unsigned char read1 (unsigned long addr)
  53. {
  54. unsigned char val;
  55. volatile unsigned char *p = (volatile unsigned char *) addr;
  56. val = *p;
  57. PSII_SYNC ();
  58. #ifdef VERBOSITY
  59. if (gVerbosityLevel > 1) {
  60. printf ("read1: addr=%08x val=%02x\n", addr, val);
  61. }
  62. #endif
  63. return val;
  64. }
  65. /** Write one 2-byte word with byte swapping.
  66. * @param addr [IN] the address to write to
  67. * @param val [IN] the value to write
  68. */
  69. void write2 (unsigned long addr, unsigned short val)
  70. {
  71. volatile unsigned short *p = (volatile unsigned short *) addr;
  72. #ifdef VERBOSITY
  73. if (gVerbosityLevel > 1) {
  74. printf ("write2: addr=%08x val=%04x -> *p=%04x\n", addr, val,
  75. ((val & 0xFF00) >> 8) | ((val & 0x00FF) << 8));
  76. }
  77. #endif
  78. *p = ((val & 0xFF00) >> 8) | ((val & 0x00FF) << 8);
  79. PSII_SYNC ();
  80. }
  81. /** Read one 2-byte word with byte swapping.
  82. * @param addr [IN] the address to read from
  83. * @return the value at addr
  84. */
  85. unsigned short read2 (unsigned long addr)
  86. {
  87. unsigned short val;
  88. volatile unsigned short *p = (volatile unsigned short *) addr;
  89. val = *p;
  90. val = ((val & 0xFF00) >> 8) | ((val & 0x00FF) << 8);
  91. PSII_SYNC ();
  92. #ifdef VERBOSITY
  93. if (gVerbosityLevel > 1) {
  94. printf ("read2: addr=%08x *p=%04x -> val=%04x\n", addr, *p,
  95. val);
  96. }
  97. #endif
  98. return val;
  99. }
  100. /** Write one 4-byte word with byte swapping.
  101. * @param addr [IN] the address to write to
  102. * @param val [IN] the value to write
  103. */
  104. void write4 (unsigned long addr, unsigned long val)
  105. {
  106. volatile unsigned long *p = (volatile unsigned long *) addr;
  107. #ifdef VERBOSITY
  108. if (gVerbosityLevel > 1) {
  109. printf ("write4: addr=%08x val=%08x -> *p=%08x\n", addr, val,
  110. ((val & 0xFF000000) >> 24) |
  111. ((val & 0x000000FF) << 24) |
  112. ((val & 0x00FF0000) >> 8) |
  113. ((val & 0x0000FF00) << 8));
  114. }
  115. #endif
  116. *p = ((val & 0xFF000000) >> 24) | ((val & 0x000000FF) << 24) |
  117. ((val & 0x00FF0000) >> 8) | ((val & 0x0000FF00) << 8);
  118. PSII_SYNC ();
  119. }
  120. /** Read one 4-byte word with byte swapping.
  121. * @param addr [IN] the address to read from
  122. * @return the value at addr
  123. */
  124. unsigned long read4 (unsigned long addr)
  125. {
  126. unsigned long val;
  127. volatile unsigned long *p = (volatile unsigned long *) addr;
  128. val = *p;
  129. val = ((val & 0xFF000000) >> 24) | ((val & 0x000000FF) << 24) |
  130. ((val & 0x00FF0000) >> 8) | ((val & 0x0000FF00) << 8);
  131. PSII_SYNC ();
  132. #ifdef VERBOSITY
  133. if (gVerbosityLevel > 1) {
  134. printf ("read4: addr=%08x *p=%08x -> val=%08x\n", addr, *p,
  135. val);
  136. }
  137. #endif
  138. return val;
  139. }
  140. int PCIReadConfig (int bus, int dev, int fn, int reg, int width,
  141. unsigned long *val)
  142. {
  143. unsigned int conAdrVal;
  144. unsigned int conDataReg = REG_CONFIG_DATA;
  145. unsigned int status;
  146. int ret_val = 0;
  147. /* DEST bit hardcoded to 1: local pci is PCI-2 */
  148. /* TYPE bit is hardcoded to 1: all config cycles are local */
  149. conAdrVal = (1 << 24)
  150. | ((bus & 0xFF) << 16)
  151. | ((dev & 0xFF) << 11)
  152. | ((fn & 0x07) << 8)
  153. | (reg & 0xFC);
  154. /* clear any pending master aborts */
  155. write4 (REG_P1_CSR, CLEAR_MASTER_ABORT);
  156. /* Load the conAdrVal value first, then read from pb_conf_data */
  157. write4 (REG_CONFIG_ADDRESS, conAdrVal);
  158. PSII_SYNC ();
  159. /* Note: documentation does not match the pspan library code */
  160. /* Note: *pData comes back as -1 if device is not present */
  161. switch (width) {
  162. case 4:
  163. *(unsigned int *) val = read4 (conDataReg);
  164. break;
  165. case 2:
  166. *(unsigned short *) val = read2 (conDataReg);
  167. break;
  168. case 1:
  169. *(unsigned char *) val = read1 (conDataReg);
  170. break;
  171. default:
  172. ret_val = ILLEGAL_REG_OFFSET;
  173. break;
  174. }
  175. PSII_SYNC ();
  176. /* clear any pending master aborts */
  177. status = read4 (REG_P1_CSR);
  178. if (status & CLEAR_MASTER_ABORT) {
  179. ret_val = NO_DEVICE_FOUND;
  180. write4 (REG_P1_CSR, CLEAR_MASTER_ABORT);
  181. }
  182. return ret_val;
  183. }
  184. int PCIWriteConfig (int bus, int dev, int fn, int reg, int width,
  185. unsigned long val)
  186. {
  187. unsigned int conAdrVal;
  188. unsigned int conDataReg = REG_CONFIG_DATA;
  189. unsigned int status;
  190. int ret_val = 0;
  191. /* DEST bit hardcoded to 1: local pci is PCI-2 */
  192. /* TYPE bit is hardcoded to 1: all config cycles are local */
  193. conAdrVal = (1 << 24)
  194. | ((bus & 0xFF) << 16)
  195. | ((dev & 0xFF) << 11)
  196. | ((fn & 0x07) << 8)
  197. | (reg & 0xFC);
  198. /* clear any pending master aborts */
  199. write4 (REG_P1_CSR, CLEAR_MASTER_ABORT);
  200. /* Load the conAdrVal value first, then read from pb_conf_data */
  201. write4 (REG_CONFIG_ADDRESS, conAdrVal);
  202. PSII_SYNC ();
  203. /* Note: documentation does not match the pspan library code */
  204. /* Note: *pData comes back as -1 if device is not present */
  205. switch (width) {
  206. case 4:
  207. write4 (conDataReg, val);
  208. break;
  209. case 2:
  210. write2 (conDataReg, val);
  211. break;
  212. case 1:
  213. write1 (conDataReg, val);
  214. break;
  215. default:
  216. ret_val = ILLEGAL_REG_OFFSET;
  217. break;
  218. }
  219. PSII_SYNC ();
  220. /* clear any pending master aborts */
  221. status = read4 (REG_P1_CSR);
  222. if (status & CLEAR_MASTER_ABORT) {
  223. ret_val = NO_DEVICE_FOUND;
  224. write4 (REG_P1_CSR, CLEAR_MASTER_ABORT);
  225. }
  226. return ret_val;
  227. }
  228. int pci_read_config_byte (int bus, int dev, int fn, int reg,
  229. unsigned char *val)
  230. {
  231. unsigned long read_val;
  232. int ret_val;
  233. ret_val = PCIReadConfig (bus, dev, fn, reg, 1, &read_val);
  234. *val = read_val & 0xFF;
  235. return ret_val;
  236. }
  237. int pci_write_config_byte (int bus, int dev, int fn, int reg,
  238. unsigned char val)
  239. {
  240. return PCIWriteConfig (bus, dev, fn, reg, 1, val);
  241. }
  242. int pci_read_config_word (int bus, int dev, int fn, int reg,
  243. unsigned short *val)
  244. {
  245. unsigned long read_val;
  246. int ret_val;
  247. ret_val = PCIReadConfig (bus, dev, fn, reg, 2, &read_val);
  248. *val = read_val & 0xFFFF;
  249. return ret_val;
  250. }
  251. int pci_write_config_word (int bus, int dev, int fn, int reg,
  252. unsigned short val)
  253. {
  254. return PCIWriteConfig (bus, dev, fn, reg, 2, val);
  255. }
  256. int pci_read_config_dword (int bus, int dev, int fn, int reg,
  257. unsigned long *val)
  258. {
  259. return PCIReadConfig (bus, dev, fn, reg, 4, val);
  260. }
  261. int pci_write_config_dword (int bus, int dev, int fn, int reg,
  262. unsigned long val)
  263. {
  264. return PCIWriteConfig (bus, dev, fn, reg, 4, val);
  265. }
  266. #endif /* INCLUDE_PCI */
  267. int I2CAccess (unsigned char theI2CAddress, unsigned char theDevCode,
  268. unsigned char theChipSel, unsigned char *theValue, int RWFlag)
  269. {
  270. int ret_val = 0;
  271. unsigned int reg_value;
  272. reg_value = PowerSpanRead (REG_I2C_CSR);
  273. if (reg_value & I2C_CSR_ACT) {
  274. printf ("Error: I2C busy\n");
  275. ret_val = I2C_BUSY;
  276. } else {
  277. reg_value = ((theI2CAddress & 0xFF) << 24)
  278. | ((theDevCode & 0x0F) << 12)
  279. | ((theChipSel & 0x07) << 9)
  280. | I2C_CSR_ERR;
  281. if (RWFlag == I2C_WRITE) {
  282. reg_value |= I2C_CSR_RW | ((*theValue & 0xFF) << 16);
  283. }
  284. PowerSpanWrite (REG_I2C_CSR, reg_value);
  285. udelay (1);
  286. do {
  287. reg_value = PowerSpanRead (REG_I2C_CSR);
  288. if ((reg_value & I2C_CSR_ACT) == 0) {
  289. if (reg_value & I2C_CSR_ERR) {
  290. ret_val = I2C_ERR;
  291. } else {
  292. *theValue =
  293. (reg_value & I2C_CSR_DATA) >>
  294. 16;
  295. }
  296. }
  297. } while (reg_value & I2C_CSR_ACT);
  298. }
  299. return ret_val;
  300. }
  301. int EEPROMRead (unsigned char theI2CAddress, unsigned char *theValue)
  302. {
  303. return I2CAccess (theI2CAddress, I2C_EEPROM_DEV, I2C_EEPROM_CHIP_SEL,
  304. theValue, I2C_READ);
  305. }
  306. int EEPROMWrite (unsigned char theI2CAddress, unsigned char theValue)
  307. {
  308. return I2CAccess (theI2CAddress, I2C_EEPROM_DEV, I2C_EEPROM_CHIP_SEL,
  309. &theValue, I2C_WRITE);
  310. }
  311. int do_eeprom (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
  312. {
  313. char cmd;
  314. int ret_val = 0;
  315. unsigned int address = 0;
  316. unsigned char value = 1;
  317. unsigned char read_value;
  318. int ii;
  319. int error = 0;
  320. unsigned char *mem_ptr;
  321. unsigned char default_eeprom[] = EEPROM_DEFAULT;
  322. if (argc < 2) {
  323. goto usage;
  324. }
  325. cmd = argv[1][0];
  326. if (argc > 2) {
  327. address = simple_strtoul (argv[2], NULL, 16);
  328. if (argc > 3) {
  329. value = simple_strtoul (argv[3], NULL, 16) & 0xFF;
  330. }
  331. }
  332. switch (cmd) {
  333. case 'r':
  334. if (address > 256) {
  335. printf ("Illegal Address\n");
  336. goto usage;
  337. }
  338. printf ("@0x%x: ", address);
  339. for (ii = 0; ii < value; ii++) {
  340. if (EEPROMRead (address + ii, &read_value) !=
  341. 0) {
  342. printf ("Read Error\n");
  343. } else {
  344. printf ("0x%02x ", read_value);
  345. }
  346. if (((ii + 1) % 16) == 0) {
  347. printf ("\n");
  348. }
  349. }
  350. printf ("\n");
  351. break;
  352. case 'w':
  353. if (address > 256) {
  354. printf ("Illegal Address\n");
  355. goto usage;
  356. }
  357. if (argc < 4) {
  358. goto usage;
  359. }
  360. if (EEPROMWrite (address, value) != 0) {
  361. printf ("Write Error\n");
  362. }
  363. break;
  364. case 'g':
  365. if (argc != 3) {
  366. goto usage;
  367. }
  368. mem_ptr = (unsigned char *) address;
  369. for (ii = 0; ((ii < EEPROM_LENGTH) && (error == 0));
  370. ii++) {
  371. if (EEPROMRead (ii, &read_value) != 0) {
  372. printf ("Read Error\n");
  373. error = 1;
  374. } else {
  375. *mem_ptr = read_value;
  376. mem_ptr++;
  377. }
  378. }
  379. break;
  380. case 'p':
  381. if (argc != 3) {
  382. goto usage;
  383. }
  384. mem_ptr = (unsigned char *) address;
  385. for (ii = 0; ((ii < EEPROM_LENGTH) && (error == 0));
  386. ii++) {
  387. if (EEPROMWrite (ii, *mem_ptr) != 0) {
  388. printf ("Write Error\n");
  389. error = 1;
  390. }
  391. mem_ptr++;
  392. }
  393. break;
  394. case 'd':
  395. if (argc != 2) {
  396. goto usage;
  397. }
  398. for (ii = 0; ((ii < EEPROM_LENGTH) && (error == 0));
  399. ii++) {
  400. if (EEPROMWrite (ii, default_eeprom[ii]) != 0) {
  401. printf ("Write Error\n");
  402. error = 1;
  403. }
  404. }
  405. break;
  406. default:
  407. goto usage;
  408. }
  409. goto done;
  410. usage:
  411. printf ("Usage:\n%s\n", cmdtp->help);
  412. done:
  413. return ret_val;
  414. }
  415. U_BOOT_CMD (eeprom, 4, 0, do_eeprom,
  416. "read/write/copy to/from the PowerSpan II eeprom",
  417. "eeprom r OFF [NUM]\n"
  418. " - read NUM words starting at OFF\n"
  419. "eeprom w OFF VAL\n"
  420. " - write word VAL at offset OFF\n"
  421. "eeprom g ADD\n"
  422. " - store contents of eeprom at address ADD\n"
  423. "eeprom p ADD\n"
  424. " - put data stored at address ADD into the eeprom\n"
  425. "eeprom d\n" " - return eeprom to default contents\n");
  426. unsigned int PowerSpanRead (unsigned int theOffset)
  427. {
  428. volatile unsigned int *ptr =
  429. (volatile unsigned int *) (PSPAN_BASEADDR + theOffset);
  430. unsigned int ret_val;
  431. #ifdef VERBOSITY
  432. if (gVerbosityLevel > 1) {
  433. printf ("PowerSpanRead: offset=%08x ", theOffset);
  434. }
  435. #endif
  436. ret_val = *ptr;
  437. PSII_SYNC ();
  438. #ifdef VERBOSITY
  439. if (gVerbosityLevel > 1) {
  440. printf ("value=%08x\n", ret_val);
  441. }
  442. #endif
  443. return ret_val;
  444. }
  445. void PowerSpanWrite (unsigned int theOffset, unsigned int theValue)
  446. {
  447. volatile unsigned int *ptr =
  448. (volatile unsigned int *) (PSPAN_BASEADDR + theOffset);
  449. #ifdef VERBOSITY
  450. if (gVerbosityLevel > 1) {
  451. printf ("PowerSpanWrite: offset=%08x val=%02x\n", theOffset,
  452. theValue);
  453. }
  454. #endif
  455. *ptr = theValue;
  456. PSII_SYNC ();
  457. }
  458. /**
  459. * Sets the indicated bits in the indicated register.
  460. * @param theOffset [IN] the register to access.
  461. * @param theMask [IN] bits set in theMask will be set in the register.
  462. */
  463. void PowerSpanSetBits (unsigned int theOffset, unsigned int theMask)
  464. {
  465. volatile unsigned int *ptr =
  466. (volatile unsigned int *) (PSPAN_BASEADDR + theOffset);
  467. unsigned int register_value;
  468. #ifdef VERBOSITY
  469. if (gVerbosityLevel > 1) {
  470. printf ("PowerSpanSetBits: offset=%08x mask=%02x\n",
  471. theOffset, theMask);
  472. }
  473. #endif
  474. register_value = *ptr;
  475. PSII_SYNC ();
  476. register_value |= theMask;
  477. *ptr = register_value;
  478. PSII_SYNC ();
  479. }
  480. /**
  481. * Clears the indicated bits in the indicated register.
  482. * @param theOffset [IN] the register to access.
  483. * @param theMask [IN] bits set in theMask will be cleared in the register.
  484. */
  485. void PowerSpanClearBits (unsigned int theOffset, unsigned int theMask)
  486. {
  487. volatile unsigned int *ptr =
  488. (volatile unsigned int *) (PSPAN_BASEADDR + theOffset);
  489. unsigned int register_value;
  490. #ifdef VERBOSITY
  491. if (gVerbosityLevel > 1) {
  492. printf ("PowerSpanClearBits: offset=%08x mask=%02x\n",
  493. theOffset, theMask);
  494. }
  495. #endif
  496. register_value = *ptr;
  497. PSII_SYNC ();
  498. register_value &= ~theMask;
  499. *ptr = register_value;
  500. PSII_SYNC ();
  501. }
  502. /**
  503. * Configures a slave image on the local bus, based on the parameters and some hardcoded system values.
  504. * Slave Images are images that cause the PowerSpan II to be a master on the PCI bus. Thus, they
  505. * are outgoing from the standpoint of the local bus.
  506. * @param theImageIndex [IN] the PowerSpan II image to set (assumed to be 0-7).
  507. * @param theBlockSize [IN] the block size of the image (as used by PowerSpan II: PB_SIx_CTL[BS]).
  508. * @param theMemIOFlag [IN] if PX_TGT_USE_MEM_IO, this image will have the MEM_IO bit set.
  509. * @param theEndianness [IN] the endian bits for the image (already shifted, use defines).
  510. * @param theLocalBaseAddr [IN] the Local address for the image (assumed to be valid with provided block size).
  511. * @param thePCIBaseAddr [IN] the PCI address for the image (assumed to be valid with provided block size).
  512. */
  513. int SetSlaveImage (int theImageIndex, unsigned int theBlockSize,
  514. int theMemIOFlag, int theEndianness,
  515. unsigned int theLocalBaseAddr, unsigned int thePCIBaseAddr)
  516. {
  517. unsigned int reg_offset = theImageIndex * PB_SLAVE_IMAGE_OFF;
  518. unsigned int reg_value = 0;
  519. /* Make sure that the Slave Image is disabled */
  520. PowerSpanClearBits ((REGS_PB_SLAVE_CSR + reg_offset),
  521. PB_SLAVE_CSR_IMG_EN);
  522. /* Setup the mask required for requested PB Slave Image configuration */
  523. reg_value = PB_SLAVE_CSR_TA_EN | theEndianness | (theBlockSize << 24);
  524. if (theMemIOFlag == PB_SLAVE_USE_MEM_IO) {
  525. reg_value |= PB_SLAVE_CSR_MEM_IO;
  526. }
  527. /* hardcoding the following:
  528. TA_EN = 1
  529. MD_EN = 0
  530. MODE = 0
  531. PRKEEP = 0
  532. RD_AMT = 0
  533. */
  534. PowerSpanWrite ((REGS_PB_SLAVE_CSR + reg_offset), reg_value);
  535. /* these values are not checked by software */
  536. PowerSpanWrite ((REGS_PB_SLAVE_BADDR + reg_offset), theLocalBaseAddr);
  537. PowerSpanWrite ((REGS_PB_SLAVE_TADDR + reg_offset), thePCIBaseAddr);
  538. /* Enable the Slave Image */
  539. PowerSpanSetBits ((REGS_PB_SLAVE_CSR + reg_offset),
  540. PB_SLAVE_CSR_IMG_EN);
  541. return 0;
  542. }
  543. /**
  544. * Configures a target image on the local bus, based on the parameters and some hardcoded system values.
  545. * Target Images are used when the PowerSpan II is acting as a target for an access. Thus, they
  546. * are incoming from the standpoint of the local bus.
  547. * In order to behave better on the host PCI bus, if thePCIBaseAddr is NULL (0x00000000), then the PCI
  548. * base address will not be updated; makes sense given that the hosts own memory should be mapped to
  549. * PCI address 0x00000000.
  550. * @param theImageIndex [IN] the PowerSpan II image to set.
  551. * @param theBlockSize [IN] the block size of the image (as used by PowerSpan II: Px_TIx_CTL[BS]).
  552. * @param theMemIOFlag [IN] if PX_TGT_USE_MEM_IO, this image will have the MEM_IO bit set.
  553. * @param theEndianness [IN] the endian bits for the image (already shifted, use defines).
  554. * @param theLocalBaseAddr [IN] the Local address for the image (assumed to be valid with provided block size).
  555. * @param thePCIBaseAddr [IN] the PCI address for the image (assumed to be valid with provided block size).
  556. */
  557. int SetTargetImage (int theImageIndex, unsigned int theBlockSize,
  558. int theMemIOFlag, int theEndianness,
  559. unsigned int theLocalBaseAddr,
  560. unsigned int thePCIBaseAddr)
  561. {
  562. unsigned int csr_reg_offset = theImageIndex * P1_TGT_IMAGE_OFF;
  563. unsigned int pci_reg_offset = theImageIndex * P1_BST_OFF;
  564. unsigned int reg_value = 0;
  565. /* Make sure that the Slave Image is disabled */
  566. PowerSpanClearBits ((REGS_P1_TGT_CSR + csr_reg_offset),
  567. PB_SLAVE_CSR_IMG_EN);
  568. /* Setup the mask required for requested PB Slave Image configuration */
  569. reg_value =
  570. PX_TGT_CSR_TA_EN | PX_TGT_CSR_BAR_EN | (theBlockSize << 24) |
  571. PX_TGT_CSR_RTT_READ | PX_TGT_CSR_WTT_WFLUSH | theEndianness;
  572. if (theMemIOFlag == PX_TGT_USE_MEM_IO) {
  573. reg_value |= PX_TGT_MEM_IO;
  574. }
  575. /* hardcoding the following:
  576. TA_EN = 1
  577. BAR_EN = 1
  578. MD_EN = 0
  579. MODE = 0
  580. DEST = 0
  581. RTT = 01010
  582. GBL = 0
  583. CI = 0
  584. WTT = 00010
  585. PRKEEP = 0
  586. MRA = 0
  587. RD_AMT = 0
  588. */
  589. PowerSpanWrite ((REGS_P1_TGT_CSR + csr_reg_offset), reg_value);
  590. PowerSpanWrite ((REGS_P1_TGT_TADDR + csr_reg_offset),
  591. theLocalBaseAddr);
  592. if (thePCIBaseAddr != (unsigned int) NULL) {
  593. PowerSpanWrite ((REGS_P1_BST + pci_reg_offset),
  594. thePCIBaseAddr);
  595. }
  596. /* Enable the Slave Image */
  597. PowerSpanSetBits ((REGS_P1_TGT_CSR + csr_reg_offset),
  598. PB_SLAVE_CSR_IMG_EN);
  599. return 0;
  600. }
  601. int do_bridge (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
  602. {
  603. char cmd;
  604. int ret_val = 1;
  605. unsigned int image_index;
  606. unsigned int block_size;
  607. unsigned int mem_io;
  608. unsigned int local_addr;
  609. unsigned int pci_addr;
  610. int endianness;
  611. if (argc != 8) {
  612. goto usage;
  613. }
  614. cmd = argv[1][0];
  615. image_index = simple_strtoul (argv[2], NULL, 16);
  616. block_size = simple_strtoul (argv[3], NULL, 16);
  617. mem_io = simple_strtoul (argv[4], NULL, 16);
  618. endianness = argv[5][0];
  619. local_addr = simple_strtoul (argv[6], NULL, 16);
  620. pci_addr = simple_strtoul (argv[7], NULL, 16);
  621. switch (cmd) {
  622. case 'i':
  623. if (tolower (endianness) == 'b') {
  624. endianness = PX_TGT_CSR_BIG_END;
  625. } else if (tolower (endianness) == 'l') {
  626. endianness = PX_TGT_CSR_TRUE_LEND;
  627. } else {
  628. goto usage;
  629. }
  630. SetTargetImage (image_index, block_size, mem_io,
  631. endianness, local_addr, pci_addr);
  632. break;
  633. case 'o':
  634. if (tolower (endianness) == 'b') {
  635. endianness = PB_SLAVE_CSR_BIG_END;
  636. } else if (tolower (endianness) == 'l') {
  637. endianness = PB_SLAVE_CSR_TRUE_LEND;
  638. } else {
  639. goto usage;
  640. }
  641. SetSlaveImage (image_index, block_size, mem_io,
  642. endianness, local_addr, pci_addr);
  643. break;
  644. default:
  645. goto usage;
  646. }
  647. goto done;
  648. usage:
  649. printf ("Usage:\n%s\n", cmdtp->help);
  650. done:
  651. return ret_val;
  652. }