1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * PCIe endpoint controller driver for UniPhier SoCs 4 * Copyright 2018 Socionext Inc. 5 * Author: Kunihiko Hayashi <hayashi.kunihiko@socionext.com> 6 */ 7 8 #include <linux/bitops.h> 9 #include <linux/bitfield.h> 10 #include <linux/clk.h> 11 #include <linux/delay.h> 12 #include <linux/init.h> 13 #include <linux/iopoll.h> 14 #include <linux/of.h> 15 #include <linux/pci.h> 16 #include <linux/phy/phy.h> 17 #include <linux/platform_device.h> 18 #include <linux/reset.h> 19 20 #include "pcie-designware.h" 21 22 /* Link Glue registers */ 23 #define PCL_RSTCTRL0 0x0010 24 #define PCL_RSTCTRL_AXI_REG BIT(3) 25 #define PCL_RSTCTRL_AXI_SLAVE BIT(2) 26 #define PCL_RSTCTRL_AXI_MASTER BIT(1) 27 #define PCL_RSTCTRL_PIPE3 BIT(0) 28 29 #define PCL_RSTCTRL1 0x0020 30 #define PCL_RSTCTRL_PERST BIT(0) 31 32 #define PCL_RSTCTRL2 0x0024 33 #define PCL_RSTCTRL_PHY_RESET BIT(0) 34 35 #define PCL_PINCTRL0 0x002c 36 #define PCL_PERST_PLDN_REGEN BIT(12) 37 #define PCL_PERST_NOE_REGEN BIT(11) 38 #define PCL_PERST_OUT_REGEN BIT(8) 39 #define PCL_PERST_PLDN_REGVAL BIT(4) 40 #define PCL_PERST_NOE_REGVAL BIT(3) 41 #define PCL_PERST_OUT_REGVAL BIT(0) 42 43 #define PCL_PIPEMON 0x0044 44 #define PCL_PCLK_ALIVE BIT(15) 45 46 #define PCL_MODE 0x8000 47 #define PCL_MODE_REGEN BIT(8) 48 #define PCL_MODE_REGVAL BIT(0) 49 50 #define PCL_APP_CLK_CTRL 0x8004 51 #define PCL_APP_CLK_REQ BIT(0) 52 53 #define PCL_APP_READY_CTRL 0x8008 54 #define PCL_APP_LTSSM_ENABLE BIT(0) 55 56 #define PCL_APP_MSI0 0x8040 57 #define PCL_APP_VEN_MSI_TC_MASK GENMASK(10, 8) 58 #define PCL_APP_VEN_MSI_VECTOR_MASK GENMASK(4, 0) 59 60 #define PCL_APP_MSI1 0x8044 61 #define PCL_APP_MSI_REQ BIT(0) 62 63 #define PCL_APP_INTX 0x8074 64 #define PCL_APP_INTX_SYS_INT BIT(0) 65 66 #define PCL_APP_PM0 0x8078 67 #define PCL_SYS_AUX_PWR_DET BIT(8) 68 69 /* assertion time of INTx in usec */ 70 #define PCL_INTX_WIDTH_USEC 30 71 72 struct uniphier_pcie_ep_priv { 73 void __iomem *base; 74 struct dw_pcie pci; 75 struct clk *clk, *clk_gio; 76 struct reset_control *rst, *rst_gio; 77 struct phy *phy; 78 const struct uniphier_pcie_ep_soc_data *data; 79 }; 80 81 struct uniphier_pcie_ep_soc_data { 82 bool has_gio; 83 void (*init)(struct uniphier_pcie_ep_priv *priv); 84 int (*wait)(struct uniphier_pcie_ep_priv *priv); 85 const struct pci_epc_features features; 86 }; 87 88 #define to_uniphier_pcie(x) dev_get_drvdata((x)->dev) 89 90 static void uniphier_pcie_ltssm_enable(struct uniphier_pcie_ep_priv *priv, 91 bool enable) 92 { 93 u32 val; 94 95 val = readl(priv->base + PCL_APP_READY_CTRL); 96 if (enable) 97 val |= PCL_APP_LTSSM_ENABLE; 98 else 99 val &= ~PCL_APP_LTSSM_ENABLE; 100 writel(val, priv->base + PCL_APP_READY_CTRL); 101 } 102 103 static void uniphier_pcie_phy_reset(struct uniphier_pcie_ep_priv *priv, 104 bool assert) 105 { 106 u32 val; 107 108 val = readl(priv->base + PCL_RSTCTRL2); 109 if (assert) 110 val |= PCL_RSTCTRL_PHY_RESET; 111 else 112 val &= ~PCL_RSTCTRL_PHY_RESET; 113 writel(val, priv->base + PCL_RSTCTRL2); 114 } 115 116 static void uniphier_pcie_pro5_init_ep(struct uniphier_pcie_ep_priv *priv) 117 { 118 u32 val; 119 120 /* set EP mode */ 121 val = readl(priv->base + PCL_MODE); 122 val |= PCL_MODE_REGEN | PCL_MODE_REGVAL; 123 writel(val, priv->base + PCL_MODE); 124 125 /* clock request */ 126 val = readl(priv->base + PCL_APP_CLK_CTRL); 127 val &= ~PCL_APP_CLK_REQ; 128 writel(val, priv->base + PCL_APP_CLK_CTRL); 129 130 /* deassert PIPE3 and AXI reset */ 131 val = readl(priv->base + PCL_RSTCTRL0); 132 val |= PCL_RSTCTRL_AXI_REG | PCL_RSTCTRL_AXI_SLAVE 133 | PCL_RSTCTRL_AXI_MASTER | PCL_RSTCTRL_PIPE3; 134 writel(val, priv->base + PCL_RSTCTRL0); 135 136 uniphier_pcie_ltssm_enable(priv, false); 137 138 msleep(100); 139 } 140 141 static void uniphier_pcie_nx1_init_ep(struct uniphier_pcie_ep_priv *priv) 142 { 143 u32 val; 144 145 /* set EP mode */ 146 val = readl(priv->base + PCL_MODE); 147 val |= PCL_MODE_REGEN | PCL_MODE_REGVAL; 148 writel(val, priv->base + PCL_MODE); 149 150 /* use auxiliary power detection */ 151 val = readl(priv->base + PCL_APP_PM0); 152 val |= PCL_SYS_AUX_PWR_DET; 153 writel(val, priv->base + PCL_APP_PM0); 154 155 /* assert PERST# */ 156 val = readl(priv->base + PCL_PINCTRL0); 157 val &= ~(PCL_PERST_NOE_REGVAL | PCL_PERST_OUT_REGVAL 158 | PCL_PERST_PLDN_REGVAL); 159 val |= PCL_PERST_NOE_REGEN | PCL_PERST_OUT_REGEN 160 | PCL_PERST_PLDN_REGEN; 161 writel(val, priv->base + PCL_PINCTRL0); 162 163 uniphier_pcie_ltssm_enable(priv, false); 164 165 usleep_range(100000, 200000); 166 167 /* deassert PERST# */ 168 val = readl(priv->base + PCL_PINCTRL0); 169 val |= PCL_PERST_OUT_REGVAL | PCL_PERST_OUT_REGEN; 170 writel(val, priv->base + PCL_PINCTRL0); 171 } 172 173 static int uniphier_pcie_nx1_wait_ep(struct uniphier_pcie_ep_priv *priv) 174 { 175 u32 status; 176 int ret; 177 178 /* wait PIPE clock */ 179 ret = readl_poll_timeout(priv->base + PCL_PIPEMON, status, 180 status & PCL_PCLK_ALIVE, 100000, 1000000); 181 if (ret) { 182 dev_err(priv->pci.dev, 183 "Failed to initialize controller in EP mode\n"); 184 return ret; 185 } 186 187 return 0; 188 } 189 190 static int uniphier_pcie_start_link(struct dw_pcie *pci) 191 { 192 struct uniphier_pcie_ep_priv *priv = to_uniphier_pcie(pci); 193 194 uniphier_pcie_ltssm_enable(priv, true); 195 196 return 0; 197 } 198 199 static void uniphier_pcie_stop_link(struct dw_pcie *pci) 200 { 201 struct uniphier_pcie_ep_priv *priv = to_uniphier_pcie(pci); 202 203 uniphier_pcie_ltssm_enable(priv, false); 204 } 205 206 static void uniphier_pcie_ep_init(struct dw_pcie_ep *ep) 207 { 208 struct dw_pcie *pci = to_dw_pcie_from_ep(ep); 209 enum pci_barno bar; 210 211 for (bar = BAR_0; bar <= BAR_5; bar++) 212 dw_pcie_ep_reset_bar(pci, bar); 213 } 214 215 static int uniphier_pcie_ep_raise_intx_irq(struct dw_pcie_ep *ep) 216 { 217 struct dw_pcie *pci = to_dw_pcie_from_ep(ep); 218 struct uniphier_pcie_ep_priv *priv = to_uniphier_pcie(pci); 219 u32 val; 220 221 /* 222 * This makes pulse signal to send INTx to the RC, so this should 223 * be cleared as soon as possible. This sequence is covered with 224 * mutex in pci_epc_raise_irq(). 225 */ 226 /* assert INTx */ 227 val = readl(priv->base + PCL_APP_INTX); 228 val |= PCL_APP_INTX_SYS_INT; 229 writel(val, priv->base + PCL_APP_INTX); 230 231 udelay(PCL_INTX_WIDTH_USEC); 232 233 /* deassert INTx */ 234 val &= ~PCL_APP_INTX_SYS_INT; 235 writel(val, priv->base + PCL_APP_INTX); 236 237 return 0; 238 } 239 240 static int uniphier_pcie_ep_raise_msi_irq(struct dw_pcie_ep *ep, 241 u8 func_no, u16 interrupt_num) 242 { 243 struct dw_pcie *pci = to_dw_pcie_from_ep(ep); 244 struct uniphier_pcie_ep_priv *priv = to_uniphier_pcie(pci); 245 u32 val; 246 247 val = FIELD_PREP(PCL_APP_VEN_MSI_TC_MASK, func_no) 248 | FIELD_PREP(PCL_APP_VEN_MSI_VECTOR_MASK, interrupt_num - 1); 249 writel(val, priv->base + PCL_APP_MSI0); 250 251 val = readl(priv->base + PCL_APP_MSI1); 252 val |= PCL_APP_MSI_REQ; 253 writel(val, priv->base + PCL_APP_MSI1); 254 255 return 0; 256 } 257 258 static int uniphier_pcie_ep_raise_irq(struct dw_pcie_ep *ep, u8 func_no, 259 unsigned int type, u16 interrupt_num) 260 { 261 struct dw_pcie *pci = to_dw_pcie_from_ep(ep); 262 263 switch (type) { 264 case PCI_IRQ_INTX: 265 return uniphier_pcie_ep_raise_intx_irq(ep); 266 case PCI_IRQ_MSI: 267 return uniphier_pcie_ep_raise_msi_irq(ep, func_no, 268 interrupt_num); 269 default: 270 dev_err(pci->dev, "UNKNOWN IRQ type (%d)\n", type); 271 } 272 273 return 0; 274 } 275 276 static const struct pci_epc_features* 277 uniphier_pcie_get_features(struct dw_pcie_ep *ep) 278 { 279 struct dw_pcie *pci = to_dw_pcie_from_ep(ep); 280 struct uniphier_pcie_ep_priv *priv = to_uniphier_pcie(pci); 281 282 return &priv->data->features; 283 } 284 285 static const struct dw_pcie_ep_ops uniphier_pcie_ep_ops = { 286 .init = uniphier_pcie_ep_init, 287 .raise_irq = uniphier_pcie_ep_raise_irq, 288 .get_features = uniphier_pcie_get_features, 289 }; 290 291 static int uniphier_pcie_ep_enable(struct uniphier_pcie_ep_priv *priv) 292 { 293 int ret; 294 295 ret = clk_prepare_enable(priv->clk); 296 if (ret) 297 return ret; 298 299 ret = clk_prepare_enable(priv->clk_gio); 300 if (ret) 301 goto out_clk_disable; 302 303 ret = reset_control_deassert(priv->rst); 304 if (ret) 305 goto out_clk_gio_disable; 306 307 ret = reset_control_deassert(priv->rst_gio); 308 if (ret) 309 goto out_rst_assert; 310 311 if (priv->data->init) 312 priv->data->init(priv); 313 314 uniphier_pcie_phy_reset(priv, true); 315 316 ret = phy_init(priv->phy); 317 if (ret) 318 goto out_rst_gio_assert; 319 320 uniphier_pcie_phy_reset(priv, false); 321 322 if (priv->data->wait) { 323 ret = priv->data->wait(priv); 324 if (ret) 325 goto out_phy_exit; 326 } 327 328 return 0; 329 330 out_phy_exit: 331 phy_exit(priv->phy); 332 out_rst_gio_assert: 333 reset_control_assert(priv->rst_gio); 334 out_rst_assert: 335 reset_control_assert(priv->rst); 336 out_clk_gio_disable: 337 clk_disable_unprepare(priv->clk_gio); 338 out_clk_disable: 339 clk_disable_unprepare(priv->clk); 340 341 return ret; 342 } 343 344 static const struct dw_pcie_ops dw_pcie_ops = { 345 .start_link = uniphier_pcie_start_link, 346 .stop_link = uniphier_pcie_stop_link, 347 }; 348 349 static int uniphier_pcie_ep_probe(struct platform_device *pdev) 350 { 351 struct device *dev = &pdev->dev; 352 struct uniphier_pcie_ep_priv *priv; 353 int ret; 354 355 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); 356 if (!priv) 357 return -ENOMEM; 358 359 priv->data = of_device_get_match_data(dev); 360 if (WARN_ON(!priv->data)) 361 return -EINVAL; 362 363 priv->pci.dev = dev; 364 priv->pci.ops = &dw_pcie_ops; 365 366 priv->base = devm_platform_ioremap_resource_byname(pdev, "link"); 367 if (IS_ERR(priv->base)) 368 return PTR_ERR(priv->base); 369 370 if (priv->data->has_gio) { 371 priv->clk_gio = devm_clk_get(dev, "gio"); 372 if (IS_ERR(priv->clk_gio)) 373 return PTR_ERR(priv->clk_gio); 374 375 priv->rst_gio = devm_reset_control_get_shared(dev, "gio"); 376 if (IS_ERR(priv->rst_gio)) 377 return PTR_ERR(priv->rst_gio); 378 } 379 380 priv->clk = devm_clk_get(dev, "link"); 381 if (IS_ERR(priv->clk)) 382 return PTR_ERR(priv->clk); 383 384 priv->rst = devm_reset_control_get_shared(dev, "link"); 385 if (IS_ERR(priv->rst)) 386 return PTR_ERR(priv->rst); 387 388 priv->phy = devm_phy_optional_get(dev, "pcie-phy"); 389 if (IS_ERR(priv->phy)) { 390 ret = PTR_ERR(priv->phy); 391 dev_err(dev, "Failed to get phy (%d)\n", ret); 392 return ret; 393 } 394 395 platform_set_drvdata(pdev, priv); 396 397 ret = uniphier_pcie_ep_enable(priv); 398 if (ret) 399 return ret; 400 401 priv->pci.ep.ops = &uniphier_pcie_ep_ops; 402 return dw_pcie_ep_init(&priv->pci.ep); 403 } 404 405 static const struct uniphier_pcie_ep_soc_data uniphier_pro5_data = { 406 .has_gio = true, 407 .init = uniphier_pcie_pro5_init_ep, 408 .wait = NULL, 409 .features = { 410 .linkup_notifier = false, 411 .msi_capable = true, 412 .msix_capable = false, 413 .align = 1 << 16, 414 .bar[BAR_0] = { .only_64bit = true, }, 415 .bar[BAR_1] = { .type = BAR_RESERVED, }, 416 .bar[BAR_2] = { .only_64bit = true, }, 417 .bar[BAR_3] = { .type = BAR_RESERVED, }, 418 .bar[BAR_4] = { .type = BAR_RESERVED, }, 419 .bar[BAR_5] = { .type = BAR_RESERVED, }, 420 }, 421 }; 422 423 static const struct uniphier_pcie_ep_soc_data uniphier_nx1_data = { 424 .has_gio = false, 425 .init = uniphier_pcie_nx1_init_ep, 426 .wait = uniphier_pcie_nx1_wait_ep, 427 .features = { 428 .linkup_notifier = false, 429 .msi_capable = true, 430 .msix_capable = false, 431 .align = 1 << 12, 432 .bar[BAR_0] = { .only_64bit = true, }, 433 .bar[BAR_1] = { .type = BAR_RESERVED, }, 434 .bar[BAR_2] = { .only_64bit = true, }, 435 .bar[BAR_3] = { .type = BAR_RESERVED, }, 436 .bar[BAR_4] = { .only_64bit = true, }, 437 .bar[BAR_5] = { .type = BAR_RESERVED, }, 438 }, 439 }; 440 441 static const struct of_device_id uniphier_pcie_ep_match[] = { 442 { 443 .compatible = "socionext,uniphier-pro5-pcie-ep", 444 .data = &uniphier_pro5_data, 445 }, 446 { 447 .compatible = "socionext,uniphier-nx1-pcie-ep", 448 .data = &uniphier_nx1_data, 449 }, 450 { /* sentinel */ }, 451 }; 452 453 static struct platform_driver uniphier_pcie_ep_driver = { 454 .probe = uniphier_pcie_ep_probe, 455 .driver = { 456 .name = "uniphier-pcie-ep", 457 .of_match_table = uniphier_pcie_ep_match, 458 .suppress_bind_attrs = true, 459 }, 460 }; 461 builtin_platform_driver(uniphier_pcie_ep_driver); 462