diff options
Diffstat (limited to 'arch/powerpc/sysdev/fsl_rio.c')
| -rw-r--r-- | arch/powerpc/sysdev/fsl_rio.c | 71 | 
1 files changed, 71 insertions, 0 deletions
diff --git a/arch/powerpc/sysdev/fsl_rio.c b/arch/powerpc/sysdev/fsl_rio.c index 935822a2503..dca8eead396 100644 --- a/arch/powerpc/sysdev/fsl_rio.c +++ b/arch/powerpc/sysdev/fsl_rio.c @@ -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;  |