Commit 2506419e authored by Bjorn Helgaas's avatar Bjorn Helgaas
Browse files

Merge branch 'remotes/lorenzo/pci/dwc'

  - Add dra72x/dra74x/dra76x SoC compatible strings (Kishon Vijay
    Abraham I)

  - Enable x2 mode support for dra72x/dra74x/dra76x SoC (Kishon Vijay
    Abraham I)

  - Configure dra7xx PHY to PCIe mode (Kishon Vijay Abraham I)

  - Simplify dwc (remove unnecessary header includes, name variables
    consistently, reduce inverted logic, etc) (Gustavo Pimentel)

  - Add i.MX8MQ support (Andrey Smirnov)

  - Add message to help debug dwc MSI-X mask bit errors (Gustavo Pimentel)

  - Work around imx7d PCIe PLL erratum (Trent Piepho)

  - Don't assert qcom reset GPIO during probe (Bjorn Andersson)

  - Skip dwc MSI init if MSIs have been disabled (Lucas Stach)

* remotes/lorenzo/pci/dwc:
  PCI: dwc: skip MSI init if MSIs have been explicitly disabled
  PCI: dwc: Remove superfluous shifting in definitions
  PCI: dwc: Make use of GENMASK/FIELD_PREP
  PCI: dwc: Make use of BIT() in constant definitions
  PCI: dwc: Share code for dw_pcie_rd/wr_other_conf()
  PCI: dwc: Make use of IS_ALIGNED()
  PCI: imx6: Add code to request/control "pcie_aux" clock for i.MX8MQ
  dt-bindings: imx6q-pcie: Add "pcie_aux" clock for imx8mq
  PCI: qcom: Don't deassert reset GPIO during probe
  PCI: imx: Add workaround for e10728, IMX7d PCIe PLL failure
  ARM: dts: imx7d: Add node for PCIe PHY
  dt-bindings: imx6q-pcie: Add description of imx7d pcie phy
  PCI: dwc: Print debug error message when MSI-X entry control mask bit is set
  PCI: imx6: Add support for i.MX8MQ
  PCI: imx6: Convert DIRECT_SPEED_CHANGE quirk code to use a flag
  PCI: imx6: Mark PHY functions as i.MX6 specific
  PCI: imx6: Introduce drvdata
  PCI: dwc: Replace bit rotation operation (1 << bit) with BIT(bit)
  PCI: dwc: Improve code readability and simplify mask/unmask operations
  PCI: dwc: Rename variable name from data to d on dw_pcie_irq_domain_free()
  PCI: dwc: Rename variable name from data to d on dw_pci_msi_set_affinity()
  PCI: dwc: Rename variable name from data to d on dw_pci_setup_msi_msg()
  PCI: dwc: Rename variable name from data to d on dw_pci_bottom_mask/unmask()
  PCI: dwc: Remove unnecessary header include (signal.h)
  PCI: dwc: Remove unnecessary header include (of_gpio.h)
  PCI: dwc: dra7xx: Invoke phy_set_mode() API to set PHY mode to PHY_MODE_PCIE
  PCI: dwc: dra7xx: Enable x2 mode support for dra74x, dra76x and dra72x
  dt-bindings: PCI: dra7xx: Add properties to enable x2 lane in dra7
  dt-bindings: PCI: dra7xx: Add SoC specific compatible strings
parents 0c65bb7a 3afc8299
Loading
Loading
Loading
Loading
+17 −1
Original line number Diff line number Diff line
@@ -9,6 +9,7 @@ Required properties:
	- "fsl,imx6sx-pcie",
	- "fsl,imx6qp-pcie"
	- "fsl,imx7d-pcie"
	- "fsl,imx8mq-pcie"
- reg: base address and length of the PCIe controller
- interrupts: A list of interrupt outputs of the controller. Must contain an
  entry for each entry in the interrupt-names property.
@@ -45,7 +46,7 @@ Additional required properties for imx6sx-pcie:
  PCIE_PHY power domains
- power-domain-names: Must be "pcie", "pcie_phy"

Additional required properties for imx7d-pcie:
Additional required properties for imx7d-pcie and imx8mq-pcie:
- power-domains: Must be set to a phandle pointing to PCIE_PHY power domain
- resets: Must contain phandles to PCIe-related reset lines exposed by SRC
  IP block
@@ -53,6 +54,11 @@ Additional required properties for imx7d-pcie:
	       - "pciephy"
	       - "apps"
	       - "turnoff"
- fsl,imx7d-pcie-phy: A phandle to an fsl,imx7d-pcie-phy node.

Additional required properties for imx8mq-pcie:
- clock-names: Must include the following additional entries:
	- "pcie_aux"

Example:

@@ -79,3 +85,13 @@ Example:
		clocks = <&clks 144>, <&clks 206>, <&clks 189>;
		clock-names = "pcie", "pcie_bus", "pcie_phy";
	};

* Freescale i.MX7d PCIe PHY

This is the PHY associated with the IMX7d PCIe controller.  It's used by the
PCI-e controller via the fsl,imx7d-pcie-phy phandle.

Required properties:
- compatible:
	- "fsl,imx7d-pcie-phy"
- reg: base address and length of the PCIe PHY controller
+9 −2
Original line number Diff line number Diff line
TI PCI Controllers

PCIe DesignWare Controller
 - compatible: Should be "ti,dra7-pcie" for RC
	       Should be "ti,dra7-pcie-ep" for EP
 - compatible: Should be "ti,dra7-pcie" for RC (deprecated)
	       Should be "ti,dra7-pcie-ep" for EP (deprecated)
	       Should be "ti,dra746-pcie-rc" for dra74x/dra76 in RC mode
	       Should be "ti,dra746-pcie-ep" for dra74x/dra76 in EP mode
	       Should be "ti,dra726-pcie-rc" for dra72x in RC mode
	       Should be "ti,dra726-pcie-ep" for dra72x in EP mode
 - phys : list of PHY specifiers (used by generic PHY framework)
 - phy-names : must be "pcie-phy0", "pcie-phy1", "pcie-phyN".. based on the
	       number of PHYs as specified in *phys* property.
 - ti,hwmods : Name of the hwmod associated to the pcie, "pcie<X>",
	       where <X> is the instance number of the pcie from the HW spec.
 - num-lanes as specified in ../designware-pcie.txt
 - ti,syscon-lane-sel : phandle/offset pair. Phandle to the system control
			module and the register offset to specify lane
			selection.

HOST MODE
=========
+9 −0
Original line number Diff line number Diff line
@@ -96,6 +96,14 @@
	};
};

&aips2 {
	pcie_phy: pcie-phy@306d0000 {
		  compatible = "fsl,imx7d-pcie-phy";
		  reg = <0x306d0000 0x10000>;
		  status = "disabled";
	};
};

&aips3 {
	usbotg2: usb@30b20000 {
		compatible = "fsl,imx7d-usb", "fsl,imx27-usb";
@@ -173,6 +181,7 @@
			 <&src IMX7_RESET_PCIE_CTRL_APPS_EN>,
			 <&src IMX7_RESET_PCIE_CTRL_APPS_TURNOFF>;
		reset-names = "pciephy", "apps", "turnoff";
		fsl,imx7d-pcie-phy = <&pcie_phy>;
		status = "disabled";
	};
};
+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/7 PCIe controller"
	depends on SOC_IMX6Q || SOC_IMX7D || (ARM && COMPILE_TEST)
	bool "Freescale i.MX6/7/8 PCIe controller"
	depends on SOC_IMX6Q || SOC_IMX7D || (ARM64 && ARCH_MXC) || COMPILE_TEST
	depends on PCI_MSI_IRQ_DOMAIN
	select PCIE_DW_HOST

+81 −0
Original line number Diff line number Diff line
@@ -81,6 +81,10 @@
#define MSI_REQ_GRANT					BIT(0)
#define MSI_VECTOR_SHIFT				7

#define PCIE_1LANE_2LANE_SELECTION			BIT(13)
#define PCIE_B1C0_MODE_SEL				BIT(2)
#define PCIE_B0_B1_TSYNCEN				BIT(0)

struct dra7xx_pcie {
	struct dw_pcie		*pci;
	void __iomem		*base;		/* DT ti_conf */
@@ -93,6 +97,7 @@ struct dra7xx_pcie {

struct dra7xx_pcie_of_data {
	enum dw_pcie_device_mode mode;
	u32 b1co_mode_sel_mask;
};

#define to_dra7xx_pcie(x)	dev_get_drvdata((x)->dev)
@@ -499,6 +504,10 @@ static int dra7xx_pcie_enable_phy(struct dra7xx_pcie *dra7xx)
	int i;

	for (i = 0; i < phy_count; i++) {
		ret = phy_set_mode(dra7xx->phy[i], PHY_MODE_PCIE);
		if (ret < 0)
			goto err_phy;

		ret = phy_init(dra7xx->phy[i]);
		if (ret < 0)
			goto err_phy;
@@ -529,6 +538,26 @@ static const struct dra7xx_pcie_of_data dra7xx_pcie_ep_of_data = {
	.mode = DW_PCIE_EP_TYPE,
};

static const struct dra7xx_pcie_of_data dra746_pcie_rc_of_data = {
	.b1co_mode_sel_mask = BIT(2),
	.mode = DW_PCIE_RC_TYPE,
};

static const struct dra7xx_pcie_of_data dra726_pcie_rc_of_data = {
	.b1co_mode_sel_mask = GENMASK(3, 2),
	.mode = DW_PCIE_RC_TYPE,
};

static const struct dra7xx_pcie_of_data dra746_pcie_ep_of_data = {
	.b1co_mode_sel_mask = BIT(2),
	.mode = DW_PCIE_EP_TYPE,
};

static const struct dra7xx_pcie_of_data dra726_pcie_ep_of_data = {
	.b1co_mode_sel_mask = GENMASK(3, 2),
	.mode = DW_PCIE_EP_TYPE,
};

static const struct of_device_id of_dra7xx_pcie_match[] = {
	{
		.compatible = "ti,dra7-pcie",
@@ -538,6 +567,22 @@ static const struct of_device_id of_dra7xx_pcie_match[] = {
		.compatible = "ti,dra7-pcie-ep",
		.data = &dra7xx_pcie_ep_of_data,
	},
	{
		.compatible = "ti,dra746-pcie-rc",
		.data = &dra746_pcie_rc_of_data,
	},
	{
		.compatible = "ti,dra726-pcie-rc",
		.data = &dra726_pcie_rc_of_data,
	},
	{
		.compatible = "ti,dra746-pcie-ep",
		.data = &dra746_pcie_ep_of_data,
	},
	{
		.compatible = "ti,dra726-pcie-ep",
		.data = &dra726_pcie_ep_of_data,
	},
	{},
};

@@ -583,6 +628,34 @@ static int dra7xx_pcie_unaligned_memaccess(struct device *dev)
	return ret;
}

static int dra7xx_pcie_configure_two_lane(struct device *dev,
					  u32 b1co_mode_sel_mask)
{
	struct device_node *np = dev->of_node;
	struct regmap *pcie_syscon;
	unsigned int pcie_reg;
	u32 mask;
	u32 val;

	pcie_syscon = syscon_regmap_lookup_by_phandle(np, "ti,syscon-lane-sel");
	if (IS_ERR(pcie_syscon)) {
		dev_err(dev, "unable to get ti,syscon-lane-sel\n");
		return -EINVAL;
	}

	if (of_property_read_u32_index(np, "ti,syscon-lane-sel", 1,
				       &pcie_reg)) {
		dev_err(dev, "couldn't get lane selection reg offset\n");
		return -EINVAL;
	}

	mask = b1co_mode_sel_mask | PCIE_B0_B1_TSYNCEN;
	val = PCIE_B1C0_MODE_SEL | PCIE_B0_B1_TSYNCEN;
	regmap_update_bits(pcie_syscon, pcie_reg, mask, val);

	return 0;
}

static int __init dra7xx_pcie_probe(struct platform_device *pdev)
{
	u32 reg;
@@ -603,6 +676,7 @@ static int __init dra7xx_pcie_probe(struct platform_device *pdev)
	const struct of_device_id *match;
	const struct dra7xx_pcie_of_data *data;
	enum dw_pcie_device_mode mode;
	u32 b1co_mode_sel_mask;

	match = of_match_device(of_match_ptr(of_dra7xx_pcie_match), dev);
	if (!match)
@@ -610,6 +684,7 @@ static int __init dra7xx_pcie_probe(struct platform_device *pdev)

	data = (struct dra7xx_pcie_of_data *)match->data;
	mode = (enum dw_pcie_device_mode)data->mode;
	b1co_mode_sel_mask = data->b1co_mode_sel_mask;

	dra7xx = devm_kzalloc(dev, sizeof(*dra7xx), GFP_KERNEL);
	if (!dra7xx)
@@ -665,6 +740,12 @@ static int __init dra7xx_pcie_probe(struct platform_device *pdev)
	dra7xx->pci = pci;
	dra7xx->phy_count = phy_count;

	if (phy_count == 2) {
		ret = dra7xx_pcie_configure_two_lane(dev, b1co_mode_sel_mask);
		if (ret < 0)
			dra7xx->phy_count = 1; /* Fallback to x1 lane mode */
	}

	ret = dra7xx_pcie_enable_phy(dra7xx);
	if (ret) {
		dev_err(dev, "failed to enable phy\n");
Loading