summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorseshendra Gadagottu <sgadagottu@nvidia.com>2018-02-14 19:25:58 -0500
committermobile promotions <svcmobile_promotions@nvidia.com>2018-02-23 00:48:30 -0500
commit7a9c2f68f36ea4eb893cb2061ad82ddce9138e8b (patch)
tree3252e58ee1bd429607dd94d3e7f8d76c4bf6a968 /drivers
parenteb219e9f3f66a3930945260b50254ee1ee99b0cd (diff)
gpu: nvgpu: gv11b: check for valid gr map_tiles
Number of gr map_tiles is equal to number of tpcs. During gr_gv11b_setup_rop_mapping programming, check for validity of gr map_tiles before programming gr_crstr_gpc_map_tile map. Bug 200389570 Bug 2051856 JIRA NVGPU-523 Change-Id: Iaeb13c6a433d76ad895f89909e3033f887665619 Signed-off-by: seshendra Gadagottu <sgadagottu@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/1657727 GVS: Gerrit_Virtual_Submit Reviewed-by: Sachin Nikam <snikam@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/nvgpu/gv11b/gr_gv11b.c71
1 files changed, 56 insertions, 15 deletions
diff --git a/drivers/gpu/nvgpu/gv11b/gr_gv11b.c b/drivers/gpu/nvgpu/gv11b/gr_gv11b.c
index 0d7a3f4d..dee3b760 100644
--- a/drivers/gpu/nvgpu/gv11b/gr_gv11b.c
+++ b/drivers/gpu/nvgpu/gv11b/gr_gv11b.c
@@ -62,6 +62,12 @@
62#define ECC_SCRUBBING_TIMEOUT_MAX 1000 62#define ECC_SCRUBBING_TIMEOUT_MAX 1000
63#define ECC_SCRUBBING_TIMEOUT_DEFAULT 10 63#define ECC_SCRUBBING_TIMEOUT_DEFAULT 10
64 64
65/*
66 * Each gpc can have maximum 32 tpcs, so each tpc index need
67 * 5 bits. Each map register(32bits) can hold 6 tpcs info.
68 */
69#define GR_TPCS_INFO_FOR_MAPREGISTER 6
70
65bool gr_gv11b_is_valid_class(struct gk20a *g, u32 class_num) 71bool gr_gv11b_is_valid_class(struct gk20a *g, u32 class_num)
66{ 72{
67 bool valid = false; 73 bool valid = false;
@@ -2305,10 +2311,12 @@ int gr_gv11b_handle_fecs_error(struct gk20a *g,
2305int gr_gv11b_setup_rop_mapping(struct gk20a *g, struct gr_gk20a *gr) 2311int gr_gv11b_setup_rop_mapping(struct gk20a *g, struct gr_gk20a *gr)
2306{ 2312{
2307 u32 map; 2313 u32 map;
2308 u32 i, j, mapregs; 2314 u32 i, j;
2315 u32 mapreg_num, base, offset, mapregs;
2309 u32 num_gpcs = nvgpu_get_litter_value(g, GPU_LIT_NUM_GPCS); 2316 u32 num_gpcs = nvgpu_get_litter_value(g, GPU_LIT_NUM_GPCS);
2310 u32 num_tpc_per_gpc = nvgpu_get_litter_value(g, 2317 u32 num_tpc_per_gpc = nvgpu_get_litter_value(g,
2311 GPU_LIT_NUM_TPC_PER_GPC); 2318 GPU_LIT_NUM_TPC_PER_GPC);
2319 u32 num_tpcs = num_gpcs * num_tpc_per_gpc;
2312 2320
2313 gk20a_dbg_fn(""); 2321 gk20a_dbg_fn("");
2314 2322
@@ -2318,21 +2326,54 @@ int gr_gv11b_setup_rop_mapping(struct gk20a *g, struct gr_gk20a *gr)
2318 gk20a_writel(g, gr_crstr_map_table_cfg_r(), 2326 gk20a_writel(g, gr_crstr_map_table_cfg_r(),
2319 gr_crstr_map_table_cfg_row_offset_f(gr->map_row_offset) | 2327 gr_crstr_map_table_cfg_row_offset_f(gr->map_row_offset) |
2320 gr_crstr_map_table_cfg_num_entries_f(gr->tpc_count)); 2328 gr_crstr_map_table_cfg_num_entries_f(gr->tpc_count));
2329 /*
2330 * 6 tpc can be stored in one map register.
2331 * But number of tpcs are not always multiple of six,
2332 * so adding additional check for valid number of
2333 * tpcs before programming map register.
2334 */
2335 mapregs = DIV_ROUND_UP(num_tpcs, GR_TPCS_INFO_FOR_MAPREGISTER);
2336
2337 for (mapreg_num = 0, base = 0; mapreg_num < mapregs; mapreg_num++,
2338 base = base + GR_TPCS_INFO_FOR_MAPREGISTER) {
2339 map = 0;
2340 for (offset = 0;
2341 (offset < GR_TPCS_INFO_FOR_MAPREGISTER && num_tpcs > 0);
2342 offset++, num_tpcs--) {
2343 switch (offset) {
2344 case 0:
2345 map = map | gr_crstr_gpc_map_tile0_f(
2346 gr->map_tiles[base + offset]);
2347 break;
2348 case 1:
2349 map = map | gr_crstr_gpc_map_tile1_f(
2350 gr->map_tiles[base + offset]);
2351 break;
2352 case 2:
2353 map = map | gr_crstr_gpc_map_tile2_f(
2354 gr->map_tiles[base + offset]);
2355 break;
2356 case 3:
2357 map = map | gr_crstr_gpc_map_tile3_f(
2358 gr->map_tiles[base + offset]);
2359 break;
2360 case 4:
2361 map = map | gr_crstr_gpc_map_tile4_f(
2362 gr->map_tiles[base + offset]);
2363 break;
2364 case 5:
2365 map = map | gr_crstr_gpc_map_tile5_f(
2366 gr->map_tiles[base + offset]);
2367 break;
2368 default:
2369 nvgpu_err(g, "incorrect rop mapping %x", offset);
2370 break;
2371 }
2372 }
2321 2373
2322 /* 6 tpc can be stored in one map register */ 2374 gk20a_writel(g, gr_crstr_gpc_map_r(mapreg_num), map);
2323 mapregs = (num_gpcs * num_tpc_per_gpc + 5) / 6; 2375 gk20a_writel(g, gr_ppcs_wwdx_map_gpc_map_r(mapreg_num), map);
2324 2376 gk20a_writel(g, gr_rstr2d_gpc_map_r(mapreg_num), map);
2325 for (i = 0, j = 0; i < mapregs; i++, j = j + 6) {
2326 map = gr_crstr_gpc_map_tile0_f(gr->map_tiles[j]) |
2327 gr_crstr_gpc_map_tile1_f(gr->map_tiles[j + 1]) |
2328 gr_crstr_gpc_map_tile2_f(gr->map_tiles[j + 2]) |
2329 gr_crstr_gpc_map_tile3_f(gr->map_tiles[j + 3]) |
2330 gr_crstr_gpc_map_tile4_f(gr->map_tiles[j + 4]) |
2331 gr_crstr_gpc_map_tile5_f(gr->map_tiles[j + 5]);
2332
2333 gk20a_writel(g, gr_crstr_gpc_map_r(i), map);
2334 gk20a_writel(g, gr_ppcs_wwdx_map_gpc_map_r(i), map);
2335 gk20a_writel(g, gr_rstr2d_gpc_map_r(i), map);
2336 } 2377 }
2337 2378
2338 gk20a_writel(g, gr_ppcs_wwdx_map_table_cfg_r(), 2379 gk20a_writel(g, gr_ppcs_wwdx_map_table_cfg_r(),