Commit 31009296 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
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
parents 7083bb60 df5192d9
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -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.
+1 −2
Original line number Diff line number Diff line
@@ -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;
+24 −4
Original line number Diff line number Diff line
@@ -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);
+0 −68
Original line number Diff line number Diff line
@@ -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;
+9 −25
Original line number Diff line number Diff line
@@ -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"));
	}
}