msys: add switch address completion via switchRegRead/Write commands

	add new commands for MSYS for reading/writing to switch
	registers via address completion:
	switchRegRead & switchRegWrite

Change-Id: I155a5507244f64b79939feeb148823cc48c34a1c
Signed-off-by: Bassel Saba <basselsa@marvell.com>
Reviewed-on: http://vgitil04.il.marvell.com:8080/19366
Tested-by: Star_Automation <star@marvell.com>
Reviewed-by: Omri Itach <omrii@marvell.com>
diff --git a/board/mv_ebu/common/USP/mv_cmd.c b/board/mv_ebu/common/USP/mv_cmd.c
index 6794675..7f55aeb 100644
--- a/board/mv_ebu/common/USP/mv_cmd.c
+++ b/board/mv_ebu/common/USP/mv_cmd.c
@@ -28,6 +28,7 @@
 #include "ctrlEnv/mvCtrlEnvLib.h"
 #include "boardEnv/mvBoardEnvLib.h"
 #include "cpu/mvCpu.h"
+#include "ctrlEnv/sys/mvAhbToMbusRegs.h"
 
 #if defined(MV_INC_BOARD_NOR_FLASH)
 #include "norflash/mvFlash.h"
@@ -922,7 +923,6 @@
 
 	return 1;
 }
-
 U_BOOT_CMD(
 	phyWrite,      4,     4,      phy_write_cmd,
 	"phyWrite	- Write Phy register\n",
@@ -932,7 +932,6 @@
 
 #if defined(MV_INCLUDE_SWITCH)
 #include "ethSwitch/mvSwitch.h"
-
 int switch_read_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
 	MV_U16 phyReg;
@@ -969,6 +968,7 @@
 	"\tWrite to the switch register.\n"
 );
 
+
 int switch_phy_read_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
 	MV_U16 phyReg;
@@ -1045,7 +1045,144 @@
 	" MAC_Port. \n"
 	"\tRead the switch ports counters. \n"
 );
-#endif
+#elif defined(MV_SWITCH_ADDRESS_COMPLETION) /* MV_INCLUDE_SWITCH */
+
+#define SWITCH_REGS_BASE_ADDR_MASK		0xFC000000
+#define SWITCH_ADDR_COMPL_MSB_VAL(addr)	((addr >> 24) & 0xFF)
+#define SWITCH_ADDR_COMPL_SHIFT(addr)	(((addr >> 24) & 0x3) << 3)
+#define SWITCH_BUS_ADDR(addr)			((~SWITCH_REGS_BASE_ADDR_MASK & addr) |\
+							(SWITCH_WIN_BASE_ADDR_GET() & SWITCH_REGS_BASE_ADDR_MASK))
+
+/*******************************************************************************
+* SWITCH_WIN_BASE_ADDR_GET
+*
+* DESCRIPTION:
+* This function returns the base address of switch registers window
+*
+*
+* RETURN:
+*	base address of switch registers window
+*
+*******************************************************************************/
+static __inline MV_U32 SWITCH_WIN_BASE_ADDR_GET(MV_VOID)
+{
+	static MV_U32	baseAddr;
+	baseAddr = MV_REG_READ(AHB_TO_MBUS_WIN_BASE_REG(SWITCH_WIN_ID));
+	return baseAddr;
+}
+
+/*******************************************************************************
+* SWITCH_ADDR_COMPL_SET
+*
+* DESCRIPTION:
+* This function configures address completion register
+*
+* INPUT:
+*	addr	- the address to access indirectly
+*
+*******************************************************************************/
+static __inline MV_STATUS SWITCH_ADDR_COMPL_SET(MV_U32 addr)
+{
+	MV_U32	rVal;
+	/* Configure address completion region REG using SERDES memory window */
+	rVal  = MV_MEMIO32_READ(SWITCH_WIN_BASE_ADDR_GET());
+	rVal &= ~(0xFF << SWITCH_ADDR_COMPL_SHIFT(addr));
+	rVal |= SWITCH_ADDR_COMPL_MSB_VAL(addr) << SWITCH_ADDR_COMPL_SHIFT(addr);
+	MV_MEMIO32_WRITE(SWITCH_WIN_BASE_ADDR_GET(), rVal);
+	return MV_OK;
+}
+
+/*******************************************************************************
+* mvSwitchRegisterGet
+*
+* DESCRIPTION:
+* This function reads switch register with address completion
+*
+* INPUT:
+*	address		- the address to read indirectly
+*	mask		- mask of the read data
+*
+* OUTPUT:
+*	data		- the register's data value
+*
+*
+*******************************************************************************/
+void mvSwitchRegisterGet(MV_U32 address, MV_U32 *data, MV_U32 mask)
+{
+	SWITCH_ADDR_COMPL_SET(address); /* Only MSB is important, serdes number offset does not matter */
+	*data  = MV_MEMIO32_READ(SWITCH_BUS_ADDR(address)) & mask;
+}
+
+/*******************************************************************************
+* switchRegRead
+*
+* DESCRIPTION:
+* This command reads switch register with address completion
+*
+*******************************************************************************/
+int switch_read_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	MV_U32 regVal;
+
+	mvSwitchRegisterGet(simple_strtoul(argv[1], NULL, 16), &regVal, 0xFFFF);
+	printf ("0x%x\n", regVal);
+
+	return 1;
+}
+U_BOOT_CMD(
+	switchRegRead,      2,     2,      switch_read_cmd,
+"switchRegRead	- Read switch register, using Address completion\n",
+" Reg_offset. \n"
+"\tRead the switch register, using Address completion. \n"
+);
+
+/*******************************************************************************
+* mvSwitchRegisterSet
+*
+* DESCRIPTION:
+* This function writes to switch register with address completion
+*
+*	address		- the address to write to indirectly
+*	data		- the data to write
+*	mask		- mask of the write data
+*
+*******************************************************************************/
+void mvSwitchRegisterSet(MV_U32 address, MV_U32 data, MV_U32 mask)
+{
+	MV_U32 regData;
+
+	if ((mask & 0xFFFF) != 0xFFFF) { /* since switch registers are 16 bits - check only the relevant bits */
+		mvSwitchRegisterGet(address, &regData, ~mask);
+		regData |= (data & mask);
+	} else
+		regData = data;
+
+	SWITCH_ADDR_COMPL_SET(address); /* Only MSB is important, serdes number offset does not matter */
+
+	MV_MEMIO32_WRITE(SWITCH_BUS_ADDR(address), regData);
+}
+
+/*******************************************************************************
+* switchRegWrite
+*
+* DESCRIPTION:
+* This command writes to switch register with address completion
+*
+*******************************************************************************/
+int switch_write_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	mvSwitchRegisterSet(simple_strtoul(argv[1], NULL, 16), simple_strtoul(argv[2], NULL, 16), 0xFFFF);
+
+	return 1;
+}
+
+U_BOOT_CMD(
+	switchRegWrite,      3,     3,      switch_write_cmd,
+"switchRegWrite	- Write to switch register, using Address completion\n",
+" Reg_offset Reg_data. \n"
+"\tWrite to the switch register, using Address completion. \n"
+);
+#endif /* MV_SWITCH_ADDRESS_COMPLETION */
 #endif /* #if defined(MV_INCLUDE_GIG_ETH) */
 
 #define REG_SDRAM_CONFIG_ADDR					0x1400
diff --git a/board/mv_ebu/msys/mvSysHwConfig.h b/board/mv_ebu/msys/mvSysHwConfig.h
index e7d490e..aaf184e 100644
--- a/board/mv_ebu/msys/mvSysHwConfig.h
+++ b/board/mv_ebu/msys/mvSysHwConfig.h
@@ -135,6 +135,7 @@
 #define SWITCH_REGS_BASE		0xA8000000
 #define SWITCH_REGS_SIZE		_64M
 #define SWITCH_REGS_VIRT_BASE	SWITCH_REGS_BASE
+#define SWITCH_WIN_ID			5
 /************************************************************/
 /* Device: CS0 - NOR or NAND, CS1 - SPI, CS2 - Boot ROM, CS3 - Boot device */
 /* NOR and NAND are configure to CS0 but it is posible to load
@@ -252,7 +253,7 @@
 		{ { PEX0_IO_BASE,         0,      PEX0_IO_SIZE    },      TBL_UNUSED,     DIS },        /*  9 PEX0_IO */	\
 		{ { INTER_REGS_BASE,      0, INTER_REGS_SIZE }, MV_AHB_TO_MBUS_INTREG_WIN, EN },        /* 10 INTER_REGS */ \
 		{ { DFX_REGS_BASE,        0,      DFX_REGS_SIZE   },      1,               EN },        /* 11 DFX_REGS */ \
-		{ { SWITCH_REGS_BASE,     0,     SWITCH_REGS_SIZE },      5,               EN },        /* 12 SWITCH   */ \
+		{ { SWITCH_REGS_BASE,     0,     SWITCH_REGS_SIZE },      SWITCH_WIN_ID,   EN },        /* 12 SWITCH   */ \
 		{ { TBL_UNUSED,           0,      TBL_UNUSED      },      TBL_UNUSED,     DIS },        /* 13 DMA_UART   */ \
 		{ { SPI_CS_BASE,          0,      SPI_CS_SIZE     },      8,               EN },        /* 14 SPI_CS0 */	\
 		{ { TBL_UNUSED,           0,      TBL_UNUSED      },      TBL_UNUSED,     DIS },        /* 15 SPI_CS1 */	\
diff --git a/include/configs/msys.h b/include/configs/msys.h
index 1c6a307..b374f30 100644
--- a/include/configs/msys.h
+++ b/include/configs/msys.h
@@ -678,6 +678,7 @@
 #define CONFIG_BOARD_LATE_INIT
 #undef CONFIG_USE_IRQ
 #define CONFIG_BZIP2
+#define MV_SWITCH_ADDRESS_COMPLETION
 
 /* for running from L2 SRAM
 #define CONFIG_STACKSIZE	(128 << 10)