summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorTerje Bergstrom <tbergstrom@nvidia.com>2016-04-19 13:27:11 -0400
committerTerje Bergstrom <tbergstrom@nvidia.com>2016-04-26 12:46:04 -0400
commitec62c649b5338e7608ea82546135e88f443b90a8 (patch)
treef7190b7d86fafd9764a13a50689ef70bdff66300 /drivers
parentb10e02f53769c6b8dcc58db09ae1cec0cdca4417 (diff)
gpu: nvgpu: Idle GR before calling PMU ZBC save
On gk20a when PMU is updating ZBC colors it is reading them from L2. But L2 has one port, and ZBC reads can race with other transactions. Idle graphics before sending PMU the ZBC_UPDATE request. Also makes pmu_save_zbc a HAL, because PMU ucode has changes to bypass this problem on some chips. Bug 1746047 Change-Id: Id8fcd6850af7ef1d8f0a6aafa0fe6b4f88b5f2d9 Signed-off-by: Terje Bergstrom <tbergstrom@nvidia.com> Reviewed-on: http://git-master/r/1129017
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/nvgpu/gk20a/gk20a.h3
-rw-r--r--drivers/gpu/nvgpu/gk20a/gr_gk20a.c72
-rw-r--r--drivers/gpu/nvgpu/gk20a/gr_gk20a.h3
-rw-r--r--drivers/gpu/nvgpu/gm20b/gr_gm20b.c2
4 files changed, 79 insertions, 1 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.h b/drivers/gpu/nvgpu/gk20a/gk20a.h
index 5c397ad8..47adcc14 100644
--- a/drivers/gpu/nvgpu/gk20a/gk20a.h
+++ b/drivers/gpu/nvgpu/gk20a/gk20a.h
@@ -188,6 +188,9 @@ struct gpu_ops {
188 struct zbc_entry *zbc_val); 188 struct zbc_entry *zbc_val);
189 int (*zbc_query_table)(struct gk20a *g, struct gr_gk20a *gr, 189 int (*zbc_query_table)(struct gk20a *g, struct gr_gk20a *gr,
190 struct zbc_query_params *query_params); 190 struct zbc_query_params *query_params);
191 void (*pmu_save_zbc)(struct gk20a *g, u32 entries);
192 int (*add_zbc)(struct gk20a *g, struct gr_gk20a *gr,
193 struct zbc_entry *zbc_val);
191 u32 (*pagepool_default_size)(struct gk20a *g); 194 u32 (*pagepool_default_size)(struct gk20a *g);
192 int (*init_ctx_state)(struct gk20a *g); 195 int (*init_ctx_state)(struct gk20a *g);
193 int (*alloc_gr_ctx)(struct gk20a *g, 196 int (*alloc_gr_ctx)(struct gk20a *g,
diff --git a/drivers/gpu/nvgpu/gk20a/gr_gk20a.c b/drivers/gpu/nvgpu/gk20a/gr_gk20a.c
index 2c7423c0..84fa1e5e 100644
--- a/drivers/gpu/nvgpu/gk20a/gr_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/gr_gk20a.c
@@ -3748,6 +3748,40 @@ int gr_gk20a_add_zbc_depth(struct gk20a *g, struct gr_gk20a *gr,
3748 return 0; 3748 return 0;
3749} 3749}
3750 3750
3751void gr_gk20a_pmu_save_zbc(struct gk20a *g, u32 entries)
3752{
3753 struct fifo_gk20a *f = &g->fifo;
3754 struct fifo_engine_info_gk20a *gr_info =
3755 f->engine_info + ENGINE_GR_GK20A;
3756 unsigned long end_jiffies = jiffies +
3757 msecs_to_jiffies(gk20a_get_gr_idle_timeout(g));
3758 u32 ret;
3759
3760 ret = gk20a_fifo_disable_engine_activity(g, gr_info, true);
3761 if (ret) {
3762 gk20a_err(dev_from_gk20a(g),
3763 "failed to disable gr engine activity");
3764 return;
3765 }
3766
3767 ret = g->ops.gr.wait_empty(g, end_jiffies, GR_IDLE_CHECK_DEFAULT);
3768 if (ret) {
3769 gk20a_err(dev_from_gk20a(g),
3770 "failed to idle graphics");
3771 goto clean_up;
3772 }
3773
3774 /* update zbc */
3775 gk20a_pmu_save_zbc(g, entries);
3776
3777clean_up:
3778 ret = gk20a_fifo_enable_engine_activity(g, gr_info);
3779 if (ret) {
3780 gk20a_err(dev_from_gk20a(g),
3781 "failed to enable gr engine activity\n");
3782 }
3783}
3784
3751int gr_gk20a_add_zbc(struct gk20a *g, struct gr_gk20a *gr, 3785int gr_gk20a_add_zbc(struct gk20a *g, struct gr_gk20a *gr,
3752 struct zbc_entry *zbc_val) 3786 struct zbc_entry *zbc_val)
3753{ 3787{
@@ -3840,7 +3874,7 @@ int gr_gk20a_add_zbc(struct gk20a *g, struct gr_gk20a *gr,
3840 /* update zbc for elpg only when new entry is added */ 3874 /* update zbc for elpg only when new entry is added */
3841 entries = max(gr->max_used_color_index, 3875 entries = max(gr->max_used_color_index,
3842 gr->max_used_depth_index); 3876 gr->max_used_depth_index);
3843 gk20a_pmu_save_zbc(g, entries); 3877 g->ops.gr.pmu_save_zbc(g, entries);
3844 } 3878 }
3845 3879
3846err_mutex: 3880err_mutex:
@@ -3995,6 +4029,40 @@ int gr_gk20a_load_zbc_default_table(struct gk20a *g, struct gr_gk20a *gr)
3995 return 0; 4029 return 0;
3996} 4030}
3997 4031
4032int _gk20a_gr_zbc_set_table(struct gk20a *g, struct gr_gk20a *gr,
4033 struct zbc_entry *zbc_val)
4034{
4035 struct fifo_gk20a *f = &g->fifo;
4036 struct fifo_engine_info_gk20a *gr_info = f->engine_info + ENGINE_GR_GK20A;
4037 unsigned long end_jiffies;
4038 int ret;
4039
4040 ret = gk20a_fifo_disable_engine_activity(g, gr_info, true);
4041 if (ret) {
4042 gk20a_err(dev_from_gk20a(g),
4043 "failed to disable gr engine activity");
4044 return ret;
4045 }
4046
4047 end_jiffies = jiffies + msecs_to_jiffies(gk20a_get_gr_idle_timeout(g));
4048 ret = g->ops.gr.wait_empty(g, end_jiffies, GR_IDLE_CHECK_DEFAULT);
4049 if (ret) {
4050 gk20a_err(dev_from_gk20a(g),
4051 "failed to idle graphics");
4052 goto clean_up;
4053 }
4054
4055 ret = gr_gk20a_add_zbc(g, gr, zbc_val);
4056
4057clean_up:
4058 if (gk20a_fifo_enable_engine_activity(g, gr_info)) {
4059 gk20a_err(dev_from_gk20a(g),
4060 "failed to enable gr engine activity");
4061 }
4062
4063 return ret;
4064}
4065
3998int gk20a_gr_zbc_set_table(struct gk20a *g, struct gr_gk20a *gr, 4066int gk20a_gr_zbc_set_table(struct gk20a *g, struct gr_gk20a *gr,
3999 struct zbc_entry *zbc_val) 4067 struct zbc_entry *zbc_val)
4000{ 4068{
@@ -8618,6 +8686,8 @@ void gk20a_init_gr_ops(struct gpu_ops *gops)
8618 gops->gr.add_zbc_depth = gr_gk20a_add_zbc_depth; 8686 gops->gr.add_zbc_depth = gr_gk20a_add_zbc_depth;
8619 gops->gr.zbc_set_table = gk20a_gr_zbc_set_table; 8687 gops->gr.zbc_set_table = gk20a_gr_zbc_set_table;
8620 gops->gr.zbc_query_table = gr_gk20a_query_zbc; 8688 gops->gr.zbc_query_table = gr_gk20a_query_zbc;
8689 gops->gr.pmu_save_zbc = gr_gk20a_pmu_save_zbc;
8690 gops->gr.add_zbc = _gk20a_gr_zbc_set_table;
8621 gops->gr.pagepool_default_size = gr_gk20a_pagepool_default_size; 8691 gops->gr.pagepool_default_size = gr_gk20a_pagepool_default_size;
8622 gops->gr.init_ctx_state = gr_gk20a_init_ctx_state; 8692 gops->gr.init_ctx_state = gr_gk20a_init_ctx_state;
8623 gops->gr.alloc_gr_ctx = gr_gk20a_alloc_gr_ctx; 8693 gops->gr.alloc_gr_ctx = gr_gk20a_alloc_gr_ctx;
diff --git a/drivers/gpu/nvgpu/gk20a/gr_gk20a.h b/drivers/gpu/nvgpu/gk20a/gr_gk20a.h
index 3417610f..3702c82d 100644
--- a/drivers/gpu/nvgpu/gk20a/gr_gk20a.h
+++ b/drivers/gpu/nvgpu/gk20a/gr_gk20a.h
@@ -553,6 +553,9 @@ int gr_gk20a_add_zbc_color(struct gk20a *g, struct gr_gk20a *gr,
553 struct zbc_entry *color_val, u32 index); 553 struct zbc_entry *color_val, u32 index);
554int gr_gk20a_add_zbc_depth(struct gk20a *g, struct gr_gk20a *gr, 554int gr_gk20a_add_zbc_depth(struct gk20a *g, struct gr_gk20a *gr,
555 struct zbc_entry *depth_val, u32 index); 555 struct zbc_entry *depth_val, u32 index);
556int _gk20a_gr_zbc_set_table(struct gk20a *g, struct gr_gk20a *gr,
557 struct zbc_entry *zbc_val);
558void gr_gk20a_pmu_save_zbc(struct gk20a *g, u32 entries);
556int gr_gk20a_wait_idle(struct gk20a *g, unsigned long end_jiffies, 559int gr_gk20a_wait_idle(struct gk20a *g, unsigned long end_jiffies,
557 u32 expect_delay); 560 u32 expect_delay);
558int gr_gk20a_handle_sm_exception(struct gk20a *g, u32 gpc, u32 tpc, 561int gr_gk20a_handle_sm_exception(struct gk20a *g, u32 gpc, u32 tpc,
diff --git a/drivers/gpu/nvgpu/gm20b/gr_gm20b.c b/drivers/gpu/nvgpu/gm20b/gr_gm20b.c
index 40925f48..5b00078f 100644
--- a/drivers/gpu/nvgpu/gm20b/gr_gm20b.c
+++ b/drivers/gpu/nvgpu/gm20b/gr_gm20b.c
@@ -1372,6 +1372,8 @@ void gm20b_init_gr(struct gpu_ops *gops)
1372 gops->gr.add_zbc_depth = gr_gk20a_add_zbc_depth; 1372 gops->gr.add_zbc_depth = gr_gk20a_add_zbc_depth;
1373 gops->gr.zbc_set_table = gk20a_gr_zbc_set_table; 1373 gops->gr.zbc_set_table = gk20a_gr_zbc_set_table;
1374 gops->gr.zbc_query_table = gr_gk20a_query_zbc; 1374 gops->gr.zbc_query_table = gr_gk20a_query_zbc;
1375 gops->gr.pmu_save_zbc = gk20a_pmu_save_zbc;
1376 gops->gr.add_zbc = gr_gk20a_add_zbc;
1375 gops->gr.pagepool_default_size = gr_gm20b_pagepool_default_size; 1377 gops->gr.pagepool_default_size = gr_gm20b_pagepool_default_size;
1376 gops->gr.init_ctx_state = gr_gk20a_init_ctx_state; 1378 gops->gr.init_ctx_state = gr_gk20a_init_ctx_state;
1377 gops->gr.alloc_gr_ctx = gr_gm20b_alloc_gr_ctx; 1379 gops->gr.alloc_gr_ctx = gr_gm20b_alloc_gr_ctx;