From: Andrey Smirnov <andrew.smirnov@gmail.com>
To: barebox@lists.infradead.org
Cc: Fabio Estevam <fabio.estevam@freescale.com>,
Andrey Smirnov <andrew.smirnov@gmail.com>
Subject: [PATCH 3/9] PCI: imx6: Add proper i.MX6+ reset sequence
Date: Mon, 25 Apr 2016 22:37:01 -0700 [thread overview]
Message-ID: <1461649027-5046-4-git-send-email-andrew.smirnov@gmail.com> (raw)
In-Reply-To: <1461649027-5046-1-git-send-email-andrew.smirnov@gmail.com>
I.MX6+ version of the silicon exposed PCIe core's reset signal as a bit
in one of the control registers. As a result using old, pre-i.MX6+,
reset sequence on i.MX6+ leads to Barebox hanging during startup. Using
exposed reset bit instead solves the problem.
This commit is based on portions of commit
c34068d48273e24d392d9a49a38be807954420ed
in http://git.freescale.com/git/cgit.cgi/imx/linux-2.6-imx.git
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
drivers/pci/pci-imx6.c | 94 +++++++++++++++++++++++++++++-------------
include/mfd/imx6q-iomuxc-gpr.h | 1 +
2 files changed, 66 insertions(+), 29 deletions(-)
diff --git a/drivers/pci/pci-imx6.c b/drivers/pci/pci-imx6.c
index 241df3f..13a8b22 100644
--- a/drivers/pci/pci-imx6.c
+++ b/drivers/pci/pci-imx6.c
@@ -20,6 +20,7 @@
#include <gpio.h>
#include <asm/mmu.h>
#include <of_gpio.h>
+#include <of_device.h>
#include <linux/clk.h>
#include <linux/kernel.h>
#include <of_address.h>
@@ -36,6 +37,11 @@
#define to_imx6_pcie(x) container_of(x, struct imx6_pcie, pp)
+enum imx6_pcie_variants {
+ IMX6Q,
+ IMX6QP,
+};
+
struct imx6_pcie {
int reset_gpio;
struct clk *pcie_bus;
@@ -43,6 +49,7 @@ struct imx6_pcie {
struct clk *pcie;
struct pcie_port pp;
void __iomem *iomuxc_gpr;
+ enum imx6_pcie_variants variant;
void __iomem *mem_base;
};
@@ -219,39 +226,48 @@ 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.
- */
- gpr1 = readl(imx6_pcie->iomuxc_gpr + IOMUXC_GPR1);
- gpr12 = readl(imx6_pcie->iomuxc_gpr + IOMUXC_GPR12);
+ switch (imx6_pcie->variant) {
+ case IMX6QP:
+ gpr1 = readl(imx6_pcie->iomuxc_gpr + IOMUXC_GPR1);
+ gpr1 |= IMX6Q_GPR1_PCIE_SW_RST;
+ writel(gpr1, imx6_pcie->iomuxc_gpr + IOMUXC_GPR1);
+ break;
+ case IMX6Q:
+ /*
+ * 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.
+ */
+ gpr1 = readl(imx6_pcie->iomuxc_gpr + IOMUXC_GPR1);
+ gpr12 = readl(imx6_pcie->iomuxc_gpr + IOMUXC_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;
+ 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;
- data_abort_mask();
- writel(val, pp->dbi_base + PCIE_PL_PFLR);
- data_abort_unmask();
+ data_abort_mask();
+ writel(val, pp->dbi_base + PCIE_PL_PFLR);
+ data_abort_unmask();
- gpr12 &= ~IMX6Q_GPR12_PCIE_CTL_2;
- writel(gpr12, imx6_pcie->iomuxc_gpr + IOMUXC_GPR12);
- }
+ gpr12 &= ~IMX6Q_GPR12_PCIE_CTL_2;
+ writel(gpr12, imx6_pcie->iomuxc_gpr + IOMUXC_GPR12);
+ }
- gpr1 |= IMX6Q_GPR1_PCIE_TEST_PD;
- writel(gpr1, imx6_pcie->iomuxc_gpr + IOMUXC_GPR1);
+ gpr1 |= IMX6Q_GPR1_PCIE_TEST_PD;
+ writel(gpr1, imx6_pcie->iomuxc_gpr + IOMUXC_GPR1);
- gpr1 &= ~IMX6Q_GPR1_PCIE_REF_CLK_EN;
- writel(gpr1, imx6_pcie->iomuxc_gpr + IOMUXC_GPR1);
+ gpr1 &= ~IMX6Q_GPR1_PCIE_REF_CLK_EN;
+ writel(gpr1, imx6_pcie->iomuxc_gpr + IOMUXC_GPR1);
+ break;
+ }
return 0;
}
@@ -298,6 +314,22 @@ static int imx6_pcie_deassert_core_reset(struct pcie_port *pp)
mdelay(100);
gpio_set_value(imx6_pcie->reset_gpio, 1);
}
+
+ /*
+ * Release the PCIe PHY reset here
+ */
+ switch (imx6_pcie->variant) {
+ case IMX6QP:
+ gpr1 = readl(imx6_pcie->iomuxc_gpr + IOMUXC_GPR1);
+ gpr1 &= ~IMX6Q_GPR1_PCIE_SW_RST;
+ writel(gpr1, imx6_pcie->iomuxc_gpr + IOMUXC_GPR1);
+
+ udelay(200);
+ break;
+ case IMX6Q: /* Nothing to do */
+ break;
+ }
+
return 0;
err_pcie:
@@ -568,6 +600,9 @@ static int __init imx6_pcie_probe(struct device_d *dev)
pp = &imx6_pcie->pp;
pp->dev = dev;
+ imx6_pcie->variant =
+ (enum imx6_pcie_variants)of_device_get_match_data(dev);
+
iores = dev_request_mem_resource(dev, 0);
if (IS_ERR(iores))
return PTR_ERR(iores);
@@ -623,7 +658,8 @@ static void imx6_pcie_remove(struct device_d *dev)
}
static struct of_device_id imx6_pcie_of_match[] = {
- { .compatible = "fsl,imx6q-pcie", },
+ { .compatible = "fsl,imx6q-pcie", .data = (void *)IMX6Q, },
+ { .compatible = "fsl,imx6qp-pcie", .data = (void *)IMX6QP, },
{},
};
diff --git a/include/mfd/imx6q-iomuxc-gpr.h b/include/mfd/imx6q-iomuxc-gpr.h
index a7ef1c8..b2c9da6 100644
--- a/include/mfd/imx6q-iomuxc-gpr.h
+++ b/include/mfd/imx6q-iomuxc-gpr.h
@@ -95,6 +95,7 @@
#define IMX6Q_GPR0_DMAREQ_MUX_SEL0_IOMUX BIT(0)
#define IMX6Q_GPR1_PCIE_REQ_MASK (0x3 << 30)
+#define IMX6Q_GPR1_PCIE_SW_RST BIT(29)
#define IMX6Q_GPR1_PCIE_EXIT_L1 BIT(28)
#define IMX6Q_GPR1_PCIE_RDY_L23 BIT(27)
#define IMX6Q_GPR1_PCIE_ENTER_L1 BIT(26)
--
2.5.5
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
next prev parent reply other threads:[~2016-04-26 5:37 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-04-26 5:36 [PATCH 0/9] i.MX6Q+ fixes plus number of latest Kernel changes Andrey Smirnov
2016-04-26 5:36 ` [PATCH 1/9] PCI: imx6: Simplify imx6_pcie_remove() Andrey Smirnov
2016-04-26 5:37 ` [PATCH 2/9] OF: Port of_match_device() and of_device_get_match_data() Andrey Smirnov
2016-04-26 5:37 ` Andrey Smirnov [this message]
2016-04-26 5:37 ` [PATCH 4/9] PCI: imx6: Rename imx6_pcie_start_link() to imx6_pcie_establish_link() Andrey Smirnov
2016-05-04 21:53 ` Bjorn Helgaas
2016-04-26 5:37 ` [PATCH 5/9] PCI: imx6: Simplify a trivial if-return sequence Andrey Smirnov
2016-04-26 5:37 ` [PATCH 6/9] PCI: imx6: Move imx6_pcie_reset_phy() near other PHY handling functions Andrey Smirnov
2016-04-26 5:37 ` [PATCH 7/9] PCI: imx6: Move PHY reset into imx6_pcie_establish_link() Andrey Smirnov
2016-04-26 5:37 ` [PATCH 8/9] PCI: imx6: Remove broken Gen2 workaround Andrey Smirnov
2016-04-26 5:37 ` [PATCH 9/9] PCI: imx6: Add DT bindings to configure PHY Tx driver settings Andrey Smirnov
2016-04-27 9:05 ` [PATCH 0/9] i.MX6Q+ fixes plus number of latest Kernel changes Lucas Stach
2016-04-28 5:45 ` Sascha Hauer
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1461649027-5046-4-git-send-email-andrew.smirnov@gmail.com \
--to=andrew.smirnov@gmail.com \
--cc=barebox@lists.infradead.org \
--cc=fabio.estevam@freescale.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox