diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.h b/drivers/gpu/nvgpu/gk20a/gk20a.h index 2dc627166..8b7315f65 100644 --- a/drivers/gpu/nvgpu/gk20a/gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/gk20a.h @@ -1201,6 +1201,7 @@ struct gpu_ops { int (*minion_data_ready_en)(struct gk20a *g, unsigned long link_mask, bool sync); void (*get_connected_link_mask)(u32 *link_mask); + void (*set_sw_war)(struct gk20a *g, u32 link_id); /* API */ int (*link_early_init)(struct gk20a *g, unsigned long mask); u32 (*link_get_mode)(struct gk20a *g, u32 link_id); diff --git a/drivers/gpu/nvgpu/gv100/hal_gv100.c b/drivers/gpu/nvgpu/gv100/hal_gv100.c index 929004214..b3d97f890 100644 --- a/drivers/gpu/nvgpu/gv100/hal_gv100.c +++ b/drivers/gpu/nvgpu/gv100/hal_gv100.c @@ -844,6 +844,7 @@ static const struct gpu_ops gv100_ops = { .setup_pll = gv100_nvlink_setup_pll, .minion_data_ready_en = gv100_nvlink_minion_data_ready_en, .get_connected_link_mask = gv100_nvlink_get_connected_link_mask, + .set_sw_war = gv100_nvlink_set_sw_war, /* API */ .link_early_init = gv100_nvlink_link_early_init, .link_get_state = gv100_nvlink_link_get_state, diff --git a/drivers/gpu/nvgpu/gv100/nvlink_gv100.c b/drivers/gpu/nvgpu/gv100/nvlink_gv100.c index e85b5a935..c328dd701 100644 --- a/drivers/gpu/nvgpu/gv100/nvlink_gv100.c +++ b/drivers/gpu/nvgpu/gv100/nvlink_gv100.c @@ -1625,23 +1625,28 @@ static int gv100_nvlink_enable_links_pre_top(struct gk20a *g, u32 links) 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) { u32 link_id; unsigned long enabled_links = (links & g->nvlink.enabled_links) & ~g->nvlink.initialized_links; - u32 reg; for_each_set_bit(link_id, &enabled_links, 32) { - - /* 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); - + if (g->ops.nvlink.set_sw_war) + g->ops.nvlink.set_sw_war(g, link_id); gv100_nvlink_initialize_tlc(g, link_id); gv100_nvlink_initialize_nvlipt(g, link_id); gv100_nvlink_enable_link_intr(g, link_id, true); diff --git a/drivers/gpu/nvgpu/gv100/nvlink_gv100.h b/drivers/gpu/nvgpu/gv100/nvlink_gv100.h index d9a4b073f..6310af28f 100644 --- a/drivers/gpu/nvgpu/gv100/nvlink_gv100.h +++ b/drivers/gpu/nvgpu/gv100/nvlink_gv100.h @@ -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, unsigned long link_mask, bool sync); void gv100_nvlink_get_connected_link_mask(u32 *link_mask); +void gv100_nvlink_set_sw_war(struct gk20a *g, u32 link_id); /* API */ int gv100_nvlink_link_early_init(struct gk20a *g, unsigned long mask); u32 gv100_nvlink_link_get_mode(struct gk20a *g, u32 link_id);