summaryrefslogtreecommitdiff
path: root/drivers/pci/controller
diff options
context:
space:
mode:
authorBjorn Helgaas <bhelgaas@google.com>2020-08-05 18:24:18 -0500
committerBjorn Helgaas <bhelgaas@google.com>2020-08-05 18:24:18 -0500
commit26418025ce0b8afd10a19e507171bfa42ea62a30 (patch)
treec8c97f0d184790aaeccc0c25a74ef1e2b17e8958 /drivers/pci/controller
parent13a77336f4f5681068bbaa4eac3ba8adff684a54 (diff)
parentc2fa6cf76d204e296e2e295d821500e0b291697d (diff)
Merge branch 'remotes/lorenzo/pci/dwc'
- Add qcom ipq806x support (Ansuel Smith) - Support max-link-speed DT property for qcom (Sham Muthayyan) - Use PCI core #defines instead of adding qcom-specific ones (Ansuel Smith) - Convert to devm_platform_ioremap_resource_byname() instead of open-coding platform_get_resource_byname() and devm_ioremap_resource() for dra7xx, keystone, artpec6, designware-plat, histb, intel-gw, kirin, qcom, uniphier (Dejin Zheng) - Remove non-ECAM HiSilicon hip05/hip06 driver (Rob Herring) * remotes/lorenzo/pci/dwc: PCI: dwc: hisi: Remove non-ECAM HiSilicon hip05/hip06 driver PCI: dwc: Convert to devm_platform_ioremap_resource_byname() PCI: qcom: Replace define with standard value PCI: qcom: Support pci speed set for ipq806x dt-bindings: PCI: qcom: Add ipq8064 rev 2 variant PCI: qcom: Add ipq8064 rev2 variant PCI: qcom: Add support for tx term offset for rev 2.1.0 PCI: qcom: Define some PARF params needed for ipq8064 SoC PCI: qcom: Use bulk clk api and assert on error dt-bindings: PCI: qcom: Add ext reset PCI: qcom: Add missing reset for ipq806x PCI: qcom: Change duplicate PCI reset to phy reset dt-bindings: PCI: qcom: Add missing clks PCI: qcom: Add missing ipq806x clocks in PCIe driver
Diffstat (limited to 'drivers/pci/controller')
-rw-r--r--drivers/pci/controller/dwc/pci-dra7xx.c11
-rw-r--r--drivers/pci/controller/dwc/pci-keystone.c3
-rw-r--r--drivers/pci/controller/dwc/pcie-artpec6.c12
-rw-r--r--drivers/pci/controller/dwc/pcie-designware-plat.c3
-rw-r--r--drivers/pci/controller/dwc/pcie-hisi.c219
-rw-r--r--drivers/pci/controller/dwc/pcie-histb.c7
-rw-r--r--drivers/pci/controller/dwc/pcie-intel-gw.c7
-rw-r--r--drivers/pci/controller/dwc/pcie-kirin.c17
-rw-r--r--drivers/pci/controller/dwc/pcie-qcom.c192
-rw-r--r--drivers/pci/controller/dwc/pcie-uniphier.c3
10 files changed, 140 insertions, 334 deletions
diff --git a/drivers/pci/controller/dwc/pci-dra7xx.c b/drivers/pci/controller/dwc/pci-dra7xx.c
index 1b2e6e6fb818..a896b9b6e274 100644
--- a/drivers/pci/controller/dwc/pci-dra7xx.c
+++ b/drivers/pci/controller/dwc/pci-dra7xx.c
@@ -593,13 +593,12 @@ static int __init dra7xx_add_pcie_ep(struct dra7xx_pcie *dra7xx,
ep = &pci->ep;
ep->ops = &pcie_ep_ops;
- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ep_dbics");
- pci->dbi_base = devm_ioremap_resource(dev, res);
+ pci->dbi_base = devm_platform_ioremap_resource_byname(pdev, "ep_dbics");
if (IS_ERR(pci->dbi_base))
return PTR_ERR(pci->dbi_base);
- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ep_dbics2");
- pci->dbi_base2 = devm_ioremap_resource(dev, res);
+ pci->dbi_base2 =
+ devm_platform_ioremap_resource_byname(pdev, "ep_dbics2");
if (IS_ERR(pci->dbi_base2))
return PTR_ERR(pci->dbi_base2);
@@ -626,7 +625,6 @@ static int __init dra7xx_add_pcie_port(struct dra7xx_pcie *dra7xx,
struct dw_pcie *pci = dra7xx->pci;
struct pcie_port *pp = &pci->pp;
struct device *dev = pci->dev;
- struct resource *res;
pp->irq = platform_get_irq(pdev, 1);
if (pp->irq < 0) {
@@ -638,8 +636,7 @@ static int __init dra7xx_add_pcie_port(struct dra7xx_pcie *dra7xx,
if (ret < 0)
return ret;
- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "rc_dbics");
- pci->dbi_base = devm_ioremap_resource(dev, res);
+ pci->dbi_base = devm_platform_ioremap_resource_byname(pdev, "rc_dbics");
if (IS_ERR(pci->dbi_base))
return PTR_ERR(pci->dbi_base);
diff --git a/drivers/pci/controller/dwc/pci-keystone.c b/drivers/pci/controller/dwc/pci-keystone.c
index 5191cad906ca..0b7ed21cf8d0 100644
--- a/drivers/pci/controller/dwc/pci-keystone.c
+++ b/drivers/pci/controller/dwc/pci-keystone.c
@@ -1323,8 +1323,7 @@ static int __init ks_pcie_probe(struct platform_device *pdev)
}
if (pci->version >= 0x480A) {
- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "atu");
- atu_base = devm_ioremap_resource(dev, res);
+ atu_base = devm_platform_ioremap_resource_byname(pdev, "atu");
if (IS_ERR(atu_base)) {
ret = PTR_ERR(atu_base);
goto err_get_sync;
diff --git a/drivers/pci/controller/dwc/pcie-artpec6.c b/drivers/pci/controller/dwc/pcie-artpec6.c
index 28d5a1095200..7d2cfa288b01 100644
--- a/drivers/pci/controller/dwc/pcie-artpec6.c
+++ b/drivers/pci/controller/dwc/pcie-artpec6.c
@@ -455,8 +455,7 @@ static int artpec6_add_pcie_ep(struct artpec6_pcie *artpec6_pcie,
ep = &pci->ep;
ep->ops = &pcie_ep_ops;
- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dbi2");
- pci->dbi_base2 = devm_ioremap_resource(dev, res);
+ pci->dbi_base2 = devm_platform_ioremap_resource_byname(pdev, "dbi2");
if (IS_ERR(pci->dbi_base2))
return PTR_ERR(pci->dbi_base2);
@@ -481,8 +480,6 @@ static int artpec6_pcie_probe(struct platform_device *pdev)
struct device *dev = &pdev->dev;
struct dw_pcie *pci;
struct artpec6_pcie *artpec6_pcie;
- struct resource *dbi_base;
- struct resource *phy_base;
int ret;
const struct of_device_id *match;
const struct artpec_pcie_of_data *data;
@@ -512,13 +509,12 @@ static int artpec6_pcie_probe(struct platform_device *pdev)
artpec6_pcie->variant = variant;
artpec6_pcie->mode = mode;
- dbi_base = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dbi");
- pci->dbi_base = devm_ioremap_resource(dev, dbi_base);
+ pci->dbi_base = devm_platform_ioremap_resource_byname(pdev, "dbi");
if (IS_ERR(pci->dbi_base))
return PTR_ERR(pci->dbi_base);
- phy_base = platform_get_resource_byname(pdev, IORESOURCE_MEM, "phy");
- artpec6_pcie->phy_base = devm_ioremap_resource(dev, phy_base);
+ artpec6_pcie->phy_base =
+ devm_platform_ioremap_resource_byname(pdev, "phy");
if (IS_ERR(artpec6_pcie->phy_base))
return PTR_ERR(artpec6_pcie->phy_base);
diff --git a/drivers/pci/controller/dwc/pcie-designware-plat.c b/drivers/pci/controller/dwc/pcie-designware-plat.c
index 73646b677aff..712456f6ce36 100644
--- a/drivers/pci/controller/dwc/pcie-designware-plat.c
+++ b/drivers/pci/controller/dwc/pcie-designware-plat.c
@@ -153,8 +153,7 @@ static int dw_plat_add_pcie_ep(struct dw_plat_pcie *dw_plat_pcie,
ep = &pci->ep;
ep->ops = &pcie_ep_ops;
- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dbi2");
- pci->dbi_base2 = devm_ioremap_resource(dev, res);
+ pci->dbi_base2 = devm_platform_ioremap_resource_byname(pdev, "dbi2");
if (IS_ERR(pci->dbi_base2))
return PTR_ERR(pci->dbi_base2);
diff --git a/drivers/pci/controller/dwc/pcie-hisi.c b/drivers/pci/controller/dwc/pcie-hisi.c
index 0ad4e07dd4c2..5ca86796d43a 100644
--- a/drivers/pci/controller/dwc/pcie-hisi.c
+++ b/drivers/pci/controller/dwc/pcie-hisi.c
@@ -10,15 +10,10 @@
*/
#include <linux/interrupt.h>
#include <linux/init.h>
-#include <linux/mfd/syscon.h>
-#include <linux/of_address.h>
-#include <linux/of_pci.h>
#include <linux/platform_device.h>
-#include <linux/of_device.h>
#include <linux/pci.h>
#include <linux/pci-acpi.h>
#include <linux/pci-ecam.h>
-#include <linux/regmap.h>
#include "../../pci.h"
#if defined(CONFIG_PCI_HISI) || (defined(CONFIG_ACPI) && defined(CONFIG_PCI_QUIRKS))
@@ -118,220 +113,6 @@ const struct pci_ecam_ops hisi_pcie_ops = {
#ifdef CONFIG_PCI_HISI
-#include "pcie-designware.h"
-
-#define PCIE_SUBCTRL_SYS_STATE4_REG 0x6818
-#define PCIE_HIP06_CTRL_OFF 0x1000
-#define PCIE_SYS_STATE4 (PCIE_HIP06_CTRL_OFF + 0x31c)
-#define PCIE_LTSSM_LINKUP_STATE 0x11
-#define PCIE_LTSSM_STATE_MASK 0x3F
-
-#define to_hisi_pcie(x) dev_get_drvdata((x)->dev)
-
-struct hisi_pcie;
-
-struct pcie_soc_ops {
- int (*hisi_pcie_link_up)(struct hisi_pcie *hisi_pcie);
-};
-
-struct hisi_pcie {
- struct dw_pcie *pci;
- struct regmap *subctrl;
- u32 port_id;
- const struct pcie_soc_ops *soc_ops;
-};
-
-/* HipXX PCIe host only supports 32-bit config access */
-static int hisi_pcie_cfg_read(struct pcie_port *pp, int where, int size,
- u32 *val)
-{
- u32 reg;
- u32 reg_val;
- void *walker = &reg_val;
- struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
-
- walker += (where & 0x3);
- reg = where & ~0x3;
- reg_val = dw_pcie_readl_dbi(pci, reg);
-
- if (size == 1)
- *val = *(u8 __force *) walker;
- else if (size == 2)
- *val = *(u16 __force *) walker;
- else if (size == 4)
- *val = reg_val;
- else
- return PCIBIOS_BAD_REGISTER_NUMBER;
-
- return PCIBIOS_SUCCESSFUL;
-}
-
-/* HipXX PCIe host only supports 32-bit config access */
-static int hisi_pcie_cfg_write(struct pcie_port *pp, int where, int size,
- u32 val)
-{
- u32 reg_val;
- u32 reg;
- void *walker = &reg_val;
- struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
-
- walker += (where & 0x3);
- reg = where & ~0x3;
- if (size == 4)
- dw_pcie_writel_dbi(pci, reg, val);
- else if (size == 2) {
- reg_val = dw_pcie_readl_dbi(pci, reg);
- *(u16 __force *) walker = val;
- dw_pcie_writel_dbi(pci, reg, reg_val);
- } else if (size == 1) {
- reg_val = dw_pcie_readl_dbi(pci, reg);
- *(u8 __force *) walker = val;
- dw_pcie_writel_dbi(pci, reg, reg_val);
- } else
- return PCIBIOS_BAD_REGISTER_NUMBER;
-
- return PCIBIOS_SUCCESSFUL;
-}
-
-static int hisi_pcie_link_up_hip05(struct hisi_pcie *hisi_pcie)
-{
- u32 val;
-
- regmap_read(hisi_pcie->subctrl, PCIE_SUBCTRL_SYS_STATE4_REG +
- 0x100 * hisi_pcie->port_id, &val);
-
- return ((val & PCIE_LTSSM_STATE_MASK) == PCIE_LTSSM_LINKUP_STATE);
-}
-
-static int hisi_pcie_link_up_hip06(struct hisi_pcie *hisi_pcie)
-{
- struct dw_pcie *pci = hisi_pcie->pci;
- u32 val;
-
- val = dw_pcie_readl_dbi(pci, PCIE_SYS_STATE4);
-
- return ((val & PCIE_LTSSM_STATE_MASK) == PCIE_LTSSM_LINKUP_STATE);
-}
-
-static int hisi_pcie_link_up(struct dw_pcie *pci)
-{
- struct hisi_pcie *hisi_pcie = to_hisi_pcie(pci);
-
- return hisi_pcie->soc_ops->hisi_pcie_link_up(hisi_pcie);
-}
-
-static const struct dw_pcie_host_ops hisi_pcie_host_ops = {
- .rd_own_conf = hisi_pcie_cfg_read,
- .wr_own_conf = hisi_pcie_cfg_write,
-};
-
-static int hisi_add_pcie_port(struct hisi_pcie *hisi_pcie,
- struct platform_device *pdev)
-{
- struct dw_pcie *pci = hisi_pcie->pci;
- struct pcie_port *pp = &pci->pp;
- struct device *dev = &pdev->dev;
- int ret;
- u32 port_id;
-
- if (of_property_read_u32(dev->of_node, "port-id", &port_id)) {
- dev_err(dev, "failed to read port-id\n");
- return -EINVAL;
- }
- if (port_id > 3) {
- dev_err(dev, "Invalid port-id: %d\n", port_id);
- return -EINVAL;
- }
- hisi_pcie->port_id = port_id;
-
- pp->ops = &hisi_pcie_host_ops;
-
- ret = dw_pcie_host_init(pp);
- if (ret) {
- dev_err(dev, "failed to initialize host\n");
- return ret;
- }
-
- return 0;
-}
-
-static const struct dw_pcie_ops dw_pcie_ops = {
- .link_up = hisi_pcie_link_up,
-};
-
-static int hisi_pcie_probe(struct platform_device *pdev)
-{
- struct device *dev = &pdev->dev;
- struct dw_pcie *pci;
- struct hisi_pcie *hisi_pcie;
- struct resource *reg;
- int ret;
-
- hisi_pcie = devm_kzalloc(dev, sizeof(*hisi_pcie), GFP_KERNEL);
- if (!hisi_pcie)
- return -ENOMEM;
-
- pci = devm_kzalloc(dev, sizeof(*pci), GFP_KERNEL);
- if (!pci)
- return -ENOMEM;
-
- pci->dev = dev;
- pci->ops = &dw_pcie_ops;
-
- hisi_pcie->pci = pci;
-
- hisi_pcie->soc_ops = of_device_get_match_data(dev);
-
- hisi_pcie->subctrl =
- syscon_regmap_lookup_by_compatible("hisilicon,pcie-sas-subctrl");
- if (IS_ERR(hisi_pcie->subctrl)) {
- dev_err(dev, "cannot get subctrl base\n");
- return PTR_ERR(hisi_pcie->subctrl);
- }
-
- reg = platform_get_resource_byname(pdev, IORESOURCE_MEM, "rc_dbi");
- pci->dbi_base = devm_pci_remap_cfg_resource(dev, reg);
- if (IS_ERR(pci->dbi_base))
- return PTR_ERR(pci->dbi_base);
- platform_set_drvdata(pdev, hisi_pcie);
-
- ret = hisi_add_pcie_port(hisi_pcie, pdev);
- if (ret)
- return ret;
-
- return 0;
-}
-
-static struct pcie_soc_ops hip05_ops = {
- &hisi_pcie_link_up_hip05
-};
-
-static struct pcie_soc_ops hip06_ops = {
- &hisi_pcie_link_up_hip06
-};
-
-static const struct of_device_id hisi_pcie_of_match[] = {
- {
- .compatible = "hisilicon,hip05-pcie",
- .data = (void *) &hip05_ops,
- },
- {
- .compatible = "hisilicon,hip06-pcie",
- .data = (void *) &hip06_ops,
- },
- {},
-};
-
-static struct platform_driver hisi_pcie_driver = {
- .probe = hisi_pcie_probe,
- .driver = {
- .name = "hisi-pcie",
- .of_match_table = hisi_pcie_of_match,
- .suppress_bind_attrs = true,
- },
-};
-builtin_platform_driver(hisi_pcie_driver);
-
static int hisi_pcie_platform_init(struct pci_config_window *cfg)
{
struct device *dev = cfg->parent;
diff --git a/drivers/pci/controller/dwc/pcie-histb.c b/drivers/pci/controller/dwc/pcie-histb.c
index 811b5c6d62ea..6d3524c39a9b 100644
--- a/drivers/pci/controller/dwc/pcie-histb.c
+++ b/drivers/pci/controller/dwc/pcie-histb.c
@@ -304,7 +304,6 @@ static int histb_pcie_probe(struct platform_device *pdev)
struct histb_pcie *hipcie;
struct dw_pcie *pci;
struct pcie_port *pp;
- struct resource *res;
struct device_node *np = pdev->dev.of_node;
struct device *dev = &pdev->dev;
enum of_gpio_flags of_flags;
@@ -324,15 +323,13 @@ static int histb_pcie_probe(struct platform_device *pdev)
pci->dev = dev;
pci->ops = &dw_pcie_ops;
- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "control");
- hipcie->ctrl = devm_ioremap_resource(dev, res);
+ hipcie->ctrl = devm_platform_ioremap_resource_byname(pdev, "control");
if (IS_ERR(hipcie->ctrl)) {
dev_err(dev, "cannot get control reg base\n");
return PTR_ERR(hipcie->ctrl);
}
- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "rc-dbi");
- pci->dbi_base = devm_ioremap_resource(dev, res);
+ pci->dbi_base = devm_platform_ioremap_resource_byname(pdev, "rc-dbi");
if (IS_ERR(pci->dbi_base)) {
dev_err(dev, "cannot get rc-dbi base\n");
return PTR_ERR(pci->dbi_base);
diff --git a/drivers/pci/controller/dwc/pcie-intel-gw.c b/drivers/pci/controller/dwc/pcie-intel-gw.c
index 2d8dbb318087..c3b3a1d162b5 100644
--- a/drivers/pci/controller/dwc/pcie-intel-gw.c
+++ b/drivers/pci/controller/dwc/pcie-intel-gw.c
@@ -253,11 +253,9 @@ static int intel_pcie_get_resources(struct platform_device *pdev)
struct intel_pcie_port *lpp = platform_get_drvdata(pdev);
struct dw_pcie *pci = &lpp->pci;
struct device *dev = pci->dev;
- struct resource *res;
int ret;
- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dbi");
- pci->dbi_base = devm_ioremap_resource(dev, res);
+ pci->dbi_base = devm_platform_ioremap_resource_byname(pdev, "dbi");
if (IS_ERR(pci->dbi_base))
return PTR_ERR(pci->dbi_base);
@@ -291,8 +289,7 @@ static int intel_pcie_get_resources(struct platform_device *pdev)
ret = of_pci_get_max_link_speed(dev->of_node);
lpp->link_gen = ret < 0 ? 0 : ret;
- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "app");
- lpp->app_base = devm_ioremap_resource(dev, res);
+ lpp->app_base = devm_platform_ioremap_resource_byname(pdev, "app");
if (IS_ERR(lpp->app_base))
return PTR_ERR(lpp->app_base);
diff --git a/drivers/pci/controller/dwc/pcie-kirin.c b/drivers/pci/controller/dwc/pcie-kirin.c
index 7b86c1608b04..9adaa65c581f 100644
--- a/drivers/pci/controller/dwc/pcie-kirin.c
+++ b/drivers/pci/controller/dwc/pcie-kirin.c
@@ -147,23 +147,18 @@ static long kirin_pcie_get_clk(struct kirin_pcie *kirin_pcie,
static long kirin_pcie_get_resource(struct kirin_pcie *kirin_pcie,
struct platform_device *pdev)
{
- struct device *dev = &pdev->dev;
- struct resource *apb;
- struct resource *phy;
- struct resource *dbi;
-
- apb = platform_get_resource_byname(pdev, IORESOURCE_MEM, "apb");
- kirin_pcie->apb_base = devm_ioremap_resource(dev, apb);
+ kirin_pcie->apb_base =
+ devm_platform_ioremap_resource_byname(pdev, "apb");
if (IS_ERR(kirin_pcie->apb_base))
return PTR_ERR(kirin_pcie->apb_base);
- phy = platform_get_resource_byname(pdev, IORESOURCE_MEM, "phy");
- kirin_pcie->phy_base = devm_ioremap_resource(dev, phy);
+ kirin_pcie->phy_base =
+ devm_platform_ioremap_resource_byname(pdev, "phy");
if (IS_ERR(kirin_pcie->phy_base))
return PTR_ERR(kirin_pcie->phy_base);
- dbi = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dbi");
- kirin_pcie->pci->dbi_base = devm_ioremap_resource(dev, dbi);
+ kirin_pcie->pci->dbi_base =
+ devm_platform_ioremap_resource_byname(pdev, "dbi");
if (IS_ERR(kirin_pcie->pci->dbi_base))
return PTR_ERR(kirin_pcie->pci->dbi_base);
diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c
index 138e1a2d21cc..b79f7878c993 100644
--- a/drivers/pci/controller/dwc/pcie-qcom.c
+++ b/drivers/pci/controller/dwc/pcie-qcom.c
@@ -27,6 +27,7 @@
#include <linux/slab.h>
#include <linux/types.h>
+#include "../../pci.h"
#include "pcie-designware.h"
#define PCIE20_PARF_SYS_CTRL 0x00
@@ -39,13 +40,14 @@
#define L23_CLK_RMV_DIS BIT(2)
#define L1_CLK_RMV_DIS BIT(1)
-#define PCIE20_COMMAND_STATUS 0x04
-#define CMD_BME_VAL 0x4
-#define PCIE20_DEVICE_CONTROL2_STATUS2 0x98
-#define PCIE_CAP_CPL_TIMEOUT_DISABLE 0x10
-
#define PCIE20_PARF_PHY_CTRL 0x40
+#define PHY_CTRL_PHY_TX0_TERM_OFFSET_MASK GENMASK(20, 16)
+#define PHY_CTRL_PHY_TX0_TERM_OFFSET(x) ((x) << 16)
+
#define PCIE20_PARF_PHY_REFCLK 0x4C
+#define PHY_REFCLK_SSP_EN BIT(16)
+#define PHY_REFCLK_USE_PAD BIT(12)
+
#define PCIE20_PARF_DBI_BASE_ADDR 0x168
#define PCIE20_PARF_SLV_ADDR_SPACE_SIZE 0x16C
#define PCIE20_PARF_MHI_CLOCK_RESET_CTRL 0x174
@@ -66,8 +68,8 @@
#define CFG_BRIDGE_SB_INIT BIT(0)
#define PCIE20_CAP 0x70
-#define PCIE20_CAP_LINK_CAPABILITIES (PCIE20_CAP + 0xC)
-#define PCIE20_CAP_ACTIVE_STATE_LINK_PM_SUPPORT (BIT(10) | BIT(11))
+#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
@@ -77,22 +79,36 @@
#define DBI_RO_WR_EN 1
#define PERST_DELAY_US 1000
+/* PARF registers */
+#define PCIE20_PARF_PCS_DEEMPH 0x34
+#define PCS_DEEMPH_TX_DEEMPH_GEN1(x) ((x) << 16)
+#define PCS_DEEMPH_TX_DEEMPH_GEN2_3_5DB(x) ((x) << 8)
+#define PCS_DEEMPH_TX_DEEMPH_GEN2_6DB(x) ((x) << 0)
+
+#define PCIE20_PARF_PCS_SWING 0x38
+#define PCS_SWING_TX_SWING_FULL(x) ((x) << 8)
+#define PCS_SWING_TX_SWING_LOW(x) ((x) << 0)
+
+#define PCIE20_PARF_CONFIG_BITS 0x50
+#define PHY_RX0_EQ(x) ((x) << 24)
#define PCIE20_v3_PARF_SLV_ADDR_SPACE_SIZE 0x358
#define SLV_ADDR_SPACE_SZ 0x10000000
+#define PCIE20_LNK_CONTROL2_LINK_STATUS2 0xa0
+
#define DEVICE_TYPE_RC 0x4
#define QCOM_PCIE_2_1_0_MAX_SUPPLY 3
+#define QCOM_PCIE_2_1_0_MAX_CLOCKS 5
struct qcom_pcie_resources_2_1_0 {
- struct clk *iface_clk;
- struct clk *core_clk;
- struct clk *phy_clk;
+ struct clk_bulk_data clks[QCOM_PCIE_2_1_0_MAX_CLOCKS];
struct reset_control *pci_reset;
struct reset_control *axi_reset;
struct reset_control *ahb_reset;
struct reset_control *por_reset;
struct reset_control *phy_reset;
+ struct reset_control *ext_reset;
struct regulator_bulk_data supplies[QCOM_PCIE_2_1_0_MAX_SUPPLY];
};
@@ -177,6 +193,7 @@ 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)
@@ -234,17 +251,21 @@ static int qcom_pcie_get_resources_2_1_0(struct qcom_pcie *pcie)
if (ret)
return ret;
- res->iface_clk = devm_clk_get(dev, "iface");
- if (IS_ERR(res->iface_clk))
- return PTR_ERR(res->iface_clk);
+ res->clks[0].id = "iface";
+ res->clks[1].id = "core";
+ res->clks[2].id = "phy";
+ res->clks[3].id = "aux";
+ res->clks[4].id = "ref";
- res->core_clk = devm_clk_get(dev, "core");
- if (IS_ERR(res->core_clk))
- return PTR_ERR(res->core_clk);
+ /* iface, core, phy are required */
+ ret = devm_clk_bulk_get(dev, 3, res->clks);
+ if (ret < 0)
+ return ret;
- res->phy_clk = devm_clk_get(dev, "phy");
- if (IS_ERR(res->phy_clk))
- return PTR_ERR(res->phy_clk);
+ /* aux, ref are optional */
+ ret = devm_clk_bulk_get_optional(dev, 2, res->clks + 3);
+ if (ret < 0)
+ return ret;
res->pci_reset = devm_reset_control_get_exclusive(dev, "pci");
if (IS_ERR(res->pci_reset))
@@ -262,6 +283,10 @@ static int qcom_pcie_get_resources_2_1_0(struct qcom_pcie *pcie)
if (IS_ERR(res->por_reset))
return PTR_ERR(res->por_reset);
+ res->ext_reset = devm_reset_control_get_optional_exclusive(dev, "ext");
+ if (IS_ERR(res->ext_reset))
+ return PTR_ERR(res->ext_reset);
+
res->phy_reset = devm_reset_control_get_exclusive(dev, "phy");
return PTR_ERR_OR_ZERO(res->phy_reset);
}
@@ -270,14 +295,13 @@ static void qcom_pcie_deinit_2_1_0(struct qcom_pcie *pcie)
{
struct qcom_pcie_resources_2_1_0 *res = &pcie->res.v2_1_0;
+ clk_bulk_disable_unprepare(ARRAY_SIZE(res->clks), res->clks);
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->pci_reset);
- clk_disable_unprepare(res->iface_clk);
- clk_disable_unprepare(res->core_clk);
- clk_disable_unprepare(res->phy_clk);
+ reset_control_assert(res->ext_reset);
+ reset_control_assert(res->phy_reset);
regulator_bulk_disable(ARRAY_SIZE(res->supplies), res->supplies);
}
@@ -286,6 +310,7 @@ static int qcom_pcie_init_2_1_0(struct qcom_pcie *pcie)
struct qcom_pcie_resources_2_1_0 *res = &pcie->res.v2_1_0;
struct dw_pcie *pci = pcie->pci;
struct device *dev = pci->dev;
+ struct device_node *node = dev->of_node;
u32 val;
int ret;
@@ -295,73 +320,85 @@ static int qcom_pcie_init_2_1_0(struct qcom_pcie *pcie)
return ret;
}
- ret = reset_control_assert(res->ahb_reset);
- if (ret) {
- dev_err(dev, "cannot assert ahb reset\n");
- goto err_assert_ahb;
- }
-
- ret = clk_prepare_enable(res->iface_clk);
- if (ret) {
- dev_err(dev, "cannot prepare/enable iface clock\n");
- goto err_assert_ahb;
- }
-
- ret = clk_prepare_enable(res->phy_clk);
- if (ret) {
- dev_err(dev, "cannot prepare/enable phy clock\n");
- goto err_clk_phy;
- }
-
- ret = clk_prepare_enable(res->core_clk);
- if (ret) {
- dev_err(dev, "cannot prepare/enable core clock\n");
- goto err_clk_core;
- }
-
ret = reset_control_deassert(res->ahb_reset);
if (ret) {
dev_err(dev, "cannot deassert ahb reset\n");
goto err_deassert_ahb;
}
- /* enable PCIe clocks and resets */
- val = readl(pcie->parf + PCIE20_PARF_PHY_CTRL);
- val &= ~BIT(0);
- writel(val, pcie->parf + PCIE20_PARF_PHY_CTRL);
-
- /* enable external reference clock */
- val = readl(pcie->parf + PCIE20_PARF_PHY_REFCLK);
- val |= BIT(16);
- writel(val, pcie->parf + PCIE20_PARF_PHY_REFCLK);
+ ret = reset_control_deassert(res->ext_reset);
+ if (ret) {
+ dev_err(dev, "cannot deassert ext reset\n");
+ goto err_deassert_ext;
+ }
ret = reset_control_deassert(res->phy_reset);
if (ret) {
dev_err(dev, "cannot deassert phy reset\n");
- return ret;
+ goto err_deassert_phy;
}
ret = reset_control_deassert(res->pci_reset);
if (ret) {
dev_err(dev, "cannot deassert pci reset\n");
- return ret;
+ goto err_deassert_pci;
}
ret = reset_control_deassert(res->por_reset);
if (ret) {
dev_err(dev, "cannot deassert por reset\n");
- return ret;
+ goto err_deassert_por;
}
ret = reset_control_deassert(res->axi_reset);
if (ret) {
dev_err(dev, "cannot deassert axi reset\n");
- return ret;
+ goto err_deassert_axi;
+ }
+
+ ret = clk_bulk_prepare_enable(ARRAY_SIZE(res->clks), res->clks);
+ if (ret)
+ goto err_clks;
+
+ /* enable PCIe clocks and resets */
+ val = readl(pcie->parf + PCIE20_PARF_PHY_CTRL);
+ val &= ~BIT(0);
+ writel(val, pcie->parf + PCIE20_PARF_PHY_CTRL);
+
+ if (of_device_is_compatible(node, "qcom,pcie-ipq8064") ||
+ of_device_is_compatible(node, "qcom,pcie-ipq8064-v2")) {
+ writel(PCS_DEEMPH_TX_DEEMPH_GEN1(24) |
+ PCS_DEEMPH_TX_DEEMPH_GEN2_3_5DB(24) |
+ PCS_DEEMPH_TX_DEEMPH_GEN2_6DB(34),
+ pcie->parf + PCIE20_PARF_PCS_DEEMPH);
+ writel(PCS_SWING_TX_SWING_FULL(120) |
+ PCS_SWING_TX_SWING_LOW(120),
+ pcie->parf + PCIE20_PARF_PCS_SWING);
+ writel(PHY_RX0_EQ(4), pcie->parf + PCIE20_PARF_CONFIG_BITS);
+ }
+
+ if (of_device_is_compatible(node, "qcom,pcie-ipq8064")) {
+ /* set TX termination offset */
+ val = readl(pcie->parf + PCIE20_PARF_PHY_CTRL);
+ val &= ~PHY_CTRL_PHY_TX0_TERM_OFFSET_MASK;
+ val |= PHY_CTRL_PHY_TX0_TERM_OFFSET(7);
+ writel(val, pcie->parf + PCIE20_PARF_PHY_CTRL);
}
+ /* enable external reference clock */
+ val = readl(pcie->parf + PCIE20_PARF_PHY_REFCLK);
+ val &= ~PHY_REFCLK_USE_PAD;
+ val |= PHY_REFCLK_SSP_EN;
+ writel(val, pcie->parf + PCIE20_PARF_PHY_REFCLK);
+
/* 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,
@@ -371,13 +408,19 @@ static int qcom_pcie_init_2_1_0(struct qcom_pcie *pcie)
return 0;
+err_clks:
+ reset_control_assert(res->axi_reset);
+err_deassert_axi:
+ reset_control_assert(res->por_reset);
+err_deassert_por:
+ reset_control_assert(res->pci_reset);
+err_deassert_pci:
+ reset_control_assert(res->phy_reset);
+err_deassert_phy:
+ reset_control_assert(res->ext_reset);
+err_deassert_ext:
+ reset_control_assert(res->ahb_reset);
err_deassert_ahb:
- clk_disable_unprepare(res->core_clk);
-err_clk_core:
- clk_disable_unprepare(res->phy_clk);
-err_clk_phy:
- clk_disable_unprepare(res->iface_clk);
-err_assert_ahb:
regulator_bulk_disable(ARRAY_SIZE(res->supplies), res->supplies);
return ret;
@@ -1047,15 +1090,15 @@ static int qcom_pcie_init_2_3_3(struct qcom_pcie *pcie)
pcie->parf + PCIE20_PARF_SYS_CTRL);
writel(0, pcie->parf + PCIE20_PARF_Q2A_FLUSH);
- writel(CMD_BME_VAL, pci->dbi_base + PCIE20_COMMAND_STATUS);
+ 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);
val = readl(pci->dbi_base + PCIE20_CAP_LINK_CAPABILITIES);
- val &= ~PCIE20_CAP_ACTIVE_STATE_LINK_PM_SUPPORT;
+ val &= ~PCI_EXP_LNKCAP_ASPMS;
writel(val, pci->dbi_base + PCIE20_CAP_LINK_CAPABILITIES);
- writel(PCIE_CAP_CPL_TIMEOUT_DISABLE, pci->dbi_base +
+ writel(PCI_EXP_DEVCTL2_COMP_TMOUT_DIS, pci->dbi_base +
PCIE20_DEVICE_CONTROL2_STATUS2);
return 0;
@@ -1358,8 +1401,11 @@ static int qcom_pcie_probe(struct platform_device *pdev)
goto err_pm_runtime_put;
}
- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "parf");
- pcie->parf = devm_ioremap_resource(dev, res);
+ 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);
goto err_pm_runtime_put;
@@ -1372,8 +1418,7 @@ static int qcom_pcie_probe(struct platform_device *pdev)
goto err_pm_runtime_put;
}
- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "elbi");
- pcie->elbi = devm_ioremap_resource(dev, res);
+ pcie->elbi = devm_platform_ioremap_resource_byname(pdev, "elbi");
if (IS_ERR(pcie->elbi)) {
ret = PTR_ERR(pcie->elbi);
goto err_pm_runtime_put;
@@ -1426,6 +1471,7 @@ err_pm_runtime_put:
static const struct of_device_id qcom_pcie_match[] = {
{ .compatible = "qcom,pcie-apq8084", .data = &ops_1_0_0 },
{ .compatible = "qcom,pcie-ipq8064", .data = &ops_2_1_0 },
+ { .compatible = "qcom,pcie-ipq8064-v2", .data = &ops_2_1_0 },
{ .compatible = "qcom,pcie-apq8064", .data = &ops_2_1_0 },
{ .compatible = "qcom,pcie-msm8996", .data = &ops_2_3_2 },
{ .compatible = "qcom,pcie-ipq8074", .data = &ops_2_3_3 },
diff --git a/drivers/pci/controller/dwc/pcie-uniphier.c b/drivers/pci/controller/dwc/pcie-uniphier.c
index a5401a0b1e58..3a7f403b57b8 100644
--- a/drivers/pci/controller/dwc/pcie-uniphier.c
+++ b/drivers/pci/controller/dwc/pcie-uniphier.c
@@ -416,8 +416,7 @@ static int uniphier_pcie_probe(struct platform_device *pdev)
if (IS_ERR(priv->pci.dbi_base))
return PTR_ERR(priv->pci.dbi_base);
- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "link");
- priv->base = devm_ioremap_resource(dev, res);
+ priv->base = devm_platform_ioremap_resource_byname(pdev, "link");
if (IS_ERR(priv->base))
return PTR_ERR(priv->base);