[linux-yocto] [PATCH 35/42] AXM55xx RapidIO : Added support for Device revision and link down Monitor.

Cristian Bercaru cristian.bercaru at windriver.com
Thu Jun 11 01:32:20 PDT 2015


From: Palani <palaniappan.ramanathan at intel.com>

Added support for the 55xx RapidIO controller Revisions (v1.0 to v1.2):
Configuration of link and response timeout values, output log messages.
The Device revision is identified from the  RapidIO Device Information
Capability Register (dicar).

Implemented the Link Down Monitor handler. The link down monitor resets
the interface, the handler waits for the link to go up.

Signed-off-by: Palani <palaniappan.ramanathan at intel.com>
---
 drivers/rapidio/devices/lsi/axxia-rio-irq.c   |   49 ++++++++++++++++++++-----
 drivers/rapidio/devices/lsi/axxia-rio-sysfs.c |   18 +++++++++
 drivers/rapidio/devices/lsi/axxia-rio.c       |   28 ++++++++++++--
 drivers/rapidio/devices/lsi/axxia-rio.h       |    8 +++-
 4 files changed, 88 insertions(+), 15 deletions(-)

diff --git a/drivers/rapidio/devices/lsi/axxia-rio-irq.c b/drivers/rapidio/devices/lsi/axxia-rio-irq.c
index 97efaa8..5302651 100644
--- a/drivers/rapidio/devices/lsi/axxia-rio-irq.c
+++ b/drivers/rapidio/devices/lsi/axxia-rio-irq.c
@@ -34,6 +34,9 @@
 #include <linux/ktime.h>
 
 #include "axxia-rio.h"
+#define OB_DME_ENTRIES		(CONFIG_OB_DME_ENTRY_SIZE)
+#define LINK_DOWN_TIMEOUT	(0x4BF0)
+
 unsigned int axxia_dme_tmr_mode[2] = { AXXIA_IBDME_INTERRUPT_MODE,
 					AXXIA_IBDME_TIMER_MODE };
 static int axxia_timer_mode_setup(char *str)
@@ -618,15 +621,32 @@ static void misc_release_handler(struct rio_irq_handler *h)
  */
 static void linkdown_irq_handler(struct rio_irq_handler *h/*, u32 state*/)
 {
-#if 0
-	struct rio_mport *mport = h->mport;
+	struct rio_priv *priv = h->data;
+	struct rio_mport *mport = priv->mport;
+	u32 val;
+	u32 val1;
+	u32 rstate;
 
-	/**
-	 * Reset platform if port is broken
-	 */
-	if (state & RAB_SRDS_STAT1_LINKDOWN_INT)
-		srio_sw_reset(mport);
-#endif
+	__rio_local_read_config_32(mport, RAB_SRDS_STAT1, &rstate);
+	__rio_local_read_config_32(mport, RAB_SRDS_CTRL2, &val);
+	__rio_local_read_config_32(mport, RAB_SRDS_CTRL1, &val1);
+	pr_info("Link Down: RAB_SRDS STAT1 = %x CTRL1 = %x CTRL2 = %x\n",
+					rstate, val1, val);
+	while (1) {
+		axxia_local_config_read(priv, RIO_ESCSR(priv->port_ndx), &val);
+		if (val & 0x2) {
+			pr_info("Link up, Exiting Linkdown monitor Handler\n");
+			__rio_local_read_config_32(mport, RAB_SRDS_CTRL1, &val);
+			__rio_local_write_config_32(mport, RAB_SRDS_CTRL1,
+								(val | 0x2));
+			__rio_local_write_config_32(mport, RAB_SRDS_CTRL2,
+							LINK_DOWN_TIMEOUT);
+			break;
+		}
+	}
+	__rio_local_read_config_32(mport, RAB_SRDS_STAT1, &rstate);
+	__rio_local_read_config_32(mport, RAB_SRDS_CTRL2, &val);
+	__rio_local_read_config_32(mport, RAB_SRDS_CTRL1, &val1);
 }
 
 /**
@@ -1209,12 +1229,11 @@ static int alloc_ob_dme_shared(struct rio_priv *priv,
 	struct rio_msg_desc *desc = NULL;
 	u32 dw0, dw1, dw2, dw3;
 	u64  desc_chn_start = 0;
-	int entries = CONFIG_OB_DME_ENTRY_SIZE;
+	int entries = OB_DME_ENTRIES;
 	int i;
 
 	sz = RIO_OUTB_DME_TO_BUF_SIZE(priv, dme_no);
 	entries = roundup_pow_of_two(entries);
-	pr_info("Configuring DME %d with %d entries\n", dme_no, entries);
 	me = alloc_message_engine(mport,
 				dme_no, NULL, sz, entries);
 	if (IS_ERR(me)) {
@@ -1978,6 +1997,12 @@ int axxia_rio_port_irq_enable(struct rio_mport *mport)
 	if (rc)
 		goto out;
 
+	__rio_local_write_config_32(mport, RAB_SRDS_CTRL1, 0x0);
+	__rio_local_write_config_32(mport, RAB_SRDS_CTRL2,
+					/*LINK_DOWN_TIMEOUT*/0x0);
+	rc = alloc_irq_handler(&priv->linkdown_irq, priv, "rio-ld");
+	if (rc)
+		goto err1;
 	rc = alloc_irq_handler(&priv->apio_irq, priv, "rio-apio");
 	if (rc)
 		goto err2;
@@ -2011,6 +2036,8 @@ err4:
 err3:
 	release_irq_handler(&priv->apio_irq);
 err2:
+	release_irq_handler(&priv->linkdown_irq);
+err1:
 	release_irq_handler(&priv->misc_irq);
 	goto err0;
 }
@@ -2641,6 +2668,8 @@ void axxia_rio_port_irq_init(struct rio_mport *mport)
 		priv->ob_mbox[i] = NULL;
 
 /* Pre-Allocating the Outbound DME Descriptors*/
+	i = roundup_pow_of_two(OB_DME_ENTRIES);
+	pr_info("RIO: Configuring each outbound DME with %d entries\n", i);
 /* MultiSegment DME*/
 	for (i = 0; i < priv->num_outb_dmes[0]; i++)
 		alloc_ob_dme_shared(priv, &priv->ob_dme_shared[i], i);
diff --git a/drivers/rapidio/devices/lsi/axxia-rio-sysfs.c b/drivers/rapidio/devices/lsi/axxia-rio-sysfs.c
index a1c522d..0e53259 100644
--- a/drivers/rapidio/devices/lsi/axxia-rio-sysfs.c
+++ b/drivers/rapidio/devices/lsi/axxia-rio-sysfs.c
@@ -38,6 +38,24 @@ static ssize_t axxia_rio_stat_show(struct device *dev,
 	char *str = buf;
 	u32 reg_val = 0;
 
+	if (priv->devid  == AXXIA_DEVID_AXM55XX) {
+		str += sprintf(str, "AXM 55xx sRIO Controller");
+		switch (priv->devrev) {
+		case AXXIA_DEVREV_AXM55XX_V1_0:
+			str += sprintf(str, "Revision 0\n");
+			break;
+		case AXXIA_DEVREV_AXM55XX_V1_1:
+			str += sprintf(str, "Revision 1\n");
+			break;
+		case AXXIA_DEVREV_AXM55XX_V1_2:
+			str += sprintf(str, "Revision 2\n");
+			break;
+		default:
+			str += sprintf(str, "Revision Unknown\n");
+			break;
+		}
+	}
+
 	axxia_rio_port_get_state(mport, 0);
 	str += sprintf(str, "Master Port state:\n");
 	axxia_local_config_read(priv, RIO_ESCSR(priv->port_ndx), &reg_val);
diff --git a/drivers/rapidio/devices/lsi/axxia-rio.c b/drivers/rapidio/devices/lsi/axxia-rio.c
index 79de85b..7e39246 100644
--- a/drivers/rapidio/devices/lsi/axxia-rio.c
+++ b/drivers/rapidio/devices/lsi/axxia-rio.c
@@ -1525,8 +1525,18 @@ int axxia_rio_start_port(struct rio_mport *mport)
 	 * Set port line request ack timout 1.5 - 3 s
 	 * Set port response timeout 1.5 - 3 s
 	 */
-	__rio_local_write_config_32(mport, RIO_PLTOCCSR, 0x7fffff);
-	__rio_local_write_config_32(mport, RIO_PRTOCCSR, 0x7fffff);
+	if ((priv->devid == AXXIA_DEVID_AXM55XX) &&
+		(priv->devrev == AXXIA_DEVREV_AXM55XX_V1_0)) {
+		__rio_local_write_config_32(mport, RIO_PLTOCCSR,
+					((RIO_LINK_TIMEOUT_VAL * 100) << 8));
+		__rio_local_write_config_32(mport, RIO_PRTOCCSR,
+				((RIO_RESPONSE_TIMEOUT_VAL * 100) << 8));
+	} else {
+		__rio_local_write_config_32(mport, RIO_PLTOCCSR,
+					((RIO_LINK_TIMEOUT_VAL) << 8));
+		__rio_local_write_config_32(mport, RIO_PRTOCCSR,
+					((RIO_RESPONSE_TIMEOUT_VAL) << 8));
+	}
 
 	/* Check port training state:
 	 */
@@ -1700,9 +1710,21 @@ static int axxia_rio_setup(struct platform_device *dev)
 		priv->outb_dmes[1] = 0x00000000;
 		break;
 	case AXXIA_DEVID_AXM55XX:
+		priv->outb_dmes[1] = 0x00000000;
 		switch (priv->devrev) {
 		case AXXIA_DEVREV_AXM55XX_V1_0:
-			priv->outb_dmes[1] = 0x00000000;
+			pr_info(
+			"RIO: AXM 55xx sRIO Dev Rev 0 (Base DID Lock issue)\n");
+			break;
+		case AXXIA_DEVREV_AXM55XX_V1_1:
+			pr_info(
+			"RIO: AXM 55xx sRIO Device Rev 1 Controller %d\n",
+								priv->ndx);
+			break;
+		case AXXIA_DEVREV_AXM55XX_V1_2:
+			pr_info(
+			"RIO: AXM 55xx sRIO Device Rev 2 Controller %d\n",
+								priv->ndx);
 			break;
 		default:
 			break;
diff --git a/drivers/rapidio/devices/lsi/axxia-rio.h b/drivers/rapidio/devices/lsi/axxia-rio.h
index 479be4b..ad8f27e 100644
--- a/drivers/rapidio/devices/lsi/axxia-rio.h
+++ b/drivers/rapidio/devices/lsi/axxia-rio.h
@@ -59,9 +59,10 @@
 #define AXXIA_DEVID_ACP34XX		0x5101000a
 #define AXXIA_DEVID_ACP25XX		0x5108000a
 #define AXXIA_DEVID_AXM55XX		0x5120000a
-#define   AXXIA_DEVREV_AXM55XX_V1_0	  0x00000000
-#define   AXXIA_DEVREV_AXM55XX_V1_1	  0x00000001
 #define AXXIA_DEVID_AXM35XX		0x5102000a
+#define   AXXIA_DEVREV_AXM55XX_V1_0	  0x00000000
+#define   AXXIA_DEVREV_AXM55XX_V1_1	  0x80000000
+#define   AXXIA_DEVREV_AXM55XX_V1_2	  0x40000000
 
 /* End Point Controller Specific Registers (0x1_0000-0x1_FFFC) */
 #define EPC_REG_BASE            0x10000
@@ -410,6 +411,9 @@
 #define RIO_PRTOCCSR            0x124
 #define RIO_GCCSR		0x13c
 
+#define RIO_LINK_TIMEOUT_VAL		(0x40)
+#define RIO_RESPONSE_TIMEOUT_VAL	(0xfa0)
+
 #define RIO_MNT_REQ_CSR(x)      (0x140+((x)*0x20))
 #define  RIO_MNT_REQ_MASK       0x00000007
 #define  RIO_MNT_REQ_RST        0x00000003
-- 
1.7.9.5



More information about the linux-yocto mailing list