From 22e0897658b3250d50dd7f37b80ff3e35c9518a2 Mon Sep 17 00:00:00 2001 From: Dominik Sliwa Date: Thu, 22 Jun 2017 12:41:18 +0200 Subject: tegra: align graphics drivers with android binaries Some functionality used by android binary drivers were missing. Signed-off-by: Dominik Sliwa Acked-by: Marcel Ziswiler --- drivers/video/tegra/dc/ext/dev.c | 62 ++++++++++++++++++++++++++ drivers/video/tegra/dc/ext/tegra_dc_ext_priv.h | 3 +- include/video/tegra_dc_ext.h | 25 +++++++++-- 3 files changed, 86 insertions(+), 4 deletions(-) diff --git a/drivers/video/tegra/dc/ext/dev.c b/drivers/video/tegra/dc/ext/dev.c index 38dc4a928ee8..22aa82248173 100644 --- a/drivers/video/tegra/dc/ext/dev.c +++ b/drivers/video/tegra/dc/ext/dev.c @@ -114,6 +114,9 @@ struct tegra_dc_ext_flip_data { bool dirty_rect_valid; }; +static void tegra_dc_ext_unpin_window(struct tegra_dc_ext_win *win); +static int tegra_dc_ext_set_vblank(struct tegra_dc_ext *ext, bool enable); + static inline s64 tegra_timespec_to_ns(const struct tegra_timespec *ts) { return ((s64) ts->tv_sec * NSEC_PER_SEC) + ts->tv_nsec; @@ -230,8 +233,15 @@ void tegra_dc_ext_enable(struct tegra_dc_ext *ext) void tegra_dc_ext_disable(struct tegra_dc_ext *ext) { int i; + unsigned long int windows = 0; + set_enable(ext, false); + /* + * Disable vblank requests + */ + tegra_dc_ext_set_vblank(ext, false); + /* * Flush the flip queue -- note that this must be called with dc->lock * unlocked or else it will hang. @@ -241,6 +251,24 @@ void tegra_dc_ext_disable(struct tegra_dc_ext *ext) flush_workqueue(win->flip_wq); } + + /* + * Blank all windows owned by dcext driver, unpin buffers that were + * removed from screen, and advance syncpt. + */ + if (ext->dc->enabled) { + for (i = 0; i < DC_N_WINDOWS; i++) { + if (ext->win[i].user) + windows |= BIT(i); + } + + tegra_dc_blank(ext->dc, windows); + for_each_set_bit(i, &windows, DC_N_WINDOWS) { + tegra_dc_ext_unpin_window(&ext->win[i]); + tegra_dc_disable_window(ext->dc, i); + } + } + } int tegra_dc_ext_check_windowattr(struct tegra_dc_ext *ext, @@ -441,6 +469,31 @@ static int tegra_dc_ext_set_windowattr(struct tegra_dc_ext *ext, return err; } +static int tegra_dc_ext_set_vblank(struct tegra_dc_ext *ext, bool enable) +{ + struct tegra_dc *dc; + int ret = 0; + + if (ext->vblank_enabled == enable) + return 0; + + dc = ext->dc; + + if (enable) { + tegra_dc_hold_dc_out(dc); + tegra_dc_vsync_enable(dc); + } else if (ext->vblank_enabled) { + tegra_dc_vsync_disable(dc); + tegra_dc_release_dc_out(dc); + } + + if (!ret) { + ext->vblank_enabled = enable; + return 0; + } + return 1; +} + static void tegra_dc_ext_unpin_handles(struct tegra_dc_dmabuf *unpin_handles[], int nr_unpin) { @@ -1602,6 +1655,15 @@ static long tegra_dc_ioctl(struct file *filp, unsigned int cmd, #endif } + case TEGRA_DC_EXT_SET_VBLANK: + { + struct tegra_dc_ext_set_vblank args; + + if (copy_from_user(&args, user_arg, sizeof(args))) + return -EFAULT; + + return tegra_dc_ext_set_vblank(user->ext, args.enable); + } default: return -EINVAL; } 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 cb34047768f3..7c549c9875d9 100644 --- a/drivers/video/tegra/dc/ext/tegra_dc_ext_priv.h +++ b/drivers/video/tegra/dc/ext/tegra_dc_ext_priv.h @@ -86,13 +86,14 @@ struct tegra_dc_ext { } cursor; bool enabled; + bool vblank_enabled; }; #define TEGRA_DC_EXT_EVENT_MASK_ALL \ (TEGRA_DC_EXT_EVENT_HOTPLUG | TEGRA_DC_EXT_EVENT_BANDWIDTH_INC | \ TEGRA_DC_EXT_EVENT_BANDWIDTH_DEC) -#define TEGRA_DC_EXT_EVENT_MAX_SZ 8 +#define TEGRA_DC_EXT_EVENT_MAX_SZ 16 struct tegra_dc_ext_event_list { struct tegra_dc_ext_event event; diff --git a/include/video/tegra_dc_ext.h b/include/video/tegra_dc_ext.h index 78e344d5ad6f..95fe6dae5436 100644 --- a/include/video/tegra_dc_ext.h +++ b/include/video/tegra_dc_ext.h @@ -186,6 +186,15 @@ struct tegra_dc_ext_flip_3 { __u16 dirty_rect[4]; /* x,y,w,h for partial screen update. 0 ignores */ }; +/* + * vblank control - enable or disable vblank events + */ + +struct tegra_dc_ext_set_vblank { + __u8 enable; + __u8 reserved[3]; /* unused - must be 0 */ +}; + /* * Cursor image format: * @@ -433,6 +442,9 @@ struct tegra_dc_ext_feature { #define TEGRA_DC_EXT_FLIP3 \ _IOWR('D', 0x14, struct tegra_dc_ext_flip_3) +#define TEGRA_DC_EXT_SET_VBLANK \ + _IOW('D', 0x15, struct tegra_dc_ext_set_vblank) + enum tegra_dc_ext_control_output_type { TEGRA_DC_EXT_DSI, TEGRA_DC_EXT_LVDS, @@ -483,13 +495,20 @@ struct tegra_dc_ext_event { char data[0]; }; -#define TEGRA_DC_EXT_EVENT_HOTPLUG 0x1 +#define TEGRA_DC_EXT_EVENT_HOTPLUG (1 << 0) struct tegra_dc_ext_control_event_hotplug { __u32 handle; }; -#define TEGRA_DC_EXT_EVENT_BANDWIDTH_INC 0x3 -#define TEGRA_DC_EXT_EVENT_BANDWIDTH_DEC 0x4 +#define TEGRA_DC_EXT_EVENT_VBLANK (1 << 1) +struct tegra_dc_ext_control_event_vblank { + __u32 handle; + __u32 reserved; /* unused */ + __u64 timestamp_ns; +}; + +#define TEGRA_DC_EXT_EVENT_BANDWIDTH_INC (1 << 2) +#define TEGRA_DC_EXT_EVENT_BANDWIDTH_DEC (1 << 3) struct tegra_dc_ext_control_event_bandwidth { __u32 handle; __u32 total_bw; -- cgit v1.2.3