osi: core: xpcs: modify lane bringup sequence

Issue: there is a PHY reset(RX_PCS_PHY_RDY) programming
in Rx sequence that was disabling the Tx path from MGBE PCS

Fix: Control entire programming sequence from SW and
by pass HW FSM

Bug 3359851
Bug 200765222

Change-Id: Iffd00d1dff00204e36eb3a14b19c07dcd3a502b8
Signed-off-by: Narayan Reddy <narayanr@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/c/kernel/nvethernetrm/+/2584394
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
Reviewed-by: Bhadram Varka <vbhadram@nvidia.com>
Reviewed-by: Srinivas Ramachandran <srinivasra@nvidia.com>
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
GVS: Gerrit_Virtual_Submit
This commit is contained in:
Narayan Reddy
2021-08-20 03:05:35 +05:30
committed by Bhadram Varka
parent fcbf3cf7e2
commit baf06e1083
2 changed files with 125 additions and 8 deletions

View File

@@ -299,6 +299,13 @@ static nve32_t xpcs_check_pcs_lock_status(struct osi_core_priv_data *osi_core)
*/
static nve32_t xpcs_lane_bring_up(struct osi_core_priv_data *osi_core)
{
unsigned int retry = 1000;
unsigned int count;
int cond;
nveu32_t cnt = 0;
nveu32_t val = 0;
#define PCS_RETRY_MAX 300
if (xpcs_uphy_lane_bring_up(osi_core,
XPCS_WRAP_UPHY_HW_INIT_CTRL_TX_EN) < 0) {
OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_HW_FAIL,
@@ -306,16 +313,115 @@ static nve32_t xpcs_lane_bring_up(struct osi_core_priv_data *osi_core)
return -1;
}
if (xpcs_uphy_lane_bring_up(osi_core,
XPCS_WRAP_UPHY_HW_INIT_CTRL_RX_EN) < 0) {
OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_HW_FAIL,
"UPHY RX lane bring-up failed\n", 0ULL);
val = osi_readla(osi_core,
(nveu8_t *)osi_core->xpcs_base +
XPCS_WRAP_UPHY_RX_CONTROL_0_0);
/* Step1 RX_SW_OVRD */
val |= XPCS_WRAP_UPHY_RX_CONTROL_0_0_RX_SW_OVRD;
osi_writela(osi_core, val,
(nveu8_t *)osi_core->xpcs_base +
XPCS_WRAP_UPHY_RX_CONTROL_0_0);
val = osi_readla(osi_core,
(nveu8_t *)osi_core->xpcs_base +
XPCS_WRAP_UPHY_RX_CONTROL_0_0);
/* Step2 RX_IDDQ */
val &= ~(XPCS_WRAP_UPHY_RX_CONTROL_0_0_RX_IDDQ);
osi_writela(osi_core, val,
(nveu8_t *)osi_core->xpcs_base +
XPCS_WRAP_UPHY_RX_CONTROL_0_0);
val = osi_readla(osi_core,
(nveu8_t *)osi_core->xpcs_base +
XPCS_WRAP_UPHY_RX_CONTROL_0_0);
/* Step2 AUX_RX_IDDQ */
val &= ~(XPCS_WRAP_UPHY_RX_CONTROL_0_0_AUX_RX_IDDQ);
osi_writela(osi_core, val,
(nveu8_t *)osi_core->xpcs_base +
XPCS_WRAP_UPHY_RX_CONTROL_0_0);
val = osi_readla(osi_core,
(nveu8_t *)osi_core->xpcs_base +
XPCS_WRAP_UPHY_RX_CONTROL_0_0);
/* Step3 RX_SLEEP */
val &= ~(XPCS_WRAP_UPHY_RX_CONTROL_0_0_RX_SLEEP);
osi_writela(osi_core, val,
(nveu8_t *)osi_core->xpcs_base +
XPCS_WRAP_UPHY_RX_CONTROL_0_0);
val = osi_readla(osi_core,
(nveu8_t *)osi_core->xpcs_base +
XPCS_WRAP_UPHY_RX_CONTROL_0_0);
/* Step4 RX_CAL_EN */
val |= XPCS_WRAP_UPHY_RX_CONTROL_0_0_RX_CAL_EN;
osi_writela(osi_core, val,
(nveu8_t *)osi_core->xpcs_base +
XPCS_WRAP_UPHY_RX_CONTROL_0_0);
/* Step5 poll for Rx cal enable */
cond = COND_NOT_MET;
count = 0;
while (cond == COND_NOT_MET) {
if (count > retry) {
return -1;
}
count++;
val = osi_readla(osi_core,
(nveu8_t *)osi_core->xpcs_base +
XPCS_WRAP_UPHY_RX_CONTROL_0_0);
if ((val & XPCS_WRAP_UPHY_RX_CONTROL_0_0_RX_CAL_EN) == 0) {
cond = COND_MET;
} else {
osi_core->osd_ops.udelay(1000U);
}
}
/* Step6 RX_DATA_EN */
val = osi_readla(osi_core, (nveu8_t *)osi_core->xpcs_base +
XPCS_WRAP_UPHY_RX_CONTROL_0_0);
val |= XPCS_WRAP_UPHY_RX_CONTROL_0_0_RX_DATA_EN;
osi_writela(osi_core, val, (nveu8_t *)osi_core->xpcs_base +
XPCS_WRAP_UPHY_RX_CONTROL_0_0);
while (cnt < PCS_RETRY_MAX) {
/* Step7 RX_CDR_RESET */
val = osi_readla(osi_core, (nveu8_t *)osi_core->xpcs_base +
XPCS_WRAP_UPHY_RX_CONTROL_0_0);
val |= XPCS_WRAP_UPHY_RX_CONTROL_0_0_RX_CDR_RESET;
osi_writela(osi_core, val, (nveu8_t *)osi_core->xpcs_base +
XPCS_WRAP_UPHY_RX_CONTROL_0_0);
/* Step8 RX_CDR_RESET */
val = osi_readla(osi_core, (nveu8_t *)osi_core->xpcs_base +
XPCS_WRAP_UPHY_RX_CONTROL_0_0);
val &= ~(XPCS_WRAP_UPHY_RX_CONTROL_0_0_RX_CDR_RESET);
osi_writela(osi_core, val, (nveu8_t *)osi_core->xpcs_base +
XPCS_WRAP_UPHY_RX_CONTROL_0_0);
val = osi_readla(osi_core, (nveu8_t *)osi_core->xpcs_base +
XPCS_WRAP_UPHY_RX_CONTROL_0_0);
/* Step9 RX_PCS_PHY_RDY */
val |= XPCS_WRAP_UPHY_RX_CONTROL_0_0_RX_PCS_PHY_RDY;
osi_writela(osi_core, val, (nveu8_t *)osi_core->xpcs_base +
XPCS_WRAP_UPHY_RX_CONTROL_0_0);
if (xpcs_check_pcs_lock_status(osi_core) < 0) {
cnt += 1;
osi_core->osd_ops.udelay(1000U);
} else {
OSI_CORE_INFO(OSI_NULL, OSI_LOG_ARG_HW_FAIL,
"PCS block lock SUCCESS\n", 0ULL);
break;
}
}
if (cnt == PCS_RETRY_MAX) {
OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_HW_FAIL,
"PCS block lock not achieved\n", 0ULL);
"Failed to get PCS block lock after max retries\n",
cnt);
return -1;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020, NVIDIA CORPORATION. All rights reserved.
* Copyright (c) 2021, NVIDIA CORPORATION. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -55,6 +55,7 @@
#define XPCS_VR_XS_PCS_EEE_MCTRL0 0xE00018
#define XPCS_WRAP_UPHY_HW_INIT_CTRL 0x8020
#define XPCS_WRAP_IRQ_STATUS 0x8050
#define XPCS_WRAP_UPHY_RX_CONTROL_0_0 0x801C
/** @} */
@@ -93,6 +94,16 @@
#define XPCS_WRAP_UPHY_HW_INIT_CTRL_TX_EN OSI_BIT(0)
#define XPCS_WRAP_UPHY_HW_INIT_CTRL_RX_EN OSI_BIT(2)
#define XPCS_WRAP_IRQ_STATUS_PCS_LINK_STS OSI_BIT(6)
#define XPCS_WRAP_UPHY_RX_CONTROL_0_0_RX_DATA_EN OSI_BIT(0)
#define XPCS_WRAP_UPHY_RX_CONTROL_0_0_RX_IDDQ OSI_BIT(4)
#define XPCS_WRAP_UPHY_RX_CONTROL_0_0_AUX_RX_IDDQ OSI_BIT(5)
#define XPCS_WRAP_UPHY_RX_CONTROL_0_0_RX_SLEEP (OSI_BIT(6) | \
OSI_BIT(7))
#define XPCS_WRAP_UPHY_RX_CONTROL_0_0_RX_CAL_EN OSI_BIT(8)
#define XPCS_WRAP_UPHY_RX_CONTROL_0_0_RX_CDR_RESET OSI_BIT(9)
#define XPCS_WRAP_UPHY_RX_CONTROL_0_0_RX_PCS_PHY_RDY OSI_BIT(10)
#define XPCS_WRAP_UPHY_RX_CONTROL_0_0_RX_SW_OVRD OSI_BIT(31)
/** @} */
int xpcs_init(struct osi_core_priv_data *osi_core);