bin_hdr: a38x: add SERDES PCIe By 4 support
Change-Id: I9b26a5174c66c205acb0cf43971df389d1dd424b
Signed-off-by: Neta Zur <neta@marvell.com>
Reviewed-on: http://vgitil04.il.marvell.com:8080/5224
Tested-by: Star_Automation <star@marvell.com>
Reviewed-by: Omri Itach <omrii@marvell.com>
Reviewed-by: Eli Nidam <elini@marvell.com>
Reviewed-by: Nadav Haklai <nadavh@marvell.com>
diff --git a/tools/marvell/bin_hdr/src_phy_a38x/mvBHboardEnvSpec.c b/tools/marvell/bin_hdr/src_phy_a38x/mvBHboardEnvSpec.c
index 4d3e697..04f6a68 100644
--- a/tools/marvell/bin_hdr/src_phy_a38x/mvBHboardEnvSpec.c
+++ b/tools/marvell/bin_hdr/src_phy_a38x/mvBHboardEnvSpec.c
@@ -171,9 +171,9 @@
SERDES_MAP DbConfigSLM1363_D[MAX_SERDES_LANES] =
{
{ PEX0, __5Gbps, PEX_ROOT_COMPLEX_x4 },
- { DEFAULT_SERDES, LAST_SERDES_SPEED, SERDES_DEFAULT_MODE },
- { DEFAULT_SERDES, LAST_SERDES_SPEED, SERDES_DEFAULT_MODE },
- { DEFAULT_SERDES, LAST_SERDES_SPEED, SERDES_DEFAULT_MODE },
+ { PEX1, __5Gbps, PEX_ROOT_COMPLEX_x4 },
+ { PEX2, __5Gbps, PEX_ROOT_COMPLEX_x4 },
+ { PEX3, __5Gbps, PEX_ROOT_COMPLEX_x4 },
{ SATA1, __3Gbps, SERDES_DEFAULT_MODE },
{ SATA2, __3Gbps, SERDES_DEFAULT_MODE }
};
diff --git a/tools/marvell/bin_hdr/src_phy_a38x/mvCtrlPex.c b/tools/marvell/bin_hdr/src_phy_a38x/mvCtrlPex.c
index 11d8d6c..6935d64 100644
--- a/tools/marvell/bin_hdr/src_phy_a38x/mvCtrlPex.c
+++ b/tools/marvell/bin_hdr/src_phy_a38x/mvCtrlPex.c
@@ -189,6 +189,14 @@
if ((serdesType != PEX0) && (serdesType != PEX1) && (serdesType != PEX2) && (serdesType != PEX3))
continue;
+ if ((serdesType != PEX0) &&
+ ((serdesMap[serdesIdx].serdesMode == PEX_ROOT_COMPLEX_x4) ||
+ (serdesMap[serdesIdx].serdesMode == PEX_END_POINT_x4)))
+ {
+ /* for PEX by4 - relevant for the first port only */
+ continue;
+ }
+
pexIdx = serdesType - PEX0;
tmp = MV_REG_READ(PEX_CAPABILITIES_REG(pexIdx));
tmp &= ~(0xf << 20);
@@ -201,6 +209,13 @@
for (serdesIdx = 0; serdesIdx < MAX_SERDES_LANES; serdesIdx++) {
serdesType = serdesMap[serdesIdx].serdesType;
+ if ((serdesType != PEX0) &&
+ ((serdesMap[serdesIdx].serdesMode == PEX_ROOT_COMPLEX_x4) ||
+ (serdesMap[serdesIdx].serdesMode == PEX_END_POINT_x4)))
+ {
+ /* for PEX by4 - relevant for the first port only */
+ continue;
+ }
switch (serdesType) {
case PEX0:
tmp |= 0x1 << PCIE0_ENABLE_OFFS;
@@ -241,6 +256,14 @@
if ((serdesType != PEX0) && (serdesType != PEX1) && (serdesType != PEX2) && (serdesType != PEX3))
continue;
+ if ((serdesType != PEX0) &&
+ ((serdesMap[serdesIdx].serdesMode == PEX_ROOT_COMPLEX_x4) ||
+ (serdesMap[serdesIdx].serdesMode == PEX_END_POINT_x4)))
+ {
+ /* for PEX by4 - relevant for the first port only */
+ continue;
+ }
+
pexIdx = serdesType - PEX0;
tmp = MV_REG_READ(PEX_DBG_STATUS_REG(pexIdx));
@@ -312,6 +335,14 @@
if ((serdesType != PEX0) && (serdesType != PEX1) && (serdesType != PEX2) && (serdesType != PEX3))
continue;
+ if ((serdesType != PEX0) &&
+ ((serdesMap[serdesIdx].serdesMode == PEX_ROOT_COMPLEX_x4) ||
+ (serdesMap[serdesIdx].serdesMode == PEX_END_POINT_x4)))
+ {
+ /* for PEX by4 - relevant for the first port only */
+ continue;
+ }
+
pexIdx = serdesType - PEX0;
devId = MV_REG_READ(PEX_CFG_DIRECT_ACCESS(pexIdx, PEX_DEVICE_AND_VENDOR_ID));
devId &= 0xFFFF;
diff --git a/tools/marvell/bin_hdr/src_phy_a38x/mvHighSpeedEnvLib.c b/tools/marvell/bin_hdr/src_phy_a38x/mvHighSpeedEnvLib.c
index a4ac66c..7ffa3dc 100644
--- a/tools/marvell/bin_hdr/src_phy_a38x/mvHighSpeedEnvLib.c
+++ b/tools/marvell/bin_hdr/src_phy_a38x/mvHighSpeedEnvLib.c
@@ -243,6 +243,13 @@
{ 0x0, 0x0, 0x0, { 0x0, 0x0 }, 10, 0 } /* 10ms delay */
};
+/* PEX by 4 config seq */
+MV_OP_PARAMS pexBy4ConfigParams[] =
+{
+ /* unitunitBaseReg unitOffset mask data waitTime numOfLoops */
+ { 0xa0710, 0x800, 0x7, { 0x5, 0x0, 0x0, 0x2 }, 0, 0}
+};
+
/* USB3 device donfig seq */
MV_OP_PARAMS usb3DeviceConfigParams[] =
{
@@ -373,6 +380,11 @@
serdesSeqDb[PEX_TX_CONFIG_SEQ].cfgSeqSize = sizeof(pexAndUsb3TxConfigParams) / sizeof(MV_OP_PARAMS);
serdesSeqDb[PEX_TX_CONFIG_SEQ].dataArrIdx = PEX;
+ /* PEX_BY_4_CONFIG_SEQ sequence init */
+ serdesSeqDb[PEX_BY_4_CONFIG_SEQ].opParamsPtr = pexBy4ConfigParams;
+ serdesSeqDb[PEX_BY_4_CONFIG_SEQ].cfgSeqSize = sizeof(pexBy4ConfigParams) / sizeof(MV_OP_PARAMS);
+ serdesSeqDb[PEX_BY_4_CONFIG_SEQ].dataArrIdx = PEX;
+
/* USB3_POWER_UP_SEQ sequence init */
serdesSeqDb[USB3_POWER_UP_SEQ].opParamsPtr = pexAndUsb3PowerUpParams;
serdesSeqDb[USB3_POWER_UP_SEQ].cfgSeqSize = sizeof(pexAndUsb3PowerUpParams) / sizeof(MV_OP_PARAMS);
@@ -571,6 +583,7 @@
REF_CLOCK refClock;
SERDES_TYPE serdesType;
SERDES_SPEED serdesSpeed;
+ SERDES_MODE serdesMode;
DEBUG_INIT_FULL_S("\n### powerUpSerdesLanes ###\n");
@@ -586,6 +599,7 @@
serdesType = serdesConfigMap[serdesLaneNum].serdesType;
serdesSpeed = serdesConfigMap[serdesLaneNum].serdesSpeed;
+ serdesMode = serdesConfigMap[serdesLaneNum].serdesMode;
/* serdes lane is not in use */
if (serdesType == DEFAULT_SERDES)
@@ -600,6 +614,7 @@
MV_TRUE,
serdesType,
serdesSpeed,
+ serdesMode,
refClock));
}
@@ -631,6 +646,7 @@
MV_BOOL serdesPowerUp,
SERDES_TYPE serdesType,
SERDES_SPEED baudRate,
+ SERDES_MODE serdesMode,
REF_CLOCK refClock
)
{
@@ -640,6 +656,7 @@
int sataIdx, pexIdx;
SERDES_SEQ speedSeqId;
MV_U32 regData;
+ MV_BOOL isPexBy1;
DEBUG_INIT_FULL_S("\n### mvSerdesPowerUpCtrl ###\n");
@@ -663,28 +680,51 @@
case PEX1:
case PEX2:
case PEX3:
- regData = MV_REG_READ(SOC_CONTROL_REG1);
- regData |= 0x4000;
- MV_REG_WRITE(SOC_CONTROL_REG1, regData);
+ isPexBy1 = (serdesMode == PEX_ROOT_COMPLEX_x1) ||
+ (serdesMode == PEX_ROOT_COMPLEX_x1);
pexIdx = serdesType - PEX0;
- regData = MV_REG_READ(((MV_PEX_IF_REGS_BASE(pexIdx)) + 0x6c));
- regData &= ~0x3F0;
- regData |= 0x10;
- MV_REG_WRITE(((MV_PEX_IF_REGS_BASE(pexIdx)) + 0x6c), regData);
+ if ((isPexBy1 == MV_TRUE) || (serdesType == PEX0))
+ {
+ /* For PEX by 4, init only the PEX 0 */
+ regData = MV_REG_READ(SOC_CONTROL_REG1);
+ if (isPexBy1 == MV_TRUE) {
+ regData |= 0x4000;
+ }
+ else{
+ regData &= ~0x4000;
+ }
+ MV_REG_WRITE(SOC_CONTROL_REG1, regData);
- regData = MV_REG_READ(((MV_PEX_IF_REGS_BASE(pexIdx)) + 0x6c));
- regData &= ~0xF;
- regData |= 0x2;
- MV_REG_WRITE(((MV_PEX_IF_REGS_BASE(pexIdx)) + 0x6c), regData);
+ regData = MV_REG_READ(((MV_PEX_IF_REGS_BASE(pexIdx)) + 0x6c));
+ regData &= ~0x3F0;
+ if (isPexBy1 == MV_TRUE) {
+ regData |= 0x10;
+ }
+ else {
+ regData |= 0x40;
+ }
+ MV_REG_WRITE(((MV_PEX_IF_REGS_BASE(pexIdx)) + 0x6c), regData);
- regData = MV_REG_READ(((MV_PEX_IF_REGS_BASE(pexIdx)) + 0x70));
- regData &= ~0x40;
- regData |= 0x40;
- MV_REG_WRITE(((MV_PEX_IF_REGS_BASE(pexIdx)) + 0x70), regData);
+ regData = MV_REG_READ(((MV_PEX_IF_REGS_BASE(pexIdx)) + 0x6c));
+ regData &= ~0xF;
+ regData |= 0x2;
+ MV_REG_WRITE(((MV_PEX_IF_REGS_BASE(pexIdx)) + 0x6c), regData);
+
+ regData = MV_REG_READ(((MV_PEX_IF_REGS_BASE(pexIdx)) + 0x70));
+ regData &= ~0x40;
+ regData |= 0x40;
+ MV_REG_WRITE(((MV_PEX_IF_REGS_BASE(pexIdx)) + 0x70), regData);
+ }
CHECK_STATUS(mvSeqExec(serdesNum, PEX_POWER_UP_SEQ));
+ if (isPexBy1 == MV_FALSE) {
+ /* for PEX by 4 - use the PEX index as the seq array index */
+ serdesSeqDb[PEX_BY_4_CONFIG_SEQ].dataArrIdx = pexIdx;
+ CHECK_STATUS(mvSeqExec(serdesNum, PEX_BY_4_CONFIG_SEQ));
+ }
+
CHECK_STATUS(mvHwsRefClockSet(serdesNum, serdesType, refClock));
CHECK_STATUS(mvSeqExec(serdesNum, speedSeqId));
CHECK_STATUS(mvSeqExec(serdesNum, PEX_TX_CONFIG_SEQ));
@@ -858,12 +898,18 @@
return MV_BAD_PARAM;
}
+ /* Checking if the board topology configuration includes PEXx4 - for the next step */
+ if ((serdesMode == PEX_END_POINT_x4) || (serdesMode == PEX_ROOT_COMPLEX_x4)) {
+ if (serdesType == PEX0) {
+ isPEXx4 = MV_TRUE;
+ } else {
+ /* update lane data to the 3 next SERDES lanes */
+ laneData = 2;
+ }
+ }
+
/* Updating the data that will be written to COMMON_PHYS_SELECTORS_REG */
regData |= (laneData << (3 * serdesIdx));
-
- /* Checking if the board topology configuration includes PEXx4 - for the next step */
- if ((serdesMode == PEX_END_POINT_x4) || (serdesMode == PEX_ROOT_COMPLEX_x4))
- isPEXx4 = MV_TRUE;
}
/* Updating the 18th bit in the COMMON PHYS SELECTORS register in case there is PEXx4 */
diff --git a/tools/marvell/bin_hdr/src_phy_a38x/mvHighSpeedEnvSpec.h b/tools/marvell/bin_hdr/src_phy_a38x/mvHighSpeedEnvSpec.h
index b96a1f3..df4a7f6 100644
--- a/tools/marvell/bin_hdr/src_phy_a38x/mvHighSpeedEnvSpec.h
+++ b/tools/marvell/bin_hdr/src_phy_a38x/mvHighSpeedEnvSpec.h
@@ -168,6 +168,7 @@
PEX__2_5_SPEED_CONFIG_SEQ,
PEX__5_SPEED_CONFIG_SEQ,
PEX_TX_CONFIG_SEQ,
+ PEX_BY_4_CONFIG_SEQ,
USB3_POWER_UP_SEQ,
USB3__HOST_SPEED_CONFIG_SEQ,
@@ -337,6 +338,7 @@
* serdesType - PEX, SATA, SGMII
* or USB3 (host or device)
* baudRate - serdes speed
+ * serdesMode - serdes mode
* refClock - ref clock (25 or 100)
* OUTPUT: None.
* RETURNS: MV_OK - for success
@@ -345,6 +347,7 @@
MV_BOOL serdesPowerUp,
SERDES_TYPE serdesType,
SERDES_SPEED baudRate,
+ SERDES_MODE serdesMode,
REF_CLOCK refClock);
#endif /* _MV_HIGHSPEED_ENV_SPEC_H */