pcie_fsl.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684
  1. // SPDX-License-Identifier: GPL-2.0+ OR X11
  2. /*
  3. * Copyright 2019 NXP
  4. *
  5. * PCIe DM U-Boot driver for Freescale PowerPC SoCs
  6. * Author: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
  7. */
  8. #include <common.h>
  9. #include <dm.h>
  10. #include <malloc.h>
  11. #include <mapmem.h>
  12. #include <pci.h>
  13. #include <asm/fsl_pci.h>
  14. #include <asm/fsl_serdes.h>
  15. #include <asm/global_data.h>
  16. #include <asm/io.h>
  17. #include <linux/delay.h>
  18. #include "pcie_fsl.h"
  19. #include <dm/device_compat.h>
  20. LIST_HEAD(fsl_pcie_list);
  21. static int fsl_pcie_link_up(struct fsl_pcie *pcie);
  22. static int fsl_pcie_addr_valid(struct fsl_pcie *pcie, pci_dev_t bdf)
  23. {
  24. struct udevice *bus = pcie->bus;
  25. if (!pcie->enabled)
  26. return -ENXIO;
  27. if (PCI_BUS(bdf) < dev_seq(bus))
  28. return -EINVAL;
  29. if (PCI_BUS(bdf) > dev_seq(bus) && (!fsl_pcie_link_up(pcie) || pcie->mode))
  30. return -EINVAL;
  31. if (PCI_BUS(bdf) == dev_seq(bus) && (PCI_DEV(bdf) > 0 || PCI_FUNC(bdf) > 0))
  32. return -EINVAL;
  33. if (PCI_BUS(bdf) == (dev_seq(bus) + 1) && (PCI_DEV(bdf) > 0))
  34. return -EINVAL;
  35. return 0;
  36. }
  37. static int fsl_pcie_read_config(const struct udevice *bus, pci_dev_t bdf,
  38. uint offset, ulong *valuep,
  39. enum pci_size_t size)
  40. {
  41. struct fsl_pcie *pcie = dev_get_priv(bus);
  42. ccsr_fsl_pci_t *regs = pcie->regs;
  43. u32 val;
  44. if (fsl_pcie_addr_valid(pcie, bdf)) {
  45. *valuep = pci_get_ff(size);
  46. return 0;
  47. }
  48. /* Skip Freescale PCIe controller's PEXCSRBAR register */
  49. if (PCI_BUS(bdf) - dev_seq(bus) == 0 &&
  50. PCI_DEV(bdf) == 0 && PCI_FUNC(bdf) == 0 &&
  51. (offset & ~3) == PCI_BASE_ADDRESS_0) {
  52. *valuep = 0;
  53. return 0;
  54. }
  55. val = PCI_CONF1_EXT_ADDRESS(PCI_BUS(bdf) - dev_seq(bus),
  56. PCI_DEV(bdf), PCI_FUNC(bdf),
  57. offset);
  58. out_be32(&regs->cfg_addr, val);
  59. sync();
  60. switch (size) {
  61. case PCI_SIZE_8:
  62. *valuep = in_8((u8 *)&regs->cfg_data + (offset & 3));
  63. break;
  64. case PCI_SIZE_16:
  65. *valuep = in_le16((u16 *)((u8 *)&regs->cfg_data +
  66. (offset & 2)));
  67. break;
  68. case PCI_SIZE_32:
  69. *valuep = in_le32(&regs->cfg_data);
  70. break;
  71. }
  72. return 0;
  73. }
  74. static int fsl_pcie_write_config(struct udevice *bus, pci_dev_t bdf,
  75. uint offset, ulong value,
  76. enum pci_size_t size)
  77. {
  78. struct fsl_pcie *pcie = dev_get_priv(bus);
  79. ccsr_fsl_pci_t *regs = pcie->regs;
  80. u32 val;
  81. u8 val_8;
  82. u16 val_16;
  83. u32 val_32;
  84. if (fsl_pcie_addr_valid(pcie, bdf))
  85. return 0;
  86. /* Skip Freescale PCIe controller's PEXCSRBAR register */
  87. if (PCI_BUS(bdf) - dev_seq(bus) == 0 &&
  88. PCI_DEV(bdf) == 0 && PCI_FUNC(bdf) == 0 &&
  89. (offset & ~3) == PCI_BASE_ADDRESS_0)
  90. return 0;
  91. val = PCI_CONF1_EXT_ADDRESS(PCI_BUS(bdf) - dev_seq(bus),
  92. PCI_DEV(bdf), PCI_FUNC(bdf),
  93. offset);
  94. out_be32(&regs->cfg_addr, val);
  95. sync();
  96. switch (size) {
  97. case PCI_SIZE_8:
  98. val_8 = value;
  99. out_8((u8 *)&regs->cfg_data + (offset & 3), val_8);
  100. break;
  101. case PCI_SIZE_16:
  102. val_16 = value;
  103. out_le16((u16 *)((u8 *)&regs->cfg_data + (offset & 2)), val_16);
  104. break;
  105. case PCI_SIZE_32:
  106. val_32 = value;
  107. out_le32(&regs->cfg_data, val_32);
  108. break;
  109. }
  110. return 0;
  111. }
  112. static int fsl_pcie_hose_read_config(struct fsl_pcie *pcie, uint offset,
  113. ulong *valuep, enum pci_size_t size)
  114. {
  115. int ret;
  116. struct udevice *bus = pcie->bus;
  117. ret = fsl_pcie_read_config(bus, PCI_BDF(dev_seq(bus), 0, 0),
  118. offset, valuep, size);
  119. return ret;
  120. }
  121. static int fsl_pcie_hose_write_config(struct fsl_pcie *pcie, uint offset,
  122. ulong value, enum pci_size_t size)
  123. {
  124. struct udevice *bus = pcie->bus;
  125. return fsl_pcie_write_config(bus, PCI_BDF(dev_seq(bus), 0, 0),
  126. offset, value, size);
  127. }
  128. static int fsl_pcie_hose_read_config_byte(struct fsl_pcie *pcie, uint offset,
  129. u8 *valuep)
  130. {
  131. ulong val;
  132. int ret;
  133. ret = fsl_pcie_hose_read_config(pcie, offset, &val, PCI_SIZE_8);
  134. *valuep = val;
  135. return ret;
  136. }
  137. static int fsl_pcie_hose_read_config_word(struct fsl_pcie *pcie, uint offset,
  138. u16 *valuep)
  139. {
  140. ulong val;
  141. int ret;
  142. ret = fsl_pcie_hose_read_config(pcie, offset, &val, PCI_SIZE_16);
  143. *valuep = val;
  144. return ret;
  145. }
  146. static int fsl_pcie_hose_read_config_dword(struct fsl_pcie *pcie, uint offset,
  147. u32 *valuep)
  148. {
  149. ulong val;
  150. int ret;
  151. ret = fsl_pcie_hose_read_config(pcie, offset, &val, PCI_SIZE_32);
  152. *valuep = val;
  153. return ret;
  154. }
  155. static int fsl_pcie_hose_write_config_byte(struct fsl_pcie *pcie, uint offset,
  156. u8 value)
  157. {
  158. return fsl_pcie_hose_write_config(pcie, offset, value, PCI_SIZE_8);
  159. }
  160. static int fsl_pcie_hose_write_config_word(struct fsl_pcie *pcie, uint offset,
  161. u16 value)
  162. {
  163. return fsl_pcie_hose_write_config(pcie, offset, value, PCI_SIZE_16);
  164. }
  165. static int fsl_pcie_hose_write_config_dword(struct fsl_pcie *pcie, uint offset,
  166. u32 value)
  167. {
  168. return fsl_pcie_hose_write_config(pcie, offset, value, PCI_SIZE_32);
  169. }
  170. static int fsl_pcie_link_up(struct fsl_pcie *pcie)
  171. {
  172. ccsr_fsl_pci_t *regs = pcie->regs;
  173. u16 ltssm;
  174. if (pcie->block_rev >= PEX_IP_BLK_REV_3_0) {
  175. ltssm = (in_be32(&regs->pex_csr0)
  176. & PEX_CSR0_LTSSM_MASK) >> PEX_CSR0_LTSSM_SHIFT;
  177. return ltssm == LTSSM_L0_REV3;
  178. }
  179. fsl_pcie_hose_read_config_word(pcie, PCI_LTSSM, &ltssm);
  180. return ltssm == LTSSM_L0;
  181. }
  182. static bool fsl_pcie_is_agent(struct fsl_pcie *pcie)
  183. {
  184. u8 header_type;
  185. fsl_pcie_hose_read_config_byte(pcie, PCI_HEADER_TYPE, &header_type);
  186. return (header_type & 0x7f) == PCI_HEADER_TYPE_NORMAL;
  187. }
  188. static int fsl_pcie_setup_law(struct fsl_pcie *pcie)
  189. {
  190. struct pci_region *io, *mem, *pref;
  191. pci_get_regions(pcie->bus, &io, &mem, &pref);
  192. if (mem)
  193. set_next_law(mem->phys_start,
  194. law_size_bits(mem->size),
  195. pcie->law_trgt_if);
  196. if (io)
  197. set_next_law(io->phys_start,
  198. law_size_bits(io->size),
  199. pcie->law_trgt_if);
  200. return 0;
  201. }
  202. static void fsl_pcie_config_ready(struct fsl_pcie *pcie)
  203. {
  204. ccsr_fsl_pci_t *regs = pcie->regs;
  205. if (pcie->block_rev >= PEX_IP_BLK_REV_3_0) {
  206. setbits_be32(&regs->config, FSL_PCIE_V3_CFG_RDY);
  207. return;
  208. }
  209. fsl_pcie_hose_write_config_byte(pcie, FSL_PCIE_CFG_RDY, 0x1);
  210. }
  211. static int fsl_pcie_setup_outbound_win(struct fsl_pcie *pcie, int idx,
  212. int type, u64 phys, u64 bus_addr,
  213. pci_size_t size)
  214. {
  215. ccsr_fsl_pci_t *regs = pcie->regs;
  216. pot_t *po = &regs->pot[idx];
  217. u32 war, sz;
  218. if (idx < 0)
  219. return -EINVAL;
  220. out_be32(&po->powbar, phys >> 12);
  221. out_be32(&po->potar, bus_addr >> 12);
  222. #ifdef CONFIG_SYS_PCI_64BIT
  223. out_be32(&po->potear, bus_addr >> 44);
  224. #else
  225. out_be32(&po->potear, 0);
  226. #endif
  227. sz = (__ilog2_u64((u64)size) - 1);
  228. war = POWAR_EN | sz;
  229. if (type == PCI_REGION_IO)
  230. war |= POWAR_IO_READ | POWAR_IO_WRITE;
  231. else
  232. war |= POWAR_MEM_READ | POWAR_MEM_WRITE;
  233. out_be32(&po->powar, war);
  234. return 0;
  235. }
  236. static int fsl_pcie_setup_inbound_win(struct fsl_pcie *pcie, int idx,
  237. bool pf, u64 phys, u64 bus_addr,
  238. pci_size_t size)
  239. {
  240. ccsr_fsl_pci_t *regs = pcie->regs;
  241. pit_t *pi = &regs->pit[idx];
  242. u32 sz = (__ilog2_u64(size) - 1);
  243. u32 flag = PIWAR_LOCAL;
  244. if (idx < 0)
  245. return -EINVAL;
  246. out_be32(&pi->pitar, phys >> 12);
  247. out_be32(&pi->piwbar, bus_addr >> 12);
  248. #ifdef CONFIG_SYS_PCI_64BIT
  249. out_be32(&pi->piwbear, bus_addr >> 44);
  250. #else
  251. out_be32(&pi->piwbear, 0);
  252. #endif
  253. #ifdef CONFIG_SYS_FSL_ERRATUM_A005434
  254. flag = 0;
  255. #endif
  256. flag |= PIWAR_EN | PIWAR_READ_SNOOP | PIWAR_WRITE_SNOOP;
  257. if (pf)
  258. flag |= PIWAR_PF;
  259. out_be32(&pi->piwar, flag | sz);
  260. return 0;
  261. }
  262. static int fsl_pcie_setup_outbound_wins(struct fsl_pcie *pcie)
  263. {
  264. struct pci_region *io, *mem, *pref;
  265. int idx = 1; /* skip 0 */
  266. pci_get_regions(pcie->bus, &io, &mem, &pref);
  267. if (io)
  268. /* ATU : OUTBOUND : IO */
  269. fsl_pcie_setup_outbound_win(pcie, idx++,
  270. PCI_REGION_IO,
  271. io->phys_start,
  272. io->bus_start,
  273. io->size);
  274. if (mem)
  275. /* ATU : OUTBOUND : MEM */
  276. fsl_pcie_setup_outbound_win(pcie, idx++,
  277. PCI_REGION_MEM,
  278. mem->phys_start,
  279. mem->bus_start,
  280. mem->size);
  281. return 0;
  282. }
  283. static int fsl_pcie_setup_inbound_wins(struct fsl_pcie *pcie)
  284. {
  285. phys_addr_t phys_start = CFG_SYS_PCI_MEMORY_PHYS;
  286. pci_addr_t bus_start = CFG_SYS_PCI_MEMORY_BUS;
  287. u64 sz = min((u64)gd->ram_size, (1ull << 32));
  288. pci_size_t pci_sz;
  289. int idx;
  290. if (pcie->block_rev >= PEX_IP_BLK_REV_2_2)
  291. idx = 2;
  292. else
  293. idx = 3;
  294. pci_sz = 1ull << __ilog2_u64(sz);
  295. dev_dbg(pcie->bus, "R0 bus_start: %llx phys_start: %llx size: %llx\n",
  296. (u64)bus_start, (u64)phys_start, (u64)sz);
  297. /* if we aren't an exact power of two match, pci_sz is smaller
  298. * round it up to the next power of two. We report the actual
  299. * size to pci region tracking.
  300. */
  301. if (pci_sz != sz)
  302. sz = 2ull << __ilog2_u64(sz);
  303. fsl_pcie_setup_inbound_win(pcie, idx--, true,
  304. CFG_SYS_PCI_MEMORY_PHYS,
  305. CFG_SYS_PCI_MEMORY_BUS, sz);
  306. #if defined(CONFIG_PHYS_64BIT) && defined(CONFIG_SYS_PCI_64BIT)
  307. /*
  308. * On 64-bit capable systems, set up a mapping for all of DRAM
  309. * in high pci address space.
  310. */
  311. pci_sz = 1ull << __ilog2_u64(gd->ram_size);
  312. /* round up to the next largest power of two */
  313. if (gd->ram_size > pci_sz)
  314. pci_sz = 1ull << (__ilog2_u64(gd->ram_size) + 1);
  315. dev_dbg(pcie->bus, "R64 bus_start: %llx phys_start: %llx size: %llx\n",
  316. (u64)CFG_SYS_PCI64_MEMORY_BUS,
  317. (u64)CFG_SYS_PCI_MEMORY_PHYS, (u64)pci_sz);
  318. fsl_pcie_setup_inbound_win(pcie, idx--, true,
  319. CFG_SYS_PCI_MEMORY_PHYS,
  320. CFG_SYS_PCI64_MEMORY_BUS, pci_sz);
  321. #endif
  322. return 0;
  323. }
  324. static int fsl_pcie_init_atmu(struct fsl_pcie *pcie)
  325. {
  326. fsl_pcie_setup_outbound_wins(pcie);
  327. fsl_pcie_setup_inbound_wins(pcie);
  328. return 0;
  329. }
  330. static void fsl_pcie_dbi_read_only_reg_write_enable(struct fsl_pcie *pcie,
  331. bool enable)
  332. {
  333. u32 val;
  334. fsl_pcie_hose_read_config_dword(pcie, DBI_RO_WR_EN, &val);
  335. if (enable)
  336. val |= 1;
  337. else
  338. val &= ~1;
  339. fsl_pcie_hose_write_config_dword(pcie, DBI_RO_WR_EN, val);
  340. }
  341. static int fsl_pcie_init_port(struct fsl_pcie *pcie)
  342. {
  343. ccsr_fsl_pci_t *regs = pcie->regs;
  344. u32 val_32;
  345. u16 val_16;
  346. fsl_pcie_init_atmu(pcie);
  347. #ifdef CONFIG_FSL_PCIE_DISABLE_ASPM
  348. val_32 = 0;
  349. fsl_pcie_hose_read_config_dword(pcie, PCI_LCR, &val_32);
  350. val_32 &= ~0x03;
  351. fsl_pcie_hose_write_config_dword(pcie, PCI_LCR, val_32);
  352. udelay(1);
  353. #endif
  354. #ifdef CONFIG_FSL_PCIE_RESET
  355. u16 ltssm;
  356. int i;
  357. if (pcie->block_rev >= PEX_IP_BLK_REV_3_0) {
  358. /* assert PCIe reset */
  359. setbits_be32(&regs->pdb_stat, 0x08000000);
  360. (void)in_be32(&regs->pdb_stat);
  361. udelay(1000);
  362. /* clear PCIe reset */
  363. clrbits_be32(&regs->pdb_stat, 0x08000000);
  364. asm("sync;isync");
  365. for (i = 0; i < 100 && !fsl_pcie_link_up(pcie); i++)
  366. udelay(1000);
  367. } else {
  368. fsl_pcie_hose_read_config_word(pcie, PCI_LTSSM, &ltssm);
  369. if (ltssm == 1) {
  370. /* assert PCIe reset */
  371. setbits_be32(&regs->pdb_stat, 0x08000000);
  372. (void)in_be32(&regs->pdb_stat);
  373. udelay(100);
  374. /* clear PCIe reset */
  375. clrbits_be32(&regs->pdb_stat, 0x08000000);
  376. asm("sync;isync");
  377. for (i = 0; i < 100 &&
  378. !fsl_pcie_link_up(pcie); i++)
  379. udelay(1000);
  380. }
  381. }
  382. #endif
  383. #ifdef CONFIG_SYS_P4080_ERRATUM_PCIE_A003
  384. if (!fsl_pcie_link_up(pcie)) {
  385. serdes_corenet_t *srds_regs;
  386. srds_regs = (void *)CFG_SYS_FSL_CORENET_SERDES_ADDR;
  387. val_32 = in_be32(&srds_regs->srdspccr0);
  388. if ((val_32 >> 28) == 3) {
  389. int i;
  390. out_be32(&srds_regs->srdspccr0, 2 << 28);
  391. setbits_be32(&regs->pdb_stat, 0x08000000);
  392. in_be32(&regs->pdb_stat);
  393. udelay(100);
  394. clrbits_be32(&regs->pdb_stat, 0x08000000);
  395. asm("sync;isync");
  396. for (i = 0; i < 100 && !fsl_pcie_link_up(pcie); i++)
  397. udelay(1000);
  398. }
  399. }
  400. #endif
  401. /*
  402. * The Read-Only Write Enable bit defaults to 1 instead of 0.
  403. * Set to 0 to protect the read-only registers.
  404. */
  405. #ifdef CONFIG_SYS_FSL_ERRATUM_A007815
  406. fsl_pcie_dbi_read_only_reg_write_enable(pcie, false);
  407. #endif
  408. /*
  409. * Enable All Error Interrupts except
  410. * - Master abort (pci)
  411. * - Master PERR (pci)
  412. * - ICCA (PCIe)
  413. */
  414. out_be32(&regs->peer, ~0x20140);
  415. /* set URR, FER, NFER (but not CER) */
  416. fsl_pcie_hose_read_config_dword(pcie, PCI_DCR, &val_32);
  417. val_32 |= 0xf000e;
  418. fsl_pcie_hose_write_config_dword(pcie, PCI_DCR, val_32);
  419. /* Clear all error indications */
  420. out_be32(&regs->pme_msg_det, 0xffffffff);
  421. out_be32(&regs->pme_msg_int_en, 0xffffffff);
  422. out_be32(&regs->pedr, 0xffffffff);
  423. fsl_pcie_hose_read_config_word(pcie, PCI_DSR, &val_16);
  424. if (val_16)
  425. fsl_pcie_hose_write_config_word(pcie, PCI_DSR, 0xffff);
  426. fsl_pcie_hose_read_config_word(pcie, PCI_SEC_STATUS, &val_16);
  427. if (val_16)
  428. fsl_pcie_hose_write_config_word(pcie, PCI_SEC_STATUS, 0xffff);
  429. return 0;
  430. }
  431. static int fsl_pcie_fixup_classcode(struct fsl_pcie *pcie)
  432. {
  433. u32 classcode_reg;
  434. u32 val;
  435. if (pcie->block_rev >= PEX_IP_BLK_REV_3_0) {
  436. classcode_reg = PCI_CLASS_REVISION;
  437. fsl_pcie_dbi_read_only_reg_write_enable(pcie, true);
  438. } else {
  439. classcode_reg = CSR_CLASSCODE;
  440. }
  441. fsl_pcie_hose_read_config_dword(pcie, classcode_reg, &val);
  442. val &= 0xff;
  443. val |= PCI_CLASS_BRIDGE_PCI_NORMAL << 8;
  444. fsl_pcie_hose_write_config_dword(pcie, classcode_reg, val);
  445. if (pcie->block_rev >= PEX_IP_BLK_REV_3_0)
  446. fsl_pcie_dbi_read_only_reg_write_enable(pcie, false);
  447. return 0;
  448. }
  449. static int fsl_pcie_init_rc(struct fsl_pcie *pcie)
  450. {
  451. return fsl_pcie_fixup_classcode(pcie);
  452. }
  453. static int fsl_pcie_init_ep(struct fsl_pcie *pcie)
  454. {
  455. fsl_pcie_config_ready(pcie);
  456. return 0;
  457. }
  458. static int fsl_pcie_probe(struct udevice *dev)
  459. {
  460. struct fsl_pcie *pcie = dev_get_priv(dev);
  461. ccsr_fsl_pci_t *regs = pcie->regs;
  462. u16 val_16;
  463. pcie->bus = dev;
  464. pcie->block_rev = in_be32(&regs->block_rev1);
  465. list_add(&pcie->list, &fsl_pcie_list);
  466. pcie->enabled = is_serdes_configured(PCIE1 + pcie->idx);
  467. if (!pcie->enabled) {
  468. printf("PCIe%d: %s disabled\n", pcie->idx, dev->name);
  469. return 0;
  470. }
  471. fsl_pcie_setup_law(pcie);
  472. pcie->mode = fsl_pcie_is_agent(pcie);
  473. fsl_pcie_init_port(pcie);
  474. printf("PCIe%d: %s ", pcie->idx, dev->name);
  475. if (pcie->mode) {
  476. printf("Endpoint");
  477. fsl_pcie_init_ep(pcie);
  478. } else {
  479. printf("Root Complex");
  480. fsl_pcie_init_rc(pcie);
  481. }
  482. if (!fsl_pcie_link_up(pcie)) {
  483. printf(": %s\n", pcie->mode ? "undetermined link" : "no link");
  484. return 0;
  485. }
  486. fsl_pcie_hose_read_config_word(pcie, PCI_LSR, &val_16);
  487. printf(": x%d gen%d\n", (val_16 & 0x3f0) >> 4, (val_16 & 0xf));
  488. return 0;
  489. }
  490. static int fsl_pcie_of_to_plat(struct udevice *dev)
  491. {
  492. struct fsl_pcie *pcie = dev_get_priv(dev);
  493. struct fsl_pcie_data *info;
  494. int ret;
  495. pcie->regs = dev_remap_addr(dev);
  496. if (!pcie->regs) {
  497. pr_err("\"reg\" resource not found\n");
  498. return -EINVAL;
  499. }
  500. ret = dev_read_u32(dev, "law_trgt_if", &pcie->law_trgt_if);
  501. if (ret < 0) {
  502. pr_err("\"law_trgt_if\" not found\n");
  503. return ret;
  504. }
  505. info = (struct fsl_pcie_data *)dev_get_driver_data(dev);
  506. pcie->info = info;
  507. pcie->idx = abs((u32)(dev_read_addr(dev) & info->block_offset_mask) -
  508. info->block_offset) / info->stride;
  509. return 0;
  510. }
  511. static const struct dm_pci_ops fsl_pcie_ops = {
  512. .read_config = fsl_pcie_read_config,
  513. .write_config = fsl_pcie_write_config,
  514. };
  515. static struct fsl_pcie_data p1_p2_data = {
  516. .block_offset = 0xa000,
  517. .block_offset_mask = 0xffff,
  518. .stride = 0x1000,
  519. };
  520. static struct fsl_pcie_data p2041_data = {
  521. .block_offset = 0x200000,
  522. .block_offset_mask = 0x3fffff,
  523. .stride = 0x1000,
  524. };
  525. static struct fsl_pcie_data t2080_data = {
  526. .block_offset = 0x240000,
  527. .block_offset_mask = 0x3fffff,
  528. .stride = 0x10000,
  529. };
  530. static const struct udevice_id fsl_pcie_ids[] = {
  531. { .compatible = "fsl,mpc8548-pcie", .data = (ulong)&p1_p2_data },
  532. { .compatible = "fsl,pcie-p1_p2", .data = (ulong)&p1_p2_data },
  533. { .compatible = "fsl,pcie-p2041", .data = (ulong)&p2041_data },
  534. { .compatible = "fsl,pcie-p3041", .data = (ulong)&p2041_data },
  535. { .compatible = "fsl,pcie-p4080", .data = (ulong)&p2041_data },
  536. { .compatible = "fsl,pcie-p5040", .data = (ulong)&p2041_data },
  537. { .compatible = "fsl,pcie-t102x", .data = (ulong)&t2080_data },
  538. { .compatible = "fsl,pcie-t104x", .data = (ulong)&t2080_data },
  539. { .compatible = "fsl,pcie-t2080", .data = (ulong)&t2080_data },
  540. { .compatible = "fsl,pcie-t4240", .data = (ulong)&t2080_data },
  541. { }
  542. };
  543. U_BOOT_DRIVER(fsl_pcie) = {
  544. .name = "fsl_pcie",
  545. .id = UCLASS_PCI,
  546. .of_match = fsl_pcie_ids,
  547. .ops = &fsl_pcie_ops,
  548. .of_to_plat = fsl_pcie_of_to_plat,
  549. .probe = fsl_pcie_probe,
  550. .priv_auto = sizeof(struct fsl_pcie),
  551. };