diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.h b/drivers/gpu/nvgpu/gk20a/gk20a.h index 75c6ef897..4333cd20d 100644 --- a/drivers/gpu/nvgpu/gk20a/gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/gk20a.h @@ -61,6 +61,9 @@ enum gk20a_cbc_op { gk20a_cbc_op_invalidate, }; +#define MC_INTR_UNIT_DISABLE false +#define MC_INTR_UNIT_ENABLE true + struct gpu_ops { struct { int (*determine_L2_size_bytes)(struct gk20a *gk20a); @@ -360,10 +363,13 @@ struct gpu_ops { } regops; struct { void (*intr_enable)(struct gk20a *g); + void (*intr_unit_config)(struct gk20a *g, + bool enable, bool is_stalling, u32 unit); irqreturn_t (*isr_stall)(struct gk20a *g); irqreturn_t (*isr_nonstall)(struct gk20a *g); irqreturn_t (*isr_thread_stall)(struct gk20a *g); irqreturn_t (*isr_thread_nonstall)(struct gk20a *g); + u32 intr_mask_restore[4]; } mc; }; diff --git a/drivers/gpu/nvgpu/gk20a/mc_gk20a.c b/drivers/gpu/nvgpu/gk20a/mc_gk20a.c index 4d1764035..899eeff7a 100644 --- a/drivers/gpu/nvgpu/gk20a/mc_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/mc_gk20a.c @@ -137,9 +137,27 @@ void mc_gk20a_intr_enable(struct gk20a *g) mc_intr_en_0_inta_hardware_f()); } +void mc_gk20a_intr_unit_config(struct gk20a *g, bool enable, + bool is_stalling, u32 mask) +{ + u32 mask_reg = (is_stalling ? mc_intr_mask_0_r() : + mc_intr_mask_1_r()); + + if (enable) { + gk20a_writel(g, mask_reg, + gk20a_readl(g, mask_reg) | + mask); + } else { + gk20a_writel(g, mask_reg, + gk20a_readl(g, mask_reg) & + ~mask); + } +} + void gk20a_init_mc(struct gpu_ops *gops) { gops->mc.intr_enable = mc_gk20a_intr_enable; + gops->mc.intr_unit_config = mc_gk20a_intr_unit_config; gops->mc.isr_stall = mc_gk20a_isr_stall; gops->mc.isr_nonstall = mc_gk20a_isr_nonstall; gops->mc.isr_thread_stall = mc_gk20a_intr_thread_stall; diff --git a/drivers/gpu/nvgpu/gk20a/mc_gk20a.h b/drivers/gpu/nvgpu/gk20a/mc_gk20a.h index 7264ab41e..4bb3e1187 100644 --- a/drivers/gpu/nvgpu/gk20a/mc_gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/mc_gk20a.h @@ -17,6 +17,8 @@ struct gk20a; void gk20a_init_mc(struct gpu_ops *gops); void mc_gk20a_intr_enable(struct gk20a *g); +void mc_gk20a_intr_unit_config(struct gk20a *g, bool enable, + bool is_stalling, u32 mask); irqreturn_t mc_gk20a_isr_stall(struct gk20a *g); irqreturn_t mc_gk20a_isr_nonstall(struct gk20a *g); irqreturn_t mc_gk20a_intr_thread_stall(struct gk20a *g); diff --git a/drivers/gpu/nvgpu/gk20a/pmu_gk20a.c b/drivers/gpu/nvgpu/gk20a/pmu_gk20a.c index 4471b0f18..27478750f 100644 --- a/drivers/gpu/nvgpu/gk20a/pmu_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/pmu_gk20a.c @@ -1178,12 +1178,10 @@ void pmu_enable_irq(struct pmu_gk20a *pmu, bool enable) gk20a_dbg_fn(""); - gk20a_writel(g, mc_intr_mask_0_r(), - gk20a_readl(g, mc_intr_mask_0_r()) & - ~mc_intr_mask_0_pmu_enabled_f()); - gk20a_writel(g, mc_intr_mask_1_r(), - gk20a_readl(g, mc_intr_mask_1_r()) & - ~mc_intr_mask_1_pmu_enabled_f()); + g->ops.mc.intr_unit_config(g, MC_INTR_UNIT_DISABLE, true, + mc_intr_mask_0_pmu_enabled_f()); + g->ops.mc.intr_unit_config(g, MC_INTR_UNIT_DISABLE, false, + mc_intr_mask_1_pmu_enabled_f()); gk20a_writel(g, pwr_falcon_irqmclr_r(), pwr_falcon_irqmclr_gptmr_f(1) | @@ -1229,9 +1227,8 @@ void pmu_enable_irq(struct pmu_gk20a *pmu, bool enable) pwr_falcon_irqmset_swgen0_f(1) | pwr_falcon_irqmset_swgen1_f(1)); - gk20a_writel(g, mc_intr_mask_0_r(), - gk20a_readl(g, mc_intr_mask_0_r()) | - mc_intr_mask_0_pmu_enabled_f()); + g->ops.mc.intr_unit_config(g, MC_INTR_UNIT_ENABLE, true, + mc_intr_mask_0_pmu_enabled_f()); } gk20a_dbg_fn("done"); diff --git a/drivers/gpu/nvgpu/gm20b/mc_gm20b.c b/drivers/gpu/nvgpu/gm20b/mc_gm20b.c index 22dce1e76..1d2d78e3e 100644 --- a/drivers/gpu/nvgpu/gm20b/mc_gm20b.c +++ b/drivers/gpu/nvgpu/gm20b/mc_gm20b.c @@ -22,6 +22,7 @@ void gm20b_init_mc(struct gpu_ops *gops) { gops->mc.intr_enable = mc_gk20a_intr_enable; + gops->mc.intr_unit_config = mc_gk20a_intr_unit_config; gops->mc.isr_stall = mc_gk20a_isr_stall; gops->mc.isr_nonstall = mc_gk20a_isr_nonstall; gops->mc.isr_thread_stall = mc_gk20a_intr_thread_stall;