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
This commit is contained in:
commit
26418025ce
|
@ -5,6 +5,7 @@
|
|||
Value type: <stringlist>
|
||||
Definition: Value should contain
|
||||
- "qcom,pcie-ipq8064" for ipq8064
|
||||
- "qcom,pcie-ipq8064-v2" for ipq8064 rev 2 or ipq8065
|
||||
- "qcom,pcie-apq8064" for apq8064
|
||||
- "qcom,pcie-apq8084" for apq8084
|
||||
- "qcom,pcie-msm8996" for msm8996 or apq8096
|
||||
|
@ -90,6 +91,8 @@
|
|||
Definition: Should contain the following entries
|
||||
- "core" Clocks the pcie hw block
|
||||
- "phy" Clocks the pcie PHY block
|
||||
- "aux" Clocks the pcie AUX block
|
||||
- "ref" Clocks the pcie ref block
|
||||
- clock-names:
|
||||
Usage: required for apq8084/ipq4019
|
||||
Value type: <stringlist>
|
||||
|
@ -177,6 +180,7 @@
|
|||
- "pwr" PWR reset
|
||||
- "ahb" AHB reset
|
||||
- "phy_ahb" PHY AHB reset
|
||||
- "ext" EXT reset
|
||||
|
||||
- reset-names:
|
||||
Usage: required for ipq8074
|
||||
|
@ -277,14 +281,17 @@
|
|||
<0 0 0 4 &intc 0 39 IRQ_TYPE_LEVEL_HIGH>; /* int_d */
|
||||
clocks = <&gcc PCIE_A_CLK>,
|
||||
<&gcc PCIE_H_CLK>,
|
||||
<&gcc PCIE_PHY_CLK>;
|
||||
clock-names = "core", "iface", "phy";
|
||||
<&gcc PCIE_PHY_CLK>,
|
||||
<&gcc PCIE_AUX_CLK>,
|
||||
<&gcc PCIE_ALT_REF_CLK>;
|
||||
clock-names = "core", "iface", "phy", "aux", "ref";
|
||||
resets = <&gcc PCIE_ACLK_RESET>,
|
||||
<&gcc PCIE_HCLK_RESET>,
|
||||
<&gcc PCIE_POR_RESET>,
|
||||
<&gcc PCIE_PCI_RESET>,
|
||||
<&gcc PCIE_PHY_RESET>;
|
||||
reset-names = "axi", "ahb", "por", "pci", "phy";
|
||||
<&gcc PCIE_PHY_RESET>,
|
||||
<&gcc PCIE_EXT_RESET>;
|
||||
reset-names = "axi", "ahb", "por", "pci", "phy", "ext";
|
||||
pinctrl-0 = <&pcie_pins_default>;
|
||||
pinctrl-names = "default";
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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 = ®_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 = ®_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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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 },
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in New Issue