From: Aurelien Jacquiot <a-jacqu...@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-jacqu...@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-jacqu...@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-jacqu...@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

_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

Reply via email to