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

Merge branch 'remotes/lorenzo/pci/dwc'

- Use dmam_alloc_coherent() instead of dma_map_page() to allocate the MSI
  target page, which means dwc drivers will work even when ZONE_DMA32 is
  disabled (Will McVicker)

- If we can't allocate an MSI target page with a 32-bit address, try
  allocating one with a 64-bit address (Will McVicker)

- Switch from of_gpio_named_count() to generic gpiod_count() (Andy
  Shevchenko)

- Add support for i.MX8MP PCIe (Richard Zhu)

- Fix the Freescale i.MX8 PHY driver, which had interchanged the phy_init()
  and phy_power_on() interfaces (Richard Zhu)

* remotes/lorenzo/pci/dwc:
  phy: freescale: imx8m-pcie: Fix the wrong order of phy_init() and phy_power_on()
  PCI: imx6: Add i.MX8MP PCIe support
  PCI: dwc: Replace of_gpio_named_count() by gpiod_count()
  PCI: dwc: Drop dependency on ZONE_DMA32
parents 3de810ac cbcf8722
Loading
Loading
Loading
Loading
+28 −5
Original line number Diff line number Diff line
@@ -51,6 +51,7 @@ enum imx6_pcie_variants {
	IMX7D,
	IMX8MQ,
	IMX8MM,
	IMX8MP,
};

#define IMX6_PCIE_FLAG_IMX6_PHY			BIT(0)
@@ -61,6 +62,7 @@ struct imx6_pcie_drvdata {
	enum imx6_pcie_variants variant;
	u32 flags;
	int dbi_length;
	const char *gpr;
};

struct imx6_pcie {
@@ -150,7 +152,8 @@ struct imx6_pcie {
static unsigned int imx6_pcie_grp_offset(const struct imx6_pcie *imx6_pcie)
{
	WARN_ON(imx6_pcie->drvdata->variant != IMX8MQ &&
		imx6_pcie->drvdata->variant != IMX8MM);
		imx6_pcie->drvdata->variant != IMX8MM &&
		imx6_pcie->drvdata->variant != IMX8MP);
	return imx6_pcie->controller_id == 1 ? IOMUXC_GPR16 : IOMUXC_GPR14;
}

@@ -301,6 +304,7 @@ static void imx6_pcie_init_phy(struct imx6_pcie *imx6_pcie)
{
	switch (imx6_pcie->drvdata->variant) {
	case IMX8MM:
	case IMX8MP:
		/*
		 * The PHY initialization had been done in the PHY
		 * driver, break here directly.
@@ -558,6 +562,7 @@ static int imx6_pcie_enable_ref_clk(struct imx6_pcie *imx6_pcie)
		break;
	case IMX8MM:
	case IMX8MQ:
	case IMX8MP:
		ret = clk_prepare_enable(imx6_pcie->pcie_aux);
		if (ret) {
			dev_err(dev, "unable to enable pcie_aux clock\n");
@@ -602,6 +607,7 @@ static void imx6_pcie_disable_ref_clk(struct imx6_pcie *imx6_pcie)
		break;
	case IMX8MM:
	case IMX8MQ:
	case IMX8MP:
		clk_disable_unprepare(imx6_pcie->pcie_aux);
		break;
	default:
@@ -669,6 +675,7 @@ static void imx6_pcie_assert_core_reset(struct imx6_pcie *imx6_pcie)
		reset_control_assert(imx6_pcie->pciephy_reset);
		fallthrough;
	case IMX8MM:
	case IMX8MP:
		reset_control_assert(imx6_pcie->apps_reset);
		break;
	case IMX6SX:
@@ -744,6 +751,7 @@ static int imx6_pcie_deassert_core_reset(struct imx6_pcie *imx6_pcie)
		break;
	case IMX6Q:		/* Nothing to do */
	case IMX8MM:
	case IMX8MP:
		break;
	}

@@ -793,6 +801,7 @@ static void imx6_pcie_ltssm_enable(struct device *dev)
	case IMX7D:
	case IMX8MQ:
	case IMX8MM:
	case IMX8MP:
		reset_control_deassert(imx6_pcie->apps_reset);
		break;
	}
@@ -812,6 +821,7 @@ static void imx6_pcie_ltssm_disable(struct device *dev)
	case IMX7D:
	case IMX8MQ:
	case IMX8MM:
	case IMX8MP:
		reset_control_assert(imx6_pcie->apps_reset);
		break;
	}
@@ -935,7 +945,7 @@ static int imx6_pcie_host_init(struct dw_pcie_rp *pp)
	}

	if (imx6_pcie->phy) {
		ret = phy_power_on(imx6_pcie->phy);
		ret = phy_init(imx6_pcie->phy);
		if (ret) {
			dev_err(dev, "pcie PHY power up failed\n");
			goto err_clk_disable;
@@ -949,7 +959,7 @@ static int imx6_pcie_host_init(struct dw_pcie_rp *pp)
	}

	if (imx6_pcie->phy) {
		ret = phy_init(imx6_pcie->phy);
		ret = phy_power_on(imx6_pcie->phy);
		if (ret) {
			dev_err(dev, "waiting for PHY ready timeout!\n");
			goto err_phy_off;
@@ -961,7 +971,7 @@ static int imx6_pcie_host_init(struct dw_pcie_rp *pp)

err_phy_off:
	if (imx6_pcie->phy)
		phy_power_off(imx6_pcie->phy);
		phy_exit(imx6_pcie->phy);
err_clk_disable:
	imx6_pcie_clk_disable(imx6_pcie);
err_reg_disable:
@@ -1179,6 +1189,7 @@ static int imx6_pcie_probe(struct platform_device *pdev)
		}
		break;
	case IMX8MM:
	case IMX8MP:
		imx6_pcie->pcie_aux = devm_clk_get(dev, "pcie_aux");
		if (IS_ERR(imx6_pcie->pcie_aux))
			return dev_err_probe(dev, PTR_ERR(imx6_pcie->pcie_aux),
@@ -1216,7 +1227,7 @@ static int imx6_pcie_probe(struct platform_device *pdev)

	/* Grab GPR config register range */
	imx6_pcie->iomuxc_gpr =
		 syscon_regmap_lookup_by_compatible("fsl,imx6q-iomuxc-gpr");
		 syscon_regmap_lookup_by_compatible(imx6_pcie->drvdata->gpr);
	if (IS_ERR(imx6_pcie->iomuxc_gpr)) {
		dev_err(dev, "unable to find iomuxc registers\n");
		return PTR_ERR(imx6_pcie->iomuxc_gpr);
@@ -1295,12 +1306,14 @@ static const struct imx6_pcie_drvdata drvdata[] = {
		.flags = IMX6_PCIE_FLAG_IMX6_PHY |
			 IMX6_PCIE_FLAG_IMX6_SPEED_CHANGE,
		.dbi_length = 0x200,
		.gpr = "fsl,imx6q-iomuxc-gpr",
	},
	[IMX6SX] = {
		.variant = IMX6SX,
		.flags = IMX6_PCIE_FLAG_IMX6_PHY |
			 IMX6_PCIE_FLAG_IMX6_SPEED_CHANGE |
			 IMX6_PCIE_FLAG_SUPPORTS_SUSPEND,
		.gpr = "fsl,imx6q-iomuxc-gpr",
	},
	[IMX6QP] = {
		.variant = IMX6QP,
@@ -1308,17 +1321,26 @@ static const struct imx6_pcie_drvdata drvdata[] = {
			 IMX6_PCIE_FLAG_IMX6_SPEED_CHANGE |
			 IMX6_PCIE_FLAG_SUPPORTS_SUSPEND,
		.dbi_length = 0x200,
		.gpr = "fsl,imx6q-iomuxc-gpr",
	},
	[IMX7D] = {
		.variant = IMX7D,
		.flags = IMX6_PCIE_FLAG_SUPPORTS_SUSPEND,
		.gpr = "fsl,imx7d-iomuxc-gpr",
	},
	[IMX8MQ] = {
		.variant = IMX8MQ,
		.gpr = "fsl,imx8mq-iomuxc-gpr",
	},
	[IMX8MM] = {
		.variant = IMX8MM,
		.flags = IMX6_PCIE_FLAG_SUPPORTS_SUSPEND,
		.gpr = "fsl,imx8mm-iomuxc-gpr",
	},
	[IMX8MP] = {
		.variant = IMX8MP,
		.flags = IMX6_PCIE_FLAG_SUPPORTS_SUSPEND,
		.gpr = "fsl,imx8mp-iomuxc-gpr",
	},
};

@@ -1329,6 +1351,7 @@ static const struct of_device_id imx6_pcie_of_match[] = {
	{ .compatible = "fsl,imx7d-pcie",  .data = &drvdata[IMX7D],  },
	{ .compatible = "fsl,imx8mq-pcie", .data = &drvdata[IMX8MQ], },
	{ .compatible = "fsl,imx8mm-pcie", .data = &drvdata[IMX8MM], },
	{ .compatible = "fsl,imx8mp-pcie", .data = &drvdata[IMX8MP], },
	{},
};

+7 −21
Original line number Diff line number Diff line
@@ -267,15 +267,6 @@ static void dw_pcie_free_msi(struct dw_pcie_rp *pp)

	irq_domain_remove(pp->msi_domain);
	irq_domain_remove(pp->irq_domain);

	if (pp->msi_data) {
		struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
		struct device *dev = pci->dev;

		dma_unmap_page(dev, pp->msi_data, PAGE_SIZE, DMA_FROM_DEVICE);
		if (pp->msi_page)
			__free_page(pp->msi_page);
	}
}

static void dw_pcie_msi_init(struct dw_pcie_rp *pp)
@@ -336,6 +327,7 @@ static int dw_pcie_msi_host_init(struct dw_pcie_rp *pp)
	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
	struct device *dev = pci->dev;
	struct platform_device *pdev = to_platform_device(dev);
	u64 *msi_vaddr;
	int ret;
	u32 ctrl, num_ctrls;

@@ -375,22 +367,16 @@ static int dw_pcie_msi_host_init(struct dw_pcie_rp *pp)
						    dw_chained_msi_isr, pp);
	}

	ret = dma_set_mask(dev, DMA_BIT_MASK(32));
	ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32));
	if (ret)
		dev_warn(dev, "Failed to set DMA mask to 32-bit. Devices with only 32-bit MSI support may not work properly\n");

	pp->msi_page = alloc_page(GFP_DMA32);
	pp->msi_data = dma_map_page(dev, pp->msi_page, 0,
				    PAGE_SIZE, DMA_FROM_DEVICE);
	ret = dma_mapping_error(dev, pp->msi_data);
	if (ret) {
		dev_err(pci->dev, "Failed to map MSI data\n");
		__free_page(pp->msi_page);
		pp->msi_page = NULL;
		pp->msi_data = 0;
	msi_vaddr = dmam_alloc_coherent(dev, sizeof(u64), &pp->msi_data,
					GFP_KERNEL);
	if (!msi_vaddr) {
		dev_err(dev, "Failed to alloc and map MSI data\n");
		dw_pcie_free_msi(pp);

		return ret;
		return -ENOMEM;
	}

	return 0;
+0 −1
Original line number Diff line number Diff line
@@ -243,7 +243,6 @@ struct dw_pcie_rp {
	struct irq_domain	*irq_domain;
	struct irq_domain	*msi_domain;
	dma_addr_t		msi_data;
	struct page		*msi_page;
	struct irq_chip		*msi_irq_chip;
	u32			num_vectors;
	u32			irq_mask[MAX_MSI_CTRLS];
+2 −2
Original line number Diff line number Diff line
@@ -13,6 +13,7 @@
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/gpio.h>
#include <linux/gpio/consumer.h>
#include <linux/interrupt.h>
#include <linux/mfd/syscon.h>
#include <linux/of_address.h>
@@ -366,12 +367,11 @@ static int kirin_pcie_get_gpio_enable(struct kirin_pcie *pcie,
				      struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct device_node *np = dev->of_node;
	char name[32];
	int ret, i;

	/* This is an optional property */
	ret = of_gpio_named_count(np, "hisilicon,clken-gpios");
	ret = gpiod_count(dev, "hisilicon,clken");
	if (ret < 0)
		return 0;

+4 −4
Original line number Diff line number Diff line
@@ -59,7 +59,7 @@ struct imx8_pcie_phy {
	bool			clkreq_unused;
};

static int imx8_pcie_phy_init(struct phy *phy)
static int imx8_pcie_phy_power_on(struct phy *phy)
{
	int ret;
	u32 val, pad_mode;
@@ -137,14 +137,14 @@ static int imx8_pcie_phy_init(struct phy *phy)
	return ret;
}

static int imx8_pcie_phy_power_on(struct phy *phy)
static int imx8_pcie_phy_init(struct phy *phy)
{
	struct imx8_pcie_phy *imx8_phy = phy_get_drvdata(phy);

	return clk_prepare_enable(imx8_phy->clk);
}

static int imx8_pcie_phy_power_off(struct phy *phy)
static int imx8_pcie_phy_exit(struct phy *phy)
{
	struct imx8_pcie_phy *imx8_phy = phy_get_drvdata(phy);

@@ -155,8 +155,8 @@ static int imx8_pcie_phy_power_off(struct phy *phy)

static const struct phy_ops imx8_pcie_phy_ops = {
	.init		= imx8_pcie_phy_init,
	.exit		= imx8_pcie_phy_exit,
	.power_on	= imx8_pcie_phy_power_on,
	.power_off	= imx8_pcie_phy_power_off,
	.owner		= THIS_MODULE,
};