pci.c 33 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024
  1. /*
  2. * (C) Copyright 2000
  3. * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
  4. *
  5. * See file CREDITS for list of people who contributed to this
  6. * project.
  7. *
  8. * This program is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU General Public License as
  10. * published by the Free Software Foundation; either version 2 of
  11. * the License, or (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program; if not, write to the Free Software
  20. * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  21. * MA 02111-1307 USA
  22. *
  23. */
  24. /* PCI.c - PCI functions */
  25. #include <common.h>
  26. #ifdef CONFIG_PCI
  27. #include <pci.h>
  28. #ifdef CONFIG_PCI_PNP
  29. int pciauto_region_allocate(struct pci_region* res, unsigned int size, unsigned int *bar);
  30. #endif
  31. #include "../../Marvell/include/pci.h"
  32. #undef DEBUG
  33. #undef IDE_SET_NATIVE_MODE
  34. static unsigned int local_buses[] = { 0, 0 };
  35. static const unsigned char pci_irq_swizzle[2][PCI_MAX_DEVICES] = {
  36. {0, 0, 0, 0, 0, 0, 0, 27, 27, [9 ... PCI_MAX_DEVICES - 1] = 0 },
  37. {0, 0, 0, 0, 0, 0, 0, 29, 29, [9 ... PCI_MAX_DEVICES - 1] = 0 },
  38. };
  39. #ifdef CONFIG_USE_CPCIDVI
  40. typedef struct {
  41. unsigned int base;
  42. unsigned int init;
  43. } GT_CPCIDVI_ROM_T;
  44. static GT_CPCIDVI_ROM_T gt_cpcidvi_rom = {0, 0};
  45. #endif
  46. #ifdef DEBUG
  47. static const unsigned int pci_bus_list[] = { PCI_0_MODE, PCI_1_MODE };
  48. static void gt_pci_bus_mode_display (PCI_HOST host)
  49. {
  50. unsigned int mode;
  51. mode = (GTREGREAD (pci_bus_list[host]) & (BIT4 | BIT5)) >> 4;
  52. switch (mode) {
  53. case 0:
  54. printf ("PCI %d bus mode: Conventional PCI\n", host);
  55. break;
  56. case 1:
  57. printf ("PCI %d bus mode: 66 MHz PCIX\n", host);
  58. break;
  59. case 2:
  60. printf ("PCI %d bus mode: 100 MHz PCIX\n", host);
  61. break;
  62. case 3:
  63. printf ("PCI %d bus mode: 133 MHz PCIX\n", host);
  64. break;
  65. default:
  66. printf ("Unknown BUS %d\n", mode);
  67. }
  68. }
  69. #endif
  70. static const unsigned int pci_p2p_configuration_reg[] = {
  71. PCI_0P2P_CONFIGURATION, PCI_1P2P_CONFIGURATION
  72. };
  73. static const unsigned int pci_configuration_address[] = {
  74. PCI_0CONFIGURATION_ADDRESS, PCI_1CONFIGURATION_ADDRESS
  75. };
  76. static const unsigned int pci_configuration_data[] = {
  77. PCI_0CONFIGURATION_DATA_VIRTUAL_REGISTER,
  78. PCI_1CONFIGURATION_DATA_VIRTUAL_REGISTER
  79. };
  80. static const unsigned int pci_error_cause_reg[] = {
  81. PCI_0ERROR_CAUSE, PCI_1ERROR_CAUSE
  82. };
  83. static const unsigned int pci_arbiter_control[] = {
  84. PCI_0ARBITER_CONTROL, PCI_1ARBITER_CONTROL
  85. };
  86. static const unsigned int pci_address_space_en[] = {
  87. PCI_0_BASE_ADDR_REG_ENABLE, PCI_1_BASE_ADDR_REG_ENABLE
  88. };
  89. static const unsigned int pci_snoop_control_base_0_low[] = {
  90. PCI_0SNOOP_CONTROL_BASE_0_LOW, PCI_1SNOOP_CONTROL_BASE_0_LOW
  91. };
  92. static const unsigned int pci_snoop_control_top_0[] = {
  93. PCI_0SNOOP_CONTROL_TOP_0, PCI_1SNOOP_CONTROL_TOP_0
  94. };
  95. static const unsigned int pci_access_control_base_0_low[] = {
  96. PCI_0ACCESS_CONTROL_BASE_0_LOW, PCI_1ACCESS_CONTROL_BASE_0_LOW
  97. };
  98. static const unsigned int pci_access_control_top_0[] = {
  99. PCI_0ACCESS_CONTROL_TOP_0, PCI_1ACCESS_CONTROL_TOP_0
  100. };
  101. static const unsigned int pci_scs_bank_size[2][4] = {
  102. {PCI_0SCS_0_BANK_SIZE, PCI_0SCS_1_BANK_SIZE,
  103. PCI_0SCS_2_BANK_SIZE, PCI_0SCS_3_BANK_SIZE},
  104. {PCI_1SCS_0_BANK_SIZE, PCI_1SCS_1_BANK_SIZE,
  105. PCI_1SCS_2_BANK_SIZE, PCI_1SCS_3_BANK_SIZE}
  106. };
  107. static const unsigned int pci_p2p_configuration[] = {
  108. PCI_0P2P_CONFIGURATION, PCI_1P2P_CONFIGURATION
  109. };
  110. /********************************************************************
  111. * pciWriteConfigReg - Write to a PCI configuration register
  112. * - Make sure the GT is configured as a master before writing
  113. * to another device on the PCI.
  114. * - The function takes care of Big/Little endian conversion.
  115. *
  116. *
  117. * Inputs: unsigned int regOffset: The register offset as it apears in the GT spec
  118. * (or any other PCI device spec)
  119. * pciDevNum: The device number needs to be addressed.
  120. *
  121. * Configuration Address 0xCF8:
  122. *
  123. * 31 30 24 23 16 15 11 10 8 7 2 0 <=bit Number
  124. * |congif|Reserved| Bus |Device|Function|Register|00|
  125. * |Enable| |Number|Number| Number | Number | | <=field Name
  126. *
  127. *********************************************************************/
  128. void pciWriteConfigReg (PCI_HOST host, unsigned int regOffset,
  129. unsigned int pciDevNum, unsigned int data)
  130. {
  131. volatile unsigned int DataForAddrReg;
  132. unsigned int functionNum;
  133. unsigned int busNum = 0;
  134. unsigned int addr;
  135. if (pciDevNum > 32) /* illegal device Number */
  136. return;
  137. if (pciDevNum == SELF) { /* configure our configuration space. */
  138. pciDevNum =
  139. (GTREGREAD (pci_p2p_configuration_reg[host]) >> 24) &
  140. 0x1f;
  141. busNum = GTREGREAD (pci_p2p_configuration_reg[host]) &
  142. 0xff0000;
  143. }
  144. functionNum = regOffset & 0x00000700;
  145. pciDevNum = pciDevNum << 11;
  146. regOffset = regOffset & 0xfc;
  147. DataForAddrReg =
  148. (regOffset | pciDevNum | functionNum | busNum) | BIT31;
  149. GT_REG_WRITE (pci_configuration_address[host], DataForAddrReg);
  150. GT_REG_READ (pci_configuration_address[host], &addr);
  151. if (addr != DataForAddrReg)
  152. return;
  153. GT_REG_WRITE (pci_configuration_data[host], data);
  154. }
  155. /********************************************************************
  156. * pciReadConfigReg - Read from a PCI0 configuration register
  157. * - Make sure the GT is configured as a master before reading
  158. * from another device on the PCI.
  159. * - The function takes care of Big/Little endian conversion.
  160. * INPUTS: regOffset: The register offset as it apears in the GT spec (or PCI
  161. * spec)
  162. * pciDevNum: The device number needs to be addressed.
  163. * RETURNS: data , if the data == 0xffffffff check the master abort bit in the
  164. * cause register to make sure the data is valid
  165. *
  166. * Configuration Address 0xCF8:
  167. *
  168. * 31 30 24 23 16 15 11 10 8 7 2 0 <=bit Number
  169. * |congif|Reserved| Bus |Device|Function|Register|00|
  170. * |Enable| |Number|Number| Number | Number | | <=field Name
  171. *
  172. *********************************************************************/
  173. unsigned int pciReadConfigReg (PCI_HOST host, unsigned int regOffset,
  174. unsigned int pciDevNum)
  175. {
  176. volatile unsigned int DataForAddrReg;
  177. unsigned int data;
  178. unsigned int functionNum;
  179. unsigned int busNum = 0;
  180. if (pciDevNum > 32) /* illegal device Number */
  181. return 0xffffffff;
  182. if (pciDevNum == SELF) { /* configure our configuration space. */
  183. pciDevNum =
  184. (GTREGREAD (pci_p2p_configuration_reg[host]) >> 24) &
  185. 0x1f;
  186. busNum = GTREGREAD (pci_p2p_configuration_reg[host]) &
  187. 0xff0000;
  188. }
  189. functionNum = regOffset & 0x00000700;
  190. pciDevNum = pciDevNum << 11;
  191. regOffset = regOffset & 0xfc;
  192. DataForAddrReg =
  193. (regOffset | pciDevNum | functionNum | busNum) | BIT31;
  194. GT_REG_WRITE (pci_configuration_address[host], DataForAddrReg);
  195. GT_REG_READ (pci_configuration_address[host], &data);
  196. if (data != DataForAddrReg)
  197. return 0xffffffff;
  198. GT_REG_READ (pci_configuration_data[host], &data);
  199. return data;
  200. }
  201. /********************************************************************
  202. * pciOverBridgeWriteConfigReg - Write to a PCI configuration register where
  203. * the agent is placed on another Bus. For more
  204. * information read P2P in the PCI spec.
  205. *
  206. * Inputs: unsigned int regOffset - The register offset as it apears in the
  207. * GT spec (or any other PCI device spec).
  208. * unsigned int pciDevNum - The device number needs to be addressed.
  209. * unsigned int busNum - On which bus does the Target agent connect
  210. * to.
  211. * unsigned int data - data to be written.
  212. *
  213. * Configuration Address 0xCF8:
  214. *
  215. * 31 30 24 23 16 15 11 10 8 7 2 0 <=bit Number
  216. * |congif|Reserved| Bus |Device|Function|Register|01|
  217. * |Enable| |Number|Number| Number | Number | | <=field Name
  218. *
  219. * The configuration Address is configure as type-I (bits[1:0] = '01') due to
  220. * PCI spec referring to P2P.
  221. *
  222. *********************************************************************/
  223. void pciOverBridgeWriteConfigReg (PCI_HOST host,
  224. unsigned int regOffset,
  225. unsigned int pciDevNum,
  226. unsigned int busNum, unsigned int data)
  227. {
  228. unsigned int DataForReg;
  229. unsigned int functionNum;
  230. functionNum = regOffset & 0x00000700;
  231. pciDevNum = pciDevNum << 11;
  232. regOffset = regOffset & 0xff;
  233. busNum = busNum << 16;
  234. if (pciDevNum == SELF) { /* This board */
  235. DataForReg = (regOffset | pciDevNum | functionNum) | BIT0;
  236. } else {
  237. DataForReg = (regOffset | pciDevNum | functionNum | busNum) |
  238. BIT31 | BIT0;
  239. }
  240. GT_REG_WRITE (pci_configuration_address[host], DataForReg);
  241. GT_REG_WRITE (pci_configuration_data[host], data);
  242. }
  243. /********************************************************************
  244. * pciOverBridgeReadConfigReg - Read from a PCIn configuration register where
  245. * the agent target locate on another PCI bus.
  246. * - Make sure the GT is configured as a master
  247. * before reading from another device on the PCI.
  248. * - The function takes care of Big/Little endian
  249. * conversion.
  250. * INPUTS: regOffset: The register offset as it apears in the GT spec (or PCI
  251. * spec). (configuration register offset.)
  252. * pciDevNum: The device number needs to be addressed.
  253. * busNum: the Bus number where the agent is place.
  254. * RETURNS: data , if the data == 0xffffffff check the master abort bit in the
  255. * cause register to make sure the data is valid
  256. *
  257. * Configuration Address 0xCF8:
  258. *
  259. * 31 30 24 23 16 15 11 10 8 7 2 0 <=bit Number
  260. * |congif|Reserved| Bus |Device|Function|Register|01|
  261. * |Enable| |Number|Number| Number | Number | | <=field Name
  262. *
  263. *********************************************************************/
  264. unsigned int pciOverBridgeReadConfigReg (PCI_HOST host,
  265. unsigned int regOffset,
  266. unsigned int pciDevNum,
  267. unsigned int busNum)
  268. {
  269. unsigned int DataForReg;
  270. unsigned int data;
  271. unsigned int functionNum;
  272. functionNum = regOffset & 0x00000700;
  273. pciDevNum = pciDevNum << 11;
  274. regOffset = regOffset & 0xff;
  275. busNum = busNum << 16;
  276. if (pciDevNum == SELF) { /* This board */
  277. DataForReg = (regOffset | pciDevNum | functionNum) | BIT31;
  278. } else { /* agent on another bus */
  279. DataForReg = (regOffset | pciDevNum | functionNum | busNum) |
  280. BIT0 | BIT31;
  281. }
  282. GT_REG_WRITE (pci_configuration_address[host], DataForReg);
  283. GT_REG_READ (pci_configuration_data[host], &data);
  284. return data;
  285. }
  286. /********************************************************************
  287. * pciGetRegOffset - Gets the register offset for this region config.
  288. *
  289. * INPUT: Bus, Region - The bus and region we ask for its base address.
  290. * OUTPUT: N/A
  291. * RETURNS: PCI register base address
  292. *********************************************************************/
  293. static unsigned int pciGetRegOffset (PCI_HOST host, PCI_REGION region)
  294. {
  295. switch (host) {
  296. case PCI_HOST0:
  297. switch (region) {
  298. case PCI_IO:
  299. return PCI_0I_O_LOW_DECODE_ADDRESS;
  300. case PCI_REGION0:
  301. return PCI_0MEMORY0_LOW_DECODE_ADDRESS;
  302. case PCI_REGION1:
  303. return PCI_0MEMORY1_LOW_DECODE_ADDRESS;
  304. case PCI_REGION2:
  305. return PCI_0MEMORY2_LOW_DECODE_ADDRESS;
  306. case PCI_REGION3:
  307. return PCI_0MEMORY3_LOW_DECODE_ADDRESS;
  308. }
  309. case PCI_HOST1:
  310. switch (region) {
  311. case PCI_IO:
  312. return PCI_1I_O_LOW_DECODE_ADDRESS;
  313. case PCI_REGION0:
  314. return PCI_1MEMORY0_LOW_DECODE_ADDRESS;
  315. case PCI_REGION1:
  316. return PCI_1MEMORY1_LOW_DECODE_ADDRESS;
  317. case PCI_REGION2:
  318. return PCI_1MEMORY2_LOW_DECODE_ADDRESS;
  319. case PCI_REGION3:
  320. return PCI_1MEMORY3_LOW_DECODE_ADDRESS;
  321. }
  322. }
  323. return PCI_0MEMORY0_LOW_DECODE_ADDRESS;
  324. }
  325. static unsigned int pciGetRemapOffset (PCI_HOST host, PCI_REGION region)
  326. {
  327. switch (host) {
  328. case PCI_HOST0:
  329. switch (region) {
  330. case PCI_IO:
  331. return PCI_0I_O_ADDRESS_REMAP;
  332. case PCI_REGION0:
  333. return PCI_0MEMORY0_ADDRESS_REMAP;
  334. case PCI_REGION1:
  335. return PCI_0MEMORY1_ADDRESS_REMAP;
  336. case PCI_REGION2:
  337. return PCI_0MEMORY2_ADDRESS_REMAP;
  338. case PCI_REGION3:
  339. return PCI_0MEMORY3_ADDRESS_REMAP;
  340. }
  341. case PCI_HOST1:
  342. switch (region) {
  343. case PCI_IO:
  344. return PCI_1I_O_ADDRESS_REMAP;
  345. case PCI_REGION0:
  346. return PCI_1MEMORY0_ADDRESS_REMAP;
  347. case PCI_REGION1:
  348. return PCI_1MEMORY1_ADDRESS_REMAP;
  349. case PCI_REGION2:
  350. return PCI_1MEMORY2_ADDRESS_REMAP;
  351. case PCI_REGION3:
  352. return PCI_1MEMORY3_ADDRESS_REMAP;
  353. }
  354. }
  355. return PCI_0MEMORY0_ADDRESS_REMAP;
  356. }
  357. /********************************************************************
  358. * pciGetBaseAddress - Gets the base address of a PCI.
  359. * - If the PCI size is 0 then this base address has no meaning!!!
  360. *
  361. *
  362. * INPUT: Bus, Region - The bus and region we ask for its base address.
  363. * OUTPUT: N/A
  364. * RETURNS: PCI base address.
  365. *********************************************************************/
  366. unsigned int pciGetBaseAddress (PCI_HOST host, PCI_REGION region)
  367. {
  368. unsigned int regBase;
  369. unsigned int regEnd;
  370. unsigned int regOffset = pciGetRegOffset (host, region);
  371. GT_REG_READ (regOffset, &regBase);
  372. GT_REG_READ (regOffset + 8, &regEnd);
  373. if (regEnd <= regBase)
  374. return 0xffffffff; /* ERROR !!! */
  375. regBase = regBase << 16;
  376. return regBase;
  377. }
  378. bool pciMapSpace (PCI_HOST host, PCI_REGION region, unsigned int remapBase,
  379. unsigned int bankBase, unsigned int bankLength)
  380. {
  381. unsigned int low = 0xfff;
  382. unsigned int high = 0x0;
  383. unsigned int regOffset = pciGetRegOffset (host, region);
  384. unsigned int remapOffset = pciGetRemapOffset (host, region);
  385. if (bankLength != 0) {
  386. low = (bankBase >> 16) & 0xffff;
  387. high = ((bankBase + bankLength) >> 16) - 1;
  388. }
  389. GT_REG_WRITE (regOffset, low | (1 << 24)); /* no swapping */
  390. GT_REG_WRITE (regOffset + 8, high);
  391. if (bankLength != 0) { /* must do AFTER writing maps */
  392. GT_REG_WRITE (remapOffset, remapBase >> 16); /* sorry, 32 bits only.
  393. dont support upper 32
  394. in this driver */
  395. }
  396. return true;
  397. }
  398. unsigned int pciGetSpaceBase (PCI_HOST host, PCI_REGION region)
  399. {
  400. unsigned int low;
  401. unsigned int regOffset = pciGetRegOffset (host, region);
  402. GT_REG_READ (regOffset, &low);
  403. return (low & 0xffff) << 16;
  404. }
  405. unsigned int pciGetSpaceSize (PCI_HOST host, PCI_REGION region)
  406. {
  407. unsigned int low, high;
  408. unsigned int regOffset = pciGetRegOffset (host, region);
  409. GT_REG_READ (regOffset, &low);
  410. GT_REG_READ (regOffset + 8, &high);
  411. return ((high & 0xffff) + 1) << 16;
  412. }
  413. /* ronen - 7/Dec/03*/
  414. /********************************************************************
  415. * gtPciDisable/EnableInternalBAR - This function enable/disable PCI BARS.
  416. * Inputs: one of the PCI BAR
  417. *********************************************************************/
  418. void gtPciEnableInternalBAR (PCI_HOST host, PCI_INTERNAL_BAR pciBAR)
  419. {
  420. RESET_REG_BITS (pci_address_space_en[host], BIT0 << pciBAR);
  421. }
  422. void gtPciDisableInternalBAR (PCI_HOST host, PCI_INTERNAL_BAR pciBAR)
  423. {
  424. SET_REG_BITS (pci_address_space_en[host], BIT0 << pciBAR);
  425. }
  426. /********************************************************************
  427. * pciMapMemoryBank - Maps PCI_host memory bank "bank" for the slave.
  428. *
  429. * Inputs: base and size of PCI SCS
  430. *********************************************************************/
  431. void pciMapMemoryBank (PCI_HOST host, MEMORY_BANK bank,
  432. unsigned int pciDramBase, unsigned int pciDramSize)
  433. {
  434. /*ronen different function for 3rd bank. */
  435. unsigned int offset = (bank < 2) ? bank * 8 : 0x100 + (bank - 2) * 8;
  436. pciDramBase = pciDramBase & 0xfffff000;
  437. pciDramBase = pciDramBase | (pciReadConfigReg (host,
  438. PCI_SCS_0_BASE_ADDRESS
  439. + offset,
  440. SELF) & 0x00000fff);
  441. pciWriteConfigReg (host, PCI_SCS_0_BASE_ADDRESS + offset, SELF,
  442. pciDramBase);
  443. if (pciDramSize == 0)
  444. pciDramSize++;
  445. GT_REG_WRITE (pci_scs_bank_size[host][bank], pciDramSize - 1);
  446. gtPciEnableInternalBAR (host, bank);
  447. }
  448. /********************************************************************
  449. * pciSetRegionFeatures - This function modifys one of the 8 regions with
  450. * feature bits given as an input.
  451. * - Be advised to check the spec before modifying them.
  452. * Inputs: PCI_PROTECT_REGION region - one of the eight regions.
  453. * unsigned int features - See file: pci.h there are defintion for those
  454. * region features.
  455. * unsigned int baseAddress - The region base Address.
  456. * unsigned int topAddress - The region top Address.
  457. * Returns: false if one of the parameters is erroneous true otherwise.
  458. *********************************************************************/
  459. bool pciSetRegionFeatures (PCI_HOST host, PCI_ACCESS_REGIONS region,
  460. unsigned int features, unsigned int baseAddress,
  461. unsigned int regionLength)
  462. {
  463. unsigned int accessLow;
  464. unsigned int accessHigh;
  465. unsigned int accessTop = baseAddress + regionLength;
  466. if (regionLength == 0) { /* close the region. */
  467. pciDisableAccessRegion (host, region);
  468. return true;
  469. }
  470. /* base Address is store is bits [11:0] */
  471. accessLow = (baseAddress & 0xfff00000) >> 20;
  472. /* All the features are update according to the defines in pci.h (to be on
  473. the safe side we disable bits: [11:0] */
  474. accessLow = accessLow | (features & 0xfffff000);
  475. /* write to the Low Access Region register */
  476. GT_REG_WRITE (pci_access_control_base_0_low[host] + 0x10 * region,
  477. accessLow);
  478. accessHigh = (accessTop & 0xfff00000) >> 20;
  479. /* write to the High Access Region register */
  480. GT_REG_WRITE (pci_access_control_top_0[host] + 0x10 * region,
  481. accessHigh - 1);
  482. return true;
  483. }
  484. /********************************************************************
  485. * pciDisableAccessRegion - Disable The given Region by writing MAX size
  486. * to its low Address and MIN size to its high Address.
  487. *
  488. * Inputs: PCI_ACCESS_REGIONS region - The region we to be Disabled.
  489. * Returns: N/A.
  490. *********************************************************************/
  491. void pciDisableAccessRegion (PCI_HOST host, PCI_ACCESS_REGIONS region)
  492. {
  493. /* writing back the registers default values. */
  494. GT_REG_WRITE (pci_access_control_base_0_low[host] + 0x10 * region,
  495. 0x01001fff);
  496. GT_REG_WRITE (pci_access_control_top_0[host] + 0x10 * region, 0);
  497. }
  498. /********************************************************************
  499. * pciArbiterEnable - Enables PCI-0`s Arbitration mechanism.
  500. *
  501. * Inputs: N/A
  502. * Returns: true.
  503. *********************************************************************/
  504. bool pciArbiterEnable (PCI_HOST host)
  505. {
  506. unsigned int regData;
  507. GT_REG_READ (pci_arbiter_control[host], &regData);
  508. GT_REG_WRITE (pci_arbiter_control[host], regData | BIT31);
  509. return true;
  510. }
  511. /********************************************************************
  512. * pciArbiterDisable - Disable PCI-0`s Arbitration mechanism.
  513. *
  514. * Inputs: N/A
  515. * Returns: true
  516. *********************************************************************/
  517. bool pciArbiterDisable (PCI_HOST host)
  518. {
  519. unsigned int regData;
  520. GT_REG_READ (pci_arbiter_control[host], &regData);
  521. GT_REG_WRITE (pci_arbiter_control[host], regData & 0x7fffffff);
  522. return true;
  523. }
  524. /********************************************************************
  525. * pciSetArbiterAgentsPriority - Priority setup for the PCI agents (Hi or Low)
  526. *
  527. * Inputs: PCI_AGENT_PRIO internalAgent - priotity for internal agent.
  528. * PCI_AGENT_PRIO externalAgent0 - priotity for external#0 agent.
  529. * PCI_AGENT_PRIO externalAgent1 - priotity for external#1 agent.
  530. * PCI_AGENT_PRIO externalAgent2 - priotity for external#2 agent.
  531. * PCI_AGENT_PRIO externalAgent3 - priotity for external#3 agent.
  532. * PCI_AGENT_PRIO externalAgent4 - priotity for external#4 agent.
  533. * PCI_AGENT_PRIO externalAgent5 - priotity for external#5 agent.
  534. * Returns: true
  535. *********************************************************************/
  536. bool pciSetArbiterAgentsPriority (PCI_HOST host, PCI_AGENT_PRIO internalAgent,
  537. PCI_AGENT_PRIO externalAgent0,
  538. PCI_AGENT_PRIO externalAgent1,
  539. PCI_AGENT_PRIO externalAgent2,
  540. PCI_AGENT_PRIO externalAgent3,
  541. PCI_AGENT_PRIO externalAgent4,
  542. PCI_AGENT_PRIO externalAgent5)
  543. {
  544. unsigned int regData;
  545. unsigned int writeData;
  546. GT_REG_READ (pci_arbiter_control[host], &regData);
  547. writeData = (internalAgent << 7) + (externalAgent0 << 8) +
  548. (externalAgent1 << 9) + (externalAgent2 << 10) +
  549. (externalAgent3 << 11) + (externalAgent4 << 12) +
  550. (externalAgent5 << 13);
  551. regData = (regData & 0xffffc07f) | writeData;
  552. GT_REG_WRITE (pci_arbiter_control[host], regData & regData);
  553. return true;
  554. }
  555. /********************************************************************
  556. * pciParkingDisable - Park on last option disable, with this function you can
  557. * disable the park on last mechanism for each agent.
  558. * disabling this option for all agents results parking
  559. * on the internal master.
  560. *
  561. * Inputs: PCI_AGENT_PARK internalAgent - parking Disable for internal agent.
  562. * PCI_AGENT_PARK externalAgent0 - parking Disable for external#0 agent.
  563. * PCI_AGENT_PARK externalAgent1 - parking Disable for external#1 agent.
  564. * PCI_AGENT_PARK externalAgent2 - parking Disable for external#2 agent.
  565. * PCI_AGENT_PARK externalAgent3 - parking Disable for external#3 agent.
  566. * PCI_AGENT_PARK externalAgent4 - parking Disable for external#4 agent.
  567. * PCI_AGENT_PARK externalAgent5 - parking Disable for external#5 agent.
  568. * Returns: true
  569. *********************************************************************/
  570. bool pciParkingDisable (PCI_HOST host, PCI_AGENT_PARK internalAgent,
  571. PCI_AGENT_PARK externalAgent0,
  572. PCI_AGENT_PARK externalAgent1,
  573. PCI_AGENT_PARK externalAgent2,
  574. PCI_AGENT_PARK externalAgent3,
  575. PCI_AGENT_PARK externalAgent4,
  576. PCI_AGENT_PARK externalAgent5)
  577. {
  578. unsigned int regData;
  579. unsigned int writeData;
  580. GT_REG_READ (pci_arbiter_control[host], &regData);
  581. writeData = (internalAgent << 14) + (externalAgent0 << 15) +
  582. (externalAgent1 << 16) + (externalAgent2 << 17) +
  583. (externalAgent3 << 18) + (externalAgent4 << 19) +
  584. (externalAgent5 << 20);
  585. regData = (regData & ~(0x7f << 14)) | writeData;
  586. GT_REG_WRITE (pci_arbiter_control[host], regData);
  587. return true;
  588. }
  589. /********************************************************************
  590. * pciEnableBrokenAgentDetection - A master is said to be broken if it fails to
  591. * respond to grant assertion within a window specified in
  592. * the input value: 'brokenValue'.
  593. *
  594. * Inputs: unsigned char brokenValue - A value which limits the Master to hold the
  595. * grant without asserting frame.
  596. * Returns: Error for illegal broken value otherwise true.
  597. *********************************************************************/
  598. bool pciEnableBrokenAgentDetection (PCI_HOST host, unsigned char brokenValue)
  599. {
  600. unsigned int data;
  601. unsigned int regData;
  602. if (brokenValue > 0xf)
  603. return false; /* brokenValue must be 4 bit */
  604. data = brokenValue << 3;
  605. GT_REG_READ (pci_arbiter_control[host], &regData);
  606. regData = (regData & 0xffffff87) | data;
  607. GT_REG_WRITE (pci_arbiter_control[host], regData | BIT1);
  608. return true;
  609. }
  610. /********************************************************************
  611. * pciDisableBrokenAgentDetection - This function disable the Broken agent
  612. * Detection mechanism.
  613. * NOTE: This operation may cause a dead lock on the
  614. * pci0 arbitration.
  615. *
  616. * Inputs: N/A
  617. * Returns: true.
  618. *********************************************************************/
  619. bool pciDisableBrokenAgentDetection (PCI_HOST host)
  620. {
  621. unsigned int regData;
  622. GT_REG_READ (pci_arbiter_control[host], &regData);
  623. regData = regData & 0xfffffffd;
  624. GT_REG_WRITE (pci_arbiter_control[host], regData);
  625. return true;
  626. }
  627. /********************************************************************
  628. * pciP2PConfig - This function set the PCI_n P2P configurate.
  629. * For more information on the P2P read PCI spec.
  630. *
  631. * Inputs: unsigned int SecondBusLow - Secondery PCI interface Bus Range Lower
  632. * Boundry.
  633. * unsigned int SecondBusHigh - Secondry PCI interface Bus Range upper
  634. * Boundry.
  635. * unsigned int busNum - The CPI bus number to which the PCI interface
  636. * is connected.
  637. * unsigned int devNum - The PCI interface's device number.
  638. *
  639. * Returns: true.
  640. *********************************************************************/
  641. bool pciP2PConfig (PCI_HOST host, unsigned int SecondBusLow,
  642. unsigned int SecondBusHigh,
  643. unsigned int busNum, unsigned int devNum)
  644. {
  645. unsigned int regData;
  646. regData = (SecondBusLow & 0xff) | ((SecondBusHigh & 0xff) << 8) |
  647. ((busNum & 0xff) << 16) | ((devNum & 0x1f) << 24);
  648. GT_REG_WRITE (pci_p2p_configuration[host], regData);
  649. return true;
  650. }
  651. /********************************************************************
  652. * pciSetRegionSnoopMode - This function modifys one of the 4 regions which
  653. * supports Cache Coherency in the PCI_n interface.
  654. * Inputs: region - One of the four regions.
  655. * snoopType - There is four optional Types:
  656. * 1. No Snoop.
  657. * 2. Snoop to WT region.
  658. * 3. Snoop to WB region.
  659. * 4. Snoop & Invalidate to WB region.
  660. * baseAddress - Base Address of this region.
  661. * regionLength - Region length.
  662. * Returns: false if one of the parameters is wrong otherwise return true.
  663. *********************************************************************/
  664. bool pciSetRegionSnoopMode (PCI_HOST host, PCI_SNOOP_REGION region,
  665. PCI_SNOOP_TYPE snoopType,
  666. unsigned int baseAddress,
  667. unsigned int regionLength)
  668. {
  669. unsigned int snoopXbaseAddress;
  670. unsigned int snoopXtopAddress;
  671. unsigned int data;
  672. unsigned int snoopHigh = baseAddress + regionLength;
  673. if ((region > PCI_SNOOP_REGION3) || (snoopType > PCI_SNOOP_WB))
  674. return false;
  675. snoopXbaseAddress =
  676. pci_snoop_control_base_0_low[host] + 0x10 * region;
  677. snoopXtopAddress = pci_snoop_control_top_0[host] + 0x10 * region;
  678. if (regionLength == 0) { /* closing the region */
  679. GT_REG_WRITE (snoopXbaseAddress, 0x0000ffff);
  680. GT_REG_WRITE (snoopXtopAddress, 0);
  681. return true;
  682. }
  683. baseAddress = baseAddress & 0xfff00000; /* Granularity of 1MByte */
  684. data = (baseAddress >> 20) | snoopType << 12;
  685. GT_REG_WRITE (snoopXbaseAddress, data);
  686. snoopHigh = (snoopHigh & 0xfff00000) >> 20;
  687. GT_REG_WRITE (snoopXtopAddress, snoopHigh - 1);
  688. return true;
  689. }
  690. static int gt_read_config_dword (struct pci_controller *hose,
  691. pci_dev_t dev, int offset, u32 * value)
  692. {
  693. int bus = PCI_BUS (dev);
  694. if ((bus == local_buses[0]) || (bus == local_buses[1])) {
  695. *value = pciReadConfigReg ((PCI_HOST) hose->cfg_addr, offset,
  696. PCI_DEV (dev));
  697. } else {
  698. *value = pciOverBridgeReadConfigReg ((PCI_HOST) hose->
  699. cfg_addr, offset,
  700. PCI_DEV (dev), bus);
  701. }
  702. return 0;
  703. }
  704. static int gt_write_config_dword (struct pci_controller *hose,
  705. pci_dev_t dev, int offset, u32 value)
  706. {
  707. int bus = PCI_BUS (dev);
  708. if ((bus == local_buses[0]) || (bus == local_buses[1])) {
  709. pciWriteConfigReg ((PCI_HOST) hose->cfg_addr, offset,
  710. PCI_DEV (dev), value);
  711. } else {
  712. pciOverBridgeWriteConfigReg ((PCI_HOST) hose->cfg_addr,
  713. offset, PCI_DEV (dev), bus,
  714. value);
  715. }
  716. return 0;
  717. }
  718. static void gt_setup_ide (struct pci_controller *hose,
  719. pci_dev_t dev, struct pci_config_table *entry)
  720. {
  721. static const int ide_bar[] = { 8, 4, 8, 4, 0, 0 };
  722. u32 bar_response, bar_value;
  723. int bar;
  724. for (bar = 0; bar < 6; bar++) {
  725. /*ronen different function for 3rd bank. */
  726. unsigned int offset =
  727. (bar < 2) ? bar * 8 : 0x100 + (bar - 2) * 8;
  728. pci_hose_write_config_dword (hose, dev, PCI_BASE_ADDRESS_0 + offset,
  729. 0x0);
  730. pci_hose_read_config_dword (hose, dev, PCI_BASE_ADDRESS_0 + offset,
  731. &bar_response);
  732. pciauto_region_allocate (bar_response &
  733. PCI_BASE_ADDRESS_SPACE_IO ? hose->
  734. pci_io : hose->pci_mem, ide_bar[bar],
  735. &bar_value);
  736. pci_hose_write_config_dword (hose, dev, PCI_BASE_ADDRESS_0 + bar * 4,
  737. bar_value);
  738. }
  739. }
  740. #ifdef CONFIG_USE_CPCIDVI
  741. static void gt_setup_cpcidvi (struct pci_controller *hose,
  742. pci_dev_t dev, struct pci_config_table *entry)
  743. {
  744. u32 bar_value, pci_response;
  745. pci_hose_read_config_dword (hose, dev, PCI_COMMAND, &pci_response);
  746. pci_hose_write_config_dword (hose, dev, PCI_BASE_ADDRESS_0, 0xffffffff);
  747. pci_hose_read_config_dword (hose, dev, PCI_BASE_ADDRESS_0, &pci_response);
  748. pciauto_region_allocate (hose->pci_mem, 0x01000000, &bar_value);
  749. pci_hose_write_config_dword (hose, dev, PCI_BASE_ADDRESS_0, (bar_value & 0xffffff00));
  750. pci_hose_write_config_dword (hose, dev, PCI_ROM_ADDRESS, 0x0);
  751. pciauto_region_allocate (hose->pci_mem, 0x40000, &bar_value);
  752. pci_hose_write_config_dword (hose, dev, PCI_ROM_ADDRESS, (bar_value & 0xffffff00) | 0x01);
  753. gt_cpcidvi_rom.base = bar_value & 0xffffff00;
  754. gt_cpcidvi_rom.init = 1;
  755. }
  756. unsigned char gt_cpcidvi_in8(unsigned int offset)
  757. {
  758. unsigned char data;
  759. if (gt_cpcidvi_rom.init == 0) {
  760. return(0);
  761. }
  762. data = in8((offset & 0x04) + 0x3f000 + gt_cpcidvi_rom.base);
  763. return(data);
  764. }
  765. void gt_cpcidvi_out8(unsigned int offset, unsigned char data)
  766. {
  767. unsigned int off;
  768. if (gt_cpcidvi_rom.init == 0) {
  769. return;
  770. }
  771. off = data;
  772. off = ((off << 3) & 0x7f8) + (offset & 0x4) + 0x3e000 + gt_cpcidvi_rom.base;
  773. in8(off);
  774. return;
  775. }
  776. #endif
  777. /* TODO BJW: Change this for DB64360. This was pulled from the EV64260 */
  778. /* and is curently not called *. */
  779. #if 0
  780. static void gt_fixup_irq (struct pci_controller *hose, pci_dev_t dev)
  781. {
  782. unsigned char pin, irq;
  783. pci_read_config_byte (dev, PCI_INTERRUPT_PIN, &pin);
  784. if (pin == 1) { /* only allow INT A */
  785. irq = pci_irq_swizzle[(PCI_HOST) hose->
  786. cfg_addr][PCI_DEV (dev)];
  787. if (irq)
  788. pci_write_config_byte (dev, PCI_INTERRUPT_LINE, irq);
  789. }
  790. }
  791. #endif
  792. struct pci_config_table gt_config_table[] = {
  793. #ifdef CONFIG_USE_CPCIDVI
  794. {PCI_VENDOR_ID_CT, PCI_DEVICE_ID_CT_69030, PCI_CLASS_DISPLAY_VGA,
  795. PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, gt_setup_cpcidvi},
  796. #endif
  797. {PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_STORAGE_IDE,
  798. PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, gt_setup_ide},
  799. {}
  800. };
  801. struct pci_controller pci0_hose = {
  802. /* fixup_irq: gt_fixup_irq, */
  803. config_table:gt_config_table,
  804. };
  805. struct pci_controller pci1_hose = {
  806. /* fixup_irq: gt_fixup_irq, */
  807. config_table:gt_config_table,
  808. };
  809. void pci_init_board (void)
  810. {
  811. unsigned int command;
  812. #ifdef CONFIG_PCI_PNP
  813. unsigned int bar;
  814. #endif
  815. #ifdef DEBUG
  816. gt_pci_bus_mode_display (PCI_HOST0);
  817. #endif
  818. #ifdef CONFIG_USE_CPCIDVI
  819. gt_cpcidvi_rom.init = 0;
  820. gt_cpcidvi_rom.base = 0;
  821. #endif
  822. pci0_hose.config_table = gt_config_table;
  823. pci1_hose.config_table = gt_config_table;
  824. #ifdef CONFIG_USE_CPCIDVI
  825. gt_config_table[0].config_device = gt_setup_cpcidvi;
  826. #endif
  827. gt_config_table[1].config_device = gt_setup_ide;
  828. pci0_hose.first_busno = 0;
  829. pci0_hose.last_busno = 0xff;
  830. local_buses[0] = pci0_hose.first_busno;
  831. /* PCI memory space */
  832. pci_set_region (pci0_hose.regions + 0,
  833. CONFIG_SYS_PCI0_0_MEM_SPACE,
  834. CONFIG_SYS_PCI0_0_MEM_SPACE,
  835. CONFIG_SYS_PCI0_MEM_SIZE, PCI_REGION_MEM);
  836. /* PCI I/O space */
  837. pci_set_region (pci0_hose.regions + 1,
  838. CONFIG_SYS_PCI0_IO_SPACE_PCI,
  839. CONFIG_SYS_PCI0_IO_SPACE, CONFIG_SYS_PCI0_IO_SIZE, PCI_REGION_IO);
  840. pci_set_ops (&pci0_hose,
  841. pci_hose_read_config_byte_via_dword,
  842. pci_hose_read_config_word_via_dword,
  843. gt_read_config_dword,
  844. pci_hose_write_config_byte_via_dword,
  845. pci_hose_write_config_word_via_dword,
  846. gt_write_config_dword);
  847. pci0_hose.region_count = 2;
  848. pci0_hose.cfg_addr = (unsigned int *) PCI_HOST0;
  849. pci_register_hose (&pci0_hose);
  850. pciArbiterDisable(PCI_HOST0); /* on PMC modules no arbiter is used */
  851. pciParkingDisable (PCI_HOST0, 1, 1, 1, 1, 1, 1, 1);
  852. command = pciReadConfigReg (PCI_HOST0, PCI_COMMAND, SELF);
  853. command |= PCI_COMMAND_MASTER;
  854. pciWriteConfigReg (PCI_HOST0, PCI_COMMAND, SELF, command);
  855. command = pciReadConfigReg (PCI_HOST0, PCI_COMMAND, SELF);
  856. command |= PCI_COMMAND_MEMORY;
  857. pciWriteConfigReg (PCI_HOST0, PCI_COMMAND, SELF, command);
  858. #ifdef CONFIG_PCI_PNP
  859. pciauto_config_init(&pci0_hose);
  860. pciauto_region_allocate(pci0_hose.pci_io, 0x400, &bar);
  861. #endif
  862. #ifdef CONFIG_PCI_SCAN_SHOW
  863. printf("PCI: Bus Dev VenId DevId Class Int\n");
  864. #endif
  865. pci0_hose.last_busno = pci_hose_scan_bus (&pci0_hose, pci0_hose.first_busno);
  866. #ifdef DEBUG
  867. gt_pci_bus_mode_display (PCI_HOST1);
  868. #endif
  869. pci1_hose.first_busno = pci0_hose.last_busno + 1;
  870. pci1_hose.last_busno = 0xff;
  871. pci1_hose.current_busno = pci1_hose.first_busno;
  872. local_buses[1] = pci1_hose.first_busno;
  873. /* PCI memory space */
  874. pci_set_region (pci1_hose.regions + 0,
  875. CONFIG_SYS_PCI1_0_MEM_SPACE,
  876. CONFIG_SYS_PCI1_0_MEM_SPACE,
  877. CONFIG_SYS_PCI1_MEM_SIZE, PCI_REGION_MEM);
  878. /* PCI I/O space */
  879. pci_set_region (pci1_hose.regions + 1,
  880. CONFIG_SYS_PCI1_IO_SPACE_PCI,
  881. CONFIG_SYS_PCI1_IO_SPACE, CONFIG_SYS_PCI1_IO_SIZE, PCI_REGION_IO);
  882. pci_set_ops (&pci1_hose,
  883. pci_hose_read_config_byte_via_dword,
  884. pci_hose_read_config_word_via_dword,
  885. gt_read_config_dword,
  886. pci_hose_write_config_byte_via_dword,
  887. pci_hose_write_config_word_via_dword,
  888. gt_write_config_dword);
  889. pci1_hose.region_count = 2;
  890. pci1_hose.cfg_addr = (unsigned int *) PCI_HOST1;
  891. pci_register_hose (&pci1_hose);
  892. pciArbiterEnable (PCI_HOST1);
  893. pciParkingDisable (PCI_HOST1, 1, 1, 1, 1, 1, 1, 1);
  894. command = pciReadConfigReg (PCI_HOST1, PCI_COMMAND, SELF);
  895. command |= PCI_COMMAND_MASTER;
  896. pciWriteConfigReg (PCI_HOST1, PCI_COMMAND, SELF, command);
  897. #ifdef CONFIG_PCI_PNP
  898. pciauto_config_init(&pci1_hose);
  899. pciauto_region_allocate(pci1_hose.pci_io, 0x400, &bar);
  900. #endif
  901. pci1_hose.last_busno = pci_hose_scan_bus (&pci1_hose, pci1_hose.first_busno);
  902. command = pciReadConfigReg (PCI_HOST1, PCI_COMMAND, SELF);
  903. command |= PCI_COMMAND_MEMORY;
  904. pciWriteConfigReg (PCI_HOST1, PCI_COMMAND, SELF, command);
  905. }
  906. #endif /* of CONFIG_PCI */