summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/gm20b/gr_gm20b.c
diff options
context:
space:
mode:
authorDeepak Nibade <dnibade@nvidia.com>2014-10-01 11:53:49 -0400
committerDan Willemsen <dwillemsen@nvidia.com>2015-03-18 15:12:10 -0400
commitf8f6b298848ed05ad83ce107ff8a4fff0b37dd2d (patch)
tree554d121fbbc47745556cd6a99c6b5d6258951b80 /drivers/gpu/nvgpu/gm20b/gr_gm20b.c
parent6275bbb33bb0f72cc03c7e68d8186b36c96ee854 (diff)
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 <kevinh@nvidia.com> Signed-off-by: Deepak Nibade <dnibade@nvidia.com> Reviewed-on: http://git-master/r/552606 Reviewed-by: Sachin Nikam <snikam@nvidia.com>
Diffstat (limited to 'drivers/gpu/nvgpu/gm20b/gr_gm20b.c')
-rw-r--r--drivers/gpu/nvgpu/gm20b/gr_gm20b.c23
1 files changed, 23 insertions, 0 deletions
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 @@
15 15
16#include <linux/types.h> 16#include <linux/types.h>
17#include <linux/delay.h> /* for mdelay */ 17#include <linux/delay.h> /* for mdelay */
18#include <linux/io.h>
19#include <linux/tegra-fuse.h>
18 20
19#include "gk20a/gk20a.h" 21#include "gk20a/gk20a.h"
20#include "gk20a/gr_gk20a.h" 22#include "gk20a/gr_gk20a.h"
@@ -492,6 +494,26 @@ static u32 gr_gm20b_get_gpc_tpc_mask(struct gk20a *g, u32 gpc_index)
492 return (~val) & ((0x1 << gr->max_tpc_per_gpc_count) - 1); 494 return (~val) & ((0x1 << gr->max_tpc_per_gpc_count) - 1);
493} 495}
494 496
497static void gr_gm20b_set_gpc_tpc_mask(struct gk20a *g, u32 gpc_index)
498{
499 tegra_clk_writel(CLK_RST_CONTROLLER_MISC_CLK_ENB_0_ALL_VISIBLE,
500 CLK_RST_CONTROLLER_MISC_CLK_ENB_0);
501
502 tegra_fuse_writel(0x1, FUSE_FUSEBYPASS_0);
503 tegra_fuse_writel(0x0, FUSE_WRITE_ACCESS_SW_0);
504
505 if (g->gr.gpc_tpc_mask[gpc_index] == 0x1) {
506 tegra_fuse_writel(0x0, FUSE_OPT_GPU_TPC0_DISABLE_0);
507 tegra_fuse_writel(0x1, FUSE_OPT_GPU_TPC1_DISABLE_0);
508 } else if (g->gr.gpc_tpc_mask[gpc_index] == 0x2) {
509 tegra_fuse_writel(0x1, FUSE_OPT_GPU_TPC0_DISABLE_0);
510 tegra_fuse_writel(0x0, FUSE_OPT_GPU_TPC1_DISABLE_0);
511 } else {
512 tegra_fuse_writel(0x0, FUSE_OPT_GPU_TPC0_DISABLE_0);
513 tegra_fuse_writel(0x0, FUSE_OPT_GPU_TPC1_DISABLE_0);
514 }
515}
516
495static int gr_gm20b_ctx_state_floorsweep(struct gk20a *g) 517static int gr_gm20b_ctx_state_floorsweep(struct gk20a *g)
496{ 518{
497 struct gr_gk20a *gr = &g->gr; 519 struct gr_gk20a *gr = &g->gr;
@@ -785,6 +807,7 @@ void gm20b_init_gr(struct gpu_ops *gops)
785 gops->gr.load_ctxsw_ucode = gr_gm20b_load_ctxsw_ucode; 807 gops->gr.load_ctxsw_ucode = gr_gm20b_load_ctxsw_ucode;
786 else 808 else
787 gops->gr.load_ctxsw_ucode = gr_gk20a_load_ctxsw_ucode; 809 gops->gr.load_ctxsw_ucode = gr_gk20a_load_ctxsw_ucode;
810 gops->gr.set_gpc_tpc_mask = gr_gm20b_set_gpc_tpc_mask;
788 gops->gr.get_gpc_tpc_mask = gr_gm20b_get_gpc_tpc_mask; 811 gops->gr.get_gpc_tpc_mask = gr_gm20b_get_gpc_tpc_mask;
789 gops->gr.free_channel_ctx = gk20a_free_channel_ctx; 812 gops->gr.free_channel_ctx = gk20a_free_channel_ctx;
790 gops->gr.alloc_obj_ctx = gk20a_alloc_obj_ctx; 813 gops->gr.alloc_obj_ctx = gk20a_alloc_obj_ctx;