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