summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/gk20a/gr_gk20a.c
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/gpu/nvgpu/gk20a/gr_gk20a.c
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/gpu/nvgpu/gk20a/gr_gk20a.c')
-rw-r--r--drivers/gpu/nvgpu/gk20a/gr_gk20a.c72
1 files changed, 71 insertions, 1 deletions
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;