* [PATCH v7 0/4] PCIE support for i.MX8MQ
@ 2019-02-02 0:15 Andrey Smirnov
2019-02-02 0:15 ` [PATCH v7 1/4] PCI: imx6: Introduce drvdata Andrey Smirnov
` (4 more replies)
0 siblings, 5 replies; 6+ messages in thread
From: Andrey Smirnov @ 2019-02-02 0:15 UTC (permalink / raw)
To: Lorenzo Pieralisi
Cc: Andrey Smirnov, Bjorn Helgaas, Fabio Estevam, Chris Healy,
Lucas Stach, Leonard Crestez, A.s. Dong, Richard Zhu, linux-imx,
linux-arm-kernel, linux-kernel, linux-pci
Everyone:
This series contains changes I made in order to enable support of PCIE
IP block on i.MX8MQ SoCs.
Changes since [v6]:
- Patches rebased on Lorenzo's pci/dwc branch
- Reworded commit message of "PCI: imx6: Mark PHY functions as i.MX6
specific"
Changes since [v5]:
- Reformatted commit messages to adhere to
https://lore.kernel.org/linux-pci/20171026223701.GA25649@bhelgaas-glaptop.roam.corp.google.com/
Changes since [v4]:
- Collected Reviewed-by from Lucas
- Replaced ((ARM || ARM64) && COMPILE_TEST) with COMPILE_TEST as per
suggestion from Rob
Changes since [v3]:
- Based on feedback from NXP, DIRECT_SPEED_CHANGE quirk was expanded
to cover both i.MX7 and i.MX8MQ
- Code setting device type in GPR12 moved to a standalone function
- Explicit "fsl,controller-id" binding was dropped, replaced by using
controller physical address to determine logical ID
- Dropped Reviewed-by from Lucas for patch 4/4 due to the change
above (haven't heard explicit "yea" for it from him)
Changes since [v2], [fixes]:
- Incorporated [patch] introducing drvdata
- i.MX6 PHY operation gating converted to a single patch and to use a
dedicated flag instead of doing explicit variant check
- Kconfig entry changed to use ARM64 && ARCH_MXC
- Dropped FALLTHROUGH annotations
Changes since [v1]:
- Driver changed to use single "fsl,controller-id" property to
distinguish between two intances of PCIE IP block
- All code pertaining to L1SS was dropped to simplify the patch
- Documented additions to DT bindings
Feedback is welcome!
Thanks,
Andrey Smirnov
[v6] https://lore.kernel.org/linux-arm-kernel/https://lore.kernel.org/linux-arm-kernel/20190124201522.8973-1-andrew.smirnov@gmail.com
[v5] https://lore.kernel.org/linux-arm-kernel/20190112215601.9535-1-andrew.smirnov@gmail.com
[v4] https://lore.kernel.org/linux-arm-kernel/20190104165335.13205-1-andrew.smirnov@gmail.com
[v3] https://lore.kernel.org/linux-arm-kernel/20181218040702.29231-1-andrew.smirnov@gmail.com
[patch] https://patchwork.kernel.org/patch/10712261/
[fixes] https://lore.kernel.org/linux-arm-kernel/20181216230916.22982-1-andrew.smirnov@gmail.com
[v2] https://lore.kernel.org/linux-arm-kernel/20181206073545.10967-1-andrew.smirnov@gmail.com
[v1] https://lore.kernel.org/linux-arm-kernel/20181117181225.10737-1-andrew.smirnov@gmail.com/
Andrey Smirnov (4):
PCI: imx6: Introduce drvdata
PCI: imx6: Mark PHY functions as i.MX6 specific
PCI: imx6: Convert DIRECT_SPEED_CHANGE quirk code to use a flag
PCI: imx6: Add support for i.MX8MQ
.../bindings/pci/fsl,imx6q-pcie.txt | 3 +-
drivers/pci/controller/dwc/Kconfig | 4 +-
drivers/pci/controller/dwc/pci-imx6.c | 150 +++++++++++++++---
3 files changed, 133 insertions(+), 24 deletions(-)
--
2.20.1
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH v7 1/4] PCI: imx6: Introduce drvdata
2019-02-02 0:15 [PATCH v7 0/4] PCIE support for i.MX8MQ Andrey Smirnov
@ 2019-02-02 0:15 ` Andrey Smirnov
2019-02-02 0:15 ` [PATCH v7 2/4] PCI: imx6: Mark PHY functions as i.MX6 specific Andrey Smirnov
` (3 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Andrey Smirnov @ 2019-02-02 0:15 UTC (permalink / raw)
To: Lorenzo Pieralisi
Cc: Andrey Smirnov, Stefan Agner, Lucas Stach, Bjorn Helgaas,
Fabio Estevam, Chris Healy, Leonard Crestez, A.s. Dong,
Richard Zhu, linux-imx, linux-arm-kernel, linux-kernel,
linux-pci
Introduce driver data struct. This will simplify handling of device
specific differences.
Signed-off-by: Stefan Agner <stefan@agner.ch>
[andrew.smirnov@gmail.com reformatted drvdata, to simplify future diffs]
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
Reviewed-by: Lucas Stach <l.stach@pengutronix.de>
Cc: Bjorn Helgaas <bhelgaas@google.com>
Cc: Fabio Estevam <fabio.estevam@nxp.com>
Cc: Chris Healy <cphealy@gmail.com>
Cc: Lucas Stach <l.stach@pengutronix.de>
Cc: Leonard Crestez <leonard.crestez@nxp.com>
Cc: "A.s. Dong" <aisheng.dong@nxp.com>
Cc: Richard Zhu <hongxing.zhu@nxp.com>
Cc: linux-imx@nxp.com
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-kernel@vger.kernel.org
Cc: linux-pci@vger.kernel.org
---
drivers/pci/controller/dwc/pci-imx6.c | 56 ++++++++++++++++++---------
1 file changed, 37 insertions(+), 19 deletions(-)
diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
index 52e47dac028f..1e940ba7e4c4 100644
--- a/drivers/pci/controller/dwc/pci-imx6.c
+++ b/drivers/pci/controller/dwc/pci-imx6.c
@@ -41,6 +41,10 @@ enum imx6_pcie_variants {
IMX7D,
};
+struct imx6_pcie_drvdata {
+ enum imx6_pcie_variants variant;
+};
+
struct imx6_pcie {
struct dw_pcie *pci;
int reset_gpio;
@@ -53,7 +57,6 @@ struct imx6_pcie {
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;
@@ -66,6 +69,7 @@ struct imx6_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 */
@@ -339,7 +343,7 @@ 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:
reset_control_assert(imx6_pcie->pciephy_reset);
reset_control_assert(imx6_pcie->apps_reset);
@@ -381,7 +385,7 @@ static int imx6_pcie_enable_ref_clk(struct imx6_pcie *imx6_pcie)
struct device *dev = pci->dev;
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) {
@@ -484,7 +488,7 @@ 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 IMX7D:
reset_control_deassert(imx6_pcie->pciephy_reset);
imx7d_pcie_wait_for_phy_pll_lock(imx6_pcie);
@@ -522,7 +526,7 @@ static void imx6_pcie_deassert_core_reset(struct imx6_pcie *imx6_pcie)
static void imx6_pcie_init_phy(struct imx6_pcie *imx6_pcie)
{
- switch (imx6_pcie->variant) {
+ switch (imx6_pcie->drvdata->variant) {
case IMX7D:
regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
IMX7D_GPR12_PCIE_PHY_REFCLK_SEL, 0);
@@ -644,7 +648,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:
@@ -697,7 +701,7 @@ 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->variant != IMX7D) {
/*
* On i.MX7, DIRECT_SPEED_CHANGE behaves differently
* from i.MX6 family when no link speed transition
@@ -794,7 +798,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 +824,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 +854,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;
@@ -866,8 +870,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)
@@ -933,8 +937,7 @@ 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);
dbi_base = platform_get_resource(pdev, IORESOURCE_MEM, 0);
pci->dbi_base = devm_ioremap_resource(dev, dbi_base);
@@ -978,7 +981,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");
@@ -1084,11 +1087,26 @@ 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,
+ },
+ [IMX6SX] = {
+ .variant = IMX6SX,
+ },
+ [IMX6QP] = {
+ .variant = IMX6QP,
+ },
+ [IMX7D] = {
+ .variant = IMX7D,
+ },
+};
+
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], },
{},
};
--
2.20.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH v7 2/4] PCI: imx6: Mark PHY functions as i.MX6 specific
2019-02-02 0:15 [PATCH v7 0/4] PCIE support for i.MX8MQ Andrey Smirnov
2019-02-02 0:15 ` [PATCH v7 1/4] PCI: imx6: Introduce drvdata Andrey Smirnov
@ 2019-02-02 0:15 ` Andrey Smirnov
2019-02-02 0:15 ` [PATCH v7 3/4] PCI: imx6: Convert DIRECT_SPEED_CHANGE quirk code to use a flag Andrey Smirnov
` (2 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Andrey Smirnov @ 2019-02-02 0:15 UTC (permalink / raw)
To: Lorenzo Pieralisi
Cc: Andrey Smirnov, Trent Piepho, Lucas Stach, Bjorn Helgaas,
Fabio Estevam, Chris Healy, Leonard Crestez, A.s. Dong,
Richard Zhu, linux-imx, linux-arm-kernel, linux-kernel,
linux-pci
PCIe PHY IP block on i.MX7D differs from the one used on i.MX6 family,
so none of the code in current implementation of imx6_setup_phy_mpll()
or imx6_pcie_reset_phy() is applicable. Introduce
IMX6_PCIE_FLAG_IMX6_PHY and checks for it to aforementioned functions
to make sure they are only executed on apporpriate PCIe IP variants.
Tested-by: Trent Piepho <tpiepho@impinj.com>
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
Reviewed-by: Lucas Stach <l.stach@pengutronix.de>
Cc: Bjorn Helgaas <bhelgaas@google.com>
Cc: Fabio Estevam <fabio.estevam@nxp.com>
Cc: Chris Healy <cphealy@gmail.com>
Cc: Lucas Stach <l.stach@pengutronix.de>
Cc: Leonard Crestez <leonard.crestez@nxp.com>
Cc: "A.s. Dong" <aisheng.dong@nxp.com>
Cc: Richard Zhu <hongxing.zhu@nxp.com>
Cc: linux-imx@nxp.com
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-kernel@vger.kernel.org
Cc: linux-pci@vger.kernel.org
---
drivers/pci/controller/dwc/pci-imx6.c | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
index 1e940ba7e4c4..26e1e974b0dd 100644
--- a/drivers/pci/controller/dwc/pci-imx6.c
+++ b/drivers/pci/controller/dwc/pci-imx6.c
@@ -41,8 +41,11 @@ enum imx6_pcie_variants {
IMX7D,
};
+#define IMX6_PCIE_FLAG_IMX6_PHY BIT(0)
+
struct imx6_pcie_drvdata {
enum imx6_pcie_variants variant;
+ u32 flags;
};
struct imx6_pcie {
@@ -255,6 +258,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);
@@ -572,6 +578,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:
/*
@@ -1090,12 +1099,15 @@ static void imx6_pcie_shutdown(struct platform_device *pdev)
static const struct imx6_pcie_drvdata drvdata[] = {
[IMX6Q] = {
.variant = IMX6Q,
+ .flags = IMX6_PCIE_FLAG_IMX6_PHY,
},
[IMX6SX] = {
.variant = IMX6SX,
+ .flags = IMX6_PCIE_FLAG_IMX6_PHY,
},
[IMX6QP] = {
.variant = IMX6QP,
+ .flags = IMX6_PCIE_FLAG_IMX6_PHY,
},
[IMX7D] = {
.variant = IMX7D,
--
2.20.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH v7 3/4] PCI: imx6: Convert DIRECT_SPEED_CHANGE quirk code to use a flag
2019-02-02 0:15 [PATCH v7 0/4] PCIE support for i.MX8MQ Andrey Smirnov
2019-02-02 0:15 ` [PATCH v7 1/4] PCI: imx6: Introduce drvdata Andrey Smirnov
2019-02-02 0:15 ` [PATCH v7 2/4] PCI: imx6: Mark PHY functions as i.MX6 specific Andrey Smirnov
@ 2019-02-02 0:15 ` Andrey Smirnov
2019-02-02 0:15 ` [PATCH v7 4/4] PCI: imx6: Add support for i.MX8MQ Andrey Smirnov
2019-02-04 12:19 ` [PATCH v7 0/4] PCIE " Lorenzo Pieralisi
4 siblings, 0 replies; 6+ messages in thread
From: Andrey Smirnov @ 2019-02-02 0:15 UTC (permalink / raw)
To: Lorenzo Pieralisi
Cc: Andrey Smirnov, Lucas Stach, Bjorn Helgaas, Fabio Estevam,
Chris Healy, Leonard Crestez, A.s. Dong, Richard Zhu, linux-imx,
linux-arm-kernel, linux-kernel, linux-pci
Both i.MX7D and i.MX8MQ have the same behaviour when it comes to
clearing DIRECT_SPEED_CHANGE bit when no speed change occur. To
account for that change the code handling that to use a generic flag
instead of checking IP block variant.
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
Reviewed-by: Lucas Stach <l.stach@pengutronix.de>
Cc: Bjorn Helgaas <bhelgaas@google.com>
Cc: Fabio Estevam <fabio.estevam@nxp.com>
Cc: Chris Healy <cphealy@gmail.com>
Cc: Lucas Stach <l.stach@pengutronix.de>
Cc: Leonard Crestez <leonard.crestez@nxp.com>
Cc: "A.s. Dong" <aisheng.dong@nxp.com>
Cc: Richard Zhu <hongxing.zhu@nxp.com>
Cc: linux-imx@nxp.com
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-kernel@vger.kernel.org
Cc: linux-pci@vger.kernel.org
---
drivers/pci/controller/dwc/pci-imx6.c | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)
diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
index 26e1e974b0dd..11b73d733dae 100644
--- a/drivers/pci/controller/dwc/pci-imx6.c
+++ b/drivers/pci/controller/dwc/pci-imx6.c
@@ -42,6 +42,7 @@ enum imx6_pcie_variants {
};
#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;
@@ -710,7 +711,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->drvdata->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
@@ -1099,15 +1101,18 @@ static void imx6_pcie_shutdown(struct platform_device *pdev)
static const struct imx6_pcie_drvdata drvdata[] = {
[IMX6Q] = {
.variant = IMX6Q,
- .flags = IMX6_PCIE_FLAG_IMX6_PHY,
+ .flags = IMX6_PCIE_FLAG_IMX6_PHY |
+ IMX6_PCIE_FLAG_IMX6_SPEED_CHANGE,
},
[IMX6SX] = {
.variant = IMX6SX,
- .flags = IMX6_PCIE_FLAG_IMX6_PHY,
+ .flags = IMX6_PCIE_FLAG_IMX6_PHY |
+ IMX6_PCIE_FLAG_IMX6_SPEED_CHANGE,
},
[IMX6QP] = {
.variant = IMX6QP,
- .flags = IMX6_PCIE_FLAG_IMX6_PHY,
+ .flags = IMX6_PCIE_FLAG_IMX6_PHY |
+ IMX6_PCIE_FLAG_IMX6_SPEED_CHANGE,
},
[IMX7D] = {
.variant = IMX7D,
--
2.20.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH v7 4/4] PCI: imx6: Add support for i.MX8MQ
2019-02-02 0:15 [PATCH v7 0/4] PCIE support for i.MX8MQ Andrey Smirnov
` (2 preceding siblings ...)
2019-02-02 0:15 ` [PATCH v7 3/4] PCI: imx6: Convert DIRECT_SPEED_CHANGE quirk code to use a flag Andrey Smirnov
@ 2019-02-02 0:15 ` Andrey Smirnov
2019-02-04 12:19 ` [PATCH v7 0/4] PCIE " Lorenzo Pieralisi
4 siblings, 0 replies; 6+ messages in thread
From: Andrey Smirnov @ 2019-02-02 0:15 UTC (permalink / raw)
To: Lorenzo Pieralisi
Cc: Andrey Smirnov, Lucas Stach, Bjorn Helgaas, Fabio Estevam,
Chris Healy, Leonard Crestez, A.s. Dong, Richard Zhu, linux-imx,
linux-arm-kernel, linux-kernel, linux-pci
Add code needed to support i.MX8MQ variant.
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
Reviewed-by: Lucas Stach <l.stach@pengutronix.de>
Cc: Bjorn Helgaas <bhelgaas@google.com>
Cc: Fabio Estevam <fabio.estevam@nxp.com>
Cc: Chris Healy <cphealy@gmail.com>
Cc: Lucas Stach <l.stach@pengutronix.de>
Cc: Leonard Crestez <leonard.crestez@nxp.com>
Cc: "A.s. Dong" <aisheng.dong@nxp.com>
Cc: Richard Zhu <hongxing.zhu@nxp.com>
Cc: linux-imx@nxp.com
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-kernel@vger.kernel.org
Cc: linux-pci@vger.kernel.org
---
.../bindings/pci/fsl,imx6q-pcie.txt | 3 +-
drivers/pci/controller/dwc/Kconfig | 4 +-
drivers/pci/controller/dwc/pci-imx6.c | 77 ++++++++++++++++++-
3 files changed, 79 insertions(+), 5 deletions(-)
diff --git a/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.txt b/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.txt
index d514c1f2365f..920ca93870a8 100644
--- a/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.txt
+++ b/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.txt
@@ -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
diff --git a/drivers/pci/controller/dwc/Kconfig b/drivers/pci/controller/dwc/Kconfig
index 548c58223868..6ea74b1c0d94 100644
--- a/drivers/pci/controller/dwc/Kconfig
+++ b/drivers/pci/controller/dwc/Kconfig
@@ -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
diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
index 11b73d733dae..c1d434ba3642 100644
--- a/drivers/pci/controller/dwc/pci-imx6.c
+++ b/drivers/pci/controller/dwc/pci-imx6.c
@@ -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>
@@ -32,6 +33,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 +46,7 @@ enum imx6_pcie_variants {
IMX6SX,
IMX6QP,
IMX7D,
+ IMX8MQ,
};
#define IMX6_PCIE_FLAG_IMX6_PHY BIT(0)
@@ -58,6 +66,7 @@ struct imx6_pcie {
struct clk *pcie_inbound_axi;
struct clk *pcie;
struct regmap *iomuxc_gpr;
+ u32 controller_id;
struct reset_control *pciephy_reset;
struct reset_control *apps_reset;
struct reset_control *turnoff_reset;
@@ -275,6 +284,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)
@@ -308,6 +318,7 @@ static int imx6q_pcie_abort_handler(unsigned long addr,
return 1;
}
+#endif
static int imx6_pcie_attach_pd(struct device *dev)
{
@@ -352,6 +363,7 @@ static void imx6_pcie_assert_core_reset(struct imx6_pcie *imx6_pcie)
switch (imx6_pcie->drvdata->variant) {
case IMX7D:
+ case IMX8MQ:
reset_control_assert(imx6_pcie->pciephy_reset);
reset_control_assert(imx6_pcie->apps_reset);
break;
@@ -386,10 +398,17 @@ 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->drvdata->variant) {
@@ -420,6 +439,19 @@ static int imx6_pcie_enable_ref_clk(struct imx6_pcie *imx6_pcie)
break;
case IMX7D:
break;
+ case IMX8MQ:
+ 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;
@@ -496,6 +528,9 @@ static void imx6_pcie_deassert_core_reset(struct imx6_pcie *imx6_pcie)
}
switch (imx6_pcie->drvdata->variant) {
+ case IMX8MQ:
+ reset_control_deassert(imx6_pcie->pciephy_reset);
+ break;
case IMX7D:
reset_control_deassert(imx6_pcie->pciephy_reset);
imx7d_pcie_wait_for_phy_pll_lock(imx6_pcie);
@@ -531,9 +566,37 @@ static void imx6_pcie_deassert_core_reset(struct imx6_pcie *imx6_pcie)
}
}
+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->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);
@@ -569,8 +632,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)
@@ -667,6 +729,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;
}
@@ -1002,6 +1065,10 @@ static int imx6_pcie_probe(struct platform_device *pdev)
}
break;
case IMX7D:
+ case IMX8MQ:
+ 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)) {
@@ -1117,6 +1184,9 @@ static const struct imx6_pcie_drvdata drvdata[] = {
[IMX7D] = {
.variant = IMX7D,
},
+ [IMX8MQ] = {
+ .variant = IMX8MQ,
+ },
};
static const struct of_device_id imx6_pcie_of_match[] = {
@@ -1124,6 +1194,7 @@ static const struct of_device_id imx6_pcie_of_match[] = {
{ .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], } ,
{},
};
@@ -1140,6 +1211,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
@@ -1149,6 +1221,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);
}
--
2.20.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH v7 0/4] PCIE support for i.MX8MQ
2019-02-02 0:15 [PATCH v7 0/4] PCIE support for i.MX8MQ Andrey Smirnov
` (3 preceding siblings ...)
2019-02-02 0:15 ` [PATCH v7 4/4] PCI: imx6: Add support for i.MX8MQ Andrey Smirnov
@ 2019-02-04 12:19 ` Lorenzo Pieralisi
4 siblings, 0 replies; 6+ messages in thread
From: Lorenzo Pieralisi @ 2019-02-04 12:19 UTC (permalink / raw)
To: Andrey Smirnov
Cc: Bjorn Helgaas, Fabio Estevam, Chris Healy, Lucas Stach,
Leonard Crestez, A.s. Dong, Richard Zhu, linux-imx,
linux-arm-kernel, linux-kernel, linux-pci
On Fri, Feb 01, 2019 at 04:15:19PM -0800, Andrey Smirnov wrote:
> Everyone:
>
> This series contains changes I made in order to enable support of PCIE
> IP block on i.MX8MQ SoCs.
>
> Changes since [v6]:
>
> - Patches rebased on Lorenzo's pci/dwc branch
>
> - Reworded commit message of "PCI: imx6: Mark PHY functions as i.MX6
> specific"
Applied to pci/dwc for v5.1, thanks.
Lorenzo
> Changes since [v5]:
>
> - Reformatted commit messages to adhere to
> https://lore.kernel.org/linux-pci/20171026223701.GA25649@bhelgaas-glaptop.roam.corp.google.com/
>
> Changes since [v4]:
>
> - Collected Reviewed-by from Lucas
>
> - Replaced ((ARM || ARM64) && COMPILE_TEST) with COMPILE_TEST as per
> suggestion from Rob
>
> Changes since [v3]:
>
> - Based on feedback from NXP, DIRECT_SPEED_CHANGE quirk was expanded
> to cover both i.MX7 and i.MX8MQ
>
> - Code setting device type in GPR12 moved to a standalone function
>
> - Explicit "fsl,controller-id" binding was dropped, replaced by using
> controller physical address to determine logical ID
>
> - Dropped Reviewed-by from Lucas for patch 4/4 due to the change
> above (haven't heard explicit "yea" for it from him)
>
> Changes since [v2], [fixes]:
>
> - Incorporated [patch] introducing drvdata
>
> - i.MX6 PHY operation gating converted to a single patch and to use a
> dedicated flag instead of doing explicit variant check
>
> - Kconfig entry changed to use ARM64 && ARCH_MXC
>
> - Dropped FALLTHROUGH annotations
>
> Changes since [v1]:
>
> - Driver changed to use single "fsl,controller-id" property to
> distinguish between two intances of PCIE IP block
>
> - All code pertaining to L1SS was dropped to simplify the patch
>
> - Documented additions to DT bindings
>
> Feedback is welcome!
>
> Thanks,
> Andrey Smirnov
>
> [v6] https://lore.kernel.org/linux-arm-kernel/https://lore.kernel.org/linux-arm-kernel/20190124201522.8973-1-andrew.smirnov@gmail.com
> [v5] https://lore.kernel.org/linux-arm-kernel/20190112215601.9535-1-andrew.smirnov@gmail.com
> [v4] https://lore.kernel.org/linux-arm-kernel/20190104165335.13205-1-andrew.smirnov@gmail.com
> [v3] https://lore.kernel.org/linux-arm-kernel/20181218040702.29231-1-andrew.smirnov@gmail.com
> [patch] https://patchwork.kernel.org/patch/10712261/
> [fixes] https://lore.kernel.org/linux-arm-kernel/20181216230916.22982-1-andrew.smirnov@gmail.com
> [v2] https://lore.kernel.org/linux-arm-kernel/20181206073545.10967-1-andrew.smirnov@gmail.com
> [v1] https://lore.kernel.org/linux-arm-kernel/20181117181225.10737-1-andrew.smirnov@gmail.com/
>
> Andrey Smirnov (4):
> PCI: imx6: Introduce drvdata
> PCI: imx6: Mark PHY functions as i.MX6 specific
> PCI: imx6: Convert DIRECT_SPEED_CHANGE quirk code to use a flag
> PCI: imx6: Add support for i.MX8MQ
>
> .../bindings/pci/fsl,imx6q-pcie.txt | 3 +-
> drivers/pci/controller/dwc/Kconfig | 4 +-
> drivers/pci/controller/dwc/pci-imx6.c | 150 +++++++++++++++---
> 3 files changed, 133 insertions(+), 24 deletions(-)
>
> --
> 2.20.1
>
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2019-02-04 12:19 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-02-02 0:15 [PATCH v7 0/4] PCIE support for i.MX8MQ Andrey Smirnov
2019-02-02 0:15 ` [PATCH v7 1/4] PCI: imx6: Introduce drvdata Andrey Smirnov
2019-02-02 0:15 ` [PATCH v7 2/4] PCI: imx6: Mark PHY functions as i.MX6 specific Andrey Smirnov
2019-02-02 0:15 ` [PATCH v7 3/4] PCI: imx6: Convert DIRECT_SPEED_CHANGE quirk code to use a flag Andrey Smirnov
2019-02-02 0:15 ` [PATCH v7 4/4] PCI: imx6: Add support for i.MX8MQ Andrey Smirnov
2019-02-04 12:19 ` [PATCH v7 0/4] PCIE " Lorenzo Pieralisi
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).