From d3d4d028afb785e52c55024d779089654f8302e7 Mon Sep 17 00:00:00 2001 From: Ansuel Smith Date: Tue, 1 Sep 2020 14:49:54 +0200 Subject: PCI: qcom: Make sure PCIe is reset before init for rev 2.1.0 Qsdk U-Boot can incorrectly leave the PCIe interface in an undefined state if bootm command is used instead of bootipq. This is caused by the not deinit of PCIe when bootm is called. Reset the PCIe before init anyway to fix this U-Boot bug. Link: https://lore.kernel.org/r/20200901124955.137-1-ansuelsmth@gmail.com Fixes: 82a823833f4e ("PCI: qcom: Add Qualcomm PCIe controller driver") Signed-off-by: Ansuel Smith Signed-off-by: Lorenzo Pieralisi Reviewed-by: Bjorn Andersson Cc: stable@vger.kernel.org # v4.19+ --- drivers/pci/controller/dwc/pcie-qcom.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'drivers/pci/controller/dwc/pcie-qcom.c') diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c index 3aac77a295ba..82336bbaf8dc 100644 --- a/drivers/pci/controller/dwc/pcie-qcom.c +++ b/drivers/pci/controller/dwc/pcie-qcom.c @@ -302,6 +302,9 @@ static void qcom_pcie_deinit_2_1_0(struct qcom_pcie *pcie) reset_control_assert(res->por_reset); reset_control_assert(res->ext_reset); reset_control_assert(res->phy_reset); + + writel(1, pcie->parf + PCIE20_PARF_PHY_CTRL); + regulator_bulk_disable(ARRAY_SIZE(res->supplies), res->supplies); } @@ -314,6 +317,16 @@ static int qcom_pcie_init_2_1_0(struct qcom_pcie *pcie) u32 val; int ret; + /* reset the PCIe interface as uboot can leave it undefined state */ + reset_control_assert(res->pci_reset); + reset_control_assert(res->axi_reset); + reset_control_assert(res->ahb_reset); + reset_control_assert(res->por_reset); + reset_control_assert(res->ext_reset); + reset_control_assert(res->phy_reset); + + writel(1, pcie->parf + PCIE20_PARF_PHY_CTRL); + ret = regulator_bulk_enable(ARRAY_SIZE(res->supplies), res->supplies); if (ret < 0) { dev_err(dev, "cannot enable regulators\n"); -- cgit v1.2.3 From cf627713e3c08920cfc3ad401354109b5273409e Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Thu, 20 Aug 2020 21:54:01 -0600 Subject: PCI: dwc: Check CONFIG_PCI_MSI inside dw_pcie_msi_init() Move the IS_ENABLED(CONFIG_PCI_MSI) check into dw_pcie_msi_init() instead of duplicating it in all the drivers. Link: https://lore.kernel.org/r/20200821035420.380495-22-robh@kernel.org Signed-off-by: Rob Herring Signed-off-by: Lorenzo Pieralisi Cc: Richard Zhu Cc: Lucas Stach Cc: Lorenzo Pieralisi Cc: Bjorn Helgaas Cc: Shawn Guo Cc: Sascha Hauer Cc: Pengutronix Kernel Team Cc: Fabio Estevam Cc: NXP Linux Team Cc: Yue Wang Cc: Kevin Hilman Cc: Jesper Nilsson Cc: Jingoo Han Cc: Gustavo Pimentel Cc: Xiaowei Song Cc: Binghui Wang Cc: Stanimir Varbanov Cc: Andy Gross Cc: Bjorn Andersson Cc: Kunihiko Hayashi Cc: Masahiro Yamada Cc: linux-amlogic@lists.infradead.org Cc: linux-arm-kernel@axis.com Cc: linux-arm-msm@vger.kernel.org --- drivers/pci/controller/dwc/pci-imx6.c | 4 +--- drivers/pci/controller/dwc/pci-meson.c | 8 +------- drivers/pci/controller/dwc/pcie-artpec6.c | 11 +---------- drivers/pci/controller/dwc/pcie-designware-host.c | 3 +++ drivers/pci/controller/dwc/pcie-designware-plat.c | 4 +--- drivers/pci/controller/dwc/pcie-histb.c | 4 +--- drivers/pci/controller/dwc/pcie-kirin.c | 4 +--- drivers/pci/controller/dwc/pcie-qcom.c | 4 +--- drivers/pci/controller/dwc/pcie-uniphier.c | 3 +-- 9 files changed, 11 insertions(+), 34 deletions(-) (limited to 'drivers/pci/controller/dwc/pcie-qcom.c') diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c index 90df28c7cb0c..68a09680e728 100644 --- a/drivers/pci/controller/dwc/pci-imx6.c +++ b/drivers/pci/controller/dwc/pci-imx6.c @@ -847,9 +847,7 @@ static int imx6_pcie_host_init(struct pcie_port *pp) imx6_setup_phy_mpll(imx6_pcie); dw_pcie_setup_rc(pp); imx6_pcie_establish_link(imx6_pcie); - - if (IS_ENABLED(CONFIG_PCI_MSI)) - dw_pcie_msi_init(pp); + dw_pcie_msi_init(pp); return 0; } diff --git a/drivers/pci/controller/dwc/pci-meson.c b/drivers/pci/controller/dwc/pci-meson.c index f4d822190359..67ca73528aad 100644 --- a/drivers/pci/controller/dwc/pci-meson.c +++ b/drivers/pci/controller/dwc/pci-meson.c @@ -377,12 +377,6 @@ static int meson_pcie_establish_link(struct meson_pcie *mp) return dw_pcie_wait_for_link(pci); } -static void meson_pcie_enable_interrupts(struct meson_pcie *mp) -{ - if (IS_ENABLED(CONFIG_PCI_MSI)) - dw_pcie_msi_init(&mp->pci.pp); -} - static int meson_pcie_rd_own_conf(struct pci_bus *bus, u32 devfn, int where, int size, u32 *val) { @@ -466,7 +460,7 @@ static int meson_pcie_host_init(struct pcie_port *pp) if (ret) return ret; - meson_pcie_enable_interrupts(mp); + dw_pcie_msi_init(pp); return 0; } diff --git a/drivers/pci/controller/dwc/pcie-artpec6.c b/drivers/pci/controller/dwc/pcie-artpec6.c index 97d50bb50f06..86f4d66d8587 100644 --- a/drivers/pci/controller/dwc/pcie-artpec6.c +++ b/drivers/pci/controller/dwc/pcie-artpec6.c @@ -346,15 +346,6 @@ static void artpec6_pcie_deassert_core_reset(struct artpec6_pcie *artpec6_pcie) usleep_range(100, 200); } -static void artpec6_pcie_enable_interrupts(struct artpec6_pcie *artpec6_pcie) -{ - struct dw_pcie *pci = artpec6_pcie->pci; - struct pcie_port *pp = &pci->pp; - - if (IS_ENABLED(CONFIG_PCI_MSI)) - dw_pcie_msi_init(pp); -} - static int artpec6_pcie_host_init(struct pcie_port *pp) { struct dw_pcie *pci = to_dw_pcie_from_pp(pp); @@ -368,7 +359,7 @@ static int artpec6_pcie_host_init(struct pcie_port *pp) dw_pcie_setup_rc(pp); artpec6_pcie_establish_link(pci); dw_pcie_wait_for_link(pci); - artpec6_pcie_enable_interrupts(artpec6_pcie); + dw_pcie_msi_init(pp); return 0; } diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c index 38d7c89dbb21..4f21d95b4077 100644 --- a/drivers/pci/controller/dwc/pcie-designware-host.c +++ b/drivers/pci/controller/dwc/pcie-designware-host.c @@ -276,6 +276,9 @@ void dw_pcie_msi_init(struct pcie_port *pp) struct device *dev = pci->dev; u64 msi_target; + if (!IS_ENABLED(CONFIG_PCI_MSI)) + return; + pp->msi_page = alloc_page(GFP_KERNEL); pp->msi_data = dma_map_page(dev, pp->msi_page, 0, PAGE_SIZE, DMA_FROM_DEVICE); diff --git a/drivers/pci/controller/dwc/pcie-designware-plat.c b/drivers/pci/controller/dwc/pcie-designware-plat.c index 712456f6ce36..e3e300669ed5 100644 --- a/drivers/pci/controller/dwc/pcie-designware-plat.c +++ b/drivers/pci/controller/dwc/pcie-designware-plat.c @@ -39,9 +39,7 @@ static int dw_plat_pcie_host_init(struct pcie_port *pp) dw_pcie_setup_rc(pp); dw_pcie_wait_for_link(pci); - - if (IS_ENABLED(CONFIG_PCI_MSI)) - dw_pcie_msi_init(pp); + dw_pcie_msi_init(pp); return 0; } diff --git a/drivers/pci/controller/dwc/pcie-histb.c b/drivers/pci/controller/dwc/pcie-histb.c index af1deae2b15d..afc1abbe49aa 100644 --- a/drivers/pci/controller/dwc/pcie-histb.c +++ b/drivers/pci/controller/dwc/pcie-histb.c @@ -202,9 +202,7 @@ static int histb_pcie_host_init(struct pcie_port *pp) pp->bridge->ops = &histb_pci_ops; histb_pcie_establish_link(pp); - - if (IS_ENABLED(CONFIG_PCI_MSI)) - dw_pcie_msi_init(pp); + dw_pcie_msi_init(pp); return 0; } diff --git a/drivers/pci/controller/dwc/pcie-kirin.c b/drivers/pci/controller/dwc/pcie-kirin.c index 8a01ab0a4a65..6f01ae013326 100644 --- a/drivers/pci/controller/dwc/pcie-kirin.c +++ b/drivers/pci/controller/dwc/pcie-kirin.c @@ -429,9 +429,7 @@ static int kirin_pcie_host_init(struct pcie_port *pp) pp->bridge->ops = &kirin_pci_ops; kirin_pcie_establish_link(pp); - - if (IS_ENABLED(CONFIG_PCI_MSI)) - dw_pcie_msi_init(pp); + dw_pcie_msi_init(pp); return 0; } diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c index 3aac77a295ba..fe7fc2ccd76d 100644 --- a/drivers/pci/controller/dwc/pcie-qcom.c +++ b/drivers/pci/controller/dwc/pcie-qcom.c @@ -1280,9 +1280,7 @@ static int qcom_pcie_host_init(struct pcie_port *pp) } dw_pcie_setup_rc(pp); - - if (IS_ENABLED(CONFIG_PCI_MSI)) - dw_pcie_msi_init(pp); + dw_pcie_msi_init(pp); qcom_ep_reset_deassert(pcie); diff --git a/drivers/pci/controller/dwc/pcie-uniphier.c b/drivers/pci/controller/dwc/pcie-uniphier.c index 3a7f403b57b8..48176265c867 100644 --- a/drivers/pci/controller/dwc/pcie-uniphier.c +++ b/drivers/pci/controller/dwc/pcie-uniphier.c @@ -322,8 +322,7 @@ static int uniphier_pcie_host_init(struct pcie_port *pp) if (ret) return ret; - if (IS_ENABLED(CONFIG_PCI_MSI)) - dw_pcie_msi_init(pp); + dw_pcie_msi_init(pp); return 0; } -- cgit v1.2.3 From 7b87ddc04b364b94142d3b1295d92f1fe1145781 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Thu, 20 Aug 2020 21:54:09 -0600 Subject: PCI: dwc/qcom: Use common PCI register definitions The QCom driver has its own defines for common PCI config space registers. It also hard codes the capability register offsets which are discoverable. Convert it to use the standard register definitions. Link: https://lore.kernel.org/r/20200821035420.380495-30-robh@kernel.org Signed-off-by: Rob Herring Signed-off-by: Lorenzo Pieralisi Cc: Stanimir Varbanov Cc: Andy Gross Cc: Bjorn Andersson Cc: Lorenzo Pieralisi Cc: Bjorn Helgaas Cc: linux-arm-msm@vger.kernel.org --- drivers/pci/controller/dwc/pcie-qcom.c | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) (limited to 'drivers/pci/controller/dwc/pcie-qcom.c') diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c index fe7fc2ccd76d..d8d1fb7e0b8f 100644 --- a/drivers/pci/controller/dwc/pcie-qcom.c +++ b/drivers/pci/controller/dwc/pcie-qcom.c @@ -67,10 +67,6 @@ #define PCIE20_AXI_MSTR_RESP_COMP_CTRL1 0x81c #define CFG_BRIDGE_SB_INIT BIT(0) -#define PCIE20_CAP 0x70 -#define PCIE20_DEVICE_CONTROL2_STATUS2 (PCIE20_CAP + PCI_EXP_DEVCTL2) -#define PCIE20_CAP_LINK_CAPABILITIES (PCIE20_CAP + PCI_EXP_LNKCAP) -#define PCIE20_CAP_LINK_1 (PCIE20_CAP + 0x14) #define PCIE_CAP_LINK1_VAL 0x2FD7F #define PCIE20_PARF_Q2A_FLUSH 0x1AC @@ -1017,6 +1013,7 @@ static int qcom_pcie_init_2_3_3(struct qcom_pcie *pcie) struct qcom_pcie_resources_2_3_3 *res = &pcie->res.v2_3_3; struct dw_pcie *pci = pcie->pci; struct device *dev = pci->dev; + u16 offset = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP); int i, ret; u32 val; @@ -1092,14 +1089,14 @@ static int qcom_pcie_init_2_3_3(struct qcom_pcie *pcie) writel(PCI_COMMAND_MASTER, pci->dbi_base + PCI_COMMAND); writel(DBI_RO_WR_EN, pci->dbi_base + PCIE20_MISC_CONTROL_1_REG); - writel(PCIE_CAP_LINK1_VAL, pci->dbi_base + PCIE20_CAP_LINK_1); + writel(PCIE_CAP_LINK1_VAL, pci->dbi_base + offset + PCI_EXP_SLTCAP); - val = readl(pci->dbi_base + PCIE20_CAP_LINK_CAPABILITIES); + val = readl(pci->dbi_base + offset + PCI_EXP_LNKCAP); val &= ~PCI_EXP_LNKCAP_ASPMS; - writel(val, pci->dbi_base + PCIE20_CAP_LINK_CAPABILITIES); + writel(val, pci->dbi_base + offset + PCI_EXP_LNKCAP); - writel(PCI_EXP_DEVCTL2_COMP_TMOUT_DIS, pci->dbi_base + - PCIE20_DEVICE_CONTROL2_STATUS2); + writel(PCI_EXP_DEVCTL2_COMP_TMOUT_DIS, pci->dbi_base + offset + + PCI_EXP_DEVCTL2); return 0; @@ -1252,7 +1249,8 @@ static void qcom_pcie_post_deinit_2_7_0(struct qcom_pcie *pcie) static int qcom_pcie_link_up(struct dw_pcie *pci) { - u16 val = readw(pci->dbi_base + PCIE20_CAP + PCI_EXP_LNKSTA); + u16 offset = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP); + u16 val = readw(pci->dbi_base + offset + PCI_EXP_LNKSTA); return !!(val & PCI_EXP_LNKSTA_DLLLA); } -- cgit v1.2.3 From 39bc5006501cc31987f4fc249c5ce07286b84768 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Thu, 20 Aug 2020 21:54:14 -0600 Subject: PCI: dwc: Centralize link gen setting keystone would force gen2 if no DT property. Now it relies on the PCI_EXP_LNKCAP value. Link: https://lore.kernel.org/r/20200821035420.380495-35-robh@kernel.org Signed-off-by: Rob Herring Signed-off-by: Lorenzo Pieralisi Cc: Kishon Vijay Abraham I Cc: Lorenzo Pieralisi Cc: Bjorn Helgaas Cc: Richard Zhu Cc: Lucas Stach Cc: Shawn Guo Cc: Sascha Hauer Cc: Pengutronix Kernel Team Cc: Fabio Estevam Cc: NXP Linux Team Cc: Murali Karicheri Cc: Jingoo Han Cc: Gustavo Pimentel Cc: Stanimir Varbanov Cc: Andy Gross Cc: Bjorn Andersson Cc: Pratyush Anand Cc: Thierry Reding Cc: Jonathan Hunter Cc: linux-omap@vger.kernel.org Cc: linux-arm-kernel@lists.infradead.org Cc: linux-arm-msm@vger.kernel.org Cc: linux-tegra@vger.kernel.org --- drivers/pci/controller/dwc/pci-dra7xx.c | 26 ------------------ drivers/pci/controller/dwc/pci-imx6.c | 9 +++---- drivers/pci/controller/dwc/pci-keystone.c | 33 ----------------------- drivers/pci/controller/dwc/pcie-designware-ep.c | 11 ++++++-- drivers/pci/controller/dwc/pcie-designware-host.c | 3 +++ drivers/pci/controller/dwc/pcie-designware.c | 33 +++++++++++++---------- drivers/pci/controller/dwc/pcie-designware.h | 2 +- drivers/pci/controller/dwc/pcie-intel-gw.c | 13 +++------ drivers/pci/controller/dwc/pcie-qcom.c | 11 -------- drivers/pci/controller/dwc/pcie-spear13xx.c | 27 +------------------ drivers/pci/controller/dwc/pcie-tegra194.c | 23 ---------------- 11 files changed, 40 insertions(+), 151 deletions(-) (limited to 'drivers/pci/controller/dwc/pcie-qcom.c') diff --git a/drivers/pci/controller/dwc/pci-dra7xx.c b/drivers/pci/controller/dwc/pci-dra7xx.c index d42e0664f378..8f0b6d644e4b 100644 --- a/drivers/pci/controller/dwc/pci-dra7xx.c +++ b/drivers/pci/controller/dwc/pci-dra7xx.c @@ -89,7 +89,6 @@ struct dra7xx_pcie { void __iomem *base; /* DT ti_conf */ int phy_count; /* DT phy-names count */ struct phy **phy; - int link_gen; struct irq_domain *irq_domain; enum dw_pcie_device_mode mode; }; @@ -140,33 +139,12 @@ static int dra7xx_pcie_establish_link(struct dw_pcie *pci) struct dra7xx_pcie *dra7xx = to_dra7xx_pcie(pci); struct device *dev = pci->dev; u32 reg; - u32 exp_cap_off = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP); if (dw_pcie_link_up(pci)) { dev_err(dev, "link is already up\n"); return 0; } - if (dra7xx->link_gen == 1) { - dw_pcie_read(pci->dbi_base + exp_cap_off + PCI_EXP_LNKCAP, - 4, ®); - if ((reg & PCI_EXP_LNKCAP_SLS) != PCI_EXP_LNKCAP_SLS_2_5GB) { - reg &= ~((u32)PCI_EXP_LNKCAP_SLS); - reg |= PCI_EXP_LNKCAP_SLS_2_5GB; - dw_pcie_write(pci->dbi_base + exp_cap_off + - PCI_EXP_LNKCAP, 4, reg); - } - - dw_pcie_read(pci->dbi_base + exp_cap_off + PCI_EXP_LNKCTL2, - 2, ®); - if ((reg & PCI_EXP_LNKCAP_SLS) != PCI_EXP_LNKCAP_SLS_2_5GB) { - reg &= ~((u32)PCI_EXP_LNKCAP_SLS); - reg |= PCI_EXP_LNKCAP_SLS_2_5GB; - dw_pcie_write(pci->dbi_base + exp_cap_off + - PCI_EXP_LNKCTL2, 2, reg); - } - } - reg = dra7xx_pcie_readl(dra7xx, PCIECTRL_DRA7XX_CONF_DEVICE_CMD); reg |= LTSSM_EN; dra7xx_pcie_writel(dra7xx, PCIECTRL_DRA7XX_CONF_DEVICE_CMD, reg); @@ -935,10 +913,6 @@ static int __init dra7xx_pcie_probe(struct platform_device *pdev) reg &= ~LTSSM_EN; dra7xx_pcie_writel(dra7xx, PCIECTRL_DRA7XX_CONF_DEVICE_CMD, reg); - dra7xx->link_gen = of_pci_get_max_link_speed(np); - if (dra7xx->link_gen < 0 || dra7xx->link_gen > 2) - dra7xx->link_gen = 2; - switch (mode) { case DW_PCIE_RC_TYPE: if (!IS_ENABLED(CONFIG_PCI_DRA7XX_HOST)) { diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c index 9f6018d3d338..337c74cbdfdb 100644 --- a/drivers/pci/controller/dwc/pci-imx6.c +++ b/drivers/pci/controller/dwc/pci-imx6.c @@ -79,7 +79,6 @@ struct imx6_pcie { u32 tx_deemph_gen2_6db; u32 tx_swing_full; u32 tx_swing_low; - int link_gen; struct regulator *vpcie; void __iomem *phy_base; @@ -771,7 +770,7 @@ static int imx6_pcie_establish_link(struct imx6_pcie *imx6_pcie) if (ret) goto err_reset_phy; - if (imx6_pcie->link_gen == 2) { + if (pci->link_gen == 2) { /* Allow Gen2 mode after the link is up. */ tmp = dw_pcie_readl_dbi(pci, offset + PCI_EXP_LNKCAP); tmp &= ~PCI_EXP_LNKCAP_SLS; @@ -1153,10 +1152,8 @@ static int imx6_pcie_probe(struct platform_device *pdev) imx6_pcie->tx_swing_low = 127; /* Limit link speed */ - ret = of_property_read_u32(node, "fsl,max-link-speed", - &imx6_pcie->link_gen); - if (ret) - imx6_pcie->link_gen = 1; + pci->link_gen = 1; + ret = of_property_read_u32(node, "fsl,max-link-speed", &pci->link_gen); imx6_pcie->vpcie = devm_regulator_get_optional(&pdev->dev, "vpcie"); if (IS_ERR(imx6_pcie->vpcie)) { diff --git a/drivers/pci/controller/dwc/pci-keystone.c b/drivers/pci/controller/dwc/pci-keystone.c index 5fe36da0b7c6..b554812dace7 100644 --- a/drivers/pci/controller/dwc/pci-keystone.c +++ b/drivers/pci/controller/dwc/pci-keystone.c @@ -1107,32 +1107,6 @@ static int ks_pcie_am654_set_mode(struct device *dev, return 0; } -static void ks_pcie_set_link_speed(struct dw_pcie *pci, int link_speed) -{ - u32 val; - u32 offset = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP); - - dw_pcie_dbi_ro_wr_en(pci); - - val = dw_pcie_readl_dbi(pci, offset + PCI_EXP_LNKCAP); - if ((val & PCI_EXP_LNKCAP_SLS) != link_speed) { - val &= ~((u32)PCI_EXP_LNKCAP_SLS); - val |= link_speed; - dw_pcie_writel_dbi(pci, offset + PCI_EXP_LNKCAP, - val); - } - - val = dw_pcie_readl_dbi(pci, offset + PCI_EXP_LNKCTL2); - if ((val & PCI_EXP_LNKCAP_SLS) != link_speed) { - val &= ~((u32)PCI_EXP_LNKCAP_SLS); - val |= link_speed; - dw_pcie_writel_dbi(pci, offset + PCI_EXP_LNKCTL2, - val); - } - - dw_pcie_dbi_ro_wr_dis(pci); -} - static const struct ks_pcie_of_data ks_pcie_rc_of_data = { .host_ops = &ks_pcie_host_ops, .version = 0x365A, @@ -1185,7 +1159,6 @@ static int __init ks_pcie_probe(struct platform_device *pdev) unsigned int version; void __iomem *base; struct phy **phy; - int link_speed; u32 num_lanes; char name[10]; int ret; @@ -1320,12 +1293,6 @@ static int __init ks_pcie_probe(struct platform_device *pdev) goto err_get_sync; } - link_speed = of_pci_get_max_link_speed(np); - if (link_speed < 0) - link_speed = 2; - - ks_pcie_set_link_speed(pci, link_speed); - switch (mode) { case DW_PCIE_RC_TYPE: if (!IS_ENABLED(CONFIG_PCI_KEYSTONE_HOST)) { diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c b/drivers/pci/controller/dwc/pcie-designware-ep.c index 29f5c616c3bc..05415a82e9f4 100644 --- a/drivers/pci/controller/dwc/pcie-designware-ep.c +++ b/drivers/pci/controller/dwc/pcie-designware-ep.c @@ -12,6 +12,8 @@ #include #include +#include "../../pci.h" + void dw_pcie_ep_linkup(struct dw_pcie_ep *ep) { struct pci_epc *epc = ep->epc; @@ -519,18 +521,20 @@ int dw_pcie_ep_init_complete(struct dw_pcie_ep *ep) ep->msix_cap = dw_pcie_find_capability(pci, PCI_CAP_ID_MSIX); offset = dw_pcie_ep_find_ext_capability(pci, PCI_EXT_CAP_ID_REBAR); + + dw_pcie_dbi_ro_wr_en(pci); + if (offset) { reg = dw_pcie_readl_dbi(pci, offset + PCI_REBAR_CTRL); nbars = (reg & PCI_REBAR_CTRL_NBAR_MASK) >> PCI_REBAR_CTRL_NBAR_SHIFT; - dw_pcie_dbi_ro_wr_en(pci); for (i = 0; i < nbars; i++, offset += PCI_REBAR_CTRL) dw_pcie_writel_dbi(pci, offset + PCI_REBAR_CAP, 0x0); - dw_pcie_dbi_ro_wr_dis(pci); } dw_pcie_setup(pci); + dw_pcie_dbi_ro_wr_dis(pci); return 0; } @@ -591,6 +595,9 @@ int dw_pcie_ep_init(struct dw_pcie_ep *ep) return -ENOMEM; ep->outbound_addr = addr; + if (pci->link_gen < 1) + pci->link_gen = of_pci_get_max_link_speed(np); + epc = devm_pci_epc_create(dev, &epc_ops); if (IS_ERR(epc)) { dev_err(dev, "Failed to create epc device\n"); diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c index 4f21d95b4077..317ff512f8df 100644 --- a/drivers/pci/controller/dwc/pcie-designware-host.c +++ b/drivers/pci/controller/dwc/pcie-designware-host.c @@ -361,6 +361,9 @@ int dw_pcie_host_init(struct pcie_port *pp) if (ret) pci->num_viewport = 2; + if (pci->link_gen < 1) + pci->link_gen = of_pci_get_max_link_speed(np); + if (pci_msi_enabled()) { /* * If a specific SoC driver needs to change the diff --git a/drivers/pci/controller/dwc/pcie-designware.c b/drivers/pci/controller/dwc/pcie-designware.c index 8b1c10595f62..62a6735ada9e 100644 --- a/drivers/pci/controller/dwc/pcie-designware.c +++ b/drivers/pci/controller/dwc/pcie-designware.c @@ -473,39 +473,41 @@ void dw_pcie_upconfig_setup(struct dw_pcie *pci) } EXPORT_SYMBOL_GPL(dw_pcie_upconfig_setup); -void dw_pcie_link_set_max_speed(struct dw_pcie *pci, u32 link_gen) +static void dw_pcie_link_set_max_speed(struct dw_pcie *pci, u32 link_gen) { - u32 reg, val; + u32 cap, ctrl2, link_speed; u8 offset = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP); - reg = dw_pcie_readl_dbi(pci, offset + PCI_EXP_LNKCTL2); - reg &= ~PCI_EXP_LNKCTL2_TLS; + cap = dw_pcie_readl_dbi(pci, offset + PCI_EXP_LNKCAP); + ctrl2 = dw_pcie_readl_dbi(pci, offset + PCI_EXP_LNKCTL2); + ctrl2 &= ~PCI_EXP_LNKCTL2_TLS; switch (pcie_link_speed[link_gen]) { case PCIE_SPEED_2_5GT: - reg |= PCI_EXP_LNKCTL2_TLS_2_5GT; + link_speed = PCI_EXP_LNKCTL2_TLS_2_5GT; break; case PCIE_SPEED_5_0GT: - reg |= PCI_EXP_LNKCTL2_TLS_5_0GT; + link_speed = PCI_EXP_LNKCTL2_TLS_5_0GT; break; case PCIE_SPEED_8_0GT: - reg |= PCI_EXP_LNKCTL2_TLS_8_0GT; + link_speed = PCI_EXP_LNKCTL2_TLS_8_0GT; break; case PCIE_SPEED_16_0GT: - reg |= PCI_EXP_LNKCTL2_TLS_16_0GT; + link_speed = PCI_EXP_LNKCTL2_TLS_16_0GT; break; default: /* Use hardware capability */ - val = dw_pcie_readl_dbi(pci, offset + PCI_EXP_LNKCAP); - val = FIELD_GET(PCI_EXP_LNKCAP_SLS, val); - reg &= ~PCI_EXP_LNKCTL2_HASD; - reg |= FIELD_PREP(PCI_EXP_LNKCTL2_TLS, val); + link_speed = FIELD_GET(PCI_EXP_LNKCAP_SLS, cap); + ctrl2 &= ~PCI_EXP_LNKCTL2_HASD; break; } - dw_pcie_writel_dbi(pci, offset + PCI_EXP_LNKCTL2, reg); + dw_pcie_writel_dbi(pci, offset + PCI_EXP_LNKCTL2, ctrl2 | link_speed); + + cap &= ~((u32)PCI_EXP_LNKCAP_SLS); + dw_pcie_writel_dbi(pci, offset + PCI_EXP_LNKCAP, cap | link_speed); + } -EXPORT_SYMBOL_GPL(dw_pcie_link_set_max_speed); void dw_pcie_link_set_n_fts(struct dw_pcie *pci, u32 n_fts) { @@ -544,6 +546,9 @@ void dw_pcie_setup(struct dw_pcie *pci) dev_dbg(pci->dev, "iATU unroll: %s\n", pci->iatu_unroll_enabled ? "enabled" : "disabled"); + if (pci->link_gen > 0) + dw_pcie_link_set_max_speed(pci, pci->link_gen); + val = dw_pcie_readl_dbi(pci, PCIE_PORT_LINK_CONTROL); val &= ~PORT_LINK_FAST_LINK_MODE; dw_pcie_writel_dbi(pci, PCIE_PORT_LINK_CONTROL, val); diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h index edf6143e1a99..a814b1f17260 100644 --- a/drivers/pci/controller/dwc/pcie-designware.h +++ b/drivers/pci/controller/dwc/pcie-designware.h @@ -252,6 +252,7 @@ struct dw_pcie { const struct dw_pcie_ops *ops; unsigned int version; int num_lanes; + int link_gen; }; #define to_dw_pcie_from_pp(port) container_of((port), struct dw_pcie, pp) @@ -270,7 +271,6 @@ void dw_pcie_write_dbi(struct dw_pcie *pci, u32 reg, size_t size, u32 val); void dw_pcie_write_dbi2(struct dw_pcie *pci, u32 reg, size_t size, u32 val); int dw_pcie_link_up(struct dw_pcie *pci); void dw_pcie_upconfig_setup(struct dw_pcie *pci); -void dw_pcie_link_set_max_speed(struct dw_pcie *pci, u32 link_gen); void dw_pcie_link_set_n_fts(struct dw_pcie *pci, u32 n_fts); int dw_pcie_wait_for_link(struct dw_pcie *pci); void dw_pcie_prog_outbound_atu(struct dw_pcie *pci, int index, diff --git a/drivers/pci/controller/dwc/pcie-intel-gw.c b/drivers/pci/controller/dwc/pcie-intel-gw.c index c3b3a1d162b5..2c0d32ffb828 100644 --- a/drivers/pci/controller/dwc/pcie-intel-gw.c +++ b/drivers/pci/controller/dwc/pcie-intel-gw.c @@ -67,8 +67,6 @@ struct intel_pcie_port { void __iomem *app_base; struct gpio_desc *reset_gpio; u32 rst_intrvl; - u32 max_speed; - u32 link_gen; u32 max_width; u32 n_fts; struct clk *core_clk; @@ -137,7 +135,6 @@ static void intel_pcie_link_setup(struct intel_pcie_port *lpp) u8 offset = lpp->pcie_cap_ofst; val = pcie_rc_cfg_rd(lpp, offset + PCI_EXP_LNKCAP); - lpp->max_speed = FIELD_GET(PCI_EXP_LNKCAP_SLS, val); lpp->max_width = FIELD_GET(PCI_EXP_LNKCAP_MLW, val); val = pcie_rc_cfg_rd(lpp, offset + PCI_EXP_LNKCTL); @@ -149,8 +146,9 @@ static void intel_pcie_link_setup(struct intel_pcie_port *lpp) static void intel_pcie_port_logic_setup(struct intel_pcie_port *lpp) { u32 val, mask; + struct dw_pcie *pci = &lpp->pci; - switch (pcie_link_speed[lpp->max_speed]) { + switch (pcie_link_speed[pci->link_gen]) { case PCIE_SPEED_8_0GT: lpp->n_fts = PORT_AFR_N_FTS_GEN3; break; @@ -179,7 +177,6 @@ static void intel_pcie_rc_setup(struct intel_pcie_port *lpp) dw_pcie_setup_rc(&lpp->pci.pp); dw_pcie_upconfig_setup(&lpp->pci); intel_pcie_port_logic_setup(lpp); - dw_pcie_link_set_max_speed(&lpp->pci, lpp->link_gen); dw_pcie_link_set_n_fts(&lpp->pci, lpp->n_fts); } @@ -286,9 +283,6 @@ static int intel_pcie_get_resources(struct platform_device *pdev) if (ret) lpp->rst_intrvl = RESET_INTERVAL_MS; - ret = of_pci_get_max_link_speed(dev->of_node); - lpp->link_gen = ret < 0 ? 0 : ret; - lpp->app_base = devm_platform_ioremap_resource_byname(pdev, "app"); if (IS_ERR(lpp->app_base)) return PTR_ERR(lpp->app_base); @@ -313,8 +307,9 @@ static int intel_pcie_wait_l2(struct intel_pcie_port *lpp) { u32 value; int ret; + struct dw_pcie *pci = &lpp->pci; - if (pcie_link_speed[lpp->max_speed] < PCIE_SPEED_8_0GT) + if (pci->link_gen < 3) return 0; /* Send PME_TURN_OFF message */ diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c index d8d1fb7e0b8f..5eb28251dbee 100644 --- a/drivers/pci/controller/dwc/pcie-qcom.c +++ b/drivers/pci/controller/dwc/pcie-qcom.c @@ -189,7 +189,6 @@ struct qcom_pcie { struct phy *phy; struct gpio_desc *reset; const struct qcom_pcie_ops *ops; - int gen; }; #define to_qcom_pcie(x) dev_get_drvdata((x)->dev) @@ -390,12 +389,6 @@ static int qcom_pcie_init_2_1_0(struct qcom_pcie *pcie) /* wait for clock acquisition */ usleep_range(1000, 1500); - if (pcie->gen == 1) { - val = readl(pci->dbi_base + PCIE20_LNK_CONTROL2_LINK_STATUS2); - val |= PCI_EXP_LNKSTA_CLS_2_5GB; - writel(val, pci->dbi_base + PCIE20_LNK_CONTROL2_LINK_STATUS2); - } - /* Set the Max TLP size to 2K, instead of using default of 4K */ writel(CFG_REMOTE_RD_REQ_BRIDGE_SIZE_2K, pci->dbi_base + PCIE20_AXI_MSTR_RESP_COMP_CTRL0); @@ -1395,10 +1388,6 @@ static int qcom_pcie_probe(struct platform_device *pdev) goto err_pm_runtime_put; } - pcie->gen = of_pci_get_max_link_speed(pdev->dev.of_node); - if (pcie->gen < 0) - pcie->gen = 2; - pcie->parf = devm_platform_ioremap_resource_byname(pdev, "parf"); if (IS_ERR(pcie->parf)) { ret = PTR_ERR(pcie->parf); diff --git a/drivers/pci/controller/dwc/pcie-spear13xx.c b/drivers/pci/controller/dwc/pcie-spear13xx.c index 056c94541a22..0d8d0fe87f27 100644 --- a/drivers/pci/controller/dwc/pcie-spear13xx.c +++ b/drivers/pci/controller/dwc/pcie-spear13xx.c @@ -26,7 +26,6 @@ struct spear13xx_pcie { void __iomem *app_base; struct phy *phy; struct clk *clk; - bool is_gen1; }; struct pcie_app_reg { @@ -94,30 +93,6 @@ static int spear13xx_pcie_establish_link(struct spear13xx_pcie *spear13xx_pcie) dw_pcie_write(pci->dbi_base + PCI_VENDOR_ID, 2, 0x104A); dw_pcie_write(pci->dbi_base + PCI_DEVICE_ID, 2, 0xCD80); - /* - * if is_gen1 is set then handle it, so that some buggy card - * also works - */ - if (spear13xx_pcie->is_gen1) { - dw_pcie_read(pci->dbi_base + exp_cap_off + PCI_EXP_LNKCAP, - 4, &val); - if ((val & PCI_EXP_LNKCAP_SLS) != PCI_EXP_LNKCAP_SLS_2_5GB) { - val &= ~((u32)PCI_EXP_LNKCAP_SLS); - val |= PCI_EXP_LNKCAP_SLS_2_5GB; - dw_pcie_write(pci->dbi_base + exp_cap_off + - PCI_EXP_LNKCAP, 4, val); - } - - dw_pcie_read(pci->dbi_base + exp_cap_off + PCI_EXP_LNKCTL2, - 2, &val); - if ((val & PCI_EXP_LNKCAP_SLS) != PCI_EXP_LNKCAP_SLS_2_5GB) { - val &= ~((u32)PCI_EXP_LNKCAP_SLS); - val |= PCI_EXP_LNKCAP_SLS_2_5GB; - dw_pcie_write(pci->dbi_base + exp_cap_off + - PCI_EXP_LNKCTL2, 2, val); - } - } - /* enable ltssm */ writel(DEVICE_TYPE_RC | (1 << MISCTRL_EN_ID) | (1 << APP_LTSSM_ENABLE_ID) @@ -276,7 +251,7 @@ static int spear13xx_pcie_probe(struct platform_device *pdev) spear13xx_pcie->app_base = pci->dbi_base + 0x2000; if (of_property_read_bool(np, "st,pcie-is-gen1")) - spear13xx_pcie->is_gen1 = true; + pci->link_gen = 1; platform_set_drvdata(pdev, spear13xx_pcie); diff --git a/drivers/pci/controller/dwc/pcie-tegra194.c b/drivers/pci/controller/dwc/pcie-tegra194.c index f121ac25d418..91ef4b3e860d 100644 --- a/drivers/pci/controller/dwc/pcie-tegra194.c +++ b/drivers/pci/controller/dwc/pcie-tegra194.c @@ -284,7 +284,6 @@ struct tegra_pcie_dw { u8 init_link_width; u32 msi_ctrl_int; u32 num_lanes; - u32 max_speed; u32 cid; u32 cfg_link_cap_l1sub; u32 pcie_cap_base; @@ -900,16 +899,6 @@ static void tegra_pcie_prepare_host(struct pcie_port *pp) AMBA_ERROR_RESPONSE_CRS_SHIFT); dw_pcie_writel_dbi(pci, PORT_LOGIC_AMBA_ERROR_RESPONSE_DEFAULT, val); - /* Configure Max Speed from DT */ - if (pcie->max_speed && pcie->max_speed != -EINVAL) { - val = dw_pcie_readl_dbi(pci, pcie->pcie_cap_base + - PCI_EXP_LNKCAP); - val &= ~PCI_EXP_LNKCAP_SLS; - val |= pcie->max_speed; - dw_pcie_writel_dbi(pci, pcie->pcie_cap_base + PCI_EXP_LNKCAP, - val); - } - /* Configure Max lane width from DT */ val = dw_pcie_readl_dbi(pci, pcie->pcie_cap_base + PCI_EXP_LNKCAP); val &= ~PCI_EXP_LNKCAP_MLW; @@ -1119,8 +1108,6 @@ static int tegra_pcie_dw_parse_dt(struct tegra_pcie_dw *pcie) return ret; } - pcie->max_speed = of_pci_get_max_link_speed(np); - ret = of_property_read_u32_index(np, "nvidia,bpmp", 1, &pcie->cid); if (ret) { dev_err(pcie->dev, "Failed to read Controller-ID: %d\n", ret); @@ -1818,16 +1805,6 @@ static void pex_ep_event_pex_rst_deassert(struct tegra_pcie_dw *pcie) val |= FTS_VAL; dw_pcie_writel_dbi(pci, PCIE_LINK_WIDTH_SPEED_CONTROL, val); - /* Configure Max Speed from DT */ - if (pcie->max_speed && pcie->max_speed != -EINVAL) { - val = dw_pcie_readl_dbi(pci, pcie->pcie_cap_base + - PCI_EXP_LNKCAP); - val &= ~PCI_EXP_LNKCAP_SLS; - val |= pcie->max_speed; - dw_pcie_writel_dbi(pci, pcie->pcie_cap_base + PCI_EXP_LNKCAP, - val); - } - pcie->pcie_cap_base = dw_pcie_find_capability(&pcie->pci, PCI_CAP_ID_EXP); clk_set_rate(pcie->core_clk, GEN4_CORE_CLK_FREQ); -- cgit v1.2.3