pci.c 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691
  1. /* PCI.c - PCI functions */
  2. /* Copyright - Galileo technology. */
  3. #include <common.h>
  4. #include <pci.h>
  5. #include <galileo/pci.h>
  6. static const unsigned char pci_irq_swizzle[2][PCI_MAX_DEVICES] = {
  7. #ifdef CONFIG_ZUMA_V2
  8. {0,0,0,0,0,0,0,29, [8 ... PCI_MAX_DEVICES-1]=0},
  9. {0,0,0,0,0,0,0,28, [8 ... PCI_MAX_DEVICES-1]=0}
  10. #else /* EVB??? This is a guess */
  11. {0,0,0,0,0,0,0,27,27, [9 ... PCI_MAX_DEVICES-1]=0},
  12. {0,0,0,0,0,0,0,29,29, [9 ... PCI_MAX_DEVICES-1]=0}
  13. #endif
  14. };
  15. static const unsigned int pci_p2p_configuration_reg[]={
  16. PCI_0P2P_CONFIGURATION, PCI_1P2P_CONFIGURATION};
  17. static const unsigned int pci_configuration_address[]={
  18. PCI_0CONFIGURATION_ADDRESS, PCI_1CONFIGURATION_ADDRESS};
  19. static const unsigned int pci_configuration_data[]={
  20. PCI_0CONFIGURATION_DATA_VIRTUAL_REGISTER,
  21. PCI_1CONFIGURATION_DATA_VIRTUAL_REGISTER};
  22. static const unsigned int pci_error_cause_reg[]={
  23. PCI_0ERROR_CAUSE, PCI_1ERROR_CAUSE};
  24. static const unsigned int pci_arbiter_control[]={
  25. PCI_0ARBITER_CONTROL, PCI_1ARBITER_CONTROL};
  26. static const unsigned int pci_snoop_control_base_0_low[]={
  27. PCI_0SNOOP_CONTROL_BASE_0_LOW, PCI_1SNOOP_CONTROL_BASE_0_LOW};
  28. static const unsigned int pci_snoop_control_top_0[]={
  29. PCI_0SNOOP_CONTROL_TOP_0, PCI_1SNOOP_CONTROL_TOP_0};
  30. static const unsigned int pci_access_control_base_0_low[]={
  31. PCI_0ACCESS_CONTROL_BASE_0_LOW, PCI_1ACCESS_CONTROL_BASE_0_LOW};
  32. static const unsigned int pci_access_control_top_0[]={
  33. PCI_0ACCESS_CONTROL_TOP_0, PCI_1ACCESS_CONTROL_TOP_0};
  34. static const unsigned int pci_scs_bank_size[2][4] = {
  35. {PCI_0SCS_0_BANK_SIZE, PCI_0SCS_1_BANK_SIZE,
  36. PCI_0SCS_2_BANK_SIZE, PCI_0SCS_3_BANK_SIZE},
  37. {PCI_1SCS_0_BANK_SIZE, PCI_1SCS_1_BANK_SIZE,
  38. PCI_1SCS_2_BANK_SIZE, PCI_1SCS_3_BANK_SIZE}};
  39. static const unsigned int pci_p2p_configuration[] = {
  40. PCI_0P2P_CONFIGURATION, PCI_1P2P_CONFIGURATION};
  41. /********************************************************************
  42. * pciWriteConfigReg - Write to a PCI configuration register
  43. * - Make sure the GT is configured as a master before writing
  44. * to another device on the PCI.
  45. * - The function takes care of Big/Little endian conversion.
  46. *
  47. *
  48. * Inputs: unsigned int regOffset: The register offset as it apears in the GT spec
  49. * (or any other PCI device spec)
  50. * pciDevNum: The device number needs to be addressed.
  51. *
  52. * Configuration Address 0xCF8:
  53. *
  54. * 31 30 24 23 16 15 11 10 8 7 2 0 <=bit Number
  55. * |congif|Reserved| Bus |Device|Function|Register|00|
  56. * |Enable| |Number|Number| Number | Number | | <=field Name
  57. *
  58. *********************************************************************/
  59. void pciWriteConfigReg(PCI_HOST host, unsigned int regOffset,unsigned int pciDevNum,unsigned int data)
  60. {
  61. volatile unsigned int DataForAddrReg;
  62. unsigned int functionNum;
  63. unsigned int busNum = 0;
  64. unsigned int addr;
  65. if(pciDevNum > 32) /* illegal device Number */
  66. return;
  67. if(pciDevNum == SELF) /* configure our configuration space. */
  68. {
  69. pciDevNum = (GTREGREAD(pci_p2p_configuration_reg[host]) >> 24) & 0x1f;
  70. busNum = GTREGREAD(pci_p2p_configuration_reg[host]) & 0xff0000;
  71. }
  72. functionNum = regOffset & 0x00000700;
  73. pciDevNum = pciDevNum << 11;
  74. regOffset = regOffset & 0xfc;
  75. DataForAddrReg = ( regOffset | pciDevNum | functionNum | busNum) | BIT31;
  76. GT_REG_WRITE(pci_configuration_address[host],DataForAddrReg);
  77. GT_REG_READ(pci_configuration_address[host], &addr);
  78. if (addr != DataForAddrReg) return;
  79. GT_REG_WRITE(pci_configuration_data[host],data);
  80. }
  81. /********************************************************************
  82. * pciReadConfigReg - Read from a PCI0 configuration register
  83. * - Make sure the GT is configured as a master before reading
  84. * from another device on the PCI.
  85. * - The function takes care of Big/Little endian conversion.
  86. * INPUTS: regOffset: The register offset as it apears in the GT spec (or PCI
  87. * spec)
  88. * pciDevNum: The device number needs to be addressed.
  89. * RETURNS: data , if the data == 0xffffffff check the master abort bit in the
  90. * cause register to make sure the data is valid
  91. *
  92. * Configuration Address 0xCF8:
  93. *
  94. * 31 30 24 23 16 15 11 10 8 7 2 0 <=bit Number
  95. * |congif|Reserved| Bus |Device|Function|Register|00|
  96. * |Enable| |Number|Number| Number | Number | | <=field Name
  97. *
  98. *********************************************************************/
  99. unsigned int pciReadConfigReg (PCI_HOST host, unsigned int regOffset,unsigned int pciDevNum)
  100. {
  101. volatile unsigned int DataForAddrReg;
  102. unsigned int data;
  103. unsigned int functionNum;
  104. unsigned int busNum = 0;
  105. if(pciDevNum > 32) /* illegal device Number */
  106. return 0xffffffff;
  107. if(pciDevNum == SELF) /* configure our configuration space. */
  108. {
  109. pciDevNum = (GTREGREAD(pci_p2p_configuration_reg[host]) >> 24) & 0x1f;
  110. busNum = GTREGREAD(pci_p2p_configuration_reg[host]) & 0xff0000;
  111. }
  112. functionNum = regOffset & 0x00000700;
  113. pciDevNum = pciDevNum << 11;
  114. regOffset = regOffset & 0xfc;
  115. DataForAddrReg = (regOffset | pciDevNum | functionNum | busNum) | BIT31 ;
  116. GT_REG_WRITE(pci_configuration_address[host],DataForAddrReg);
  117. GT_REG_READ(pci_configuration_address[host], &data);
  118. if (data != DataForAddrReg)
  119. return 0xffffffff;
  120. GT_REG_READ(pci_configuration_data[host], &data);
  121. return data;
  122. }
  123. /********************************************************************
  124. * pciOverBridgeWriteConfigReg - Write to a PCI configuration register where
  125. * the agent is placed on another Bus. For more
  126. * information read P2P in the PCI spec.
  127. *
  128. * Inputs: unsigned int regOffset - The register offset as it apears in the
  129. * GT spec (or any other PCI device spec).
  130. * unsigned int pciDevNum - The device number needs to be addressed.
  131. * unsigned int busNum - On which bus does the Target agent connect
  132. * to.
  133. * unsigned int data - data to be written.
  134. *
  135. * Configuration Address 0xCF8:
  136. *
  137. * 31 30 24 23 16 15 11 10 8 7 2 0 <=bit Number
  138. * |congif|Reserved| Bus |Device|Function|Register|01|
  139. * |Enable| |Number|Number| Number | Number | | <=field Name
  140. *
  141. * The configuration Address is configure as type-I (bits[1:0] = '01') due to
  142. * PCI spec referring to P2P.
  143. *
  144. *********************************************************************/
  145. void pciOverBridgeWriteConfigReg(PCI_HOST host,
  146. unsigned int regOffset,
  147. unsigned int pciDevNum,
  148. unsigned int busNum,unsigned int data)
  149. {
  150. unsigned int DataForReg;
  151. unsigned int functionNum;
  152. functionNum = regOffset & 0x00000700;
  153. pciDevNum = pciDevNum << 11;
  154. regOffset = regOffset & 0xff;
  155. busNum = busNum << 16;
  156. if(pciDevNum == SELF) /* This board */
  157. {
  158. DataForReg = ( regOffset | pciDevNum | functionNum) | BIT0;
  159. }
  160. else
  161. {
  162. DataForReg = ( regOffset | pciDevNum | functionNum | busNum) |
  163. BIT31 | BIT0;
  164. }
  165. GT_REG_WRITE(pci_configuration_address[host],DataForReg);
  166. if(pciDevNum == SELF) /* This board */
  167. {
  168. GT_REG_WRITE(pci_configuration_data[host],data);
  169. }
  170. else /* configuration Transaction over the pci. */
  171. {
  172. /* The PCI is working in LE Mode So it swap the Data. */
  173. GT_REG_WRITE(pci_configuration_data[host],WORD_SWAP(data));
  174. }
  175. }
  176. /********************************************************************
  177. * pciOverBridgeReadConfigReg - Read from a PCIn configuration register where
  178. * the agent target locate on another PCI bus.
  179. * - Make sure the GT is configured as a master
  180. * before reading from another device on the PCI.
  181. * - The function takes care of Big/Little endian
  182. * conversion.
  183. * INPUTS: regOffset: The register offset as it apears in the GT spec (or PCI
  184. * spec). (configuration register offset.)
  185. * pciDevNum: The device number needs to be addressed.
  186. * busNum: the Bus number where the agent is place.
  187. * RETURNS: data , if the data == 0xffffffff check the master abort bit in the
  188. * cause register to make sure the data is valid
  189. *
  190. * Configuration Address 0xCF8:
  191. *
  192. * 31 30 24 23 16 15 11 10 8 7 2 0 <=bit Number
  193. * |congif|Reserved| Bus |Device|Function|Register|01|
  194. * |Enable| |Number|Number| Number | Number | | <=field Name
  195. *
  196. *********************************************************************/
  197. unsigned int pciOverBridgeReadConfigReg(PCI_HOST host,
  198. unsigned int regOffset,
  199. unsigned int pciDevNum,
  200. unsigned int busNum)
  201. {
  202. unsigned int DataForReg;
  203. unsigned int data;
  204. unsigned int functionNum;
  205. functionNum = regOffset & 0x00000700;
  206. pciDevNum = pciDevNum << 11;
  207. regOffset = regOffset & 0xff;
  208. busNum = busNum << 16;
  209. if (pciDevNum == SELF) /* This board */
  210. {
  211. DataForReg = (regOffset | pciDevNum | functionNum) | BIT31 ;
  212. }
  213. else /* agent on another bus */
  214. {
  215. DataForReg = (regOffset | pciDevNum | functionNum | busNum) |
  216. BIT0 | BIT31 ;
  217. }
  218. GT_REG_WRITE(pci_configuration_address[host],DataForReg);
  219. if (pciDevNum == SELF) /* This board */
  220. {
  221. GT_REG_READ(pci_configuration_data[host], &data);
  222. return data;
  223. }
  224. else /* The PCI is working in LE Mode So it swap the Data. */
  225. {
  226. GT_REG_READ(pci_configuration_data[host], &data);
  227. return WORD_SWAP(data);
  228. }
  229. }
  230. /********************************************************************
  231. * pciGetRegOffset - Gets the register offset for this region config.
  232. *
  233. * INPUT: Bus, Region - The bus and region we ask for its base address.
  234. * OUTPUT: N/A
  235. * RETURNS: PCI register base address
  236. *********************************************************************/
  237. static unsigned int pciGetRegOffset(PCI_HOST host, PCI_REGION region)
  238. {
  239. switch (host)
  240. {
  241. case PCI_HOST0:
  242. switch(region) {
  243. case PCI_IO: return PCI_0I_O_LOW_DECODE_ADDRESS;
  244. case PCI_REGION0: return PCI_0MEMORY0_LOW_DECODE_ADDRESS;
  245. case PCI_REGION1: return PCI_0MEMORY1_LOW_DECODE_ADDRESS;
  246. case PCI_REGION2: return PCI_0MEMORY2_LOW_DECODE_ADDRESS;
  247. case PCI_REGION3: return PCI_0MEMORY3_LOW_DECODE_ADDRESS;
  248. }
  249. case PCI_HOST1:
  250. switch(region) {
  251. case PCI_IO: return PCI_1I_O_LOW_DECODE_ADDRESS;
  252. case PCI_REGION0: return PCI_1MEMORY0_LOW_DECODE_ADDRESS;
  253. case PCI_REGION1: return PCI_1MEMORY1_LOW_DECODE_ADDRESS;
  254. case PCI_REGION2: return PCI_1MEMORY2_LOW_DECODE_ADDRESS;
  255. case PCI_REGION3: return PCI_1MEMORY3_LOW_DECODE_ADDRESS;
  256. }
  257. }
  258. return PCI_0MEMORY0_LOW_DECODE_ADDRESS;
  259. }
  260. static unsigned int pciGetRemapOffset(PCI_HOST host, PCI_REGION region)
  261. {
  262. switch (host)
  263. {
  264. case PCI_HOST0:
  265. switch(region) {
  266. case PCI_IO: return PCI_0I_O_ADDRESS_REMAP;
  267. case PCI_REGION0: return PCI_0MEMORY0_ADDRESS_REMAP;
  268. case PCI_REGION1: return PCI_0MEMORY1_ADDRESS_REMAP;
  269. case PCI_REGION2: return PCI_0MEMORY2_ADDRESS_REMAP;
  270. case PCI_REGION3: return PCI_0MEMORY3_ADDRESS_REMAP;
  271. }
  272. case PCI_HOST1:
  273. switch(region) {
  274. case PCI_IO: return PCI_1I_O_ADDRESS_REMAP;
  275. case PCI_REGION0: return PCI_1MEMORY0_ADDRESS_REMAP;
  276. case PCI_REGION1: return PCI_1MEMORY1_ADDRESS_REMAP;
  277. case PCI_REGION2: return PCI_1MEMORY2_ADDRESS_REMAP;
  278. case PCI_REGION3: return PCI_1MEMORY3_ADDRESS_REMAP;
  279. }
  280. }
  281. return PCI_0MEMORY0_ADDRESS_REMAP;
  282. }
  283. bool pciMapSpace(PCI_HOST host, PCI_REGION region, unsigned int remapBase, unsigned int bankBase,unsigned int bankLength)
  284. {
  285. unsigned int low=0xfff;
  286. unsigned int high=0x0;
  287. unsigned int regOffset=pciGetRegOffset(host, region);
  288. unsigned int remapOffset=pciGetRemapOffset(host, region);
  289. if(bankLength!=0) {
  290. low = (bankBase >> 20) & 0xfff;
  291. high=((bankBase+bankLength)>>20)-1;
  292. }
  293. GT_REG_WRITE(regOffset, low | (1<<24)); /* no swapping */
  294. GT_REG_WRITE(regOffset+8, high);
  295. if(bankLength!=0) { /* must do AFTER writing maps */
  296. GT_REG_WRITE(remapOffset, remapBase>>20); /* sorry, 32 bits only.
  297. dont support upper 32
  298. in this driver */
  299. }
  300. return true;
  301. }
  302. unsigned int pciGetSpaceBase(PCI_HOST host, PCI_REGION region)
  303. {
  304. unsigned int low;
  305. unsigned int regOffset=pciGetRegOffset(host, region);
  306. GT_REG_READ(regOffset,&low);
  307. return (low&0xfff)<<20;
  308. }
  309. unsigned int pciGetSpaceSize(PCI_HOST host, PCI_REGION region)
  310. {
  311. unsigned int low,high;
  312. unsigned int regOffset=pciGetRegOffset(host, region);
  313. GT_REG_READ(regOffset,&low);
  314. GT_REG_READ(regOffset+8,&high);
  315. high&=0xfff;
  316. low&=0xfff;
  317. if(high<=low) return 0;
  318. return (high+1-low)<<20;
  319. }
  320. /********************************************************************
  321. * pciMapMemoryBank - Maps PCI_host memory bank "bank" for the slave.
  322. *
  323. * Inputs: base and size of PCI SCS
  324. *********************************************************************/
  325. void pciMapMemoryBank(PCI_HOST host, MEMORY_BANK bank, unsigned int pciDramBase,unsigned int pciDramSize)
  326. {
  327. pciDramBase = pciDramBase & 0xfffff000;
  328. pciDramBase = pciDramBase | (pciReadConfigReg(host,
  329. PCI_SCS_0_BASE_ADDRESS + 4*bank,SELF) & 0x00000fff);
  330. pciWriteConfigReg(host,PCI_SCS_0_BASE_ADDRESS + 4*bank,SELF,pciDramBase);
  331. if(pciDramSize == 0)
  332. pciDramSize ++;
  333. GT_REG_WRITE(pci_scs_bank_size[host][bank], pciDramSize-1);
  334. }
  335. /********************************************************************
  336. * pciSetRegionFeatures - This function modifys one of the 8 regions with
  337. * feature bits given as an input.
  338. * - Be advised to check the spec before modifying them.
  339. * Inputs: PCI_PROTECT_REGION region - one of the eight regions.
  340. * unsigned int features - See file: pci.h there are defintion for those
  341. * region features.
  342. * unsigned int baseAddress - The region base Address.
  343. * unsigned int topAddress - The region top Address.
  344. * Returns: false if one of the parameters is erroneous true otherwise.
  345. *********************************************************************/
  346. bool pciSetRegionFeatures(PCI_HOST host, PCI_ACCESS_REGIONS region,unsigned int features,
  347. unsigned int baseAddress,unsigned int regionLength)
  348. {
  349. unsigned int accessLow;
  350. unsigned int accessHigh;
  351. unsigned int accessTop = baseAddress + regionLength;
  352. if(regionLength == 0) /* close the region. */
  353. {
  354. pciDisableAccessRegion(host, region);
  355. return true;
  356. }
  357. /* base Address is store is bits [11:0] */
  358. accessLow = (baseAddress & 0xfff00000) >> 20;
  359. /* All the features are update according to the defines in pci.h (to be on
  360. the safe side we disable bits: [11:0] */
  361. accessLow = accessLow | (features & 0xfffff000);
  362. /* write to the Low Access Region register */
  363. GT_REG_WRITE( pci_access_control_base_0_low[host] + 0x10*region,accessLow);
  364. accessHigh = (accessTop & 0xfff00000) >> 20;
  365. /* write to the High Access Region register */
  366. GT_REG_WRITE(pci_access_control_top_0[host] + 0x10*region,accessHigh - 1);
  367. return true;
  368. }
  369. /********************************************************************
  370. * pciDisableAccessRegion - Disable The given Region by writing MAX size
  371. * to its low Address and MIN size to its high Address.
  372. *
  373. * Inputs: PCI_ACCESS_REGIONS region - The region we to be Disabled.
  374. * Returns: N/A.
  375. *********************************************************************/
  376. void pciDisableAccessRegion(PCI_HOST host, PCI_ACCESS_REGIONS region)
  377. {
  378. /* writing back the registers default values. */
  379. GT_REG_WRITE(pci_access_control_base_0_low[host] + 0x10*region,0x01001fff);
  380. GT_REG_WRITE(pci_access_control_top_0[host] + 0x10*region,0);
  381. }
  382. /********************************************************************
  383. * pciArbiterEnable - Enables PCI-0`s Arbitration mechanism.
  384. *
  385. * Inputs: N/A
  386. * Returns: true.
  387. *********************************************************************/
  388. bool pciArbiterEnable(PCI_HOST host)
  389. {
  390. unsigned int regData;
  391. GT_REG_READ(pci_arbiter_control[host],&regData);
  392. GT_REG_WRITE(pci_arbiter_control[host],regData | BIT31);
  393. return true;
  394. }
  395. /********************************************************************
  396. * pciArbiterDisable - Disable PCI-0`s Arbitration mechanism.
  397. *
  398. * Inputs: N/A
  399. * Returns: true
  400. *********************************************************************/
  401. bool pciArbiterDisable(PCI_HOST host)
  402. {
  403. unsigned int regData;
  404. GT_REG_READ(pci_arbiter_control[host],&regData);
  405. GT_REG_WRITE(pci_arbiter_control[host],regData & 0x7fffffff);
  406. return true;
  407. }
  408. /********************************************************************
  409. * pciParkingDisable - Park on last option disable, with this function you can
  410. * disable the park on last mechanism for each agent.
  411. * disabling this option for all agents results parking
  412. * on the internal master.
  413. *
  414. * Inputs: PCI_AGENT_PARK internalAgent - parking Disable for internal agent.
  415. * PCI_AGENT_PARK externalAgent0 - parking Disable for external#0 agent.
  416. * PCI_AGENT_PARK externalAgent1 - parking Disable for external#1 agent.
  417. * PCI_AGENT_PARK externalAgent2 - parking Disable for external#2 agent.
  418. * PCI_AGENT_PARK externalAgent3 - parking Disable for external#3 agent.
  419. * PCI_AGENT_PARK externalAgent4 - parking Disable for external#4 agent.
  420. * PCI_AGENT_PARK externalAgent5 - parking Disable for external#5 agent.
  421. * Returns: true
  422. *********************************************************************/
  423. bool pciParkingDisable(PCI_HOST host, PCI_AGENT_PARK internalAgent,
  424. PCI_AGENT_PARK externalAgent0,
  425. PCI_AGENT_PARK externalAgent1,
  426. PCI_AGENT_PARK externalAgent2,
  427. PCI_AGENT_PARK externalAgent3,
  428. PCI_AGENT_PARK externalAgent4,
  429. PCI_AGENT_PARK externalAgent5)
  430. {
  431. unsigned int regData;
  432. unsigned int writeData;
  433. GT_REG_READ(pci_arbiter_control[host],&regData);
  434. writeData = (internalAgent << 14) + (externalAgent0 << 15) + \
  435. (externalAgent1 << 16) + (externalAgent2 << 17) + \
  436. (externalAgent3 << 18) + (externalAgent4 << 19) + \
  437. (externalAgent5 << 20);
  438. regData = (regData & ~(0x7f<<14)) | writeData;
  439. GT_REG_WRITE(pci_arbiter_control[host],regData);
  440. return true;
  441. }
  442. /********************************************************************
  443. * pciSetRegionSnoopMode - This function modifys one of the 4 regions which
  444. * supports Cache Coherency in the PCI_n interface.
  445. * Inputs: region - One of the four regions.
  446. * snoopType - There is four optional Types:
  447. * 1. No Snoop.
  448. * 2. Snoop to WT region.
  449. * 3. Snoop to WB region.
  450. * 4. Snoop & Invalidate to WB region.
  451. * baseAddress - Base Address of this region.
  452. * regionLength - Region length.
  453. * Returns: false if one of the parameters is wrong otherwise return true.
  454. *********************************************************************/
  455. bool pciSetRegionSnoopMode(PCI_HOST host, PCI_SNOOP_REGION region,PCI_SNOOP_TYPE snoopType,
  456. unsigned int baseAddress,
  457. unsigned int regionLength)
  458. {
  459. unsigned int snoopXbaseAddress;
  460. unsigned int snoopXtopAddress;
  461. unsigned int data;
  462. unsigned int snoopHigh = baseAddress + regionLength;
  463. if( (region > PCI_SNOOP_REGION3) || (snoopType > PCI_SNOOP_WB) )
  464. return false;
  465. snoopXbaseAddress = pci_snoop_control_base_0_low[host] + 0x10 * region;
  466. snoopXtopAddress = pci_snoop_control_top_0[host] + 0x10 * region;
  467. if(regionLength == 0) /* closing the region */
  468. {
  469. GT_REG_WRITE(snoopXbaseAddress,0x0000ffff);
  470. GT_REG_WRITE(snoopXtopAddress,0);
  471. return true;
  472. }
  473. baseAddress = baseAddress & 0xfff00000; /* Granularity of 1MByte */
  474. data = (baseAddress >> 20) | snoopType << 12;
  475. GT_REG_WRITE(snoopXbaseAddress,data);
  476. snoopHigh = (snoopHigh & 0xfff00000) >> 20;
  477. GT_REG_WRITE(snoopXtopAddress,snoopHigh - 1);
  478. return true;
  479. }
  480. /*
  481. *
  482. */
  483. static int gt_read_config_dword(struct pci_controller *hose,
  484. pci_dev_t dev,
  485. int offset, u32* value)
  486. {
  487. *value = pciReadConfigReg((PCI_HOST) hose->cfg_addr, offset, PCI_DEV(dev));
  488. return 0;
  489. }
  490. static int gt_write_config_dword(struct pci_controller *hose,
  491. pci_dev_t dev,
  492. int offset, u32 value)
  493. {
  494. pciWriteConfigReg((PCI_HOST)hose->cfg_addr, offset, PCI_DEV(dev), value);
  495. return 0;
  496. }
  497. /*
  498. *
  499. */
  500. static void gt_setup_ide(struct pci_controller *hose,
  501. pci_dev_t dev, struct pci_config_table *entry)
  502. {
  503. static const int ide_bar[]={8,4,8,4,0,0};
  504. u32 bar_response, bar_value;
  505. int bar;
  506. for (bar=0; bar<6; bar++)
  507. {
  508. pci_write_config_dword(dev, PCI_BASE_ADDRESS_0 + bar*4, 0x0);
  509. pci_read_config_dword(dev, PCI_BASE_ADDRESS_0 + bar*4, &bar_response);
  510. pciauto_region_allocate(bar_response & PCI_BASE_ADDRESS_SPACE_IO ?
  511. hose->pci_io : hose->pci_mem, ide_bar[bar], &bar_value);
  512. pci_write_config_dword(dev, PCI_BASE_ADDRESS_0 + bar*4, bar_value);
  513. }
  514. }
  515. static void gt_fixup_irq(struct pci_controller *hose, pci_dev_t dev)
  516. {
  517. unsigned char pin, irq;
  518. pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
  519. if(pin == 1) { /* only allow INT A */
  520. irq = pci_irq_swizzle[(PCI_HOST)hose->cfg_addr][PCI_DEV(dev)];
  521. if(irq)
  522. pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
  523. }
  524. }
  525. struct pci_config_table gt_config_table[] = {
  526. { PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_STORAGE_IDE,
  527. PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, gt_setup_ide},
  528. { }
  529. };
  530. struct pci_controller pci0_hose = {
  531. fixup_irq: gt_fixup_irq,
  532. config_table: gt_config_table,
  533. };
  534. struct pci_controller pci1_hose = {
  535. fixup_irq: gt_fixup_irq,
  536. config_table: gt_config_table,
  537. };
  538. void
  539. pci_init_board(void)
  540. {
  541. unsigned int command;
  542. pci0_hose.first_busno = 0;
  543. pci0_hose.last_busno = 0xff;
  544. /* PCI memory space */
  545. pci_set_region(pci0_hose.regions + 0,
  546. CFG_PCI0_0_MEM_SPACE,
  547. CFG_PCI0_0_MEM_SPACE,
  548. CFG_PCI0_MEM_SIZE,
  549. PCI_REGION_MEM);
  550. /* PCI I/O space */
  551. pci_set_region(pci0_hose.regions + 1,
  552. CFG_PCI0_IO_SPACE_PCI,
  553. CFG_PCI0_IO_SPACE,
  554. CFG_PCI0_IO_SIZE,
  555. PCI_REGION_IO);
  556. pci_set_ops(&pci0_hose,
  557. pci_hose_read_config_byte_via_dword,
  558. pci_hose_read_config_word_via_dword,
  559. gt_read_config_dword,
  560. pci_hose_write_config_byte_via_dword,
  561. pci_hose_write_config_word_via_dword,
  562. gt_write_config_dword);
  563. pci0_hose.region_count = 2;
  564. pci0_hose.cfg_addr = (unsigned int*) PCI_HOST0;
  565. pci_register_hose(&pci0_hose);
  566. pciArbiterEnable(PCI_HOST0);
  567. pciParkingDisable(PCI_HOST0,1,1,1,1,1,1,1);
  568. command = pciReadConfigReg(PCI_HOST0, PCI_COMMAND, SELF);
  569. command |= PCI_COMMAND_MASTER;
  570. pciWriteConfigReg(PCI_HOST0, PCI_COMMAND, SELF, command);
  571. pci0_hose.last_busno = pci_hose_scan(&pci0_hose);
  572. command = pciReadConfigReg(PCI_HOST0, PCI_COMMAND, SELF);
  573. command |= PCI_COMMAND_MEMORY;
  574. pciWriteConfigReg(PCI_HOST0, PCI_COMMAND, SELF, command);
  575. pci1_hose.first_busno = pci0_hose.last_busno + 1;
  576. pci1_hose.last_busno = 0xff;
  577. /* PCI memory space */
  578. pci_set_region(pci1_hose.regions + 0,
  579. CFG_PCI1_0_MEM_SPACE,
  580. CFG_PCI1_0_MEM_SPACE,
  581. CFG_PCI1_MEM_SIZE,
  582. PCI_REGION_MEM);
  583. /* PCI I/O space */
  584. pci_set_region(pci1_hose.regions + 1,
  585. CFG_PCI1_IO_SPACE_PCI,
  586. CFG_PCI1_IO_SPACE,
  587. CFG_PCI1_IO_SIZE,
  588. PCI_REGION_IO);
  589. pci_set_ops(&pci1_hose,
  590. pci_hose_read_config_byte_via_dword,
  591. pci_hose_read_config_word_via_dword,
  592. gt_read_config_dword,
  593. pci_hose_write_config_byte_via_dword,
  594. pci_hose_write_config_word_via_dword,
  595. gt_write_config_dword);
  596. pci1_hose.region_count = 2;
  597. pci1_hose.cfg_addr = (unsigned int*) PCI_HOST1;
  598. pci_register_hose(&pci1_hose);
  599. pciArbiterEnable(PCI_HOST1);
  600. pciParkingDisable(PCI_HOST1,1,1,1,1,1,1,1);
  601. command = pciReadConfigReg(PCI_HOST1, PCI_COMMAND, SELF);
  602. command |= PCI_COMMAND_MASTER;
  603. pciWriteConfigReg(PCI_HOST1, PCI_COMMAND, SELF, command);
  604. pci1_hose.last_busno = pci_hose_scan(&pci1_hose);
  605. command = pciReadConfigReg(PCI_HOST1, PCI_COMMAND, SELF);
  606. command |= PCI_COMMAND_MEMORY;
  607. pciWriteConfigReg(PCI_HOST1, PCI_COMMAND, SELF, command);
  608. }