Merge tag 'pci-v6.18-fixes-3' of git://git.kernel.org/pub/scm/linux/kernel/git/pci/pci

Pull pci fixes from Bjorn Helgaas:

 - Add DWC custom pci_ops for the root bus instead of overwriting the
   DBI base address, which broke drivers that rely on the DBI address
   for iATU programming; fixes an FU740 probe regression (Krishna
   Chaitanya Chundru)

 - Revert qcom ECAM enablement, which is rendered unnecessary by the DWC
   custom pci_ops (Krishna Chaitanya Chundru)

 - Fix longstanding MIPS Malta resource registration issues to avoid
   exposing them when the next commit fixes the boot failure (Maciej W.
   Rozycki)

 - Use pcibios_align_resource() on MIPS Malta to fix boot failure caused
   by using the generic pci_enable_resources() (Ilpo Järvinen)

 - Enable only ASPM L0s and L1, not L1 PM Substates, for devicetree
   platforms because we lack information required to configure L1
   Substates; fixes regressions on powerpc and rockchip. A qcom
   regression (L1 Substates no longer enabled) remains and will be
   addressed next (Bjorn Helgaas)

* tag 'pci-v6.18-fixes-3' of git://git.kernel.org/pub/scm/linux/kernel/git/pci/pci:
  PCI/ASPM: Enable only L0s and L1 for devicetree platforms
  MIPS: Malta: Use pcibios_align_resource() to block io range
  MIPS: Malta: Fix PCI southbridge legacy resource reservations
  MIPS: Malta: Fix keyboard resource preventing i8042 driver from registering
  Revert "PCI: qcom: Prepare for the DWC ECAM enablement"
  PCI: dwc: Use custom pci_ops for root bus DBI vs ECAM config access
This commit is contained in:
Linus Torvalds
2025-10-24 16:43:08 -07:00
5 changed files with 36 additions and 101 deletions

View File

@@ -47,7 +47,7 @@ static struct resource standard_io_resources[] = {
.name = "keyboard",
.start = 0x60,
.end = 0x6f,
.flags = IORESOURCE_IO | IORESOURCE_BUSY
.flags = IORESOURCE_IO
},
{
.name = "dma page reg",
@@ -213,7 +213,7 @@ void __init plat_mem_setup(void)
/* Request I/O space for devices used on the Malta board. */
for (i = 0; i < ARRAY_SIZE(standard_io_resources); i++)
request_resource(&ioport_resource, standard_io_resources+i);
insert_resource(&ioport_resource, standard_io_resources + i);
/*
* Enable DMA channel 4 (cascade channel) in the PIIX4 south bridge.

View File

@@ -230,8 +230,7 @@ void __init mips_pcibios_init(void)
}
/* PIIX4 ACPI starts at 0x1000 */
if (controller->io_resource->start < 0x00001000UL)
controller->io_resource->start = 0x00001000UL;
PCIBIOS_MIN_IO = 0x1000;
iomem_resource.end &= 0xfffffffffULL; /* 64 GB */
ioport_resource.end = controller->io_resource->end;

View File

@@ -23,6 +23,7 @@
#include "pcie-designware.h"
static struct pci_ops dw_pcie_ops;
static struct pci_ops dw_pcie_ecam_ops;
static struct pci_ops dw_child_pcie_ops;
#define DW_PCIE_MSI_FLAGS_REQUIRED (MSI_FLAG_USE_DEF_DOM_OPS | \
@@ -471,9 +472,6 @@ static int dw_pcie_create_ecam_window(struct dw_pcie_rp *pp, struct resource *re
if (IS_ERR(pp->cfg))
return PTR_ERR(pp->cfg);
pci->dbi_base = pp->cfg->win;
pci->dbi_phys_addr = res->start;
return 0;
}
@@ -529,7 +527,7 @@ static int dw_pcie_host_get_resources(struct dw_pcie_rp *pp)
if (ret)
return ret;
pp->bridge->ops = (struct pci_ops *)&pci_generic_ecam_ops.pci_ops;
pp->bridge->ops = &dw_pcie_ecam_ops;
pp->bridge->sysdata = pp->cfg;
pp->cfg->priv = pp;
} else {
@@ -842,12 +840,34 @@ void __iomem *dw_pcie_own_conf_map_bus(struct pci_bus *bus, unsigned int devfn,
}
EXPORT_SYMBOL_GPL(dw_pcie_own_conf_map_bus);
static void __iomem *dw_pcie_ecam_conf_map_bus(struct pci_bus *bus, unsigned int devfn, int where)
{
struct pci_config_window *cfg = bus->sysdata;
struct dw_pcie_rp *pp = cfg->priv;
struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
unsigned int busn = bus->number;
if (busn > 0)
return pci_ecam_map_bus(bus, devfn, where);
if (PCI_SLOT(devfn) > 0)
return NULL;
return pci->dbi_base + where;
}
static struct pci_ops dw_pcie_ops = {
.map_bus = dw_pcie_own_conf_map_bus,
.read = pci_generic_config_read,
.write = pci_generic_config_write,
};
static struct pci_ops dw_pcie_ecam_ops = {
.map_bus = dw_pcie_ecam_conf_map_bus,
.read = pci_generic_config_read,
.write = pci_generic_config_write,
};
static int dw_pcie_iatu_setup(struct dw_pcie_rp *pp)
{
struct dw_pcie *pci = to_dw_pcie_from_pp(pp);

View File

@@ -55,7 +55,6 @@
#define PARF_AXI_MSTR_WR_ADDR_HALT_V2 0x1a8
#define PARF_Q2A_FLUSH 0x1ac
#define PARF_LTSSM 0x1b0
#define PARF_SLV_DBI_ELBI 0x1b4
#define PARF_INT_ALL_STATUS 0x224
#define PARF_INT_ALL_CLEAR 0x228
#define PARF_INT_ALL_MASK 0x22c
@@ -65,16 +64,6 @@
#define PARF_DBI_BASE_ADDR_V2_HI 0x354
#define PARF_SLV_ADDR_SPACE_SIZE_V2 0x358
#define PARF_SLV_ADDR_SPACE_SIZE_V2_HI 0x35c
#define PARF_BLOCK_SLV_AXI_WR_BASE 0x360
#define PARF_BLOCK_SLV_AXI_WR_BASE_HI 0x364
#define PARF_BLOCK_SLV_AXI_WR_LIMIT 0x368
#define PARF_BLOCK_SLV_AXI_WR_LIMIT_HI 0x36c
#define PARF_BLOCK_SLV_AXI_RD_BASE 0x370
#define PARF_BLOCK_SLV_AXI_RD_BASE_HI 0x374
#define PARF_BLOCK_SLV_AXI_RD_LIMIT 0x378
#define PARF_BLOCK_SLV_AXI_RD_LIMIT_HI 0x37c
#define PARF_ECAM_BASE 0x380
#define PARF_ECAM_BASE_HI 0x384
#define PARF_NO_SNOOP_OVERRIDE 0x3d4
#define PARF_ATU_BASE_ADDR 0x634
#define PARF_ATU_BASE_ADDR_HI 0x638
@@ -98,7 +87,6 @@
/* PARF_SYS_CTRL register fields */
#define MAC_PHY_POWERDOWN_IN_P2_D_MUX_EN BIT(29)
#define PCIE_ECAM_BLOCKER_EN BIT(26)
#define MST_WAKEUP_EN BIT(13)
#define SLV_WAKEUP_EN BIT(12)
#define MSTR_ACLK_CGC_DIS BIT(10)
@@ -146,9 +134,6 @@
/* PARF_LTSSM register fields */
#define LTSSM_EN BIT(8)
/* PARF_SLV_DBI_ELBI */
#define SLV_DBI_ELBI_ADDR_BASE GENMASK(11, 0)
/* PARF_INT_ALL_{STATUS/CLEAR/MASK} register fields */
#define PARF_INT_ALL_LINK_UP BIT(13)
#define PARF_INT_MSI_DEV_0_7 GENMASK(30, 23)
@@ -326,47 +311,6 @@ static void qcom_ep_reset_deassert(struct qcom_pcie *pcie)
qcom_perst_assert(pcie, false);
}
static void qcom_pci_config_ecam(struct dw_pcie_rp *pp)
{
struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
struct qcom_pcie *pcie = to_qcom_pcie(pci);
u64 addr, addr_end;
u32 val;
writel_relaxed(lower_32_bits(pci->dbi_phys_addr), pcie->parf + PARF_ECAM_BASE);
writel_relaxed(upper_32_bits(pci->dbi_phys_addr), pcie->parf + PARF_ECAM_BASE_HI);
/*
* The only device on the root bus is a single Root Port. If we try to
* access any devices other than Device/Function 00.0 on Bus 0, the TLP
* will go outside of the controller to the PCI bus. But with CFG Shift
* Feature (ECAM) enabled in iATU, there is no guarantee that the
* response is going to be all F's. Hence, to make sure that the
* requester gets all F's response for accesses other than the Root
* Port, configure iATU to block the transactions starting from
* function 1 of the root bus to the end of the root bus (i.e., from
* dbi_base + 4KB to dbi_base + 1MB).
*/
addr = pci->dbi_phys_addr + SZ_4K;
writel_relaxed(lower_32_bits(addr), pcie->parf + PARF_BLOCK_SLV_AXI_WR_BASE);
writel_relaxed(upper_32_bits(addr), pcie->parf + PARF_BLOCK_SLV_AXI_WR_BASE_HI);
writel_relaxed(lower_32_bits(addr), pcie->parf + PARF_BLOCK_SLV_AXI_RD_BASE);
writel_relaxed(upper_32_bits(addr), pcie->parf + PARF_BLOCK_SLV_AXI_RD_BASE_HI);
addr_end = pci->dbi_phys_addr + SZ_1M - 1;
writel_relaxed(lower_32_bits(addr_end), pcie->parf + PARF_BLOCK_SLV_AXI_WR_LIMIT);
writel_relaxed(upper_32_bits(addr_end), pcie->parf + PARF_BLOCK_SLV_AXI_WR_LIMIT_HI);
writel_relaxed(lower_32_bits(addr_end), pcie->parf + PARF_BLOCK_SLV_AXI_RD_LIMIT);
writel_relaxed(upper_32_bits(addr_end), pcie->parf + PARF_BLOCK_SLV_AXI_RD_LIMIT_HI);
val = readl_relaxed(pcie->parf + PARF_SYS_CTRL);
val |= PCIE_ECAM_BLOCKER_EN;
writel_relaxed(val, pcie->parf + PARF_SYS_CTRL);
}
static int qcom_pcie_start_link(struct dw_pcie *pci)
{
struct qcom_pcie *pcie = to_qcom_pcie(pci);
@@ -1320,7 +1264,6 @@ static int qcom_pcie_host_init(struct dw_pcie_rp *pp)
{
struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
struct qcom_pcie *pcie = to_qcom_pcie(pci);
u16 offset;
int ret;
qcom_ep_reset_assert(pcie);
@@ -1329,17 +1272,6 @@ static int qcom_pcie_host_init(struct dw_pcie_rp *pp)
if (ret)
return ret;
if (pp->ecam_enabled) {
/*
* Override ELBI when ECAM is enabled, as when ECAM is enabled,
* ELBI moves under the 'config' space.
*/
offset = FIELD_GET(SLV_DBI_ELBI_ADDR_BASE, readl(pcie->parf + PARF_SLV_DBI_ELBI));
pci->elbi_base = pci->dbi_base + offset;
qcom_pci_config_ecam(pp);
}
ret = qcom_pcie_phy_power_on(pcie);
if (ret)
goto err_deinit;

View File

@@ -243,8 +243,7 @@ struct pcie_link_state {
/* Clock PM state */
u32 clkpm_capable:1; /* Clock PM capable? */
u32 clkpm_enabled:1; /* Current Clock PM state */
u32 clkpm_default:1; /* Default Clock PM state by BIOS or
override */
u32 clkpm_default:1; /* Default Clock PM state by BIOS */
u32 clkpm_disable:1; /* Clock PM disabled */
};
@@ -376,18 +375,6 @@ static void pcie_set_clkpm(struct pcie_link_state *link, int enable)
pcie_set_clkpm_nocheck(link, enable);
}
static void pcie_clkpm_override_default_link_state(struct pcie_link_state *link,
int enabled)
{
struct pci_dev *pdev = link->downstream;
/* For devicetree platforms, enable ClockPM by default */
if (of_have_populated_dt() && !enabled) {
link->clkpm_default = 1;
pci_info(pdev, "ASPM: DT platform, enabling ClockPM\n");
}
}
static void pcie_clkpm_cap_init(struct pcie_link_state *link, int blacklist)
{
int capable = 1, enabled = 1;
@@ -410,7 +397,6 @@ static void pcie_clkpm_cap_init(struct pcie_link_state *link, int blacklist)
}
link->clkpm_enabled = enabled;
link->clkpm_default = enabled;
pcie_clkpm_override_default_link_state(link, enabled);
link->clkpm_capable = capable;
link->clkpm_disable = blacklist ? 1 : 0;
}
@@ -811,19 +797,17 @@ static void pcie_aspm_override_default_link_state(struct pcie_link_state *link)
struct pci_dev *pdev = link->downstream;
u32 override;
/* For devicetree platforms, enable all ASPM states by default */
/* For devicetree platforms, enable L0s and L1 by default */
if (of_have_populated_dt()) {
link->aspm_default = PCIE_LINK_STATE_ASPM_ALL;
if (link->aspm_support & PCIE_LINK_STATE_L0S)
link->aspm_default |= PCIE_LINK_STATE_L0S;
if (link->aspm_support & PCIE_LINK_STATE_L1)
link->aspm_default |= PCIE_LINK_STATE_L1;
override = link->aspm_default & ~link->aspm_enabled;
if (override)
pci_info(pdev, "ASPM: DT platform, enabling%s%s%s%s%s%s%s\n",
FLAG(override, L0S_UP, " L0s-up"),
FLAG(override, L0S_DW, " L0s-dw"),
FLAG(override, L1, " L1"),
FLAG(override, L1_1, " ASPM-L1.1"),
FLAG(override, L1_2, " ASPM-L1.2"),
FLAG(override, L1_1_PCIPM, " PCI-PM-L1.1"),
FLAG(override, L1_2_PCIPM, " PCI-PM-L1.2"));
pci_info(pdev, "ASPM: default states%s%s\n",
FLAG(override, L0S, " L0s"),
FLAG(override, L1, " L1"));
}
}