aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBjorn Helgaas <bhelgaas@google.com>2026-06-23 17:32:07 -0500
committerBjorn Helgaas <bhelgaas@google.com>2026-06-23 17:32:07 -0500
commit87edaec536414bbc1461fb332f45782bb4d27cfd (patch)
tree3aa32eaaad88875ff4c5d2c13b3fb2b20af14cd1
parent878f37d6dea3f08814a92d0456bd30e032b87e21 (diff)
parente220b668b17f329476d0fcea6783bb06cceeca6d (diff)
Merge branch 'pci/controller/dwc-intel-gw'
- Enable clock before PHY init for correct ordering (Florian Eckert) - Add .start_link() callback so the driver works again (Florian Eckert) - Stop overwriting the ATU base address discovered by dw_pcie_get_resources() (Florian Eckert) - Add DT 'atu' region since this is hardware-specific, and fall back to driver default if lacking (Florian Eckert) * pci/controller/dwc-intel-gw: dt-bindings: PCI: intel,lgm-pcie: Add 'atu' resource PCI: intel-gw: Fix ATU base address setup and add optional DT 'atu' region PCI: intel-gw: Add .start_link() callback PCI: intel-gw: Enable clock before PHY init PCI: intel-gw: Move interrupt enable to own function PCI: intel-gw: Remove unused PCIE_APP_INTX_OFST definition
-rw-r--r--Documentation/devicetree/bindings/pci/intel-gw-pcie.yaml9
-rw-r--r--drivers/pci/controller/dwc/pcie-intel-gw.c74
2 files changed, 58 insertions, 25 deletions
diff --git a/Documentation/devicetree/bindings/pci/intel-gw-pcie.yaml b/Documentation/devicetree/bindings/pci/intel-gw-pcie.yaml
index 54e2890ae631..394bb46b38e6 100644
--- a/Documentation/devicetree/bindings/pci/intel-gw-pcie.yaml
+++ b/Documentation/devicetree/bindings/pci/intel-gw-pcie.yaml
@@ -27,16 +27,20 @@ properties:
- const: snps,dw-pcie
reg:
+ minItems: 3
items:
- description: Controller control and status registers.
- description: PCIe configuration registers.
- description: Controller application registers.
+ - description: Internal Address Translation Unit (iATU) registers.
reg-names:
+ minItems: 3
items:
- const: dbi
- const: config
- const: app
+ - const: atu
ranges:
maxItems: 1
@@ -95,8 +99,9 @@ examples:
#size-cells = <2>;
reg = <0xd0e00000 0x1000>,
<0xd2000000 0x800000>,
- <0xd0a41000 0x1000>;
- reg-names = "dbi", "config", "app";
+ <0xd0a41000 0x1000>,
+ <0xd0ec0000 0x1000>;
+ reg-names = "dbi", "config", "app", "atu";
linux,pci-domain = <0>;
max-link-speed = <4>;
bus-range = <0x00 0x08>;
diff --git a/drivers/pci/controller/dwc/pcie-intel-gw.c b/drivers/pci/controller/dwc/pcie-intel-gw.c
index c21906eced61..2674cd376f49 100644
--- a/drivers/pci/controller/dwc/pcie-intel-gw.c
+++ b/drivers/pci/controller/dwc/pcie-intel-gw.c
@@ -47,7 +47,6 @@
#define PCIE_APP_IRN_INTD BIT(16)
#define PCIE_APP_IRN_MSG_LTR BIT(18)
#define PCIE_APP_IRN_SYS_ERR_RC BIT(29)
-#define PCIE_APP_INTX_OFST 12
#define PCIE_APP_IRN_INT \
(PCIE_APP_IRN_AER_REPORT | PCIE_APP_IRN_PME | \
@@ -196,6 +195,13 @@ static void intel_pcie_device_rst_deassert(struct intel_pcie *pcie)
gpiod_set_value_cansleep(pcie->reset_gpio, 0);
}
+static void intel_pcie_core_irq_enable(struct intel_pcie *pcie)
+{
+ pcie_app_wr(pcie, PCIE_APP_IRNEN, 0);
+ pcie_app_wr(pcie, PCIE_APP_IRNCR, PCIE_APP_IRN_INT);
+ pcie_app_wr(pcie, PCIE_APP_IRNEN, PCIE_APP_IRN_INT);
+}
+
static void intel_pcie_core_irq_disable(struct intel_pcie *pcie)
{
pcie_app_wr(pcie, PCIE_APP_IRNEN, 0);
@@ -278,6 +284,16 @@ static void intel_pcie_turn_off(struct intel_pcie *pcie)
pcie_rc_cfg_wr_mask(pcie, PCI_COMMAND, PCI_COMMAND_MEMORY, 0);
}
+static int intel_pcie_start_link(struct dw_pcie *pci)
+{
+ struct intel_pcie *pcie = dev_get_drvdata(pci->dev);
+
+ intel_pcie_device_rst_deassert(pcie);
+ intel_pcie_ltssm_enable(pcie);
+
+ return 0;
+}
+
static int intel_pcie_host_setup(struct intel_pcie *pcie)
{
int ret;
@@ -285,49 +301,33 @@ static int intel_pcie_host_setup(struct intel_pcie *pcie)
intel_pcie_core_rst_assert(pcie);
intel_pcie_device_rst_assert(pcie);
-
- ret = phy_init(pcie->phy);
- if (ret)
- return ret;
-
intel_pcie_core_rst_deassert(pcie);
+ /* Controller clock must be provided earlier than PHY */
ret = clk_prepare_enable(pcie->core_clk);
if (ret) {
dev_err(pcie->pci.dev, "Core clock enable failed: %d\n", ret);
goto clk_err;
}
- pci->atu_base = pci->dbi_base + 0xC0000;
+ ret = phy_init(pcie->phy);
+ if (ret)
+ goto phy_err;
intel_pcie_ltssm_disable(pcie);
intel_pcie_link_setup(pcie);
intel_pcie_init_n_fts(pci);
- ret = dw_pcie_setup_rc(&pci->pp);
- if (ret)
- goto app_init_err;
-
dw_pcie_upconfig_setup(pci);
- intel_pcie_device_rst_deassert(pcie);
- intel_pcie_ltssm_enable(pcie);
-
- ret = dw_pcie_wait_for_link(pci);
- if (ret)
- goto app_init_err;
-
- /* Enable integrated interrupts */
- pcie_app_wr_mask(pcie, PCIE_APP_IRNEN, PCIE_APP_IRN_INT,
- PCIE_APP_IRN_INT);
+ intel_pcie_core_irq_enable(pcie);
return 0;
-app_init_err:
+phy_err:
clk_disable_unprepare(pcie->core_clk);
clk_err:
intel_pcie_core_rst_assert(pcie);
- phy_exit(pcie->phy);
return ret;
}
@@ -381,6 +381,7 @@ static int intel_pcie_rc_init(struct dw_pcie_rp *pp)
}
static const struct dw_pcie_ops intel_pcie_ops = {
+ .start_link = intel_pcie_start_link,
};
static const struct dw_pcie_host_ops intel_pcie_dw_ops = {
@@ -392,6 +393,7 @@ static int intel_pcie_probe(struct platform_device *pdev)
struct device *dev = &pdev->dev;
struct intel_pcie *pcie;
struct dw_pcie_rp *pp;
+ struct resource *res;
struct dw_pcie *pci;
int ret;
@@ -416,6 +418,32 @@ static int intel_pcie_probe(struct platform_device *pdev)
pci->ops = &intel_pcie_ops;
pp->ops = &intel_pcie_dw_ops;
+ /*
+ * If the 'atu' region is not available in the devicetree, use the
+ * default offset from DBI region for backwards compatibility. The
+ * 'atu' region should always be specified in the devicetree, as
+ * this is a hardware-specific address that should not be defined
+ * in the driver.
+ */
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "atu");
+ if (!res) {
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dbi");
+ pci->dbi_base = devm_pci_remap_cfg_resource(pci->dev, res);
+ if (IS_ERR(pci->dbi_base))
+ return PTR_ERR(pci->dbi_base);
+
+ pci->dbi_phys_addr = res->start;
+ pci->atu_base = devm_ioremap(dev, res->start + 0xC0000, SZ_4K);
+ if (!pci->atu_base) {
+ dev_err(dev, "failed to remap ATU space\n");
+ return -ENOMEM;
+ }
+
+ pci->atu_size = SZ_4K;
+ pci->atu_phys_addr = res->start + 0xC0000;
+ dev_warn(dev, "ATU region not specified in DT. Using default offset\n");
+ }
+
ret = dw_pcie_host_init(pp);
if (ret) {
dev_err(dev, "Cannot initialize host\n");