440spe_pcie.c 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993
  1. /*
  2. * (C) Copyright 2006 - 2007
  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. #include <asm/processor.h>
  23. #include <asm-ppc/io.h>
  24. #include <ppc4xx.h>
  25. #include <common.h>
  26. #include <pci.h>
  27. #if defined(CONFIG_440SPE) && defined(CONFIG_PCI)
  28. #include "440spe_pcie.h"
  29. enum {
  30. PTYPE_ENDPOINT = 0x0,
  31. PTYPE_LEGACY_ENDPOINT = 0x1,
  32. PTYPE_ROOT_PORT = 0x4,
  33. LNKW_X1 = 0x1,
  34. LNKW_X4 = 0x4,
  35. LNKW_X8 = 0x8
  36. };
  37. static inline int pcie_in_8(const volatile unsigned char __iomem *addr)
  38. {
  39. int ret;
  40. PCIE_IN(lbzx, ret, addr);
  41. return ret;
  42. }
  43. static inline int pcie_in_le16(const volatile unsigned short __iomem *addr)
  44. {
  45. int ret;
  46. PCIE_IN(lhbrx, ret, addr)
  47. return ret;
  48. }
  49. static inline unsigned pcie_in_le32(const volatile unsigned __iomem *addr)
  50. {
  51. unsigned ret;
  52. PCIE_IN(lwbrx, ret, addr);
  53. return ret;
  54. }
  55. static int pcie_read_config(struct pci_controller *hose, unsigned int devfn,
  56. int offset, int len, u32 *val) {
  57. *val = 0;
  58. /*
  59. * 440SPE implements only one function per port
  60. */
  61. if (!((PCI_FUNC(devfn) == 0) && (PCI_DEV(devfn) == 1)))
  62. return 0;
  63. devfn = PCI_BDF(0,0,0);
  64. offset += devfn << 4;
  65. switch (len) {
  66. case 1:
  67. *val = pcie_in_8(hose->cfg_data + offset);
  68. break;
  69. case 2:
  70. *val = pcie_in_le16((u16 *)(hose->cfg_data + offset));
  71. break;
  72. default:
  73. *val = pcie_in_le32((u32*)(hose->cfg_data + offset));
  74. break;
  75. }
  76. return 0;
  77. }
  78. static int pcie_write_config(struct pci_controller *hose, unsigned int devfn,
  79. int offset, int len, u32 val) {
  80. /*
  81. * 440SPE implements only one function per port
  82. */
  83. if (!((PCI_FUNC(devfn) == 0) && (PCI_DEV(devfn) == 1)))
  84. return 0;
  85. devfn = PCI_BDF(0,0,0);
  86. offset += devfn << 4;
  87. switch (len) {
  88. case 1:
  89. out_8(hose->cfg_data + offset, val);
  90. break;
  91. case 2:
  92. out_le16((u16 *)(hose->cfg_data + offset), val);
  93. break;
  94. default:
  95. out_le32((u32 *)(hose->cfg_data + offset), val);
  96. break;
  97. }
  98. return 0;
  99. }
  100. int pcie_read_config_byte(struct pci_controller *hose,pci_dev_t dev,int offset,u8 *val)
  101. {
  102. u32 v;
  103. int rv;
  104. rv = pcie_read_config(hose, dev, offset, 1, &v);
  105. *val = (u8)v;
  106. return rv;
  107. }
  108. int pcie_read_config_word(struct pci_controller *hose,pci_dev_t dev,int offset,u16 *val)
  109. {
  110. u32 v;
  111. int rv;
  112. rv = pcie_read_config(hose, dev, offset, 2, &v);
  113. *val = (u16)v;
  114. return rv;
  115. }
  116. int pcie_read_config_dword(struct pci_controller *hose,pci_dev_t dev,int offset,u32 *val)
  117. {
  118. u32 v;
  119. int rv;
  120. rv = pcie_read_config(hose, dev, offset, 3, &v);
  121. *val = (u32)v;
  122. return rv;
  123. }
  124. int pcie_write_config_byte(struct pci_controller *hose,pci_dev_t dev,int offset,u8 val)
  125. {
  126. return pcie_write_config(hose,(u32)dev,offset,1,val);
  127. }
  128. int pcie_write_config_word(struct pci_controller *hose,pci_dev_t dev,int offset,u16 val)
  129. {
  130. return pcie_write_config(hose,(u32)dev,offset,2,(u32 )val);
  131. }
  132. int pcie_write_config_dword(struct pci_controller *hose,pci_dev_t dev,int offset,u32 val)
  133. {
  134. return pcie_write_config(hose,(u32)dev,offset,3,(u32 )val);
  135. }
  136. static void ppc440spe_setup_utl(u32 port) {
  137. volatile void *utl_base = NULL;
  138. /*
  139. * Map UTL registers
  140. */
  141. switch (port) {
  142. case 0:
  143. mtdcr(DCRN_PEGPL_REGBAH(PCIE0), 0x0000000c);
  144. mtdcr(DCRN_PEGPL_REGBAL(PCIE0), 0x20000000);
  145. mtdcr(DCRN_PEGPL_REGMSK(PCIE0), 0x00007001);
  146. mtdcr(DCRN_PEGPL_SPECIAL(PCIE0), 0x68782800);
  147. break;
  148. case 1:
  149. mtdcr(DCRN_PEGPL_REGBAH(PCIE1), 0x0000000c);
  150. mtdcr(DCRN_PEGPL_REGBAL(PCIE1), 0x20001000);
  151. mtdcr(DCRN_PEGPL_REGMSK(PCIE1), 0x00007001);
  152. mtdcr(DCRN_PEGPL_SPECIAL(PCIE1), 0x68782800);
  153. break;
  154. case 2:
  155. mtdcr(DCRN_PEGPL_REGBAH(PCIE2), 0x0000000c);
  156. mtdcr(DCRN_PEGPL_REGBAL(PCIE2), 0x20002000);
  157. mtdcr(DCRN_PEGPL_REGMSK(PCIE2), 0x00007001);
  158. mtdcr(DCRN_PEGPL_SPECIAL(PCIE2), 0x68782800);
  159. break;
  160. }
  161. utl_base = (unsigned int *)(CFG_PCIE_BASE + 0x1000 * port);
  162. /*
  163. * Set buffer allocations and then assert VRB and TXE.
  164. */
  165. out_be32(utl_base + PEUTL_OUTTR, 0x08000000);
  166. out_be32(utl_base + PEUTL_INTR, 0x02000000);
  167. out_be32(utl_base + PEUTL_OPDBSZ, 0x10000000);
  168. out_be32(utl_base + PEUTL_PBBSZ, 0x53000000);
  169. out_be32(utl_base + PEUTL_IPHBSZ, 0x08000000);
  170. out_be32(utl_base + PEUTL_IPDBSZ, 0x10000000);
  171. out_be32(utl_base + PEUTL_RCIRQEN, 0x00f00000);
  172. out_be32(utl_base + PEUTL_PCTL, 0x80800066);
  173. }
  174. static int check_error(void)
  175. {
  176. u32 valPE0, valPE1, valPE2;
  177. int err = 0;
  178. /* SDR0_PEGPLLLCT1 reset */
  179. if (!(valPE0 = SDR_READ(PESDR0_PLLLCT1) & 0x01000000)) {
  180. printf("PCIE: SDR0_PEGPLLLCT1 reset error 0x%x\n", valPE0);
  181. }
  182. valPE0 = SDR_READ(PESDR0_RCSSET);
  183. valPE1 = SDR_READ(PESDR1_RCSSET);
  184. valPE2 = SDR_READ(PESDR2_RCSSET);
  185. /* SDR0_PExRCSSET rstgu */
  186. if (!(valPE0 & 0x01000000) ||
  187. !(valPE1 & 0x01000000) ||
  188. !(valPE2 & 0x01000000)) {
  189. printf("PCIE: SDR0_PExRCSSET rstgu error\n");
  190. err = -1;
  191. }
  192. /* SDR0_PExRCSSET rstdl */
  193. if (!(valPE0 & 0x00010000) ||
  194. !(valPE1 & 0x00010000) ||
  195. !(valPE2 & 0x00010000)) {
  196. printf("PCIE: SDR0_PExRCSSET rstdl error\n");
  197. err = -1;
  198. }
  199. /* SDR0_PExRCSSET rstpyn */
  200. if ((valPE0 & 0x00001000) ||
  201. (valPE1 & 0x00001000) ||
  202. (valPE2 & 0x00001000)) {
  203. printf("PCIE: SDR0_PExRCSSET rstpyn error\n");
  204. err = -1;
  205. }
  206. /* SDR0_PExRCSSET hldplb */
  207. if ((valPE0 & 0x10000000) ||
  208. (valPE1 & 0x10000000) ||
  209. (valPE2 & 0x10000000)) {
  210. printf("PCIE: SDR0_PExRCSSET hldplb error\n");
  211. err = -1;
  212. }
  213. /* SDR0_PExRCSSET rdy */
  214. if ((valPE0 & 0x00100000) ||
  215. (valPE1 & 0x00100000) ||
  216. (valPE2 & 0x00100000)) {
  217. printf("PCIE: SDR0_PExRCSSET rdy error\n");
  218. err = -1;
  219. }
  220. /* SDR0_PExRCSSET shutdown */
  221. if ((valPE0 & 0x00000100) ||
  222. (valPE1 & 0x00000100) ||
  223. (valPE2 & 0x00000100)) {
  224. printf("PCIE: SDR0_PExRCSSET shutdown error\n");
  225. err = -1;
  226. }
  227. return err;
  228. }
  229. /*
  230. * Initialize PCI Express core
  231. */
  232. int ppc440spe_init_pcie(void)
  233. {
  234. int time_out = 20;
  235. /* Set PLL clock receiver to LVPECL */
  236. SDR_WRITE(PESDR0_PLLLCT1, SDR_READ(PESDR0_PLLLCT1) | 1 << 28);
  237. if (check_error())
  238. return -1;
  239. if (!(SDR_READ(PESDR0_PLLLCT2) & 0x10000))
  240. {
  241. printf("PCIE: PESDR_PLLCT2 resistance calibration failed (0x%08x)\n",
  242. SDR_READ(PESDR0_PLLLCT2));
  243. return -1;
  244. }
  245. /* De-assert reset of PCIe PLL, wait for lock */
  246. SDR_WRITE(PESDR0_PLLLCT1, SDR_READ(PESDR0_PLLLCT1) & ~(1 << 24));
  247. udelay(3);
  248. while (time_out) {
  249. if (!(SDR_READ(PESDR0_PLLLCT3) & 0x10000000)) {
  250. time_out--;
  251. udelay(1);
  252. } else
  253. break;
  254. }
  255. if (!time_out) {
  256. printf("PCIE: VCO output not locked\n");
  257. return -1;
  258. }
  259. return 0;
  260. }
  261. /*
  262. * Yucca board as End point and root point setup
  263. * and
  264. * testing inbound and out bound windows
  265. *
  266. * YUCCA board can be plugged into another yucca board or you can get PCI-E
  267. * cable which can be used to setup loop back from one port to another port.
  268. * Please rememeber that unless there is a endpoint plugged in to root port it
  269. * will not initialize. It is the same in case of endpoint , unless there is
  270. * root port attached it will not initialize.
  271. *
  272. * In this release of software all the PCI-E ports are configured as either
  273. * endpoint or rootpoint.In future we will have support for selective ports
  274. * setup as endpoint and root point in single board.
  275. *
  276. * Once your board came up as root point , you can verify by reading
  277. * /proc/bus/pci/devices. Where you can see the configuration registers
  278. * of end point device attached to the port.
  279. *
  280. * Enpoint cofiguration can be verified by connecting Yucca board to any
  281. * host or another yucca board. Then try to scan the device. In case of
  282. * linux use "lspci" or appripriate os command.
  283. *
  284. * How do I verify the inbound and out bound windows ?(yucca to yucca)
  285. * in this configuration inbound and outbound windows are setup to access
  286. * sram memroy area. SRAM is at 0x4 0000 0000 , on PLB bus. This address
  287. * is mapped at 0x90000000. From u-boot prompt write data 0xb000 0000,
  288. * This is waere your POM(PLB out bound memory window) mapped. then
  289. * read the data from other yucca board's u-boot prompt at address
  290. * 0x9000 0000(SRAM). Data should match.
  291. * In case of inbound , write data to u-boot command prompt at 0xb000 0000
  292. * which is mapped to 0x4 0000 0000. Now on rootpoint yucca u-boot prompt check
  293. * data at 0x9000 0000(SRAM).Data should match.
  294. */
  295. int ppc440spe_init_pcie_rootport(int port)
  296. {
  297. static int core_init;
  298. volatile u32 val = 0;
  299. int attempts;
  300. if (!core_init) {
  301. ++core_init;
  302. if (ppc440spe_init_pcie())
  303. return -1;
  304. }
  305. /*
  306. * Initialize various parts of the PCI Express core for our port:
  307. *
  308. * - Set as a root port and enable max width
  309. * (PXIE0 -> X8, PCIE1 and PCIE2 -> X4).
  310. * - Set up UTL configuration.
  311. * - Increase SERDES drive strength to levels suggested by AMCC.
  312. * - De-assert RSTPYN, RSTDL and RSTGU.
  313. *
  314. * NOTICE for revB chip: PESDRn_UTLSET2 is not set - we leave it with
  315. * default setting 0x11310000. The register has new fields,
  316. * PESDRn_UTLSET2[LKINE] in particular: clearing it leads to PCIE core
  317. * hang.
  318. */
  319. switch (port) {
  320. case 0:
  321. SDR_WRITE(PESDR0_DLPSET, 1 << 24 | PTYPE_ROOT_PORT << 20 | LNKW_X8 << 12);
  322. SDR_WRITE(PESDR0_UTLSET1, 0x21222222);
  323. if (!ppc440spe_revB())
  324. SDR_WRITE(PESDR0_UTLSET2, 0x11000000);
  325. SDR_WRITE(PESDR0_HSSL0SET1, 0x35000000);
  326. SDR_WRITE(PESDR0_HSSL1SET1, 0x35000000);
  327. SDR_WRITE(PESDR0_HSSL2SET1, 0x35000000);
  328. SDR_WRITE(PESDR0_HSSL3SET1, 0x35000000);
  329. SDR_WRITE(PESDR0_HSSL4SET1, 0x35000000);
  330. SDR_WRITE(PESDR0_HSSL5SET1, 0x35000000);
  331. SDR_WRITE(PESDR0_HSSL6SET1, 0x35000000);
  332. SDR_WRITE(PESDR0_HSSL7SET1, 0x35000000);
  333. SDR_WRITE(PESDR0_RCSSET,
  334. (SDR_READ(PESDR0_RCSSET) & ~(1 << 24 | 1 << 16)) | 1 << 12);
  335. break;
  336. case 1:
  337. SDR_WRITE(PESDR1_DLPSET, 1 << 24 | PTYPE_ROOT_PORT << 20 | LNKW_X4 << 12);
  338. SDR_WRITE(PESDR1_UTLSET1, 0x21222222);
  339. if (!ppc440spe_revB())
  340. SDR_WRITE(PESDR1_UTLSET2, 0x11000000);
  341. SDR_WRITE(PESDR1_HSSL0SET1, 0x35000000);
  342. SDR_WRITE(PESDR1_HSSL1SET1, 0x35000000);
  343. SDR_WRITE(PESDR1_HSSL2SET1, 0x35000000);
  344. SDR_WRITE(PESDR1_HSSL3SET1, 0x35000000);
  345. SDR_WRITE(PESDR1_RCSSET,
  346. (SDR_READ(PESDR1_RCSSET) & ~(1 << 24 | 1 << 16)) | 1 << 12);
  347. break;
  348. case 2:
  349. SDR_WRITE(PESDR2_DLPSET, 1 << 24 | PTYPE_ROOT_PORT << 20 | LNKW_X4 << 12);
  350. SDR_WRITE(PESDR2_UTLSET1, 0x21222222);
  351. if (!ppc440spe_revB())
  352. SDR_WRITE(PESDR2_UTLSET2, 0x11000000);
  353. SDR_WRITE(PESDR2_HSSL0SET1, 0x35000000);
  354. SDR_WRITE(PESDR2_HSSL1SET1, 0x35000000);
  355. SDR_WRITE(PESDR2_HSSL2SET1, 0x35000000);
  356. SDR_WRITE(PESDR2_HSSL3SET1, 0x35000000);
  357. SDR_WRITE(PESDR2_RCSSET,
  358. (SDR_READ(PESDR2_RCSSET) & ~(1 << 24 | 1 << 16)) | 1 << 12);
  359. break;
  360. }
  361. /*
  362. * Notice: the following delay has critical impact on device
  363. * initialization - if too short (<50ms) the link doesn't get up.
  364. */
  365. mdelay(100);
  366. switch (port) {
  367. case 0:
  368. val = SDR_READ(PESDR0_RCSSTS);
  369. break;
  370. case 1:
  371. val = SDR_READ(PESDR1_RCSSTS);
  372. break;
  373. case 2:
  374. val = SDR_READ(PESDR2_RCSSTS);
  375. break;
  376. }
  377. if (val & (1 << 20)) {
  378. printf("PCIE%d: PGRST failed %08x\n", port, val);
  379. return -1;
  380. }
  381. /*
  382. * Verify link is up
  383. */
  384. val = 0;
  385. switch (port) {
  386. case 0:
  387. val = SDR_READ(PESDR0_LOOP);
  388. break;
  389. case 1:
  390. val = SDR_READ(PESDR1_LOOP);
  391. break;
  392. case 2:
  393. val = SDR_READ(PESDR2_LOOP);
  394. break;
  395. }
  396. if (!(val & 0x00001000)) {
  397. printf("PCIE%d: link is not up.\n", port);
  398. return -1;
  399. }
  400. /*
  401. * Setup UTL registers - but only on revA!
  402. * We use default settings for revB chip.
  403. */
  404. if (!ppc440spe_revB())
  405. ppc440spe_setup_utl(port);
  406. /*
  407. * We map PCI Express configuration access into the 512MB regions
  408. *
  409. * NOTICE: revB is very strict about PLB real addressess and ranges to
  410. * be mapped for config space; it seems to only work with d_nnnn_nnnn
  411. * range (hangs the core upon config transaction attempts when set
  412. * otherwise) while revA uses c_nnnn_nnnn.
  413. *
  414. * For revA:
  415. * PCIE0: 0xc_4000_0000
  416. * PCIE1: 0xc_8000_0000
  417. * PCIE2: 0xc_c000_0000
  418. *
  419. * For revB:
  420. * PCIE0: 0xd_0000_0000
  421. * PCIE1: 0xd_2000_0000
  422. * PCIE2: 0xd_4000_0000
  423. */
  424. switch (port) {
  425. case 0:
  426. if (ppc440spe_revB()) {
  427. mtdcr(DCRN_PEGPL_CFGBAH(PCIE0), 0x0000000d);
  428. mtdcr(DCRN_PEGPL_CFGBAL(PCIE0), 0x00000000);
  429. } else {
  430. /* revA */
  431. mtdcr(DCRN_PEGPL_CFGBAH(PCIE0), 0x0000000c);
  432. mtdcr(DCRN_PEGPL_CFGBAL(PCIE0), 0x40000000);
  433. }
  434. mtdcr(DCRN_PEGPL_CFGMSK(PCIE0), 0xe0000001); /* 512MB region, valid */
  435. break;
  436. case 1:
  437. if (ppc440spe_revB()) {
  438. mtdcr(DCRN_PEGPL_CFGBAH(PCIE1), 0x0000000d);
  439. mtdcr(DCRN_PEGPL_CFGBAL(PCIE1), 0x20000000);
  440. } else {
  441. mtdcr(DCRN_PEGPL_CFGBAH(PCIE1), 0x0000000c);
  442. mtdcr(DCRN_PEGPL_CFGBAL(PCIE1), 0x80000000);
  443. }
  444. mtdcr(DCRN_PEGPL_CFGMSK(PCIE1), 0xe0000001); /* 512MB region, valid */
  445. break;
  446. case 2:
  447. if (ppc440spe_revB()) {
  448. mtdcr(DCRN_PEGPL_CFGBAH(PCIE2), 0x0000000d);
  449. mtdcr(DCRN_PEGPL_CFGBAL(PCIE2), 0x40000000);
  450. } else {
  451. mtdcr(DCRN_PEGPL_CFGBAH(PCIE2), 0x0000000c);
  452. mtdcr(DCRN_PEGPL_CFGBAL(PCIE2), 0xc0000000);
  453. }
  454. mtdcr(DCRN_PEGPL_CFGMSK(PCIE2), 0xe0000001); /* 512MB region, valid */
  455. break;
  456. }
  457. /*
  458. * Check for VC0 active and assert RDY.
  459. */
  460. attempts = 10;
  461. switch (port) {
  462. case 0:
  463. while(!(SDR_READ(PESDR0_RCSSTS) & (1 << 16))) {
  464. if (!(attempts--)) {
  465. printf("PCIE0: VC0 not active\n");
  466. return -1;
  467. }
  468. mdelay(1000);
  469. }
  470. SDR_WRITE(PESDR0_RCSSET, SDR_READ(PESDR0_RCSSET) | 1 << 20);
  471. break;
  472. case 1:
  473. while(!(SDR_READ(PESDR1_RCSSTS) & (1 << 16))) {
  474. if (!(attempts--)) {
  475. printf("PCIE1: VC0 not active\n");
  476. return -1;
  477. }
  478. mdelay(1000);
  479. }
  480. SDR_WRITE(PESDR1_RCSSET, SDR_READ(PESDR1_RCSSET) | 1 << 20);
  481. break;
  482. case 2:
  483. while(!(SDR_READ(PESDR2_RCSSTS) & (1 << 16))) {
  484. if (!(attempts--)) {
  485. printf("PCIE2: VC0 not active\n");
  486. return -1;
  487. }
  488. mdelay(1000);
  489. }
  490. SDR_WRITE(PESDR2_RCSSET, SDR_READ(PESDR2_RCSSET) | 1 << 20);
  491. break;
  492. }
  493. mdelay(100);
  494. return 0;
  495. }
  496. int ppc440spe_init_pcie_endport(int port)
  497. {
  498. static int core_init;
  499. volatile u32 val = 0;
  500. int attempts;
  501. if (!core_init) {
  502. ++core_init;
  503. if (ppc440spe_init_pcie())
  504. return -1;
  505. }
  506. /*
  507. * Initialize various parts of the PCI Express core for our port:
  508. *
  509. * - Set as a end port and enable max width
  510. * (PXIE0 -> X8, PCIE1 and PCIE2 -> X4).
  511. * - Set up UTL configuration.
  512. * - Increase SERDES drive strength to levels suggested by AMCC.
  513. * - De-assert RSTPYN, RSTDL and RSTGU.
  514. *
  515. * NOTICE for revB chip: PESDRn_UTLSET2 is not set - we leave it with
  516. * default setting 0x11310000. The register has new fields,
  517. * PESDRn_UTLSET2[LKINE] in particular: clearing it leads to PCIE core
  518. * hang.
  519. */
  520. switch (port) {
  521. case 0:
  522. SDR_WRITE(PESDR0_DLPSET, 1 << 24 | PTYPE_LEGACY_ENDPOINT << 20 | LNKW_X8 << 12);
  523. SDR_WRITE(PESDR0_UTLSET1, 0x20222222);
  524. if (!ppc440spe_revB())
  525. SDR_WRITE(PESDR0_UTLSET2, 0x11000000);
  526. SDR_WRITE(PESDR0_HSSL0SET1, 0x35000000);
  527. SDR_WRITE(PESDR0_HSSL1SET1, 0x35000000);
  528. SDR_WRITE(PESDR0_HSSL2SET1, 0x35000000);
  529. SDR_WRITE(PESDR0_HSSL3SET1, 0x35000000);
  530. SDR_WRITE(PESDR0_HSSL4SET1, 0x35000000);
  531. SDR_WRITE(PESDR0_HSSL5SET1, 0x35000000);
  532. SDR_WRITE(PESDR0_HSSL6SET1, 0x35000000);
  533. SDR_WRITE(PESDR0_HSSL7SET1, 0x35000000);
  534. SDR_WRITE(PESDR0_RCSSET,
  535. (SDR_READ(PESDR0_RCSSET) & ~(1 << 24 | 1 << 16)) | 1 << 12);
  536. break;
  537. case 1:
  538. SDR_WRITE(PESDR1_DLPSET, 1 << 24 | PTYPE_LEGACY_ENDPOINT << 20 | LNKW_X4 << 12);
  539. SDR_WRITE(PESDR1_UTLSET1, 0x20222222);
  540. if (!ppc440spe_revB())
  541. SDR_WRITE(PESDR1_UTLSET2, 0x11000000);
  542. SDR_WRITE(PESDR1_HSSL0SET1, 0x35000000);
  543. SDR_WRITE(PESDR1_HSSL1SET1, 0x35000000);
  544. SDR_WRITE(PESDR1_HSSL2SET1, 0x35000000);
  545. SDR_WRITE(PESDR1_HSSL3SET1, 0x35000000);
  546. SDR_WRITE(PESDR1_RCSSET,
  547. (SDR_READ(PESDR1_RCSSET) & ~(1 << 24 | 1 << 16)) | 1 << 12);
  548. break;
  549. case 2:
  550. SDR_WRITE(PESDR2_DLPSET, 1 << 24 | PTYPE_LEGACY_ENDPOINT << 20 | LNKW_X4 << 12);
  551. SDR_WRITE(PESDR2_UTLSET1, 0x20222222);
  552. if (!ppc440spe_revB())
  553. SDR_WRITE(PESDR2_UTLSET2, 0x11000000);
  554. SDR_WRITE(PESDR2_HSSL0SET1, 0x35000000);
  555. SDR_WRITE(PESDR2_HSSL1SET1, 0x35000000);
  556. SDR_WRITE(PESDR2_HSSL2SET1, 0x35000000);
  557. SDR_WRITE(PESDR2_HSSL3SET1, 0x35000000);
  558. SDR_WRITE(PESDR2_RCSSET,
  559. (SDR_READ(PESDR2_RCSSET) & ~(1 << 24 | 1 << 16)) | 1 << 12);
  560. break;
  561. }
  562. /*
  563. * Notice: the following delay has critical impact on device
  564. * initialization - if too short (<50ms) the link doesn't get up.
  565. */
  566. mdelay(100);
  567. switch (port) {
  568. case 0: val = SDR_READ(PESDR0_RCSSTS); break;
  569. case 1: val = SDR_READ(PESDR1_RCSSTS); break;
  570. case 2: val = SDR_READ(PESDR2_RCSSTS); break;
  571. }
  572. if (val & (1 << 20)) {
  573. printf("PCIE%d: PGRST failed %08x\n", port, val);
  574. return -1;
  575. }
  576. /*
  577. * Verify link is up
  578. */
  579. val = 0;
  580. switch (port)
  581. {
  582. case 0:
  583. val = SDR_READ(PESDR0_LOOP);
  584. break;
  585. case 1:
  586. val = SDR_READ(PESDR1_LOOP);
  587. break;
  588. case 2:
  589. val = SDR_READ(PESDR2_LOOP);
  590. break;
  591. }
  592. if (!(val & 0x00001000)) {
  593. printf("PCIE%d: link is not up.\n", port);
  594. return -1;
  595. }
  596. /*
  597. * Setup UTL registers - but only on revA!
  598. * We use default settings for revB chip.
  599. */
  600. if (!ppc440spe_revB())
  601. ppc440spe_setup_utl(port);
  602. /*
  603. * We map PCI Express configuration access into the 512MB regions
  604. *
  605. * NOTICE: revB is very strict about PLB real addressess and ranges to
  606. * be mapped for config space; it seems to only work with d_nnnn_nnnn
  607. * range (hangs the core upon config transaction attempts when set
  608. * otherwise) while revA uses c_nnnn_nnnn.
  609. *
  610. * For revA:
  611. * PCIE0: 0xc_4000_0000
  612. * PCIE1: 0xc_8000_0000
  613. * PCIE2: 0xc_c000_0000
  614. *
  615. * For revB:
  616. * PCIE0: 0xd_0000_0000
  617. * PCIE1: 0xd_2000_0000
  618. * PCIE2: 0xd_4000_0000
  619. */
  620. switch (port) {
  621. case 0:
  622. if (ppc440spe_revB()) {
  623. mtdcr(DCRN_PEGPL_CFGBAH(PCIE0), 0x0000000d);
  624. mtdcr(DCRN_PEGPL_CFGBAL(PCIE0), 0x00000000);
  625. } else {
  626. /* revA */
  627. mtdcr(DCRN_PEGPL_CFGBAH(PCIE0), 0x0000000c);
  628. mtdcr(DCRN_PEGPL_CFGBAL(PCIE0), 0x40000000);
  629. }
  630. mtdcr(DCRN_PEGPL_CFGMSK(PCIE0), 0xe0000001); /* 512MB region, valid */
  631. break;
  632. case 1:
  633. if (ppc440spe_revB()) {
  634. mtdcr(DCRN_PEGPL_CFGBAH(PCIE1), 0x0000000d);
  635. mtdcr(DCRN_PEGPL_CFGBAL(PCIE1), 0x20000000);
  636. } else {
  637. mtdcr(DCRN_PEGPL_CFGBAH(PCIE1), 0x0000000c);
  638. mtdcr(DCRN_PEGPL_CFGBAL(PCIE1), 0x80000000);
  639. }
  640. mtdcr(DCRN_PEGPL_CFGMSK(PCIE1), 0xe0000001); /* 512MB region, valid */
  641. break;
  642. case 2:
  643. if (ppc440spe_revB()) {
  644. mtdcr(DCRN_PEGPL_CFGBAH(PCIE2), 0x0000000d);
  645. mtdcr(DCRN_PEGPL_CFGBAL(PCIE2), 0x40000000);
  646. } else {
  647. mtdcr(DCRN_PEGPL_CFGBAH(PCIE2), 0x0000000c);
  648. mtdcr(DCRN_PEGPL_CFGBAL(PCIE2), 0xc0000000);
  649. }
  650. mtdcr(DCRN_PEGPL_CFGMSK(PCIE2), 0xe0000001); /* 512MB region, valid */
  651. break;
  652. }
  653. /*
  654. * Check for VC0 active and assert RDY.
  655. */
  656. attempts = 10;
  657. switch (port) {
  658. case 0:
  659. while(!(SDR_READ(PESDR0_RCSSTS) & (1 << 16))) {
  660. if (!(attempts--)) {
  661. printf("PCIE0: VC0 not active\n");
  662. return -1;
  663. }
  664. mdelay(1000);
  665. }
  666. SDR_WRITE(PESDR0_RCSSET, SDR_READ(PESDR0_RCSSET) | 1 << 20);
  667. break;
  668. case 1:
  669. while(!(SDR_READ(PESDR1_RCSSTS) & (1 << 16))) {
  670. if (!(attempts--)) {
  671. printf("PCIE1: VC0 not active\n");
  672. return -1;
  673. }
  674. mdelay(1000);
  675. }
  676. SDR_WRITE(PESDR1_RCSSET, SDR_READ(PESDR1_RCSSET) | 1 << 20);
  677. break;
  678. case 2:
  679. while(!(SDR_READ(PESDR2_RCSSTS) & (1 << 16))) {
  680. if (!(attempts--)) {
  681. printf("PCIE2: VC0 not active\n");
  682. return -1;
  683. }
  684. mdelay(1000);
  685. }
  686. SDR_WRITE(PESDR2_RCSSET, SDR_READ(PESDR2_RCSSET) | 1 << 20);
  687. break;
  688. }
  689. mdelay(100);
  690. return 0;
  691. }
  692. void ppc440spe_setup_pcie_rootpoint(struct pci_controller *hose, int port)
  693. {
  694. volatile void *mbase = NULL;
  695. volatile void *rmbase = NULL;
  696. pci_set_ops(hose,
  697. pcie_read_config_byte,
  698. pcie_read_config_word,
  699. pcie_read_config_dword,
  700. pcie_write_config_byte,
  701. pcie_write_config_word,
  702. pcie_write_config_dword);
  703. switch (port) {
  704. case 0:
  705. mbase = (u32 *)CFG_PCIE0_XCFGBASE;
  706. rmbase = (u32 *)CFG_PCIE0_CFGBASE;
  707. hose->cfg_data = (u8 *)CFG_PCIE0_CFGBASE;
  708. break;
  709. case 1:
  710. mbase = (u32 *)CFG_PCIE1_XCFGBASE;
  711. rmbase = (u32 *)CFG_PCIE1_CFGBASE;
  712. hose->cfg_data = (u8 *)CFG_PCIE1_CFGBASE;
  713. break;
  714. case 2:
  715. mbase = (u32 *)CFG_PCIE2_XCFGBASE;
  716. rmbase = (u32 *)CFG_PCIE2_CFGBASE;
  717. hose->cfg_data = (u8 *)CFG_PCIE2_CFGBASE;
  718. break;
  719. }
  720. /*
  721. * Set bus numbers on our root port
  722. */
  723. if (ppc440spe_revB()) {
  724. out_8((u8 *)mbase + PCI_PRIMARY_BUS, 0);
  725. out_8((u8 *)mbase + PCI_SECONDARY_BUS, 1);
  726. out_8((u8 *)mbase + PCI_SUBORDINATE_BUS, 1);
  727. } else {
  728. out_8((u8 *)mbase + PCI_PRIMARY_BUS, 0);
  729. out_8((u8 *)mbase + PCI_SECONDARY_BUS, 0);
  730. }
  731. /*
  732. * Set up outbound translation to hose->mem_space from PLB
  733. * addresses at an offset of 0xd_0000_0000. We set the low
  734. * bits of the mask to 11 to turn off splitting into 8
  735. * subregions and to enable the outbound translation.
  736. */
  737. out_le32(mbase + PECFG_POM0LAH, 0x00000000);
  738. out_le32(mbase + PECFG_POM0LAL, 0x00000000);
  739. switch (port) {
  740. case 0:
  741. mtdcr(DCRN_PEGPL_OMR1BAH(PCIE0), 0x0000000d);
  742. mtdcr(DCRN_PEGPL_OMR1BAL(PCIE0), CFG_PCIE_MEMBASE +
  743. port * CFG_PCIE_MEMSIZE);
  744. mtdcr(DCRN_PEGPL_OMR1MSKH(PCIE0), 0x7fffffff);
  745. mtdcr(DCRN_PEGPL_OMR1MSKL(PCIE0),
  746. ~(CFG_PCIE_MEMSIZE - 1) | 3);
  747. break;
  748. case 1:
  749. mtdcr(DCRN_PEGPL_OMR1BAH(PCIE1), 0x0000000d);
  750. mtdcr(DCRN_PEGPL_OMR1BAL(PCIE1), (CFG_PCIE_MEMBASE +
  751. port * CFG_PCIE_MEMSIZE));
  752. mtdcr(DCRN_PEGPL_OMR1MSKH(PCIE1), 0x7fffffff);
  753. mtdcr(DCRN_PEGPL_OMR1MSKL(PCIE1),
  754. ~(CFG_PCIE_MEMSIZE - 1) | 3);
  755. break;
  756. case 2:
  757. mtdcr(DCRN_PEGPL_OMR1BAH(PCIE2), 0x0000000d);
  758. mtdcr(DCRN_PEGPL_OMR1BAL(PCIE2), (CFG_PCIE_MEMBASE +
  759. port * CFG_PCIE_MEMSIZE));
  760. mtdcr(DCRN_PEGPL_OMR1MSKH(PCIE2), 0x7fffffff);
  761. mtdcr(DCRN_PEGPL_OMR1MSKL(PCIE2),
  762. ~(CFG_PCIE_MEMSIZE - 1) | 3);
  763. break;
  764. }
  765. /* Set up 16GB inbound memory window at 0 */
  766. out_le32(mbase + PCI_BASE_ADDRESS_0, 0);
  767. out_le32(mbase + PCI_BASE_ADDRESS_1, 0);
  768. out_le32(mbase + PECFG_BAR0HMPA, 0x7fffffc);
  769. out_le32(mbase + PECFG_BAR0LMPA, 0);
  770. out_le32(mbase + PECFG_PIM01SAH, 0xffff0000);
  771. out_le32(mbase + PECFG_PIM01SAL, 0x00000000);
  772. out_le32(mbase + PECFG_PIM0LAL, 0);
  773. out_le32(mbase + PECFG_PIM0LAH, 0);
  774. out_le32(mbase + PECFG_PIM1LAL, 0x00000000);
  775. out_le32(mbase + PECFG_PIM1LAH, 0x00000004);
  776. out_le32(mbase + PECFG_PIMEN, 0x1);
  777. /* Enable I/O, Mem, and Busmaster cycles */
  778. out_le16((u16 *)(mbase + PCI_COMMAND),
  779. in_le16((u16 *)(mbase + PCI_COMMAND)) |
  780. PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
  781. printf("PCIE:%d successfully set as rootpoint\n",port);
  782. }
  783. int ppc440spe_setup_pcie_endpoint(struct pci_controller *hose, int port)
  784. {
  785. volatile void *mbase = NULL;
  786. int attempts = 0;
  787. pci_set_ops(hose,
  788. pcie_read_config_byte,
  789. pcie_read_config_word,
  790. pcie_read_config_dword,
  791. pcie_write_config_byte,
  792. pcie_write_config_word,
  793. pcie_write_config_dword);
  794. switch (port) {
  795. case 0:
  796. mbase = (u32 *)CFG_PCIE0_XCFGBASE;
  797. hose->cfg_data = (u8 *)CFG_PCIE0_CFGBASE;
  798. break;
  799. case 1:
  800. mbase = (u32 *)CFG_PCIE1_XCFGBASE;
  801. hose->cfg_data = (u8 *)CFG_PCIE1_CFGBASE;
  802. break;
  803. case 2:
  804. mbase = (u32 *)CFG_PCIE2_XCFGBASE;
  805. hose->cfg_data = (u8 *)CFG_PCIE2_CFGBASE;
  806. break;
  807. }
  808. /*
  809. * Set up outbound translation to hose->mem_space from PLB
  810. * addresses at an offset of 0xd_0000_0000. We set the low
  811. * bits of the mask to 11 to turn off splitting into 8
  812. * subregions and to enable the outbound translation.
  813. */
  814. out_le32(mbase + PECFG_POM0LAH, 0x00001ff8);
  815. out_le32(mbase + PECFG_POM0LAL, 0x00001000);
  816. switch (port) {
  817. case 0:
  818. mtdcr(DCRN_PEGPL_OMR1BAH(PCIE0), 0x0000000d);
  819. mtdcr(DCRN_PEGPL_OMR1BAL(PCIE0), CFG_PCIE_MEMBASE +
  820. port * CFG_PCIE_MEMSIZE);
  821. mtdcr(DCRN_PEGPL_OMR1MSKH(PCIE0), 0x7fffffff);
  822. mtdcr(DCRN_PEGPL_OMR1MSKL(PCIE0),
  823. ~(CFG_PCIE_MEMSIZE - 1) | 3);
  824. break;
  825. case 1:
  826. mtdcr(DCRN_PEGPL_OMR1BAH(PCIE1), 0x0000000d);
  827. mtdcr(DCRN_PEGPL_OMR1BAL(PCIE1), (CFG_PCIE_MEMBASE +
  828. port * CFG_PCIE_MEMSIZE));
  829. mtdcr(DCRN_PEGPL_OMR1MSKH(PCIE1), 0x7fffffff);
  830. mtdcr(DCRN_PEGPL_OMR1MSKL(PCIE1),
  831. ~(CFG_PCIE_MEMSIZE - 1) | 3);
  832. break;
  833. case 2:
  834. mtdcr(DCRN_PEGPL_OMR1BAH(PCIE2), 0x0000000d);
  835. mtdcr(DCRN_PEGPL_OMR1BAL(PCIE2), (CFG_PCIE_MEMBASE +
  836. port * CFG_PCIE_MEMSIZE));
  837. mtdcr(DCRN_PEGPL_OMR1MSKH(PCIE2), 0x7fffffff);
  838. mtdcr(DCRN_PEGPL_OMR1MSKL(PCIE2),
  839. ~(CFG_PCIE_MEMSIZE - 1) | 3);
  840. break;
  841. }
  842. /* Set up 16GB inbound memory window at 0 */
  843. out_le32(mbase + PCI_BASE_ADDRESS_0, 0);
  844. out_le32(mbase + PCI_BASE_ADDRESS_1, 0);
  845. out_le32(mbase + PECFG_BAR0HMPA, 0x7fffffc);
  846. out_le32(mbase + PECFG_BAR0LMPA, 0);
  847. out_le32(mbase + PECFG_PIM0LAL, 0x00000000);
  848. out_le32(mbase + PECFG_PIM0LAH, 0x00000004); /* pointing to SRAM */
  849. out_le32(mbase + PECFG_PIMEN, 0x1);
  850. /* Enable I/O, Mem, and Busmaster cycles */
  851. out_le16((u16 *)(mbase + PCI_COMMAND),
  852. in_le16((u16 *)(mbase + PCI_COMMAND)) |
  853. PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
  854. out_le16(mbase + 0x200,0xcaad); /* Setting vendor ID */
  855. out_le16(mbase + 0x202,0xfeed); /* Setting device ID */
  856. attempts = 10;
  857. switch (port) {
  858. case 0:
  859. while (!(SDR_READ(PESDR0_RCSSTS) & (1 << 8))) {
  860. if (!(attempts--)) {
  861. printf("PCIE0: BMEN is not active\n");
  862. return -1;
  863. }
  864. mdelay(1000);
  865. }
  866. break;
  867. case 1:
  868. while (!(SDR_READ(PESDR1_RCSSTS) & (1 << 8))) {
  869. if (!(attempts--)) {
  870. printf("PCIE1: BMEN is not active\n");
  871. return -1;
  872. }
  873. mdelay(1000);
  874. }
  875. break;
  876. case 2:
  877. while (!(SDR_READ(PESDR2_RCSSTS) & (1 << 8))) {
  878. if (!(attempts--)) {
  879. printf("PCIE2: BMEN is not active\n");
  880. return -1;
  881. }
  882. mdelay(1000);
  883. }
  884. break;
  885. }
  886. printf("PCIE:%d successfully set as endpoint\n",port);
  887. return 0;
  888. }
  889. #endif /* CONFIG_440SPE && CONFIG_PCI */