Hello all
I have an IMX6Q system (similar to SabreSD but not the same) that is failing to boot into Linux. There are numerous of our systems with the same hw/sw that work flawlessly. This non-booting system has been checked over by the hardware dept and found to be okay.
I've tracked the boot halt through the Kernel to pci_bus_read_dev_vendor_id() in drivers/pci/probe.c. A few printk's reveal that the boot halts at the PCI config space read (pci_bus_read_config_dword()) of the i210 NIC chip (this is the only device on the PCIe bus).
Interestingly, I can get this system to successfully boot to the login prompt with full network capabilities if I spray the IMX6Q (only) liberally with freezer spray (this is clearly not a production solution;)
So, I've got two questions that I hope the community can help me with:
1) Given that other systems with equivalent hw/sw work well and that I can get this system to boot correctly by using freezer spray on the IMX6Q chip can anyone suggest what might be the issue?
2) Also, I'm wondering whether moving the PCIe device enumeration to later in the boot would help. I've so far been unable to find any suggestions for how to do this. Would anyone be able to point me in the right direction?
Many thanks
Solved! Go to Solution.
Further to my previous post, my systems have now had a reasonable amount of testing without further incident. Therefore, for Linux kernel 3.14.28 I updated the following sections in "drivers/pci/host/pci-imx6.c" as shown below.
Thanks go to Igor and the community.
@@ -276,6 +276,8 @@
val |= PCIE_PL_PFLR_FORCE_LINK;
writel(val, pp->dbi_base + PCIE_PL_PFLR);
+ usleep_range(30, 50);
+
regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
IMX6Q_GPR12_PCIE_CTL_2, 0);
}
@@ -332,7 +334,7 @@
} else {
/* power up core phy and enable ref clock */
regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1,
- IMX6Q_GPR1_PCIE_TEST_PD, 0);
+ IMX6Q_GPR1_PCIE_TEST_PD, 0 << 18);
/* sata_ref is not used by pcie on imx6sx */
ret = clk_prepare_enable(imx6_pcie->ref_100m);
@@ -355,6 +357,13 @@
/* allow the clocks to stabilize */
udelay(200);
+ if(!is_imx6sx_pcie(imx6_pcie))
+ {
+ udelay(10);
+ regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1, IMX6Q_GPR1_PCIE_REF_CLK_EN, 1 << 16);
+ }
+
/* Some boards don't have PCIe reset GPIO. */
if (gpio_is_valid(imx6_pcie->reset_gpio)) {
gpio_set_value_cansleep(imx6_pcie->reset_gpio, 0);
@@ -442,7 +451,7 @@
int count = 200;
while (!dw_pcie_link_up(pp)) {
- udelay(100);
+ usleep_range(100, 1000);
if (--count)
continue;
Hi Adrian
seems freezer increases signal/noise ratio as driver strength is
increasing with lower temperature. One can try to decrease system
noise decreasing core voltage to 1.17V or 1.20V, 1.25V or
alternatively increase pcie signals amplitude using IOMUXC_GPR8 register
settings :
https://community.freescale.com/docs/DOC-95554
Also one can try attached patches and solutions/patches on link below
PCIe link doesn't come up with XIO2001 PCI bridge on iMX6Q custom board
Best regards
igor
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
Hi
Thanks for your comments and the links.
I think the patches you posted are for an earlier kernel than I am using (3.14), therefore I'm in the process of applying the patche code to my 3.14.28 source.
I have some questions regarding patch 0001-ENGR00319415 to "arch/arm/cpu/armv7/mx6/soc.c"
File "arch/arm/cpu/armv7/mx6/soc.c" doesn't exist in kernel version 3.14.28, therefore I am adding the patch code to "arch/arm/mach-imx/mach-imx6q.c". So far I have added it to "imx6q_init_machine()" before the call to "of_platform_populate()" as this allows the patch code to be run before the peripheral devices are initialized.
Is "arch/arm/mach-imx/mach-imx6q.c" the correct file to use?
Is "imx6q_init_machine()" the best place to put this patch code in mach-imx6q.c?
Also, there is no reset_cpu() function call for IMX6Q within my kernel source. I assume that a "soft" reset is required so that the state of the registers is preserved, what "soft" reset mechanism would you suggest?
Many thanks
for kernel version 3.14.28 one can try patch
https://community.freescale.com/message/613869#comment-613869
~igor
Update:
I'm having some good results with the links that you provided yesterday. Will keep you all posted and provide an update when I've got some firm results on a warm board.
Many thanks
Further to my previous post, my systems have now had a reasonable amount of testing without further incident. Therefore, for Linux kernel 3.14.28 I updated the following sections in "drivers/pci/host/pci-imx6.c" as shown below.
Thanks go to Igor and the community.
@@ -276,6 +276,8 @@
val |= PCIE_PL_PFLR_FORCE_LINK;
writel(val, pp->dbi_base + PCIE_PL_PFLR);
+ usleep_range(30, 50);
+
regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
IMX6Q_GPR12_PCIE_CTL_2, 0);
}
@@ -332,7 +334,7 @@
} else {
/* power up core phy and enable ref clock */
regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1,
- IMX6Q_GPR1_PCIE_TEST_PD, 0);
+ IMX6Q_GPR1_PCIE_TEST_PD, 0 << 18);
/* sata_ref is not used by pcie on imx6sx */
ret = clk_prepare_enable(imx6_pcie->ref_100m);
@@ -355,6 +357,13 @@
/* allow the clocks to stabilize */
udelay(200);
+ if(!is_imx6sx_pcie(imx6_pcie))
+ {
+ udelay(10);
+ regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1, IMX6Q_GPR1_PCIE_REF_CLK_EN, 1 << 16);
+ }
+
/* Some boards don't have PCIe reset GPIO. */
if (gpio_is_valid(imx6_pcie->reset_gpio)) {
gpio_set_value_cansleep(imx6_pcie->reset_gpio, 0);
@@ -442,7 +451,7 @@
int count = 200;
while (!dw_pcie_link_up(pp)) {
- udelay(100);
+ usleep_range(100, 1000);
if (--count)
continue;