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
This commit is contained in:
Bjorn Helgaas 2019-03-06 15:30:19 -06:00
commit 2506419e06
12 changed files with 408 additions and 127 deletions

View File

@ -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

View File

@ -1,14 +1,21 @@
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
=========

View File

@ -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";
};
};

View File

@ -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

View File

@ -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");

View File

@ -8,6 +8,7 @@
* Author: Sean Cross <xobs@kosagi.com>
*/
#include <linux/bitfield.h>
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/gpio.h>
@ -18,6 +19,7 @@
#include <linux/module.h>
#include <linux/of_gpio.h>
#include <linux/of_device.h>
#include <linux/of_address.h>
#include <linux/pci.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
@ -32,6 +34,12 @@
#include "pcie-designware.h"
#define IMX8MQ_GPR_PCIE_REF_USE_PAD BIT(9)
#define IMX8MQ_GPR_PCIE_CLK_REQ_OVERRIDE_EN BIT(10)
#define IMX8MQ_GPR_PCIE_CLK_REQ_OVERRIDE BIT(11)
#define IMX8MQ_GPR12_PCIE2_CTRL_DEVICE_TYPE GENMASK(11, 8)
#define IMX8MQ_PCIE2_BASE_ADDR 0x33c00000
#define to_imx6_pcie(x) dev_get_drvdata((x)->dev)
enum imx6_pcie_variants {
@ -39,6 +47,15 @@ enum imx6_pcie_variants {
IMX6SX,
IMX6QP,
IMX7D,
IMX8MQ,
};
#define IMX6_PCIE_FLAG_IMX6_PHY BIT(0)
#define IMX6_PCIE_FLAG_IMX6_SPEED_CHANGE BIT(1)
struct imx6_pcie_drvdata {
enum imx6_pcie_variants variant;
u32 flags;
};
struct imx6_pcie {
@ -49,11 +66,12 @@ struct imx6_pcie {
struct clk *pcie_phy;
struct clk *pcie_inbound_axi;
struct clk *pcie;
struct clk *pcie_aux;
struct regmap *iomuxc_gpr;
u32 controller_id;
struct reset_control *pciephy_reset;
struct reset_control *apps_reset;
struct reset_control *turnoff_reset;
enum imx6_pcie_variants variant;
u32 tx_deemph_gen1;
u32 tx_deemph_gen2_3p5db;
u32 tx_deemph_gen2_6db;
@ -61,11 +79,13 @@ struct imx6_pcie {
u32 tx_swing_low;
int link_gen;
struct regulator *vpcie;
void __iomem *phy_base;
/* power domain for pcie */
struct device *pd_pcie;
/* power domain for pcie phy */
struct device *pd_pcie_phy;
const struct imx6_pcie_drvdata *drvdata;
};
/* Parameters for the waiting for PCIe PHY PLL to lock on i.MX7 */
@ -101,7 +121,6 @@ struct imx6_pcie {
#define PCIE_PHY_STAT_ACK_LOC 16
#define PCIE_LINK_WIDTH_SPEED_CONTROL 0x80C
#define PORT_LOGIC_SPEED_CHANGE (0x1 << 17)
/* PHY registers (not memory-mapped) */
#define PCIE_PHY_ATEOVRD 0x10
@ -117,6 +136,23 @@ struct imx6_pcie {
#define PCIE_PHY_RX_ASIC_OUT 0x100D
#define PCIE_PHY_RX_ASIC_OUT_VALID (1 << 0)
/* iMX7 PCIe PHY registers */
#define PCIE_PHY_CMN_REG4 0x14
/* These are probably the bits that *aren't* DCC_FB_EN */
#define PCIE_PHY_CMN_REG4_DCC_FB_EN 0x29
#define PCIE_PHY_CMN_REG15 0x54
#define PCIE_PHY_CMN_REG15_DLY_4 BIT(2)
#define PCIE_PHY_CMN_REG15_PLL_PD BIT(5)
#define PCIE_PHY_CMN_REG15_OVRD_PLL_PD BIT(7)
#define PCIE_PHY_CMN_REG24 0x90
#define PCIE_PHY_CMN_REG24_RX_EQ BIT(6)
#define PCIE_PHY_CMN_REG24_RX_EQ_SEL BIT(3)
#define PCIE_PHY_CMN_REG26 0x98
#define PCIE_PHY_CMN_REG26_ATT_MODE 0xBC
#define PHY_RX_OVRD_IN_LO 0x1005
#define PHY_RX_OVRD_IN_LO_RX_DATA_EN (1 << 5)
#define PHY_RX_OVRD_IN_LO_RX_PLL_EN (1 << 3)
@ -251,6 +287,9 @@ static void imx6_pcie_reset_phy(struct imx6_pcie *imx6_pcie)
{
u32 tmp;
if (!(imx6_pcie->drvdata->flags & IMX6_PCIE_FLAG_IMX6_PHY))
return;
pcie_phy_read(imx6_pcie, PHY_RX_OVRD_IN_LO, &tmp);
tmp |= (PHY_RX_OVRD_IN_LO_RX_DATA_EN |
PHY_RX_OVRD_IN_LO_RX_PLL_EN);
@ -264,6 +303,7 @@ static void imx6_pcie_reset_phy(struct imx6_pcie *imx6_pcie)
pcie_phy_write(imx6_pcie, PHY_RX_OVRD_IN_LO, tmp);
}
#ifdef CONFIG_ARM
/* Added for PCI abort handling */
static int imx6q_pcie_abort_handler(unsigned long addr,
unsigned int fsr, struct pt_regs *regs)
@ -297,6 +337,7 @@ static int imx6q_pcie_abort_handler(unsigned long addr,
return 1;
}
#endif
static int imx6_pcie_attach_pd(struct device *dev)
{
@ -339,8 +380,9 @@ static void imx6_pcie_assert_core_reset(struct imx6_pcie *imx6_pcie)
{
struct device *dev = imx6_pcie->pci->dev;
switch (imx6_pcie->variant) {
switch (imx6_pcie->drvdata->variant) {
case IMX7D:
case IMX8MQ:
reset_control_assert(imx6_pcie->pciephy_reset);
reset_control_assert(imx6_pcie->apps_reset);
break;
@ -375,13 +417,20 @@ static void imx6_pcie_assert_core_reset(struct imx6_pcie *imx6_pcie)
}
}
static unsigned int imx6_pcie_grp_offset(const struct imx6_pcie *imx6_pcie)
{
WARN_ON(imx6_pcie->drvdata->variant != IMX8MQ);
return imx6_pcie->controller_id == 1 ? IOMUXC_GPR16 : IOMUXC_GPR14;
}
static int imx6_pcie_enable_ref_clk(struct imx6_pcie *imx6_pcie)
{
struct dw_pcie *pci = imx6_pcie->pci;
struct device *dev = pci->dev;
unsigned int offset;
int ret = 0;
switch (imx6_pcie->variant) {
switch (imx6_pcie->drvdata->variant) {
case IMX6SX:
ret = clk_prepare_enable(imx6_pcie->pcie_inbound_axi);
if (ret) {
@ -409,6 +458,25 @@ static int imx6_pcie_enable_ref_clk(struct imx6_pcie *imx6_pcie)
break;
case IMX7D:
break;
case IMX8MQ:
ret = clk_prepare_enable(imx6_pcie->pcie_aux);
if (ret) {
dev_err(dev, "unable to enable pcie_aux clock\n");
break;
}
offset = imx6_pcie_grp_offset(imx6_pcie);
/*
* Set the over ride low and enabled
* make sure that REF_CLK is turned on.
*/
regmap_update_bits(imx6_pcie->iomuxc_gpr, offset,
IMX8MQ_GPR_PCIE_CLK_REQ_OVERRIDE,
0);
regmap_update_bits(imx6_pcie->iomuxc_gpr, offset,
IMX8MQ_GPR_PCIE_CLK_REQ_OVERRIDE_EN,
IMX8MQ_GPR_PCIE_CLK_REQ_OVERRIDE_EN);
break;
}
return ret;
@ -484,9 +552,32 @@ static void imx6_pcie_deassert_core_reset(struct imx6_pcie *imx6_pcie)
!imx6_pcie->gpio_active_high);
}
switch (imx6_pcie->variant) {
switch (imx6_pcie->drvdata->variant) {
case IMX8MQ:
reset_control_deassert(imx6_pcie->pciephy_reset);
break;
case IMX7D:
reset_control_deassert(imx6_pcie->pciephy_reset);
/* Workaround for ERR010728, failure of PCI-e PLL VCO to
* oscillate, especially when cold. This turns off "Duty-cycle
* Corrector" and other mysterious undocumented things.
*/
if (likely(imx6_pcie->phy_base)) {
/* De-assert DCC_FB_EN */
writel(PCIE_PHY_CMN_REG4_DCC_FB_EN,
imx6_pcie->phy_base + PCIE_PHY_CMN_REG4);
/* Assert RX_EQS and RX_EQS_SEL */
writel(PCIE_PHY_CMN_REG24_RX_EQ_SEL
| PCIE_PHY_CMN_REG24_RX_EQ,
imx6_pcie->phy_base + PCIE_PHY_CMN_REG24);
/* Assert ATT_MODE */
writel(PCIE_PHY_CMN_REG26_ATT_MODE,
imx6_pcie->phy_base + PCIE_PHY_CMN_REG26);
} else {
dev_warn(dev, "Unable to apply ERR010728 workaround. DT missing fsl,imx7d-pcie-phy phandle ?\n");
}
imx7d_pcie_wait_for_phy_pll_lock(imx6_pcie);
break;
case IMX6SX:
@ -520,9 +611,37 @@ err_pcie_phy:
}
}
static void imx6_pcie_configure_type(struct imx6_pcie *imx6_pcie)
{
unsigned int mask, val;
if (imx6_pcie->drvdata->variant == IMX8MQ &&
imx6_pcie->controller_id == 1) {
mask = IMX8MQ_GPR12_PCIE2_CTRL_DEVICE_TYPE;
val = FIELD_PREP(IMX8MQ_GPR12_PCIE2_CTRL_DEVICE_TYPE,
PCI_EXP_TYPE_ROOT_PORT);
} else {
mask = IMX6Q_GPR12_DEVICE_TYPE;
val = FIELD_PREP(IMX6Q_GPR12_DEVICE_TYPE,
PCI_EXP_TYPE_ROOT_PORT);
}
regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12, mask, val);
}
static void imx6_pcie_init_phy(struct imx6_pcie *imx6_pcie)
{
switch (imx6_pcie->variant) {
switch (imx6_pcie->drvdata->variant) {
case IMX8MQ:
/*
* TODO: Currently this code assumes external
* oscillator is being used
*/
regmap_update_bits(imx6_pcie->iomuxc_gpr,
imx6_pcie_grp_offset(imx6_pcie),
IMX8MQ_GPR_PCIE_REF_USE_PAD,
IMX8MQ_GPR_PCIE_REF_USE_PAD);
break;
case IMX7D:
regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
IMX7D_GPR12_PCIE_PHY_REFCLK_SEL, 0);
@ -558,8 +677,7 @@ static void imx6_pcie_init_phy(struct imx6_pcie *imx6_pcie)
break;
}
regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
IMX6Q_GPR12_DEVICE_TYPE, PCI_EXP_TYPE_ROOT_PORT << 12);
imx6_pcie_configure_type(imx6_pcie);
}
static int imx6_setup_phy_mpll(struct imx6_pcie *imx6_pcie)
@ -568,6 +686,9 @@ static int imx6_setup_phy_mpll(struct imx6_pcie *imx6_pcie)
int mult, div;
u32 val;
if (!(imx6_pcie->drvdata->flags & IMX6_PCIE_FLAG_IMX6_PHY))
return 0;
switch (phy_rate) {
case 125000000:
/*
@ -644,7 +765,7 @@ static void imx6_pcie_ltssm_enable(struct device *dev)
{
struct imx6_pcie *imx6_pcie = dev_get_drvdata(dev);
switch (imx6_pcie->variant) {
switch (imx6_pcie->drvdata->variant) {
case IMX6Q:
case IMX6SX:
case IMX6QP:
@ -653,6 +774,7 @@ static void imx6_pcie_ltssm_enable(struct device *dev)
IMX6Q_GPR12_PCIE_CTL_2);
break;
case IMX7D:
case IMX8MQ:
reset_control_deassert(imx6_pcie->apps_reset);
break;
}
@ -697,7 +819,8 @@ static int imx6_pcie_establish_link(struct imx6_pcie *imx6_pcie)
tmp |= PORT_LOGIC_SPEED_CHANGE;
dw_pcie_writel_dbi(pci, PCIE_LINK_WIDTH_SPEED_CONTROL, tmp);
if (imx6_pcie->variant != IMX7D) {
if (imx6_pcie->drvdata->flags &
IMX6_PCIE_FLAG_IMX6_SPEED_CHANGE) {
/*
* On i.MX7, DIRECT_SPEED_CHANGE behaves differently
* from i.MX6 family when no link speed transition
@ -794,7 +917,7 @@ static void imx6_pcie_ltssm_disable(struct device *dev)
{
struct imx6_pcie *imx6_pcie = dev_get_drvdata(dev);
switch (imx6_pcie->variant) {
switch (imx6_pcie->drvdata->variant) {
case IMX6SX:
case IMX6QP:
regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
@ -820,7 +943,7 @@ static void imx6_pcie_pm_turnoff(struct imx6_pcie *imx6_pcie)
}
/* Others poke directly at IOMUXC registers */
switch (imx6_pcie->variant) {
switch (imx6_pcie->drvdata->variant) {
case IMX6SX:
regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
IMX6SX_GPR12_PCIE_PM_TURN_OFF,
@ -850,7 +973,7 @@ 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);
switch (imx6_pcie->variant) {
switch (imx6_pcie->drvdata->variant) {
case IMX6SX:
clk_disable_unprepare(imx6_pcie->pcie_inbound_axi);
break;
@ -859,6 +982,9 @@ static void imx6_pcie_clk_disable(struct imx6_pcie *imx6_pcie)
IMX7D_GPR12_PCIE_PHY_REFCLK_SEL,
IMX7D_GPR12_PCIE_PHY_REFCLK_SEL);
break;
case IMX8MQ:
clk_disable_unprepare(imx6_pcie->pcie_aux);
break;
default:
break;
}
@ -866,8 +992,8 @@ static void imx6_pcie_clk_disable(struct imx6_pcie *imx6_pcie)
static inline bool imx6_pcie_supports_suspend(struct imx6_pcie *imx6_pcie)
{
return (imx6_pcie->variant == IMX7D ||
imx6_pcie->variant == IMX6SX);
return (imx6_pcie->drvdata->variant == IMX7D ||
imx6_pcie->drvdata->variant == IMX6SX);
}
static int imx6_pcie_suspend_noirq(struct device *dev)
@ -916,6 +1042,7 @@ static int imx6_pcie_probe(struct platform_device *pdev)
struct device *dev = &pdev->dev;
struct dw_pcie *pci;
struct imx6_pcie *imx6_pcie;
struct device_node *np;
struct resource *dbi_base;
struct device_node *node = dev->of_node;
int ret;
@ -933,8 +1060,24 @@ static int imx6_pcie_probe(struct platform_device *pdev)
pci->ops = &dw_pcie_ops;
imx6_pcie->pci = pci;
imx6_pcie->variant =
(enum imx6_pcie_variants)of_device_get_match_data(dev);
imx6_pcie->drvdata = of_device_get_match_data(dev);
/* Find the PHY if one is defined, only imx7d uses it */
np = of_parse_phandle(node, "fsl,imx7d-pcie-phy", 0);
if (np) {
struct resource res;
ret = of_address_to_resource(np, 0, &res);
if (ret) {
dev_err(dev, "Unable to map PCIe PHY\n");
return ret;
}
imx6_pcie->phy_base = devm_ioremap_resource(dev, &res);
if (IS_ERR(imx6_pcie->phy_base)) {
dev_err(dev, "Unable to map PCIe PHY\n");
return PTR_ERR(imx6_pcie->phy_base);
}
}
dbi_base = platform_get_resource(pdev, IORESOURCE_MEM, 0);
pci->dbi_base = devm_ioremap_resource(dev, dbi_base);
@ -978,7 +1121,7 @@ static int imx6_pcie_probe(struct platform_device *pdev)
return PTR_ERR(imx6_pcie->pcie);
}
switch (imx6_pcie->variant) {
switch (imx6_pcie->drvdata->variant) {
case IMX6SX:
imx6_pcie->pcie_inbound_axi = devm_clk_get(dev,
"pcie_inbound_axi");
@ -987,7 +1130,17 @@ static int imx6_pcie_probe(struct platform_device *pdev)
return PTR_ERR(imx6_pcie->pcie_inbound_axi);
}
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);
}
/* fall through */
case IMX7D:
if (dbi_base->start == IMX8MQ_PCIE2_BASE_ADDR)
imx6_pcie->controller_id = 1;
imx6_pcie->pciephy_reset = devm_reset_control_get_exclusive(dev,
"pciephy");
if (IS_ERR(imx6_pcie->pciephy_reset)) {
@ -1084,11 +1237,36 @@ static void imx6_pcie_shutdown(struct platform_device *pdev)
imx6_pcie_assert_core_reset(imx6_pcie);
}
static const struct imx6_pcie_drvdata drvdata[] = {
[IMX6Q] = {
.variant = IMX6Q,
.flags = IMX6_PCIE_FLAG_IMX6_PHY |
IMX6_PCIE_FLAG_IMX6_SPEED_CHANGE,
},
[IMX6SX] = {
.variant = IMX6SX,
.flags = IMX6_PCIE_FLAG_IMX6_PHY |
IMX6_PCIE_FLAG_IMX6_SPEED_CHANGE,
},
[IMX6QP] = {
.variant = IMX6QP,
.flags = IMX6_PCIE_FLAG_IMX6_PHY |
IMX6_PCIE_FLAG_IMX6_SPEED_CHANGE,
},
[IMX7D] = {
.variant = IMX7D,
},
[IMX8MQ] = {
.variant = IMX8MQ,
},
};
static const struct of_device_id imx6_pcie_of_match[] = {
{ .compatible = "fsl,imx6q-pcie", .data = (void *)IMX6Q, },
{ .compatible = "fsl,imx6sx-pcie", .data = (void *)IMX6SX, },
{ .compatible = "fsl,imx6qp-pcie", .data = (void *)IMX6QP, },
{ .compatible = "fsl,imx7d-pcie", .data = (void *)IMX7D, },
{ .compatible = "fsl,imx6q-pcie", .data = &drvdata[IMX6Q], },
{ .compatible = "fsl,imx6sx-pcie", .data = &drvdata[IMX6SX], },
{ .compatible = "fsl,imx6qp-pcie", .data = &drvdata[IMX6QP], },
{ .compatible = "fsl,imx7d-pcie", .data = &drvdata[IMX7D], },
{ .compatible = "fsl,imx8mq-pcie", .data = &drvdata[IMX8MQ], } ,
{},
};
@ -1105,6 +1283,7 @@ static struct platform_driver imx6_pcie_driver = {
static int __init imx6_pcie_init(void)
{
#ifdef CONFIG_ARM
/*
* Since probe() can be deferred we need to make sure that
* hook_fault_code is not called after __init memory is freed
@ -1114,6 +1293,7 @@ static int __init imx6_pcie_init(void)
*/
hook_fault_code(8, imx6q_pcie_abort_handler, SIGBUS, 0,
"external abort on non-linefetch");
#endif
return platform_driver_register(&imx6_pcie_driver);
}

View File

@ -465,8 +465,10 @@ int dw_pcie_ep_raise_msix_irq(struct dw_pcie_ep *ep, u8 func_no,
iounmap(msix_tbl);
if (vec_ctrl & PCI_MSIX_ENTRY_CTRL_MASKBIT)
if (vec_ctrl & PCI_MSIX_ENTRY_CTRL_MASKBIT) {
dev_dbg(pci->dev, "MSI-X entry ctrl set\n");
return -EPERM;
}
ret = dw_pcie_ep_map_addr(epc, func_no, ep->msi_mem_phys, msg_addr,
epc->mem->page_size);

View File

@ -120,9 +120,9 @@ static void dw_chained_msi_isr(struct irq_desc *desc)
chained_irq_exit(chip, desc);
}
static void dw_pci_setup_msi_msg(struct irq_data *data, struct msi_msg *msg)
static void dw_pci_setup_msi_msg(struct irq_data *d, struct msi_msg *msg)
{
struct pcie_port *pp = irq_data_get_irq_chip_data(data);
struct pcie_port *pp = irq_data_get_irq_chip_data(d);
struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
u64 msi_target;
@ -135,61 +135,61 @@ static void dw_pci_setup_msi_msg(struct irq_data *data, struct msi_msg *msg)
msg->address_hi = upper_32_bits(msi_target);
if (pp->ops->get_msi_data)
msg->data = pp->ops->get_msi_data(pp, data->hwirq);
msg->data = pp->ops->get_msi_data(pp, d->hwirq);
else
msg->data = data->hwirq;
msg->data = d->hwirq;
dev_dbg(pci->dev, "msi#%d address_hi %#x address_lo %#x\n",
(int)data->hwirq, msg->address_hi, msg->address_lo);
(int)d->hwirq, msg->address_hi, msg->address_lo);
}
static int dw_pci_msi_set_affinity(struct irq_data *irq_data,
static int dw_pci_msi_set_affinity(struct irq_data *d,
const struct cpumask *mask, bool force)
{
return -EINVAL;
}
static void dw_pci_bottom_mask(struct irq_data *data)
static void dw_pci_bottom_mask(struct irq_data *d)
{
struct pcie_port *pp = irq_data_get_irq_chip_data(data);
struct pcie_port *pp = irq_data_get_irq_chip_data(d);
unsigned int res, bit, ctrl;
unsigned long flags;
raw_spin_lock_irqsave(&pp->lock, flags);
if (pp->ops->msi_clear_irq) {
pp->ops->msi_clear_irq(pp, data->hwirq);
pp->ops->msi_clear_irq(pp, d->hwirq);
} else {
ctrl = data->hwirq / MAX_MSI_IRQS_PER_CTRL;
ctrl = d->hwirq / MAX_MSI_IRQS_PER_CTRL;
res = ctrl * MSI_REG_CTRL_BLOCK_SIZE;
bit = data->hwirq % MAX_MSI_IRQS_PER_CTRL;
bit = d->hwirq % MAX_MSI_IRQS_PER_CTRL;
pp->irq_status[ctrl] &= ~(1 << bit);
pp->irq_mask[ctrl] |= BIT(bit);
dw_pcie_wr_own_conf(pp, PCIE_MSI_INTR0_MASK + res, 4,
~pp->irq_status[ctrl]);
pp->irq_mask[ctrl]);
}
raw_spin_unlock_irqrestore(&pp->lock, flags);
}
static void dw_pci_bottom_unmask(struct irq_data *data)
static void dw_pci_bottom_unmask(struct irq_data *d)
{
struct pcie_port *pp = irq_data_get_irq_chip_data(data);
struct pcie_port *pp = irq_data_get_irq_chip_data(d);
unsigned int res, bit, ctrl;
unsigned long flags;
raw_spin_lock_irqsave(&pp->lock, flags);
if (pp->ops->msi_set_irq) {
pp->ops->msi_set_irq(pp, data->hwirq);
pp->ops->msi_set_irq(pp, d->hwirq);
} else {
ctrl = data->hwirq / MAX_MSI_IRQS_PER_CTRL;
ctrl = d->hwirq / MAX_MSI_IRQS_PER_CTRL;
res = ctrl * MSI_REG_CTRL_BLOCK_SIZE;
bit = data->hwirq % MAX_MSI_IRQS_PER_CTRL;
bit = d->hwirq % MAX_MSI_IRQS_PER_CTRL;
pp->irq_status[ctrl] |= 1 << bit;
pp->irq_mask[ctrl] &= ~BIT(bit);
dw_pcie_wr_own_conf(pp, PCIE_MSI_INTR0_MASK + res, 4,
~pp->irq_status[ctrl]);
pp->irq_mask[ctrl]);
}
raw_spin_unlock_irqrestore(&pp->lock, flags);
@ -207,7 +207,7 @@ static void dw_pci_bottom_ack(struct irq_data *d)
raw_spin_lock_irqsave(&pp->lock, flags);
dw_pcie_wr_own_conf(pp, PCIE_MSI_INTR0_STATUS + res, 4, 1 << bit);
dw_pcie_wr_own_conf(pp, PCIE_MSI_INTR0_STATUS + res, 4, BIT(bit));
if (pp->ops->msi_irq_ack)
pp->ops->msi_irq_ack(d->hwirq, pp);
@ -255,13 +255,13 @@ static int dw_pcie_irq_domain_alloc(struct irq_domain *domain,
static void dw_pcie_irq_domain_free(struct irq_domain *domain,
unsigned int virq, unsigned int nr_irqs)
{
struct irq_data *data = irq_domain_get_irq_data(domain, virq);
struct pcie_port *pp = irq_data_get_irq_chip_data(data);
struct irq_data *d = irq_domain_get_irq_data(domain, virq);
struct pcie_port *pp = irq_data_get_irq_chip_data(d);
unsigned long flags;
raw_spin_lock_irqsave(&pp->lock, flags);
bitmap_release_region(pp->msi_irq_in_use, data->hwirq,
bitmap_release_region(pp->msi_irq_in_use, d->hwirq,
order_base_2(nr_irqs));
raw_spin_unlock_irqrestore(&pp->lock, flags);
@ -439,7 +439,7 @@ int dw_pcie_host_init(struct pcie_port *pp)
if (ret)
pci->num_viewport = 2;
if (IS_ENABLED(CONFIG_PCI_MSI)) {
if (IS_ENABLED(CONFIG_PCI_MSI) && pci_msi_enabled()) {
/*
* If a specific SoC driver needs to change the
* default number of vectors, it needs to implement
@ -512,8 +512,9 @@ error:
return ret;
}
static int dw_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus,
u32 devfn, int where, int size, u32 *val)
static int dw_pcie_access_other_conf(struct pcie_port *pp, struct pci_bus *bus,
u32 devfn, int where, int size, u32 *val,
bool write)
{
int ret, type;
u32 busdev, cfg_size;
@ -521,9 +522,6 @@ static int dw_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus,
void __iomem *va_cfg_base;
struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
if (pp->ops->rd_other_conf)
return pp->ops->rd_other_conf(pp, bus, devfn, where, size, val);
busdev = PCIE_ATU_BUS(bus->number) | PCIE_ATU_DEV(PCI_SLOT(devfn)) |
PCIE_ATU_FUNC(PCI_FUNC(devfn));
@ -542,7 +540,11 @@ static int dw_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus,
dw_pcie_prog_outbound_atu(pci, PCIE_ATU_REGION_INDEX1,
type, cpu_addr,
busdev, cfg_size);
ret = dw_pcie_read(va_cfg_base + where, size, val);
if (write)
ret = dw_pcie_write(va_cfg_base + where, size, *val);
else
ret = dw_pcie_read(va_cfg_base + where, size, val);
if (pci->num_viewport <= 2)
dw_pcie_prog_outbound_atu(pci, PCIE_ATU_REGION_INDEX1,
PCIE_ATU_TYPE_IO, pp->io_base,
@ -551,43 +553,26 @@ static int dw_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus,
return ret;
}
static int dw_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus,
u32 devfn, int where, int size, u32 *val)
{
if (pp->ops->rd_other_conf)
return pp->ops->rd_other_conf(pp, bus, devfn, where,
size, val);
return dw_pcie_access_other_conf(pp, bus, devfn, where, size, val,
false);
}
static int dw_pcie_wr_other_conf(struct pcie_port *pp, struct pci_bus *bus,
u32 devfn, int where, int size, u32 val)
{
int ret, type;
u32 busdev, cfg_size;
u64 cpu_addr;
void __iomem *va_cfg_base;
struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
if (pp->ops->wr_other_conf)
return pp->ops->wr_other_conf(pp, bus, devfn, where, size, val);
return pp->ops->wr_other_conf(pp, bus, devfn, where,
size, val);
busdev = PCIE_ATU_BUS(bus->number) | PCIE_ATU_DEV(PCI_SLOT(devfn)) |
PCIE_ATU_FUNC(PCI_FUNC(devfn));
if (bus->parent->number == pp->root_bus_nr) {
type = PCIE_ATU_TYPE_CFG0;
cpu_addr = pp->cfg0_base;
cfg_size = pp->cfg0_size;
va_cfg_base = pp->va_cfg0_base;
} else {
type = PCIE_ATU_TYPE_CFG1;
cpu_addr = pp->cfg1_base;
cfg_size = pp->cfg1_size;
va_cfg_base = pp->va_cfg1_base;
}
dw_pcie_prog_outbound_atu(pci, PCIE_ATU_REGION_INDEX1,
type, cpu_addr,
busdev, cfg_size);
ret = dw_pcie_write(va_cfg_base + where, size, val);
if (pci->num_viewport <= 2)
dw_pcie_prog_outbound_atu(pci, PCIE_ATU_REGION_INDEX1,
PCIE_ATU_TYPE_IO, pp->io_base,
pp->io_bus_addr, pp->io_size);
return ret;
return dw_pcie_access_other_conf(pp, bus, devfn, where, size, &val,
true);
}
static int dw_pcie_valid_device(struct pcie_port *pp, struct pci_bus *bus,
@ -665,13 +650,13 @@ void dw_pcie_setup_rc(struct pcie_port *pp)
/* Initialize IRQ Status array */
for (ctrl = 0; ctrl < num_ctrls; ctrl++) {
pp->irq_mask[ctrl] = ~0;
dw_pcie_wr_own_conf(pp, PCIE_MSI_INTR0_MASK +
(ctrl * MSI_REG_CTRL_BLOCK_SIZE),
4, ~0);
4, pp->irq_mask[ctrl]);
dw_pcie_wr_own_conf(pp, PCIE_MSI_INTR0_ENABLE +
(ctrl * MSI_REG_CTRL_BLOCK_SIZE),
4, ~0);
pp->irq_status[ctrl] = 0;
}
/* Setup RC BARs */

View File

@ -13,11 +13,9 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/of_device.h>
#include <linux/of_gpio.h>
#include <linux/pci.h>
#include <linux/platform_device.h>
#include <linux/resource.h>
#include <linux/signal.h>
#include <linux/types.h>
#include <linux/regmap.h>

View File

@ -22,7 +22,7 @@
int dw_pcie_read(void __iomem *addr, int size, u32 *val)
{
if ((uintptr_t)addr & (size - 1)) {
if (!IS_ALIGNED((uintptr_t)addr, size)) {
*val = 0;
return PCIBIOS_BAD_REGISTER_NUMBER;
}
@ -43,7 +43,7 @@ int dw_pcie_read(void __iomem *addr, int size, u32 *val)
int dw_pcie_write(void __iomem *addr, int size, u32 val)
{
if ((uintptr_t)addr & (size - 1))
if (!IS_ALIGNED((uintptr_t)addr, size))
return PCIBIOS_BAD_REGISTER_NUMBER;
if (size == 4)
@ -306,7 +306,7 @@ void dw_pcie_disable_atu(struct dw_pcie *pci, int index,
}
dw_pcie_writel_dbi(pci, PCIE_ATU_VIEWPORT, region | index);
dw_pcie_writel_dbi(pci, PCIE_ATU_CR2, ~PCIE_ATU_ENABLE);
dw_pcie_writel_dbi(pci, PCIE_ATU_CR2, (u32)~PCIE_ATU_ENABLE);
}
int dw_pcie_wait_for_link(struct dw_pcie *pci)

View File

@ -11,6 +11,7 @@
#ifndef _PCIE_DESIGNWARE_H
#define _PCIE_DESIGNWARE_H
#include <linux/bitfield.h>
#include <linux/dma-mapping.h>
#include <linux/irq.h>
#include <linux/msi.h>
@ -30,23 +31,25 @@
/* Synopsys-specific PCIe configuration registers */
#define PCIE_PORT_LINK_CONTROL 0x710
#define PORT_LINK_MODE_MASK (0x3f << 16)
#define PORT_LINK_MODE_1_LANES (0x1 << 16)
#define PORT_LINK_MODE_2_LANES (0x3 << 16)
#define PORT_LINK_MODE_4_LANES (0x7 << 16)
#define PORT_LINK_MODE_8_LANES (0xf << 16)
#define PORT_LINK_MODE_MASK GENMASK(21, 16)
#define PORT_LINK_MODE(n) FIELD_PREP(PORT_LINK_MODE_MASK, n)
#define PORT_LINK_MODE_1_LANES PORT_LINK_MODE(0x1)
#define PORT_LINK_MODE_2_LANES PORT_LINK_MODE(0x3)
#define PORT_LINK_MODE_4_LANES PORT_LINK_MODE(0x7)
#define PORT_LINK_MODE_8_LANES PORT_LINK_MODE(0xf)
#define PCIE_PORT_DEBUG0 0x728
#define PORT_LOGIC_LTSSM_STATE_MASK 0x1f
#define PORT_LOGIC_LTSSM_STATE_L0 0x11
#define PCIE_LINK_WIDTH_SPEED_CONTROL 0x80C
#define PORT_LOGIC_SPEED_CHANGE (0x1 << 17)
#define PORT_LOGIC_LINK_WIDTH_MASK (0x1f << 8)
#define PORT_LOGIC_LINK_WIDTH_1_LANES (0x1 << 8)
#define PORT_LOGIC_LINK_WIDTH_2_LANES (0x2 << 8)
#define PORT_LOGIC_LINK_WIDTH_4_LANES (0x4 << 8)
#define PORT_LOGIC_LINK_WIDTH_8_LANES (0x8 << 8)
#define PORT_LOGIC_SPEED_CHANGE BIT(17)
#define PORT_LOGIC_LINK_WIDTH_MASK GENMASK(12, 8)
#define PORT_LOGIC_LINK_WIDTH(n) FIELD_PREP(PORT_LOGIC_LINK_WIDTH_MASK, n)
#define PORT_LOGIC_LINK_WIDTH_1_LANES PORT_LOGIC_LINK_WIDTH(0x1)
#define PORT_LOGIC_LINK_WIDTH_2_LANES PORT_LOGIC_LINK_WIDTH(0x2)
#define PORT_LOGIC_LINK_WIDTH_4_LANES PORT_LOGIC_LINK_WIDTH(0x4)
#define PORT_LOGIC_LINK_WIDTH_8_LANES PORT_LOGIC_LINK_WIDTH(0x8)
#define PCIE_MSI_ADDR_LO 0x820
#define PCIE_MSI_ADDR_HI 0x824
@ -55,30 +58,30 @@
#define PCIE_MSI_INTR0_STATUS 0x830
#define PCIE_ATU_VIEWPORT 0x900
#define PCIE_ATU_REGION_INBOUND (0x1 << 31)
#define PCIE_ATU_REGION_OUTBOUND (0x0 << 31)
#define PCIE_ATU_REGION_INDEX2 (0x2 << 0)
#define PCIE_ATU_REGION_INDEX1 (0x1 << 0)
#define PCIE_ATU_REGION_INDEX0 (0x0 << 0)
#define PCIE_ATU_REGION_INBOUND BIT(31)
#define PCIE_ATU_REGION_OUTBOUND 0
#define PCIE_ATU_REGION_INDEX2 0x2
#define PCIE_ATU_REGION_INDEX1 0x1
#define PCIE_ATU_REGION_INDEX0 0x0
#define PCIE_ATU_CR1 0x904
#define PCIE_ATU_TYPE_MEM (0x0 << 0)
#define PCIE_ATU_TYPE_IO (0x2 << 0)
#define PCIE_ATU_TYPE_CFG0 (0x4 << 0)
#define PCIE_ATU_TYPE_CFG1 (0x5 << 0)
#define PCIE_ATU_TYPE_MEM 0x0
#define PCIE_ATU_TYPE_IO 0x2
#define PCIE_ATU_TYPE_CFG0 0x4
#define PCIE_ATU_TYPE_CFG1 0x5
#define PCIE_ATU_CR2 0x908
#define PCIE_ATU_ENABLE (0x1 << 31)
#define PCIE_ATU_BAR_MODE_ENABLE (0x1 << 30)
#define PCIE_ATU_ENABLE BIT(31)
#define PCIE_ATU_BAR_MODE_ENABLE BIT(30)
#define PCIE_ATU_LOWER_BASE 0x90C
#define PCIE_ATU_UPPER_BASE 0x910
#define PCIE_ATU_LIMIT 0x914
#define PCIE_ATU_LOWER_TARGET 0x918
#define PCIE_ATU_BUS(x) (((x) & 0xff) << 24)
#define PCIE_ATU_DEV(x) (((x) & 0x1f) << 19)
#define PCIE_ATU_FUNC(x) (((x) & 0x7) << 16)
#define PCIE_ATU_BUS(x) FIELD_PREP(GENMASK(31, 24), x)
#define PCIE_ATU_DEV(x) FIELD_PREP(GENMASK(23, 19), x)
#define PCIE_ATU_FUNC(x) FIELD_PREP(GENMASK(18, 16), x)
#define PCIE_ATU_UPPER_TARGET 0x91C
#define PCIE_MISC_CONTROL_1_OFF 0x8BC
#define PCIE_DBI_RO_WR_EN (0x1 << 0)
#define PCIE_DBI_RO_WR_EN BIT(0)
/*
* iATU Unroll-specific register definitions
@ -105,7 +108,7 @@
((region) << 9)
#define PCIE_GET_ATU_INB_UNR_REG_OFFSET(region) \
(((region) << 9) | (0x1 << 8))
(((region) << 9) | BIT(8))
#define MAX_MSI_IRQS 256
#define MAX_MSI_IRQS_PER_CTRL 32
@ -177,7 +180,7 @@ struct pcie_port {
struct irq_domain *msi_domain;
dma_addr_t msi_data;
u32 num_vectors;
u32 irq_status[MAX_MSI_CTRLS];
u32 irq_mask[MAX_MSI_CTRLS];
raw_spinlock_t lock;
DECLARE_BITMAP(msi_irq_in_use, MAX_MSI_IRQS);
};

View File

@ -1228,7 +1228,7 @@ static int qcom_pcie_probe(struct platform_device *pdev)
pcie->ops = of_device_get_match_data(dev);
pcie->reset = devm_gpiod_get_optional(dev, "perst", GPIOD_OUT_LOW);
pcie->reset = devm_gpiod_get_optional(dev, "perst", GPIOD_OUT_HIGH);
if (IS_ERR(pcie->reset)) {
ret = PTR_ERR(pcie->reset);
goto err_pm_runtime_put;