pcie-starfive.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * PCIe host controller driver for StarFive JH7110 Soc.
  4. *
  5. * Copyright (C) 2023 StarFive Technology Co., Ltd.
  6. */
  7. #include <linux/bitfield.h>
  8. #include <linux/clk.h>
  9. #include <linux/delay.h>
  10. #include <linux/gpio/consumer.h>
  11. #include <linux/interrupt.h>
  12. #include <linux/kernel.h>
  13. #include <linux/mfd/syscon.h>
  14. #include <linux/module.h>
  15. #include <linux/of_address.h>
  16. #include <linux/of_irq.h>
  17. #include <linux/of_pci.h>
  18. #include <linux/pci.h>
  19. #include <linux/phy/phy.h>
  20. #include <linux/platform_device.h>
  21. #include <linux/pm_runtime.h>
  22. #include <linux/regmap.h>
  23. #include <linux/reset.h>
  24. #include "../../pci.h"
  25. #include "pcie-plda.h"
  26. #define PCIE_FUNC_NUM 4
  27. /* system control */
  28. #define STG_SYSCON_PCIE0_BASE 0x48
  29. #define STG_SYSCON_PCIE1_BASE 0x1f8
  30. #define STG_SYSCON_AR_OFFSET 0x78
  31. #define STG_SYSCON_AXI4_SLVL_AR_MASK GENMASK(22, 8)
  32. #define STG_SYSCON_AXI4_SLVL_PHY_AR(x) FIELD_PREP(GENMASK(20, 17), x)
  33. #define STG_SYSCON_AW_OFFSET 0x7c
  34. #define STG_SYSCON_AXI4_SLVL_AW_MASK GENMASK(14, 0)
  35. #define STG_SYSCON_AXI4_SLVL_PHY_AW(x) FIELD_PREP(GENMASK(12, 9), x)
  36. #define STG_SYSCON_CLKREQ BIT(22)
  37. #define STG_SYSCON_CKREF_SRC_MASK GENMASK(19, 18)
  38. #define STG_SYSCON_RP_NEP_OFFSET 0xe8
  39. #define STG_SYSCON_K_RP_NEP BIT(8)
  40. #define STG_SYSCON_LNKSTA_OFFSET 0x170
  41. #define DATA_LINK_ACTIVE BIT(5)
  42. /* Parameters for the waiting for link up routine */
  43. #define LINK_WAIT_MAX_RETRIES 10
  44. #define LINK_WAIT_USLEEP_MIN 90000
  45. #define LINK_WAIT_USLEEP_MAX 100000
  46. struct starfive_jh7110_pcie {
  47. struct plda_pcie_rp plda;
  48. struct reset_control *resets;
  49. struct clk_bulk_data *clks;
  50. struct regmap *reg_syscon;
  51. struct gpio_desc *power_gpio;
  52. struct gpio_desc *reset_gpio;
  53. struct phy *phy;
  54. unsigned int stg_pcie_base;
  55. int num_clks;
  56. };
  57. /*
  58. * JH7110 PCIe port BAR0/1 can be configured as 64-bit prefetchable memory
  59. * space. PCIe read and write requests targeting BAR0/1 are routed to so called
  60. * 'Bridge Configuration space' in PLDA IP datasheet, which contains the bridge
  61. * internal registers, such as interrupt, DMA and ATU registers...
  62. * JH7110 can access the Bridge Configuration space by local bus, and don`t
  63. * want the bridge internal registers accessed by the DMA from EP devices.
  64. * Thus, they are unimplemented and should be hidden here.
  65. */
  66. static bool starfive_pcie_hide_rc_bar(struct pci_bus *bus, unsigned int devfn,
  67. int offset)
  68. {
  69. if (pci_is_root_bus(bus) && !devfn &&
  70. (offset == PCI_BASE_ADDRESS_0 || offset == PCI_BASE_ADDRESS_1))
  71. return true;
  72. return false;
  73. }
  74. static int starfive_pcie_config_write(struct pci_bus *bus, unsigned int devfn,
  75. int where, int size, u32 value)
  76. {
  77. if (starfive_pcie_hide_rc_bar(bus, devfn, where))
  78. return PCIBIOS_SUCCESSFUL;
  79. return pci_generic_config_write(bus, devfn, where, size, value);
  80. }
  81. static int starfive_pcie_config_read(struct pci_bus *bus, unsigned int devfn,
  82. int where, int size, u32 *value)
  83. {
  84. if (starfive_pcie_hide_rc_bar(bus, devfn, where)) {
  85. *value = 0;
  86. return PCIBIOS_SUCCESSFUL;
  87. }
  88. return pci_generic_config_read(bus, devfn, where, size, value);
  89. }
  90. static int starfive_pcie_parse_dt(struct starfive_jh7110_pcie *pcie,
  91. struct device *dev)
  92. {
  93. int domain_nr;
  94. pcie->num_clks = devm_clk_bulk_get_all(dev, &pcie->clks);
  95. if (pcie->num_clks < 0)
  96. return dev_err_probe(dev, pcie->num_clks,
  97. "failed to get pcie clocks\n");
  98. pcie->resets = devm_reset_control_array_get_exclusive(dev);
  99. if (IS_ERR(pcie->resets))
  100. return dev_err_probe(dev, PTR_ERR(pcie->resets),
  101. "failed to get pcie resets");
  102. pcie->reg_syscon =
  103. syscon_regmap_lookup_by_phandle(dev->of_node,
  104. "starfive,stg-syscon");
  105. if (IS_ERR(pcie->reg_syscon))
  106. return dev_err_probe(dev, PTR_ERR(pcie->reg_syscon),
  107. "failed to parse starfive,stg-syscon\n");
  108. pcie->phy = devm_phy_optional_get(dev, NULL);
  109. if (IS_ERR(pcie->phy))
  110. return dev_err_probe(dev, PTR_ERR(pcie->phy),
  111. "failed to get pcie phy\n");
  112. /*
  113. * The PCIe domain numbers are set to be static in JH7110 DTS.
  114. * As the STG system controller defines different bases in PCIe RP0 &
  115. * RP1, we use them to identify which controller is doing the hardware
  116. * initialization.
  117. */
  118. domain_nr = of_get_pci_domain_nr(dev->of_node);
  119. if (domain_nr < 0 || domain_nr > 1)
  120. return dev_err_probe(dev, -ENODEV,
  121. "failed to get valid pcie domain\n");
  122. if (domain_nr == 0)
  123. pcie->stg_pcie_base = STG_SYSCON_PCIE0_BASE;
  124. else
  125. pcie->stg_pcie_base = STG_SYSCON_PCIE1_BASE;
  126. pcie->reset_gpio = devm_gpiod_get_optional(dev, "perst",
  127. GPIOD_OUT_HIGH);
  128. if (IS_ERR(pcie->reset_gpio))
  129. return dev_err_probe(dev, PTR_ERR(pcie->reset_gpio),
  130. "failed to get perst-gpio\n");
  131. pcie->power_gpio = devm_gpiod_get_optional(dev, "enable",
  132. GPIOD_OUT_LOW);
  133. if (IS_ERR(pcie->power_gpio))
  134. return dev_err_probe(dev, PTR_ERR(pcie->power_gpio),
  135. "failed to get power-gpio\n");
  136. return 0;
  137. }
  138. static struct pci_ops starfive_pcie_ops = {
  139. .map_bus = plda_pcie_map_bus,
  140. .read = starfive_pcie_config_read,
  141. .write = starfive_pcie_config_write,
  142. };
  143. static int starfive_pcie_clk_rst_init(struct starfive_jh7110_pcie *pcie)
  144. {
  145. struct device *dev = pcie->plda.dev;
  146. int ret;
  147. ret = clk_bulk_prepare_enable(pcie->num_clks, pcie->clks);
  148. if (ret)
  149. return dev_err_probe(dev, ret, "failed to enable clocks\n");
  150. ret = reset_control_deassert(pcie->resets);
  151. if (ret) {
  152. clk_bulk_disable_unprepare(pcie->num_clks, pcie->clks);
  153. dev_err_probe(dev, ret, "failed to deassert resets\n");
  154. }
  155. return ret;
  156. }
  157. static void starfive_pcie_clk_rst_deinit(struct starfive_jh7110_pcie *pcie)
  158. {
  159. reset_control_assert(pcie->resets);
  160. clk_bulk_disable_unprepare(pcie->num_clks, pcie->clks);
  161. }
  162. static bool starfive_pcie_link_up(struct plda_pcie_rp *plda)
  163. {
  164. struct starfive_jh7110_pcie *pcie =
  165. container_of(plda, struct starfive_jh7110_pcie, plda);
  166. int ret;
  167. u32 stg_reg_val;
  168. ret = regmap_read(pcie->reg_syscon,
  169. pcie->stg_pcie_base + STG_SYSCON_LNKSTA_OFFSET,
  170. &stg_reg_val);
  171. if (ret) {
  172. dev_err(pcie->plda.dev, "failed to read link status\n");
  173. return false;
  174. }
  175. return !!(stg_reg_val & DATA_LINK_ACTIVE);
  176. }
  177. static int starfive_pcie_host_wait_for_link(struct starfive_jh7110_pcie *pcie)
  178. {
  179. int retries;
  180. /* Check if the link is up or not */
  181. for (retries = 0; retries < LINK_WAIT_MAX_RETRIES; retries++) {
  182. if (starfive_pcie_link_up(&pcie->plda)) {
  183. dev_info(pcie->plda.dev, "port link up\n");
  184. return 0;
  185. }
  186. usleep_range(LINK_WAIT_USLEEP_MIN, LINK_WAIT_USLEEP_MAX);
  187. }
  188. return -ETIMEDOUT;
  189. }
  190. static int starfive_pcie_enable_phy(struct device *dev,
  191. struct starfive_jh7110_pcie *pcie)
  192. {
  193. int ret;
  194. if (!pcie->phy)
  195. return 0;
  196. ret = phy_init(pcie->phy);
  197. if (ret)
  198. return dev_err_probe(dev, ret,
  199. "failed to initialize pcie phy\n");
  200. ret = phy_set_mode(pcie->phy, PHY_MODE_PCIE);
  201. if (ret) {
  202. dev_err_probe(dev, ret, "failed to set pcie mode\n");
  203. goto err_phy_on;
  204. }
  205. ret = phy_power_on(pcie->phy);
  206. if (ret) {
  207. dev_err_probe(dev, ret, "failed to power on pcie phy\n");
  208. goto err_phy_on;
  209. }
  210. return 0;
  211. err_phy_on:
  212. phy_exit(pcie->phy);
  213. return ret;
  214. }
  215. static void starfive_pcie_disable_phy(struct starfive_jh7110_pcie *pcie)
  216. {
  217. phy_power_off(pcie->phy);
  218. phy_exit(pcie->phy);
  219. }
  220. static void starfive_pcie_host_deinit(struct plda_pcie_rp *plda)
  221. {
  222. struct starfive_jh7110_pcie *pcie =
  223. container_of(plda, struct starfive_jh7110_pcie, plda);
  224. starfive_pcie_clk_rst_deinit(pcie);
  225. if (pcie->power_gpio)
  226. gpiod_set_value_cansleep(pcie->power_gpio, 0);
  227. starfive_pcie_disable_phy(pcie);
  228. }
  229. static int starfive_pcie_host_init(struct plda_pcie_rp *plda)
  230. {
  231. struct starfive_jh7110_pcie *pcie =
  232. container_of(plda, struct starfive_jh7110_pcie, plda);
  233. struct device *dev = plda->dev;
  234. int ret;
  235. int i;
  236. ret = starfive_pcie_enable_phy(dev, pcie);
  237. if (ret)
  238. return ret;
  239. regmap_update_bits(pcie->reg_syscon,
  240. pcie->stg_pcie_base + STG_SYSCON_RP_NEP_OFFSET,
  241. STG_SYSCON_K_RP_NEP, STG_SYSCON_K_RP_NEP);
  242. regmap_update_bits(pcie->reg_syscon,
  243. pcie->stg_pcie_base + STG_SYSCON_AW_OFFSET,
  244. STG_SYSCON_CKREF_SRC_MASK,
  245. FIELD_PREP(STG_SYSCON_CKREF_SRC_MASK, 2));
  246. regmap_update_bits(pcie->reg_syscon,
  247. pcie->stg_pcie_base + STG_SYSCON_AW_OFFSET,
  248. STG_SYSCON_CLKREQ, STG_SYSCON_CLKREQ);
  249. ret = starfive_pcie_clk_rst_init(pcie);
  250. if (ret)
  251. return ret;
  252. if (pcie->power_gpio)
  253. gpiod_set_value_cansleep(pcie->power_gpio, 1);
  254. if (pcie->reset_gpio)
  255. gpiod_set_value_cansleep(pcie->reset_gpio, 1);
  256. /* Disable physical functions except #0 */
  257. for (i = 1; i < PCIE_FUNC_NUM; i++) {
  258. regmap_update_bits(pcie->reg_syscon,
  259. pcie->stg_pcie_base + STG_SYSCON_AR_OFFSET,
  260. STG_SYSCON_AXI4_SLVL_AR_MASK,
  261. STG_SYSCON_AXI4_SLVL_PHY_AR(i));
  262. regmap_update_bits(pcie->reg_syscon,
  263. pcie->stg_pcie_base + STG_SYSCON_AW_OFFSET,
  264. STG_SYSCON_AXI4_SLVL_AW_MASK,
  265. STG_SYSCON_AXI4_SLVL_PHY_AW(i));
  266. plda_pcie_disable_func(plda);
  267. }
  268. regmap_update_bits(pcie->reg_syscon,
  269. pcie->stg_pcie_base + STG_SYSCON_AR_OFFSET,
  270. STG_SYSCON_AXI4_SLVL_AR_MASK, 0);
  271. regmap_update_bits(pcie->reg_syscon,
  272. pcie->stg_pcie_base + STG_SYSCON_AW_OFFSET,
  273. STG_SYSCON_AXI4_SLVL_AW_MASK, 0);
  274. plda_pcie_enable_root_port(plda);
  275. plda_pcie_write_rc_bar(plda, 0);
  276. /* PCIe PCI Standard Configuration Identification Settings. */
  277. plda_pcie_set_standard_class(plda);
  278. /*
  279. * The LTR message receiving is enabled by the register "PCIe Message
  280. * Reception" as default, but the forward id & addr are uninitialized.
  281. * If we do not disable LTR message forwarding here, or set a legal
  282. * forwarding address, the kernel will get stuck.
  283. * To workaround, disable the LTR message forwarding here before using
  284. * this feature.
  285. */
  286. plda_pcie_disable_ltr(plda);
  287. /*
  288. * Enable the prefetchable memory window 64-bit addressing in JH7110.
  289. * The 64-bits prefetchable address translation configurations in ATU
  290. * can be work after enable the register setting below.
  291. */
  292. plda_pcie_set_pref_win_64bit(plda);
  293. /*
  294. * Ensure that PERST has been asserted for at least 100 ms,
  295. * the sleep value is T_PVPERL from PCIe CEM spec r2.0 (Table 2-4)
  296. */
  297. msleep(100);
  298. if (pcie->reset_gpio)
  299. gpiod_set_value_cansleep(pcie->reset_gpio, 0);
  300. /*
  301. * With a Downstream Port (<=5GT/s), software must wait a minimum
  302. * of 100ms following exit from a conventional reset before
  303. * sending a configuration request to the device.
  304. */
  305. msleep(PCIE_RESET_CONFIG_WAIT_MS);
  306. if (starfive_pcie_host_wait_for_link(pcie))
  307. dev_info(dev, "port link down\n");
  308. return 0;
  309. }
  310. static const struct plda_pcie_host_ops sf_host_ops = {
  311. .host_init = starfive_pcie_host_init,
  312. .host_deinit = starfive_pcie_host_deinit,
  313. };
  314. static const struct plda_event stf_pcie_event = {
  315. .intx_event = EVENT_PM_MSI_INT_INTX,
  316. .msi_event = EVENT_PM_MSI_INT_MSI
  317. };
  318. static int starfive_pcie_probe(struct platform_device *pdev)
  319. {
  320. struct starfive_jh7110_pcie *pcie;
  321. struct device *dev = &pdev->dev;
  322. struct plda_pcie_rp *plda;
  323. int ret;
  324. pcie = devm_kzalloc(dev, sizeof(*pcie), GFP_KERNEL);
  325. if (!pcie)
  326. return -ENOMEM;
  327. plda = &pcie->plda;
  328. plda->dev = dev;
  329. ret = starfive_pcie_parse_dt(pcie, dev);
  330. if (ret)
  331. return ret;
  332. pm_runtime_enable(&pdev->dev);
  333. pm_runtime_get_sync(&pdev->dev);
  334. plda->host_ops = &sf_host_ops;
  335. plda->num_events = PLDA_MAX_EVENT_NUM;
  336. /* mask doorbell event */
  337. plda->events_bitmap = GENMASK(PLDA_INT_EVENT_NUM - 1, 0)
  338. & ~BIT(PLDA_AXI_DOORBELL)
  339. & ~BIT(PLDA_PCIE_DOORBELL);
  340. plda->events_bitmap <<= PLDA_NUM_DMA_EVENTS;
  341. ret = plda_pcie_host_init(&pcie->plda, &starfive_pcie_ops,
  342. &stf_pcie_event);
  343. if (ret) {
  344. pm_runtime_put_sync(&pdev->dev);
  345. pm_runtime_disable(&pdev->dev);
  346. return ret;
  347. }
  348. platform_set_drvdata(pdev, pcie);
  349. return 0;
  350. }
  351. static void starfive_pcie_remove(struct platform_device *pdev)
  352. {
  353. struct starfive_jh7110_pcie *pcie = platform_get_drvdata(pdev);
  354. pm_runtime_put(&pdev->dev);
  355. pm_runtime_disable(&pdev->dev);
  356. plda_pcie_host_deinit(&pcie->plda);
  357. platform_set_drvdata(pdev, NULL);
  358. }
  359. static int starfive_pcie_suspend_noirq(struct device *dev)
  360. {
  361. struct starfive_jh7110_pcie *pcie = dev_get_drvdata(dev);
  362. clk_bulk_disable_unprepare(pcie->num_clks, pcie->clks);
  363. starfive_pcie_disable_phy(pcie);
  364. return 0;
  365. }
  366. static int starfive_pcie_resume_noirq(struct device *dev)
  367. {
  368. struct starfive_jh7110_pcie *pcie = dev_get_drvdata(dev);
  369. int ret;
  370. ret = starfive_pcie_enable_phy(dev, pcie);
  371. if (ret)
  372. return ret;
  373. ret = clk_bulk_prepare_enable(pcie->num_clks, pcie->clks);
  374. if (ret) {
  375. dev_err(dev, "failed to enable clocks\n");
  376. starfive_pcie_disable_phy(pcie);
  377. return ret;
  378. }
  379. return 0;
  380. }
  381. static const struct dev_pm_ops starfive_pcie_pm_ops = {
  382. NOIRQ_SYSTEM_SLEEP_PM_OPS(starfive_pcie_suspend_noirq,
  383. starfive_pcie_resume_noirq)
  384. };
  385. static const struct of_device_id starfive_pcie_of_match[] = {
  386. { .compatible = "starfive,jh7110-pcie", },
  387. { /* sentinel */ }
  388. };
  389. MODULE_DEVICE_TABLE(of, starfive_pcie_of_match);
  390. static struct platform_driver starfive_pcie_driver = {
  391. .driver = {
  392. .name = "pcie-starfive",
  393. .of_match_table = of_match_ptr(starfive_pcie_of_match),
  394. .pm = pm_sleep_ptr(&starfive_pcie_pm_ops),
  395. },
  396. .probe = starfive_pcie_probe,
  397. .remove_new = starfive_pcie_remove,
  398. };
  399. module_platform_driver(starfive_pcie_driver);
  400. MODULE_DESCRIPTION("StarFive JH7110 PCIe host driver");
  401. MODULE_LICENSE("GPL v2");