4xx_pcie.c 31 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171
  1. /*
  2. * (C) Copyright 2006 - 2008
  3. * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
  4. *
  5. * Copyright (c) 2005 Cisco Systems. All rights reserved.
  6. * Roland Dreier <rolandd@cisco.com>
  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. */
  22. /* define DEBUG for debugging output (obviously ;-)) */
  23. #if 0
  24. #define DEBUG
  25. #endif
  26. #include <common.h>
  27. #include <pci.h>
  28. #include <ppc4xx.h>
  29. #include <asm/processor.h>
  30. #include <asm-ppc/io.h>
  31. #if (defined(CONFIG_440SPE) || defined(CONFIG_405EX) || \
  32. defined(CONFIG_460EX) || defined(CONFIG_460GT)) && \
  33. defined(CONFIG_PCI) && !defined(CONFIG_PCI_DISABLE_PCIE)
  34. #include <asm/4xx_pcie.h>
  35. enum {
  36. PTYPE_ENDPOINT = 0x0,
  37. PTYPE_LEGACY_ENDPOINT = 0x1,
  38. PTYPE_ROOT_PORT = 0x4,
  39. LNKW_X1 = 0x1,
  40. LNKW_X4 = 0x4,
  41. LNKW_X8 = 0x8
  42. };
  43. static int validate_endpoint(struct pci_controller *hose)
  44. {
  45. if (hose->cfg_data == (u8 *)CONFIG_SYS_PCIE0_CFGBASE)
  46. return (is_end_point(0));
  47. else if (hose->cfg_data == (u8 *)CONFIG_SYS_PCIE1_CFGBASE)
  48. return (is_end_point(1));
  49. #if CONFIG_SYS_PCIE_NR_PORTS > 2
  50. else if (hose->cfg_data == (u8 *)CONFIG_SYS_PCIE2_CFGBASE)
  51. return (is_end_point(2));
  52. #endif
  53. return 0;
  54. }
  55. static u8* pcie_get_base(struct pci_controller *hose, unsigned int devfn)
  56. {
  57. u8 *base = (u8*)hose->cfg_data;
  58. /* use local configuration space for the first bus */
  59. if (PCI_BUS(devfn) == 0) {
  60. if (hose->cfg_data == (u8*)CONFIG_SYS_PCIE0_CFGBASE)
  61. base = (u8*)CONFIG_SYS_PCIE0_XCFGBASE;
  62. if (hose->cfg_data == (u8*)CONFIG_SYS_PCIE1_CFGBASE)
  63. base = (u8*)CONFIG_SYS_PCIE1_XCFGBASE;
  64. #if CONFIG_SYS_PCIE_NR_PORTS > 2
  65. if (hose->cfg_data == (u8*)CONFIG_SYS_PCIE2_CFGBASE)
  66. base = (u8*)CONFIG_SYS_PCIE2_XCFGBASE;
  67. #endif
  68. }
  69. return base;
  70. }
  71. static void pcie_dmer_disable(void)
  72. {
  73. mtdcr (DCRN_PEGPL_CFG(DCRN_PCIE0_BASE),
  74. mfdcr (DCRN_PEGPL_CFG(DCRN_PCIE0_BASE)) | GPL_DMER_MASK_DISA);
  75. mtdcr (DCRN_PEGPL_CFG(DCRN_PCIE1_BASE),
  76. mfdcr (DCRN_PEGPL_CFG(DCRN_PCIE1_BASE)) | GPL_DMER_MASK_DISA);
  77. #if CONFIG_SYS_PCIE_NR_PORTS > 2
  78. mtdcr (DCRN_PEGPL_CFG(DCRN_PCIE2_BASE),
  79. mfdcr (DCRN_PEGPL_CFG(DCRN_PCIE2_BASE)) | GPL_DMER_MASK_DISA);
  80. #endif
  81. }
  82. static void pcie_dmer_enable(void)
  83. {
  84. mtdcr (DCRN_PEGPL_CFG (DCRN_PCIE0_BASE),
  85. mfdcr (DCRN_PEGPL_CFG(DCRN_PCIE0_BASE)) & ~GPL_DMER_MASK_DISA);
  86. mtdcr (DCRN_PEGPL_CFG (DCRN_PCIE1_BASE),
  87. mfdcr (DCRN_PEGPL_CFG(DCRN_PCIE1_BASE)) & ~GPL_DMER_MASK_DISA);
  88. #if CONFIG_SYS_PCIE_NR_PORTS > 2
  89. mtdcr (DCRN_PEGPL_CFG (DCRN_PCIE2_BASE),
  90. mfdcr (DCRN_PEGPL_CFG(DCRN_PCIE2_BASE)) & ~GPL_DMER_MASK_DISA);
  91. #endif
  92. }
  93. static int pcie_read_config(struct pci_controller *hose, unsigned int devfn,
  94. int offset, int len, u32 *val) {
  95. u8 *address;
  96. *val = 0;
  97. if (validate_endpoint(hose))
  98. return 0; /* No upstream config access */
  99. /*
  100. * Bus numbers are relative to hose->first_busno
  101. */
  102. devfn -= PCI_BDF(hose->first_busno, 0, 0);
  103. /*
  104. * NOTICE: configuration space ranges are currenlty mapped only for
  105. * the first 16 buses, so such limit must be imposed. In case more
  106. * buses are required the TLB settings in board/amcc/<board>/init.S
  107. * need to be altered accordingly (one bus takes 1 MB of memory space).
  108. */
  109. if (PCI_BUS(devfn) >= 16)
  110. return 0;
  111. /*
  112. * Only single device/single function is supported for the primary and
  113. * secondary buses of the 440SPe host bridge.
  114. */
  115. if ((!((PCI_FUNC(devfn) == 0) && (PCI_DEV(devfn) == 0))) &&
  116. ((PCI_BUS(devfn) == 0) || (PCI_BUS(devfn) == 1)))
  117. return 0;
  118. address = pcie_get_base(hose, devfn);
  119. offset += devfn << 4;
  120. /*
  121. * Reading from configuration space of non-existing device can
  122. * generate transaction errors. For the read duration we suppress
  123. * assertion of machine check exceptions to avoid those.
  124. */
  125. pcie_dmer_disable ();
  126. debug("%s: cfg_data=%08x offset=%08x\n", __func__, hose->cfg_data, offset);
  127. switch (len) {
  128. case 1:
  129. *val = in_8(hose->cfg_data + offset);
  130. break;
  131. case 2:
  132. *val = in_le16((u16 *)(hose->cfg_data + offset));
  133. break;
  134. default:
  135. *val = in_le32((u32*)(hose->cfg_data + offset));
  136. break;
  137. }
  138. pcie_dmer_enable ();
  139. return 0;
  140. }
  141. static int pcie_write_config(struct pci_controller *hose, unsigned int devfn,
  142. int offset, int len, u32 val) {
  143. u8 *address;
  144. if (validate_endpoint(hose))
  145. return 0; /* No upstream config access */
  146. /*
  147. * Bus numbers are relative to hose->first_busno
  148. */
  149. devfn -= PCI_BDF(hose->first_busno, 0, 0);
  150. /*
  151. * Same constraints as in pcie_read_config().
  152. */
  153. if (PCI_BUS(devfn) >= 16)
  154. return 0;
  155. if ((!((PCI_FUNC(devfn) == 0) && (PCI_DEV(devfn) == 0))) &&
  156. ((PCI_BUS(devfn) == 0) || (PCI_BUS(devfn) == 1)))
  157. return 0;
  158. address = pcie_get_base(hose, devfn);
  159. offset += devfn << 4;
  160. /*
  161. * Suppress MCK exceptions, similar to pcie_read_config()
  162. */
  163. pcie_dmer_disable ();
  164. switch (len) {
  165. case 1:
  166. out_8(hose->cfg_data + offset, val);
  167. break;
  168. case 2:
  169. out_le16((u16 *)(hose->cfg_data + offset), val);
  170. break;
  171. default:
  172. out_le32((u32 *)(hose->cfg_data + offset), val);
  173. break;
  174. }
  175. pcie_dmer_enable ();
  176. return 0;
  177. }
  178. int pcie_read_config_byte(struct pci_controller *hose,pci_dev_t dev,int offset,u8 *val)
  179. {
  180. u32 v;
  181. int rv;
  182. rv = pcie_read_config(hose, dev, offset, 1, &v);
  183. *val = (u8)v;
  184. return rv;
  185. }
  186. int pcie_read_config_word(struct pci_controller *hose,pci_dev_t dev,int offset,u16 *val)
  187. {
  188. u32 v;
  189. int rv;
  190. rv = pcie_read_config(hose, dev, offset, 2, &v);
  191. *val = (u16)v;
  192. return rv;
  193. }
  194. int pcie_read_config_dword(struct pci_controller *hose,pci_dev_t dev,int offset,u32 *val)
  195. {
  196. u32 v;
  197. int rv;
  198. rv = pcie_read_config(hose, dev, offset, 3, &v);
  199. *val = (u32)v;
  200. return rv;
  201. }
  202. int pcie_write_config_byte(struct pci_controller *hose,pci_dev_t dev,int offset,u8 val)
  203. {
  204. return pcie_write_config(hose,(u32)dev,offset,1,val);
  205. }
  206. int pcie_write_config_word(struct pci_controller *hose,pci_dev_t dev,int offset,u16 val)
  207. {
  208. return pcie_write_config(hose,(u32)dev,offset,2,(u32 )val);
  209. }
  210. int pcie_write_config_dword(struct pci_controller *hose,pci_dev_t dev,int offset,u32 val)
  211. {
  212. return pcie_write_config(hose,(u32)dev,offset,3,(u32 )val);
  213. }
  214. #if defined(CONFIG_440SPE)
  215. static void ppc4xx_setup_utl(u32 port) {
  216. volatile void *utl_base = NULL;
  217. /*
  218. * Map UTL registers
  219. */
  220. switch (port) {
  221. case 0:
  222. mtdcr(DCRN_PEGPL_REGBAH(PCIE0), 0x0000000c);
  223. mtdcr(DCRN_PEGPL_REGBAL(PCIE0), 0x20000000);
  224. mtdcr(DCRN_PEGPL_REGMSK(PCIE0), 0x00007001);
  225. mtdcr(DCRN_PEGPL_SPECIAL(PCIE0), 0x68782800);
  226. break;
  227. case 1:
  228. mtdcr(DCRN_PEGPL_REGBAH(PCIE1), 0x0000000c);
  229. mtdcr(DCRN_PEGPL_REGBAL(PCIE1), 0x20001000);
  230. mtdcr(DCRN_PEGPL_REGMSK(PCIE1), 0x00007001);
  231. mtdcr(DCRN_PEGPL_SPECIAL(PCIE1), 0x68782800);
  232. break;
  233. case 2:
  234. mtdcr(DCRN_PEGPL_REGBAH(PCIE2), 0x0000000c);
  235. mtdcr(DCRN_PEGPL_REGBAL(PCIE2), 0x20002000);
  236. mtdcr(DCRN_PEGPL_REGMSK(PCIE2), 0x00007001);
  237. mtdcr(DCRN_PEGPL_SPECIAL(PCIE2), 0x68782800);
  238. break;
  239. }
  240. utl_base = (unsigned int *)(CONFIG_SYS_PCIE_BASE + 0x1000 * port);
  241. /*
  242. * Set buffer allocations and then assert VRB and TXE.
  243. */
  244. out_be32(utl_base + PEUTL_OUTTR, 0x08000000);
  245. out_be32(utl_base + PEUTL_INTR, 0x02000000);
  246. out_be32(utl_base + PEUTL_OPDBSZ, 0x10000000);
  247. out_be32(utl_base + PEUTL_PBBSZ, 0x53000000);
  248. out_be32(utl_base + PEUTL_IPHBSZ, 0x08000000);
  249. out_be32(utl_base + PEUTL_IPDBSZ, 0x10000000);
  250. out_be32(utl_base + PEUTL_RCIRQEN, 0x00f00000);
  251. out_be32(utl_base + PEUTL_PCTL, 0x80800066);
  252. }
  253. static int check_error(void)
  254. {
  255. u32 valPE0, valPE1, valPE2;
  256. int err = 0;
  257. /* SDR0_PEGPLLLCT1 reset */
  258. if (!(valPE0 = SDR_READ(PESDR0_PLLLCT1) & 0x01000000))
  259. printf("PCIE: SDR0_PEGPLLLCT1 reset error 0x%x\n", valPE0);
  260. valPE0 = SDR_READ(PESDR0_RCSSET);
  261. valPE1 = SDR_READ(PESDR1_RCSSET);
  262. valPE2 = SDR_READ(PESDR2_RCSSET);
  263. /* SDR0_PExRCSSET rstgu */
  264. if (!(valPE0 & 0x01000000) ||
  265. !(valPE1 & 0x01000000) ||
  266. !(valPE2 & 0x01000000)) {
  267. printf("PCIE: SDR0_PExRCSSET rstgu error\n");
  268. err = -1;
  269. }
  270. /* SDR0_PExRCSSET rstdl */
  271. if (!(valPE0 & 0x00010000) ||
  272. !(valPE1 & 0x00010000) ||
  273. !(valPE2 & 0x00010000)) {
  274. printf("PCIE: SDR0_PExRCSSET rstdl error\n");
  275. err = -1;
  276. }
  277. /* SDR0_PExRCSSET rstpyn */
  278. if ((valPE0 & 0x00001000) ||
  279. (valPE1 & 0x00001000) ||
  280. (valPE2 & 0x00001000)) {
  281. printf("PCIE: SDR0_PExRCSSET rstpyn error\n");
  282. err = -1;
  283. }
  284. /* SDR0_PExRCSSET hldplb */
  285. if ((valPE0 & 0x10000000) ||
  286. (valPE1 & 0x10000000) ||
  287. (valPE2 & 0x10000000)) {
  288. printf("PCIE: SDR0_PExRCSSET hldplb error\n");
  289. err = -1;
  290. }
  291. /* SDR0_PExRCSSET rdy */
  292. if ((valPE0 & 0x00100000) ||
  293. (valPE1 & 0x00100000) ||
  294. (valPE2 & 0x00100000)) {
  295. printf("PCIE: SDR0_PExRCSSET rdy error\n");
  296. err = -1;
  297. }
  298. /* SDR0_PExRCSSET shutdown */
  299. if ((valPE0 & 0x00000100) ||
  300. (valPE1 & 0x00000100) ||
  301. (valPE2 & 0x00000100)) {
  302. printf("PCIE: SDR0_PExRCSSET shutdown error\n");
  303. err = -1;
  304. }
  305. return err;
  306. }
  307. /*
  308. * Initialize PCI Express core
  309. */
  310. int ppc4xx_init_pcie(void)
  311. {
  312. int time_out = 20;
  313. /* Set PLL clock receiver to LVPECL */
  314. SDR_WRITE(PESDR0_PLLLCT1, SDR_READ(PESDR0_PLLLCT1) | 1 << 28);
  315. if (check_error())
  316. return -1;
  317. if (!(SDR_READ(PESDR0_PLLLCT2) & 0x10000))
  318. {
  319. printf("PCIE: PESDR_PLLCT2 resistance calibration failed (0x%08x)\n",
  320. SDR_READ(PESDR0_PLLLCT2));
  321. return -1;
  322. }
  323. /* De-assert reset of PCIe PLL, wait for lock */
  324. SDR_WRITE(PESDR0_PLLLCT1, SDR_READ(PESDR0_PLLLCT1) & ~(1 << 24));
  325. udelay(3);
  326. while (time_out) {
  327. if (!(SDR_READ(PESDR0_PLLLCT3) & 0x10000000)) {
  328. time_out--;
  329. udelay(1);
  330. } else
  331. break;
  332. }
  333. if (!time_out) {
  334. printf("PCIE: VCO output not locked\n");
  335. return -1;
  336. }
  337. return 0;
  338. }
  339. #endif
  340. #if defined(CONFIG_460EX) || defined(CONFIG_460GT)
  341. static void ppc4xx_setup_utl(u32 port)
  342. {
  343. volatile void *utl_base = NULL;
  344. /*
  345. * Map UTL registers at 0x0801_n000 (4K 0xfff mask) PEGPLn_REGMSK
  346. */
  347. switch (port) {
  348. case 0:
  349. mtdcr(DCRN_PEGPL_REGBAH(PCIE0), U64_TO_U32_HIGH(CONFIG_SYS_PCIE0_UTLBASE));
  350. mtdcr(DCRN_PEGPL_REGBAL(PCIE0), U64_TO_U32_LOW(CONFIG_SYS_PCIE0_UTLBASE));
  351. mtdcr(DCRN_PEGPL_REGMSK(PCIE0), 0x00007001); /* BAM 11100000=4KB */
  352. mtdcr(DCRN_PEGPL_SPECIAL(PCIE0), 0);
  353. break;
  354. case 1:
  355. mtdcr(DCRN_PEGPL_REGBAH(PCIE1), U64_TO_U32_HIGH(CONFIG_SYS_PCIE0_UTLBASE));
  356. mtdcr(DCRN_PEGPL_REGBAL(PCIE1), U64_TO_U32_LOW(CONFIG_SYS_PCIE0_UTLBASE)
  357. + 0x1000);
  358. mtdcr(DCRN_PEGPL_REGMSK(PCIE1), 0x00007001); /* BAM 11100000=4KB */
  359. mtdcr(DCRN_PEGPL_SPECIAL(PCIE1), 0);
  360. break;
  361. }
  362. utl_base = (unsigned int *)(CONFIG_SYS_PCIE_BASE + 0x1000 * port);
  363. /*
  364. * Set buffer allocations and then assert VRB and TXE.
  365. */
  366. out_be32(utl_base + PEUTL_PBCTL, 0x0800000c); /* PLBME, CRRE */
  367. out_be32(utl_base + PEUTL_OUTTR, 0x08000000);
  368. out_be32(utl_base + PEUTL_INTR, 0x02000000);
  369. out_be32(utl_base + PEUTL_OPDBSZ, 0x04000000); /* OPD = 512 Bytes */
  370. out_be32(utl_base + PEUTL_PBBSZ, 0x00000000); /* Max 512 Bytes */
  371. out_be32(utl_base + PEUTL_IPHBSZ, 0x02000000);
  372. out_be32(utl_base + PEUTL_IPDBSZ, 0x04000000); /* IPD = 512 Bytes */
  373. out_be32(utl_base + PEUTL_RCIRQEN, 0x00f00000);
  374. out_be32(utl_base + PEUTL_PCTL, 0x80800066); /* VRB,TXE,timeout=default */
  375. }
  376. /*
  377. * TODO: double check PCI express SDR based on the latest user manual
  378. * Some registers specified here no longer exist.. has to be
  379. * updated based on the final EAS spec.
  380. */
  381. static int check_error(void)
  382. {
  383. u32 valPE0, valPE1;
  384. int err = 0;
  385. valPE0 = SDR_READ(SDRN_PESDR_RCSSET(0));
  386. valPE1 = SDR_READ(SDRN_PESDR_RCSSET(1));
  387. /* SDR0_PExRCSSET rstgu */
  388. if (!(valPE0 & PESDRx_RCSSET_RSTGU) || !(valPE1 & PESDRx_RCSSET_RSTGU)) {
  389. printf("PCIE: SDR0_PExRCSSET rstgu error\n");
  390. err = -1;
  391. }
  392. /* SDR0_PExRCSSET rstdl */
  393. if (!(valPE0 & PESDRx_RCSSET_RSTDL) || !(valPE1 & PESDRx_RCSSET_RSTDL)) {
  394. printf("PCIE: SDR0_PExRCSSET rstdl error\n");
  395. err = -1;
  396. }
  397. /* SDR0_PExRCSSET rstpyn */
  398. if ((valPE0 & PESDRx_RCSSET_RSTPYN) || (valPE1 & PESDRx_RCSSET_RSTPYN)) {
  399. printf("PCIE: SDR0_PExRCSSET rstpyn error\n");
  400. err = -1;
  401. }
  402. /* SDR0_PExRCSSET hldplb */
  403. if ((valPE0 & PESDRx_RCSSET_HLDPLB) || (valPE1 & PESDRx_RCSSET_HLDPLB)) {
  404. printf("PCIE: SDR0_PExRCSSET hldplb error\n");
  405. err = -1;
  406. }
  407. /* SDR0_PExRCSSET rdy */
  408. if ((valPE0 & PESDRx_RCSSET_RDY) || (valPE1 & PESDRx_RCSSET_RDY)) {
  409. printf("PCIE: SDR0_PExRCSSET rdy error\n");
  410. err = -1;
  411. }
  412. return err;
  413. }
  414. /*
  415. * Initialize PCI Express core as described in User Manual
  416. * TODO: double check PE SDR PLL Register with the updated user manual.
  417. */
  418. int ppc4xx_init_pcie(void)
  419. {
  420. if (check_error())
  421. return -1;
  422. return 0;
  423. }
  424. #endif /* CONFIG_460EX */
  425. #if defined(CONFIG_405EX)
  426. static void ppc4xx_setup_utl(u32 port)
  427. {
  428. u32 utl_base;
  429. /*
  430. * Map UTL registers at 0xef4f_n000 (4K 0xfff mask) PEGPLn_REGMSK
  431. */
  432. switch (port) {
  433. case 0:
  434. mtdcr(DCRN_PEGPL_REGBAH(PCIE0), 0x00000000);
  435. mtdcr(DCRN_PEGPL_REGBAL(PCIE0), CONFIG_SYS_PCIE0_UTLBASE);
  436. mtdcr(DCRN_PEGPL_REGMSK(PCIE0), 0x00007001); /* 4k region, valid */
  437. mtdcr(DCRN_PEGPL_SPECIAL(PCIE0), 0);
  438. break;
  439. case 1:
  440. mtdcr(DCRN_PEGPL_REGBAH(PCIE1), 0x00000000);
  441. mtdcr(DCRN_PEGPL_REGBAL(PCIE1), CONFIG_SYS_PCIE1_UTLBASE);
  442. mtdcr(DCRN_PEGPL_REGMSK(PCIE1), 0x00007001); /* 4k region, valid */
  443. mtdcr(DCRN_PEGPL_SPECIAL(PCIE1), 0);
  444. break;
  445. }
  446. utl_base = (port==0) ? CONFIG_SYS_PCIE0_UTLBASE : CONFIG_SYS_PCIE1_UTLBASE;
  447. /*
  448. * Set buffer allocations and then assert VRB and TXE.
  449. */
  450. out_be32((u32 *)(utl_base + PEUTL_OUTTR), 0x02000000);
  451. out_be32((u32 *)(utl_base + PEUTL_INTR), 0x02000000);
  452. out_be32((u32 *)(utl_base + PEUTL_OPDBSZ), 0x04000000);
  453. out_be32((u32 *)(utl_base + PEUTL_PBBSZ), 0x21000000);
  454. out_be32((u32 *)(utl_base + PEUTL_IPHBSZ), 0x02000000);
  455. out_be32((u32 *)(utl_base + PEUTL_IPDBSZ), 0x04000000);
  456. out_be32((u32 *)(utl_base + PEUTL_RCIRQEN), 0x00f00000);
  457. out_be32((u32 *)(utl_base + PEUTL_PCTL), 0x80800066);
  458. out_be32((u32 *)(utl_base + PEUTL_PBCTL), 0x0800000c);
  459. out_be32((u32 *)(utl_base + PEUTL_RCSTA),
  460. in_be32((u32 *)(utl_base + PEUTL_RCSTA)) | 0x000040000);
  461. }
  462. int ppc4xx_init_pcie(void)
  463. {
  464. /*
  465. * Nothing to do on 405EX
  466. */
  467. return 0;
  468. }
  469. #endif /* CONFIG_405EX */
  470. /*
  471. * Board-specific pcie initialization
  472. * Platform code can reimplement ppc4xx_init_pcie_port_hw() if needed
  473. */
  474. /*
  475. * Initialize various parts of the PCI Express core for our port:
  476. *
  477. * - Set as a root port and enable max width
  478. * (PXIE0 -> X8, PCIE1 and PCIE2 -> X4).
  479. * - Set up UTL configuration.
  480. * - Increase SERDES drive strength to levels suggested by AMCC.
  481. * - De-assert RSTPYN, RSTDL and RSTGU.
  482. *
  483. * NOTICE for 440SPE revB chip: PESDRn_UTLSET2 is not set - we leave it
  484. * with default setting 0x11310000. The register has new fields,
  485. * PESDRn_UTLSET2[LKINE] in particular: clearing it leads to PCIE core
  486. * hang.
  487. */
  488. #if defined(CONFIG_440SPE)
  489. int __ppc4xx_init_pcie_port_hw(int port, int rootport)
  490. {
  491. u32 val = 1 << 24;
  492. u32 utlset1;
  493. if (rootport) {
  494. val = PTYPE_ROOT_PORT << 20;
  495. utlset1 = 0x21222222;
  496. } else {
  497. val = PTYPE_LEGACY_ENDPOINT << 20;
  498. utlset1 = 0x20222222;
  499. }
  500. if (port == 0)
  501. val |= LNKW_X8 << 12;
  502. else
  503. val |= LNKW_X4 << 12;
  504. SDR_WRITE(SDRN_PESDR_DLPSET(port), val);
  505. SDR_WRITE(SDRN_PESDR_UTLSET1(port), utlset1);
  506. if (!ppc440spe_revB())
  507. SDR_WRITE(SDRN_PESDR_UTLSET2(port), 0x11000000);
  508. SDR_WRITE(SDRN_PESDR_HSSL0SET1(port), 0x35000000);
  509. SDR_WRITE(SDRN_PESDR_HSSL1SET1(port), 0x35000000);
  510. SDR_WRITE(SDRN_PESDR_HSSL2SET1(port), 0x35000000);
  511. SDR_WRITE(SDRN_PESDR_HSSL3SET1(port), 0x35000000);
  512. if (port == 0) {
  513. SDR_WRITE(PESDR0_HSSL4SET1, 0x35000000);
  514. SDR_WRITE(PESDR0_HSSL5SET1, 0x35000000);
  515. SDR_WRITE(PESDR0_HSSL6SET1, 0x35000000);
  516. SDR_WRITE(PESDR0_HSSL7SET1, 0x35000000);
  517. }
  518. SDR_WRITE(SDRN_PESDR_RCSSET(port), (SDR_READ(SDRN_PESDR_RCSSET(port)) &
  519. ~(1 << 24 | 1 << 16)) | 1 << 12);
  520. return 0;
  521. }
  522. #endif /* CONFIG_440SPE */
  523. #if defined(CONFIG_460EX) || defined(CONFIG_460GT)
  524. int __ppc4xx_init_pcie_port_hw(int port, int rootport)
  525. {
  526. u32 val;
  527. u32 utlset1;
  528. if (rootport)
  529. val = PTYPE_ROOT_PORT << 20;
  530. else
  531. val = PTYPE_LEGACY_ENDPOINT << 20;
  532. if (port == 0) {
  533. val |= LNKW_X1 << 12;
  534. utlset1 = 0x20000000;
  535. } else {
  536. val |= LNKW_X4 << 12;
  537. utlset1 = 0x20101101;
  538. }
  539. SDR_WRITE(SDRN_PESDR_DLPSET(port), val);
  540. SDR_WRITE(SDRN_PESDR_UTLSET1(port), utlset1);
  541. SDR_WRITE(SDRN_PESDR_UTLSET2(port), 0x01210000);
  542. switch (port) {
  543. case 0:
  544. SDR_WRITE(PESDR0_L0CDRCTL, 0x00003230);
  545. SDR_WRITE(PESDR0_L0DRV, 0x00000130);
  546. SDR_WRITE(PESDR0_L0CLK, 0x00000006);
  547. SDR_WRITE(PESDR0_PHY_CTL_RST,0x10000000);
  548. break;
  549. case 1:
  550. SDR_WRITE(PESDR1_L0CDRCTL, 0x00003230);
  551. SDR_WRITE(PESDR1_L1CDRCTL, 0x00003230);
  552. SDR_WRITE(PESDR1_L2CDRCTL, 0x00003230);
  553. SDR_WRITE(PESDR1_L3CDRCTL, 0x00003230);
  554. SDR_WRITE(PESDR1_L0DRV, 0x00000130);
  555. SDR_WRITE(PESDR1_L1DRV, 0x00000130);
  556. SDR_WRITE(PESDR1_L2DRV, 0x00000130);
  557. SDR_WRITE(PESDR1_L3DRV, 0x00000130);
  558. SDR_WRITE(PESDR1_L0CLK, 0x00000006);
  559. SDR_WRITE(PESDR1_L1CLK, 0x00000006);
  560. SDR_WRITE(PESDR1_L2CLK, 0x00000006);
  561. SDR_WRITE(PESDR1_L3CLK, 0x00000006);
  562. SDR_WRITE(PESDR1_PHY_CTL_RST,0x10000000);
  563. break;
  564. }
  565. SDR_WRITE(SDRN_PESDR_RCSSET(port), SDR_READ(SDRN_PESDR_RCSSET(port)) |
  566. (PESDRx_RCSSET_RSTGU | PESDRx_RCSSET_RSTPYN));
  567. /* Poll for PHY reset */
  568. switch (port) {
  569. case 0:
  570. while (!(SDR_READ(PESDR0_RSTSTA) & 0x1))
  571. udelay(10);
  572. break;
  573. case 1:
  574. while (!(SDR_READ(PESDR1_RSTSTA) & 0x1))
  575. udelay(10);
  576. break;
  577. }
  578. SDR_WRITE(SDRN_PESDR_RCSSET(port),
  579. (SDR_READ(SDRN_PESDR_RCSSET(port)) &
  580. ~(PESDRx_RCSSET_RSTGU | PESDRx_RCSSET_RSTDL)) |
  581. PESDRx_RCSSET_RSTPYN);
  582. return 0;
  583. }
  584. #endif /* CONFIG_440SPE */
  585. #if defined(CONFIG_405EX)
  586. int __ppc4xx_init_pcie_port_hw(int port, int rootport)
  587. {
  588. u32 val;
  589. if (rootport)
  590. val = 0x00401000;
  591. else
  592. val = 0x00101000;
  593. SDR_WRITE(SDRN_PESDR_DLPSET(port), val);
  594. SDR_WRITE(SDRN_PESDR_UTLSET1(port), 0x00000000);
  595. SDR_WRITE(SDRN_PESDR_UTLSET2(port), 0x01010000);
  596. SDR_WRITE(SDRN_PESDR_PHYSET1(port), 0x720F0000);
  597. SDR_WRITE(SDRN_PESDR_PHYSET2(port), 0x70600003);
  598. /* Assert the PE0_PHY reset */
  599. SDR_WRITE(SDRN_PESDR_RCSSET(port), 0x01010000);
  600. udelay(1000);
  601. /* deassert the PE0_hotreset */
  602. if (is_end_point(port))
  603. SDR_WRITE(SDRN_PESDR_RCSSET(port), 0x01111000);
  604. else
  605. SDR_WRITE(SDRN_PESDR_RCSSET(port), 0x01101000);
  606. /* poll for phy !reset */
  607. while (!(SDR_READ(SDRN_PESDR_PHYSTA(port)) & 0x00001000))
  608. ;
  609. /* deassert the PE0_gpl_utl_reset */
  610. SDR_WRITE(SDRN_PESDR_RCSSET(port), 0x00101000);
  611. if (port == 0)
  612. mtdcr(DCRN_PEGPL_CFG(PCIE0), 0x10000000); /* guarded on */
  613. else
  614. mtdcr(DCRN_PEGPL_CFG(PCIE1), 0x10000000); /* guarded on */
  615. return 0;
  616. }
  617. #endif /* CONFIG_405EX */
  618. int ppc4xx_init_pcie_port_hw(int port, int rootport)
  619. __attribute__((weak, alias("__ppc4xx_init_pcie_port_hw")));
  620. /*
  621. * We map PCI Express configuration access into the 512MB regions
  622. *
  623. * NOTICE: revB is very strict about PLB real addressess and ranges to
  624. * be mapped for config space; it seems to only work with d_nnnn_nnnn
  625. * range (hangs the core upon config transaction attempts when set
  626. * otherwise) while revA uses c_nnnn_nnnn.
  627. *
  628. * For 440SPe revA:
  629. * PCIE0: 0xc_4000_0000
  630. * PCIE1: 0xc_8000_0000
  631. * PCIE2: 0xc_c000_0000
  632. *
  633. * For 440SPe revB:
  634. * PCIE0: 0xd_0000_0000
  635. * PCIE1: 0xd_2000_0000
  636. * PCIE2: 0xd_4000_0000
  637. *
  638. * For 405EX:
  639. * PCIE0: 0xa000_0000
  640. * PCIE1: 0xc000_0000
  641. *
  642. * For 460EX/GT:
  643. * PCIE0: 0xd_0000_0000
  644. * PCIE1: 0xd_2000_0000
  645. */
  646. static inline u64 ppc4xx_get_cfgaddr(int port)
  647. {
  648. #if defined(CONFIG_405EX)
  649. if (port == 0)
  650. return (u64)CONFIG_SYS_PCIE0_CFGBASE;
  651. else
  652. return (u64)CONFIG_SYS_PCIE1_CFGBASE;
  653. #endif
  654. #if defined(CONFIG_440SPE)
  655. if (ppc440spe_revB()) {
  656. switch (port) {
  657. default: /* to satisfy compiler */
  658. case 0:
  659. return 0x0000000d00000000ULL;
  660. case 1:
  661. return 0x0000000d20000000ULL;
  662. case 2:
  663. return 0x0000000d40000000ULL;
  664. }
  665. } else {
  666. switch (port) {
  667. default: /* to satisfy compiler */
  668. case 0:
  669. return 0x0000000c40000000ULL;
  670. case 1:
  671. return 0x0000000c80000000ULL;
  672. case 2:
  673. return 0x0000000cc0000000ULL;
  674. }
  675. }
  676. #endif
  677. #if defined(CONFIG_460EX) || defined(CONFIG_460GT)
  678. if (port == 0)
  679. return 0x0000000d00000000ULL;
  680. else
  681. return 0x0000000d20000000ULL;
  682. #endif
  683. }
  684. /*
  685. * 4xx boards as end point and root point setup
  686. * and
  687. * testing inbound and out bound windows
  688. *
  689. * 4xx boards can be plugged into another 4xx boards or you can get PCI-E
  690. * cable which can be used to setup loop back from one port to another port.
  691. * Please rememeber that unless there is a endpoint plugged in to root port it
  692. * will not initialize. It is the same in case of endpoint , unless there is
  693. * root port attached it will not initialize.
  694. *
  695. * In this release of software all the PCI-E ports are configured as either
  696. * endpoint or rootpoint.In future we will have support for selective ports
  697. * setup as endpoint and root point in single board.
  698. *
  699. * Once your board came up as root point , you can verify by reading
  700. * /proc/bus/pci/devices. Where you can see the configuration registers
  701. * of end point device attached to the port.
  702. *
  703. * Enpoint cofiguration can be verified by connecting 4xx board to any
  704. * host or another 4xx board. Then try to scan the device. In case of
  705. * linux use "lspci" or appripriate os command.
  706. *
  707. * How do I verify the inbound and out bound windows ? (4xx to 4xx)
  708. * in this configuration inbound and outbound windows are setup to access
  709. * sram memroy area. SRAM is at 0x4 0000 0000 , on PLB bus. This address
  710. * is mapped at 0x90000000. From u-boot prompt write data 0xb000 0000,
  711. * This is waere your POM(PLB out bound memory window) mapped. then
  712. * read the data from other 4xx board's u-boot prompt at address
  713. * 0x9000 0000(SRAM). Data should match.
  714. * In case of inbound , write data to u-boot command prompt at 0xb000 0000
  715. * which is mapped to 0x4 0000 0000. Now on rootpoint yucca u-boot prompt check
  716. * data at 0x9000 0000(SRAM).Data should match.
  717. */
  718. int ppc4xx_init_pcie_port(int port, int rootport)
  719. {
  720. static int core_init;
  721. volatile u32 val = 0;
  722. int attempts;
  723. u64 addr;
  724. u32 low, high;
  725. if (!core_init) {
  726. if (ppc4xx_init_pcie())
  727. return -1;
  728. ++core_init;
  729. }
  730. /*
  731. * Initialize various parts of the PCI Express core for our port
  732. */
  733. ppc4xx_init_pcie_port_hw(port, rootport);
  734. /*
  735. * Notice: the following delay has critical impact on device
  736. * initialization - if too short (<50ms) the link doesn't get up.
  737. */
  738. mdelay(100);
  739. val = SDR_READ(SDRN_PESDR_RCSSTS(port));
  740. if (val & (1 << 20)) {
  741. printf("PCIE%d: PGRST failed %08x\n", port, val);
  742. return -1;
  743. }
  744. /*
  745. * Verify link is up
  746. */
  747. val = SDR_READ(SDRN_PESDR_LOOP(port));
  748. if (!(val & 0x00001000)) {
  749. printf("PCIE%d: link is not up.\n", port);
  750. return -1;
  751. }
  752. /*
  753. * Setup UTL registers - but only on revA!
  754. * We use default settings for revB chip.
  755. */
  756. if (!ppc440spe_revB())
  757. ppc4xx_setup_utl(port);
  758. /*
  759. * We map PCI Express configuration access into the 512MB regions
  760. */
  761. addr = ppc4xx_get_cfgaddr(port);
  762. low = U64_TO_U32_LOW(addr);
  763. high = U64_TO_U32_HIGH(addr);
  764. switch (port) {
  765. case 0:
  766. mtdcr(DCRN_PEGPL_CFGBAH(PCIE0), high);
  767. mtdcr(DCRN_PEGPL_CFGBAL(PCIE0), low);
  768. mtdcr(DCRN_PEGPL_CFGMSK(PCIE0), 0xe0000001); /* 512MB region, valid */
  769. break;
  770. case 1:
  771. mtdcr(DCRN_PEGPL_CFGBAH(PCIE1), high);
  772. mtdcr(DCRN_PEGPL_CFGBAL(PCIE1), low);
  773. mtdcr(DCRN_PEGPL_CFGMSK(PCIE1), 0xe0000001); /* 512MB region, valid */
  774. break;
  775. #if CONFIG_SYS_PCIE_NR_PORTS > 2
  776. case 2:
  777. mtdcr(DCRN_PEGPL_CFGBAH(PCIE2), high);
  778. mtdcr(DCRN_PEGPL_CFGBAL(PCIE2), low);
  779. mtdcr(DCRN_PEGPL_CFGMSK(PCIE2), 0xe0000001); /* 512MB region, valid */
  780. break;
  781. #endif
  782. }
  783. /*
  784. * Check for VC0 active and assert RDY.
  785. */
  786. attempts = 10;
  787. while(!(SDR_READ(SDRN_PESDR_RCSSTS(port)) & (1 << 16))) {
  788. if (!(attempts--)) {
  789. printf("PCIE%d: VC0 not active\n", port);
  790. return -1;
  791. }
  792. mdelay(1000);
  793. }
  794. SDR_WRITE(SDRN_PESDR_RCSSET(port),
  795. SDR_READ(SDRN_PESDR_RCSSET(port)) | 1 << 20);
  796. mdelay(100);
  797. return 0;
  798. }
  799. int ppc4xx_init_pcie_rootport(int port)
  800. {
  801. return ppc4xx_init_pcie_port(port, 1);
  802. }
  803. int ppc4xx_init_pcie_endport(int port)
  804. {
  805. return ppc4xx_init_pcie_port(port, 0);
  806. }
  807. void ppc4xx_setup_pcie_rootpoint(struct pci_controller *hose, int port)
  808. {
  809. volatile void *mbase = NULL;
  810. volatile void *rmbase = NULL;
  811. pci_set_ops(hose,
  812. pcie_read_config_byte,
  813. pcie_read_config_word,
  814. pcie_read_config_dword,
  815. pcie_write_config_byte,
  816. pcie_write_config_word,
  817. pcie_write_config_dword);
  818. switch (port) {
  819. case 0:
  820. mbase = (u32 *)CONFIG_SYS_PCIE0_XCFGBASE;
  821. rmbase = (u32 *)CONFIG_SYS_PCIE0_CFGBASE;
  822. hose->cfg_data = (u8 *)CONFIG_SYS_PCIE0_CFGBASE;
  823. break;
  824. case 1:
  825. mbase = (u32 *)CONFIG_SYS_PCIE1_XCFGBASE;
  826. rmbase = (u32 *)CONFIG_SYS_PCIE1_CFGBASE;
  827. hose->cfg_data = (u8 *)CONFIG_SYS_PCIE1_CFGBASE;
  828. break;
  829. #if CONFIG_SYS_PCIE_NR_PORTS > 2
  830. case 2:
  831. mbase = (u32 *)CONFIG_SYS_PCIE2_XCFGBASE;
  832. rmbase = (u32 *)CONFIG_SYS_PCIE2_CFGBASE;
  833. hose->cfg_data = (u8 *)CONFIG_SYS_PCIE2_CFGBASE;
  834. break;
  835. #endif
  836. }
  837. /*
  838. * Set bus numbers on our root port
  839. */
  840. out_8((u8 *)mbase + PCI_PRIMARY_BUS, 0);
  841. out_8((u8 *)mbase + PCI_SECONDARY_BUS, 1);
  842. out_8((u8 *)mbase + PCI_SUBORDINATE_BUS, 1);
  843. /*
  844. * Set up outbound translation to hose->mem_space from PLB
  845. * addresses at an offset of 0xd_0000_0000. We set the low
  846. * bits of the mask to 11 to turn off splitting into 8
  847. * subregions and to enable the outbound translation.
  848. */
  849. out_le32(mbase + PECFG_POM0LAH, 0x00000000);
  850. out_le32(mbase + PECFG_POM0LAL, CONFIG_SYS_PCIE_MEMBASE +
  851. port * CONFIG_SYS_PCIE_MEMSIZE);
  852. debug("PECFG_POM0LA=%08x.%08x\n", in_le32(mbase + PECFG_POM0LAH),
  853. in_le32(mbase + PECFG_POM0LAL));
  854. switch (port) {
  855. case 0:
  856. mtdcr(DCRN_PEGPL_OMR1BAH(PCIE0), CONFIG_SYS_PCIE_ADDR_HIGH);
  857. mtdcr(DCRN_PEGPL_OMR1BAL(PCIE0), CONFIG_SYS_PCIE_MEMBASE +
  858. port * CONFIG_SYS_PCIE_MEMSIZE);
  859. mtdcr(DCRN_PEGPL_OMR1MSKH(PCIE0), 0x7fffffff);
  860. mtdcr(DCRN_PEGPL_OMR1MSKL(PCIE0),
  861. ~(CONFIG_SYS_PCIE_MEMSIZE - 1) | 3);
  862. debug("0:PEGPL_OMR1BA=%08x.%08x MSK=%08x.%08x\n",
  863. mfdcr(DCRN_PEGPL_OMR1BAH(PCIE0)),
  864. mfdcr(DCRN_PEGPL_OMR1BAL(PCIE0)),
  865. mfdcr(DCRN_PEGPL_OMR1MSKH(PCIE0)),
  866. mfdcr(DCRN_PEGPL_OMR1MSKL(PCIE0)));
  867. break;
  868. case 1:
  869. mtdcr(DCRN_PEGPL_OMR1BAH(PCIE1), CONFIG_SYS_PCIE_ADDR_HIGH);
  870. mtdcr(DCRN_PEGPL_OMR1BAL(PCIE1), CONFIG_SYS_PCIE_MEMBASE +
  871. port * CONFIG_SYS_PCIE_MEMSIZE);
  872. mtdcr(DCRN_PEGPL_OMR1MSKH(PCIE1), 0x7fffffff);
  873. mtdcr(DCRN_PEGPL_OMR1MSKL(PCIE1),
  874. ~(CONFIG_SYS_PCIE_MEMSIZE - 1) | 3);
  875. debug("1:PEGPL_OMR1BA=%08x.%08x MSK=%08x.%08x\n",
  876. mfdcr(DCRN_PEGPL_OMR1BAH(PCIE1)),
  877. mfdcr(DCRN_PEGPL_OMR1BAL(PCIE1)),
  878. mfdcr(DCRN_PEGPL_OMR1MSKH(PCIE1)),
  879. mfdcr(DCRN_PEGPL_OMR1MSKL(PCIE1)));
  880. break;
  881. #if CONFIG_SYS_PCIE_NR_PORTS > 2
  882. case 2:
  883. mtdcr(DCRN_PEGPL_OMR1BAH(PCIE2), CONFIG_SYS_PCIE_ADDR_HIGH);
  884. mtdcr(DCRN_PEGPL_OMR1BAL(PCIE2), CONFIG_SYS_PCIE_MEMBASE +
  885. port * CONFIG_SYS_PCIE_MEMSIZE);
  886. mtdcr(DCRN_PEGPL_OMR1MSKH(PCIE2), 0x7fffffff);
  887. mtdcr(DCRN_PEGPL_OMR1MSKL(PCIE2),
  888. ~(CONFIG_SYS_PCIE_MEMSIZE - 1) | 3);
  889. debug("2:PEGPL_OMR1BA=%08x.%08x MSK=%08x.%08x\n",
  890. mfdcr(DCRN_PEGPL_OMR1BAH(PCIE2)),
  891. mfdcr(DCRN_PEGPL_OMR1BAL(PCIE2)),
  892. mfdcr(DCRN_PEGPL_OMR1MSKH(PCIE2)),
  893. mfdcr(DCRN_PEGPL_OMR1MSKL(PCIE2)));
  894. break;
  895. #endif
  896. }
  897. /* Set up 4GB inbound memory window at 0 */
  898. out_le32(mbase + PCI_BASE_ADDRESS_0, 0);
  899. out_le32(mbase + PCI_BASE_ADDRESS_1, 0);
  900. out_le32(mbase + PECFG_BAR0HMPA, 0x7ffffff);
  901. out_le32(mbase + PECFG_BAR0LMPA, 0);
  902. out_le32(mbase + PECFG_PIM01SAH, 0xffff0000);
  903. out_le32(mbase + PECFG_PIM01SAL, 0x00000000);
  904. out_le32(mbase + PECFG_PIM0LAL, 0);
  905. out_le32(mbase + PECFG_PIM0LAH, 0);
  906. out_le32(mbase + PECFG_PIM1LAL, 0x00000000);
  907. out_le32(mbase + PECFG_PIM1LAH, 0x00000004);
  908. out_le32(mbase + PECFG_PIMEN, 0x1);
  909. /* Enable I/O, Mem, and Busmaster cycles */
  910. out_le16((u16 *)(mbase + PCI_COMMAND),
  911. in_le16((u16 *)(mbase + PCI_COMMAND)) |
  912. PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
  913. /* Set Device and Vendor Id */
  914. out_le16(mbase + 0x200, 0xaaa0 + port);
  915. out_le16(mbase + 0x202, 0xbed0 + port);
  916. /* Set Class Code to PCI-PCI bridge and Revision Id to 1 */
  917. out_le32(mbase + 0x208, 0x06040001);
  918. printf("PCIE%d: successfully set as root-complex\n", port);
  919. }
  920. int ppc4xx_setup_pcie_endpoint(struct pci_controller *hose, int port)
  921. {
  922. volatile void *mbase = NULL;
  923. int attempts = 0;
  924. pci_set_ops(hose,
  925. pcie_read_config_byte,
  926. pcie_read_config_word,
  927. pcie_read_config_dword,
  928. pcie_write_config_byte,
  929. pcie_write_config_word,
  930. pcie_write_config_dword);
  931. switch (port) {
  932. case 0:
  933. mbase = (u32 *)CONFIG_SYS_PCIE0_XCFGBASE;
  934. hose->cfg_data = (u8 *)CONFIG_SYS_PCIE0_CFGBASE;
  935. break;
  936. case 1:
  937. mbase = (u32 *)CONFIG_SYS_PCIE1_XCFGBASE;
  938. hose->cfg_data = (u8 *)CONFIG_SYS_PCIE1_CFGBASE;
  939. break;
  940. #if defined(CONFIG_SYS_PCIE2_CFGBASE)
  941. case 2:
  942. mbase = (u32 *)CONFIG_SYS_PCIE2_XCFGBASE;
  943. hose->cfg_data = (u8 *)CONFIG_SYS_PCIE2_CFGBASE;
  944. break;
  945. #endif
  946. }
  947. /*
  948. * Set up outbound translation to hose->mem_space from PLB
  949. * addresses at an offset of 0xd_0000_0000. We set the low
  950. * bits of the mask to 11 to turn off splitting into 8
  951. * subregions and to enable the outbound translation.
  952. */
  953. out_le32(mbase + PECFG_POM0LAH, 0x00001ff8);
  954. out_le32(mbase + PECFG_POM0LAL, 0x00001000);
  955. switch (port) {
  956. case 0:
  957. mtdcr(DCRN_PEGPL_OMR1BAH(PCIE0), CONFIG_SYS_PCIE_ADDR_HIGH);
  958. mtdcr(DCRN_PEGPL_OMR1BAL(PCIE0), CONFIG_SYS_PCIE_MEMBASE +
  959. port * CONFIG_SYS_PCIE_MEMSIZE);
  960. mtdcr(DCRN_PEGPL_OMR1MSKH(PCIE0), 0x7fffffff);
  961. mtdcr(DCRN_PEGPL_OMR1MSKL(PCIE0),
  962. ~(CONFIG_SYS_PCIE_MEMSIZE - 1) | 3);
  963. break;
  964. case 1:
  965. mtdcr(DCRN_PEGPL_OMR1BAH(PCIE1), CONFIG_SYS_PCIE_ADDR_HIGH);
  966. mtdcr(DCRN_PEGPL_OMR1BAL(PCIE1), CONFIG_SYS_PCIE_MEMBASE +
  967. port * CONFIG_SYS_PCIE_MEMSIZE);
  968. mtdcr(DCRN_PEGPL_OMR1MSKH(PCIE1), 0x7fffffff);
  969. mtdcr(DCRN_PEGPL_OMR1MSKL(PCIE1),
  970. ~(CONFIG_SYS_PCIE_MEMSIZE - 1) | 3);
  971. break;
  972. #if CONFIG_SYS_PCIE_NR_PORTS > 2
  973. case 2:
  974. mtdcr(DCRN_PEGPL_OMR1BAH(PCIE2), CONFIG_SYS_PCIE_ADDR_HIGH);
  975. mtdcr(DCRN_PEGPL_OMR1BAL(PCIE2), CONFIG_SYS_PCIE_MEMBASE +
  976. port * CONFIG_SYS_PCIE_MEMSIZE);
  977. mtdcr(DCRN_PEGPL_OMR1MSKH(PCIE2), 0x7fffffff);
  978. mtdcr(DCRN_PEGPL_OMR1MSKL(PCIE2),
  979. ~(CONFIG_SYS_PCIE_MEMSIZE - 1) | 3);
  980. break;
  981. #endif
  982. }
  983. /* Set up 64MB inbound memory window at 0 */
  984. out_le32(mbase + PCI_BASE_ADDRESS_0, 0);
  985. out_le32(mbase + PCI_BASE_ADDRESS_1, 0);
  986. out_le32(mbase + PECFG_PIM01SAH, 0xffffffff);
  987. out_le32(mbase + PECFG_PIM01SAL, 0xfc000000);
  988. /* Setup BAR0 */
  989. out_le32(mbase + PECFG_BAR0HMPA, 0x7fffffff);
  990. out_le32(mbase + PECFG_BAR0LMPA, 0xfc000000 | PCI_BASE_ADDRESS_MEM_TYPE_64);
  991. /* Disable BAR1 & BAR2 */
  992. out_le32(mbase + PECFG_BAR1MPA, 0);
  993. out_le32(mbase + PECFG_BAR2HMPA, 0);
  994. out_le32(mbase + PECFG_BAR2LMPA, 0);
  995. out_le32(mbase + PECFG_PIM0LAL, U64_TO_U32_LOW(CONFIG_SYS_PCIE_INBOUND_BASE));
  996. out_le32(mbase + PECFG_PIM0LAH, U64_TO_U32_HIGH(CONFIG_SYS_PCIE_INBOUND_BASE));
  997. out_le32(mbase + PECFG_PIMEN, 0x1);
  998. /* Enable I/O, Mem, and Busmaster cycles */
  999. out_le16((u16 *)(mbase + PCI_COMMAND),
  1000. in_le16((u16 *)(mbase + PCI_COMMAND)) |
  1001. PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
  1002. out_le16(mbase + 0x200, 0xcaad); /* Setting vendor ID */
  1003. out_le16(mbase + 0x202, 0xfeed); /* Setting device ID */
  1004. /* Set Class Code to Processor/PPC */
  1005. out_le32(mbase + 0x208, 0x0b200001);
  1006. attempts = 10;
  1007. while(!(SDR_READ(SDRN_PESDR_RCSSTS(port)) & (1 << 8))) {
  1008. if (!(attempts--)) {
  1009. printf("PCIE%d: BME not active\n", port);
  1010. return -1;
  1011. }
  1012. mdelay(1000);
  1013. }
  1014. printf("PCIE%d: successfully set as endpoint\n", port);
  1015. return 0;
  1016. }
  1017. #endif /* CONFIG_440SPE && CONFIG_PCI */