diff options
Diffstat (limited to 'drivers/gpu/nvgpu/gk20a/gr_gk20a.c')
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/gr_gk20a.c | 134 |
1 files changed, 48 insertions, 86 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/gr_gk20a.c b/drivers/gpu/nvgpu/gk20a/gr_gk20a.c index fc1da1fe..3d70afd5 100644 --- a/drivers/gpu/nvgpu/gk20a/gr_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/gr_gk20a.c | |||
@@ -3581,6 +3581,7 @@ int gr_gk20a_add_zbc(struct gk20a *g, struct gr_gk20a *gr, | |||
3581 | 3581 | ||
3582 | /* no endian swap ? */ | 3582 | /* no endian swap ? */ |
3583 | 3583 | ||
3584 | mutex_lock(&gr->zbc_lock); | ||
3584 | switch (zbc_val->type) { | 3585 | switch (zbc_val->type) { |
3585 | case GK20A_ZBC_TYPE_COLOR: | 3586 | case GK20A_ZBC_TYPE_COLOR: |
3586 | /* search existing tables */ | 3587 | /* search existing tables */ |
@@ -3596,7 +3597,8 @@ int gr_gk20a_add_zbc(struct gk20a *g, struct gr_gk20a *gr, | |||
3596 | sizeof(zbc_val->color_l2))) { | 3597 | sizeof(zbc_val->color_l2))) { |
3597 | gk20a_err(dev_from_gk20a(g), | 3598 | gk20a_err(dev_from_gk20a(g), |
3598 | "zbc l2 and ds color don't match with existing entries"); | 3599 | "zbc l2 and ds color don't match with existing entries"); |
3599 | return -EINVAL; | 3600 | ret = -EINVAL; |
3601 | goto err_mutex; | ||
3600 | } | 3602 | } |
3601 | added = true; | 3603 | added = true; |
3602 | c_tbl->ref_cnt++; | 3604 | c_tbl->ref_cnt++; |
@@ -3652,7 +3654,8 @@ int gr_gk20a_add_zbc(struct gk20a *g, struct gr_gk20a *gr, | |||
3652 | default: | 3654 | default: |
3653 | gk20a_err(dev_from_gk20a(g), | 3655 | gk20a_err(dev_from_gk20a(g), |
3654 | "invalid zbc table type %d", zbc_val->type); | 3656 | "invalid zbc table type %d", zbc_val->type); |
3655 | return -EINVAL; | 3657 | ret = -EINVAL; |
3658 | goto err_mutex; | ||
3656 | } | 3659 | } |
3657 | 3660 | ||
3658 | if (!added && ret == 0) { | 3661 | if (!added && ret == 0) { |
@@ -3662,89 +3665,8 @@ int gr_gk20a_add_zbc(struct gk20a *g, struct gr_gk20a *gr, | |||
3662 | gr_gk20a_pmu_save_zbc(g, entries); | 3665 | gr_gk20a_pmu_save_zbc(g, entries); |
3663 | } | 3666 | } |
3664 | 3667 | ||
3665 | return ret; | 3668 | err_mutex: |
3666 | } | 3669 | mutex_unlock(&gr->zbc_lock); |
3667 | |||
3668 | int gr_gk20a_clear_zbc_table(struct gk20a *g, struct gr_gk20a *gr) | ||
3669 | { | ||
3670 | struct fifo_gk20a *f = &g->fifo; | ||
3671 | struct fifo_engine_info_gk20a *gr_info = f->engine_info + ENGINE_GR_GK20A; | ||
3672 | u32 i, j; | ||
3673 | unsigned long end_jiffies = jiffies + | ||
3674 | msecs_to_jiffies(gk20a_get_gr_idle_timeout(g)); | ||
3675 | u32 ret; | ||
3676 | |||
3677 | ret = gk20a_fifo_disable_engine_activity(g, gr_info, true); | ||
3678 | if (ret) { | ||
3679 | gk20a_err(dev_from_gk20a(g), | ||
3680 | "failed to disable gr engine activity\n"); | ||
3681 | return ret; | ||
3682 | } | ||
3683 | |||
3684 | ret = gr_gk20a_wait_idle(g, end_jiffies, GR_IDLE_CHECK_DEFAULT); | ||
3685 | if (ret) { | ||
3686 | gk20a_err(dev_from_gk20a(g), | ||
3687 | "failed to idle graphics\n"); | ||
3688 | goto clean_up; | ||
3689 | } | ||
3690 | |||
3691 | for (i = 0; i < GK20A_ZBC_TABLE_SIZE; i++) { | ||
3692 | gr->zbc_col_tbl[i].format = 0; | ||
3693 | gr->zbc_col_tbl[i].ref_cnt = 0; | ||
3694 | |||
3695 | gk20a_writel(g, gr_ds_zbc_color_fmt_r(), | ||
3696 | gr_ds_zbc_color_fmt_val_invalid_f()); | ||
3697 | gk20a_writel(g, gr_ds_zbc_tbl_index_r(), | ||
3698 | gr_ds_zbc_tbl_index_val_f(i + GK20A_STARTOF_ZBC_TABLE)); | ||
3699 | |||
3700 | /* trigger the write */ | ||
3701 | gk20a_writel(g, gr_ds_zbc_tbl_ld_r(), | ||
3702 | gr_ds_zbc_tbl_ld_select_c_f() | | ||
3703 | gr_ds_zbc_tbl_ld_action_write_f() | | ||
3704 | gr_ds_zbc_tbl_ld_trigger_active_f()); | ||
3705 | |||
3706 | /* clear l2 table */ | ||
3707 | g->ops.ltc.clear_zbc_color_entry(g, i); | ||
3708 | |||
3709 | for (j = 0; j < GK20A_ZBC_COLOR_VALUE_SIZE; j++) { | ||
3710 | gr->zbc_col_tbl[i].color_l2[j] = 0; | ||
3711 | gr->zbc_col_tbl[i].color_ds[j] = 0; | ||
3712 | } | ||
3713 | } | ||
3714 | gr->max_used_color_index = 0; | ||
3715 | gr->max_default_color_index = 0; | ||
3716 | |||
3717 | for (i = 0; i < GK20A_ZBC_TABLE_SIZE; i++) { | ||
3718 | gr->zbc_dep_tbl[i].depth = 0; | ||
3719 | gr->zbc_dep_tbl[i].format = 0; | ||
3720 | gr->zbc_dep_tbl[i].ref_cnt = 0; | ||
3721 | |||
3722 | gk20a_writel(g, gr_ds_zbc_z_fmt_r(), | ||
3723 | gr_ds_zbc_z_fmt_val_invalid_f()); | ||
3724 | gk20a_writel(g, gr_ds_zbc_tbl_index_r(), | ||
3725 | gr_ds_zbc_tbl_index_val_f(i + GK20A_STARTOF_ZBC_TABLE)); | ||
3726 | |||
3727 | /* trigger the write */ | ||
3728 | gk20a_writel(g, gr_ds_zbc_tbl_ld_r(), | ||
3729 | gr_ds_zbc_tbl_ld_select_z_f() | | ||
3730 | gr_ds_zbc_tbl_ld_action_write_f() | | ||
3731 | gr_ds_zbc_tbl_ld_trigger_active_f()); | ||
3732 | |||
3733 | /* clear l2 table */ | ||
3734 | g->ops.ltc.clear_zbc_depth_entry(g, i); | ||
3735 | } | ||
3736 | gr->max_used_depth_index = 0; | ||
3737 | gr->max_default_depth_index = 0; | ||
3738 | |||
3739 | clean_up: | ||
3740 | ret = gk20a_fifo_enable_engine_activity(g, gr_info); | ||
3741 | if (ret) { | ||
3742 | gk20a_err(dev_from_gk20a(g), | ||
3743 | "failed to enable gr engine activity\n"); | ||
3744 | } | ||
3745 | |||
3746 | /* elpg stuff */ | ||
3747 | |||
3748 | return ret; | 3670 | return ret; |
3749 | } | 3671 | } |
3750 | 3672 | ||
@@ -3794,6 +3716,42 @@ int gr_gk20a_query_zbc(struct gk20a *g, struct gr_gk20a *gr, | |||
3794 | return 0; | 3716 | return 0; |
3795 | } | 3717 | } |
3796 | 3718 | ||
3719 | int gr_gk20a_load_zbc_table(struct gk20a *g, struct gr_gk20a *gr) | ||
3720 | { | ||
3721 | int i, ret; | ||
3722 | |||
3723 | mutex_init(&gr->zbc_lock); | ||
3724 | for (i = 0; i < gr->max_used_color_index; i++) { | ||
3725 | struct zbc_color_table *c_tbl = &gr->zbc_col_tbl[i]; | ||
3726 | struct zbc_entry zbc_val; | ||
3727 | |||
3728 | zbc_val.type = GK20A_ZBC_TYPE_COLOR; | ||
3729 | memcpy(zbc_val.color_ds, | ||
3730 | c_tbl->color_ds, sizeof(zbc_val.color_ds)); | ||
3731 | memcpy(zbc_val.color_l2, | ||
3732 | c_tbl->color_l2, sizeof(zbc_val.color_l2)); | ||
3733 | zbc_val.format = c_tbl->format; | ||
3734 | |||
3735 | ret = gr_gk20a_add_zbc_color(g, gr, &zbc_val, i); | ||
3736 | |||
3737 | if (ret) | ||
3738 | return ret; | ||
3739 | } | ||
3740 | for (i = 0; i < gr->max_used_depth_index; i++) { | ||
3741 | struct zbc_depth_table *d_tbl = &gr->zbc_dep_tbl[i]; | ||
3742 | struct zbc_entry zbc_val; | ||
3743 | |||
3744 | zbc_val.type = GK20A_ZBC_TYPE_DEPTH; | ||
3745 | zbc_val.depth = d_tbl->depth; | ||
3746 | zbc_val.format = d_tbl->format; | ||
3747 | |||
3748 | ret = gr_gk20a_add_zbc_depth(g, gr, &zbc_val, i); | ||
3749 | if (ret) | ||
3750 | return ret; | ||
3751 | } | ||
3752 | return 0; | ||
3753 | } | ||
3754 | |||
3797 | int gr_gk20a_load_zbc_default_table(struct gk20a *g, struct gr_gk20a *gr) | 3755 | int gr_gk20a_load_zbc_default_table(struct gk20a *g, struct gr_gk20a *gr) |
3798 | { | 3756 | { |
3799 | struct zbc_entry zbc_val; | 3757 | struct zbc_entry zbc_val; |
@@ -4286,7 +4244,11 @@ static int gk20a_init_gr_setup_hw(struct gk20a *g) | |||
4286 | data = gk20a_readl(g, gr_status_mask_r()); | 4244 | data = gk20a_readl(g, gr_status_mask_r()); |
4287 | gk20a_writel(g, gr_status_mask_r(), data & gr->status_disable_mask); | 4245 | gk20a_writel(g, gr_status_mask_r(), data & gr->status_disable_mask); |
4288 | 4246 | ||
4289 | g->ops.ltc.init_zbc(g, gr); | 4247 | if (gr->sw_ready) |
4248 | gr_gk20a_load_zbc_table(g, gr); | ||
4249 | else | ||
4250 | gr_gk20a_load_zbc_default_table(g, gr); | ||
4251 | |||
4290 | g->ops.ltc.init_cbc(g, gr); | 4252 | g->ops.ltc.init_cbc(g, gr); |
4291 | 4253 | ||
4292 | /* load ctx init */ | 4254 | /* load ctx init */ |