[RAPIDIO] Add RapidIO connection info print out and re-training for broken connections
authorZhang Wei <wei.zhang@freescale.com>
Fri, 18 Apr 2008 20:33:44 +0000 (13:33 -0700)
committerPaul Mackerras <paulus@samba.org>
Tue, 29 Apr 2008 09:40:29 +0000 (19:40 +1000)
Signed-off-by: Zhang Wei <wei.zhang@freescale.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Paul Mackerras <paulus@samba.org>
arch/powerpc/sysdev/fsl_rio.c

index 935822a..dca8eea 100644 (file)
@@ -942,6 +942,48 @@ static int fsl_rio_get_cmdline(char *s)
 
 __setup("riohdid=", fsl_rio_get_cmdline);
 
+static inline void fsl_rio_info(struct device *dev, u32 ccsr)
+{
+       const char *str;
+       if (ccsr & 1) {
+               /* Serial phy */
+               switch (ccsr >> 30) {
+               case 0:
+                       str = "1";
+                       break;
+               case 1:
+                       str = "4";
+                       break;
+               default:
+                       str = "Unknown";
+                       break;;
+               }
+               dev_info(dev, "Hardware port width: %s\n", str);
+
+               switch ((ccsr >> 27) & 7) {
+               case 0:
+                       str = "Single-lane 0";
+                       break;
+               case 1:
+                       str = "Single-lane 2";
+                       break;
+               case 2:
+                       str = "Four-lane";
+                       break;
+               default:
+                       str = "Unknown";
+                       break;
+               }
+               dev_info(dev, "Training connection status: %s\n", str);
+       } else {
+               /* Parallel phy */
+               if (!(ccsr & 0x80000000))
+                       dev_info(dev, "Output port operating in 8-bit mode\n");
+               if (!(ccsr & 0x08000000))
+                       dev_info(dev, "Input port operating in 8-bit mode\n");
+       }
+}
+
 /**
  * fsl_rio_setup - Setup MPC85xx RapidIO interface
  * @fsl_rio_setup - Setup Freescale PowerPC RapidIO interface
@@ -1055,6 +1097,35 @@ int fsl_rio_setup(struct of_device *dev)
                        (port->phy_type == RIO_PHY_PARALLEL) ? "parallel" :
                        ((port->phy_type == RIO_PHY_SERIAL) ? "serial" :
                         "unknown"));
+       /* Checking the port training status */
+       if (in_be32((priv->regs_win + RIO_ESCSR)) & 1) {
+               dev_err(&dev->dev, "Port is not ready. "
+                                  "Try to restart connection...\n");
+               switch (port->phy_type) {
+               case RIO_PHY_SERIAL:
+                       /* Disable ports */
+                       out_be32(priv->regs_win + RIO_CCSR, 0);
+                       /* Set 1x lane */
+                       setbits32(priv->regs_win + RIO_CCSR, 0x02000000);
+                       /* Enable ports */
+                       setbits32(priv->regs_win + RIO_CCSR, 0x00600000);
+                       break;
+               case RIO_PHY_PARALLEL:
+                       /* Disable ports */
+                       out_be32(priv->regs_win + RIO_CCSR, 0x22000000);
+                       /* Enable ports */
+                       out_be32(priv->regs_win + RIO_CCSR, 0x44000000);
+                       break;
+               }
+               msleep(100);
+               if (in_be32((priv->regs_win + RIO_ESCSR)) & 1) {
+                       dev_err(&dev->dev, "Port restart failed.\n");
+                       rc = -ENOLINK;
+                       goto err;
+               }
+               dev_info(&dev->dev, "Port restart success!\n");
+       }
+       fsl_rio_info(&dev->dev, ccsr);
 
        port->sys_size = (in_be32((priv->regs_win + RIO_PEF_CAR))
                                        & RIO_PEF_CTLS) >> 4;