1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * STMicroelectronics STM32MP25 PCIe endpoint driver. 4 * 5 * Copyright (C) 2025 STMicroelectronics 6 * Author: Christian Bruel <christian.bruel@foss.st.com> 7 */ 8 9 #include <linux/clk.h> 10 #include <linux/mfd/syscon.h> 11 #include <linux/of_platform.h> 12 #include <linux/of_gpio.h> 13 #include <linux/phy/phy.h> 14 #include <linux/platform_device.h> 15 #include <linux/pm_runtime.h> 16 #include <linux/regmap.h> 17 #include <linux/reset.h> 18 #include "pcie-designware.h" 19 #include "pcie-stm32.h" 20 21 struct stm32_pcie { 22 struct dw_pcie pci; 23 struct regmap *regmap; 24 struct reset_control *rst; 25 struct phy *phy; 26 struct clk *clk; 27 struct gpio_desc *perst_gpio; 28 unsigned int perst_irq; 29 }; 30 31 static void stm32_pcie_ep_init(struct dw_pcie_ep *ep) 32 { 33 struct dw_pcie *pci = to_dw_pcie_from_ep(ep); 34 enum pci_barno bar; 35 36 for (bar = 0; bar < PCI_STD_NUM_BARS; bar++) 37 dw_pcie_ep_reset_bar(pci, bar); 38 } 39 40 static int stm32_pcie_enable_link(struct dw_pcie *pci) 41 { 42 struct stm32_pcie *stm32_pcie = to_stm32_pcie(pci); 43 44 regmap_update_bits(stm32_pcie->regmap, SYSCFG_PCIECR, 45 STM32MP25_PCIECR_LTSSM_EN, 46 STM32MP25_PCIECR_LTSSM_EN); 47 48 return dw_pcie_wait_for_link(pci); 49 } 50 51 static void stm32_pcie_disable_link(struct dw_pcie *pci) 52 { 53 struct stm32_pcie *stm32_pcie = to_stm32_pcie(pci); 54 55 regmap_update_bits(stm32_pcie->regmap, SYSCFG_PCIECR, STM32MP25_PCIECR_LTSSM_EN, 0); 56 } 57 58 static int stm32_pcie_start_link(struct dw_pcie *pci) 59 { 60 struct stm32_pcie *stm32_pcie = to_stm32_pcie(pci); 61 int ret; 62 63 dev_dbg(pci->dev, "Enable link\n"); 64 65 ret = stm32_pcie_enable_link(pci); 66 if (ret) { 67 dev_err(pci->dev, "PCIe cannot establish link: %d\n", ret); 68 return ret; 69 } 70 71 enable_irq(stm32_pcie->perst_irq); 72 73 return 0; 74 } 75 76 static void stm32_pcie_stop_link(struct dw_pcie *pci) 77 { 78 struct stm32_pcie *stm32_pcie = to_stm32_pcie(pci); 79 80 dev_dbg(pci->dev, "Disable link\n"); 81 82 disable_irq(stm32_pcie->perst_irq); 83 84 stm32_pcie_disable_link(pci); 85 } 86 87 static int stm32_pcie_raise_irq(struct dw_pcie_ep *ep, u8 func_no, 88 unsigned int type, u16 interrupt_num) 89 { 90 struct dw_pcie *pci = to_dw_pcie_from_ep(ep); 91 92 switch (type) { 93 case PCI_IRQ_INTX: 94 return dw_pcie_ep_raise_intx_irq(ep, func_no); 95 case PCI_IRQ_MSI: 96 return dw_pcie_ep_raise_msi_irq(ep, func_no, interrupt_num); 97 default: 98 dev_err(pci->dev, "UNKNOWN IRQ type\n"); 99 return -EINVAL; 100 } 101 } 102 103 static const struct pci_epc_features stm32_pcie_epc_features = { 104 .msi_capable = true, 105 .align = SZ_64K, 106 }; 107 108 static const struct pci_epc_features* 109 stm32_pcie_get_features(struct dw_pcie_ep *ep) 110 { 111 return &stm32_pcie_epc_features; 112 } 113 114 static const struct dw_pcie_ep_ops stm32_pcie_ep_ops = { 115 .init = stm32_pcie_ep_init, 116 .raise_irq = stm32_pcie_raise_irq, 117 .get_features = stm32_pcie_get_features, 118 }; 119 120 static const struct dw_pcie_ops dw_pcie_ops = { 121 .start_link = stm32_pcie_start_link, 122 .stop_link = stm32_pcie_stop_link, 123 }; 124 125 static int stm32_pcie_enable_resources(struct stm32_pcie *stm32_pcie) 126 { 127 int ret; 128 129 ret = phy_init(stm32_pcie->phy); 130 if (ret) 131 return ret; 132 133 ret = clk_prepare_enable(stm32_pcie->clk); 134 if (ret) 135 phy_exit(stm32_pcie->phy); 136 137 return ret; 138 } 139 140 static void stm32_pcie_disable_resources(struct stm32_pcie *stm32_pcie) 141 { 142 clk_disable_unprepare(stm32_pcie->clk); 143 144 phy_exit(stm32_pcie->phy); 145 } 146 147 static void stm32_pcie_perst_assert(struct dw_pcie *pci) 148 { 149 struct stm32_pcie *stm32_pcie = to_stm32_pcie(pci); 150 struct dw_pcie_ep *ep = &stm32_pcie->pci.ep; 151 struct device *dev = pci->dev; 152 153 dev_dbg(dev, "PERST asserted by host\n"); 154 155 pci_epc_deinit_notify(ep->epc); 156 157 stm32_pcie_disable_resources(stm32_pcie); 158 159 pm_runtime_put_sync(dev); 160 } 161 162 static void stm32_pcie_perst_deassert(struct dw_pcie *pci) 163 { 164 struct stm32_pcie *stm32_pcie = to_stm32_pcie(pci); 165 struct device *dev = pci->dev; 166 struct dw_pcie_ep *ep = &pci->ep; 167 int ret; 168 169 dev_dbg(dev, "PERST de-asserted by host\n"); 170 171 ret = pm_runtime_resume_and_get(dev); 172 if (ret < 0) { 173 dev_err(dev, "Failed to resume runtime PM: %d\n", ret); 174 return; 175 } 176 177 ret = stm32_pcie_enable_resources(stm32_pcie); 178 if (ret) { 179 dev_err(dev, "Failed to enable resources: %d\n", ret); 180 goto err_pm_put_sync; 181 } 182 183 /* 184 * Reprogram the configuration space registers here because the DBI 185 * registers were reset by the PHY RCC during phy_init(). 186 */ 187 ret = dw_pcie_ep_init_registers(ep); 188 if (ret) { 189 dev_err(dev, "Failed to complete initialization: %d\n", ret); 190 goto err_disable_resources; 191 } 192 193 pci_epc_init_notify(ep->epc); 194 195 return; 196 197 err_disable_resources: 198 stm32_pcie_disable_resources(stm32_pcie); 199 200 err_pm_put_sync: 201 pm_runtime_put_sync(dev); 202 } 203 204 static irqreturn_t stm32_pcie_ep_perst_irq_thread(int irq, void *data) 205 { 206 struct stm32_pcie *stm32_pcie = data; 207 struct dw_pcie *pci = &stm32_pcie->pci; 208 u32 perst; 209 210 perst = gpiod_get_value(stm32_pcie->perst_gpio); 211 if (perst) 212 stm32_pcie_perst_assert(pci); 213 else 214 stm32_pcie_perst_deassert(pci); 215 216 irq_set_irq_type(gpiod_to_irq(stm32_pcie->perst_gpio), 217 (perst ? IRQF_TRIGGER_HIGH : IRQF_TRIGGER_LOW)); 218 219 return IRQ_HANDLED; 220 } 221 222 static int stm32_add_pcie_ep(struct stm32_pcie *stm32_pcie, 223 struct platform_device *pdev) 224 { 225 struct dw_pcie_ep *ep = &stm32_pcie->pci.ep; 226 struct device *dev = &pdev->dev; 227 int ret; 228 229 ret = regmap_update_bits(stm32_pcie->regmap, SYSCFG_PCIECR, 230 STM32MP25_PCIECR_TYPE_MASK, 231 STM32MP25_PCIECR_EP); 232 if (ret) 233 return ret; 234 235 reset_control_assert(stm32_pcie->rst); 236 reset_control_deassert(stm32_pcie->rst); 237 238 ep->ops = &stm32_pcie_ep_ops; 239 240 ret = dw_pcie_ep_init(ep); 241 if (ret) { 242 dev_err(dev, "Failed to initialize ep: %d\n", ret); 243 return ret; 244 } 245 246 ret = stm32_pcie_enable_resources(stm32_pcie); 247 if (ret) { 248 dev_err(dev, "Failed to enable resources: %d\n", ret); 249 dw_pcie_ep_deinit(ep); 250 return ret; 251 } 252 253 return 0; 254 } 255 256 static int stm32_pcie_probe(struct platform_device *pdev) 257 { 258 struct stm32_pcie *stm32_pcie; 259 struct device *dev = &pdev->dev; 260 int ret; 261 262 stm32_pcie = devm_kzalloc(dev, sizeof(*stm32_pcie), GFP_KERNEL); 263 if (!stm32_pcie) 264 return -ENOMEM; 265 266 stm32_pcie->pci.dev = dev; 267 stm32_pcie->pci.ops = &dw_pcie_ops; 268 269 stm32_pcie->regmap = syscon_regmap_lookup_by_compatible("st,stm32mp25-syscfg"); 270 if (IS_ERR(stm32_pcie->regmap)) 271 return dev_err_probe(dev, PTR_ERR(stm32_pcie->regmap), 272 "No syscfg specified\n"); 273 274 stm32_pcie->phy = devm_phy_get(dev, NULL); 275 if (IS_ERR(stm32_pcie->phy)) 276 return dev_err_probe(dev, PTR_ERR(stm32_pcie->phy), 277 "failed to get pcie-phy\n"); 278 279 stm32_pcie->clk = devm_clk_get(dev, NULL); 280 if (IS_ERR(stm32_pcie->clk)) 281 return dev_err_probe(dev, PTR_ERR(stm32_pcie->clk), 282 "Failed to get PCIe clock source\n"); 283 284 stm32_pcie->rst = devm_reset_control_get_exclusive(dev, NULL); 285 if (IS_ERR(stm32_pcie->rst)) 286 return dev_err_probe(dev, PTR_ERR(stm32_pcie->rst), 287 "Failed to get PCIe reset\n"); 288 289 stm32_pcie->perst_gpio = devm_gpiod_get(dev, "reset", GPIOD_IN); 290 if (IS_ERR(stm32_pcie->perst_gpio)) 291 return dev_err_probe(dev, PTR_ERR(stm32_pcie->perst_gpio), 292 "Failed to get reset GPIO\n"); 293 294 ret = phy_set_mode(stm32_pcie->phy, PHY_MODE_PCIE); 295 if (ret) 296 return ret; 297 298 platform_set_drvdata(pdev, stm32_pcie); 299 300 pm_runtime_get_noresume(dev); 301 302 ret = devm_pm_runtime_enable(dev); 303 if (ret < 0) { 304 pm_runtime_put_noidle(&pdev->dev); 305 return dev_err_probe(dev, ret, "Failed to enable runtime PM\n"); 306 } 307 308 stm32_pcie->perst_irq = gpiod_to_irq(stm32_pcie->perst_gpio); 309 310 /* Will be enabled in start_link when device is initialized. */ 311 irq_set_status_flags(stm32_pcie->perst_irq, IRQ_NOAUTOEN); 312 313 ret = devm_request_threaded_irq(dev, stm32_pcie->perst_irq, NULL, 314 stm32_pcie_ep_perst_irq_thread, 315 IRQF_TRIGGER_HIGH | IRQF_ONESHOT, 316 "perst_irq", stm32_pcie); 317 if (ret) { 318 pm_runtime_put_noidle(&pdev->dev); 319 return dev_err_probe(dev, ret, "Failed to request PERST IRQ\n"); 320 } 321 322 ret = stm32_add_pcie_ep(stm32_pcie, pdev); 323 if (ret) 324 pm_runtime_put_noidle(&pdev->dev); 325 326 return ret; 327 } 328 329 static void stm32_pcie_remove(struct platform_device *pdev) 330 { 331 struct stm32_pcie *stm32_pcie = platform_get_drvdata(pdev); 332 struct dw_pcie *pci = &stm32_pcie->pci; 333 struct dw_pcie_ep *ep = &pci->ep; 334 335 dw_pcie_stop_link(pci); 336 337 pci_epc_deinit_notify(ep->epc); 338 dw_pcie_ep_deinit(ep); 339 340 stm32_pcie_disable_resources(stm32_pcie); 341 342 pm_runtime_put_sync(&pdev->dev); 343 } 344 345 static const struct of_device_id stm32_pcie_ep_of_match[] = { 346 { .compatible = "st,stm32mp25-pcie-ep" }, 347 {}, 348 }; 349 350 static struct platform_driver stm32_pcie_ep_driver = { 351 .probe = stm32_pcie_probe, 352 .remove = stm32_pcie_remove, 353 .driver = { 354 .name = "stm32-ep-pcie", 355 .of_match_table = stm32_pcie_ep_of_match, 356 }, 357 }; 358 359 module_platform_driver(stm32_pcie_ep_driver); 360 361 MODULE_AUTHOR("Christian Bruel <christian.bruel@foss.st.com>"); 362 MODULE_DESCRIPTION("STM32MP25 PCIe Endpoint Controller driver"); 363 MODULE_LICENSE("GPL"); 364 MODULE_DEVICE_TABLE(of, stm32_pcie_ep_of_match); 365