IMX6Q: Linux boot halts at PCIe config space read

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

IMX6Q: Linux boot halts at PCIe config space read

Jump to solution
2,523 Views
adrianmcgrath
Contributor III

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

Labels (3)
0 Kudos
1 Solution
1,272 Views
adrianmcgrath
Contributor III

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;

View solution in original post

0 Kudos
5 Replies
1,272 Views
igorpadykov
NXP Employee
NXP Employee

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!

-----------------------------------------------------------------------------------------------------------------------

0 Kudos
1,272 Views
adrianmcgrath
Contributor III

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

0 Kudos
1,272 Views
igorpadykov
NXP Employee
NXP Employee

for kernel version 3.14.28 one can try patch

https://community.freescale.com/message/613869#comment-613869

~igor

0 Kudos
1,272 Views
adrianmcgrath
Contributor III

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

0 Kudos
1,273 Views
adrianmcgrath
Contributor III

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;

0 Kudos