diff options
author | Deepak Nibade <dnibade@nvidia.com> | 2018-04-02 05:41:02 -0400 |
---|---|---|
committer | mobile promotions <svcmobile_promotions@nvidia.com> | 2018-04-03 11:23:08 -0400 |
commit | 4b8432a663e12c915acec9043ab8493b30471188 (patch) | |
tree | 6654069e3801f0d7a89e876b6683807739fbaf31 /drivers/gpu/nvgpu/gk20a | |
parent | d02ae4f1e94fbeb9401bde9d34044792e213c54b (diff) |
gpu: nvgpu: fix address table for GPCS_TPC6 broadcast conversion
In gr_gk20a_create_priv_addr_table() and gv11b_gr_egpc_etpc_priv_addr_table(),
we create a table of unicast addresses from broadcast addresses
For GPC boardcast addresses like NV_PGRAPH_PRI_EGPCS_ETPC6_SM_*, we generate
the table assuming there are 7 TPCs in all the GPCs
But this is incorrect in some cases like GV100 where GPC0/1 have only 6 TPCs
And hence we end up generating registers which do not exist
Fix this by explicitly checking the number of TPCs and ensuring that address
generated is belongs to valid TPC
Bug 200400376
Jira NVGPU-564
Change-Id: I65d7d6cd7f0bf16171eb54ed71f1f3840ade3495
Signed-off-by: Deepak Nibade <dnibade@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/1686806
Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com>
GVS: Gerrit_Virtual_Submit
Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com>
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
Diffstat (limited to 'drivers/gpu/nvgpu/gk20a')
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/gr_gk20a.c | 17 |
1 files changed, 13 insertions, 4 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/gr_gk20a.c b/drivers/gpu/nvgpu/gk20a/gr_gk20a.c index e06d190e..ceb606e4 100644 --- a/drivers/gpu/nvgpu/gk20a/gr_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/gr_gk20a.c | |||
@@ -6353,6 +6353,7 @@ static int gr_gk20a_create_priv_addr_table(struct gk20a *g, | |||
6353 | { | 6353 | { |
6354 | int addr_type; /*enum ctxsw_addr_type */ | 6354 | int addr_type; /*enum ctxsw_addr_type */ |
6355 | u32 gpc_num, tpc_num, ppc_num, be_num; | 6355 | u32 gpc_num, tpc_num, ppc_num, be_num; |
6356 | u32 priv_addr, gpc_addr; | ||
6356 | u32 broadcast_flags; | 6357 | u32 broadcast_flags; |
6357 | u32 t; | 6358 | u32 t; |
6358 | int err; | 6359 | int err; |
@@ -6404,10 +6405,18 @@ static int gr_gk20a_create_priv_addr_table(struct gk20a *g, | |||
6404 | priv_addr_table, &t); | 6405 | priv_addr_table, &t); |
6405 | if (err) | 6406 | if (err) |
6406 | return err; | 6407 | return err; |
6407 | } else | 6408 | } else { |
6408 | priv_addr_table[t++] = | 6409 | priv_addr = pri_gpc_addr(g, |
6409 | pri_gpc_addr(g, pri_gpccs_addr_mask(addr), | 6410 | pri_gpccs_addr_mask(addr), |
6410 | gpc_num); | 6411 | gpc_num); |
6412 | |||
6413 | gpc_addr = pri_gpccs_addr_mask(priv_addr); | ||
6414 | tpc_num = g->ops.gr.get_tpc_num(g, gpc_addr); | ||
6415 | if (tpc_num >= g->gr.gpc_tpc_count[gpc_num]) | ||
6416 | continue; | ||
6417 | |||
6418 | priv_addr_table[t++] = priv_addr; | ||
6419 | } | ||
6411 | } | 6420 | } |
6412 | } else if (((addr_type == CTXSW_ADDR_TYPE_EGPC) || | 6421 | } else if (((addr_type == CTXSW_ADDR_TYPE_EGPC) || |
6413 | (addr_type == CTXSW_ADDR_TYPE_ETPC)) && | 6422 | (addr_type == CTXSW_ADDR_TYPE_ETPC)) && |