From 869b4dd2748263a4c88569973a17c787834427c2 Mon Sep 17 00:00:00 2001 From: Adeel Raza Date: Tue, 3 May 2016 17:42:07 -0700 Subject: gpu: nvgpu: add code to handle DT fuse overrides Add code for handling GP10B fuse overrides specified in the device tree. Also add specific handling for the ECC fuse override. Bug 1699676 Change-Id: Ifa07983054cd143f7f1745a6a6de36f4d4e08126 Signed-off-by: Adeel Raza Reviewed-on: http://git-master/r/1140893 Reviewed-by: Automatic_Commit_Validation_User GVS: Gerrit_Virtual_Submit Reviewed-by: Terje Bergstrom --- drivers/gpu/nvgpu/gp10b/gr_gp10b.c | 45 ++++++++++++++++++++++++++++++++++++++ drivers/gpu/nvgpu/gp10b/gr_gp10b.h | 2 ++ 2 files changed, 47 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/nvgpu/gp10b/gr_gp10b.c b/drivers/gpu/nvgpu/gp10b/gr_gp10b.c index 8ea9235d..b36eff8f 100644 --- a/drivers/gpu/nvgpu/gp10b/gr_gp10b.c +++ b/drivers/gpu/nvgpu/gp10b/gr_gp10b.c @@ -17,6 +17,8 @@ #include #include +#include + #include "gk20a/gr_gk20a.h" #include "gk20a/semaphore_gk20a.h" #include "gk20a/dbg_gpu_gk20a.h" @@ -1390,6 +1392,12 @@ static int gr_gp10b_init_fs_state(struct gk20a *g) gr_gpcs_tpcs_sm_disp_ctrl_re_suppress_disable_f()); gk20a_writel(g, gr_gpcs_tpcs_sm_disp_ctrl_r(), data); + if (g->gr.t18x.fecs_feature_override_ecc_val != 0) { + gk20a_writel(g, + gr_fecs_feature_override_ecc_r(), + g->gr.t18x.fecs_feature_override_ecc_val); + } + return gr_gm20b_ctx_state_floorsweep(g); } @@ -1989,6 +1997,42 @@ static int gr_gp10b_get_preemption_mode_flags(struct gk20a *g, return 0; } +static int gp10b_gr_fuse_override(struct gk20a *g) +{ + struct device_node *np = g->dev->of_node; + u32 *fuses; + int count, i; + + if (!np) /* may be pcie device */ + return 0; + + count = of_property_count_elems_of_size(np, "fuse-overrides", 8); + if (count <= 0) + return count; + + fuses = kmalloc(sizeof(u32) * count * 2, GFP_KERNEL); + if (!fuses) + return -ENOMEM; + of_property_read_u32_array(np, "fuse-overrides", fuses, count * 2); + for (i = 0; i < count; i++) { + u32 fuse, value; + + fuse = fuses[2 * i]; + value = fuses[2 * i + 1]; + switch (fuse) { + case GP10B_FUSE_OPT_ECC_EN: + g->gr.t18x.fecs_feature_override_ecc_val = value; + break; + default: + gk20a_err(dev_from_gk20a(g), + "ignore unknown fuse override %08x", fuse); + break; + } + } + + kfree(fuses); + return 0; +} void gp10b_init_gr(struct gpu_ops *gops) { @@ -2031,4 +2075,5 @@ void gp10b_init_gr(struct gpu_ops *gops) gops->gr.suspend_contexts = gr_gp10b_suspend_contexts; gops->gr.set_preemption_mode = gr_gp10b_set_preemption_mode; gops->gr.get_preemption_mode_flags = gr_gp10b_get_preemption_mode_flags; + gops->gr.fuse_override = gp10b_gr_fuse_override; } diff --git a/drivers/gpu/nvgpu/gp10b/gr_gp10b.h b/drivers/gpu/nvgpu/gp10b/gr_gp10b.h index 8c544f14..eb361820 100644 --- a/drivers/gpu/nvgpu/gp10b/gr_gp10b.h +++ b/drivers/gpu/nvgpu/gp10b/gr_gp10b.h @@ -83,6 +83,8 @@ struct gr_t18x { struct ecc_stat l2_ded_count; } ecc_stats; + u32 fecs_feature_override_ecc_val; + int cilp_preempt_pending_chid; }; -- cgit v1.2.2