Lines Matching +full:pcie +full:- +full:ep
1 // SPDX-License-Identifier: GPL-2.0
3 * PCIe host controller driver for Samsung Exynos SoCs
26 #include "pcie-designware.h"
28 #define to_exynos_pcie(x) dev_get_drvdata((x)->dev)
30 /* PCIe ELBI registers */
56 void __iomem *elbi_base; /* DT 0th resource: PCIe CTRL */
76 struct exynos_pcie *ep);
77 int (*get_clk_resources)(struct exynos_pcie *ep);
78 int (*init_clk_resources)(struct exynos_pcie *ep);
79 void (*deinit_clk_resources)(struct exynos_pcie *ep);
83 struct exynos_pcie *ep) in exynos5440_pcie_get_mem_resources() argument
85 struct dw_pcie *pci = ep->pci; in exynos5440_pcie_get_mem_resources()
86 struct device *dev = pci->dev; in exynos5440_pcie_get_mem_resources()
88 ep->mem_res = devm_kzalloc(dev, sizeof(*ep->mem_res), GFP_KERNEL); in exynos5440_pcie_get_mem_resources()
89 if (!ep->mem_res) in exynos5440_pcie_get_mem_resources()
90 return -ENOMEM; in exynos5440_pcie_get_mem_resources()
92 ep->mem_res->elbi_base = devm_platform_ioremap_resource(pdev, 0); in exynos5440_pcie_get_mem_resources()
93 if (IS_ERR(ep->mem_res->elbi_base)) in exynos5440_pcie_get_mem_resources()
94 return PTR_ERR(ep->mem_res->elbi_base); in exynos5440_pcie_get_mem_resources()
99 static int exynos5440_pcie_get_clk_resources(struct exynos_pcie *ep) in exynos5440_pcie_get_clk_resources() argument
101 struct dw_pcie *pci = ep->pci; in exynos5440_pcie_get_clk_resources()
102 struct device *dev = pci->dev; in exynos5440_pcie_get_clk_resources()
104 ep->clk_res = devm_kzalloc(dev, sizeof(*ep->clk_res), GFP_KERNEL); in exynos5440_pcie_get_clk_resources()
105 if (!ep->clk_res) in exynos5440_pcie_get_clk_resources()
106 return -ENOMEM; in exynos5440_pcie_get_clk_resources()
108 ep->clk_res->clk = devm_clk_get(dev, "pcie"); in exynos5440_pcie_get_clk_resources()
109 if (IS_ERR(ep->clk_res->clk)) { in exynos5440_pcie_get_clk_resources()
110 dev_err(dev, "Failed to get pcie rc clock\n"); in exynos5440_pcie_get_clk_resources()
111 return PTR_ERR(ep->clk_res->clk); in exynos5440_pcie_get_clk_resources()
114 ep->clk_res->bus_clk = devm_clk_get(dev, "pcie_bus"); in exynos5440_pcie_get_clk_resources()
115 if (IS_ERR(ep->clk_res->bus_clk)) { in exynos5440_pcie_get_clk_resources()
116 dev_err(dev, "Failed to get pcie bus clock\n"); in exynos5440_pcie_get_clk_resources()
117 return PTR_ERR(ep->clk_res->bus_clk); in exynos5440_pcie_get_clk_resources()
123 static int exynos5440_pcie_init_clk_resources(struct exynos_pcie *ep) in exynos5440_pcie_init_clk_resources() argument
125 struct dw_pcie *pci = ep->pci; in exynos5440_pcie_init_clk_resources()
126 struct device *dev = pci->dev; in exynos5440_pcie_init_clk_resources()
129 ret = clk_prepare_enable(ep->clk_res->clk); in exynos5440_pcie_init_clk_resources()
131 dev_err(dev, "cannot enable pcie rc clock"); in exynos5440_pcie_init_clk_resources()
135 ret = clk_prepare_enable(ep->clk_res->bus_clk); in exynos5440_pcie_init_clk_resources()
137 dev_err(dev, "cannot enable pcie bus clock"); in exynos5440_pcie_init_clk_resources()
144 clk_disable_unprepare(ep->clk_res->clk); in exynos5440_pcie_init_clk_resources()
149 static void exynos5440_pcie_deinit_clk_resources(struct exynos_pcie *ep) in exynos5440_pcie_deinit_clk_resources() argument
151 clk_disable_unprepare(ep->clk_res->bus_clk); in exynos5440_pcie_deinit_clk_resources()
152 clk_disable_unprepare(ep->clk_res->clk); in exynos5440_pcie_deinit_clk_resources()
172 static void exynos_pcie_sideband_dbi_w_mode(struct exynos_pcie *ep, bool on) in exynos_pcie_sideband_dbi_w_mode() argument
176 val = exynos_pcie_readl(ep->mem_res->elbi_base, PCIE_ELBI_SLV_AWMISC); in exynos_pcie_sideband_dbi_w_mode()
181 exynos_pcie_writel(ep->mem_res->elbi_base, val, PCIE_ELBI_SLV_AWMISC); in exynos_pcie_sideband_dbi_w_mode()
184 static void exynos_pcie_sideband_dbi_r_mode(struct exynos_pcie *ep, bool on) in exynos_pcie_sideband_dbi_r_mode() argument
188 val = exynos_pcie_readl(ep->mem_res->elbi_base, PCIE_ELBI_SLV_ARMISC); in exynos_pcie_sideband_dbi_r_mode()
193 exynos_pcie_writel(ep->mem_res->elbi_base, val, PCIE_ELBI_SLV_ARMISC); in exynos_pcie_sideband_dbi_r_mode()
196 static void exynos_pcie_assert_core_reset(struct exynos_pcie *ep) in exynos_pcie_assert_core_reset() argument
200 val = exynos_pcie_readl(ep->mem_res->elbi_base, PCIE_CORE_RESET); in exynos_pcie_assert_core_reset()
202 exynos_pcie_writel(ep->mem_res->elbi_base, val, PCIE_CORE_RESET); in exynos_pcie_assert_core_reset()
203 exynos_pcie_writel(ep->mem_res->elbi_base, 0, PCIE_PWR_RESET); in exynos_pcie_assert_core_reset()
204 exynos_pcie_writel(ep->mem_res->elbi_base, 0, PCIE_STICKY_RESET); in exynos_pcie_assert_core_reset()
205 exynos_pcie_writel(ep->mem_res->elbi_base, 0, PCIE_NONSTICKY_RESET); in exynos_pcie_assert_core_reset()
208 static void exynos_pcie_deassert_core_reset(struct exynos_pcie *ep) in exynos_pcie_deassert_core_reset() argument
212 val = exynos_pcie_readl(ep->mem_res->elbi_base, PCIE_CORE_RESET); in exynos_pcie_deassert_core_reset()
215 exynos_pcie_writel(ep->mem_res->elbi_base, val, PCIE_CORE_RESET); in exynos_pcie_deassert_core_reset()
216 exynos_pcie_writel(ep->mem_res->elbi_base, 1, PCIE_STICKY_RESET); in exynos_pcie_deassert_core_reset()
217 exynos_pcie_writel(ep->mem_res->elbi_base, 1, PCIE_NONSTICKY_RESET); in exynos_pcie_deassert_core_reset()
218 exynos_pcie_writel(ep->mem_res->elbi_base, 1, PCIE_APP_INIT_RESET); in exynos_pcie_deassert_core_reset()
219 exynos_pcie_writel(ep->mem_res->elbi_base, 0, PCIE_APP_INIT_RESET); in exynos_pcie_deassert_core_reset()
222 static void exynos_pcie_assert_reset(struct exynos_pcie *ep) in exynos_pcie_assert_reset() argument
224 struct dw_pcie *pci = ep->pci; in exynos_pcie_assert_reset()
225 struct device *dev = pci->dev; in exynos_pcie_assert_reset()
227 if (ep->reset_gpio >= 0) in exynos_pcie_assert_reset()
228 devm_gpio_request_one(dev, ep->reset_gpio, in exynos_pcie_assert_reset()
232 static int exynos_pcie_establish_link(struct exynos_pcie *ep) in exynos_pcie_establish_link() argument
234 struct dw_pcie *pci = ep->pci; in exynos_pcie_establish_link()
235 struct pcie_port *pp = &pci->pp; in exynos_pcie_establish_link()
236 struct device *dev = pci->dev; in exynos_pcie_establish_link()
243 exynos_pcie_assert_core_reset(ep); in exynos_pcie_establish_link()
245 phy_reset(ep->phy); in exynos_pcie_establish_link()
247 exynos_pcie_writel(ep->mem_res->elbi_base, 1, in exynos_pcie_establish_link()
250 phy_power_on(ep->phy); in exynos_pcie_establish_link()
251 phy_init(ep->phy); in exynos_pcie_establish_link()
253 exynos_pcie_deassert_core_reset(ep); in exynos_pcie_establish_link()
255 exynos_pcie_assert_reset(ep); in exynos_pcie_establish_link()
258 exynos_pcie_writel(ep->mem_res->elbi_base, PCIE_ELBI_LTSSM_ENABLE, in exynos_pcie_establish_link()
265 phy_power_off(ep->phy); in exynos_pcie_establish_link()
266 return -ETIMEDOUT; in exynos_pcie_establish_link()
269 static void exynos_pcie_clear_irq_pulse(struct exynos_pcie *ep) in exynos_pcie_clear_irq_pulse() argument
273 val = exynos_pcie_readl(ep->mem_res->elbi_base, PCIE_IRQ_PULSE); in exynos_pcie_clear_irq_pulse()
274 exynos_pcie_writel(ep->mem_res->elbi_base, val, PCIE_IRQ_PULSE); in exynos_pcie_clear_irq_pulse()
277 static void exynos_pcie_enable_irq_pulse(struct exynos_pcie *ep) in exynos_pcie_enable_irq_pulse() argument
284 exynos_pcie_writel(ep->mem_res->elbi_base, val, PCIE_IRQ_EN_PULSE); in exynos_pcie_enable_irq_pulse()
289 struct exynos_pcie *ep = arg; in exynos_pcie_irq_handler() local
291 exynos_pcie_clear_irq_pulse(ep); in exynos_pcie_irq_handler()
295 static void exynos_pcie_msi_init(struct exynos_pcie *ep) in exynos_pcie_msi_init() argument
297 struct dw_pcie *pci = ep->pci; in exynos_pcie_msi_init()
298 struct pcie_port *pp = &pci->pp; in exynos_pcie_msi_init()
304 val = exynos_pcie_readl(ep->mem_res->elbi_base, PCIE_IRQ_EN_LEVEL); in exynos_pcie_msi_init()
306 exynos_pcie_writel(ep->mem_res->elbi_base, val, PCIE_IRQ_EN_LEVEL); in exynos_pcie_msi_init()
309 static void exynos_pcie_enable_interrupts(struct exynos_pcie *ep) in exynos_pcie_enable_interrupts() argument
311 exynos_pcie_enable_irq_pulse(ep); in exynos_pcie_enable_interrupts()
314 exynos_pcie_msi_init(ep); in exynos_pcie_enable_interrupts()
320 struct exynos_pcie *ep = to_exynos_pcie(pci); in exynos_pcie_read_dbi() local
323 exynos_pcie_sideband_dbi_r_mode(ep, true); in exynos_pcie_read_dbi()
325 exynos_pcie_sideband_dbi_r_mode(ep, false); in exynos_pcie_read_dbi()
332 struct exynos_pcie *ep = to_exynos_pcie(pci); in exynos_pcie_write_dbi() local
334 exynos_pcie_sideband_dbi_w_mode(ep, true); in exynos_pcie_write_dbi()
336 exynos_pcie_sideband_dbi_w_mode(ep, false); in exynos_pcie_write_dbi()
342 struct dw_pcie *pci = to_dw_pcie_from_pp(bus->sysdata); in exynos_pcie_rd_own_conf()
356 struct dw_pcie *pci = to_dw_pcie_from_pp(bus->sysdata); in exynos_pcie_wr_own_conf()
372 struct exynos_pcie *ep = to_exynos_pcie(pci); in exynos_pcie_link_up() local
375 val = exynos_pcie_readl(ep->mem_res->elbi_base, PCIE_ELBI_RDLH_LINKUP); in exynos_pcie_link_up()
385 struct exynos_pcie *ep = to_exynos_pcie(pci); in exynos_pcie_host_init() local
387 pp->bridge->ops = &exynos_pci_ops; in exynos_pcie_host_init()
389 exynos_pcie_establish_link(ep); in exynos_pcie_host_init()
390 exynos_pcie_enable_interrupts(ep); in exynos_pcie_host_init()
399 static int __init exynos_add_pcie_port(struct exynos_pcie *ep, in exynos_add_pcie_port() argument
402 struct dw_pcie *pci = ep->pci; in exynos_add_pcie_port()
403 struct pcie_port *pp = &pci->pp; in exynos_add_pcie_port()
404 struct device *dev = &pdev->dev; in exynos_add_pcie_port()
407 pp->irq = platform_get_irq(pdev, 1); in exynos_add_pcie_port()
408 if (pp->irq < 0) in exynos_add_pcie_port()
409 return pp->irq; in exynos_add_pcie_port()
411 ret = devm_request_irq(dev, pp->irq, exynos_pcie_irq_handler, in exynos_add_pcie_port()
412 IRQF_SHARED, "exynos-pcie", ep); in exynos_add_pcie_port()
419 pp->msi_irq = platform_get_irq(pdev, 0); in exynos_add_pcie_port()
420 if (pp->msi_irq < 0) in exynos_add_pcie_port()
421 return pp->msi_irq; in exynos_add_pcie_port()
424 pp->ops = &exynos_pcie_host_ops; in exynos_add_pcie_port()
443 struct device *dev = &pdev->dev; in exynos_pcie_probe()
445 struct exynos_pcie *ep; in exynos_pcie_probe() local
446 struct device_node *np = dev->of_node; in exynos_pcie_probe()
449 ep = devm_kzalloc(dev, sizeof(*ep), GFP_KERNEL); in exynos_pcie_probe()
450 if (!ep) in exynos_pcie_probe()
451 return -ENOMEM; in exynos_pcie_probe()
455 return -ENOMEM; in exynos_pcie_probe()
457 pci->dev = dev; in exynos_pcie_probe()
458 pci->ops = &dw_pcie_ops; in exynos_pcie_probe()
460 ep->pci = pci; in exynos_pcie_probe()
461 ep->ops = (const struct exynos_pcie_ops *) in exynos_pcie_probe()
464 ep->reset_gpio = of_get_named_gpio(np, "reset-gpio", 0); in exynos_pcie_probe()
466 ep->phy = devm_of_phy_get(dev, np, NULL); in exynos_pcie_probe()
467 if (IS_ERR(ep->phy)) { in exynos_pcie_probe()
468 if (PTR_ERR(ep->phy) != -ENODEV) in exynos_pcie_probe()
469 return PTR_ERR(ep->phy); in exynos_pcie_probe()
471 ep->phy = NULL; in exynos_pcie_probe()
474 if (ep->ops && ep->ops->get_mem_resources) { in exynos_pcie_probe()
475 ret = ep->ops->get_mem_resources(pdev, ep); in exynos_pcie_probe()
480 if (ep->ops && ep->ops->get_clk_resources && in exynos_pcie_probe()
481 ep->ops->init_clk_resources) { in exynos_pcie_probe()
482 ret = ep->ops->get_clk_resources(ep); in exynos_pcie_probe()
485 ret = ep->ops->init_clk_resources(ep); in exynos_pcie_probe()
490 platform_set_drvdata(pdev, ep); in exynos_pcie_probe()
492 ret = exynos_add_pcie_port(ep, pdev); in exynos_pcie_probe()
499 phy_exit(ep->phy); in exynos_pcie_probe()
501 if (ep->ops && ep->ops->deinit_clk_resources) in exynos_pcie_probe()
502 ep->ops->deinit_clk_resources(ep); in exynos_pcie_probe()
508 struct exynos_pcie *ep = platform_get_drvdata(pdev); in exynos_pcie_remove() local
510 if (ep->ops && ep->ops->deinit_clk_resources) in exynos_pcie_remove()
511 ep->ops->deinit_clk_resources(ep); in exynos_pcie_remove()
518 .compatible = "samsung,exynos5440-pcie",
527 .name = "exynos-pcie",
532 /* Exynos PCIe driver does not allow module unload */