Commit ed1e2002 authored by Bjorn Helgaas's avatar Bjorn Helgaas
Browse files

Merge branch 'pci/controller/imx6'

- Add IMX8MQ_EP third 64-bit BAR in epc_features (Richard Zhu)

- Add IMX8MM_EP and IMX8MP_EP fixed 256-byte BAR 4 in epc_features (Richard
  Zhu)

- Factor imx_pcie_add_lut_by_rid() out of imx_pcie_enable_device() for use
  by LUT configuration (Frank Li)

- Configure LUT for MSI/IOMMU in Endpoint mode so Root Complex can trigger
  doorbel on Endpoint (Frank Li)

- Remove apps_reset (LTSSM_EN) from imx_pcie_{assert,deassert}_core_reset(),
  which fixes a hotplug regression on i.MX8MM (Richard Zhu)

- Delay Endpoint link start until configfs 'start' written (Richard Zhu)

* pci/controller/imx6:
  PCI: imx6: Delay link start until configfs 'start' written
  PCI: imx6: Remove apps_reset toggling from imx_pcie_{assert/deassert}_core_reset
  PCI: imx6: Add LUT configuration for MSI/IOMMU in Endpoint mode
  PCI: imx6: Add helper function imx_pcie_add_lut_by_rid()
  PCI: imx6: Add IMX8MM_EP and IMX8MP_EP fixed 256-byte BAR 4 in epc_features
  PCI: imx6: Add IMX8MQ_EP third 64-bit BAR in epc_features
parents 4cf17132 2e6ea706
Loading
Loading
Loading
Loading
+26 −14
Original line number Diff line number Diff line
@@ -860,7 +860,6 @@ static int imx95_pcie_core_reset(struct imx_pcie *imx_pcie, bool assert)
static void imx_pcie_assert_core_reset(struct imx_pcie *imx_pcie)
{
	reset_control_assert(imx_pcie->pciephy_reset);
	reset_control_assert(imx_pcie->apps_reset);

	if (imx_pcie->drvdata->core_reset)
		imx_pcie->drvdata->core_reset(imx_pcie, true);
@@ -872,7 +871,6 @@ static void imx_pcie_assert_core_reset(struct imx_pcie *imx_pcie)
static int imx_pcie_deassert_core_reset(struct imx_pcie *imx_pcie)
{
	reset_control_deassert(imx_pcie->pciephy_reset);
	reset_control_deassert(imx_pcie->apps_reset);

	if (imx_pcie->drvdata->core_reset)
		imx_pcie->drvdata->core_reset(imx_pcie, false);
@@ -1063,6 +1061,9 @@ static int imx_pcie_add_lut(struct imx_pcie *imx_pcie, u16 rid, u8 sid)
	data1 |= IMX95_PE0_LUT_VLD;
	regmap_write(imx_pcie->iomuxc_gpr, IMX95_PE0_LUT_DATA1, data1);

	if (imx_pcie->drvdata->mode == DW_PCIE_EP_TYPE)
		data2 = 0x7; /* In the EP mode, only 'Device ID' is required */
	else
		data2 = IMX95_PE0_LUT_MASK; /* Match all bits of RID */
	data2 |= FIELD_PREP(IMX95_PE0_LUT_REQID, rid);
	regmap_write(imx_pcie->iomuxc_gpr, IMX95_PE0_LUT_DATA2, data2);
@@ -1096,18 +1097,14 @@ static void imx_pcie_remove_lut(struct imx_pcie *imx_pcie, u16 rid)
	}
}

static int imx_pcie_enable_device(struct pci_host_bridge *bridge,
				  struct pci_dev *pdev)
static int imx_pcie_add_lut_by_rid(struct imx_pcie *imx_pcie, u32 rid)
{
	struct imx_pcie *imx_pcie = to_imx_pcie(to_dw_pcie_from_pp(bridge->sysdata));
	u32 sid_i, sid_m, rid = pci_dev_id(pdev);
	struct device *dev = imx_pcie->pci->dev;
	struct device_node *target;
	struct device *dev;
	u32 sid_i, sid_m;
	int err_i, err_m;
	u32 sid = 0;

	dev = imx_pcie->pci->dev;

	target = NULL;
	err_i = of_map_id(dev->of_node, rid, "iommu-map", "iommu-map-mask",
			  &target, &sid_i);
@@ -1182,6 +1179,13 @@ static int imx_pcie_enable_device(struct pci_host_bridge *bridge,
	return imx_pcie_add_lut(imx_pcie, rid, sid);
}

static int imx_pcie_enable_device(struct pci_host_bridge *bridge, struct pci_dev *pdev)
{
	struct imx_pcie *imx_pcie = to_imx_pcie(to_dw_pcie_from_pp(bridge->sysdata));

	return imx_pcie_add_lut_by_rid(imx_pcie, pci_dev_id(pdev));
}

static void imx_pcie_disable_device(struct pci_host_bridge *bridge,
				    struct pci_dev *pdev)
{
@@ -1247,6 +1251,9 @@ static int imx_pcie_host_init(struct dw_pcie_rp *pp)
		}
	}

	/* Make sure that PCIe LTSSM is cleared */
	imx_pcie_ltssm_disable(dev);

	ret = imx_pcie_deassert_core_reset(imx_pcie);
	if (ret < 0) {
		dev_err(dev, "pcie deassert core reset failed: %d\n", ret);
@@ -1385,6 +1392,8 @@ static const struct pci_epc_features imx8m_pcie_epc_features = {
	.msix_capable = false,
	.bar[BAR_1] = { .type = BAR_RESERVED, },
	.bar[BAR_3] = { .type = BAR_RESERVED, },
	.bar[BAR_4] = { .type = BAR_FIXED, .fixed_size = SZ_256, },
	.bar[BAR_5] = { .type = BAR_RESERVED, },
	.align = SZ_64K,
};

@@ -1465,9 +1474,6 @@ static int imx_add_pcie_ep(struct imx_pcie *imx_pcie,

	pci_epc_init_notify(ep->epc);

	/* Start LTSSM. */
	imx_pcie_ltssm_enable(dev);

	return 0;
}

@@ -1764,6 +1770,12 @@ static int imx_pcie_probe(struct platform_device *pdev)
		ret = imx_add_pcie_ep(imx_pcie, pdev);
		if (ret < 0)
			return ret;

		/*
		 * FIXME: Only single Device (EPF) is supported due to the
		 * Endpoint framework limitation.
		 */
		imx_pcie_add_lut_by_rid(imx_pcie, 0);
	} else {
		pci->pp.use_atu_msg = true;
		ret = dw_pcie_host_init(&pci->pp);
@@ -1912,7 +1924,7 @@ static const struct imx_pcie_drvdata drvdata[] = {
		.mode_mask[0] = IMX6Q_GPR12_DEVICE_TYPE,
		.mode_off[1] = IOMUXC_GPR12,
		.mode_mask[1] = IMX8MQ_GPR12_PCIE2_CTRL_DEVICE_TYPE,
		.epc_features = &imx8m_pcie_epc_features,
		.epc_features = &imx8q_pcie_epc_features,
		.init_phy = imx8mq_pcie_init_phy,
		.enable_ref_clk = imx8mm_pcie_enable_ref_clk,
	},