From f8f6b298848ed05ad83ce107ff8a4fff0b37dd2d Mon Sep 17 00:00:00 2001 From: Deepak Nibade Date: Wed, 1 Oct 2014 21:23:49 +0530 Subject: gpu: nvgpu: support config of TPC FUSE dynamically Follow steps below to config active TPC number: echo 1 > /sys/devices/platform/host1x/gpu.0/force_idle echo 0x1/0x2/0x3 > /sys/devices/platform/host1x/gpu.0/tpc_fs_mask echo 0 > /sys/devices/platform/host1x/gpu.0/force_idle where, 0x1 : disable TPC1 0x2 : disable TPC0 0x3 : both TPCs active Also, add API set_gpc_tpc_mask to update the TPCs and call this API after update to sysfs "tpc_fs_mask" Once fuses are updated for new TPC settings, we need to reconfigure GR and golden_image. Hence disable gr->sw_ready and golden_image_initialized flags. Also, initialize gr->tpc_count = 0 each time in gr_gk20a_init_gr_config(), otherwise it goes on adding tpc count Bug 1513685 Change-Id: Ib50bafef08664262f8426ac0d6cbad74b32c5909 Signed-off-by: Kevin Huang Signed-off-by: Deepak Nibade Reviewed-on: http://git-master/r/552606 Reviewed-by: Sachin Nikam --- drivers/gpu/nvgpu/gm20b/gr_gm20b.c | 23 +++++++++++++++++++++++ drivers/gpu/nvgpu/gm20b/gr_gm20b.h | 11 +++++++++++ 2 files changed, 34 insertions(+) (limited to 'drivers/gpu/nvgpu/gm20b') diff --git a/drivers/gpu/nvgpu/gm20b/gr_gm20b.c b/drivers/gpu/nvgpu/gm20b/gr_gm20b.c index 8f056181..a6b54ea5 100644 --- a/drivers/gpu/nvgpu/gm20b/gr_gm20b.c +++ b/drivers/gpu/nvgpu/gm20b/gr_gm20b.c @@ -15,6 +15,8 @@ #include #include /* for mdelay */ +#include +#include #include "gk20a/gk20a.h" #include "gk20a/gr_gk20a.h" @@ -492,6 +494,26 @@ static u32 gr_gm20b_get_gpc_tpc_mask(struct gk20a *g, u32 gpc_index) return (~val) & ((0x1 << gr->max_tpc_per_gpc_count) - 1); } +static void gr_gm20b_set_gpc_tpc_mask(struct gk20a *g, u32 gpc_index) +{ + tegra_clk_writel(CLK_RST_CONTROLLER_MISC_CLK_ENB_0_ALL_VISIBLE, + CLK_RST_CONTROLLER_MISC_CLK_ENB_0); + + tegra_fuse_writel(0x1, FUSE_FUSEBYPASS_0); + tegra_fuse_writel(0x0, FUSE_WRITE_ACCESS_SW_0); + + if (g->gr.gpc_tpc_mask[gpc_index] == 0x1) { + tegra_fuse_writel(0x0, FUSE_OPT_GPU_TPC0_DISABLE_0); + tegra_fuse_writel(0x1, FUSE_OPT_GPU_TPC1_DISABLE_0); + } else if (g->gr.gpc_tpc_mask[gpc_index] == 0x2) { + tegra_fuse_writel(0x1, FUSE_OPT_GPU_TPC0_DISABLE_0); + tegra_fuse_writel(0x0, FUSE_OPT_GPU_TPC1_DISABLE_0); + } else { + tegra_fuse_writel(0x0, FUSE_OPT_GPU_TPC0_DISABLE_0); + tegra_fuse_writel(0x0, FUSE_OPT_GPU_TPC1_DISABLE_0); + } +} + static int gr_gm20b_ctx_state_floorsweep(struct gk20a *g) { struct gr_gk20a *gr = &g->gr; @@ -785,6 +807,7 @@ void gm20b_init_gr(struct gpu_ops *gops) gops->gr.load_ctxsw_ucode = gr_gm20b_load_ctxsw_ucode; else gops->gr.load_ctxsw_ucode = gr_gk20a_load_ctxsw_ucode; + gops->gr.set_gpc_tpc_mask = gr_gm20b_set_gpc_tpc_mask; gops->gr.get_gpc_tpc_mask = gr_gm20b_get_gpc_tpc_mask; gops->gr.free_channel_ctx = gk20a_free_channel_ctx; gops->gr.alloc_obj_ctx = gk20a_alloc_obj_ctx; diff --git a/drivers/gpu/nvgpu/gm20b/gr_gm20b.h b/drivers/gpu/nvgpu/gm20b/gr_gm20b.h index 470e5bae..fd109eec 100644 --- a/drivers/gpu/nvgpu/gm20b/gr_gm20b.h +++ b/drivers/gpu/nvgpu/gm20b/gr_gm20b.h @@ -25,6 +25,17 @@ enum { MAXWELL_CHANNEL_GPFIFO_A= 0xB06F, }; +#define tegra_clk_writel(value, offset) \ + writel(value, IO_ADDRESS(0x60006000 + offset)) + +#define CLK_RST_CONTROLLER_MISC_CLK_ENB_0 0x48 +#define CLK_RST_CONTROLLER_MISC_CLK_ENB_0_ALL_VISIBLE BIT(28) + +#define FUSE_FUSEBYPASS_0 0x24 +#define FUSE_WRITE_ACCESS_SW_0 0x30 +#define FUSE_OPT_GPU_TPC0_DISABLE_0 0x30C +#define FUSE_OPT_GPU_TPC1_DISABLE_0 0x33C + #define NVB197_SET_ALPHA_CIRCULAR_BUFFER_SIZE 0x02dc #define NVB197_SET_CIRCULAR_BUFFER_SIZE 0x1280 #define NVB197_SET_SHADER_EXCEPTIONS 0x1528 -- cgit v1.2.2