Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

Merge branch 'pci/host-imx6' into next

* pci/host-imx6:
  PCI: imx6: Add regulator support
parents 85e4b30a c26ebe98
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -33,6 +33,10 @@ Optional properties:
- reset-gpio-active-high: If present then the reset sequence using the GPIO
  specified in the "reset-gpio" property is reversed (H=reset state,
  L=operation state).
- vpcie-supply: Should specify the regulator in charge of PCIe port power.
  The regulator will be enabled when initializing the PCIe host and
  disabled either as part of the init process or when shutting down the
  host.

Additional required properties for imx6sx-pcie:
- clock names: Must include the following additional entries:
+36 −1
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@
#include <linux/pci.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
#include <linux/resource.h>
#include <linux/signal.h>
#include <linux/types.h>
@@ -59,6 +60,7 @@ struct imx6_pcie {
	u32			tx_swing_full;
	u32			tx_swing_low;
	int			link_gen;
	struct regulator	*vpcie;
};

/* Parameters for the waiting for PCIe PHY PLL to lock on i.MX7 */
@@ -284,6 +286,8 @@ static int imx6q_pcie_abort_handler(unsigned long addr,

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

	switch (imx6_pcie->variant) {
	case IMX7D:
		reset_control_assert(imx6_pcie->pciephy_reset);
@@ -310,6 +314,14 @@ static void imx6_pcie_assert_core_reset(struct imx6_pcie *imx6_pcie)
				   IMX6Q_GPR1_PCIE_REF_CLK_EN, 0 << 16);
		break;
	}

	if (imx6_pcie->vpcie && regulator_is_enabled(imx6_pcie->vpcie) > 0) {
		int ret = regulator_disable(imx6_pcie->vpcie);

		if (ret)
			dev_err(dev, "failed to disable vpcie regulator: %d\n",
				ret);
	}
}

static int imx6_pcie_enable_ref_clk(struct imx6_pcie *imx6_pcie)
@@ -376,10 +388,19 @@ static void imx6_pcie_deassert_core_reset(struct imx6_pcie *imx6_pcie)
	struct device *dev = pci->dev;
	int ret;

	if (imx6_pcie->vpcie && !regulator_is_enabled(imx6_pcie->vpcie)) {
		ret = regulator_enable(imx6_pcie->vpcie);
		if (ret) {
			dev_err(dev, "failed to enable vpcie regulator: %d\n",
				ret);
			return;
		}
	}

	ret = clk_prepare_enable(imx6_pcie->pcie_phy);
	if (ret) {
		dev_err(dev, "unable to enable pcie_phy clock\n");
		return;
		goto err_pcie_phy;
	}

	ret = clk_prepare_enable(imx6_pcie->pcie_bus);
@@ -439,6 +460,13 @@ static void imx6_pcie_deassert_core_reset(struct imx6_pcie *imx6_pcie)
	clk_disable_unprepare(imx6_pcie->pcie_bus);
err_pcie_bus:
	clk_disable_unprepare(imx6_pcie->pcie_phy);
err_pcie_phy:
	if (imx6_pcie->vpcie && regulator_is_enabled(imx6_pcie->vpcie) > 0) {
		ret = regulator_disable(imx6_pcie->vpcie);
		if (ret)
			dev_err(dev, "failed to disable vpcie regulator: %d\n",
				ret);
	}
}

static void imx6_pcie_init_phy(struct imx6_pcie *imx6_pcie)
@@ -802,6 +830,13 @@ static int imx6_pcie_probe(struct platform_device *pdev)
	if (ret)
		imx6_pcie->link_gen = 1;

	imx6_pcie->vpcie = devm_regulator_get_optional(&pdev->dev, "vpcie");
	if (IS_ERR(imx6_pcie->vpcie)) {
		if (PTR_ERR(imx6_pcie->vpcie) == -EPROBE_DEFER)
			return -EPROBE_DEFER;
		imx6_pcie->vpcie = NULL;
	}

	platform_set_drvdata(pdev, imx6_pcie);

	ret = imx6_add_pcie_port(imx6_pcie, pdev);