powerspan.c 21 KB

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