diff options
Diffstat (limited to 'drivers/gpu/nvgpu/gv11b')
-rw-r--r-- | drivers/gpu/nvgpu/gv11b/gr_gv11b.c | 196 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gv11b/gr_gv11b.h | 3 |
2 files changed, 199 insertions, 0 deletions
diff --git a/drivers/gpu/nvgpu/gv11b/gr_gv11b.c b/drivers/gpu/nvgpu/gv11b/gr_gv11b.c index 00bfde6b..fab2ae9a 100644 --- a/drivers/gpu/nvgpu/gv11b/gr_gv11b.c +++ b/drivers/gpu/nvgpu/gv11b/gr_gv11b.c | |||
@@ -3378,6 +3378,196 @@ static void gv11b_gr_access_smpc_reg(struct gk20a *g, u32 quad, u32 offset) | |||
3378 | gk20a_writel(g, gr_gpcs_tpcs_sm_debug_sfe_control_r(), reg_val); | 3378 | gk20a_writel(g, gr_gpcs_tpcs_sm_debug_sfe_control_r(), reg_val); |
3379 | } | 3379 | } |
3380 | 3380 | ||
3381 | static bool pri_is_egpc_addr_shared(struct gk20a *g, u32 addr) | ||
3382 | { | ||
3383 | u32 egpc_shared_base = EGPC_PRI_SHARED_BASE; | ||
3384 | u32 gpc_stride = nvgpu_get_litter_value(g, GPU_LIT_GPC_STRIDE); | ||
3385 | |||
3386 | return (addr >= egpc_shared_base) && | ||
3387 | (addr < egpc_shared_base + gpc_stride); | ||
3388 | } | ||
3389 | |||
3390 | static bool gv11b_gr_pri_is_egpc_addr(struct gk20a *g, u32 addr) | ||
3391 | { | ||
3392 | u32 egpc_base = g->ops.gr.get_egpc_base(g); | ||
3393 | u32 gpc_stride = nvgpu_get_litter_value(g, GPU_LIT_GPC_STRIDE); | ||
3394 | u32 num_gpcs = nvgpu_get_litter_value(g, GPU_LIT_NUM_GPCS); | ||
3395 | |||
3396 | return ((addr >= egpc_base) && | ||
3397 | (addr < egpc_base + num_gpcs * gpc_stride)) || | ||
3398 | pri_is_egpc_addr_shared(g, addr); | ||
3399 | } | ||
3400 | |||
3401 | static bool gv11b_gr_pri_is_etpc_addr(struct gk20a *g, u32 addr) | ||
3402 | { | ||
3403 | u32 egpc_addr = 0; | ||
3404 | |||
3405 | if (g->ops.gr.is_egpc_addr(g, addr)) { | ||
3406 | egpc_addr = pri_gpccs_addr_mask(addr); | ||
3407 | if (g->ops.gr.is_tpc_addr(g, egpc_addr)) | ||
3408 | return true; | ||
3409 | } | ||
3410 | |||
3411 | return false; | ||
3412 | } | ||
3413 | |||
3414 | static u32 pri_get_egpc_num(struct gk20a *g, u32 addr) | ||
3415 | { | ||
3416 | u32 i, start; | ||
3417 | u32 egpc_base = g->ops.gr.get_egpc_base(g); | ||
3418 | u32 num_gpcs = nvgpu_get_litter_value(g, GPU_LIT_NUM_GPCS); | ||
3419 | u32 gpc_stride = nvgpu_get_litter_value(g, GPU_LIT_GPC_STRIDE); | ||
3420 | |||
3421 | for (i = 0; i < num_gpcs; i++) { | ||
3422 | start = egpc_base + (i * gpc_stride); | ||
3423 | if ((addr >= start) && (addr < (start + gpc_stride))) | ||
3424 | return i; | ||
3425 | } | ||
3426 | return 0; | ||
3427 | } | ||
3428 | |||
3429 | static u32 pri_egpc_addr(struct gk20a *g, u32 addr, u32 gpc) | ||
3430 | { | ||
3431 | u32 egpc_base = g->ops.gr.get_egpc_base(g); | ||
3432 | u32 gpc_stride = nvgpu_get_litter_value(g, GPU_LIT_GPC_STRIDE); | ||
3433 | |||
3434 | return egpc_base + (gpc * gpc_stride) + addr; | ||
3435 | } | ||
3436 | |||
3437 | static u32 pri_etpc_addr(struct gk20a *g, u32 addr, u32 gpc, u32 tpc) | ||
3438 | { | ||
3439 | u32 egpc_base = g->ops.gr.get_egpc_base(g); | ||
3440 | u32 gpc_stride = nvgpu_get_litter_value(g, GPU_LIT_GPC_STRIDE); | ||
3441 | u32 tpc_in_gpc_base = nvgpu_get_litter_value(g, | ||
3442 | GPU_LIT_TPC_IN_GPC_BASE); | ||
3443 | u32 tpc_in_gpc_stride = nvgpu_get_litter_value(g, | ||
3444 | GPU_LIT_TPC_IN_GPC_STRIDE); | ||
3445 | |||
3446 | return egpc_base + (gpc * gpc_stride) + | ||
3447 | tpc_in_gpc_base + (tpc * tpc_in_gpc_stride) + | ||
3448 | addr; | ||
3449 | } | ||
3450 | |||
3451 | static void gv11b_gr_get_egpc_etpc_num(struct gk20a *g, u32 addr, | ||
3452 | u32 *egpc_num, u32 *etpc_num) | ||
3453 | { | ||
3454 | u32 egpc_addr = 0; | ||
3455 | |||
3456 | *egpc_num = pri_get_egpc_num(g, addr); | ||
3457 | egpc_addr = pri_gpccs_addr_mask(addr); | ||
3458 | *etpc_num = g->ops.gr.get_tpc_num(g, egpc_addr); | ||
3459 | |||
3460 | nvgpu_log(g, gpu_dbg_fn | gpu_dbg_gpu_dbg, | ||
3461 | "egpc_num = %d etpc_num = %d", *egpc_num, *etpc_num); | ||
3462 | } | ||
3463 | |||
3464 | static int gv11b_gr_decode_egpc_addr(struct gk20a *g, u32 addr, int *addr_type, | ||
3465 | u32 *gpc_num, u32 *tpc_num, u32 *broadcast_flags) | ||
3466 | { | ||
3467 | u32 gpc_addr; | ||
3468 | |||
3469 | if (g->ops.gr.is_egpc_addr(g, addr)) { | ||
3470 | nvgpu_log_info(g, "addr=0x%x is egpc", addr); | ||
3471 | |||
3472 | *addr_type = CTXSW_ADDR_TYPE_EGPC; | ||
3473 | gpc_addr = pri_gpccs_addr_mask(addr); | ||
3474 | if (pri_is_egpc_addr_shared(g, addr)) { | ||
3475 | *broadcast_flags |= PRI_BROADCAST_FLAGS_EGPC; | ||
3476 | *gpc_num = 0; | ||
3477 | nvgpu_log_info(g, "shared egpc"); | ||
3478 | } else { | ||
3479 | *gpc_num = pri_get_egpc_num(g, addr); | ||
3480 | nvgpu_log_info(g, "gpc=0x%x", *gpc_num); | ||
3481 | } | ||
3482 | if (g->ops.gr.is_tpc_addr(g, gpc_addr)) { | ||
3483 | nvgpu_log_info(g, "addr=0x%x is etpc", addr); | ||
3484 | *addr_type = CTXSW_ADDR_TYPE_ETPC; | ||
3485 | if (pri_is_tpc_addr_shared(g, gpc_addr)) { | ||
3486 | *broadcast_flags |= PRI_BROADCAST_FLAGS_ETPC; | ||
3487 | *tpc_num = 0; | ||
3488 | nvgpu_log_info(g, "shared etpc"); | ||
3489 | } else { | ||
3490 | *tpc_num = g->ops.gr.get_tpc_num(g, gpc_addr); | ||
3491 | nvgpu_log_info(g, "tpc=0x%x", *tpc_num); | ||
3492 | } | ||
3493 | } | ||
3494 | |||
3495 | nvgpu_log(g, gpu_dbg_fn | gpu_dbg_gpu_dbg, | ||
3496 | "addr_type = %d, broadcast_flags = %#08x", | ||
3497 | *addr_type, *broadcast_flags); | ||
3498 | return 0; | ||
3499 | } | ||
3500 | return -EINVAL; | ||
3501 | } | ||
3502 | |||
3503 | static void gv11b_gr_egpc_etpc_priv_addr_table(struct gk20a *g, u32 addr, | ||
3504 | u32 gpc, u32 broadcast_flags, u32 *priv_addr_table, u32 *t) | ||
3505 | { | ||
3506 | u32 gpc_num, tpc_num; | ||
3507 | |||
3508 | nvgpu_log_info(g, "addr=0x%x", addr); | ||
3509 | |||
3510 | /* The GPC/TPC unicast registers are included in the compressed PRI | ||
3511 | * tables. Convert a GPC/TPC broadcast address to unicast addresses so | ||
3512 | * that we can look up the offsets. | ||
3513 | */ | ||
3514 | if (broadcast_flags & PRI_BROADCAST_FLAGS_EGPC) { | ||
3515 | nvgpu_log_info(g, "broadcast flags egpc"); | ||
3516 | for (gpc_num = 0; gpc_num < g->gr.gpc_count; gpc_num++) { | ||
3517 | |||
3518 | if (broadcast_flags & PRI_BROADCAST_FLAGS_ETPC) { | ||
3519 | nvgpu_log_info(g, "broadcast flags etpc"); | ||
3520 | for (tpc_num = 0; | ||
3521 | tpc_num < g->gr.gpc_tpc_count[gpc_num]; | ||
3522 | tpc_num++) { | ||
3523 | priv_addr_table[*t] = | ||
3524 | pri_etpc_addr(g, | ||
3525 | pri_tpccs_addr_mask(addr), | ||
3526 | gpc_num, tpc_num); | ||
3527 | nvgpu_log_info(g, | ||
3528 | "priv_addr_table[%d]:%#08x", | ||
3529 | *t, priv_addr_table[*t]); | ||
3530 | (*t)++; | ||
3531 | } | ||
3532 | } else { | ||
3533 | priv_addr_table[*t] = | ||
3534 | pri_egpc_addr(g, | ||
3535 | pri_gpccs_addr_mask(addr), | ||
3536 | gpc_num); | ||
3537 | nvgpu_log_info(g, "priv_addr_table[%d]:%#08x", | ||
3538 | *t, priv_addr_table[*t]); | ||
3539 | (*t)++; | ||
3540 | } | ||
3541 | } | ||
3542 | } else if (!(broadcast_flags & PRI_BROADCAST_FLAGS_EGPC)) { | ||
3543 | if (broadcast_flags & PRI_BROADCAST_FLAGS_ETPC) { | ||
3544 | nvgpu_log_info(g, "broadcast flags etpc but not egpc"); | ||
3545 | for (tpc_num = 0; | ||
3546 | tpc_num < g->gr.gpc_tpc_count[gpc]; | ||
3547 | tpc_num++) { | ||
3548 | priv_addr_table[*t] = | ||
3549 | pri_etpc_addr(g, | ||
3550 | pri_tpccs_addr_mask(addr), | ||
3551 | gpc, tpc_num); | ||
3552 | nvgpu_log_info(g, | ||
3553 | "priv_addr_table[%d]:%#08x", | ||
3554 | *t, priv_addr_table[*t]); | ||
3555 | (*t)++; | ||
3556 | } | ||
3557 | } else { | ||
3558 | priv_addr_table[*t] = addr; | ||
3559 | nvgpu_log_info(g, "priv_addr_table[%d]:%#08x", | ||
3560 | *t, priv_addr_table[*t]); | ||
3561 | (*t)++; | ||
3562 | } | ||
3563 | } | ||
3564 | } | ||
3565 | |||
3566 | static u32 gv11b_gr_get_egpc_base(struct gk20a *g) | ||
3567 | { | ||
3568 | return EGPC_PRI_BASE; | ||
3569 | } | ||
3570 | |||
3381 | void gv11b_init_gr(struct gpu_ops *gops) | 3571 | void gv11b_init_gr(struct gpu_ops *gops) |
3382 | { | 3572 | { |
3383 | gp10b_init_gr(gops); | 3573 | gp10b_init_gr(gops); |
@@ -3468,4 +3658,10 @@ void gv11b_init_gr(struct gpu_ops *gops) | |||
3468 | gops->gr.get_sm_dsm_perf_ctrl_regs = gv11b_gr_get_sm_dsm_perf_ctrl_regs; | 3658 | gops->gr.get_sm_dsm_perf_ctrl_regs = gv11b_gr_get_sm_dsm_perf_ctrl_regs; |
3469 | gops->gr.get_ovr_perf_regs = gv11b_gr_get_ovr_perf_regs; | 3659 | gops->gr.get_ovr_perf_regs = gv11b_gr_get_ovr_perf_regs; |
3470 | gops->gr.access_smpc_reg = gv11b_gr_access_smpc_reg; | 3660 | gops->gr.access_smpc_reg = gv11b_gr_access_smpc_reg; |
3661 | gops->gr.decode_egpc_addr = gv11b_gr_decode_egpc_addr; | ||
3662 | gops->gr.egpc_etpc_priv_addr_table = gv11b_gr_egpc_etpc_priv_addr_table; | ||
3663 | gops->gr.get_egpc_etpc_num = gv11b_gr_get_egpc_etpc_num; | ||
3664 | gops->gr.get_egpc_base = gv11b_gr_get_egpc_base; | ||
3665 | gops->gr.is_egpc_addr = gv11b_gr_pri_is_egpc_addr; | ||
3666 | gops->gr.is_etpc_addr = gv11b_gr_pri_is_etpc_addr; | ||
3471 | } | 3667 | } |
diff --git a/drivers/gpu/nvgpu/gv11b/gr_gv11b.h b/drivers/gpu/nvgpu/gv11b/gr_gv11b.h index e6149b37..0793dae5 100644 --- a/drivers/gpu/nvgpu/gv11b/gr_gv11b.h +++ b/drivers/gpu/nvgpu/gv11b/gr_gv11b.h | |||
@@ -16,6 +16,9 @@ | |||
16 | #ifndef _NVGPU_GR_GV11B_H_ | 16 | #ifndef _NVGPU_GR_GV11B_H_ |
17 | #define _NVGPU_GR_GV11B_H_ | 17 | #define _NVGPU_GR_GV11B_H_ |
18 | 18 | ||
19 | #define EGPC_PRI_BASE 0x580000 | ||
20 | #define EGPC_PRI_SHARED_BASE 0x480000 | ||
21 | |||
19 | #define GV11B_ZBC_TYPE_STENCIL T19X_ZBC | 22 | #define GV11B_ZBC_TYPE_STENCIL T19X_ZBC |
20 | #define ZBC_STENCIL_CLEAR_FMT_INVAILD 0 | 23 | #define ZBC_STENCIL_CLEAR_FMT_INVAILD 0 |
21 | #define ZBC_STENCIL_CLEAR_FMT_U8 1 | 24 | #define ZBC_STENCIL_CLEAR_FMT_U8 1 |