1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * PCIe controller driver for Intel Keem Bay 4 * Copyright (C) 2020 Intel Corporation 5 */ 6 7 #include <linux/bitfield.h> 8 #include <linux/bits.h> 9 #include <linux/clk.h> 10 #include <linux/delay.h> 11 #include <linux/err.h> 12 #include <linux/gpio/consumer.h> 13 #include <linux/init.h> 14 #include <linux/iopoll.h> 15 #include <linux/irqchip/chained_irq.h> 16 #include <linux/kernel.h> 17 #include <linux/mod_devicetable.h> 18 #include <linux/pci.h> 19 #include <linux/platform_device.h> 20 #include <linux/property.h> 21 22 #include "pcie-designware.h" 23 24 /* PCIE_REGS_APB_SLV Registers */ 25 #define PCIE_REGS_PCIE_CFG 0x0004 26 #define PCIE_DEVICE_TYPE BIT(8) 27 #define PCIE_RSTN BIT(0) 28 #define PCIE_REGS_PCIE_APP_CNTRL 0x0008 29 #define APP_LTSSM_ENABLE BIT(0) 30 #define PCIE_REGS_INTERRUPT_ENABLE 0x0028 31 #define MSI_CTRL_INT_EN BIT(8) 32 #define EDMA_INT_EN GENMASK(7, 0) 33 #define PCIE_REGS_INTERRUPT_STATUS 0x002c 34 #define MSI_CTRL_INT BIT(8) 35 #define PCIE_REGS_PCIE_SII_PM_STATE 0x00b0 36 #define SMLH_LINK_UP BIT(19) 37 #define RDLH_LINK_UP BIT(8) 38 #define PCIE_REGS_PCIE_SII_LINK_UP (SMLH_LINK_UP | RDLH_LINK_UP) 39 #define PCIE_REGS_PCIE_PHY_CNTL 0x0164 40 #define PHY0_SRAM_BYPASS BIT(8) 41 #define PCIE_REGS_PCIE_PHY_STAT 0x0168 42 #define PHY0_MPLLA_STATE BIT(1) 43 #define PCIE_REGS_LJPLL_STA 0x016c 44 #define LJPLL_LOCK BIT(0) 45 #define PCIE_REGS_LJPLL_CNTRL_0 0x0170 46 #define LJPLL_EN BIT(29) 47 #define LJPLL_FOUT_EN GENMASK(24, 21) 48 #define PCIE_REGS_LJPLL_CNTRL_2 0x0178 49 #define LJPLL_REF_DIV GENMASK(17, 12) 50 #define LJPLL_FB_DIV GENMASK(11, 0) 51 #define PCIE_REGS_LJPLL_CNTRL_3 0x017c 52 #define LJPLL_POST_DIV3A GENMASK(24, 22) 53 #define LJPLL_POST_DIV2A GENMASK(18, 16) 54 55 #define PERST_DELAY_US 1000 56 #define AUX_CLK_RATE_HZ 24000000 57 58 struct keembay_pcie { 59 struct dw_pcie pci; 60 void __iomem *apb_base; 61 enum dw_pcie_device_mode mode; 62 63 struct clk *clk_master; 64 struct clk *clk_aux; 65 struct gpio_desc *reset; 66 }; 67 68 struct keembay_pcie_of_data { 69 enum dw_pcie_device_mode mode; 70 }; 71 72 static void keembay_ep_reset_assert(struct keembay_pcie *pcie) 73 { 74 gpiod_set_value_cansleep(pcie->reset, 1); 75 usleep_range(PERST_DELAY_US, PERST_DELAY_US + 500); 76 } 77 78 static void keembay_ep_reset_deassert(struct keembay_pcie *pcie) 79 { 80 /* 81 * Ensure that PERST# is asserted for a minimum of 100ms. 82 * 83 * For more details, refer to PCI Express Card Electromechanical 84 * Specification Revision 1.1, Table-2.4. 85 */ 86 msleep(100); 87 88 gpiod_set_value_cansleep(pcie->reset, 0); 89 usleep_range(PERST_DELAY_US, PERST_DELAY_US + 500); 90 } 91 92 static void keembay_pcie_ltssm_set(struct keembay_pcie *pcie, bool enable) 93 { 94 u32 val; 95 96 val = readl(pcie->apb_base + PCIE_REGS_PCIE_APP_CNTRL); 97 if (enable) 98 val |= APP_LTSSM_ENABLE; 99 else 100 val &= ~APP_LTSSM_ENABLE; 101 writel(val, pcie->apb_base + PCIE_REGS_PCIE_APP_CNTRL); 102 } 103 104 static int keembay_pcie_link_up(struct dw_pcie *pci) 105 { 106 struct keembay_pcie *pcie = dev_get_drvdata(pci->dev); 107 u32 val; 108 109 val = readl(pcie->apb_base + PCIE_REGS_PCIE_SII_PM_STATE); 110 111 return (val & PCIE_REGS_PCIE_SII_LINK_UP) == PCIE_REGS_PCIE_SII_LINK_UP; 112 } 113 114 static int keembay_pcie_start_link(struct dw_pcie *pci) 115 { 116 struct keembay_pcie *pcie = dev_get_drvdata(pci->dev); 117 u32 val; 118 int ret; 119 120 if (pcie->mode == DW_PCIE_EP_TYPE) 121 return 0; 122 123 keembay_pcie_ltssm_set(pcie, false); 124 125 ret = readl_poll_timeout(pcie->apb_base + PCIE_REGS_PCIE_PHY_STAT, 126 val, val & PHY0_MPLLA_STATE, 20, 127 500 * USEC_PER_MSEC); 128 if (ret) { 129 dev_err(pci->dev, "MPLLA is not locked\n"); 130 return ret; 131 } 132 133 keembay_pcie_ltssm_set(pcie, true); 134 135 return 0; 136 } 137 138 static void keembay_pcie_stop_link(struct dw_pcie *pci) 139 { 140 struct keembay_pcie *pcie = dev_get_drvdata(pci->dev); 141 142 keembay_pcie_ltssm_set(pcie, false); 143 } 144 145 static const struct dw_pcie_ops keembay_pcie_ops = { 146 .link_up = keembay_pcie_link_up, 147 .start_link = keembay_pcie_start_link, 148 .stop_link = keembay_pcie_stop_link, 149 }; 150 151 static inline struct clk *keembay_pcie_probe_clock(struct device *dev, 152 const char *id, u64 rate) 153 { 154 struct clk *clk; 155 int ret; 156 157 clk = devm_clk_get(dev, id); 158 if (IS_ERR(clk)) 159 return clk; 160 161 if (rate) { 162 ret = clk_set_rate(clk, rate); 163 if (ret) 164 return ERR_PTR(ret); 165 } 166 167 ret = clk_prepare_enable(clk); 168 if (ret) 169 return ERR_PTR(ret); 170 171 ret = devm_add_action_or_reset(dev, 172 (void(*)(void *))clk_disable_unprepare, 173 clk); 174 if (ret) 175 return ERR_PTR(ret); 176 177 return clk; 178 } 179 180 static int keembay_pcie_probe_clocks(struct keembay_pcie *pcie) 181 { 182 struct dw_pcie *pci = &pcie->pci; 183 struct device *dev = pci->dev; 184 185 pcie->clk_master = keembay_pcie_probe_clock(dev, "master", 0); 186 if (IS_ERR(pcie->clk_master)) 187 return dev_err_probe(dev, PTR_ERR(pcie->clk_master), 188 "Failed to enable master clock"); 189 190 pcie->clk_aux = keembay_pcie_probe_clock(dev, "aux", AUX_CLK_RATE_HZ); 191 if (IS_ERR(pcie->clk_aux)) 192 return dev_err_probe(dev, PTR_ERR(pcie->clk_aux), 193 "Failed to enable auxiliary clock"); 194 195 return 0; 196 } 197 198 /* 199 * Initialize the internal PCIe PLL in Host mode. 200 * See the following sections in Keem Bay data book, 201 * (1) 6.4.6.1 PCIe Subsystem Example Initialization, 202 * (2) 6.8 PCIe Low Jitter PLL for Ref Clk Generation. 203 */ 204 static int keembay_pcie_pll_init(struct keembay_pcie *pcie) 205 { 206 struct dw_pcie *pci = &pcie->pci; 207 u32 val; 208 int ret; 209 210 val = FIELD_PREP(LJPLL_REF_DIV, 0) | FIELD_PREP(LJPLL_FB_DIV, 0x32); 211 writel(val, pcie->apb_base + PCIE_REGS_LJPLL_CNTRL_2); 212 213 val = FIELD_PREP(LJPLL_POST_DIV3A, 0x2) | 214 FIELD_PREP(LJPLL_POST_DIV2A, 0x2); 215 writel(val, pcie->apb_base + PCIE_REGS_LJPLL_CNTRL_3); 216 217 val = FIELD_PREP(LJPLL_EN, 0x1) | FIELD_PREP(LJPLL_FOUT_EN, 0xc); 218 writel(val, pcie->apb_base + PCIE_REGS_LJPLL_CNTRL_0); 219 220 ret = readl_poll_timeout(pcie->apb_base + PCIE_REGS_LJPLL_STA, 221 val, val & LJPLL_LOCK, 20, 222 500 * USEC_PER_MSEC); 223 if (ret) 224 dev_err(pci->dev, "Low jitter PLL is not locked\n"); 225 226 return ret; 227 } 228 229 static void keembay_pcie_msi_irq_handler(struct irq_desc *desc) 230 { 231 struct keembay_pcie *pcie = irq_desc_get_handler_data(desc); 232 struct irq_chip *chip = irq_desc_get_chip(desc); 233 u32 val, mask, status; 234 struct dw_pcie_rp *pp; 235 236 /* 237 * Keem Bay PCIe Controller provides an additional IP logic on top of 238 * standard DWC IP to clear MSI IRQ by writing '1' to the respective 239 * bit of the status register. 240 * 241 * So, a chained irq handler is defined to handle this additional 242 * IP logic. 243 */ 244 245 chained_irq_enter(chip, desc); 246 247 pp = &pcie->pci.pp; 248 val = readl(pcie->apb_base + PCIE_REGS_INTERRUPT_STATUS); 249 mask = readl(pcie->apb_base + PCIE_REGS_INTERRUPT_ENABLE); 250 251 status = val & mask; 252 253 if (status & MSI_CTRL_INT) { 254 dw_handle_msi_irq(pp); 255 writel(status, pcie->apb_base + PCIE_REGS_INTERRUPT_STATUS); 256 } 257 258 chained_irq_exit(chip, desc); 259 } 260 261 static int keembay_pcie_setup_msi_irq(struct keembay_pcie *pcie) 262 { 263 struct dw_pcie *pci = &pcie->pci; 264 struct device *dev = pci->dev; 265 struct platform_device *pdev = to_platform_device(dev); 266 int irq; 267 268 irq = platform_get_irq_byname(pdev, "pcie"); 269 if (irq < 0) 270 return irq; 271 272 irq_set_chained_handler_and_data(irq, keembay_pcie_msi_irq_handler, 273 pcie); 274 275 return 0; 276 } 277 278 static void keembay_pcie_ep_init(struct dw_pcie_ep *ep) 279 { 280 struct dw_pcie *pci = to_dw_pcie_from_ep(ep); 281 struct keembay_pcie *pcie = dev_get_drvdata(pci->dev); 282 283 writel(EDMA_INT_EN, pcie->apb_base + PCIE_REGS_INTERRUPT_ENABLE); 284 } 285 286 static int keembay_pcie_ep_raise_irq(struct dw_pcie_ep *ep, u8 func_no, 287 enum pci_epc_irq_type type, 288 u16 interrupt_num) 289 { 290 struct dw_pcie *pci = to_dw_pcie_from_ep(ep); 291 292 switch (type) { 293 case PCI_EPC_IRQ_LEGACY: 294 /* Legacy interrupts are not supported in Keem Bay */ 295 dev_err(pci->dev, "Legacy IRQ is not supported\n"); 296 return -EINVAL; 297 case PCI_EPC_IRQ_MSI: 298 return dw_pcie_ep_raise_msi_irq(ep, func_no, interrupt_num); 299 case PCI_EPC_IRQ_MSIX: 300 return dw_pcie_ep_raise_msix_irq(ep, func_no, interrupt_num); 301 default: 302 dev_err(pci->dev, "Unknown IRQ type %d\n", type); 303 return -EINVAL; 304 } 305 } 306 307 static const struct pci_epc_features keembay_pcie_epc_features = { 308 .linkup_notifier = false, 309 .msi_capable = true, 310 .msix_capable = true, 311 .reserved_bar = BIT(BAR_1) | BIT(BAR_3) | BIT(BAR_5), 312 .bar_fixed_64bit = BIT(BAR_0) | BIT(BAR_2) | BIT(BAR_4), 313 .align = SZ_16K, 314 }; 315 316 static const struct pci_epc_features * 317 keembay_pcie_get_features(struct dw_pcie_ep *ep) 318 { 319 return &keembay_pcie_epc_features; 320 } 321 322 static const struct dw_pcie_ep_ops keembay_pcie_ep_ops = { 323 .ep_init = keembay_pcie_ep_init, 324 .raise_irq = keembay_pcie_ep_raise_irq, 325 .get_features = keembay_pcie_get_features, 326 }; 327 328 static const struct dw_pcie_host_ops keembay_pcie_host_ops = { 329 }; 330 331 static int keembay_pcie_add_pcie_port(struct keembay_pcie *pcie, 332 struct platform_device *pdev) 333 { 334 struct dw_pcie *pci = &pcie->pci; 335 struct dw_pcie_rp *pp = &pci->pp; 336 struct device *dev = &pdev->dev; 337 u32 val; 338 int ret; 339 340 pp->ops = &keembay_pcie_host_ops; 341 pp->msi_irq[0] = -ENODEV; 342 343 ret = keembay_pcie_setup_msi_irq(pcie); 344 if (ret) 345 return ret; 346 347 pcie->reset = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH); 348 if (IS_ERR(pcie->reset)) 349 return PTR_ERR(pcie->reset); 350 351 ret = keembay_pcie_probe_clocks(pcie); 352 if (ret) 353 return ret; 354 355 val = readl(pcie->apb_base + PCIE_REGS_PCIE_PHY_CNTL); 356 val |= PHY0_SRAM_BYPASS; 357 writel(val, pcie->apb_base + PCIE_REGS_PCIE_PHY_CNTL); 358 359 writel(PCIE_DEVICE_TYPE, pcie->apb_base + PCIE_REGS_PCIE_CFG); 360 361 ret = keembay_pcie_pll_init(pcie); 362 if (ret) 363 return ret; 364 365 val = readl(pcie->apb_base + PCIE_REGS_PCIE_CFG); 366 writel(val | PCIE_RSTN, pcie->apb_base + PCIE_REGS_PCIE_CFG); 367 keembay_ep_reset_deassert(pcie); 368 369 ret = dw_pcie_host_init(pp); 370 if (ret) { 371 keembay_ep_reset_assert(pcie); 372 dev_err(dev, "Failed to initialize host: %d\n", ret); 373 return ret; 374 } 375 376 val = readl(pcie->apb_base + PCIE_REGS_INTERRUPT_ENABLE); 377 if (IS_ENABLED(CONFIG_PCI_MSI)) 378 val |= MSI_CTRL_INT_EN; 379 writel(val, pcie->apb_base + PCIE_REGS_INTERRUPT_ENABLE); 380 381 return 0; 382 } 383 384 static int keembay_pcie_probe(struct platform_device *pdev) 385 { 386 const struct keembay_pcie_of_data *data; 387 struct device *dev = &pdev->dev; 388 struct keembay_pcie *pcie; 389 struct dw_pcie *pci; 390 enum dw_pcie_device_mode mode; 391 392 data = device_get_match_data(dev); 393 if (!data) 394 return -ENODEV; 395 396 mode = (enum dw_pcie_device_mode)data->mode; 397 398 pcie = devm_kzalloc(dev, sizeof(*pcie), GFP_KERNEL); 399 if (!pcie) 400 return -ENOMEM; 401 402 pci = &pcie->pci; 403 pci->dev = dev; 404 pci->ops = &keembay_pcie_ops; 405 406 pcie->mode = mode; 407 408 pcie->apb_base = devm_platform_ioremap_resource_byname(pdev, "apb"); 409 if (IS_ERR(pcie->apb_base)) 410 return PTR_ERR(pcie->apb_base); 411 412 platform_set_drvdata(pdev, pcie); 413 414 switch (pcie->mode) { 415 case DW_PCIE_RC_TYPE: 416 if (!IS_ENABLED(CONFIG_PCIE_KEEMBAY_HOST)) 417 return -ENODEV; 418 419 return keembay_pcie_add_pcie_port(pcie, pdev); 420 case DW_PCIE_EP_TYPE: 421 if (!IS_ENABLED(CONFIG_PCIE_KEEMBAY_EP)) 422 return -ENODEV; 423 424 pci->ep.ops = &keembay_pcie_ep_ops; 425 return dw_pcie_ep_init(&pci->ep); 426 default: 427 dev_err(dev, "Invalid device type %d\n", pcie->mode); 428 return -ENODEV; 429 } 430 } 431 432 static const struct keembay_pcie_of_data keembay_pcie_rc_of_data = { 433 .mode = DW_PCIE_RC_TYPE, 434 }; 435 436 static const struct keembay_pcie_of_data keembay_pcie_ep_of_data = { 437 .mode = DW_PCIE_EP_TYPE, 438 }; 439 440 static const struct of_device_id keembay_pcie_of_match[] = { 441 { 442 .compatible = "intel,keembay-pcie", 443 .data = &keembay_pcie_rc_of_data, 444 }, 445 { 446 .compatible = "intel,keembay-pcie-ep", 447 .data = &keembay_pcie_ep_of_data, 448 }, 449 {} 450 }; 451 452 static struct platform_driver keembay_pcie_driver = { 453 .driver = { 454 .name = "keembay-pcie", 455 .of_match_table = keembay_pcie_of_match, 456 .suppress_bind_attrs = true, 457 }, 458 .probe = keembay_pcie_probe, 459 }; 460 builtin_platform_driver(keembay_pcie_driver); 461