diff options
author | seshendra Gadagottu <sgadagottu@nvidia.com> | 2018-02-14 19:25:58 -0500 |
---|---|---|
committer | mobile promotions <svcmobile_promotions@nvidia.com> | 2018-02-23 00:48:30 -0500 |
commit | 7a9c2f68f36ea4eb893cb2061ad82ddce9138e8b (patch) | |
tree | 3252e58ee1bd429607dd94d3e7f8d76c4bf6a968 /drivers/gpu/nvgpu/gv11b | |
parent | eb219e9f3f66a3930945260b50254ee1ee99b0cd (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/gpu/nvgpu/gv11b')
-rw-r--r-- | drivers/gpu/nvgpu/gv11b/gr_gv11b.c | 71 |
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 | |||
65 | bool gr_gv11b_is_valid_class(struct gk20a *g, u32 class_num) | 71 | bool 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, | |||
2305 | int gr_gv11b_setup_rop_mapping(struct gk20a *g, struct gr_gk20a *gr) | 2311 | int 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(), |