diff mbox

Intel I350 mini-PCIe card (igb) on Mirabox (mvebu / Armada 370)

Message ID 20140326201243.GA1536@obsidianresearch.com (mailing list archive)
State New, archived
Headers show

Commit Message

Jason Gunthorpe March 26, 2014, 8:12 p.m. UTC
On Wed, Mar 26, 2014 at 07:31:12PM +0000, Neil Greatorex wrote:
> > Sorry, it has a mistake, that is not how you detect CRS on this chip..
> >
> > CRS might be something the driver has to emulate as well.....
> >
> > This is better.. CRS will be bit 19 in the ICR

> I ran your patch. The dmesg output is available at
> https://gist.github.com/ngreatorex/9790164
> 
> I'm afraid the output doesn't mean much to me :-)

This is the relevant bit:

[    0.136040] mvebu-pcie pcie-controller.3: ICR is 0
[    0.161162] mvebu-pcie pcie-controller.3: Vendor ID is ffffffff
[    0.161170] mvebu-pcie pcie-controller.3: ICR is 800200
[    1.170071] mvebu-pcie pcie-controller.3: Try 2: Vendor ID is ffffffff
[    1.170083] mvebu-pcie pcie-controller.3: ICR is 808200 

#1 The ICR indicates PexLinkFail and NFErrDet after the first vendor
   read. I think PexLinkFail is very surprising, documentation says it
   means there was an error on the link and it re-trained. Perhaps it
   is a side effect of #2..

#2 It looks like I botched the format of the configuration since the NIC
   didn't respond, I think I see why.

#3 After sleeping the PEX detected a UR or CA TLP, which is not
   necessarily surprising, considering #2..

So, we need a result that actually reads the vendor id..

Here is a revision, I suspect the error with the debugging was not
calling mvebu_pcie_set_local_bus_nr, so a type 1 transaction was being
produced. I am looking for the 2nd Vendor ID to return 80861521.

Also, are you using the "reset-gpios" DT property?

Comments

Neil Greatorex March 26, 2014, 8:34 p.m. UTC | #1
Jason,

On Wed, Mar 26, 2014 at 8:12 PM, Jason Gunthorpe
<jgunthorpe@obsidianresearch.com> wrote:
>
> So, we need a result that actually reads the vendor id..
>
> Here is a revision, I suspect the error with the debugging was not
> calling mvebu_pcie_set_local_bus_nr, so a type 1 transaction was being
> produced. I am looking for the 2nd Vendor ID to return 80861521.
>

Thanks. Here's the relevant output with that patch:

[    0.135772] mvebu-pcie pcie-controller.3: ICR is 0
[    0.160889] mvebu-pcie pcie-controller.3: Vendor ID is ffffffff
[    0.160897] mvebu-pcie pcie-controller.3: ICR is 800200
[    1.170215] mvebu-pcie pcie-controller.3: Try 2: Vendor ID is 15218086
[    1.170228] mvebu-pcie pcie-controller.3: ICR is 0
[    1.170290] mvebu-pcie pcie-controller.3: ICR is 0
[    1.170299] mvebu-pcie pcie-controller.3: Vendor ID is 10091b73
[    1.170306] mvebu-pcie pcie-controller.3: ICR is 0
[    2.180207] mvebu-pcie pcie-controller.3: Try 2: Vendor ID is 10091b73
[    2.180215] mvebu-pcie pcie-controller.3: ICR is 0

Success! For reference, the full dmesg is at https://gist.github.com/9792618

> Also, are you using the "reset-gpios" DT property?
>

I'm appending arch/arm/boot/dts/armada-370-mirabox.dtb to the kernel
image as the bootloader on the Mirabox is ancient and doesn't support
DTs. As far as I can see, there's no reset-gpios property anywhere in
that DT.

With regards to the bootloader, in case the information helps, it prints out:

PEX 0: Root Complex Interface, Detected Link X1
PEX 1: Root Complex Interface, Detected Link X1

As I am booting from the SD card, which is internally connected via
USB, the boot loader is obviously initialising the XHCI controller.
I'm guessing this is why it is detected immediately without needing
the delay.

Cheers,
Neil
diff mbox

Patch

diff --git a/drivers/pci/host/pci-mvebu.c b/drivers/pci/host/pci-mvebu.c
index b8f2fc9..6da4983 100644
--- a/drivers/pci/host/pci-mvebu.c
+++ b/drivers/pci/host/pci-mvebu.c
@@ -999,6 +999,38 @@  static int mvebu_pcie_probe(struct platform_device *pdev)
 
 		mvebu_pcie_set_local_dev_nr(port, 1);
 
+		/* Wait for the link to come up */
+		if (!mvebu_pcie_link_up(port)) {
+			unsigned int I;
+
+			dev_info(&pdev->dev, "Waiting for link up\n");
+			for (I = 0; I != 100; I++) {
+				udelay(100);
+				if (mvebu_pcie_link_up(port))
+					break;
+			}
+			dev_info(&pdev->dev, "Link is %u\n",
+				 mvebu_pcie_link_up(port));
+		}
+
+		/* Clear and report the ICR */
+		mvebu_writel(port, 0, 0x1900);
+		dev_info(&pdev->dev, "ICR is %x\n", mvebu_readl(port, 0x1900));
+
+		/* Read the vendor ID from the connected device */
+		mvebu_pcie_set_local_bus_nr(port, 1);
+		mvebu_writel(port, PCIE_CONF_ADDR(1, 0, 0), PCIE_CONF_ADDR_OFF);
+		dev_info(&pdev->dev, "Vendor ID is %x\n",
+			 mvebu_readl(port, PCIE_CONF_DATA_OFF));
+		dev_info(&pdev->dev, "ICR is %x\n", mvebu_readl(port, 0x1900));
+		mvebu_writel(port, 0, 0x1900);
+		msleep(1000);
+		mvebu_writel(port, PCIE_CONF_ADDR(1, 0, 0), PCIE_CONF_ADDR_OFF);
+		dev_info(&pdev->dev, "Try 2: Vendor ID is %x\n",
+			 mvebu_readl(port, PCIE_CONF_DATA_OFF));
+		dev_info(&pdev->dev, "ICR is %x\n", mvebu_readl(port, 0x1900));
+
+
 		port->dn = child;
 		spin_lock_init(&port->conf_lock);
 		mvebu_sw_pci_bridge_init(port);