* [PATCH v2 0/2] Add PCIe driver support for imx6sx.
@ 2016-02-18 11:59 Christoph Fritz
2016-02-18 11:59 ` [PATCH v2 1/2] MFD: imx6sx: Add PCIe register definitions for iomuxc gpr Christoph Fritz
2016-02-18 11:59 ` [PATCH v2 2/2] PCI: imx6: add initial imx6sx support Christoph Fritz
0 siblings, 2 replies; 6+ messages in thread
From: Christoph Fritz @ 2016-02-18 11:59 UTC (permalink / raw)
To: Richard Zhu, Lucas Stach, Bjorn Helgaas, Lee Jones
Cc: linux-pci, Fabio Estevam
Add PCIe driver support for imx6sx.
v2:
* leave out regulator handling from driver, will be done later
in PM subsystem
* use BIT() macro for MFD
Christoph Fritz (2):
MFD: imx6sx: Add PCIe register definitions for iomuxc gpr
PCI: imx6: add initial imx6sx support
drivers/pci/host/pci-imx6.c | 130 +++++++++++++++++++---------
include/linux/mfd/syscon/imx6q-iomuxc-gpr.h | 5 ++
2 files changed, 96 insertions(+), 39 deletions(-)
--
2.1.4
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH v2 1/2] MFD: imx6sx: Add PCIe register definitions for iomuxc gpr
2016-02-18 11:59 [PATCH v2 0/2] Add PCIe driver support for imx6sx Christoph Fritz
@ 2016-02-18 11:59 ` Christoph Fritz
2016-02-18 11:59 ` [PATCH v2 2/2] PCI: imx6: add initial imx6sx support Christoph Fritz
1 sibling, 0 replies; 6+ messages in thread
From: Christoph Fritz @ 2016-02-18 11:59 UTC (permalink / raw)
To: Richard Zhu, Lucas Stach, Bjorn Helgaas, Lee Jones
Cc: linux-pci, Fabio Estevam
This patch adds macros to define masks and bits for imx6sx
PCIe registers. This is based on a patch by Richard Zhu.
Signed-off-by: Christoph Fritz <chf.fritz@googlemail.com>
---
include/linux/mfd/syscon/imx6q-iomuxc-gpr.h | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/include/linux/mfd/syscon/imx6q-iomuxc-gpr.h b/include/linux/mfd/syscon/imx6q-iomuxc-gpr.h
index 558a485..238c8db 100644
--- a/include/linux/mfd/syscon/imx6q-iomuxc-gpr.h
+++ b/include/linux/mfd/syscon/imx6q-iomuxc-gpr.h
@@ -422,6 +422,7 @@
#define IMX6SX_GPR5_VADC_TO_CSI_CAPTURE_EN_MASK (0x1 << 26)
#define IMX6SX_GPR5_VADC_TO_CSI_CAPTURE_EN_ENABLE (0x1 << 26)
#define IMX6SX_GPR5_VADC_TO_CSI_CAPTURE_EN_DISABLE (0x0 << 26)
+#define IMX6SX_GPR5_PCIE_BTNRST_RESET BIT(19)
#define IMX6SX_GPR5_CSI1_MUX_CTRL_MASK (0x3 << 4)
#define IMX6SX_GPR5_CSI1_MUX_CTRL_EXT_PIN (0x0 << 4)
#define IMX6SX_GPR5_CSI1_MUX_CTRL_CVD (0x1 << 4)
@@ -435,6 +436,10 @@
#define IMX6SX_GPR5_DISP_MUX_DCIC1_LVDS (0x1 << 1)
#define IMX6SX_GPR5_DISP_MUX_DCIC1_MASK (0x1 << 1)
+#define IMX6SX_GPR12_PCIE_TEST_POWERDOWN BIT(30)
+#define IMX6SX_GPR12_PCIE_RX_EQ_MASK (0x7 << 0)
+#define IMX6SX_GPR12_PCIE_RX_EQ_2 (0x2 << 0)
+
/* For imx6ul iomux gpr register field define */
#define IMX6UL_GPR1_ENET1_CLK_DIR (0x1 << 17)
#define IMX6UL_GPR1_ENET2_CLK_DIR (0x1 << 18)
--
2.1.4
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH v2 2/2] PCI: imx6: add initial imx6sx support
2016-02-18 11:59 [PATCH v2 0/2] Add PCIe driver support for imx6sx Christoph Fritz
2016-02-18 11:59 ` [PATCH v2 1/2] MFD: imx6sx: Add PCIe register definitions for iomuxc gpr Christoph Fritz
@ 2016-02-18 11:59 ` Christoph Fritz
2016-02-20 19:37 ` Fabio Estevam
1 sibling, 1 reply; 6+ messages in thread
From: Christoph Fritz @ 2016-02-18 11:59 UTC (permalink / raw)
To: Richard Zhu, Lucas Stach, Bjorn Helgaas, Lee Jones
Cc: linux-pci, Fabio Estevam
This patch adds initial PCIe support for the imx6 SoC derivate imx6sx.
PCI_MSI support is untested as its necessary suspend/resume quirk is
left out of this patch.
This patch is heavily based on patches by Richard Zhu.
Signed-off-by: Christoph Fritz <chf.fritz@googlemail.com>
---
drivers/pci/host/pci-imx6.c | 130 +++++++++++++++++++++++++++++++-------------
1 file changed, 91 insertions(+), 39 deletions(-)
diff --git a/drivers/pci/host/pci-imx6.c b/drivers/pci/host/pci-imx6.c
index fe60096..7e634a6 100644
--- a/drivers/pci/host/pci-imx6.c
+++ b/drivers/pci/host/pci-imx6.c
@@ -35,9 +35,11 @@ struct imx6_pcie {
struct gpio_desc *reset_gpio;
struct clk *pcie_bus;
struct clk *pcie_phy;
+ struct clk *pcie_inbound_axi;
struct clk *pcie;
struct pcie_port pp;
struct regmap *iomuxc_gpr;
+ bool is_imx6sx;
void __iomem *mem_base;
};
@@ -214,35 +216,46 @@ static int imx6_pcie_assert_core_reset(struct pcie_port *pp)
struct imx6_pcie *imx6_pcie = to_imx6_pcie(pp);
u32 val, gpr1, gpr12;
- /*
- * If the bootloader already enabled the link we need some special
- * handling to get the core back into a state where it is safe to
- * touch it for configuration. As there is no dedicated reset signal
- * wired up for MX6QDL, we need to manually force LTSSM into "detect"
- * state before completely disabling LTSSM, which is a prerequisite
- * for core configuration.
- *
- * If both LTSSM_ENABLE and REF_SSP_ENABLE are active we have a strong
- * indication that the bootloader activated the link.
- */
- regmap_read(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1, &gpr1);
- regmap_read(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12, &gpr12);
-
- if ((gpr1 & IMX6Q_GPR1_PCIE_REF_CLK_EN) &&
- (gpr12 & IMX6Q_GPR12_PCIE_CTL_2)) {
- val = readl(pp->dbi_base + PCIE_PL_PFLR);
- val &= ~PCIE_PL_PFLR_LINK_STATE_MASK;
- val |= PCIE_PL_PFLR_FORCE_LINK;
- writel(val, pp->dbi_base + PCIE_PL_PFLR);
-
+ if (imx6_pcie->is_imx6sx) {
regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
- IMX6Q_GPR12_PCIE_CTL_2, 0 << 10);
- }
+ IMX6SX_GPR12_PCIE_TEST_POWERDOWN,
+ IMX6SX_GPR12_PCIE_TEST_POWERDOWN);
+ /* Force PCIe PHY reset */
+ regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR5,
+ IMX6SX_GPR5_PCIE_BTNRST_RESET,
+ IMX6SX_GPR5_PCIE_BTNRST_RESET);
+ } else {
+ /*
+ * If the bootloader already enabled the link we need some
+ * special handling to get the core back into a state where
+ * it is safe to touch it for configuration. As there is no
+ * dedicated reset signal to manually force LTSSM into "detect"
+ * state before completely disabling LTSSM, which is a
+ * prerequisite for core configuration.
+ *
+ * If both LTSSM_ENABLE and REF_SSP_ENABLE are active we have
+ * a strong indication that the bootloader activated the link.
+ */
+ regmap_read(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1, &gpr1);
+ regmap_read(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12, &gpr12);
+
+ if ((gpr1 & IMX6Q_GPR1_PCIE_REF_CLK_EN) &&
+ (gpr12 & IMX6Q_GPR12_PCIE_CTL_2)) {
+ val = readl(pp->dbi_base + PCIE_PL_PFLR);
+ val &= ~PCIE_PL_PFLR_LINK_STATE_MASK;
+ val |= PCIE_PL_PFLR_FORCE_LINK;
+ writel(val, pp->dbi_base + PCIE_PL_PFLR);
+
+ regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
+ IMX6Q_GPR12_PCIE_CTL_2, 0);
+ }
- regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1,
- IMX6Q_GPR1_PCIE_TEST_PD, 1 << 18);
- regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1,
- IMX6Q_GPR1_PCIE_REF_CLK_EN, 0 << 16);
+ regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1,
+ IMX6Q_GPR1_PCIE_TEST_PD,
+ IMX6Q_GPR1_PCIE_TEST_PD);
+ regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1,
+ IMX6Q_GPR1_PCIE_REF_CLK_EN, 0);
+ }
return 0;
}
@@ -270,18 +283,30 @@ static int imx6_pcie_deassert_core_reset(struct pcie_port *pp)
goto err_pcie;
}
- /* power up core phy and enable ref clock */
- regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1,
- IMX6Q_GPR1_PCIE_TEST_PD, 0 << 18);
- /*
- * the async reset input need ref clock to sync internally,
- * when the ref clock comes after reset, internal synced
- * reset time is too short, cannot meet the requirement.
- * add one ~10us delay here.
- */
- udelay(10);
- regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1,
- IMX6Q_GPR1_PCIE_REF_CLK_EN, 1 << 16);
+ if (imx6_pcie->is_imx6sx) {
+ ret = clk_prepare_enable(imx6_pcie->pcie_inbound_axi);
+ if (ret) {
+ dev_err(pp->dev, "unable to enable pcie_axi clock\n");
+ goto err_inbound_axi;
+ }
+
+ regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
+ IMX6SX_GPR12_PCIE_TEST_POWERDOWN, 0);
+ } else {
+ /* power up core phy and enable ref clock */
+ regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1,
+ IMX6Q_GPR1_PCIE_TEST_PD, 0);
+ /*
+ * the async reset input need ref clock to sync internally,
+ * when the ref clock comes after reset, internal synced
+ * reset time is too short , cannot meet the requirement.
+ * add one ~10us delay here.
+ */
+ udelay(10);
+ regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1,
+ IMX6Q_GPR1_PCIE_REF_CLK_EN,
+ IMX6Q_GPR1_PCIE_REF_CLK_EN);
+ }
/* allow the clocks to stabilize */
usleep_range(200, 500);
@@ -292,8 +317,15 @@ static int imx6_pcie_deassert_core_reset(struct pcie_port *pp)
msleep(100);
gpiod_set_value_cansleep(imx6_pcie->reset_gpio, 1);
}
+
+ if (imx6_pcie->is_imx6sx)
+ regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR5,
+ IMX6SX_GPR5_PCIE_BTNRST_RESET, 0);
+
return 0;
+err_inbound_axi:
+ clk_disable_unprepare(imx6_pcie->pcie);
err_pcie:
clk_disable_unprepare(imx6_pcie->pcie_bus);
err_pcie_bus:
@@ -307,6 +339,12 @@ static void imx6_pcie_init_phy(struct pcie_port *pp)
{
struct imx6_pcie *imx6_pcie = to_imx6_pcie(pp);
+ if (imx6_pcie->is_imx6sx) {
+ regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
+ IMX6SX_GPR12_PCIE_RX_EQ_MASK,
+ IMX6SX_GPR12_PCIE_RX_EQ_2);
+ }
+
regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
IMX6Q_GPR12_PCIE_CTL_2, 0 << 10);
@@ -571,6 +609,9 @@ static int __init imx6_pcie_probe(struct platform_device *pdev)
pp = &imx6_pcie->pp;
pp->dev = &pdev->dev;
+ imx6_pcie->is_imx6sx = of_device_is_compatible(pp->dev->of_node,
+ "fsl,imx6sx-pcie");
+
/* Added for PCI abort handling */
hook_fault_code(16 + 6, imx6q_pcie_abort_handler, SIGBUS, 0,
"imprecise external abort");
@@ -606,6 +647,16 @@ static int __init imx6_pcie_probe(struct platform_device *pdev)
return PTR_ERR(imx6_pcie->pcie);
}
+ if (imx6_pcie->is_imx6sx) {
+ imx6_pcie->pcie_inbound_axi = devm_clk_get(&pdev->dev,
+ "pcie_inbound_axi");
+ if (IS_ERR(imx6_pcie->pcie_inbound_axi)) {
+ dev_err(&pdev->dev,
+ "pcie_incbound_axi clock missing or invalid\n");
+ return PTR_ERR(imx6_pcie->pcie_inbound_axi);
+ }
+ }
+
/* Grab GPR config register range */
imx6_pcie->iomuxc_gpr =
syscon_regmap_lookup_by_compatible("fsl,imx6q-iomuxc-gpr");
@@ -632,6 +683,7 @@ static void imx6_pcie_shutdown(struct platform_device *pdev)
static const struct of_device_id imx6_pcie_of_match[] = {
{ .compatible = "fsl,imx6q-pcie", },
+ { .compatible = "fsl,imx6sx-pcie", },
{},
};
MODULE_DEVICE_TABLE(of, imx6_pcie_of_match);
--
2.1.4
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH v2 2/2] PCI: imx6: add initial imx6sx support
2016-02-18 11:59 ` [PATCH v2 2/2] PCI: imx6: add initial imx6sx support Christoph Fritz
@ 2016-02-20 19:37 ` Fabio Estevam
2016-02-22 0:40 ` Christoph Fritz
0 siblings, 1 reply; 6+ messages in thread
From: Fabio Estevam @ 2016-02-20 19:37 UTC (permalink / raw)
To: Christoph Fritz
Cc: Richard Zhu, Lucas Stach, Bjorn Helgaas, Lee Jones, linux-pci,
Fabio Estevam
Hi Christoph,
On Thu, Feb 18, 2016 at 9:59 AM, Christoph Fritz
<chf.fritz@googlemail.com> wrote:
> static const struct of_device_id imx6_pcie_of_match[] = {
> { .compatible = "fsl,imx6q-pcie", },
> + { .compatible = "fsl,imx6sx-pcie", },
Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.txt needs to be
updated to include this new compatible string.
Thanks
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v2 2/2] PCI: imx6: add initial imx6sx support
2016-02-20 19:37 ` Fabio Estevam
@ 2016-02-22 0:40 ` Christoph Fritz
2016-02-22 9:19 ` Christoph Fritz
0 siblings, 1 reply; 6+ messages in thread
From: Christoph Fritz @ 2016-02-22 0:40 UTC (permalink / raw)
To: Fabio Estevam
Cc: Richard Zhu, Lucas Stach, Bjorn Helgaas, Lee Jones, linux-pci,
Fabio Estevam
Hi Fabio
On Sat, 2016-02-20 at 17:37 -0200, Fabio Estevam wrote:
> On Thu, Feb 18, 2016 at 9:59 AM, Christoph Fritz
> <chf.fritz@googlemail.com> wrote:
>
> > static const struct of_device_id imx6_pcie_of_match[] = {
> > { .compatible = "fsl,imx6q-pcie", },
> > + { .compatible = "fsl,imx6sx-pcie", },
>
> Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.txt needs to be
> updated to include this new compatible string.
Thanks, I'll wait a bit for other possible comments and will then send a
v3 patchset which updates the documentation too.
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v2 2/2] PCI: imx6: add initial imx6sx support
2016-02-22 0:40 ` Christoph Fritz
@ 2016-02-22 9:19 ` Christoph Fritz
0 siblings, 0 replies; 6+ messages in thread
From: Christoph Fritz @ 2016-02-22 9:19 UTC (permalink / raw)
To: Richard Zhu, Lucas Stach
Cc: Fabio Estevam, Bjorn Helgaas, Lee Jones, linux-pci, Fabio Estevam
On Mon, 2016-02-22 at 01:40 +0100, Christoph Fritz wrote:
> On Sat, 2016-02-20 at 17:37 -0200, Fabio Estevam wrote:
> > On Thu, Feb 18, 2016 at 9:59 AM, Christoph Fritz
> > <chf.fritz@googlemail.com> wrote:
> >
> > > static const struct of_device_id imx6_pcie_of_match[] = {
> > > { .compatible = "fsl,imx6q-pcie", },
> > > + { .compatible = "fsl,imx6sx-pcie", },
> >
> > Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.txt needs to be
> > updated to include this new compatible string.
>
> Thanks, I'll wait a bit for other possible comments and will then send a
> v3 patchset which updates the documentation too.
>
@MAINTAINERS (Lucas or Richard):
Do you want the documentation changes as a separate patch?
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2016-02-22 9:19 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-02-18 11:59 [PATCH v2 0/2] Add PCIe driver support for imx6sx Christoph Fritz
2016-02-18 11:59 ` [PATCH v2 1/2] MFD: imx6sx: Add PCIe register definitions for iomuxc gpr Christoph Fritz
2016-02-18 11:59 ` [PATCH v2 2/2] PCI: imx6: add initial imx6sx support Christoph Fritz
2016-02-20 19:37 ` Fabio Estevam
2016-02-22 0:40 ` Christoph Fritz
2016-02-22 9:19 ` Christoph Fritz
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.