pcie-uniphier-ep.c (10892B)
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_device.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 72struct 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 81struct 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 90static 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 103static 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 116static 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 141static 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 173static 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 190static 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 199static 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 206static 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 215static int uniphier_pcie_ep_raise_legacy_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 240static 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 258static int uniphier_pcie_ep_raise_irq(struct dw_pcie_ep *ep, u8 func_no, 259 enum pci_epc_irq_type type, 260 u16 interrupt_num) 261{ 262 struct dw_pcie *pci = to_dw_pcie_from_ep(ep); 263 264 switch (type) { 265 case PCI_EPC_IRQ_LEGACY: 266 return uniphier_pcie_ep_raise_legacy_irq(ep); 267 case PCI_EPC_IRQ_MSI: 268 return uniphier_pcie_ep_raise_msi_irq(ep, func_no, 269 interrupt_num); 270 default: 271 dev_err(pci->dev, "UNKNOWN IRQ type (%d)\n", type); 272 } 273 274 return 0; 275} 276 277static const struct pci_epc_features* 278uniphier_pcie_get_features(struct dw_pcie_ep *ep) 279{ 280 struct dw_pcie *pci = to_dw_pcie_from_ep(ep); 281 struct uniphier_pcie_ep_priv *priv = to_uniphier_pcie(pci); 282 283 return &priv->data->features; 284} 285 286static const struct dw_pcie_ep_ops uniphier_pcie_ep_ops = { 287 .ep_init = uniphier_pcie_ep_init, 288 .raise_irq = uniphier_pcie_ep_raise_irq, 289 .get_features = uniphier_pcie_get_features, 290}; 291 292static int uniphier_pcie_ep_enable(struct uniphier_pcie_ep_priv *priv) 293{ 294 int ret; 295 296 ret = clk_prepare_enable(priv->clk); 297 if (ret) 298 return ret; 299 300 ret = clk_prepare_enable(priv->clk_gio); 301 if (ret) 302 goto out_clk_disable; 303 304 ret = reset_control_deassert(priv->rst); 305 if (ret) 306 goto out_clk_gio_disable; 307 308 ret = reset_control_deassert(priv->rst_gio); 309 if (ret) 310 goto out_rst_assert; 311 312 if (priv->data->init) 313 priv->data->init(priv); 314 315 uniphier_pcie_phy_reset(priv, true); 316 317 ret = phy_init(priv->phy); 318 if (ret) 319 goto out_rst_gio_assert; 320 321 uniphier_pcie_phy_reset(priv, false); 322 323 if (priv->data->wait) { 324 ret = priv->data->wait(priv); 325 if (ret) 326 goto out_phy_exit; 327 } 328 329 return 0; 330 331out_phy_exit: 332 phy_exit(priv->phy); 333out_rst_gio_assert: 334 reset_control_assert(priv->rst_gio); 335out_rst_assert: 336 reset_control_assert(priv->rst); 337out_clk_gio_disable: 338 clk_disable_unprepare(priv->clk_gio); 339out_clk_disable: 340 clk_disable_unprepare(priv->clk); 341 342 return ret; 343} 344 345static const struct dw_pcie_ops dw_pcie_ops = { 346 .start_link = uniphier_pcie_start_link, 347 .stop_link = uniphier_pcie_stop_link, 348}; 349 350static int uniphier_pcie_ep_probe(struct platform_device *pdev) 351{ 352 struct device *dev = &pdev->dev; 353 struct uniphier_pcie_ep_priv *priv; 354 int ret; 355 356 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); 357 if (!priv) 358 return -ENOMEM; 359 360 priv->data = of_device_get_match_data(dev); 361 if (WARN_ON(!priv->data)) 362 return -EINVAL; 363 364 priv->pci.dev = dev; 365 priv->pci.ops = &dw_pcie_ops; 366 367 priv->base = devm_platform_ioremap_resource_byname(pdev, "link"); 368 if (IS_ERR(priv->base)) 369 return PTR_ERR(priv->base); 370 371 if (priv->data->has_gio) { 372 priv->clk_gio = devm_clk_get(dev, "gio"); 373 if (IS_ERR(priv->clk_gio)) 374 return PTR_ERR(priv->clk_gio); 375 376 priv->rst_gio = devm_reset_control_get_shared(dev, "gio"); 377 if (IS_ERR(priv->rst_gio)) 378 return PTR_ERR(priv->rst_gio); 379 } 380 381 priv->clk = devm_clk_get(dev, "link"); 382 if (IS_ERR(priv->clk)) 383 return PTR_ERR(priv->clk); 384 385 priv->rst = devm_reset_control_get_shared(dev, "link"); 386 if (IS_ERR(priv->rst)) 387 return PTR_ERR(priv->rst); 388 389 priv->phy = devm_phy_optional_get(dev, "pcie-phy"); 390 if (IS_ERR(priv->phy)) { 391 ret = PTR_ERR(priv->phy); 392 dev_err(dev, "Failed to get phy (%d)\n", ret); 393 return ret; 394 } 395 396 platform_set_drvdata(pdev, priv); 397 398 ret = uniphier_pcie_ep_enable(priv); 399 if (ret) 400 return ret; 401 402 priv->pci.ep.ops = &uniphier_pcie_ep_ops; 403 return dw_pcie_ep_init(&priv->pci.ep); 404} 405 406static const struct uniphier_pcie_ep_soc_data uniphier_pro5_data = { 407 .has_gio = true, 408 .init = uniphier_pcie_pro5_init_ep, 409 .wait = NULL, 410 .features = { 411 .linkup_notifier = false, 412 .msi_capable = true, 413 .msix_capable = false, 414 .align = 1 << 16, 415 .bar_fixed_64bit = BIT(BAR_0) | BIT(BAR_2) | BIT(BAR_4), 416 .reserved_bar = BIT(BAR_4), 417 }, 418}; 419 420static const struct uniphier_pcie_ep_soc_data uniphier_nx1_data = { 421 .has_gio = false, 422 .init = uniphier_pcie_nx1_init_ep, 423 .wait = uniphier_pcie_nx1_wait_ep, 424 .features = { 425 .linkup_notifier = false, 426 .msi_capable = true, 427 .msix_capable = false, 428 .align = 1 << 12, 429 .bar_fixed_64bit = BIT(BAR_0) | BIT(BAR_2) | BIT(BAR_4), 430 }, 431}; 432 433static const struct of_device_id uniphier_pcie_ep_match[] = { 434 { 435 .compatible = "socionext,uniphier-pro5-pcie-ep", 436 .data = &uniphier_pro5_data, 437 }, 438 { 439 .compatible = "socionext,uniphier-nx1-pcie-ep", 440 .data = &uniphier_nx1_data, 441 }, 442 { /* sentinel */ }, 443}; 444 445static struct platform_driver uniphier_pcie_ep_driver = { 446 .probe = uniphier_pcie_ep_probe, 447 .driver = { 448 .name = "uniphier-pcie-ep", 449 .of_match_table = uniphier_pcie_ep_match, 450 .suppress_bind_attrs = true, 451 }, 452}; 453builtin_platform_driver(uniphier_pcie_ep_driver);