From ea76deaa6a6da3167a3baf7fdcf10b9ebc92d296 Mon Sep 17 00:00:00 2001 From: Kevin Huang Date: Wed, 2 Apr 2014 18:36:42 -0700 Subject: video: tegra: host: fix the bundle corruption Wait for FE idle between SW bundles. Bug 1477234 Bug 1486347 Bug 1485069 Change-Id: I5181b1240fff73cfecd07aa3e54076cde800ea00 Signed-off-by: Kevin Huang Reviewed-on: http://git-master/r/391591 Reviewed-by: Terje Bergstrom Tested-by: Terje Bergstrom --- drivers/gpu/nvgpu/gk20a/gr_gk20a.c | 31 ++++++++++++++++++++++++++++++- drivers/gpu/nvgpu/gk20a/hw_gr_gk20a.h | 8 ++++++++ 2 files changed, 38 insertions(+), 1 deletion(-) (limited to 'drivers/gpu/nvgpu') diff --git a/drivers/gpu/nvgpu/gk20a/gr_gk20a.c b/drivers/gpu/nvgpu/gk20a/gr_gk20a.c index 0f93940b..ced1f62f 100644 --- a/drivers/gpu/nvgpu/gk20a/gr_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/gr_gk20a.c @@ -322,6 +322,34 @@ static int gr_gk20a_wait_idle(struct gk20a *g, unsigned long end_jiffies, return -EAGAIN; } +static int gr_gk20a_wait_fe_idle(struct gk20a *g, unsigned long end_jiffies, + u32 expect_delay) +{ + u32 val; + u32 delay = expect_delay; + + gk20a_dbg_fn(""); + + do { + val = gk20a_readl(g, gr_status_r()); + + if (!gr_status_fe_method_upper_v(val) && + !gr_status_fe_method_lower_v(val) && + !gr_status_fe_method_fe_gi_v(val)) { + gk20a_dbg_fn("done"); + return 0; + } + + usleep_range(delay, delay * 2); + delay = min_t(u32, delay << 1, GR_IDLE_CHECK_MAX); + } while (time_before(jiffies, end_jiffies) + || !tegra_platform_is_silicon()); + + gk20a_err(dev_from_gk20a(g), + "timeout, fe busy : %x", val); + + return -EAGAIN; +} static int gr_gk20a_ctx_reset(struct gk20a *g, u32 rst_mask) { u32 delay = GR_IDLE_CHECK_DEFAULT; @@ -1475,7 +1503,8 @@ static u32 gk20a_init_sw_bundle(struct gk20a *g) /* load bundle init */ for (i = 0; i < sw_bundle_init->count; i++) { - + err |= gr_gk20a_wait_fe_idle(g, end_jiffies, + GR_IDLE_CHECK_DEFAULT); if (i == 0 || last_bundle_data != sw_bundle_init->l[i].value) { gk20a_writel(g, gr_pipe_bundle_data_r(), sw_bundle_init->l[i].value); diff --git a/drivers/gpu/nvgpu/gk20a/hw_gr_gk20a.h b/drivers/gpu/nvgpu/gk20a/hw_gr_gk20a.h index ece7602d..4e7ada14 100644 --- a/drivers/gpu/nvgpu/gk20a/hw_gr_gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/hw_gr_gk20a.h @@ -234,6 +234,10 @@ static inline u32 gr_status_r(void) { return 0x00400700; } +static inline u32 gr_status_fe_method_upper_v(u32 r) +{ + return (r >> 1) & 0x1; +} static inline u32 gr_status_fe_method_lower_v(u32 r) { return (r >> 2) & 0x1; @@ -242,6 +246,10 @@ static inline u32 gr_status_fe_method_lower_idle_v(void) { return 0x00000000; } +static inline u32 gr_status_fe_method_fe_gi_v(u32 r) +{ + return (r >> 21) & 0x1; +} static inline u32 gr_status_mask_r(void) { return 0x00400610; -- cgit v1.2.2