[U-Boot] [PATCH 4/4] rapidio: add driver for TI KeyStone RapidIO

jacquiot.aurelien at gmail.com jacquiot.aurelien at gmail.com
Tue Nov 10 13:13:53 CET 2015


From: Aurelien Jacquiot <a-jacquiot at ti.com>

This commit includes the KeyStone device driver for RapidIO
allowing to use the RapidIO boot functionality.

Today only K2HK devices have RapidIO support.

Signed-off-by: Aurelien Jacquiot <a-jacquiot at ti.com>
---
 Makefile                       |    1 +
 configs/k2hk_evm_defconfig     |    2 +
 drivers/Kconfig                |    2 +
 drivers/rapidio/Kconfig        |    5 +
 drivers/rapidio/Makefile       |    8 +
 drivers/rapidio/keystone_rio.c | 1374 ++++++++++++++++++++++++++++++++++++++++
 drivers/rapidio/keystone_rio.h |  650 +++++++++++++++++++
 7 files changed, 2042 insertions(+), 0 deletions(-)
 create mode 100644 drivers/rapidio/Kconfig
 create mode 100644 drivers/rapidio/Makefile
 create mode 100644 drivers/rapidio/keystone_rio.c
 create mode 100644 drivers/rapidio/keystone_rio.h

diff --git a/Makefile b/Makefile
index 3c21f8d..67e6b25 100644
--- a/Makefile
+++ b/Makefile
@@ -661,6 +661,7 @@ libs-y += drivers/usb/musb/
 libs-y += drivers/usb/musb-new/
 libs-y += drivers/usb/phy/
 libs-y += drivers/usb/ulpi/
+libs-y += drivers/rapidio/
 libs-y += common/
 libs-$(CONFIG_API) += api/
 libs-$(CONFIG_HAS_POST) += post/
diff --git a/configs/k2hk_evm_defconfig b/configs/k2hk_evm_defconfig
index d5a4ef2..e350ea4 100644
--- a/configs/k2hk_evm_defconfig
+++ b/configs/k2hk_evm_defconfig
@@ -11,3 +11,5 @@ CONFIG_SYS_PROMPT="K2HK EVM # "
 CONFIG_OF_CONTROL=y
 CONFIG_DM=y
 CONFIG_SPI_FLASH=y
+CONFIG_CMD_RIO=y
+CONFIG_KEYSTONE_RIO=y
diff --git a/drivers/Kconfig b/drivers/Kconfig
index c481e93..37a37a6 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -70,6 +70,8 @@ source "drivers/video/Kconfig"
 
 source "drivers/watchdog/Kconfig"
 
+source "drivers/rapidio/Kconfig"
+
 config PHYS_TO_BUS
 	bool "Custom physical to bus address mapping"
 	help
diff --git a/drivers/rapidio/Kconfig b/drivers/rapidio/Kconfig
new file mode 100644
index 0000000..2560957
--- /dev/null
+++ b/drivers/rapidio/Kconfig
@@ -0,0 +1,5 @@
+config KEYSTONE_RIO
+	bool "Support for TI KeyStone RapidIO"
+	depends on TARGET_K2HK_EVM
+        ---help---
+	  Say Y here if you want to use RapidIO to boot your board.
diff --git a/drivers/rapidio/Makefile b/drivers/rapidio/Makefile
new file mode 100644
index 0000000..bd7ec50
--- /dev/null
+++ b/drivers/rapidio/Makefile
@@ -0,0 +1,8 @@
+#
+# (C) Copyright 2015
+# Texas Instruments Incorporated, <www.ti.com>
+#
+# SPDX-License-Identifier:	GPL-2.0+
+#
+
+obj-$(CONFIG_KEYSTONE_RIO) += keystone_rio.o
diff --git a/drivers/rapidio/keystone_rio.c b/drivers/rapidio/keystone_rio.c
new file mode 100644
index 0000000..9fe93c3
--- /dev/null
+++ b/drivers/rapidio/keystone_rio.c
@@ -0,0 +1,1374 @@
+/*
+ * (C) Copyright 2015
+ * Texas Instruments Incorporated, <www.ti.com>
+ * Authors: Aurelien Jacquiot <a-jacquiot at ti.com>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#include <common.h>
+#include <command.h>
+#include <malloc.h>
+#include <asm/dma-mapping.h>
+#include <asm/io.h>
+#include <asm/arch/psc_defs.h>
+#include <rio.h>
+
+#include "keystone_rio.h"
+
+#define DRIVER_VER	    "v1.1"
+
+#ifdef CONFIG_SOC_K2HK
+#define KEYSTONE_RIO_IS_K2 1
+#else
+#define KEYSTONE_RIO_IS_K2 0
+#endif
+
+#define K2_SERDES(p)        ((p)->board_rio_cfg.keystone2_serdes)
+
+static unsigned int rio_dbg;
+
+#define debug_rio(fmt, args...)	if (rio_dbg) printf(fmt, ##args)
+
+/*
+ * Main KeyStone RapidIO driver data
+ */
+struct keystone_rio_data {
+	int			riohdid;
+	u32			rio_pe_feat;
+
+	u32			ports_registering;
+	u32			port_chk_cnt;
+
+	u32		       *jtagid_reg;
+	u32		       *serdes_sts_reg;
+	struct keystone_srio_serdes_regs     *serdes_regs;
+	struct keystone_rio_regs	     *regs;
+
+	struct keystone_rio_car_csr_regs     *car_csr_regs;
+	struct keystone_rio_serial_port_regs *serial_port_regs;
+	struct keystone_rio_err_mgmt_regs    *err_mgmt_regs;
+	struct keystone_rio_phy_layer_regs   *phy_regs;
+	struct keystone_rio_transport_layer_regs *transport_regs;
+	struct keystone_rio_pkt_buf_regs     *pkt_buf_regs;
+	struct keystone_rio_evt_mgmt_regs    *evt_mgmt_regs;
+	struct keystone_rio_port_write_regs  *port_write_regs;
+	struct keystone_rio_link_layer_regs  *link_regs;
+	struct keystone_rio_fabric_regs      *fabric_regs;
+	u32				      car_csr_regs_base;
+
+	struct keystone_rio_board_controller_info board_rio_cfg;
+} __krio_priv;
+
+/*--------------------- Maintenance Request Management  ---------------------*/
+
+static u32 keystone_rio_dio_get_lsu_cc(u32 lsu_id, u8 ltid, u8 *lcb,
+				       struct keystone_rio_data *krio_priv)
+{
+	u32 idx;
+	u32 shift;
+	u32 value;
+	u32 cc;
+	/* lSU shadow register status mapping */
+	u32 lsu_index[8] = { 0, 9, 15, 20, 24, 33, 39, 44 };
+
+	/* Compute LSU stat index from LSU id and LTID */
+	idx   = (lsu_index[lsu_id] + ltid) >> 3;
+	shift = ((lsu_index[lsu_id] + ltid) & 0x7) << 2;
+
+	/* Get completion code and context */
+	value  = readl(&(krio_priv->regs->lsu_stat_reg[idx]));
+	cc     = (value >> (shift + 1)) & 0x7;
+	*lcb   = (value >> shift) & 0x1;
+
+	return cc;
+}
+
+/**
+ * maint_request - Perform a maintenance request
+ * @port_id: output port ID of transaction
+ * @dest_id: destination ID of target device
+ * @hopcount: hopcount for this request
+ * @offset: offset in the RapidIO configuration space
+ * @buff: dma address of the data on the host
+ * @buff_len: length of the data
+ * @size: 1 for 16bit, 0 for 8bit ID size
+ * @type: packet type
+ *
+ * Returns %0 on success or %-1 on failure.
+ */
+static inline int keystone_rio_maint_request(
+	int port_id,
+	u32 dest_id,
+	u8  hopcount,
+	u32 offset,
+	dma_addr_t buff,
+	int buff_len,
+	u16 size,
+	u16 type,
+	struct keystone_rio_data *krio_priv)
+{
+	unsigned int count;
+	unsigned int status = 0;
+	unsigned int res    = 0;
+	u8           context;
+	u8           ltid;
+
+	/* Check is there is space in the LSU shadow reg and that it is free */
+	count = 0;
+	while (1) {
+		status = readl(&(krio_priv->regs->lsu_reg[0].busy_full));
+		if (((status & KEYSTONE_RIO_LSU_FULL_MASK) == 0x0) &&
+		    ((status & KEYSTONE_RIO_LSU_BUSY_MASK) == 0x0))
+			break;
+		count++;
+
+		if (count >= KEYSTONE_RIO_TIMEOUT_CNT) {
+			debug_rio("RIO: no LSU available, status = 0x%x\n",
+				  status);
+			res = -1;
+			goto out;
+		}
+		udelay(1);
+	}
+
+	/* Get LCB and LTID, LSU reg 6 is already read */
+	context = (status >> 4) & 0x1;
+	ltid    = status & 0xf;
+
+	/* LSU Reg 0 - MSB of RapidIO address */
+	writel(0, &(krio_priv->regs->lsu_reg[0].addr_msb));
+
+	/* LSU Reg 1 - LSB of destination */
+	writel(offset, &(krio_priv->regs->lsu_reg[0].addr_lsb_cfg_ofs));
+
+	/* LSU Reg 2 - source address */
+	writel(buff, &(krio_priv->regs->lsu_reg[0].dsp_addr));
+
+	/* LSU Reg 3 - byte count */
+	writel(buff_len,
+	       &(krio_priv->regs->lsu_reg[0].dbell_val_byte_cnt));
+
+	/* LSU Reg 4 - */
+	writel(((port_id << 8)
+		| (KEYSTONE_RIO_LSU_PRIO << 4)
+		| (size ? (1 << 10) : 0)
+		| ((u32) dest_id << 16)),
+	       &(krio_priv->regs->lsu_reg[0].destid));
+
+	/* LSU Reg 5 */
+	writel(((hopcount & 0xff) << 8) | (type & 0xff),
+	       &(krio_priv->regs->lsu_reg[0].dbell_info_fttype));
+
+	/* Retrieve our completion code */
+	count = 0;
+	res   = 0;
+	while (1) {
+		u8 lcb;
+
+		status = keystone_rio_dio_get_lsu_cc(0, ltid, &lcb, krio_priv);
+		if (lcb == context)
+			break;
+		count++;
+		if (count >= KEYSTONE_RIO_TIMEOUT_CNT) {
+			debug_rio(
+				"RIO: timeout %d, ltid = %d, context = %d, lcb = %d, cc = %d\n",
+				count, ltid, context, lcb, status);
+			res = -2;
+			break;
+		}
+		udelay(1);
+	}
+out:
+	if (res)
+		return res;
+
+	if (status)
+		debug_rio("RIO: transfer error = 0x%x\n", status);
+
+	switch (status) {
+	case KEYSTONE_RIO_LSU_CC_TIMEOUT:
+	case KEYSTONE_RIO_LSU_CC_XOFF:
+	case KEYSTONE_RIO_LSU_CC_ERROR:
+	case KEYSTONE_RIO_LSU_CC_INVALID:
+	case KEYSTONE_RIO_LSU_CC_DMA:
+		return -3;
+		break;
+	case KEYSTONE_RIO_LSU_CC_RETRY:
+		return -4;
+		break;
+	case KEYSTONE_RIO_LSU_CC_CANCELED:
+		return -5;
+		break;
+	default:
+		break;
+	}
+
+	return 0;
+}
+
+/**
+ * rio_config_read - Generate a RIO read maintenance transaction
+ * @portid: Output port ID of transaction
+ * @destid: Destination ID of transaction
+ * @hopcount: Number of hops to target device
+ * @offset: Offset into configuration space
+ * @len: Length (in bytes) of the maintenance transaction
+ * @val: Location to be read into
+ *
+ * Returns %0 on success or %-1 on failure.
+ */
+int rio_config_read(int  portid,
+		    u16  destid,
+		    u8   hopcount,
+		    u32  offset,
+		    int  len,
+		    u32 *val)
+{
+	struct keystone_rio_data *krio_priv = &__krio_priv;
+	u32 *tbuf;
+	int res;
+	dma_addr_t dma;
+
+	tbuf = malloc(len);
+	if (!tbuf)
+		return -1;
+
+	memset(tbuf, 0, len);
+
+	dma = dma_map_single(tbuf, len, DMA_FROM_DEVICE);
+
+	res = keystone_rio_maint_request(portid, destid, hopcount, offset, dma,
+					 len, krio_priv->board_rio_cfg.size,
+					 KEYSTONE_RIO_PACKET_TYPE_MAINT_R,
+					 krio_priv);
+
+	dma_unmap_single((void *)tbuf, len, dma);
+
+	/* Taking care of byteswap */
+	switch (len) {
+	case 1:
+		*val = *((u8 *)tbuf);
+		break;
+	case 2:
+		*val = ntohs(*((u16 *)tbuf));
+		break;
+	default:
+		*val = ntohl(*((u32 *)tbuf));
+		break;
+	}
+
+	free(tbuf);
+
+	debug_rio(
+		"RIO: %s portid %d destid %d hopcount %d offset 0x%x len %d val 0x%x res %d\n",
+		__func__, portid, destid, hopcount, offset, len, *val,
+		res);
+
+	return res;
+}
+
+/**
+ * rio_config_write - Generate a RIO write maintenance transaction
+ * @portid: Output port ID of transaction
+ * @destid: Destination ID of transaction
+ * @hopcount: Number of hops to target device
+ * @offset: Offset into configuration space
+ * @len: Length (in bytes) of the maintenance transaction
+ * @val: Value to be written
+ *
+ * Returns %0 on success or %-1 on failure.
+ */
+int rio_config_write(int portid,
+		     u16 destid,
+		     u8  hopcount,
+		     u32 offset,
+		     int len,
+		     u32 val)
+{
+	struct keystone_rio_data *krio_priv = &__krio_priv;
+	u32 *tbuf;
+	int res;
+	dma_addr_t dma;
+
+	tbuf = malloc(len);
+	if (!tbuf)
+		return -1;
+
+	memset(tbuf, 0, len);
+
+	/* Taking care of byteswap */
+	switch (len) {
+	case 1:
+		*tbuf = ((u8) val);
+		break;
+	case 2:
+		*tbuf = htons((u16) val);
+		break;
+	default:
+		*tbuf = htonl((u32) val);
+		break;
+	}
+
+	dma = dma_map_single(tbuf, len, DMA_TO_DEVICE);
+
+	res = keystone_rio_maint_request(portid, destid, hopcount, offset, dma,
+					 len, krio_priv->board_rio_cfg.size,
+					 KEYSTONE_RIO_PACKET_TYPE_MAINT_W,
+					 krio_priv);
+
+	dma_unmap_single((void *)tbuf, len, dma);
+
+	debug_rio(
+		"RIO: %s portid %d destid %d hopcount %d offset 0x%x len %d val 0x%x res %d\n",
+		__func__, portid, destid, hopcount, offset, len, val,
+		res);
+
+	free(tbuf);
+
+	return res;
+}
+
+/**
+ * rio_local_config_read - RIO local config space read
+ * @offset: Offset into configuration space
+ * @len: Length (in bytes) of the maintenance transaction
+ * @data: Value to be read into
+ *
+ * Returns %0 on success or %-1 on failure.
+ */
+int rio_local_config_read(u32 offset, int len, u32 *data)
+{
+	struct keystone_rio_data *krio_priv = &__krio_priv;
+
+	*data = readl((void *)(krio_priv->car_csr_regs_base + offset));
+
+	debug_rio("RIO: %s offset 0x%x data 0x%x\n",
+		  __func__, offset, *data);
+
+	return 0;
+}
+
+/**
+ * rio_local_config_write - RIO local config space write
+ * @offset: Offset into configuration space
+ * @len: Length (in bytes) of the maintenance transaction
+ * @data: Value to be written
+ *
+ * Returns %0 on success or %-1 on failure.
+ */
+int rio_local_config_write(u32 offset, int len, u32 data)
+{
+	struct keystone_rio_data *krio_priv = &__krio_priv;
+
+	debug_rio("RIO: %s offset 0x%x data 0x%x\n",
+		  __func__, offset, data);
+
+	writel(data, (void *)(krio_priv->car_csr_regs_base + offset));
+
+	return 0;
+}
+
+/*------------------------- RapidIO hw controller setup ---------------------*/
+
+struct keystone_lane_config {
+	int start; /* lane start number of the port */
+	int end;   /* lane end number of the port */
+};
+
+/*
+ * Table with the various lanes per port configuration modes:
+ * path mode 0: 4 ports in 1x
+ * path mode 1: 3 ports in 2x/1x
+ * path mode 2: 3 ports in 1x/2x
+ * path mode 3: 2 ports in 2x
+ * path mode 4: 1 ports in 4x
+ */
+static struct keystone_lane_config keystone_lane_configs[5][4] = {
+	{ {0, 1}, {1, 2},   {2, 3},   {3, 4}   },
+	{ {0, 2}, {-1, -1}, {2, 3},   {3, 4}   },
+	{ {0, 1}, {1, 2},   {2, 4},   {-1, -1} },
+	{ {0, 2}, {-1, -1}, {2, 4},   {-1, -1} },
+	{ {0, 4}, {-1, -1}, {-1, -1}, {-1, -1} },
+};
+
+/* Retrieve the corresponding lanes bitmask from ports bitmask and path_mode */
+static int keystone_rio_get_lane_config(u32 ports, u32 path_mode)
+{
+	u32 lanes = 0;
+
+	while (ports) {
+		u32 lane;
+		u32 port = ffs(ports) - 1;
+		ports &= ~(1 << port);
+
+		if (keystone_lane_configs[path_mode][port].start == -1)
+			return -1;
+
+		for (lane = keystone_lane_configs[path_mode][port].start;
+		     lane < keystone_lane_configs[path_mode][port].end;
+		     lane++) {
+			lanes |= (1 << lane);
+		}
+	}
+	return (int) lanes;
+}
+
+#define reg_fmkr(msb, lsb, val)					\
+	(((val) & ((1 << ((msb) - (lsb) + 1)) - 1)) << (lsb))
+
+#define reg_finsr(addr, msb, lsb, val)					\
+	writel(((readl(addr)						\
+		 & ~(((1 << ((msb) - (lsb) + 1)) - 1) << (lsb)))	\
+		| reg_fmkr(msb, lsb, val)), (addr))
+
+static void k2_rio_serdes_init_3g(u32 lanes,
+				  struct keystone_rio_data *krio_priv)
+{
+	void __iomem *reg = (void __iomem *)krio_priv->serdes_regs;
+
+	/* Uses 6G half rate configuration */
+	reg_finsr((reg + 0x0000), 31, 24, 0x00);
+	reg_finsr((reg + 0x0014),  7,  0, 0x82);
+	reg_finsr((reg + 0x0014), 15,  8, 0x82);
+	reg_finsr((reg + 0x0060),  7,  0, 0x48);
+	reg_finsr((reg + 0x0060), 15,  8, 0x2c);
+	reg_finsr((reg + 0x0060), 23, 16, 0x13);
+	reg_finsr((reg + 0x0064), 15,  8, 0xc7);
+	reg_finsr((reg + 0x0064), 23, 16, 0xc3);
+	reg_finsr((reg + 0x0078), 15,  8, 0xc0);
+
+	/*  Setting lane 0 SerDes to 3GHz */
+	reg_finsr((reg + 0x0204),  7,  0, 0x80);
+	reg_finsr((reg + 0x0204), 31, 24, 0x78);
+	reg_finsr((reg + 0x0208),  7,  0, 0x24);
+	reg_finsr((reg + 0x020c), 31, 24, 0x02);
+	reg_finsr((reg + 0x0210), 31, 24, 0x1b);
+	reg_finsr((reg + 0x0214),  7,  0, 0x7c);
+	reg_finsr((reg + 0x0214), 15,  8, 0x6e);
+	reg_finsr((reg + 0x0218),  7,  0, 0xe4);
+	reg_finsr((reg + 0x0218), 23, 16, 0x80);
+	reg_finsr((reg + 0x0218), 31, 24, 0x75);
+	reg_finsr((reg + 0x022c), 15,  8, 0x08);
+	reg_finsr((reg + 0x022c), 23, 16, 0x20);
+	reg_finsr((reg + 0x0280),  7,  0, 0x70);
+	reg_finsr((reg + 0x0280), 23, 16, 0x70);
+	reg_finsr((reg + 0x0284),  7,  0, 0x85);
+	reg_finsr((reg + 0x0284), 23, 16, 0x0f);
+	reg_finsr((reg + 0x0284), 31, 24, 0x1d);
+	reg_finsr((reg + 0x028c), 15,  8, 0x3b);
+
+	/*  Setting lane 1 SerDes to 3GHz */
+	reg_finsr((reg + 0x0404),  7,  0, 0x80);
+	reg_finsr((reg + 0x0404), 31, 24, 0x78);
+	reg_finsr((reg + 0x0408),  7,  0, 0x24);
+	reg_finsr((reg + 0x040c), 31, 24, 0x02);
+	reg_finsr((reg + 0x0410), 31, 24, 0x1b);
+	reg_finsr((reg + 0x0414),  7,  0, 0x7c);
+	reg_finsr((reg + 0x0414), 15,  8, 0x6e);
+	reg_finsr((reg + 0x0418),  7,  0, 0xe4);
+	reg_finsr((reg + 0x0418), 23, 16, 0x80);
+	reg_finsr((reg + 0x0418), 31, 24, 0x75);
+	reg_finsr((reg + 0x042c), 15,  8, 0x08);
+	reg_finsr((reg + 0x042c), 23, 16, 0x20);
+	reg_finsr((reg + 0x0480),  7,  0, 0x70);
+	reg_finsr((reg + 0x0480), 23, 16, 0x70);
+	reg_finsr((reg + 0x0484),  7,  0, 0x85);
+	reg_finsr((reg + 0x0484), 23, 16, 0x0f);
+	reg_finsr((reg + 0x0484), 31, 24, 0x1d);
+	reg_finsr((reg + 0x048c), 15,  8, 0x3b);
+
+	/*  Setting lane 2 SerDes to 3GHz */
+	reg_finsr((reg + 0x0604),  7,  0, 0x80);
+	reg_finsr((reg + 0x0604), 31, 24, 0x78);
+	reg_finsr((reg + 0x0608),  7,  0, 0x24);
+	reg_finsr((reg + 0x060c), 31, 24, 0x02);
+	reg_finsr((reg + 0x0610), 31, 24, 0x1b);
+	reg_finsr((reg + 0x0614),  7,  0, 0x7c);
+	reg_finsr((reg + 0x0614), 15,  8, 0x6e);
+	reg_finsr((reg + 0x0618),  7,  0, 0xe4);
+	reg_finsr((reg + 0x0618), 23, 16, 0x80);
+	reg_finsr((reg + 0x0618), 31, 24, 0x75);
+	reg_finsr((reg + 0x062c), 15,  8, 0x08);
+	reg_finsr((reg + 0x062c), 23, 16, 0x20);
+	reg_finsr((reg + 0x0680),  7,  0, 0x70);
+	reg_finsr((reg + 0x0680), 23, 16, 0x70);
+	reg_finsr((reg + 0x0684),  7,  0, 0x85);
+	reg_finsr((reg + 0x0684), 23, 16, 0x0f);
+	reg_finsr((reg + 0x0684), 31, 24, 0x1d);
+	reg_finsr((reg + 0x068c), 15,  8, 0x3b);
+
+	/*  Setting lane 3 SerDes to 3GHz */
+	reg_finsr((reg + 0x0804),  7,  0, 0x80);
+	reg_finsr((reg + 0x0804), 31, 24, 0x78);
+	reg_finsr((reg + 0x0808),  7,  0, 0x24);
+	reg_finsr((reg + 0x080c), 31, 24, 0x02);
+	reg_finsr((reg + 0x0810), 31, 24, 0x1b);
+	reg_finsr((reg + 0x0814),  7,  0, 0x7c);
+	reg_finsr((reg + 0x0814), 15,  8, 0x6e);
+	reg_finsr((reg + 0x0818),  7,  0, 0xe4);
+	reg_finsr((reg + 0x0818), 23, 16, 0x80);
+	reg_finsr((reg + 0x0818), 31, 24, 0x75);
+	reg_finsr((reg + 0x082c), 15,  8, 0x08);
+	reg_finsr((reg + 0x082c), 23, 16, 0x20);
+	reg_finsr((reg + 0x0880),  7,  0, 0x70);
+	reg_finsr((reg + 0x0880), 23, 16, 0x70);
+	reg_finsr((reg + 0x0884),  7,  0, 0x85);
+	reg_finsr((reg + 0x0884), 23, 16, 0x0f);
+	reg_finsr((reg + 0x0884), 31, 24, 0x1d);
+	reg_finsr((reg + 0x088c), 15,  8, 0x3b);
+
+	reg_finsr((reg + 0x0a00), 15,  8, 0x08);
+	reg_finsr((reg + 0x0a08), 23, 16, 0x72);
+	reg_finsr((reg + 0x0a08), 31, 24, 0x37);
+	reg_finsr((reg + 0x0a30), 15,  8, 0x77);
+	reg_finsr((reg + 0x0a30), 23, 16, 0x77);
+	reg_finsr((reg + 0x0a84), 15,  8, 0x06);
+	reg_finsr((reg + 0x0a94), 31, 24, 0x10);
+	reg_finsr((reg + 0x0aa0), 31, 24, 0x81);
+	reg_finsr((reg + 0x0abc), 31, 24, 0xff);
+	reg_finsr((reg + 0x0ac0),  7,  0, 0x8b);
+	reg_finsr((reg + 0x0a48), 15,  8, 0x8c);
+	reg_finsr((reg + 0x0a48), 23, 16, 0xfd);
+	reg_finsr((reg + 0x0a54),  7,  0, 0x72);
+	reg_finsr((reg + 0x0a54), 15,  8, 0xec);
+	reg_finsr((reg + 0x0a54), 23, 16, 0x2f);
+	reg_finsr((reg + 0x0a58), 15,  8, 0x21);
+	reg_finsr((reg + 0x0a58), 23, 16, 0xf9);
+	reg_finsr((reg + 0x0a58), 31, 24, 0x00);
+	reg_finsr((reg + 0x0a5c),  7,  0, 0x60);
+	reg_finsr((reg + 0x0a5c), 15,  8, 0x00);
+	reg_finsr((reg + 0x0a5c), 23, 16, 0x04);
+	reg_finsr((reg + 0x0a5c), 31, 24, 0x00);
+	reg_finsr((reg + 0x0a60),  7,  0, 0x00);
+	reg_finsr((reg + 0x0a60), 15,  8, 0x80);
+	reg_finsr((reg + 0x0a60), 23, 16, 0x00);
+	reg_finsr((reg + 0x0a60), 31, 24, 0x00);
+	reg_finsr((reg + 0x0a64),  7,  0, 0x20);
+	reg_finsr((reg + 0x0a64), 15,  8, 0x12);
+	reg_finsr((reg + 0x0a64), 23, 16, 0x58);
+	reg_finsr((reg + 0x0a64), 31, 24, 0x0c);
+	reg_finsr((reg + 0x0a68),  7,  0, 0x02);
+	reg_finsr((reg + 0x0a68), 15,  8, 0x06);
+	reg_finsr((reg + 0x0a68), 23, 16, 0x3b);
+	reg_finsr((reg + 0x0a68), 31, 24, 0xe1);
+	reg_finsr((reg + 0x0a6c),  7,  0, 0xc1);
+	reg_finsr((reg + 0x0a6c), 15,  8, 0x4c);
+	reg_finsr((reg + 0x0a6c), 23, 16, 0x07);
+	reg_finsr((reg + 0x0a6c), 31, 24, 0xb8);
+	reg_finsr((reg + 0x0a70),  7,  0, 0x89);
+	reg_finsr((reg + 0x0a70), 15,  8, 0xe9);
+	reg_finsr((reg + 0x0a70), 23, 16, 0x02);
+	reg_finsr((reg + 0x0a70), 31, 24, 0x3f);
+	reg_finsr((reg + 0x0a74),  7,  0, 0x01);
+	reg_finsr((reg + 0x0b20), 23, 16, 0x37);
+	reg_finsr((reg + 0x0b1c), 31, 24, 0x37);
+	reg_finsr((reg + 0x0b20),  7,  0, 0x5d);
+	reg_finsr((reg + 0x0000),  7,  0, 0x03);
+	reg_finsr((reg + 0x0a00),  7,  0, 0x5f);
+}
+
+static void k2_rio_serdes_init_5g(u32 lanes,
+				  struct keystone_rio_data *krio_priv)
+{
+	void __iomem *reg = (void __iomem *)krio_priv->serdes_regs;
+
+	/* Uses 5Gbps full rate configuration by default */
+	reg_finsr((reg + 0x0000), 31, 24, 0x00);
+	reg_finsr((reg + 0x0014),  7,  0, 0x82);
+	reg_finsr((reg + 0x0014), 15,  8, 0x82);
+	reg_finsr((reg + 0x0060),  7,  0, 0x38);
+	reg_finsr((reg + 0x0060), 15,  8, 0x24);
+	reg_finsr((reg + 0x0060), 23, 16, 0x14);
+	reg_finsr((reg + 0x0064), 15,  8, 0xc7);
+	reg_finsr((reg + 0x0064), 23, 16, 0xc3);
+	reg_finsr((reg + 0x0078), 15,  8, 0xc0);
+
+	/*  Setting lane 0 SerDes to 5GHz */
+	reg_finsr((reg + 0x0204),  7,  0, 0x80);
+	reg_finsr((reg + 0x0204), 31, 24, 0x78);
+	reg_finsr((reg + 0x0208),  7,  0, 0x26);
+	reg_finsr((reg + 0x020c), 31, 24, 0x02);
+	reg_finsr((reg + 0x0214),  7,  0, 0x38);
+	reg_finsr((reg + 0x0214), 15,  8, 0x6f);
+	reg_finsr((reg + 0x0218),  7,  0, 0xe4);
+	reg_finsr((reg + 0x0218), 23, 16, 0x80);
+	reg_finsr((reg + 0x0218), 31, 24, 0x75);
+	reg_finsr((reg + 0x022c), 15,  8, 0x08);
+	reg_finsr((reg + 0x022c), 23, 16, 0x20);
+	reg_finsr((reg + 0x0280),  7,  0, 0x86);
+	reg_finsr((reg + 0x0280), 23, 16, 0x86);
+	reg_finsr((reg + 0x0284),  7,  0, 0x85);
+	reg_finsr((reg + 0x0284), 23, 16, 0x0f);
+	reg_finsr((reg + 0x0284), 31, 24, 0x1d);
+	reg_finsr((reg + 0x028c), 15,  8, 0x2c);
+
+	/*  Setting lane 1 SerDes to 5GHz */
+	reg_finsr((reg + 0x0404),  7,  0, 0x80);
+	reg_finsr((reg + 0x0404), 31, 24, 0x78);
+	reg_finsr((reg + 0x0408),  7,  0, 0x26);
+	reg_finsr((reg + 0x040c), 31, 24, 0x02);
+	reg_finsr((reg + 0x0414),  7,  0, 0x38);
+	reg_finsr((reg + 0x0414), 15,  8, 0x6f);
+	reg_finsr((reg + 0x0418),  7,  0, 0xe4);
+	reg_finsr((reg + 0x0418), 23, 16, 0x80);
+	reg_finsr((reg + 0x0418), 31, 24, 0x75);
+	reg_finsr((reg + 0x042c), 15,  8, 0x08);
+	reg_finsr((reg + 0x042c), 23, 16, 0x20);
+	reg_finsr((reg + 0x0480),  7,  0, 0x86);
+	reg_finsr((reg + 0x0480), 23, 16, 0x86);
+	reg_finsr((reg + 0x0484),  7,  0, 0x85);
+	reg_finsr((reg + 0x0484), 23, 16, 0x0f);
+	reg_finsr((reg + 0x0484), 31, 24, 0x1d);
+	reg_finsr((reg + 0x048c), 15,  8, 0x2c);
+
+	/*  Setting lane 2 SerDes to 5GHz */
+	reg_finsr((reg + 0x0604),  7,  0, 0x80);
+	reg_finsr((reg + 0x0604), 31, 24, 0x78);
+	reg_finsr((reg + 0x0608),  7,  0, 0x26);
+	reg_finsr((reg + 0x060c), 31, 24, 0x02);
+	reg_finsr((reg + 0x0614),  7,  0, 0x38);
+	reg_finsr((reg + 0x0614), 15,  8, 0x6f);
+	reg_finsr((reg + 0x0618),  7,  0, 0xe4);
+	reg_finsr((reg + 0x0618), 23, 16, 0x80);
+	reg_finsr((reg + 0x0618), 31, 24, 0x75);
+	reg_finsr((reg + 0x062c), 15,  8, 0x08);
+	reg_finsr((reg + 0x062c), 23, 16, 0x20);
+	reg_finsr((reg + 0x0680),  7,  0, 0x86);
+	reg_finsr((reg + 0x0680), 23, 16, 0x86);
+	reg_finsr((reg + 0x0684),  7,  0, 0x85);
+	reg_finsr((reg + 0x0684), 23, 16, 0x0f);
+	reg_finsr((reg + 0x0684), 31, 24, 0x1d);
+	reg_finsr((reg + 0x068c), 15,  8, 0x2c);
+
+	/*  Setting lane 3 SerDes to 5GHz */
+	reg_finsr((reg + 0x0804),  7,  0, 0x80);
+	reg_finsr((reg + 0x0804), 31, 24, 0x78);
+	reg_finsr((reg + 0x0808),  7,  0, 0x26);
+	reg_finsr((reg + 0x080c), 31, 24, 0x02);
+	reg_finsr((reg + 0x0814),  7,  0, 0x38);
+	reg_finsr((reg + 0x0814), 15,  8, 0x6f);
+	reg_finsr((reg + 0x0818),  7,  0, 0xe4);
+	reg_finsr((reg + 0x0818), 23, 16, 0x80);
+	reg_finsr((reg + 0x0818), 31, 24, 0x75);
+	reg_finsr((reg + 0x082c), 15,  8, 0x08);
+	reg_finsr((reg + 0x082c), 23, 16, 0x20);
+	reg_finsr((reg + 0x0880),  7,  0, 0x86);
+	reg_finsr((reg + 0x0880), 23, 16, 0x86);
+	reg_finsr((reg + 0x0884),  7,  0, 0x85);
+	reg_finsr((reg + 0x0884), 23, 16, 0x0f);
+	reg_finsr((reg + 0x0884), 31, 24, 0x1d);
+	reg_finsr((reg + 0x088c), 15,  8, 0x2c);
+
+	reg_finsr((reg + 0x0a00), 15,  8, 0x80);
+	reg_finsr((reg + 0x0a08), 23, 16, 0xd2);
+	reg_finsr((reg + 0x0a08), 31, 24, 0x38);
+	reg_finsr((reg + 0x0a30), 15,  8, 0x8d);
+	reg_finsr((reg + 0x0a30), 23, 16, 0x8d);
+	reg_finsr((reg + 0x0a84), 15,  8, 0x06);
+	reg_finsr((reg + 0x0a94), 31, 24, 0x10);
+	reg_finsr((reg + 0x0aa0), 31, 24, 0x81);
+	reg_finsr((reg + 0x0abc), 31, 24, 0xff);
+	reg_finsr((reg + 0x0ac0),  7,  0, 0x8b);
+	reg_finsr((reg + 0x0a48), 15,  8, 0x8c);
+	reg_finsr((reg + 0x0a48), 23, 16, 0xfd);
+	reg_finsr((reg + 0x0a54),  7,  0, 0x72);
+	reg_finsr((reg + 0x0a54), 15,  8, 0xec);
+	reg_finsr((reg + 0x0a54), 23, 16, 0x2f);
+	reg_finsr((reg + 0x0a58), 15,  8, 0x21);
+	reg_finsr((reg + 0x0a58), 23, 16, 0xf9);
+	reg_finsr((reg + 0x0a58), 31, 24, 0x00);
+	reg_finsr((reg + 0x0a5c),  7,  0, 0x60);
+	reg_finsr((reg + 0x0a5c), 15,  8, 0x00);
+	reg_finsr((reg + 0x0a5c), 23, 16, 0x04);
+	reg_finsr((reg + 0x0a5c), 31, 24, 0x00);
+	reg_finsr((reg + 0x0a60),  7,  0, 0x00);
+	reg_finsr((reg + 0x0a60), 15,  8, 0x80);
+	reg_finsr((reg + 0x0a60), 23, 16, 0x00);
+	reg_finsr((reg + 0x0a60), 31, 24, 0x00);
+	reg_finsr((reg + 0x0a64),  7,  0, 0x20);
+	reg_finsr((reg + 0x0a64), 15,  8, 0x12);
+	reg_finsr((reg + 0x0a64), 23, 16, 0x58);
+	reg_finsr((reg + 0x0a64), 31, 24, 0x0c);
+	reg_finsr((reg + 0x0a68),  7,  0, 0x02);
+	reg_finsr((reg + 0x0a68), 15,  8, 0x06);
+	reg_finsr((reg + 0x0a68), 23, 16, 0x3b);
+	reg_finsr((reg + 0x0a68), 31, 24, 0xe1);
+	reg_finsr((reg + 0x0a6c),  7,  0, 0xc1);
+	reg_finsr((reg + 0x0a6c), 15,  8, 0x4c);
+	reg_finsr((reg + 0x0a6c), 23, 16, 0x07);
+	reg_finsr((reg + 0x0a6c), 31, 24, 0xb8);
+	reg_finsr((reg + 0x0a70),  7,  0, 0x89);
+	reg_finsr((reg + 0x0a70), 15,  8, 0xe9);
+	reg_finsr((reg + 0x0a70), 23, 16, 0x02);
+	reg_finsr((reg + 0x0a70), 31, 24, 0x3f);
+	reg_finsr((reg + 0x0a74),  7,  0, 0x01);
+	reg_finsr((reg + 0x0b20), 23, 16, 0x37);
+	reg_finsr((reg + 0x0b1c), 31, 24, 0x37);
+	reg_finsr((reg + 0x0b20),  7,  0, 0x5d);
+	reg_finsr((reg + 0x0000),  7,  0, 0x03);
+	reg_finsr((reg + 0x0a00),  7,  0, 0x5f);
+}
+
+static void k2_rio_serdes_lane_enable(u32 lane, u32 rate,
+				      struct keystone_rio_data *krio_priv)
+{
+	void *regs = (void *)krio_priv->serdes_regs;
+	u32 val;
+
+	/* Bit 28 Toggled. Bring it out of Reset TX PLL for all lanes */
+	val = readl(regs + 0x200 * (lane + 1) + 0x28);
+	val &= ~BIT(29);
+	writel(val, regs + 0x200 * (lane + 1) + 0x28);
+
+	/* Set Lane Control Rate */
+	switch (rate) {
+	case KEYSTONE_RIO_FULL_RATE:
+		writel(0xF0C0F0F0, regs + 0x1fe0 + 4 * lane);
+		break;
+	case KEYSTONE_RIO_HALF_RATE:
+		writel(0xF4C0F4F0, regs + 0x1fe0 + 4 * lane);
+		break;
+	case KEYSTONE_RIO_QUARTER_RATE:
+		writel(0xF8C0F8F0, regs + 0x1fe0 + 4 * lane);
+		break;
+	default:
+		return;
+	}
+}
+
+static int k2_rio_serdes_config(u32 lanes, u32 baud,
+				struct keystone_rio_data *krio_priv)
+{
+	void *regs = (void *)krio_priv->serdes_regs;
+	u32 rate;
+	u32 val;
+
+	/* Disable pll before configuring the SerDes registers */
+	writel(0x00000000, regs + 0x1ff4);
+
+	switch (baud) {
+	case KEYSTONE_RIO_BAUD_1_250:
+		rate = KEYSTONE_RIO_QUARTER_RATE;
+		k2_rio_serdes_init_5g(lanes, krio_priv);
+		break;
+	case KEYSTONE_RIO_BAUD_2_500:
+		rate = KEYSTONE_RIO_HALF_RATE;
+		k2_rio_serdes_init_5g(lanes, krio_priv);
+		break;
+	case KEYSTONE_RIO_BAUD_5_000:
+		rate = KEYSTONE_RIO_FULL_RATE;
+		k2_rio_serdes_init_5g(lanes, krio_priv);
+		break;
+	case KEYSTONE_RIO_BAUD_3_125:
+		rate = KEYSTONE_RIO_HALF_RATE;
+		k2_rio_serdes_init_3g(lanes, krio_priv);
+		break;
+	default:
+		printf("RIO: unsupported baud rate %d\n", baud);
+		return -1;
+	}
+
+	/* Enable serdes for requested lanes */
+	while (lanes) {
+		u32 lane = ffs(lanes) - 1;
+		lanes &= ~(1 << lane);
+
+		if (lane >= KEYSTONE_RIO_MAX_PORT)
+			return -1;
+
+		k2_rio_serdes_lane_enable(lane, rate, krio_priv);
+	}
+
+	/* Enable pll via the pll_ctrl 0x0014 */
+	writel(0xe0000000, regs + 0x1ff4);
+
+	/* Wait until CMU_OK bit is set */
+	do {
+		val = readl(regs + 0xbf8);
+	} while (!(val & BIT(16)));
+
+	return 0;
+}
+
+static int k2_rio_serdes_wait_lock(struct keystone_rio_data *krio_priv,
+				   u32 lanes)
+{
+	u32 loop;
+	u32 val;
+	u32 val_mask;
+	void *regs = (void *)krio_priv->serdes_regs;
+
+	val_mask = lanes | (lanes << 8);
+
+	/* Wait for the SerDes PLL lock */
+	for (loop = 0; loop < 100000; loop++) {
+		/* read PLL_CTRL */
+		val = readl(regs + 0x1ff4);
+		if ((val & val_mask) == val_mask)
+			break;
+		udelay(10);
+	}
+
+	if (loop == 100000)
+		return -1;
+
+	return 0;
+}
+
+/**
+ * keystone_rio_hw_init - Configure a RapidIO controller
+ * @mode: serdes configuration
+ * @hostid: device id of the host
+ */
+static void keystone_rio_hw_init(u32 mode, u32 baud,
+				 struct keystone_rio_data *krio_priv)
+{
+	u32 val;
+	u32 block;
+	struct keystone_serdes_config *serdes_config
+		= &(krio_priv->board_rio_cfg.serdes_config[mode]);
+
+	/* Set sRIO out of reset */
+	writel(0x00000011, &krio_priv->regs->pcr);
+
+	/* Clear BOOT_COMPLETE bit (allowing write) */
+	writel(0x00000000, &krio_priv->regs->per_set_cntl);
+
+	/* Enable blocks */
+	writel(1, &krio_priv->regs->gbl_en);
+	for (block = 0; block <= KEYSTONE_RIO_BLK_NUM; block++)
+		writel(1, &(krio_priv->regs->blk[block].enable));
+
+	/* Set control register 1 configuration */
+	writel(0x00000000, &krio_priv->regs->per_set_cntl1);
+
+	/* Set Control register */
+	writel(serdes_config->cfg_cntl, &krio_priv->regs->per_set_cntl);
+
+	if (K2_SERDES(krio_priv)) {
+		u32 path_mode = krio_priv->board_rio_cfg.path_mode;
+		u32 ports     = krio_priv->board_rio_cfg.ports;
+		int res;
+
+		/* K2 SerDes main configuration */
+		res = keystone_rio_get_lane_config(ports, path_mode);
+		if (res > 0) {
+			u32 lanes = (u32) res;
+			res = k2_rio_serdes_config(lanes, baud, krio_priv);
+		}
+	} else {
+		u32 port;
+
+		/* K1 SerDes main configuration */
+		writel(serdes_config->serdes_cfg_pll,
+		       &krio_priv->serdes_regs->pll);
+
+		/* Per-port SerDes configuration */
+		for (port = 0; port < KEYSTONE_RIO_MAX_PORT; port++) {
+			writel(serdes_config->rx_chan_config[port],
+			       &krio_priv->serdes_regs->channel[port].rx);
+			writel(serdes_config->tx_chan_config[port],
+			       &krio_priv->serdes_regs->channel[port].tx);
+		}
+
+		/* Check for RIO SerDes PLL lock */
+		do {
+			val = readl(krio_priv->serdes_sts_reg);
+		} while ((val & 0x1) != 0x1);
+	}
+
+	/* Set prescalar for ip_clk */
+	writel(serdes_config->prescalar_srv_clk,
+	       &krio_priv->link_regs->prescalar_srv_clk);
+
+	/* Peripheral-specific configuration and capabilities */
+	writel(KEYSTONE_RIO_DEV_ID_VAL,
+	       &krio_priv->car_csr_regs->dev_id);
+	writel(KEYSTONE_RIO_DEV_INFO_VAL,
+	       &krio_priv->car_csr_regs->dev_info);
+	writel(KEYSTONE_RIO_ID_TI,
+	       &krio_priv->car_csr_regs->assembly_id);
+	writel(KEYSTONE_RIO_EXT_FEAT_PTR,
+	       &krio_priv->car_csr_regs->assembly_info);
+
+	/* Set host device id */
+	writel((krio_priv->riohdid & 0xffff)
+	       | ((krio_priv->riohdid & 0xff) << 16),
+	       &krio_priv->car_csr_regs->base_dev_id);
+
+	krio_priv->rio_pe_feat = RIO_PEF_PROCESSOR
+		| RIO_PEF_CTLS
+		| KEYSTONE_RIO_PEF_FLOW_CONTROL
+		| RIO_PEF_EXT_FEATURES
+		| RIO_PEF_ADDR_34
+		| RIO_PEF_STD_RT
+		| RIO_PEF_INB_DOORBELL
+		| RIO_PEF_INB_MBOX;
+
+	writel(krio_priv->rio_pe_feat,
+	       &krio_priv->car_csr_regs->pe_feature);
+
+	writel(KEYSTONE_RIO_MAX_PORT << 8,
+	       &krio_priv->car_csr_regs->sw_port);
+
+	writel((RIO_SRC_OPS_READ
+		| RIO_SRC_OPS_WRITE
+		| RIO_SRC_OPS_STREAM_WRITE
+		| RIO_SRC_OPS_WRITE_RESPONSE
+		| RIO_SRC_OPS_DATA_MSG
+		| RIO_SRC_OPS_DOORBELL
+		| RIO_SRC_OPS_ATOMIC_TST_SWP
+		| RIO_SRC_OPS_ATOMIC_INC
+		| RIO_SRC_OPS_ATOMIC_DEC
+		| RIO_SRC_OPS_ATOMIC_SET
+		| RIO_SRC_OPS_ATOMIC_CLR
+		| RIO_SRC_OPS_PORT_WRITE),
+	       &krio_priv->car_csr_regs->src_op);
+
+	writel((RIO_DST_OPS_READ
+		| RIO_DST_OPS_WRITE
+		| RIO_DST_OPS_STREAM_WRITE
+		| RIO_DST_OPS_WRITE_RESPONSE
+		| RIO_DST_OPS_DATA_MSG
+		| RIO_DST_OPS_DOORBELL
+		| RIO_DST_OPS_PORT_WRITE),
+	       &krio_priv->car_csr_regs->dest_op);
+
+	writel(RIO_PELL_ADDR_34,
+	       &krio_priv->car_csr_regs->pe_logical_ctl);
+
+	val = (((KEYSTONE_RIO_SP_HDR_NEXT_BLK_PTR & 0xffff) << 16) |
+	       KEYSTONE_RIO_SP_HDR_EP_REC_ID);
+	writel(val, &krio_priv->serial_port_regs->sp_maint_blk_hdr);
+
+	/* clear high bits of local config space base addr */
+	writel(0x00000000, &krio_priv->car_csr_regs->local_cfg_hbar);
+
+	/* set local config space base addr */
+	writel(0x00520000, &krio_priv->car_csr_regs->local_cfg_bar);
+
+	/* Enable HOST & MASTER_ENABLE bits */
+	writel(0xe0000000, &krio_priv->serial_port_regs->sp_gen_ctl);
+
+	/* set link timeout value */
+	writel(0x000FFF00,
+	       &krio_priv->serial_port_regs->sp_link_timeout_ctl);
+
+	/* set response timeout value */
+	writel(0x000FFF00,
+	       &krio_priv->serial_port_regs->sp_rsp_timeout_ctl);
+
+	/* allows SELF_RESET and PWDN_PORT resets to clear sticky reg bits */
+	writel(0x00000001, &krio_priv->link_regs->reg_rst_ctl);
+
+	/* Set error detection mode */
+	/* clear all errors */
+	writel(0x00000000, &krio_priv->err_mgmt_regs->err_det);
+
+	/* enable all error detection */
+	writel(0x00000000, &krio_priv->err_mgmt_regs->err_en);
+
+	/* set err det block header */
+	val = (((KEYSTONE_RIO_ERR_HDR_NEXT_BLK_PTR & 0xffff) << 16) |
+	       KEYSTONE_RIO_ERR_EXT_FEAT_ID);
+	writel(val, &krio_priv->err_mgmt_regs->err_report_blk_hdr);
+
+	/* clear msb of err catptured addr reg */
+	writel(0x00000000, &krio_priv->err_mgmt_regs->h_addr_capt);
+
+	/* clear lsb of err catptured addr reg */
+	writel(0x00000000, &krio_priv->err_mgmt_regs->addr_capt);
+
+	/* clear err catptured source and dest devID reg */
+	writel(0x00000000, &krio_priv->err_mgmt_regs->id_capt);
+
+	/* clear err catptured packet info */
+	writel(0x00000000, &krio_priv->err_mgmt_regs->ctrl_capt);
+
+	/* Force all writes to finish */
+	val = readl(&krio_priv->err_mgmt_regs->ctrl_capt);
+}
+
+/**
+ * keystone_rio_start - Start RapidIO controller
+ */
+static void keystone_rio_start(struct keystone_rio_data *krio_priv)
+{
+	u32 val;
+
+	/* set PEREN bit to enable logical layer data flow */
+	val = (KEYSTONE_RIO_PER_EN | KEYSTONE_RIO_PER_FREE);
+	writel(val, &krio_priv->regs->pcr);
+
+	/* set BOOT_COMPLETE bit */
+	val = readl(&krio_priv->regs->per_set_cntl);
+	writel(val | KEYSTONE_RIO_BOOT_COMPLETE,
+	       &krio_priv->regs->per_set_cntl);
+}
+
+/**
+ * keystone_rio_port_status - Return if the port is OK or not
+ * @port: index of the port
+ *
+ * Return %0 if the port is ready or %-EIO on failure.
+ */
+static int keystone_rio_port_status(int port,
+				    struct keystone_rio_data *krio_priv)
+{
+	unsigned int count, value;
+	int solid_ok = 0;
+
+	if (port >= KEYSTONE_RIO_MAX_PORT)
+		return -1;
+
+	/* Check port status */
+	for (count = 0; count < 300; count++) {
+		value = readl(
+			&(krio_priv->serial_port_regs->sp[port].err_stat));
+
+		if (value & RIO_PORT_N_ERR_STS_PORT_OK) {
+			solid_ok++;
+			if (solid_ok == 100)
+				break;
+		} else {
+			if (solid_ok) {
+				debug_rio(
+					"RIO: unstable port %d (solid_ok = %d)\n",
+					port, solid_ok);
+				return -2;
+			}
+			solid_ok = 0;
+		}
+		udelay(20);
+	}
+
+	return 0;
+}
+
+/**
+ * keystone_rio_port_disable - Disable a RapidIO port
+ * @port: index of the port to configure
+ */
+static void keystone_rio_port_disable(u32 port,
+				      struct keystone_rio_data *krio_priv)
+{
+	/* Disable port */
+	writel(0x800000, &(krio_priv->serial_port_regs->sp[port].ctl));
+}
+
+/**
+ * keystone_rio_port_init - Configure a RapidIO port
+ * @port: index of the port to configure
+ * @mode: serdes configuration
+ */
+static int keystone_rio_port_init(u32 port, u32 path_mode,
+				  struct keystone_rio_data *krio_priv)
+{
+	if (port >= KEYSTONE_RIO_MAX_PORT)
+		return -1;
+
+	/* Disable packet forwarding */
+	writel(0xffffffff, &(krio_priv->regs->pkt_fwd_cntl[port].pf_16b));
+	writel(0x0003ffff, &(krio_priv->regs->pkt_fwd_cntl[port].pf_8b));
+
+	/* Silence and discovery timers */
+	if ((port == 0) || (port == 2)) {
+		writel(0x20000000,
+		       &(krio_priv->phy_regs->phy_sp[port].silence_timer));
+		writel(0x20000000,
+		       &(krio_priv->phy_regs->phy_sp[port].discovery_timer));
+	}
+
+	/* Enable port in input and output */
+	writel(0x600000, &(krio_priv->serial_port_regs->sp[port].ctl));
+
+	/* Program channel allocation to ports (1x, 2x or 4x) */
+	writel(path_mode, &(krio_priv->phy_regs->phy_sp[port].path_ctl));
+
+	return 0;
+}
+
+/**
+ * keystone_rio_port_activate - Start using a RapidIO port
+ * @port: index of the port to configure
+ */
+static int keystone_rio_port_activate(u32 port,
+				      struct keystone_rio_data *krio_priv)
+{
+	/* Cleanup port error status */
+	writel(KEYSTONE_RIO_PORT_ERROR_MASK,
+	       &(krio_priv->serial_port_regs->sp[port].err_stat));
+	writel(0, &(krio_priv->err_mgmt_regs->sp_err[port].det));
+
+	/* Enable promiscuous */
+	writel(0x00309000,
+	       &(krio_priv->transport_regs->transport_sp[port].control));
+
+	return 0;
+}
+
+/*------------------------ Main driver functions -----------------------*/
+
+static void keystone_rio_get_controller_defaults(
+	struct keystone_rio_data *krio_priv,
+	int riosize,
+	u32 rioports,
+	int riopmode,
+	int riobaudrate)
+{
+	struct keystone_rio_board_controller_info *c
+		= &krio_priv->board_rio_cfg;
+	int i;
+
+	c->keystone2_serdes = KEYSTONE_RIO_IS_K2;
+
+	if (K2_SERDES(krio_priv)) {
+		/* K2 configuration */
+		c->rio_regs_base        = 0x2900000;
+		c->rio_regs_size        = 0x40000;
+		c->boot_cfg_regs_base   = 0x2620000;
+		c->boot_cfg_regs_size   = 0x1000;
+		c->serdes_cfg_regs_base = 0x232c000;
+		c->serdes_cfg_regs_size = 0x1000;
+	} else {
+		/* K1 configuration */
+		c->rio_regs_base        = 0x2900000;
+		c->rio_regs_size        = 0x21000;
+		c->boot_cfg_regs_base   = 0x2620000;
+		c->boot_cfg_regs_size   = 0x3b0;
+		c->serdes_cfg_regs_base = 0x2900360;
+		c->serdes_cfg_regs_size = 0x1000;
+	}
+
+	/* dev-id-size */
+	c->size = riosize;
+
+	/* ports to use */
+	c->ports = rioports;
+
+	/* SerDes config */
+	c->serdes_config_num = 1; /* total number of serdes_config[] entries */
+	c->mode              = 0; /* default serdes_config[] entry to use */
+	c->path_mode         = riopmode;
+
+	if (K2_SERDES(krio_priv)) {
+		/*
+		 * K2 sRIO config 0
+		 */
+		c->serdes_config[0].prescalar_srv_clk = 0x001f;
+		c->serdes_baudrate = riobaudrate;
+	} else {
+		/*
+		 * K1 sRIO config 0: MPY = 5x, div rate = half,
+		 * link rate = 3.125 Gbps, mode 1x
+		 */
+
+		/* setting control register config */
+		c->serdes_config[0].cfg_cntl = 0x0c053860;
+
+		/* SerDes PLL configuration */
+		c->serdes_config[0].serdes_cfg_pll = 0x0229;
+
+		/* prescalar_srv_clk */
+		c->serdes_config[0].prescalar_srv_clk = 0x001e;
+
+		/* serdes rx_chan_config */
+		for (i = 0; i < KEYSTONE_RIO_MAX_PORT; i++)
+			c->serdes_config[0].rx_chan_config[i] = 0x00440495;
+
+		/* serdes tx_chan_config */
+		for (i = 0; i < KEYSTONE_RIO_MAX_PORT; i++)
+			c->serdes_config[0].tx_chan_config[i] = 0x00180795;
+	}
+}
+
+/*
+ * Platform configuration setup
+ */
+static int keystone_rio_setup_controller(struct keystone_rio_data *krio_priv)
+{
+	u32 ports;
+	u32 p;
+	u32 mode;
+	u32 baud;
+	u32 path_mode;
+	u32 size = 0;
+	int res = 0;
+	char str[8];
+
+	size      = krio_priv->board_rio_cfg.size;
+	ports     = krio_priv->board_rio_cfg.ports;
+	mode      = krio_priv->board_rio_cfg.mode;
+	baud      = krio_priv->board_rio_cfg.serdes_baudrate;
+	path_mode = krio_priv->board_rio_cfg.path_mode;
+
+	debug_rio(
+		"RIO: size = %d, ports = 0x%x, mode = %d, baud = %d, path_mode = %d\n",
+		size, ports, mode, baud, path_mode);
+
+	if (mode >= krio_priv->board_rio_cfg.serdes_config_num) {
+		mode = 0;
+		printf("RIO: invalid port mode, forcing it to %d\n", mode);
+	}
+
+	if (baud > KEYSTONE_RIO_BAUD_5_000) {
+		baud = KEYSTONE_RIO_BAUD_5_000;
+		printf("RIO: invalid baud rate, forcing it to 5Gbps\n");
+	}
+
+	switch (baud) {
+	case KEYSTONE_RIO_BAUD_1_250:
+		snprintf(str, sizeof(str), "1.25");
+		break;
+	case KEYSTONE_RIO_BAUD_2_500:
+		snprintf(str, sizeof(str), "2.50");
+		break;
+	case KEYSTONE_RIO_BAUD_3_125:
+		snprintf(str, sizeof(str), "3.125");
+		break;
+	case KEYSTONE_RIO_BAUD_5_000:
+		snprintf(str, sizeof(str), "5.00");
+		break;
+	default:
+		return -1;
+	}
+
+	printf("RIO: initializing %s Gbps interface with port configuration %d\n",
+	       str, path_mode);
+
+	/* Hardware set up of the controller */
+	keystone_rio_hw_init(mode, baud, krio_priv);
+
+	/* Disable all ports */
+	for (p = 0; p < KEYSTONE_RIO_MAX_PORT; p++)
+		keystone_rio_port_disable(p, krio_priv);
+
+	/* Start the controller */
+	keystone_rio_start(krio_priv);
+
+	/* Try to lock K2 SerDes*/
+	if (K2_SERDES(krio_priv)) {
+		int lanes = keystone_rio_get_lane_config(ports, path_mode);
+		if (lanes > 0) {
+			res = k2_rio_serdes_wait_lock(krio_priv, (u32) lanes);
+			if (res < 0)
+				debug_rio(
+					"SerDes for lane mask 0x%x on %s Gbps not locked\n",
+					lanes, str);
+		}
+	}
+
+	/* Use and check ports status (but only the requested ones) */
+	krio_priv->ports_registering = ports;
+	while (ports) {
+		int status;
+		u32 port = ffs(ports) - 1;
+		if (port > 32)
+			return 0;
+		ports &= ~(1 << port);
+
+		res = keystone_rio_port_init(port, path_mode, krio_priv);
+		if (res < 0) {
+			printf("RIO: initialization of port %d failed\n", p);
+			return res;
+		}
+
+		/* Start the port */
+		keystone_rio_port_activate(port, krio_priv);
+
+		/* Check the port status */
+		status = keystone_rio_port_status(port, krio_priv);
+		if (status == 0) {
+			krio_priv->ports_registering &= ~(1 << port);
+			printf("RIO: port RIO%d ready\n", port);
+		} else {
+			printf("RIO: port %d not ready (status %d)\n",
+			       port, status);
+		}
+	}
+
+	if (krio_priv->ports_registering != 0)
+		return -1;
+
+	return res;
+}
+
+/**
+ * rio_init - Initialize RapidIO subsystem
+ * @riohdid: RapidIO host device ID
+ * @riosize: RapidIO device ID size
+ * @rioports: bitmask of ports to configure
+ * @riopmode: path mode (lanes to ports mapping)
+ * @riobaudrate: link baudrate
+ *
+ * Returns riohandle on success or %NULL on failure.
+ */
+void *rio_init(int riohdid,
+	       int riosize,
+	       u32 rioports,
+	       int riopmode,
+	       int riobaudrate)
+{
+	struct keystone_rio_data *krio_priv = &__krio_priv;
+	int res = 0;
+	void *regs;
+
+	keystone_rio_get_controller_defaults(krio_priv,
+					     riosize,
+					     rioports,
+					     riopmode,
+					     riobaudrate);
+
+	regs = (void *)krio_priv->board_rio_cfg.boot_cfg_regs_base;
+	krio_priv->jtagid_reg     = regs + 0x0018;
+	krio_priv->serdes_sts_reg = regs + 0x0154;
+
+	regs = (void *)krio_priv->board_rio_cfg.serdes_cfg_regs_base;
+	krio_priv->serdes_regs = regs;
+
+	regs = (void *)krio_priv->board_rio_cfg.rio_regs_base;
+	krio_priv->regs		     = regs;
+	krio_priv->car_csr_regs	     = regs + 0x0b000;
+	krio_priv->serial_port_regs  = regs + 0x0b100;
+	krio_priv->err_mgmt_regs     = regs + 0x0c000;
+	krio_priv->phy_regs	     = regs + 0x1b000;
+	krio_priv->transport_regs    = regs + 0x1b300;
+	krio_priv->pkt_buf_regs	     = regs + 0x1b600;
+	krio_priv->evt_mgmt_regs     = regs + 0x1b900;
+	krio_priv->port_write_regs   = regs + 0x1ba00;
+	krio_priv->link_regs	     = regs + 0x1bd00;
+	krio_priv->fabric_regs	     = regs + 0x1be00;
+	krio_priv->car_csr_regs_base = (u32) regs + 0xb000;
+
+	krio_priv->riohdid = riohdid;
+
+	/* Enable srio clock */
+	psc_enable_module(KS2_LPSC_SRIO);
+
+	printf("KeyStone RapidIO driver %s, hdid=%d\n", DRIVER_VER, riohdid);
+
+	/* Setup the sRIO controller */
+	res = keystone_rio_setup_controller(krio_priv);
+	if (res < 0)
+		return NULL;
+
+	return (void *)krio_priv;
+}
+
+/**
+ * rio_shutdown - Shutdown RapidIO subsystem
+ * @riohandle: RapidIO handle (returned by rio_init)
+ *
+ * Returns %0 on success or %-1 on failure.
+ */
+int rio_shutdown(void *riohandle)
+{
+	if (riohandle != &__krio_priv)
+		return -1;
+
+	/* Power off */
+	psc_disable_module(KS2_LPSC_SRIO);
+
+	return 0;
+}
diff --git a/drivers/rapidio/keystone_rio.h b/drivers/rapidio/keystone_rio.h
new file mode 100644
index 0000000..92547ae
--- /dev/null
+++ b/drivers/rapidio/keystone_rio.h
@@ -0,0 +1,650 @@
+/*
+ * (C) Copyright 2015
+ * Texas Instruments Incorporated, <www.ti.com>
+ * Authors: Aurelien Jacquiot <a-jacquiot at ti.com>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#ifndef KEYSTONE_RIO_H
+#define KEYSTONE_RIO_H
+
+#include <asm/setup.h>
+#include <asm/cache.h>
+#include <asm/io.h>
+
+#define BIT(x) (1 << (x))
+
+#define KEYSTONE_RIO_MAP_FLAG_SEGMENT	  BIT(0)
+#define KEYSTONE_RIO_MAP_FLAG_SRC_PROMISC BIT(1)
+#define KEYSTONE_RIO_MAP_FLAG_TT_16	  BIT(13)
+#define KEYSTONE_RIO_MAP_FLAG_DST_PROMISC BIT(15)
+#define KEYSTONE_RIO_DESC_FLAG_TT_16	  BIT(9)
+
+#define KEYSTONE_RIO_BOOT_COMPLETE	  BIT(24)
+#define KEYSTONE_RIO_PER_EN		  BIT(2)
+#define KEYSTONE_RIO_PER_FREE		  BIT(0)
+#define KEYSTONE_RIO_PEF_FLOW_CONTROL	  BIT(7)
+
+/*
+ * Packet types
+ */
+#define KEYSTONE_RIO_PACKET_TYPE_NREAD    0x24
+#define KEYSTONE_RIO_PACKET_TYPE_NWRITE   0x54
+#define KEYSTONE_RIO_PACKET_TYPE_NWRITE_R 0x55
+#define KEYSTONE_RIO_PACKET_TYPE_SWRITE   0x60
+#define KEYSTONE_RIO_PACKET_TYPE_DBELL    0xa0
+#define KEYSTONE_RIO_PACKET_TYPE_MAINT_R  0x80
+#define KEYSTONE_RIO_PACKET_TYPE_MAINT_W  0x81
+#define KEYSTONE_RIO_PACKET_TYPE_MAINT_RR 0x82
+#define KEYSTONE_RIO_PACKET_TYPE_MAINT_WR 0x83
+#define KEYSTONE_RIO_PACKET_TYPE_MAINT_PW 0x84
+
+/*
+ * LSU defines
+ */
+#define KEYSTONE_RIO_LSU_PRIO           0
+
+#define KEYSTONE_RIO_LSU_BUSY_MASK      BIT(31)
+#define KEYSTONE_RIO_LSU_FULL_MASK      BIT(30)
+
+#define KEYSTONE_RIO_LSU_CC_MASK        0x0f
+#define KEYSTONE_RIO_LSU_CC_TIMEOUT     0x01
+#define KEYSTONE_RIO_LSU_CC_XOFF        0x02
+#define KEYSTONE_RIO_LSU_CC_ERROR       0x03
+#define KEYSTONE_RIO_LSU_CC_INVALID     0x04
+#define KEYSTONE_RIO_LSU_CC_DMA         0x05
+#define KEYSTONE_RIO_LSU_CC_RETRY       0x06
+#define KEYSTONE_RIO_LSU_CC_CANCELED    0x07
+
+/* Mask for receiving both error and good completion LSU interrupts */
+#define KEYSTONE_RIO_ICSR_LSU0(src_id)  ((0x10001) << (src_id))
+
+/* Keystone2 supported baud rates */
+#define KEYSTONE_RIO_BAUD_1_250		0
+#define KEYSTONE_RIO_BAUD_2_500		1
+#define KEYSTONE_RIO_BAUD_3_125		2
+#define KEYSTONE_RIO_BAUD_5_000		3
+
+#define KEYSTONE_RIO_FULL_RATE		0
+#define KEYSTONE_RIO_HALF_RATE		1
+#define KEYSTONE_RIO_QUARTER_RATE	2
+
+/* Max ports configuration per path modes */
+#define KEYSTONE_MAX_PORTS_PATH_MODE_0  0xf /* 4 ports */
+#define KEYSTONE_MAX_PORTS_PATH_MODE_1  0xd /* 3 ports */
+#define KEYSTONE_MAX_PORTS_PATH_MODE_2  0x7 /* 3 ports */
+#define KEYSTONE_MAX_PORTS_PATH_MODE_3  0x5 /* 2 ports */
+#define KEYSTONE_MAX_PORTS_PATH_MODE_4  0x1 /* 1 ports */
+
+#define SERDES_LANE(lane_num)	                (0x01 << lane_num)
+#define IS_SERDES_LANE_USED(lanes, lane_num)	(lanes & SERDES_LANE(lane_num))
+
+/*
+ * Various RIO defines
+ */
+#define KEYSTONE_RIO_TIMEOUT_CNT	1000
+
+/*
+ * RIO error, reset and special event interrupt defines
+ */
+#define KEYSTONE_RIO_PORT_ERROR_OUT_PKT_DROP	BIT(26)
+#define KEYSTONE_RIO_PORT_ERROR_OUT_FAILED	BIT(25)
+#define KEYSTONE_RIO_PORT_ERROR_OUT_DEGRADED	BIT(24)
+#define KEYSTONE_RIO_PORT_ERROR_OUT_RETRY	BIT(20)
+#define KEYSTONE_RIO_PORT_ERROR_OUT_ERROR	BIT(17)
+#define KEYSTONE_RIO_PORT_ERROR_IN_ERROR	BIT(9)
+#define KEYSTONE_RIO_PORT_ERROR_PW_PENDING	BIT(4)
+#define KEYSTONE_RIO_PORT_ERROR_PORT_ERR	BIT(2)
+
+#define KEYSTONE_RIO_PORT_ERROR_MASK   \
+	(KEYSTONE_RIO_PORT_ERROR_OUT_PKT_DROP	|\
+	KEYSTONE_RIO_PORT_ERROR_OUT_FAILED	|\
+	KEYSTONE_RIO_PORT_ERROR_OUT_DEGRADED	|\
+	KEYSTONE_RIO_PORT_ERROR_OUT_RETRY	|\
+	KEYSTONE_RIO_PORT_ERROR_OUT_ERROR	|\
+	KEYSTONE_RIO_PORT_ERROR_IN_ERROR	|\
+	KEYSTONE_RIO_PORT_ERROR_PW_PENDING	|\
+	KEYSTONE_RIO_PORT_ERROR_PORT_ERR)
+
+
+#define KEYSTONE_RIO_SP_HDR_NEXT_BLK_PTR	0x1000
+#define KEYSTONE_RIO_SP_HDR_EP_REC_ID		0x0002
+#define KEYSTONE_RIO_ERR_HDR_NEXT_BLK_PTR	0x3000
+#define KEYSTONE_RIO_ERR_EXT_FEAT_ID		0x0007
+
+/*
+ * RapidIO global definitions
+ */
+#define KEYSTONE_RIO_MAX_PORT	       4
+#define KEYSTONE_RIO_BLK_NUM	       9
+#define KEYSTONE_RIO_MAINT_BUF_SIZE    64
+
+/*
+ * Dev Id and dev revision
+ */
+#define KEYSTONE_RIO_DEV_ID_VAL	\
+	((((__raw_readl(krio_priv->jtagid_reg)) << 4)  & 0xffff0000) | 0x30)
+
+#define KEYSTONE_RIO_DEV_INFO_VAL \
+	(((__raw_readl(krio_priv->jtagid_reg)) >> 28) & 0xf)
+
+#define KEYSTONE_RIO_ID_TI	       (0x00000030)
+#define KEYSTONE_RIO_EXT_FEAT_PTR      (0x00000100)
+
+/*
+ * SerDes configurations
+ */
+struct keystone_serdes_config {
+	u32 cfg_cntl;            /* setting control register config */
+	u16 serdes_cfg_pll;      /* SerDes PLL configuration */
+	u16 prescalar_srv_clk;   /* prescalar fo ip_clk */
+
+	/* SerDes receive channel configuration (per-port) */
+	u32 rx_chan_config[KEYSTONE_RIO_MAX_PORT];
+
+	/* SerDes transmit channel configuration (per-port) */
+	u32 tx_chan_config[KEYSTONE_RIO_MAX_PORT];
+};
+
+/*
+ * Per board RIO devices controller configuration
+ */
+struct keystone_rio_board_controller_info {
+	u32		rio_regs_base;
+	u32		rio_regs_size;
+
+	u32		boot_cfg_regs_base;
+	u32		boot_cfg_regs_size;
+
+	u32		serdes_cfg_regs_base;
+	u32		serdes_cfg_regs_size;
+
+	u16 ports;      /* bitfield of port(s) to probe on this controller */
+	u16 mode;       /* hw mode (default serdes config).
+			   index into serdes_config[] */
+	u16 id;         /* host id */
+	u16 size;       /* RapidIO common transport system size.
+			 * 0 - Small size. 256 devices.
+			 * 1 - Large size, 65536 devices. */
+	u16 keystone2_serdes;
+	u16 serdes_config_num;
+	u32 serdes_baudrate;
+	u32 path_mode;
+
+	struct keystone_serdes_config serdes_config[4];
+};
+
+struct keystone_rio_data;
+
+/*
+ * RapidIO Registers
+ */
+
+struct keystone_srio_serdes_regs {
+	u32	pll;
+
+	struct {
+		u32	rx;
+		u32	tx;
+	} channel[4];
+};
+
+/* RIO Registers  0000 - 2fff */
+struct keystone_rio_regs {
+/* Required Peripheral Registers */
+	u32	pid;			/* 0000 */
+	u32	pcr;			/* 0004 */
+	u32	__rsvd0[3];		/* 0008 - 0010 */
+
+/* Peripheral Settting Control Registers */
+	u32	per_set_cntl;		/* 0014 */
+	u32	per_set_cntl1;		/* 0018 */
+
+	u32	__rsvd1[2];		/* 001c - 0020 */
+
+	u32	gbl_en;			/* 0024 */
+	u32	gbl_en_stat;		/* 0028 */
+
+	struct {
+		u32 enable;		/* 002c */
+		u32 status;		/* 0030 */
+	} blk[10];			/* 002c - 0078 */
+
+	/* ID Registers */
+	u32	__rsvd2[17];		/* 007c - 00bc */
+	u32	multiid_reg[8];		/* 00c0 - 00dc */
+
+/* Hardware Packet Forwarding Registers */
+	struct {
+		u32	pf_16b;
+		u32	pf_8b;
+	} pkt_fwd_cntl[8];		/* 00e0 - 011c */
+
+	u32	__rsvd3[24];		/* 0120 - 017c */
+
+/* Interrupt Registers */
+	struct {
+		u32	status;
+		u32	__rsvd0;
+		u32	clear;
+		u32	__rsvd1;
+	} doorbell_int[4];		/* 0180 - 01bc */
+
+	struct {
+		u32	status;
+		u32	__rsvd0;
+		u32	clear;
+		u32	__rsvd1;
+	} lsu_int[2];			/* 01c0 - 01dc */
+
+	u32	err_rst_evnt_int_stat;	/* 01e0 */
+	u32	__rsvd4;
+	u32	err_rst_evnt_int_clear;	/* 01e8 */
+	u32	__rsvd5;
+
+	u32	__rsvd6[4];		/* 01f0 - 01fc */
+
+	struct {
+		u32 route;		/* 0200 */
+		u32 route2;		/* 0204 */
+		u32 __rsvd;		/* 0208 */
+	} doorbell_int_route[4];	/* 0200 - 022c */
+
+	u32	lsu0_int_route[4];		/* 0230 - 023c */
+	u32	lsu1_int_route1;		/* 0240 */
+
+	u32	__rsvd7[3];		/* 0244 - 024c */
+
+	u32	err_rst_evnt_int_route[3];	/* 0250 - 0258 */
+
+	u32	__rsvd8[2];		/* 025c - 0260 */
+
+	u32	interupt_ctl;		/* 0264 */
+
+	u32	__rsvd9[26];		/* 0268, 026c, 0270 - 02cc */
+
+	u32	intdst_rate_cntl[16];	/* 02d0 - 030c */
+	u32	intdst_rate_disable;	/* 0310 */
+
+	u32	__rsvd10[59];		/* 0314 - 03fc */
+
+/* RXU Registers */
+	struct {
+		u32	ltr_mbox_src;
+		u32	dest_prom_seg;
+		u32	flow_qid;
+	} rxu_map[64];			/* 0400 - 06fc */
+
+	struct {
+		u32	cos_src;
+		u32	dest_prom;
+		u32	stream;
+	} rxu_type9_map[64];		/* 0700 - 09fc */
+
+	u32	__rsvd11[192];		/* 0a00 - 0cfc */
+
+/* LSU/MAU Registers */
+	struct {
+		u32 addr_msb;		/* 0d00 */
+		u32 addr_lsb_cfg_ofs;	/* 0d04 */
+		u32 dsp_addr;		/* 0d08 */
+		u32 dbell_val_byte_cnt;	/* 0d0c */
+		u32 destid;		/* 0d10 */
+		u32 dbell_info_fttype;	/* 0d14 */
+		u32 busy_full;		/* 0d18 */
+	} lsu_reg[8];			/* 0d00 - 0ddc */
+
+	u32	lsu_setup_reg[2];	/* 0de0 - 0de4 */
+	u32	lsu_stat_reg[6];	/* 0de8 - 0dfc */
+	u32	lsu_flow_masks[4];	/* 0e00 - 0e0c */
+
+	u32	__rsvd12[16];		/* 0e10 - 0e4c */
+
+/* Flow Control Registers */
+	u32	flow_cntl[16];		/* 0e50 - 0e8c */
+	u32	__rsvd13[8];		/* 0e90 - 0eac */
+
+/* TXU Registers 0eb0 - 0efc */
+	u32	tx_cppi_flow_masks[8];	/* 0eb0 - 0ecc */
+	u32	tx_queue_sch_info[4];	/* 0ed0 - 0edc */
+	u32	garbage_coll_qid[3];	/* 0ee0 - 0ee8 */
+
+	u32	__rsvd14[69];		/* 0eec, 0ef0 - 0ffc */
+
+};
+
+/* CDMAHP Registers 1000 - 2ffc */
+struct keystone_rio_pktdma_regs {
+	u32	__rsvd[2048];		/* 1000 - 2ffc */
+};
+
+/* CSR/CAR Registers  b000+ */
+struct keystone_rio_car_csr_regs {
+	u32	dev_id;			/* b000 */
+	u32	dev_info;		/* b004 */
+	u32	assembly_id;		/* b008 */
+	u32	assembly_info;		/* b00c */
+	u32	pe_feature;		/* b010 */
+
+	u32	sw_port;		/* b014 */
+
+	u32	src_op;			/* b018 */
+	u32	dest_op;		/* b01c */
+
+	u32	__rsvd1[7];		/* b020 - b038 */
+
+	u32	data_stm_info;		/* b03c */
+
+	u32	__rsvd2[2];		/* b040 - b044 */
+
+	u32	data_stm_logical_ctl;	/* b048 */
+	u32	pe_logical_ctl;		/* b04c */
+
+	u32	__rsvd3[2];		/* b050 - b054 */
+
+	u32	local_cfg_hbar;		/* b058 */
+	u32	local_cfg_bar;		/* b05c */
+
+	u32	base_dev_id;		/* b060 */
+	u32	__rsvd4;
+	u32	host_base_id_lock;	/* b068 */
+	u32	component_tag;		/* b06c */
+					/* b070 - b0fc */
+};
+
+struct keystone_rio_serial_port_regs {
+	u32	sp_maint_blk_hdr;	/* b100 */
+	u32	__rsvd6[7];		/* b104 - b11c */
+
+	u32	sp_link_timeout_ctl;	/* b120 */
+	u32	sp_rsp_timeout_ctl;	/* b124 */
+	u32	__rsvd7[5];		/* b128 - b138 */
+	u32	sp_gen_ctl;		/* b13c */
+
+	struct {
+		u32	link_maint_req;	/* b140 */
+		u32	link_maint_resp;/* b144 */
+		u32	ackid_stat;	/* b148 */
+		u32	__rsvd[2];	/* b14c - b150 */
+		u32	ctl2;		/* b154 */
+		u32	err_stat;	/* b158 */
+		u32	ctl;		/* b15c */
+	} sp[4];			/* b140 - b1bc */
+
+					/* b1c0 - bffc */
+};
+
+struct keystone_rio_err_mgmt_regs {
+	u32	err_report_blk_hdr;	/* c000 */
+	u32	__rsvd9;
+	u32	err_det;		/* c008 */
+	u32	err_en;			/* c00c */
+	u32	h_addr_capt;		/* c010 */
+	u32	addr_capt;		/* c014 */
+	u32	id_capt;		/* c018 */
+	u32	ctrl_capt;		/* c01c */
+	u32	__rsvd10[2];		/* c020 - c024 */
+	u32	port_write_tgt_id;	/* c028 */
+	u32	__rsvd11[5];		/* c02c - c03c */
+
+	struct {
+		u32	det;		/* c040 */
+		u32	rate_en;	/* c044 */
+		u32	attr_capt_dbg0;	/* c048 */
+		u32	capt_0_dbg1;	/* c04c */
+		u32	capt_1_dbg2;	/* c050 */
+		u32	capt_2_dbg3;	/* c054 */
+		u32	capt_3_dbg4;	/* c058 */
+		u32	__rsvd0[3];	/* c05c - c064 */
+		u32	rate;		/* c068 */
+		u32	thresh;		/* c06c */
+		u32	__rsvd1[4];	/* c070 - c07c */
+	} sp_err[4];			/* c040 - c13c */
+
+	u32	__rsvd12[1972];		/* c140 - e00c */
+
+	struct {
+		u32	stat0;		/* e010 */
+		u32	stat1;		/* e014 */
+		u32	__rsvd[6];	/* e018 - e02c */
+	} lane_stat[4];			/* e010 - e08c */
+
+					/* e090 - 1affc */
+};
+
+struct keystone_rio_phy_layer_regs {
+	u32	phy_blk_hdr;		/* 1b000 */
+	u32	__rsvd14[31];		/* 1b004 - 1b07c */
+	struct {
+		u32	imp_spec_ctl;	/* 1b080 */
+		u32	pwdn_ctl;	/* 1b084 */
+		u32	__rsvd0[2];
+
+		u32	status;		/* 1b090 */
+		u32	int_enable;	/* 1b094 */
+		u32	port_wr_enable;	/* 1b098 */
+		u32	event_gen;	/* 1b09c */
+
+		u32	all_int_en;	/* 1b0a0 */
+		u32	all_port_wr_en;	/* 1b0a4 */
+		u32	__rsvd1[2];
+
+		u32	path_ctl;	/* 1b0b0 */
+		u32	discovery_timer;/* 1b0b4 */
+		u32	silence_timer;	/* 1b0b8 */
+		u32	vmin_exp;	/* 1b0bc */
+
+		u32	pol_ctl;	/* 1b0c0 */
+		u32	__rsvd2;
+		u32	denial_ctl;	/* 1b0c8 */
+		u32	__rsvd3;
+
+		u32	rcvd_mecs;	/* 1b0d0 */
+		u32	__rsvd4;
+		u32	mecs_fwd;	/* 1b0d8 */
+		u32	__rsvd5;
+
+		u32	long_cs_tx1;	/* 1b0e0 */
+		u32	long_cs_tx2;	/* 1b0e4 */
+		u32	__rsvd[6];	/* 1b0e8, 1b0ec, 1b0f0 - 1b0fc */
+	} phy_sp[4];			/* 1b080 - 1b27c */
+
+					/* 1b280 - 1b2fc */
+};
+
+struct keystone_rio_transport_layer_regs {
+	u32	transport_blk_hdr;	/* 1b300 */
+	u32	__rsvd16[31];		/* 1b304 - 1b37c */
+
+	struct {
+		u32	control;	/*1b380 */
+		u32	__rsvd0[3];
+
+		u32	status;		/* 1b390 */
+		u32	int_enable;	/* 1b394 */
+		u32	port_wr_enable;	/* 1b398 */
+		u32	event_gen;	/* 1b39c */
+
+		struct {
+			u32	ctl;		/* 1b3a0 */
+			u32	pattern_match;	/* 1b3a4 */
+			u32	__rsvd[2];	/* 1b3a8 - 1b3ac */
+		} base_route[4];		/* 1b3a0 - 1b3dc */
+
+		u32	__rsvd1[8];		/* 1b3e0 - 1b3fc */
+
+	} transport_sp[4];			/* 1b380 - 1b57c */
+
+						/* 1b580 - 1b5fc */
+};
+
+struct keystone_rio_pkt_buf_regs {
+	u32	pkt_buf_blk_hdr;	/* 1b600 */
+	u32	__rsvd18[31];		/* 1b604 - 1b67c */
+
+	struct {
+		u32	control;	/* 1b680 */
+		u32	__rsvd0[3];
+
+		u32	status;		/* 1b690 */
+		u32	int_enable;	/* 1b694 */
+		u32	port_wr_enable;	/* 1b698 */
+		u32	event_gen;	/* 1b69c */
+
+		u32	ingress_rsc;	/* 1b6a0 */
+		u32	egress_rsc;	/* 1b6a4 */
+		u32	__rsvd1[2];
+
+		u32	ingress_watermark[4];	/* 1b6b0 - 1b6bc */
+		u32	__rsvd2[16];	/* 1b6c0 - 1b6fc */
+
+	} pkt_buf_sp[4];		/* 1b680 - 1b87c */
+
+					/* 1b880 - 1b8fc */
+};
+
+struct keystone_rio_evt_mgmt_regs {
+	u32	evt_mgmt_blk_hdr;	/* 1b900 */
+	u32	__rsvd20[3];
+
+	u32	evt_mgmt_int_stat;	/* 1b910 */
+	u32	evt_mgmt_int_enable;	/* 1b914 */
+	u32	evt_mgmt_int_port_stat;	/* 1b918 */
+	u32	__rsvd21;
+
+	u32	evt_mgmt_port_wr_stat;	/* 1b920 */
+	u32	evt_mgmt_port_wr_enable;/* 1b924 */
+	u32	evt_mgmt_port_wr_port_stat;	/* 1b928 */
+	u32	__rsvd22;
+
+	u32	evt_mgmt_dev_int_en;	/* 1b930 */
+	u32	evt_mgmt_dev_port_wr_en;	/* 1b934 */
+	u32	__rsvd23;
+	u32	evt_mgmt_mecs_stat;	/* 1b93c */
+
+	u32	evt_mgmt_mecs_int_en;	/* 1b940 */
+	u32	evt_mgmt_mecs_cap_en;	/* 1b944 */
+	u32	evt_mgmt_mecs_trig_en;	/* 1b948 */
+	u32	evt_mgmt_mecs_req;	/* 1b94c */
+
+	u32	evt_mgmt_mecs_port_stat;/* 1b950 */
+	u32	__rsvd24[2];
+	u32	evt_mgmt_mecs_event_gen;/* 1b95c */
+
+	u32	evt_mgmt_rst_port_stat;	/* 1b960 */
+	u32	__rsvd25;
+	u32	evt_mgmt_rst_int_en;	/* 1b968 */
+	u32	__rsvd26;
+
+	u32	evt_mgmt_rst_port_wr_en;/* 1b970 */
+					/* 1b974 - 1b9fc */
+};
+
+struct keystone_rio_port_write_regs {
+	u32	port_wr_blk_hdr;	/* 1ba00 */
+	u32	port_wr_ctl;		/* 1ba04 */
+	u32	port_wr_route;		/* 1ba08 */
+	u32	__rsvd28;
+
+	u32	port_wr_rx_stat;	/* 1ba10 */
+	u32	port_wr_rx_event_gen;	/* 1ba14 */
+	u32	__rsvd29[2];
+
+	u32	port_wr_rx_capt[4];	/* 1ba20 - 1ba2c */
+					/* 1ba30 - 1bcfc */
+};
+
+struct keystone_rio_link_layer_regs {
+	u32	link_blk_hdr;		/* 1bd00 */
+	u32	__rsvd31[8];		/* 1bd04 - 1bd20 */
+	u32	whiteboard;		/* 1bd24 */
+	u32	port_number;		/* 1bd28 */
+
+	u32	__rsvd32;		/* 1bd2c */
+
+	u32	prescalar_srv_clk;	/* 1bd30 */
+	u32	reg_rst_ctl;		/* 1bd34 */
+	u32	__rsvd33[4];		/* 1bd38, 1bd3c, 1bd40, 1bd44 */
+	u32	local_err_det;		/* 1bd48 */
+	u32	local_err_en;		/* 1bd4c */
+
+	u32	local_h_addr_capt;	/* 1bd50 */
+	u32	local_addr_capt;	/* 1bd54 */
+	u32	local_id_capt;		/* 1bd58 */
+	u32	local_ctrl_capt;	/* 1bd5c */
+
+					/* 1bd60 - 1bdfc */
+};
+
+struct keystone_rio_fabric_regs {
+	u32	fabric_hdr;		/* 1be00 */
+	u32	__rsvd35[3];		/* 1be04 - 1be0c */
+
+	u32	fabric_csr;		/* 1be10 */
+	u32	__rsvd36[11];		/* 1be14 - 1be3c */
+
+	u32	sp_fabric_status[4];	/* 1be40 - 1be4c */
+};
+
+/**
+ * keystone_rio_config_read - Generate a KeyStone read maintenance transaction
+ * @portid: Output port ID of transaction
+ * @destid: Destination ID of transaction
+ * @hopcount: Number of hops to target device
+ * @offset: Offset into configuration space
+ * @len: Length (in bytes) of the maintenance transaction
+ * @val: Location to be read into
+ *
+ * Generates a KeyStone read maintenance transaction. Returns %0 on
+ * success or %-1 on failure.
+ */
+int keystone_rio_config_read(int  portid,
+			     u16  destid,
+			     u8   hopcount,
+			     u32  offset,
+			     int  len,
+			     u32 *val);
+
+/**
+ * keystone_rio_config_write - Generate a KeyStone write maintenance transaction
+ * @portid: Output port ID of transaction
+ * @destid: Destination ID of transaction
+ * @hopcount: Number of hops to target device
+ * @offset: Offset into configuration space
+ * @len: Length (in bytes) of the maintenance transaction
+ * @val: Value to be written
+ *
+ * Generates an KeyStone write maintenance transaction. Returns %0 on
+ * success or %-1 on failure.
+ */
+int keystone_rio_config_write(int portid,
+			      u16 destid,
+			      u8  hopcount,
+			      u32 offset,
+			      int len,
+			      u32 val);
+
+/**
+ * keystone_local_config_read - Generate a KeyStone local config space read
+ * @offset: Offset into configuration space
+ * @len: Length (in bytes) of the maintenance transaction
+ * @data: Value to be read into
+ *
+ * Generates a KeyStone local configuration space read. Returns %0 on
+ * success or %-1 on failure.
+ */
+int keystone_local_config_read(u32 offset, int len, u32 *data);
+
+/**
+ * keystone_local_config_write - Generate a KeyStone local config space write
+ * @offset: Offset into configuration space
+ * @len: Length (in bytes) of the maintenance transaction
+ * @data: Value to be written
+ *
+ * Generates a KeyStone local configuration space write. Returns %0 on
+ * success or %-EINVAL on failure.
+ */
+int keystone_local_config_write(u32 offset, int len, u32 data);
+
+#endif /* KEYSTONE_RIO_H */
-- 
1.6.2.1



More information about the U-Boot mailing list