]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
PCI: rcar: Poll PHYRDY in rcar_pcie_hw_init()
authorSergei Shtylyov <sergei.shtylyov@cogentembedded.com>
Thu, 3 May 2018 19:36:37 +0000 (22:36 +0300)
committerLorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Fri, 4 May 2018 09:00:07 +0000 (10:00 +0100)
In all the R-Car gen1/2/3 manuals, we are instructed to poll PCIEPHYSR
for PHYRDY=1 at an early stage of the PCIEC initialization -- while
the driver only does this on R-Car H1 (polling a PHY specific register).
Add the PHYRDY polling to rcar_pcie_hw_init(). Note that without the
special PHY driver on the R-Car V3H (R8A77980) the PCIEC initialization
just freezes the kernel -- adding the PHYRDY polling allows the init code
to exit gracefully on timeout (PHY starts powered down after reset on this
SoC).

Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Reviewed-by: Rob Herring <robh@kernel.org>
Reviewed-by: Simon Horman <horms+renesas@verge.net.au>
drivers/pci/host/pcie-rcar.c

index e403c5206b2411942129cd678405f7db81b60265..fa084477a3cdc2ab38c6b2037028bc420d03bc58 100644 (file)
@@ -37,6 +37,8 @@
 #define PCIECDR                        0x000020
 #define PCIEMSR                        0x000028
 #define PCIEINTXR              0x000400
+#define PCIEPHYSR              0x0007f0
+#define  PHYRDY                        BIT(0)
 #define PCIEMSITXR             0x000840
 
 /* Transfer control */
@@ -527,6 +529,20 @@ static void phy_write_reg(struct rcar_pcie *pcie,
        phy_wait_for_ack(pcie);
 }
 
+static int rcar_pcie_wait_for_phyrdy(struct rcar_pcie *pcie)
+{
+       unsigned int timeout = 10;
+
+       while (timeout--) {
+               if (rcar_pci_read_reg(pcie, PCIEPHYSR) & PHYRDY)
+                       return 0;
+
+               msleep(5);
+       }
+
+       return -ETIMEDOUT;
+}
+
 static int rcar_pcie_wait_for_dl(struct rcar_pcie *pcie)
 {
        unsigned int timeout = 10;
@@ -551,6 +567,10 @@ static int rcar_pcie_hw_init(struct rcar_pcie *pcie)
        /* Set mode */
        rcar_pci_write_reg(pcie, 1, PCIEMSR);
 
+       err = rcar_pcie_wait_for_phyrdy(pcie);
+       if (err)
+               return err;
+
        /*
         * Initial header for port config space is type 1, set the device
         * class to match. Hardware takes care of propagating the IDSETR