diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2020-10-22 12:41:00 -0700 | 
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2020-10-22 12:41:00 -0700 | 
| commit | 00937f36b09e89c74e4a059dbb8acbf4b971d5eb (patch) | |
| tree | ff2e5f5fa6736460437f57680405a20124d1e969 /drivers/pci/controller/dwc/pci-imx6.c | |
| parent | 96485e4462604744d66bf4301557d996d80b85eb (diff) | |
| parent | 28e34e751f6c50098d9bcecb30c97634b6126730 (diff) | |
Merge tag 'pci-v5.10-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci
Pull PCI updates from Bjorn Helgaas:
 "Enumeration:
   - Print IRQ number used by PCIe Link Bandwidth Notification (Dongdong
     Liu)
   - Add schedule point in pci_read_config() to reduce max latency
     (Jiang Biao)
   - Add Kconfig options for MPS/MRRS strategy (Jim Quinlan)
  Resource management:
   - Fix pci_iounmap() memory leak when !CONFIG_GENERIC_IOMAP (Lorenzo
     Pieralisi)
  PCIe native device hotplug:
   - Reduce noisiness on hot removal (Lukas Wunner)
  Power management:
   - Revert "PCI/PM: Apply D2 delay as milliseconds, not microseconds"
     that was done on the basis of spec typo (Bjorn Helgaas)
   - Rename pci_dev.d3_delay to d3hot_delay to remove D3hot/D3cold
     ambiguity (Krzysztof Wilczyński)
   - Remove unused pcibios_pm_ops (Vaibhav Gupta)
  IOMMU:
   - Enable Translation Blocking for external devices to harden against
     DMA attacks (Rajat Jain)
  Error handling:
   - Add an ACPI APEI notifier chain for vendor CPER records to enable
     device-specific error handling (Shiju Jose)
  ASPM:
   - Remove struct aspm_register_info to simplify code (Saheed O.
     Bolarinwa)
  Amlogic Meson PCIe controller driver:
   - Build as module by default (Kevin Hilman)
  Ampere Altra PCIe controller driver:
   - Add MCFG quirk to work around non-standard ECAM implementation
     (Tuan Phan)
  Broadcom iProc PCIe controller driver:
   - Set affinity mask on MSI interrupts (Mark Tomlinson)
  Broadcom STB PCIe controller driver:
   - Make PCIE_BRCMSTB depend on ARCH_BRCMSTB (Jim Quinlan)
   - Add DT bindings for more Brcmstb chips (Jim Quinlan)
   - Add bcm7278 register info (Jim Quinlan)
   - Add bcm7278 PERST# support (Jim Quinlan)
   - Add suspend and resume pm_ops (Jim Quinlan)
   - Add control of rescal reset (Jim Quinlan)
   - Set additional internal memory DMA viewport sizes (Jim Quinlan)
   - Accommodate MSI for older chips (Jim Quinlan)
   - Set bus max burst size by chip type (Jim Quinlan)
   - Add support for bcm7211, bcm7216, bcm7445, bcm7278 (Jim Quinlan)
  Freescale i.MX6 PCIe controller driver:
   - Use dev_err_probe() to reduce redundant messages (Anson Huang)
  Freescale Layerscape PCIe controller driver:
   - Enforce 4K DMA buffer alignment in endpoint test (Hou Zhiqiang)
   - Add DT compatible strings for ls1088a, ls2088a (Xiaowei Bao)
   - Add endpoint support for ls1088a, ls2088a (Xiaowei Bao)
   - Add endpoint test support for lS1088a (Xiaowei Bao)
   - Add MSI-X support for ls1088a (Xiaowei Bao)
  HiSilicon HIP PCIe controller driver:
   - Handle HIP-specific errors via ACPI APEI (Yicong Yang)
  HiSilicon Kirin PCIe controller driver:
   - Return -EPROBE_DEFER if the GPIO isn't ready (Bean Huo)
  Intel VMD host bridge driver:
   - Factor out physical offset, bus offset, IRQ domain, IRQ allocation
     (Jon Derrick)
   - Use generic PCI PM correctly (Jon Derrick)
  Marvell Aardvark PCIe controller driver:
   - Fix compilation on s390 (Pali Rohár)
   - Implement driver 'remove' function and allow to build it as module
     (Pali Rohár)
   - Move PCIe reset card code to advk_pcie_train_link() (Pali Rohár)
   - Convert mvebu a3700 internal SMCC firmware return codes to errno
     (Pali Rohár)
   - Fix initialization with old Marvell's Arm Trusted Firmware (Pali
     Rohár)
  Microsoft Hyper-V host bridge driver:
   - Fix hibernation in case interrupts are not re-created (Dexuan Cui)
  NVIDIA Tegra PCIe controller driver:
   - Stop checking return value of debugfs_create() functions (Greg
     Kroah-Hartman)
   - Convert to use DEFINE_SEQ_ATTRIBUTE macro (Liu Shixin)
  Qualcomm PCIe controller driver:
   - Reset PCIe to work around Qsdk U-Boot issue (Ansuel Smith)
  Renesas R-Car PCIe controller driver:
   - Add DT documentation for r8a774a1, r8a774b1, r8a774e1 endpoints
     (Lad Prabhakar)
   - Add RZ/G2M, RZ/G2N, RZ/G2H IDs to endpoint test (Lad Prabhakar)
   - Add DT support for r8a7742 (Lad Prabhakar)
  Socionext UniPhier Pro5 controller driver:
   - Add DT descriptions of iATU register (host and endpoint) (Kunihiko
     Hayashi)
  Synopsys DesignWare PCIe controller driver:
   - Add link up check in dw_child_pcie_ops.map_bus() (racy, but seems
     unavoidable) (Hou Zhiqiang)
   - Fix endpoint Header Type check so multi-function devices work (Hou
     Zhiqiang)
   - Skip PCIE_MSI_INTR0* programming if MSI is disabled (Jisheng Zhang)
   - Stop leaking MSI page in suspend/resume (Jisheng Zhang)
   - Add common iATU register support instead of keystone-specific code
     (Kunihiko Hayashi)
   - Major config space access and other cleanups in dwc core and
     drivers that use it (al, exynos, histb, imx6, intel-gw, keystone,
     kirin, meson, qcom, tegra) (Rob Herring)
   - Add multiple PFs support for endpoint (Xiaowei Bao)
   - Add MSI-X doorbell mode in endpoint mode (Xiaowei Bao)
  Miscellaneous:
   - Use fallthrough pseudo-keyword (Gustavo A. R. Silva)
   - Fix "0 used as NULL pointer" warnings (Gustavo Pimentel)
   - Fix "cast truncates bits from constant value" warnings (Gustavo
     Pimentel)
   - Remove redundant zeroing for sg_init_table() (Julia Lawall)
   - Use scnprintf(), not snprintf(), in sysfs "show" functions
     (Krzysztof Wilczyński)
   - Remove unused assignments (Krzysztof Wilczyński)
   - Fix "0 used as NULL pointer" warning (Krzysztof Wilczyński)
   - Simplify bool comparisons (Krzysztof Wilczyński)
   - Use for_each_child_of_node() and for_each_node_by_name() (Qinglang
     Miao)
   - Simplify return expressions (Qinglang Miao)"
* tag 'pci-v5.10-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci: (147 commits)
  PCI: vmd: Update VMD PM to correctly use generic PCI PM
  PCI: vmd: Create IRQ allocation helper
  PCI: vmd: Create IRQ Domain configuration helper
  PCI: vmd: Create bus offset configuration helper
  PCI: vmd: Create physical offset helper
  PCI: v3-semi: Remove unneeded break
  PCI: dwc: Add link up check in dw_child_pcie_ops.map_bus()
  PCI/ASPM: Remove struct pcie_link_state.l1ss
  PCI/ASPM: Remove struct aspm_register_info.l1ss_cap
  PCI/ASPM: Pass L1SS Capabilities value, not struct aspm_register_info
  PCI/ASPM: Remove struct aspm_register_info.l1ss_ctl1
  PCI/ASPM: Remove struct aspm_register_info.l1ss_ctl2 (unused)
  PCI/ASPM: Remove struct aspm_register_info.l1ss_cap_ptr
  PCI/ASPM: Remove struct aspm_register_info.latency_encoding
  PCI/ASPM: Remove struct aspm_register_info.enabled
  PCI/ASPM: Remove struct aspm_register_info.support
  PCI/ASPM: Use 'parent' and 'child' for readability
  PCI/ASPM: Move LTR path check to where it's used
  PCI/ASPM: Move pci_clear_and_set_dword() earlier
  PCI: dwc: Fix MSI page leakage in suspend/resume
  ...
Diffstat (limited to 'drivers/pci/controller/dwc/pci-imx6.c')
| -rw-r--r-- | drivers/pci/controller/dwc/pci-imx6.c | 87 | 
1 files changed, 33 insertions, 54 deletions
diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c index 5fef2613b223..5cf1ef12fb9b 100644 --- a/drivers/pci/controller/dwc/pci-imx6.c +++ b/drivers/pci/controller/dwc/pci-imx6.c @@ -79,7 +79,6 @@ struct imx6_pcie {  	u32			tx_deemph_gen2_6db;  	u32			tx_swing_full;  	u32			tx_swing_low; -	int			link_gen;  	struct regulator	*vpcie;  	void __iomem		*phy_base; @@ -94,15 +93,6 @@ struct imx6_pcie {  #define PHY_PLL_LOCK_WAIT_USLEEP_MAX	200  #define PHY_PLL_LOCK_WAIT_TIMEOUT	(2000 * PHY_PLL_LOCK_WAIT_USLEEP_MAX) -/* PCIe Root Complex registers (memory-mapped) */ -#define PCIE_RC_IMX6_MSI_CAP			0x50 -#define PCIE_RC_LCR				0x7c -#define PCIE_RC_LCR_MAX_LINK_SPEEDS_GEN1	0x1 -#define PCIE_RC_LCR_MAX_LINK_SPEEDS_GEN2	0x2 -#define PCIE_RC_LCR_MAX_LINK_SPEEDS_MASK	0xf - -#define PCIE_RC_LCSR				0x80 -  /* PCIe Port Logic registers (memory-mapped) */  #define PL_OFFSET 0x700 @@ -116,8 +106,6 @@ struct imx6_pcie {  #define PCIE_PHY_STAT (PL_OFFSET + 0x110)  #define PCIE_PHY_STAT_ACK		BIT(16) -#define PCIE_LINK_WIDTH_SPEED_CONTROL	0x80C -  /* PHY registers (not memory-mapped) */  #define PCIE_PHY_ATEOVRD			0x10  #define  PCIE_PHY_ATEOVRD_EN			BIT(2) @@ -761,6 +749,7 @@ static int imx6_pcie_establish_link(struct imx6_pcie *imx6_pcie)  {  	struct dw_pcie *pci = imx6_pcie->pci;  	struct device *dev = pci->dev; +	u8 offset = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP);  	u32 tmp;  	int ret; @@ -769,10 +758,10 @@ static int imx6_pcie_establish_link(struct imx6_pcie *imx6_pcie)  	 * started in Gen2 mode, there is a possibility the devices on the  	 * bus will not be detected at all.  This happens with PCIe switches.  	 */ -	tmp = dw_pcie_readl_dbi(pci, PCIE_RC_LCR); -	tmp &= ~PCIE_RC_LCR_MAX_LINK_SPEEDS_MASK; -	tmp |= PCIE_RC_LCR_MAX_LINK_SPEEDS_GEN1; -	dw_pcie_writel_dbi(pci, PCIE_RC_LCR, tmp); +	tmp = dw_pcie_readl_dbi(pci, offset + PCI_EXP_LNKCAP); +	tmp &= ~PCI_EXP_LNKCAP_SLS; +	tmp |= PCI_EXP_LNKCAP_SLS_2_5GB; +	dw_pcie_writel_dbi(pci, offset + PCI_EXP_LNKCAP, tmp);  	/* Start LTSSM. */  	imx6_pcie_ltssm_enable(dev); @@ -781,12 +770,12 @@ static int imx6_pcie_establish_link(struct imx6_pcie *imx6_pcie)  	if (ret)  		goto err_reset_phy; -	if (imx6_pcie->link_gen == 2) { +	if (pci->link_gen == 2) {  		/* Allow Gen2 mode after the link is up. */ -		tmp = dw_pcie_readl_dbi(pci, PCIE_RC_LCR); -		tmp &= ~PCIE_RC_LCR_MAX_LINK_SPEEDS_MASK; -		tmp |= PCIE_RC_LCR_MAX_LINK_SPEEDS_GEN2; -		dw_pcie_writel_dbi(pci, PCIE_RC_LCR, tmp); +		tmp = dw_pcie_readl_dbi(pci, offset + PCI_EXP_LNKCAP); +		tmp &= ~PCI_EXP_LNKCAP_SLS; +		tmp |= PCI_EXP_LNKCAP_SLS_5_0GB; +		dw_pcie_writel_dbi(pci, offset + PCI_EXP_LNKCAP, tmp);  		/*  		 * Start Directed Speed Change so the best possible @@ -824,8 +813,8 @@ static int imx6_pcie_establish_link(struct imx6_pcie *imx6_pcie)  		dev_info(dev, "Link: Gen2 disabled\n");  	} -	tmp = dw_pcie_readl_dbi(pci, PCIE_RC_LCSR); -	dev_info(dev, "Link up, Gen%i\n", (tmp >> 16) & 0xf); +	tmp = dw_pcie_readw_dbi(pci, offset + PCI_EXP_LNKSTA); +	dev_info(dev, "Link up, Gen%i\n", tmp & PCI_EXP_LNKSTA_CLS);  	return 0;  err_reset_phy: @@ -847,9 +836,7 @@ static int imx6_pcie_host_init(struct pcie_port *pp)  	imx6_setup_phy_mpll(imx6_pcie);  	dw_pcie_setup_rc(pp);  	imx6_pcie_establish_link(imx6_pcie); - -	if (IS_ENABLED(CONFIG_PCI_MSI)) -		dw_pcie_msi_init(pp); +	dw_pcie_msi_init(pp);  	return 0;  } @@ -1073,38 +1060,33 @@ static int imx6_pcie_probe(struct platform_device *pdev)  	/* Fetch clocks */  	imx6_pcie->pcie_phy = devm_clk_get(dev, "pcie_phy"); -	if (IS_ERR(imx6_pcie->pcie_phy)) { -		dev_err(dev, "pcie_phy clock source missing or invalid\n"); -		return PTR_ERR(imx6_pcie->pcie_phy); -	} +	if (IS_ERR(imx6_pcie->pcie_phy)) +		return dev_err_probe(dev, PTR_ERR(imx6_pcie->pcie_phy), +				     "pcie_phy clock source missing or invalid\n");  	imx6_pcie->pcie_bus = devm_clk_get(dev, "pcie_bus"); -	if (IS_ERR(imx6_pcie->pcie_bus)) { -		dev_err(dev, "pcie_bus clock source missing or invalid\n"); -		return PTR_ERR(imx6_pcie->pcie_bus); -	} +	if (IS_ERR(imx6_pcie->pcie_bus)) +		return dev_err_probe(dev, PTR_ERR(imx6_pcie->pcie_bus), +				     "pcie_bus clock source missing or invalid\n");  	imx6_pcie->pcie = devm_clk_get(dev, "pcie"); -	if (IS_ERR(imx6_pcie->pcie)) { -		dev_err(dev, "pcie clock source missing or invalid\n"); -		return PTR_ERR(imx6_pcie->pcie); -	} +	if (IS_ERR(imx6_pcie->pcie)) +		return dev_err_probe(dev, PTR_ERR(imx6_pcie->pcie), +				     "pcie clock source missing or invalid\n");  	switch (imx6_pcie->drvdata->variant) {  	case IMX6SX:  		imx6_pcie->pcie_inbound_axi = devm_clk_get(dev,  							   "pcie_inbound_axi"); -		if (IS_ERR(imx6_pcie->pcie_inbound_axi)) { -			dev_err(dev, "pcie_inbound_axi clock missing or invalid\n"); -			return PTR_ERR(imx6_pcie->pcie_inbound_axi); -		} +		if (IS_ERR(imx6_pcie->pcie_inbound_axi)) +			return dev_err_probe(dev, PTR_ERR(imx6_pcie->pcie_inbound_axi), +					     "pcie_inbound_axi clock missing or invalid\n");  		break;  	case IMX8MQ:  		imx6_pcie->pcie_aux = devm_clk_get(dev, "pcie_aux"); -		if (IS_ERR(imx6_pcie->pcie_aux)) { -			dev_err(dev, "pcie_aux clock source missing or invalid\n"); -			return PTR_ERR(imx6_pcie->pcie_aux); -		} +		if (IS_ERR(imx6_pcie->pcie_aux)) +			return dev_err_probe(dev, PTR_ERR(imx6_pcie->pcie_aux), +					     "pcie_aux clock source missing or invalid\n");  		fallthrough;  	case IMX7D:  		if (dbi_base->start == IMX8MQ_PCIE2_BASE_ADDR) @@ -1165,10 +1147,8 @@ static int imx6_pcie_probe(struct platform_device *pdev)  		imx6_pcie->tx_swing_low = 127;  	/* Limit link speed */ -	ret = of_property_read_u32(node, "fsl,max-link-speed", -				   &imx6_pcie->link_gen); -	if (ret) -		imx6_pcie->link_gen = 1; +	pci->link_gen = 1; +	ret = of_property_read_u32(node, "fsl,max-link-speed", &pci->link_gen);  	imx6_pcie->vpcie = devm_regulator_get_optional(&pdev->dev, "vpcie");  	if (IS_ERR(imx6_pcie->vpcie)) { @@ -1188,11 +1168,10 @@ static int imx6_pcie_probe(struct platform_device *pdev)  		return ret;  	if (pci_msi_enabled()) { -		val = dw_pcie_readw_dbi(pci, PCIE_RC_IMX6_MSI_CAP + -					PCI_MSI_FLAGS); +		u8 offset = dw_pcie_find_capability(pci, PCI_CAP_ID_MSI); +		val = dw_pcie_readw_dbi(pci, offset + PCI_MSI_FLAGS);  		val |= PCI_MSI_FLAGS_ENABLE; -		dw_pcie_writew_dbi(pci, PCIE_RC_IMX6_MSI_CAP + PCI_MSI_FLAGS, -				   val); +		dw_pcie_writew_dbi(pci, offset + PCI_MSI_FLAGS, val);  	}  	return 0;  | 
