mirror of
git://nv-tegra.nvidia.com/linux-nvgpu.git
synced 2025-12-23 18:16:01 +03:00
gpu: nvgpu: nvlink: Add HAL for SW WAR
Workaround of setting SAFE_CTR_INIT on NVLINK (WAR for Bug 1888034) is needed only on nvlink 2.0. Add HAL to avoid running the WAR on future chips. Bug 2006692 Change-Id: I85fb90ea5ce7b848946f2c362e7a952787cc1261 Signed-off-by: Tejal Kudav <tkudav@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/1738401 Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
This commit is contained in:
@@ -1201,6 +1201,7 @@ struct gpu_ops {
|
|||||||
int (*minion_data_ready_en)(struct gk20a *g,
|
int (*minion_data_ready_en)(struct gk20a *g,
|
||||||
unsigned long link_mask, bool sync);
|
unsigned long link_mask, bool sync);
|
||||||
void (*get_connected_link_mask)(u32 *link_mask);
|
void (*get_connected_link_mask)(u32 *link_mask);
|
||||||
|
void (*set_sw_war)(struct gk20a *g, u32 link_id);
|
||||||
/* API */
|
/* API */
|
||||||
int (*link_early_init)(struct gk20a *g, unsigned long mask);
|
int (*link_early_init)(struct gk20a *g, unsigned long mask);
|
||||||
u32 (*link_get_mode)(struct gk20a *g, u32 link_id);
|
u32 (*link_get_mode)(struct gk20a *g, u32 link_id);
|
||||||
|
|||||||
@@ -844,6 +844,7 @@ static const struct gpu_ops gv100_ops = {
|
|||||||
.setup_pll = gv100_nvlink_setup_pll,
|
.setup_pll = gv100_nvlink_setup_pll,
|
||||||
.minion_data_ready_en = gv100_nvlink_minion_data_ready_en,
|
.minion_data_ready_en = gv100_nvlink_minion_data_ready_en,
|
||||||
.get_connected_link_mask = gv100_nvlink_get_connected_link_mask,
|
.get_connected_link_mask = gv100_nvlink_get_connected_link_mask,
|
||||||
|
.set_sw_war = gv100_nvlink_set_sw_war,
|
||||||
/* API */
|
/* API */
|
||||||
.link_early_init = gv100_nvlink_link_early_init,
|
.link_early_init = gv100_nvlink_link_early_init,
|
||||||
.link_get_state = gv100_nvlink_link_get_state,
|
.link_get_state = gv100_nvlink_link_get_state,
|
||||||
|
|||||||
@@ -1625,23 +1625,28 @@ static int gv100_nvlink_enable_links_pre_top(struct gk20a *g, u32 links)
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void gv100_nvlink_set_sw_war(struct gk20a *g, u32 link_id)
|
||||||
|
{
|
||||||
|
u32 reg;
|
||||||
|
|
||||||
|
/* WAR for HW bug 1888034 */
|
||||||
|
reg = DLPL_REG_RD32(g, link_id, nvl_sl0_safe_ctrl2_tx_r());
|
||||||
|
reg = set_field(reg, nvl_sl0_safe_ctrl2_tx_ctr_init_m(),
|
||||||
|
nvl_sl0_safe_ctrl2_tx_ctr_init_init_f());
|
||||||
|
reg = set_field(reg, nvl_sl0_safe_ctrl2_tx_ctr_initscl_m(),
|
||||||
|
nvl_sl0_safe_ctrl2_tx_ctr_initscl_init_f());
|
||||||
|
DLPL_REG_WR32(g, link_id, nvl_sl0_safe_ctrl2_tx_r(), reg);
|
||||||
|
}
|
||||||
|
|
||||||
static int gv100_nvlink_enable_links_post_top(struct gk20a *g, u32 links)
|
static int gv100_nvlink_enable_links_post_top(struct gk20a *g, u32 links)
|
||||||
{
|
{
|
||||||
u32 link_id;
|
u32 link_id;
|
||||||
unsigned long enabled_links = (links & g->nvlink.enabled_links) &
|
unsigned long enabled_links = (links & g->nvlink.enabled_links) &
|
||||||
~g->nvlink.initialized_links;
|
~g->nvlink.initialized_links;
|
||||||
u32 reg;
|
|
||||||
|
|
||||||
for_each_set_bit(link_id, &enabled_links, 32) {
|
for_each_set_bit(link_id, &enabled_links, 32) {
|
||||||
|
if (g->ops.nvlink.set_sw_war)
|
||||||
/* WAR for HW bug 1888034 */
|
g->ops.nvlink.set_sw_war(g, link_id);
|
||||||
reg = DLPL_REG_RD32(g, link_id, nvl_sl0_safe_ctrl2_tx_r());
|
|
||||||
reg = set_field(reg, nvl_sl0_safe_ctrl2_tx_ctr_init_m(),
|
|
||||||
nvl_sl0_safe_ctrl2_tx_ctr_init_init_f());
|
|
||||||
reg = set_field(reg, nvl_sl0_safe_ctrl2_tx_ctr_initscl_m(),
|
|
||||||
nvl_sl0_safe_ctrl2_tx_ctr_initscl_init_f());
|
|
||||||
DLPL_REG_WR32(g, link_id, nvl_sl0_safe_ctrl2_tx_r(), reg);
|
|
||||||
|
|
||||||
gv100_nvlink_initialize_tlc(g, link_id);
|
gv100_nvlink_initialize_tlc(g, link_id);
|
||||||
gv100_nvlink_initialize_nvlipt(g, link_id);
|
gv100_nvlink_initialize_nvlipt(g, link_id);
|
||||||
gv100_nvlink_enable_link_intr(g, link_id, true);
|
gv100_nvlink_enable_link_intr(g, link_id, true);
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ int gv100_nvlink_setup_pll(struct gk20a *g, unsigned long link_mask);
|
|||||||
int gv100_nvlink_minion_data_ready_en(struct gk20a *g,
|
int gv100_nvlink_minion_data_ready_en(struct gk20a *g,
|
||||||
unsigned long link_mask, bool sync);
|
unsigned long link_mask, bool sync);
|
||||||
void gv100_nvlink_get_connected_link_mask(u32 *link_mask);
|
void gv100_nvlink_get_connected_link_mask(u32 *link_mask);
|
||||||
|
void gv100_nvlink_set_sw_war(struct gk20a *g, u32 link_id);
|
||||||
/* API */
|
/* API */
|
||||||
int gv100_nvlink_link_early_init(struct gk20a *g, unsigned long mask);
|
int gv100_nvlink_link_early_init(struct gk20a *g, unsigned long mask);
|
||||||
u32 gv100_nvlink_link_get_mode(struct gk20a *g, u32 link_id);
|
u32 gv100_nvlink_link_get_mode(struct gk20a *g, u32 link_id);
|
||||||
|
|||||||
Reference in New Issue
Block a user