From aef3564ff85a9ddf49eb7a1349dec04ec243970d Mon Sep 17 00:00:00 2001 From: Marcel Ziswiler Date: Fri, 16 Nov 2012 17:13:59 +0100 Subject: android: dc: tegra: video: conditionally revert timestamp support Android R14 userspace seems to have issues with timestamp support: [ 14.764337] host1x host1x: SurfaceFlinger: syncpoint id 8 (disp0_a) stuck waiting 3, timeout=2147483447 [ 14.773845] host1x host1x: id 8 (disp0_a) min 2 max 4 [ 14.779163] host1x host1x: id 9 (disp1_a) min 2 max 4 [ 14.784316] host1x host1x: id 18 (2d_0) min 21 max 25 [ 14.789586] host1x host1x: id 20 (disp0_b) min 2 max 4 [ 14.794889] host1x host1x: id 21 (disp1_b) min 2 max 4 [ 14.800241] host1x host1x: id 22 (3d) min 77 max 95 [ 14.805217] host1x host1x: id 24 (disp0_c) min 2 max 4 [ 14.810573] host1x host1x: id 25 (disp1_c) min 2 max 4 [ 14.815873] host1x host1x: id 26 (vblank0) min 800 max 0 [ 14.821264] host1x host1x: id 27 (vblank1) min 684 max 0 [ 14.826810] host1x host1x: waitbase id 3 val 77 Therefore conditionally revert it in that case for now. See e4e2e776a3d4bf1adf37fc061cfdfb92281f3ace. --- drivers/video/tegra/dc/dc.c | 6 ++++++ drivers/video/tegra/dc/dc_priv.h | 6 ++++++ drivers/video/tegra/dc/ext/dev.c | 28 +++++++++++++++++++++++++- drivers/video/tegra/dc/ext/tegra_dc_ext_priv.h | 2 ++ drivers/video/tegra/dc/mode.c | 4 ++++ drivers/video/tegra/dc/window.c | 15 +++++++++++++- 6 files changed, 59 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/video/tegra/dc/dc.c b/drivers/video/tegra/dc/dc.c index d01df2f520b8..ca2103f73c8a 100644 --- a/drivers/video/tegra/dc/dc.c +++ b/drivers/video/tegra/dc/dc.c @@ -1082,9 +1082,11 @@ static void tegra_dc_continuous_irq(struct tegra_dc *dc, unsigned long status) queue_work(system_freezable_wq, &dc->vblank_work); if (status & FRAME_END_INT) { +#ifndef CONFIG_ANDROID struct timespec tm = CURRENT_TIME; dc->frame_end_timestamp = timespec_to_ns(&tm); wake_up(&dc->timestamp_wq); +#endif /* !CONFIG_ANDROID */ /* Mark the frame_end as complete. */ if (!completion_done(&dc->frame_end_complete)) @@ -1094,6 +1096,7 @@ static void tegra_dc_continuous_irq(struct tegra_dc *dc, unsigned long status) } } +#ifndef CONFIG_ANDROID /* XXX: Not sure if we limit look ahead to 1 frame */ bool tegra_dc_is_within_n_vsync(struct tegra_dc *dc, s64 ts) { @@ -1109,6 +1112,7 @@ bool tegra_dc_does_vsync_separate(struct tegra_dc *dc, s64 new_ts, s64 old_ts) != div_s64((old_ts - dc->frame_end_timestamp), dc->frametime_ns))); } +#endif /* !CONFIG_ANDROID */ #endif static irqreturn_t tegra_dc_irq(int irq, void *ptr) @@ -1824,7 +1828,9 @@ static int tegra_dc_probe(struct nvhost_device *ndev, mutex_init(&dc->one_shot_lock); init_completion(&dc->frame_end_complete); init_waitqueue_head(&dc->wq); +#ifndef CONFIG_ANDROID init_waitqueue_head(&dc->timestamp_wq); +#endif /* !CONFIG_ANDROID */ #ifdef CONFIG_ARCH_TEGRA_2x_SOC INIT_WORK(&dc->reset_work, tegra_dc_reset_worker); #endif diff --git a/drivers/video/tegra/dc/dc_priv.h b/drivers/video/tegra/dc/dc_priv.h index 75c3a2a29658..e91071f70ddc 100644 --- a/drivers/video/tegra/dc/dc_priv.h +++ b/drivers/video/tegra/dc/dc_priv.h @@ -113,14 +113,18 @@ struct tegra_dc { void *out_data; struct tegra_dc_mode mode; +#ifndef CONFIG_ANDROID s64 frametime_ns; +#endif /* !CONFIG_ANDROID */ struct tegra_dc_win windows[DC_N_WINDOWS]; struct tegra_dc_blend blend; int n_windows; wait_queue_head_t wq; +#ifndef CONFIG_ANDROID wait_queue_head_t timestamp_wq; +#endif /* !CONFIG_ANDROID */ struct mutex lock; struct mutex one_shot_lock; @@ -165,7 +169,9 @@ struct tegra_dc { struct delayed_work underflow_work; u32 one_shot_delay_ms; struct delayed_work one_shot_work; +#ifndef CONFIG_ANDROID s64 frame_end_timestamp; +#endif /* !CONFIG_ANDROID */ }; #define print_mode_info(dc, mode) do { \ diff --git a/drivers/video/tegra/dc/ext/dev.c b/drivers/video/tegra/dc/ext/dev.c index 88273e26c51c..c8104deb5ed6 100644 --- a/drivers/video/tegra/dc/ext/dev.c +++ b/drivers/video/tegra/dc/ext/dev.c @@ -56,7 +56,9 @@ struct tegra_dc_ext_flip_data { struct tegra_dc_ext *ext; struct work_struct work; struct tegra_dc_ext_flip_win win[DC_N_WINDOWS]; +#ifndef CONFIG_ANDROID struct list_head timestamp_node; +#endif /* !CONFIG_ANDROID */ }; int tegra_dc_ext_get_num_outputs(void) @@ -208,7 +210,9 @@ static int tegra_dc_ext_set_windowattr(struct tegra_dc_ext *ext, { int err = 0; struct tegra_dc_ext_win *ext_win = &ext->win[win->idx]; +#ifndef CONFIG_ANDROID s64 timestamp_ns; +#endif /* !CONFIG_ANDROID */ if (flip_win->handle[TEGRA_DC_Y] == NULL) { win->flags = 0; @@ -272,6 +276,7 @@ static int tegra_dc_ext_set_windowattr(struct tegra_dc_ext *ext, msecs_to_jiffies(500), NULL); } +#ifndef CONFIG_ANDROID #ifndef CONFIG_TEGRA_SIMULATION_PLATFORM timestamp_ns = timespec_to_ns(&flip_win->attr.timestamp); @@ -286,6 +291,9 @@ static int tegra_dc_ext_set_windowattr(struct tegra_dc_ext *ext, } #endif return err; +#else /* !CONFIG_ANDROID */ + return 0; +#endif /* !CONFIG_ANDROID */ } static void (*flip_callback)(void); @@ -337,11 +345,14 @@ static void tegra_dc_ext_flip_worker(struct work_struct *work) for (i = 0; i < DC_N_WINDOWS; i++) { struct tegra_dc_ext_flip_win *flip_win = &data->win[i]; - int j = 0, index = flip_win->attr.index; + int index = flip_win->attr.index; struct tegra_dc_win *win; struct tegra_dc_ext_win *ext_win; +#ifndef CONFIG_ANDROID + int j = 0; struct tegra_dc_ext_flip_data *temp = NULL; s64 head_timestamp = 0; +#endif /* !CONFIG_ANDROID */ if (index < 0) continue; @@ -353,6 +364,7 @@ static void tegra_dc_ext_flip_worker(struct work_struct *work) (flip_win->attr.flags & TEGRA_DC_EXT_FLIP_FLAG_CURSOR)) skip_flip = true; +#ifndef CONFIG_ANDROID mutex_lock(&ext_win->queue_lock); list_for_each_entry(temp, &ext_win->timestamp_queue, timestamp_node) { @@ -377,6 +389,7 @@ static void tegra_dc_ext_flip_worker(struct work_struct *work) if (!list_empty(&ext_win->timestamp_queue)) list_del(&data->timestamp_node); mutex_unlock(&ext_win->queue_lock); +#endif /* !CONFIG_ANDROID */ if (win->flags & TEGRA_WIN_FLAG_ENABLED) { int j; @@ -409,6 +422,9 @@ static void tegra_dc_ext_flip_worker(struct work_struct *work) flip_callback(); spin_unlock(&flip_callback_lock); } +#ifdef CONFIG_ANDROID + } +#endif /* CONFIG_ANDROID */ for (i = 0; i < DC_N_WINDOWS; i++) { struct tegra_dc_ext_flip_win *flip_win = &data->win[i]; @@ -420,7 +436,9 @@ static void tegra_dc_ext_flip_worker(struct work_struct *work) tegra_dc_incr_syncpt_min(ext->dc, index, flip_win->syncpt_max); } +#ifndef CONFIG_ANDROID } +#endif /* !CONFIG_ANDROID */ /* unpin and deref previous front buffers */ for (i = 0; i < nr_unpin; i++) { @@ -531,7 +549,9 @@ static int tegra_dc_ext_flip(struct tegra_dc_ext_user *user, struct tegra_dc_ext_flip_data *data; int work_index = -1; int i, ret = 0; +#ifndef CONFIG_ANDROID bool has_timestamp = false; +#endif /* !CONFIG_ANDROID */ #ifdef CONFIG_ANDROID int index_check[DC_N_WINDOWS] = {0, }; @@ -572,8 +592,10 @@ static int tegra_dc_ext_flip(struct tegra_dc_ext_user *user, int index = args->win[i].index; memcpy(&flip_win->attr, &args->win[i], sizeof(flip_win->attr)); +#ifndef CONFIG_ANDROID if (timespec_to_ns(&flip_win->attr.timestamp)) has_timestamp = true; +#endif /* !CONFIG_ANDROID */ if (index < 0) continue; @@ -648,11 +670,13 @@ static int tegra_dc_ext_flip(struct tegra_dc_ext_user *user, ret = -EINVAL; goto unlock; } +#ifndef CONFIG_ANDROID if (has_timestamp) { mutex_lock(&ext->win[work_index].queue_lock); list_add_tail(&data->timestamp_node, &ext->win[work_index].timestamp_queue); mutex_unlock(&ext->win[work_index].queue_lock); } +#endif /* !CONFIG_ANDROID */ queue_work(ext->win[work_index].flip_wq, &data->work); unlock_windows_for_flip(user, args); @@ -993,8 +1017,10 @@ static int tegra_dc_ext_setup_windows(struct tegra_dc_ext *ext) } mutex_init(&win->lock); +#ifndef CONFIG_ANDROID mutex_init(&win->queue_lock); INIT_LIST_HEAD(&win->timestamp_queue); +#endif /* !CONFIG_ANDROID */ } return 0; diff --git a/drivers/video/tegra/dc/ext/tegra_dc_ext_priv.h b/drivers/video/tegra/dc/ext/tegra_dc_ext_priv.h index ef7361d1d933..7238e95e59db 100644 --- a/drivers/video/tegra/dc/ext/tegra_dc_ext_priv.h +++ b/drivers/video/tegra/dc/ext/tegra_dc_ext_priv.h @@ -59,9 +59,11 @@ struct tegra_dc_ext_win { atomic_t nr_pending_flips; +#ifndef CONFIG_ANDROID struct mutex queue_lock; struct list_head timestamp_queue; +#endif /* !CONFIG_ANDROID */ }; struct tegra_dc_ext { diff --git a/drivers/video/tegra/dc/mode.c b/drivers/video/tegra/dc/mode.c index 3a95f2e7ab0e..6457f9604e90 100644 --- a/drivers/video/tegra/dc/mode.c +++ b/drivers/video/tegra/dc/mode.c @@ -137,6 +137,7 @@ static bool check_ref_to_sync(struct tegra_dc_mode *mode) return true; } +#ifndef CONFIG_ANDROID static s64 calc_frametime_ns(const struct tegra_dc_mode *m) { long h_total, v_total; @@ -147,6 +148,7 @@ static s64 calc_frametime_ns(const struct tegra_dc_mode *m) return (!m->pclk) ? 0 : (s64)(div_s64(((s64)h_total * v_total * 1000000000ULL), m->pclk)); } +#endif /* !CONFIG_ANDROID */ /* return in 1000ths of a Hertz */ int tegra_dc_calc_refresh(const struct tegra_dc_mode *m) @@ -276,7 +278,9 @@ int tegra_dc_set_mode(struct tegra_dc *dc, const struct tegra_dc_mode *mode) panel_sync_rate = dc->out->dsi->rated_refresh_rate * 1000; print_mode(dc, mode, __func__); +#ifndef CONFIG_ANDROID dc->frametime_ns = calc_frametime_ns(mode); +#endif /* !CONFIG_ANDROID */ return 0; } diff --git a/drivers/video/tegra/dc/window.c b/drivers/video/tegra/dc/window.c index cd91fab428ed..af18564f45b9 100644 --- a/drivers/video/tegra/dc/window.c +++ b/drivers/video/tegra/dc/window.c @@ -24,7 +24,9 @@ #include "dc_priv.h" static int no_vsync; +#ifndef CONFIG_ANDROID static atomic_t frame_end_ref = ATOMIC_INIT(0); +#endif /* !CONFIG_ANDROID */ module_param_named(no_vsync, no_vsync, int, S_IRUGO | S_IWUSR); @@ -41,6 +43,7 @@ static bool tegra_dc_windows_are_clean(struct tegra_dc_win *windows[], return true; } +#ifndef CONFIG_ANDROID int tegra_dc_config_frame_end_intr(struct tegra_dc *dc, bool enable) { tegra_dc_writel(dc, FRAME_END_INT, DC_CMD_INT_STATUS); @@ -51,6 +54,7 @@ int tegra_dc_config_frame_end_intr(struct tegra_dc *dc, bool enable) tegra_dc_mask_interrupt(dc, FRAME_END_INT); return 0; } +#endif /* !CONFIG_ANDROID */ static int get_topmost_window(u32 *depths, unsigned long *wins) { @@ -418,9 +422,14 @@ int tegra_dc_update_windows(struct tegra_dc_win *windows[], int n) FRAME_END_INT | V_BLANK_INT | ALL_UF_INT); } else { clear_bit(V_BLANK_FLIP, &dc->vblank_ref_count); - tegra_dc_mask_interrupt(dc, V_BLANK_INT | ALL_UF_INT); + tegra_dc_mask_interrupt(dc, +#ifndef CONFIG_ANDROID + V_BLANK_INT | ALL_UF_INT); if (!atomic_read(&frame_end_ref)) tegra_dc_mask_interrupt(dc, FRAME_END_INT); +#else /* !CONFIG_ANDROID */ + FRAME_END_INT | V_BLANK_INT | ALL_UF_INT); +#endif /* !CONFIG_ANDROID */ } if (dc->out->flags & TEGRA_DC_OUT_ONE_SHOT_MODE) @@ -470,7 +479,11 @@ void tegra_dc_trigger_windows(struct tegra_dc *dc) if (!dirty) { if (!(dc->out->flags & TEGRA_DC_OUT_ONE_SHOT_MODE) +#ifndef CONFIG_ANDROID && !atomic_read(&frame_end_ref)) +#else /* !CONFIG_ANDROID */ + ) +#endif /* !CONFIG_ANDROID */ tegra_dc_mask_interrupt(dc, FRAME_END_INT); } -- cgit v1.2.3