msys: axp-amc: add AXP serdes configuration
Change-Id: Ibea50a002bf9920480f37f2848487a42c0aa59fc
Signed-off-by: Marcin Wojtas <mw@semihalf.com>
Signed-off-by: Omri Itach <omrii@marvell.com>
Reviewed-on: http://vgitil04.il.marvell.com:8080/20561
diff --git a/board/mv_ebu/msys/msys_family/ctrlEnv/mvCtrlEnvLib.c b/board/mv_ebu/msys/msys_family/ctrlEnv/mvCtrlEnvLib.c
index 2a45c4b..56f91b8 100755
--- a/board/mv_ebu/msys/msys_family/ctrlEnv/mvCtrlEnvLib.c
+++ b/board/mv_ebu/msys/msys_family/ctrlEnv/mvCtrlEnvLib.c
@@ -281,9 +281,9 @@
MV_U32 mppGroup;
MV_U32 mppVal;
MV_U32 i, gppMask;
- int maxGroup = mvCtrlDevFamilyIdGet(0) == MV_78460_DEV_ID ?
+ MV_U32 maxGroup = mvCtrlDevFamilyIdGet(0) == MV_78460_DEV_ID ?
MV_MPP_MAX_GROUP_AXP : MV_MPP_MAX_GROUP;
-
+ MV_STATUS status;
/* Disable MBus Error Propagation */
MV_REG_BIT_RESET(SOC_COHERENCY_FABRIC_CTRL_REG, BIT8);
@@ -321,7 +321,12 @@
mvBoardOtherModulesScan();
/* Update interfaces configuration based on above scan */
- if (MV_OK != mvCtrlSerdesPhyConfig())
+ if (mvCtrlDevFamilyIdGet(0) == MV_78460_DEV_ID)
+ status = mvCtrlSerdesPhyConfigAxp();
+ else
+ status = mvCtrlSerdesPhyConfig();
+
+ if (status != MV_OK)
mvOsPrintf("mvCtrlEnvInit: Can't init some or all SERDES lanes\n");
if (mvCtrlDevFamilyIdGet(0) != MV_78460_DEV_ID) {
@@ -386,7 +391,7 @@
MV_U32 mvCtrlPexMaxIfGet(MV_VOID)
{
if (mvCtrlDevFamilyIdGet(0) == MV_78460_DEV_ID)
- return MV_PEX_MAX_IF_AXP;
+ return MV_PEX_MAX_IF;
return mvCtrlSocUnitInfoNumGet(PEX_UNIT_ID);
}
@@ -1473,6 +1478,23 @@
break;
#endif
+#if defined(MV_INCLUDE_INTEG_SATA)
+ case SATA_UNIT_ID:
+ if (enable == MV_FALSE)
+ MV_REG_BIT_RESET(POWER_MNG_CTRL_REG, AXP_PMC_SATASTOPCLOCK_MASK(index));
+ else
+ MV_REG_BIT_SET(POWER_MNG_CTRL_REG, AXP_PMC_SATASTOPCLOCK_MASK(index));
+
+ break;
+#endif
+#if defined(MV_INCLUDE_TDM)
+ case TDM_UNIT_ID:
+ if (enable == MV_FALSE)
+ MV_REG_BIT_RESET(POWER_MNG_CTRL_REG, AXP_PMC_TDMSTOPCLOCK_MASK);
+ else
+ MV_REG_BIT_SET(POWER_MNG_CTRL_REG, AXP_PMC_TDMSTOPCLOCK_MASK);
+ break;
+#endif
default:
break;
}
@@ -1564,6 +1586,22 @@
state = MV_TRUE;
break;
#endif
+#if defined(MV_INCLUDE_SATA)
+ case SATA_UNIT_ID:
+ if ((reg & AXP_PMC_SATASTOPCLOCK_MASK(index)) == AXP_PMC_SATASTOPCLOCK_STOP(index))
+ state = MV_FALSE;
+ else
+ state = MV_TRUE;
+ break;
+#endif
+#if defined(MV_INCLUDE_TDM)
+ case TDM_UNIT_ID:
+ if ((reg & AXP_PMC_TDMSTOPCLOCK_MASK) == AXP_PMC_TDMSTOPCLOCK_STOP)
+ state = MV_FALSE;
+ else
+ state = MV_TRUE;
+ break;
+#endif
default:
state = MV_TRUE;
break;
@@ -1614,6 +1652,166 @@
return (reg & (0x1 << REG_SDRAM_CONFIG_ECC_OFFS)) ? MV_TRUE : MV_FALSE;
}
+static const MV_U8 serdesCfg[][8] = SERDES_CFG_AXP;
+
+/*******************************************************************************
+* mvCtrlSerdesPhyConfigAxp
+*
+* DESCRIPTION:
+* Configure Serdes MUX and init PHYs connected to SERDES lines for AXP.
+*
+* INPUT:
+* None.
+*
+* OUTPUT:
+* None.
+*
+* RETURN:
+* Status
+*
+*******************************************************************************/
+MV_STATUS mvCtrlSerdesPhyConfigAxp(MV_VOID)
+{
+ MV_U32 socCtrlReg, RegX4, serdesLine0_7;
+ MV_U32 serdesLineCfg;
+ MV_U8 serdesLineNum;
+ MV_U8 pexIf;
+ MV_U8 pexUnit;
+ MV_STATUS status = MV_OK;
+ MV_U32 pexIfNum = mvCtrlPexMaxIfGet();
+ MV_U8 maxSerdesLines = 16; /* Valid for MV_78460_DEV_ID */
+ MV_BOARD_PEX_INFO *boardPexInfo = mvBoardPexInfoGet();
+
+ /* This is a mapping of the final power management clock
+ * gating control register value @ 0x18220
+ */
+ MV_U32 powermngmntctrlregmap = 0x0;
+ MV_U32 tmpcounter = 0;
+
+ /* Check if no SERDESs available - FPGA */
+ if (maxSerdesLines == 0)
+ return MV_OK;
+
+ memset(boardPexInfo, 0, sizeof(MV_BOARD_PEX_INFO));
+ socCtrlReg = MV_REG_READ(SOC_CTRL_REG);
+ RegX4 = MV_REG_READ(GEN_PURP_RES_2_REG);
+ boardPexInfo->pexUnitCfg[0].pexCfg = ((RegX4 & 0x0F) == 0x0F) ? PEX_BUS_MODE_X4 : PEX_BUS_MODE_X1;
+ boardPexInfo->pexUnitCfg[1].pexCfg = ((RegX4 & 0x0F0) == 0x0F0) ? PEX_BUS_MODE_X4 : PEX_BUS_MODE_X1;
+ boardPexInfo->pexUnitCfg[2].pexCfg = ((RegX4 & 0x0F00) == 0x0F00) ? PEX_BUS_MODE_X4 : PEX_BUS_MODE_X1;
+ boardPexInfo->pexUnitCfg[3].pexCfg = ((RegX4 & 0x0F000) == 0x0F000) ? PEX_BUS_MODE_X4 : PEX_BUS_MODE_X1;
+
+ serdesLine0_7 = MV_REG_READ(SERDES_LINE_MUX_REG_0_7);
+ /* Prepare PHY parameters for each step according to MUX selection */
+ for (pexIf = 0; pexIf < pexIfNum; pexIf++) {
+ /* For each serdes lane */
+ pexUnit = (pexIf < 9) ? (pexIf >> 2) : 3;
+ if ((socCtrlReg & (1 << pexUnit)) == 0) {
+ boardPexInfo->pexUnitCfg[pexUnit].pexCfg = PEX_BUS_DISABLED;
+ continue;
+ }
+ if (pexIf < 8) {
+ serdesLineCfg = (serdesLine0_7 >> (pexIf << 2)) & 0xF;
+ if (serdesLineCfg != serdesCfg[pexIf][SERDES_UNIT_PEX])
+ continue;
+ }
+ boardPexInfo->pexMapping[boardPexInfo->boardPexIfNum] = pexIf;
+ boardPexInfo->boardPexIfNum++;
+ boardPexInfo->pexUnitCfg[pexUnit].pexLaneStat[pexIf] = 0x1;
+ powermngmntctrlregmap = powermngmntctrlregmap | (0x1 << (pexIf + 5));
+ if (pexIf < 8) {
+ if (boardPexInfo->pexUnitCfg[pexUnit].pexCfg == PEX_BUS_MODE_X4) {
+ powermngmntctrlregmap |= (0xf << (pexIf + 5));
+ pexIf += 3;
+ } else
+ powermngmntctrlregmap |= (0x1 << (pexIf + 5));
+ } else
+ powermngmntctrlregmap |= (0x1 << (18 + pexIf));
+ }
+
+ for (serdesLineNum = 0; serdesLineNum < 8; serdesLineNum++) {
+ serdesLineCfg = (serdesLine0_7 >> (serdesLineNum << 2)) & 0xF;
+ if (serdesLineCfg == serdesCfg[serdesLineNum][SERDES_UNIT_SATA]) {
+ if ((serdesLineNum == 4) || (serdesLineNum == 6))
+ powermngmntctrlregmap |= AXP_PMC_SATASTOPCLOCK_MASK(0);
+ else if (serdesLineNum == 5)
+ powermngmntctrlregmap |= AXP_PMC_SATASTOPCLOCK_MASK(1);
+ else
+ goto err_cfg;
+
+ } else if (serdesLineCfg == serdesCfg[serdesLineNum][SERDES_UNIT_SGMII0])
+ powermngmntctrlregmap |= AXP_PMC_GESTOPCLOCK_MASK(0);
+ else if (serdesLineCfg == serdesCfg[serdesLineNum][SERDES_UNIT_SGMII1])
+ powermngmntctrlregmap |= AXP_PMC_GESTOPCLOCK_MASK(1);
+ else if (serdesLineCfg == serdesCfg[serdesLineNum][SERDES_UNIT_SGMII2])
+ powermngmntctrlregmap |= AXP_PMC_GESTOPCLOCK_MASK(2);
+ else if (serdesLineCfg == serdesCfg[serdesLineNum][SERDES_UNIT_SGMII3])
+ powermngmntctrlregmap |= AXP_PMC_GESTOPCLOCK_MASK(3);
+ else if (serdesLineCfg == serdesCfg[serdesLineNum][SERDES_UNIT_QSGMII])
+ powermngmntctrlregmap |= AXP_PMC_GESTOPCLOCK_MASK(0) |
+ AXP_PMC_GESTOPCLOCK_MASK(1) |
+ AXP_PMC_GESTOPCLOCK_MASK(2) |
+ AXP_PMC_GESTOPCLOCK_MASK(3);
+ }
+
+#if defined(MV_INCLUDE_CLK_PWR_CNTRL)
+ /* Enabling port GE0 always since we need SMI 0 to access other PHYs*/
+ powermngmntctrlregmap = powermngmntctrlregmap | BIT4;
+ /* Check if GE1 is not enabled via MPPs and not Serdes - if yes you have to enable the clock*/
+ if (MV_TRUE == mvBoardIsGbEPortConnected(1))
+ powermngmntctrlregmap = powermngmntctrlregmap | AXP_PMC_GESTOPCLOCK_MASK(1);
+
+ /* Hard core enable DDR, USB, SDIO, LCD, XOR, IDMA, CESA cause we don't support this at this momemt*/
+ powermngmntctrlregmap = powermngmntctrlregmap | (BIT0 | BIT13 | (0x1FF<<16) |
+ BIT24 | BIT25 | BIT28 | BIT31);
+ DB(mvOsPrintf("%s:Shutting down unused interfaces:\n", __func__));
+ /* Now report everything to the screen*/
+ if (!(powermngmntctrlregmap & AXP_PMC_SATASTOPCLOCK_MASK(0))) {
+ DB(mvOsPrintf("%s: SATA0\n", __func__));
+ mvCtrlPwrClckSet(SATA_UNIT_ID, 0, MV_FALSE);
+ }
+ if (!(powermngmntctrlregmap & AXP_PMC_SATASTOPCLOCK_MASK(1))) {
+ DB(mvOsPrintf("%s: SATA1\n", __func__));
+ mvCtrlPwrClckSet(SATA_UNIT_ID, 1, MV_FALSE);
+ }
+ for (tmpcounter = 0; tmpcounter < 4; tmpcounter++) {
+ if (!(powermngmntctrlregmap & (1 << (4 - tmpcounter)))) {
+ DB(mvOsPrintf("%s: GBE%d\n", __func__, tmpcounter));
+ mvCtrlPwrClckSet(ETH_GIG_UNIT_ID, tmpcounter, MV_FALSE);
+ }
+ }
+ for (tmpcounter = 0; tmpcounter < 8; tmpcounter++) {
+ if (!(powermngmntctrlregmap & (1 << (5 + tmpcounter)))) {
+ DB(mvOsPrintf("%s: PEX%d.%d\n", __func__, tmpcounter>>2, tmpcounter % 4));
+ mvCtrlPwrClckSet(PEX_UNIT_ID, tmpcounter, MV_FALSE);
+ }
+ }
+ if (!(powermngmntctrlregmap & BIT26)) {
+ DB(mvOsPrintf("%s: PEX2\n", __func__));
+ mvCtrlPwrClckSet(PEX_UNIT_ID, 8, MV_FALSE);
+ }
+ if (!(powermngmntctrlregmap & BIT27)) {
+ DB(mvOsPrintf("%s: PEX3\n", __func__));
+ mvCtrlPwrClckSet(PEX_UNIT_ID, 9, MV_FALSE);
+ }
+
+ if (!(powermngmntctrlregmap & BIT25)) {
+ DB(mvOsPrintf("%s: TDM\n", __func__));
+ mvCtrlPwrClckSet(TDM_UNIT_ID, 0, MV_FALSE);
+ }
+
+ /* Apply clock gating */
+ MV_REG_WRITE(POWER_MNG_CTRL_REG, MV_REG_READ(POWER_MNG_CTRL_REG) & powermngmntctrlregmap);
+ /* The Sata driver doesn't support clock gating at this point so we enable the logic to the block*/
+ MV_REG_WRITE(POWER_MNG_CTRL_REG, MV_REG_READ(POWER_MNG_CTRL_REG) | (BIT15 | BIT30));
+#endif /* defined(MV_INCLUDE_CLK_PWR_CNTRL) */
+
+ return status;
+err_cfg:
+ DB(mvOsPrintf("%s: Wrong CFG (%#x) for SERDES line %d.\n",
+ __func__, serdesLineCfg, serdesLineNum));
+ return MV_ERROR;
+}
+
/*******************************************************************************
* mvCtrlSerdesPhyConfig
*
diff --git a/board/mv_ebu/msys/msys_family/ctrlEnv/mvCtrlEnvLib.h b/board/mv_ebu/msys/msys_family/ctrlEnv/mvCtrlEnvLib.h
index 127e409..1e11379 100755
--- a/board/mv_ebu/msys/msys_family/ctrlEnv/mvCtrlEnvLib.h
+++ b/board/mv_ebu/msys/msys_family/ctrlEnv/mvCtrlEnvLib.h
@@ -82,6 +82,18 @@
/* typedefs */
typedef MV_STATUS(*MV_WIN_GET_FUNC_PTR)(MV_U32, MV_U32, MV_UNIT_WIN_INFO*);
+/* SERDES description - AXP only */
+typedef enum {
+ SERDES_UNIT_UNCONNECTED = 0x0,
+ SERDES_UNIT_PEX = 0x1,
+ SERDES_UNIT_SATA = 0x2,
+ SERDES_UNIT_SGMII0 = 0x3,
+ SERDES_UNIT_SGMII1 = 0x4,
+ SERDES_UNIT_SGMII2 = 0x5,
+ SERDES_UNIT_SGMII3 = 0x6,
+ SERDES_UNIT_QSGMII = 0x7,
+ SERDES_UNIT_LAST
+} MV_SERDES_UNIT_INDX;
typedef enum {
PEX_BUS_DISABLED = 0,
@@ -198,6 +210,7 @@
MV_BOOL mvCtrlIsBootFromNAND(MV_VOID);
MV_BOOL mvCtrlPwrMemGet(MV_UNIT_ID unitId, MV_U32 index);
MV_STATUS mvCtrlSerdesPhyConfig(MV_VOID);
+MV_STATUS mvCtrlSerdesPhyConfigAxp(MV_VOID);
MV_BOOL mvCtrlIsDLBEnabled(MV_VOID);
MV_U32 mvCtrlDDRBudWidth(MV_VOID);
MV_BOOL mvCtrlDDRThruXbar(MV_VOID);
diff --git a/board/mv_ebu/msys/msys_family/ctrlEnv/mvCtrlEnvRegs.h b/board/mv_ebu/msys/msys_family/ctrlEnv/mvCtrlEnvRegs.h
index 81c6358..7eea56e 100644
--- a/board/mv_ebu/msys/msys_family/ctrlEnv/mvCtrlEnvRegs.h
+++ b/board/mv_ebu/msys/msys_family/ctrlEnv/mvCtrlEnvRegs.h
@@ -228,6 +228,10 @@
/* Sample at Reset - AXP only */
#define MPP_SAMPLE_AT_RESET(id) (0x18230 + (id * 4))
+/* Controller environment and SERDERS registers - AXP only */
+#define SERDES_LINE_MUX_REG_0_7 0x18270
+#define GEN_PURP_RES_2_REG 0x182F8
+
/* Dragonite Register */
#define DRAGONITE_CTRL_REG 0x1c
#define DRAGONITE_POE_CAUSE_IRQ_REG 0x64
@@ -399,6 +403,30 @@
/*22*/ { 2, 5, 10, 5 } \
}
+/* This structure refrect registers:
+ * Serdes 0-7 selectors 0x18270
+ * and Serdes 8-15 selectors 0x18274
+ * AXP only
+ */
+
+#define SERDES_CFG_AXP { \
+ {0, 1, -1 , -1, -1, -1, -1, -1}, /* Lane 0 */ \
+ {0, 1, -1 , -1, -1, -1, -1, -1}, /* Lane 1 */ \
+ {0, 1, -1 , 2, -1, -1, -1, -1}, /* Lane 2 */ \
+ {0, 1, -1 , -1, 2, -1, -1, 3}, /* Lane 3 */ \
+ {0, 1, 2 , -1, -1, 3, -1, -1}, /* Lane 4 */ \
+ {0, 1, 2 , -1, 3, -1, -1, 4}, /* Lane 5 */ \
+ {0, 1, 2 , 4, -1, 3, -1, -1}, /* Lane 6 */ \
+ {0, 1, -1 , 2, -1, -1, 3, -1}, /* Lane 7 */ \
+ {0, 1, -1 , -1, -1, -1, -1, -1}, /* Lane 8 */ \
+ {0, 1, -1 , -1, -1, -1, -1, -1}, /* Lane 9 */ \
+ {0, 1, -1 , -1, -1, -1, -1, -1}, /* Lane 10 */ \
+ {0, 1, -1 , -1, -1, -1, -1, -1}, /* Lane 11 */ \
+ {0, 1, -1 , -1, -1, -1, -1, -1}, /* Lane 12 */ \
+ {0, 1, -1 , -1, -1, -1, -1, -1}, /* Lane 13 */ \
+ {0, 1, -1 , -1, -1, -1, -1, -1}, /* Lane 14 */ \
+ {0, 1, -1 , -1, -1, -1, -1, -1} /* Lane 15 */ \
+}
/* These macros help units to identify a target Mport Arbiter group */
#define MV_TARGET_IS_DRAM(target) \
((target >= SDRAM_CS0) && (target <= SDRAM_CS3))
diff --git a/board/mv_ebu/msys/msys_family/ctrlEnv/mvCtrlEnvSpec.h b/board/mv_ebu/msys/msys_family/ctrlEnv/mvCtrlEnvSpec.h
index 9ace2ff..82c91ba 100755
--- a/board/mv_ebu/msys/msys_family/ctrlEnv/mvCtrlEnvSpec.h
+++ b/board/mv_ebu/msys/msys_family/ctrlEnv/mvCtrlEnvSpec.h
@@ -178,10 +178,8 @@
#endif
/* This define describes the maximum number of supported PEX Interfaces */
-#define MV_PEX_MAX_IF 1
-#define MV_PEX_MAX_UNIT 1
-#define MV_PEX_MAX_IF_AXP 10
-#define MV_PEX_MAX_UNIT_AXP 4
+#define MV_PEX_MAX_IF 10 /* 1 for MSYS */
+#define MV_PEX_MAX_UNIT 4 /* 1 for MSYS */
#ifdef MV_INCLUDE_PEX
#define MV_INCLUDE_PEX0
#define MV_DISABLE_PEX_DEVICE_BAR