diff options
author | Konsta Holtta <kholtta@nvidia.com> | 2015-03-09 06:07:04 -0400 |
---|---|---|
committer | Dan Willemsen <dwillemsen@nvidia.com> | 2015-04-04 22:00:42 -0400 |
commit | 84aae5639e95c8130bad8b6ea7808a240bef6bd2 (patch) | |
tree | 6d413a25837f14bd8b35433305e0c3d6799d362a /drivers/gpu/nvgpu/gk20a/gr_gk20a.c | |
parent | 5b28f2fe75328ad7a060d987f3b988521706056e (diff) |
gpu: nvgpu: zbc: disable activity only from ioctl
Move the fifo engine activity disabling and wait-for-idle from the
lowest-level functions higher, into the ioctl path of zbc operations, so
that the sw initialization path wouldn't call them. During the init
path, the disable isn't necessary, and the code path could result in a
deadlock in the fifo runlist mutex.
Change-Id: Ia3d768b7ad2d829416a1144486e6788d3177eb04
Signed-off-by: Konsta Holtta <kholtta@nvidia.com>
Reviewed-on: http://git-master/r/715195
Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com>
Tested-by: Terje Bergstrom <tbergstrom@nvidia.com>
Diffstat (limited to 'drivers/gpu/nvgpu/gk20a/gr_gk20a.c')
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/gr_gk20a.c | 125 |
1 files changed, 38 insertions, 87 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/gr_gk20a.c b/drivers/gpu/nvgpu/gk20a/gr_gk20a.c index b5de90c0..0aa0037f 100644 --- a/drivers/gpu/nvgpu/gk20a/gr_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/gr_gk20a.c | |||
@@ -3494,26 +3494,7 @@ static void gr_gk20a_detect_sm_arch(struct gk20a *g) | |||
3494 | int gr_gk20a_add_zbc_color(struct gk20a *g, struct gr_gk20a *gr, | 3494 | int gr_gk20a_add_zbc_color(struct gk20a *g, struct gr_gk20a *gr, |
3495 | struct zbc_entry *color_val, u32 index) | 3495 | struct zbc_entry *color_val, u32 index) |
3496 | { | 3496 | { |
3497 | struct fifo_gk20a *f = &g->fifo; | ||
3498 | struct fifo_engine_info_gk20a *gr_info = f->engine_info + ENGINE_GR_GK20A; | ||
3499 | u32 i; | 3497 | u32 i; |
3500 | unsigned long end_jiffies = jiffies + | ||
3501 | msecs_to_jiffies(gk20a_get_gr_idle_timeout(g)); | ||
3502 | u32 ret; | ||
3503 | |||
3504 | ret = gk20a_fifo_disable_engine_activity(g, gr_info, true); | ||
3505 | if (ret) { | ||
3506 | gk20a_err(dev_from_gk20a(g), | ||
3507 | "failed to disable gr engine activity\n"); | ||
3508 | return ret; | ||
3509 | } | ||
3510 | |||
3511 | ret = gr_gk20a_wait_idle(g, end_jiffies, GR_IDLE_CHECK_DEFAULT); | ||
3512 | if (ret) { | ||
3513 | gk20a_err(dev_from_gk20a(g), | ||
3514 | "failed to idle graphics\n"); | ||
3515 | goto clean_up; | ||
3516 | } | ||
3517 | 3498 | ||
3518 | /* update l2 table */ | 3499 | /* update l2 table */ |
3519 | g->ops.ltc.set_zbc_color_entry(g, color_val, index); | 3500 | g->ops.ltc.set_zbc_color_entry(g, color_val, index); |
@@ -3548,39 +3529,12 @@ int gr_gk20a_add_zbc_color(struct gk20a *g, struct gr_gk20a *gr, | |||
3548 | gr->zbc_col_tbl[index].format = color_val->format; | 3529 | gr->zbc_col_tbl[index].format = color_val->format; |
3549 | gr->zbc_col_tbl[index].ref_cnt++; | 3530 | gr->zbc_col_tbl[index].ref_cnt++; |
3550 | 3531 | ||
3551 | clean_up: | 3532 | return 0; |
3552 | ret = gk20a_fifo_enable_engine_activity(g, gr_info); | ||
3553 | if (ret) { | ||
3554 | gk20a_err(dev_from_gk20a(g), | ||
3555 | "failed to enable gr engine activity\n"); | ||
3556 | } | ||
3557 | |||
3558 | return ret; | ||
3559 | } | 3533 | } |
3560 | 3534 | ||
3561 | int gr_gk20a_add_zbc_depth(struct gk20a *g, struct gr_gk20a *gr, | 3535 | int gr_gk20a_add_zbc_depth(struct gk20a *g, struct gr_gk20a *gr, |
3562 | struct zbc_entry *depth_val, u32 index) | 3536 | struct zbc_entry *depth_val, u32 index) |
3563 | { | 3537 | { |
3564 | struct fifo_gk20a *f = &g->fifo; | ||
3565 | struct fifo_engine_info_gk20a *gr_info = f->engine_info + ENGINE_GR_GK20A; | ||
3566 | unsigned long end_jiffies = jiffies + | ||
3567 | msecs_to_jiffies(gk20a_get_gr_idle_timeout(g)); | ||
3568 | u32 ret; | ||
3569 | |||
3570 | ret = gk20a_fifo_disable_engine_activity(g, gr_info, true); | ||
3571 | if (ret) { | ||
3572 | gk20a_err(dev_from_gk20a(g), | ||
3573 | "failed to disable gr engine activity\n"); | ||
3574 | return ret; | ||
3575 | } | ||
3576 | |||
3577 | ret = gr_gk20a_wait_idle(g, end_jiffies, GR_IDLE_CHECK_DEFAULT); | ||
3578 | if (ret) { | ||
3579 | gk20a_err(dev_from_gk20a(g), | ||
3580 | "failed to idle graphics\n"); | ||
3581 | goto clean_up; | ||
3582 | } | ||
3583 | |||
3584 | /* update l2 table */ | 3538 | /* update l2 table */ |
3585 | g->ops.ltc.set_zbc_depth_entry(g, depth_val, index); | 3539 | g->ops.ltc.set_zbc_depth_entry(g, depth_val, index); |
3586 | 3540 | ||
@@ -3605,50 +3559,12 @@ int gr_gk20a_add_zbc_depth(struct gk20a *g, struct gr_gk20a *gr, | |||
3605 | gr->zbc_dep_tbl[index].format = depth_val->format; | 3559 | gr->zbc_dep_tbl[index].format = depth_val->format; |
3606 | gr->zbc_dep_tbl[index].ref_cnt++; | 3560 | gr->zbc_dep_tbl[index].ref_cnt++; |
3607 | 3561 | ||
3608 | clean_up: | 3562 | return 0; |
3609 | ret = gk20a_fifo_enable_engine_activity(g, gr_info); | ||
3610 | if (ret) { | ||
3611 | gk20a_err(dev_from_gk20a(g), | ||
3612 | "failed to enable gr engine activity\n"); | ||
3613 | } | ||
3614 | |||
3615 | return ret; | ||
3616 | } | 3563 | } |
3617 | 3564 | ||
3618 | void gr_gk20a_pmu_save_zbc(struct gk20a *g, u32 entries) | 3565 | void gr_gk20a_pmu_save_zbc(struct gk20a *g, u32 entries) |
3619 | { | 3566 | { |
3620 | struct fifo_gk20a *f = &g->fifo; | ||
3621 | struct fifo_engine_info_gk20a *gr_info = | ||
3622 | f->engine_info + ENGINE_GR_GK20A; | ||
3623 | unsigned long end_jiffies = jiffies + | ||
3624 | msecs_to_jiffies(gk20a_get_gr_idle_timeout(g)); | ||
3625 | u32 ret; | ||
3626 | |||
3627 | ret = gk20a_fifo_disable_engine_activity(g, gr_info, true); | ||
3628 | if (ret) { | ||
3629 | gk20a_err(dev_from_gk20a(g), | ||
3630 | "failed to disable gr engine activity\n"); | ||
3631 | return; | ||
3632 | } | ||
3633 | |||
3634 | ret = gr_gk20a_wait_idle(g, end_jiffies, GR_IDLE_CHECK_DEFAULT); | ||
3635 | if (ret) { | ||
3636 | gk20a_err(dev_from_gk20a(g), | ||
3637 | "failed to idle graphics\n"); | ||
3638 | goto clean_up; | ||
3639 | } | ||
3640 | |||
3641 | /* update zbc */ | ||
3642 | gk20a_pmu_save_zbc(g, entries); | 3567 | gk20a_pmu_save_zbc(g, entries); |
3643 | |||
3644 | clean_up: | ||
3645 | ret = gk20a_fifo_enable_engine_activity(g, gr_info); | ||
3646 | if (ret) { | ||
3647 | gk20a_err(dev_from_gk20a(g), | ||
3648 | "failed to enable gr engine activity\n"); | ||
3649 | } | ||
3650 | |||
3651 | return; | ||
3652 | } | 3568 | } |
3653 | 3569 | ||
3654 | int gr_gk20a_add_zbc(struct gk20a *g, struct gr_gk20a *gr, | 3570 | int gr_gk20a_add_zbc(struct gk20a *g, struct gr_gk20a *gr, |
@@ -3898,13 +3814,48 @@ int gr_gk20a_load_zbc_default_table(struct gk20a *g, struct gr_gk20a *gr) | |||
3898 | return 0; | 3814 | return 0; |
3899 | } | 3815 | } |
3900 | 3816 | ||
3817 | static int _gk20a_gr_zbc_set_table(struct gk20a *g, struct gr_gk20a *gr, | ||
3818 | struct zbc_entry *zbc_val) | ||
3819 | { | ||
3820 | struct fifo_gk20a *f = &g->fifo; | ||
3821 | struct fifo_engine_info_gk20a *gr_info = f->engine_info + ENGINE_GR_GK20A; | ||
3822 | unsigned long end_jiffies; | ||
3823 | int ret; | ||
3824 | |||
3825 | ret = gk20a_fifo_disable_engine_activity(g, gr_info, true); | ||
3826 | if (ret) { | ||
3827 | gk20a_err(dev_from_gk20a(g), | ||
3828 | "failed to disable gr engine activity\n"); | ||
3829 | return ret; | ||
3830 | } | ||
3831 | |||
3832 | end_jiffies = jiffies + msecs_to_jiffies(gk20a_get_gr_idle_timeout(g)); | ||
3833 | ret = gr_gk20a_wait_idle(g, end_jiffies, GR_IDLE_CHECK_DEFAULT); | ||
3834 | if (ret) { | ||
3835 | gk20a_err(dev_from_gk20a(g), | ||
3836 | "failed to idle graphics\n"); | ||
3837 | goto clean_up; | ||
3838 | } | ||
3839 | |||
3840 | ret = gr_gk20a_elpg_protected_call(g, | ||
3841 | gr_gk20a_add_zbc(g, gr, zbc_val)); | ||
3842 | |||
3843 | clean_up: | ||
3844 | if (gk20a_fifo_enable_engine_activity(g, gr_info)) { | ||
3845 | gk20a_err(dev_from_gk20a(g), | ||
3846 | "failed to enable gr engine activity\n"); | ||
3847 | } | ||
3848 | |||
3849 | return ret; | ||
3850 | } | ||
3851 | |||
3901 | int gk20a_gr_zbc_set_table(struct gk20a *g, struct gr_gk20a *gr, | 3852 | int gk20a_gr_zbc_set_table(struct gk20a *g, struct gr_gk20a *gr, |
3902 | struct zbc_entry *zbc_val) | 3853 | struct zbc_entry *zbc_val) |
3903 | { | 3854 | { |
3904 | gk20a_dbg_fn(""); | 3855 | gk20a_dbg_fn(""); |
3905 | 3856 | ||
3906 | return gr_gk20a_elpg_protected_call(g, | 3857 | return gr_gk20a_elpg_protected_call(g, |
3907 | gr_gk20a_add_zbc(g, gr, zbc_val)); | 3858 | _gk20a_gr_zbc_set_table(g, gr, zbc_val)); |
3908 | } | 3859 | } |
3909 | 3860 | ||
3910 | void gr_gk20a_init_blcg_mode(struct gk20a *g, u32 mode, u32 engine) | 3861 | void gr_gk20a_init_blcg_mode(struct gk20a *g, u32 mode, u32 engine) |