440spe_pcie.c 25 KB

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