Commit 6a790bf0 authored by Bjorn Helgaas's avatar Bjorn Helgaas
Browse files

Merge branch 'remotes/lorenzo/pci/dwc'

  - Constify histb dw_pcie_host_ops structure (Julia Lawall)

  - Support multiple power domains for imx6 (Leonard Crestez)

  - Constify layerscape driver data (Stefan Agner)

  - Update imx6 Kconfig to allow imx6 PCIe in imx7 kernel (Trent Piepho)

  - Support armada8k GPIO reset (Baruch Siach)

  - Support suspend/resume support on imx6 (Leonard Crestez)

  - Don't hard-code DesignWare DBI/ATU offst (Stephen Warren)

  - Skip i.MX6 PHY setup on i.MX7D (Andrey Smirnov)

  - Remove Jianguo Sun from HiSilicon STB maintainers (Lorenzo Pieralisi)

* remotes/lorenzo/pci/dwc:
  MAINTAINERS: Remove Jianguo Sun from HiSilicon STB DWC entry
  PCI: dwc: Don't hard-code DBI/ATU offset
  PCI: imx: Add imx6sx suspend/resume support
  PCI: armada8k: Add support for gpio controlled reset signal
  PCI: dwc: Adjust Kconfig to allow IMX6 PCIe host on IMX7
  PCI: dwc: layerscape: Constify driver data
  PCI: imx: Add multi-pd support
  dt-bindings: imx6q-pcie: Add multi-pd bindings for imx6sx
  PCI: histb: Constify dw_pcie_host_ops structure
parents 33f3fd75 ffeccc22
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -41,7 +41,9 @@ Optional properties:
Additional required properties for imx6sx-pcie:
- clock names: Must include the following additional entries:
	- "pcie_inbound_axi"
- power-domains: Must be set to a phandle pointing to the PCIE_PHY power domain
- power-domains: Must be set to phandles pointing to the DISPLAY and
  PCIE_PHY power domains
- power-domain-names: Must be "pcie", "pcie_phy"

Additional required properties for imx7d-pcie:
- power-domains: Must be set to a phandle pointing to PCIE_PHY power domain
+0 −1
Original line number Diff line number Diff line
@@ -11549,7 +11549,6 @@ F: Documentation/devicetree/bindings/pci/kirin-pcie.txt
F:	drivers/pci/controller/dwc/pcie-kirin.c

PCIE DRIVER FOR HISILICON STB
M:	Jianguo Sun <sunjianguo1@huawei.com>
M:	Shawn Guo <shawn.guo@linaro.org>
L:	linux-pci@vger.kernel.org
S:	Maintained
+2 −2
Original line number Diff line number Diff line
@@ -89,8 +89,8 @@ config PCI_EXYNOS
	select PCIE_DW_HOST

config PCI_IMX6
	bool "Freescale i.MX6 PCIe controller"
	depends on SOC_IMX6Q || (ARM && COMPILE_TEST)
	bool "Freescale i.MX6/7 PCIe controller"
	depends on SOC_IMX6Q || SOC_IMX7D || (ARM && COMPILE_TEST)
	depends on PCI_MSI_IRQ_DOMAIN
	select PCIE_DW_HOST

+87 −5
Original line number Diff line number Diff line
@@ -27,6 +27,8 @@
#include <linux/types.h>
#include <linux/interrupt.h>
#include <linux/reset.h>
#include <linux/pm_domain.h>
#include <linux/pm_runtime.h>

#include "pcie-designware.h"

@@ -59,6 +61,11 @@ struct imx6_pcie {
	u32			tx_swing_low;
	int			link_gen;
	struct regulator	*vpcie;

	/* power domain for pcie */
	struct device		*pd_pcie;
	/* power domain for pcie phy */
	struct device		*pd_pcie_phy;
};

/* Parameters for the waiting for PCIe PHY PLL to lock on i.MX7 */
@@ -292,6 +299,43 @@ static int imx6q_pcie_abort_handler(unsigned long addr,
	return 1;
}

static int imx6_pcie_attach_pd(struct device *dev)
{
	struct imx6_pcie *imx6_pcie = dev_get_drvdata(dev);
	struct device_link *link;

	/* Do nothing when in a single power domain */
	if (dev->pm_domain)
		return 0;

	imx6_pcie->pd_pcie = dev_pm_domain_attach_by_name(dev, "pcie");
	if (IS_ERR(imx6_pcie->pd_pcie))
		return PTR_ERR(imx6_pcie->pd_pcie);
	link = device_link_add(dev, imx6_pcie->pd_pcie,
			DL_FLAG_STATELESS |
			DL_FLAG_PM_RUNTIME |
			DL_FLAG_RPM_ACTIVE);
	if (!link) {
		dev_err(dev, "Failed to add device_link to pcie pd.\n");
		return -EINVAL;
	}

	imx6_pcie->pd_pcie_phy = dev_pm_domain_attach_by_name(dev, "pcie_phy");
	if (IS_ERR(imx6_pcie->pd_pcie_phy))
		return PTR_ERR(imx6_pcie->pd_pcie_phy);

	device_link_add(dev, imx6_pcie->pd_pcie_phy,
			DL_FLAG_STATELESS |
			DL_FLAG_PM_RUNTIME |
			DL_FLAG_RPM_ACTIVE);
	if (IS_ERR(link)) {
		dev_err(dev, "Failed to add device_link to pcie_phy pd: %ld\n", PTR_ERR(link));
		return PTR_ERR(link);
	}

	return 0;
}

static void imx6_pcie_assert_core_reset(struct imx6_pcie *imx6_pcie)
{
	struct device *dev = imx6_pcie->pci->dev;
@@ -773,8 +817,28 @@ static void imx6_pcie_ltssm_disable(struct device *dev)

static void imx6_pcie_pm_turnoff(struct imx6_pcie *imx6_pcie)
{
	struct device *dev = imx6_pcie->pci->dev;

	/* Some variants have a turnoff reset in DT */
	if (imx6_pcie->turnoff_reset) {
		reset_control_assert(imx6_pcie->turnoff_reset);
		reset_control_deassert(imx6_pcie->turnoff_reset);
		goto pm_turnoff_sleep;
	}

	/* Others poke directly at IOMUXC registers */
	switch (imx6_pcie->variant) {
	case IMX6SX:
		regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
				IMX6SX_GPR12_PCIE_PM_TURN_OFF,
				IMX6SX_GPR12_PCIE_PM_TURN_OFF);
		regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
				IMX6SX_GPR12_PCIE_PM_TURN_OFF, 0);
		break;
	default:
		dev_err(dev, "PME_Turn_Off not implemented\n");
		return;
	}

	/*
	 * Components with an upstream port must respond to
@@ -783,6 +847,7 @@ static void imx6_pcie_pm_turnoff(struct imx6_pcie *imx6_pcie)
	 * The standard recommends a 1-10ms timeout after which to
	 * proceed anyway as if acks were received.
	 */
pm_turnoff_sleep:
	usleep_range(1000, 10000);
}

@@ -792,18 +857,31 @@ static void imx6_pcie_clk_disable(struct imx6_pcie *imx6_pcie)
	clk_disable_unprepare(imx6_pcie->pcie_phy);
	clk_disable_unprepare(imx6_pcie->pcie_bus);

	if (imx6_pcie->variant == IMX7D) {
	switch (imx6_pcie->variant) {
	case IMX6SX:
		clk_disable_unprepare(imx6_pcie->pcie_inbound_axi);
		break;
	case IMX7D:
		regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
				   IMX7D_GPR12_PCIE_PHY_REFCLK_SEL,
				   IMX7D_GPR12_PCIE_PHY_REFCLK_SEL);
		break;
	default:
		break;
	}
}

static inline bool imx6_pcie_supports_suspend(struct imx6_pcie *imx6_pcie)
{
	return (imx6_pcie->variant == IMX7D ||
		imx6_pcie->variant == IMX6SX);
}

static int imx6_pcie_suspend_noirq(struct device *dev)
{
	struct imx6_pcie *imx6_pcie = dev_get_drvdata(dev);

	if (imx6_pcie->variant != IMX7D)
	if (!imx6_pcie_supports_suspend(imx6_pcie))
		return 0;

	imx6_pcie_pm_turnoff(imx6_pcie);
@@ -819,7 +897,7 @@ static int imx6_pcie_resume_noirq(struct device *dev)
	struct imx6_pcie *imx6_pcie = dev_get_drvdata(dev);
	struct pcie_port *pp = &imx6_pcie->pci->pp;

	if (imx6_pcie->variant != IMX7D)
	if (!imx6_pcie_supports_suspend(imx6_pcie))
		return 0;

	imx6_pcie_assert_core_reset(imx6_pcie);
@@ -985,6 +1063,10 @@ static int imx6_pcie_probe(struct platform_device *pdev)

	platform_set_drvdata(pdev, imx6_pcie);

	ret = imx6_pcie_attach_pd(dev);
	if (ret)
		return ret;

	ret = imx6_add_pcie_port(imx6_pcie, pdev);
	if (ret < 0)
		return ret;
+5 −5
Original line number Diff line number Diff line
@@ -222,12 +222,12 @@ static const struct dw_pcie_ops dw_ls_pcie_ops = {
	.link_up = ls_pcie_link_up,
};

static struct ls_pcie_drvdata ls1021_drvdata = {
static const struct ls_pcie_drvdata ls1021_drvdata = {
	.ops = &ls1021_pcie_host_ops,
	.dw_pcie_ops = &dw_ls1021_pcie_ops,
};

static struct ls_pcie_drvdata ls1043_drvdata = {
static const struct ls_pcie_drvdata ls1043_drvdata = {
	.lut_offset = 0x10000,
	.ltssm_shift = 24,
	.lut_dbg = 0x7fc,
@@ -235,7 +235,7 @@ static struct ls_pcie_drvdata ls1043_drvdata = {
	.dw_pcie_ops = &dw_ls_pcie_ops,
};

static struct ls_pcie_drvdata ls1046_drvdata = {
static const struct ls_pcie_drvdata ls1046_drvdata = {
	.lut_offset = 0x80000,
	.ltssm_shift = 24,
	.lut_dbg = 0x407fc,
@@ -243,7 +243,7 @@ static struct ls_pcie_drvdata ls1046_drvdata = {
	.dw_pcie_ops = &dw_ls_pcie_ops,
};

static struct ls_pcie_drvdata ls2080_drvdata = {
static const struct ls_pcie_drvdata ls2080_drvdata = {
	.lut_offset = 0x80000,
	.ltssm_shift = 0,
	.lut_dbg = 0x7fc,
@@ -251,7 +251,7 @@ static struct ls_pcie_drvdata ls2080_drvdata = {
	.dw_pcie_ops = &dw_ls_pcie_ops,
};

static struct ls_pcie_drvdata ls2088_drvdata = {
static const struct ls_pcie_drvdata ls2088_drvdata = {
	.lut_offset = 0x80000,
	.ltssm_shift = 0,
	.lut_dbg = 0x407fc,
Loading