Lines Matching +full:pci +full:- +full:dev

1 // SPDX-License-Identifier: GPL-2.0
3 * pcie-dra7xx - PCIe controller driver for TI DRA7xx SoCs
5 * Copyright (C) 2013-2014 Texas Instruments Incorporated - https://www.ti.com
22 #include <linux/pci.h>
32 #include "../../pci.h"
33 #include "pcie-designware.h"
89 struct dw_pcie *pci; member
91 int phy_count; /* DT phy-names count */
103 #define to_dra7xx_pcie(x) dev_get_drvdata((x)->dev)
107 return readl(pcie->base + offset); in dra7xx_pcie_readl()
113 writel(value, pcie->base + offset); in dra7xx_pcie_writel()
116 static u64 dra7xx_pcie_cpu_addr_fixup(struct dw_pcie *pci, u64 pci_addr) in dra7xx_pcie_cpu_addr_fixup() argument
121 static int dra7xx_pcie_link_up(struct dw_pcie *pci) in dra7xx_pcie_link_up() argument
123 struct dra7xx_pcie *dra7xx = to_dra7xx_pcie(pci); in dra7xx_pcie_link_up()
129 static void dra7xx_pcie_stop_link(struct dw_pcie *pci) in dra7xx_pcie_stop_link() argument
131 struct dra7xx_pcie *dra7xx = to_dra7xx_pcie(pci); in dra7xx_pcie_stop_link()
139 static int dra7xx_pcie_establish_link(struct dw_pcie *pci) in dra7xx_pcie_establish_link() argument
141 struct dra7xx_pcie *dra7xx = to_dra7xx_pcie(pci); in dra7xx_pcie_establish_link()
142 struct device *dev = pci->dev; in dra7xx_pcie_establish_link() local
145 if (dw_pcie_link_up(pci)) { in dra7xx_pcie_establish_link()
146 dev_err(dev, "link is already up\n"); in dra7xx_pcie_establish_link()
183 struct dw_pcie *pci = to_dw_pcie_from_pp(pp); in dra7xx_pcie_host_init() local
184 struct dra7xx_pcie *dra7xx = to_dra7xx_pcie(pci); in dra7xx_pcie_host_init()
195 irq_set_chip_data(irq, domain->host_data); in dra7xx_pcie_intx_map()
207 struct dw_pcie *pci = to_dw_pcie_from_pp(pp); in dra7xx_pcie_handle_msi() local
211 val = dw_pcie_readl_dbi(pci, PCIE_MSI_INTR0_STATUS + in dra7xx_pcie_handle_msi()
218 generic_handle_domain_irq(pp->irq_domain, in dra7xx_pcie_handle_msi()
229 struct dw_pcie *pci = to_dw_pcie_from_pp(pp); in dra7xx_pcie_handle_msi_irq() local
232 num_ctrls = pp->num_vectors / MAX_MSI_IRQS_PER_CTRL; in dra7xx_pcie_handle_msi_irq()
250 dev_warn_ratelimited(pci->dev, in dra7xx_pcie_handle_msi_irq()
259 struct dw_pcie *pci; in dra7xx_pcie_msi_irq_handler() local
266 pci = to_dw_pcie_from_pp(pp); in dra7xx_pcie_msi_irq_handler()
267 dra7xx = to_dra7xx_pcie(pci); in dra7xx_pcie_msi_irq_handler()
281 generic_handle_domain_irq(dra7xx->irq_domain, bit); in dra7xx_pcie_msi_irq_handler()
291 struct dw_pcie *pci = dra7xx->pci; in dra7xx_pcie_irq_handler() local
292 struct device *dev = pci->dev; in dra7xx_pcie_irq_handler() local
293 struct dw_pcie_ep *ep = &pci->ep; in dra7xx_pcie_irq_handler()
299 dev_dbg(dev, "System Error\n"); in dra7xx_pcie_irq_handler()
302 dev_dbg(dev, "Fatal Error\n"); in dra7xx_pcie_irq_handler()
305 dev_dbg(dev, "Non Fatal Error\n"); in dra7xx_pcie_irq_handler()
308 dev_dbg(dev, "Correctable Error\n"); in dra7xx_pcie_irq_handler()
311 dev_dbg(dev, "AXI tag lookup fatal Error\n"); in dra7xx_pcie_irq_handler()
314 dev_dbg(dev, "ECRC Error\n"); in dra7xx_pcie_irq_handler()
317 dev_dbg(dev, in dra7xx_pcie_irq_handler()
318 "Power Management Event Turn-Off message received\n"); in dra7xx_pcie_irq_handler()
321 dev_dbg(dev, in dra7xx_pcie_irq_handler()
322 "Power Management Turn-Off Ack message received\n"); in dra7xx_pcie_irq_handler()
325 dev_dbg(dev, "PM Power Management Event message received\n"); in dra7xx_pcie_irq_handler()
328 dev_dbg(dev, "Link Request Reset\n"); in dra7xx_pcie_irq_handler()
331 if (dra7xx->mode == DW_PCIE_EP_TYPE) in dra7xx_pcie_irq_handler()
333 dev_dbg(dev, "Link-up state change\n"); in dra7xx_pcie_irq_handler()
337 dev_dbg(dev, "CFG 'Bus Master Enable' change\n"); in dra7xx_pcie_irq_handler()
340 dev_dbg(dev, "CFG 'Memory Space Enable' change\n"); in dra7xx_pcie_irq_handler()
349 struct dw_pcie *pci = to_dw_pcie_from_pp(pp); in dra7xx_pcie_init_irq_domain() local
350 struct device *dev = pci->dev; in dra7xx_pcie_init_irq_domain() local
351 struct dra7xx_pcie *dra7xx = to_dra7xx_pcie(pci); in dra7xx_pcie_init_irq_domain()
352 struct device_node *node = dev->of_node; in dra7xx_pcie_init_irq_domain()
356 dev_err(dev, "No PCIe Intc node found\n"); in dra7xx_pcie_init_irq_domain()
357 return -ENODEV; in dra7xx_pcie_init_irq_domain()
360 irq_set_chained_handler_and_data(pp->irq, dra7xx_pcie_msi_irq_handler, in dra7xx_pcie_init_irq_domain()
362 dra7xx->irq_domain = irq_domain_add_linear(pcie_intc_node, PCI_NUM_INTX, in dra7xx_pcie_init_irq_domain()
365 if (!dra7xx->irq_domain) { in dra7xx_pcie_init_irq_domain()
366 dev_err(dev, "Failed to get a INTx IRQ domain\n"); in dra7xx_pcie_init_irq_domain()
367 return -ENODEV; in dra7xx_pcie_init_irq_domain()
379 struct dw_pcie *pci = to_dw_pcie_from_ep(ep); in dra7xx_pcie_ep_init() local
380 struct dra7xx_pcie *dra7xx = to_dra7xx_pcie(pci); in dra7xx_pcie_ep_init()
384 dw_pcie_ep_reset_bar(pci, bar); in dra7xx_pcie_ep_init()
401 reg = (interrupt_num - 1) << MSI_VECTOR_SHIFT; in dra7xx_pcie_raise_msi_irq()
409 struct dw_pcie *pci = to_dw_pcie_from_ep(ep); in dra7xx_pcie_raise_irq() local
410 struct dra7xx_pcie *dra7xx = to_dra7xx_pcie(pci); in dra7xx_pcie_raise_irq()
420 dev_err(pci->dev, "UNKNOWN IRQ type\n"); in dra7xx_pcie_raise_irq()
449 struct device *dev = &pdev->dev; in dra7xx_add_pcie_ep() local
450 struct dw_pcie *pci = dra7xx->pci; in dra7xx_add_pcie_ep() local
452 ep = &pci->ep; in dra7xx_add_pcie_ep()
453 ep->ops = &pcie_ep_ops; in dra7xx_add_pcie_ep()
455 pci->dbi_base = devm_platform_ioremap_resource_byname(pdev, "ep_dbics"); in dra7xx_add_pcie_ep()
456 if (IS_ERR(pci->dbi_base)) in dra7xx_add_pcie_ep()
457 return PTR_ERR(pci->dbi_base); in dra7xx_add_pcie_ep()
459 pci->dbi_base2 = in dra7xx_add_pcie_ep()
461 if (IS_ERR(pci->dbi_base2)) in dra7xx_add_pcie_ep()
462 return PTR_ERR(pci->dbi_base2); in dra7xx_add_pcie_ep()
466 dev_err(dev, "failed to initialize endpoint\n"); in dra7xx_add_pcie_ep()
477 struct dw_pcie *pci = dra7xx->pci; in dra7xx_add_pcie_port() local
478 struct dw_pcie_rp *pp = &pci->pp; in dra7xx_add_pcie_port()
479 struct device *dev = pci->dev; in dra7xx_add_pcie_port() local
481 pp->irq = platform_get_irq(pdev, 1); in dra7xx_add_pcie_port()
482 if (pp->irq < 0) in dra7xx_add_pcie_port()
483 return pp->irq; in dra7xx_add_pcie_port()
486 pp->msi_irq[0] = -ENODEV; in dra7xx_add_pcie_port()
492 pci->dbi_base = devm_platform_ioremap_resource_byname(pdev, "rc_dbics"); in dra7xx_add_pcie_port()
493 if (IS_ERR(pci->dbi_base)) in dra7xx_add_pcie_port()
494 return PTR_ERR(pci->dbi_base); in dra7xx_add_pcie_port()
496 pp->ops = &dra7xx_pcie_host_ops; in dra7xx_add_pcie_port()
500 dev_err(dev, "failed to initialize host\n"); in dra7xx_add_pcie_port()
516 int phy_count = dra7xx->phy_count; in dra7xx_pcie_disable_phy()
518 while (phy_count--) { in dra7xx_pcie_disable_phy()
519 phy_power_off(dra7xx->phy[phy_count]); in dra7xx_pcie_disable_phy()
520 phy_exit(dra7xx->phy[phy_count]); in dra7xx_pcie_disable_phy()
526 int phy_count = dra7xx->phy_count; in dra7xx_pcie_enable_phy()
531 ret = phy_set_mode(dra7xx->phy[i], PHY_MODE_PCIE); in dra7xx_pcie_enable_phy()
535 ret = phy_init(dra7xx->phy[i]); in dra7xx_pcie_enable_phy()
539 ret = phy_power_on(dra7xx->phy[i]); in dra7xx_pcie_enable_phy()
541 phy_exit(dra7xx->phy[i]); in dra7xx_pcie_enable_phy()
549 while (--i >= 0) { in dra7xx_pcie_enable_phy()
550 phy_power_off(dra7xx->phy[i]); in dra7xx_pcie_enable_phy()
551 phy_exit(dra7xx->phy[i]); in dra7xx_pcie_enable_phy()
587 .compatible = "ti,dra7-pcie",
591 .compatible = "ti,dra7-pcie-ep",
595 .compatible = "ti,dra746-pcie-rc",
599 .compatible = "ti,dra726-pcie-rc",
603 .compatible = "ti,dra746-pcie-ep",
607 .compatible = "ti,dra726-pcie-ep",
618 * Access to the PCIe slave port that are not 32-bit aligned will result
620 * byte and half-word accesses are not possible to byte offset 0x1, 0x2, or
625 static int dra7xx_pcie_unaligned_memaccess(struct device *dev) in dra7xx_pcie_unaligned_memaccess() argument
628 struct device_node *np = dev->of_node; in dra7xx_pcie_unaligned_memaccess()
633 "ti,syscon-unaligned-access"); in dra7xx_pcie_unaligned_memaccess()
635 dev_dbg(dev, "can't get ti,syscon-unaligned-access\n"); in dra7xx_pcie_unaligned_memaccess()
636 return -EINVAL; in dra7xx_pcie_unaligned_memaccess()
639 ret = of_parse_phandle_with_fixed_args(np, "ti,syscon-unaligned-access", in dra7xx_pcie_unaligned_memaccess()
642 dev_err(dev, "failed to parse ti,syscon-unaligned-access\n"); in dra7xx_pcie_unaligned_memaccess()
649 dev_err(dev, "failed to enable unaligned access\n"); in dra7xx_pcie_unaligned_memaccess()
656 static int dra7xx_pcie_configure_two_lane(struct device *dev, in dra7xx_pcie_configure_two_lane() argument
659 struct device_node *np = dev->of_node; in dra7xx_pcie_configure_two_lane()
665 pcie_syscon = syscon_regmap_lookup_by_phandle(np, "ti,syscon-lane-sel"); in dra7xx_pcie_configure_two_lane()
667 dev_err(dev, "unable to get ti,syscon-lane-sel\n"); in dra7xx_pcie_configure_two_lane()
668 return -EINVAL; in dra7xx_pcie_configure_two_lane()
671 if (of_property_read_u32_index(np, "ti,syscon-lane-sel", 1, in dra7xx_pcie_configure_two_lane()
673 dev_err(dev, "couldn't get lane selection reg offset\n"); in dra7xx_pcie_configure_two_lane()
674 return -EINVAL; in dra7xx_pcie_configure_two_lane()
694 struct dw_pcie *pci; in dra7xx_pcie_probe() local
696 struct device *dev = &pdev->dev; in dra7xx_pcie_probe() local
697 struct device_node *np = dev->of_node; in dra7xx_pcie_probe()
704 data = of_device_get_match_data(dev); in dra7xx_pcie_probe()
706 return -EINVAL; in dra7xx_pcie_probe()
708 mode = (enum dw_pcie_device_mode)data->mode; in dra7xx_pcie_probe()
709 b1co_mode_sel_mask = data->b1co_mode_sel_mask; in dra7xx_pcie_probe()
711 dra7xx = devm_kzalloc(dev, sizeof(*dra7xx), GFP_KERNEL); in dra7xx_pcie_probe()
713 return -ENOMEM; in dra7xx_pcie_probe()
715 pci = devm_kzalloc(dev, sizeof(*pci), GFP_KERNEL); in dra7xx_pcie_probe()
716 if (!pci) in dra7xx_pcie_probe()
717 return -ENOMEM; in dra7xx_pcie_probe()
719 pci->dev = dev; in dra7xx_pcie_probe()
720 pci->ops = &dw_pcie_ops; in dra7xx_pcie_probe()
730 phy_count = of_property_count_strings(np, "phy-names"); in dra7xx_pcie_probe()
732 dev_err(dev, "unable to find the strings\n"); in dra7xx_pcie_probe()
736 phy = devm_kcalloc(dev, phy_count, sizeof(*phy), GFP_KERNEL); in dra7xx_pcie_probe()
738 return -ENOMEM; in dra7xx_pcie_probe()
740 link = devm_kcalloc(dev, phy_count, sizeof(*link), GFP_KERNEL); in dra7xx_pcie_probe()
742 return -ENOMEM; in dra7xx_pcie_probe()
744 dra7xx->clk = devm_clk_get_optional(dev, NULL); in dra7xx_pcie_probe()
745 if (IS_ERR(dra7xx->clk)) in dra7xx_pcie_probe()
746 return dev_err_probe(dev, PTR_ERR(dra7xx->clk), in dra7xx_pcie_probe()
749 ret = clk_prepare_enable(dra7xx->clk); in dra7xx_pcie_probe()
754 snprintf(name, sizeof(name), "pcie-phy%d", i); in dra7xx_pcie_probe()
755 phy[i] = devm_phy_get(dev, name); in dra7xx_pcie_probe()
759 link[i] = device_link_add(dev, &phy[i]->dev, DL_FLAG_STATELESS); in dra7xx_pcie_probe()
761 ret = -EINVAL; in dra7xx_pcie_probe()
766 dra7xx->base = base; in dra7xx_pcie_probe()
767 dra7xx->phy = phy; in dra7xx_pcie_probe()
768 dra7xx->pci = pci; in dra7xx_pcie_probe()
769 dra7xx->phy_count = phy_count; in dra7xx_pcie_probe()
772 ret = dra7xx_pcie_configure_two_lane(dev, b1co_mode_sel_mask); in dra7xx_pcie_probe()
774 dra7xx->phy_count = 1; /* Fallback to x1 lane mode */ in dra7xx_pcie_probe()
779 dev_err(dev, "failed to enable phy\n"); in dra7xx_pcie_probe()
785 pm_runtime_enable(dev); in dra7xx_pcie_probe()
786 ret = pm_runtime_get_sync(dev); in dra7xx_pcie_probe()
788 dev_err(dev, "pm_runtime_get_sync failed\n"); in dra7xx_pcie_probe()
792 reset = devm_gpiod_get_optional(dev, NULL, GPIOD_OUT_HIGH); in dra7xx_pcie_probe()
795 dev_err(&pdev->dev, "gpio request failed, ret %d\n", ret); in dra7xx_pcie_probe()
806 ret = -ENODEV; in dra7xx_pcie_probe()
813 ret = dra7xx_pcie_unaligned_memaccess(dev); in dra7xx_pcie_probe()
815 dev_err(dev, "WA for Errata i870 not applied\n"); in dra7xx_pcie_probe()
823 ret = -ENODEV; in dra7xx_pcie_probe()
830 ret = dra7xx_pcie_unaligned_memaccess(dev); in dra7xx_pcie_probe()
839 dev_err(dev, "INVALID device type %d\n", mode); in dra7xx_pcie_probe()
841 dra7xx->mode = mode; in dra7xx_pcie_probe()
843 ret = devm_request_threaded_irq(dev, irq, NULL, dra7xx_pcie_irq_handler, in dra7xx_pcie_probe()
845 "dra7xx-pcie-main", dra7xx); in dra7xx_pcie_probe()
847 dev_err(dev, "failed to request irq\n"); in dra7xx_pcie_probe()
855 pm_runtime_put(dev); in dra7xx_pcie_probe()
856 pm_runtime_disable(dev); in dra7xx_pcie_probe()
860 while (--i >= 0) in dra7xx_pcie_probe()
866 static int dra7xx_pcie_suspend(struct device *dev) in dra7xx_pcie_suspend() argument
868 struct dra7xx_pcie *dra7xx = dev_get_drvdata(dev); in dra7xx_pcie_suspend()
869 struct dw_pcie *pci = dra7xx->pci; in dra7xx_pcie_suspend() local
872 if (dra7xx->mode != DW_PCIE_RC_TYPE) in dra7xx_pcie_suspend()
876 val = dw_pcie_readl_dbi(pci, PCI_COMMAND); in dra7xx_pcie_suspend()
878 dw_pcie_writel_dbi(pci, PCI_COMMAND, val); in dra7xx_pcie_suspend()
883 static int dra7xx_pcie_resume(struct device *dev) in dra7xx_pcie_resume() argument
885 struct dra7xx_pcie *dra7xx = dev_get_drvdata(dev); in dra7xx_pcie_resume()
886 struct dw_pcie *pci = dra7xx->pci; in dra7xx_pcie_resume() local
889 if (dra7xx->mode != DW_PCIE_RC_TYPE) in dra7xx_pcie_resume()
893 val = dw_pcie_readl_dbi(pci, PCI_COMMAND); in dra7xx_pcie_resume()
895 dw_pcie_writel_dbi(pci, PCI_COMMAND, val); in dra7xx_pcie_resume()
900 static int dra7xx_pcie_suspend_noirq(struct device *dev) in dra7xx_pcie_suspend_noirq() argument
902 struct dra7xx_pcie *dra7xx = dev_get_drvdata(dev); in dra7xx_pcie_suspend_noirq()
909 static int dra7xx_pcie_resume_noirq(struct device *dev) in dra7xx_pcie_resume_noirq() argument
911 struct dra7xx_pcie *dra7xx = dev_get_drvdata(dev); in dra7xx_pcie_resume_noirq()
916 dev_err(dev, "failed to enable phy\n"); in dra7xx_pcie_resume_noirq()
925 struct device *dev = &pdev->dev; in dra7xx_pcie_shutdown() local
926 struct dra7xx_pcie *dra7xx = dev_get_drvdata(dev); in dra7xx_pcie_shutdown()
929 dra7xx_pcie_stop_link(dra7xx->pci); in dra7xx_pcie_shutdown()
931 ret = pm_runtime_put_sync(dev); in dra7xx_pcie_shutdown()
933 dev_dbg(dev, "pm_runtime_put_sync failed\n"); in dra7xx_pcie_shutdown()
935 pm_runtime_disable(dev); in dra7xx_pcie_shutdown()
938 clk_disable_unprepare(dra7xx->clk); in dra7xx_pcie_shutdown()
950 .name = "dra7-pcie",