diff options
Diffstat (limited to 'drivers/video/omap2/dsscomp/dsscomp.h')
-rw-r--r-- | drivers/video/omap2/dsscomp/dsscomp.h | 208 |
1 files changed, 208 insertions, 0 deletions
diff --git a/drivers/video/omap2/dsscomp/dsscomp.h b/drivers/video/omap2/dsscomp/dsscomp.h new file mode 100644 index 0000000..8edfaa7 --- /dev/null +++ b/drivers/video/omap2/dsscomp/dsscomp.h @@ -0,0 +1,208 @@ +/* + * linux/drivers/video/omap2/dsscomp/base.c + * + * DSS Composition basic operation support + * + * Copyright (C) 2011 Texas Instruments, Inc + * Author: Lajos Molnar <molnar@ti.com> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef _DSSCOMP_H +#define _DSSCOMP_H + +#include <linux/miscdevice.h> +#include <linux/debugfs.h> +#include <linux/seq_file.h> +#ifdef CONFIG_DSSCOMP_DEBUG_LOG +#include <linux/hrtimer.h> +#endif + +#define MAX_OVERLAYS 5 +#define MAX_MANAGERS 3 +#define MAX_DISPLAYS 4 + +#define DEBUG_OVERLAYS (1 << 0) +#define DEBUG_COMPOSITIONS (1 << 1) +#define DEBUG_PHASES (1 << 2) +#define DEBUG_WAITS (1 << 3) +#define DEBUG_GRALLOC_PHASES (1 << 4) + +/* + * Utility macros + */ +#define ZERO(c) memset(&c, 0, sizeof(c)) +#define ZEROn(c, n) memset(c, 0, sizeof(*c) * n) +#define DEV(c) (c->dev.this_device) + +/** + * DSS Composition Device Driver + * + * @dev: misc device base + * @dbgfs: debugfs hook + */ +struct dsscomp_dev { + struct miscdevice dev; + struct dentry *dbgfs; + + /* cached DSS objects */ + u32 num_ovls; + struct omap_overlay *ovls[MAX_OVERLAYS]; + u32 num_mgrs; + struct omap_overlay_manager *mgrs[MAX_MANAGERS]; + u32 num_displays; + struct omap_dss_device *displays[MAX_DISPLAYS]; + struct notifier_block state_notifiers[MAX_DISPLAYS]; +}; + +extern int debug; + +#ifdef CONFIG_DEBUG_FS +extern struct mutex dbg_mtx; +extern struct list_head dbg_comps; +#define DO_IF_DEBUG_FS(cmd) { \ + mutex_lock(&dbg_mtx); \ + cmd; \ + mutex_unlock(&dbg_mtx); \ +} +#else +#define DO_IF_DEBUG_FS(cmd) +#endif + +enum dsscomp_state { + DSSCOMP_STATE_ACTIVE = 0xAC54156E, + DSSCOMP_STATE_APPLYING = 0xB554C591, + DSSCOMP_STATE_APPLIED = 0xB60504C1, + DSSCOMP_STATE_PROGRAMMED = 0xC0520652, + DSSCOMP_STATE_DISPLAYED = 0xD15504CA, +}; + +struct dsscomp_data { + enum dsscomp_state state; + /* + * :TRICKY: before applying, overlays used in a composition are stored + * in ovl_mask and the other masks are empty. Once composition is + * applied, blank is set to see if all overlays are to be disabled on + * this composition, any disabled overlays in the composition are set in + * ovl_dmask, and ovl_mask is updated to include ALL overlays that are + * actually on the display - even if they are not part of the + * composition. The reason: we use ovl_mask to see if an overlay is used + * or planned to be used on a manager. We update ovl_mask when + * composition is programmed (removing the disabled overlays). + */ + bool blank; /* true if all overlays are to be disabled */ + u32 ovl_mask; /* overlays used on this frame */ + u32 ovl_dmask; /* overlays disabled on this frame */ + u32 ix; /* manager index that this frame is on */ + struct dsscomp_setup_mgr_data frm; + struct dss2_ovl_info ovls[5]; + void (*extra_cb)(void *data, int status); + void *extra_cb_data; + bool must_apply; /* whether composition must be applied */ + +#ifdef CONFIG_DEBUG_FS + struct list_head dbg_q; + u32 dbg_used; + struct { + u32 t, state; + } dbg_log[8]; +#endif +}; + +struct dsscomp_sync_obj { + int state; + int fd; + atomic_t refs; +}; + +/* + * Kernel interface + */ +int dsscomp_queue_init(struct dsscomp_dev *cdev); +void dsscomp_queue_exit(void); +void dsscomp_gralloc_init(struct dsscomp_dev *cdev); +void dsscomp_gralloc_exit(void); +int dsscomp_gralloc_queue_ioctl(struct dsscomp_setup_dispc_data *d); +int dsscomp_wait(struct dsscomp_sync_obj *sync, enum dsscomp_wait_phase phase, + int timeout); +int dsscomp_state_notifier(struct notifier_block *nb, + unsigned long arg, void *ptr); + +/* basic operation - if not using queues */ +int set_dss_ovl_info(struct dss2_ovl_info *oi); +int set_dss_mgr_info(struct dss2_mgr_info *mi, struct omapdss_ovl_cb *cb); +struct omap_overlay_manager *find_dss_mgr(int display_ix); +void swap_rb_in_ovl_info(struct dss2_ovl_info *oi); +void swap_rb_in_mgr_info(struct dss2_mgr_info *mi); + +/* + * Debug functions + */ +void dump_ovl_info(struct dsscomp_dev *cdev, struct dss2_ovl_info *oi); +void dump_comp_info(struct dsscomp_dev *cdev, struct dsscomp_setup_mgr_data *d, + const char *phase); +void dump_total_comp_info(struct dsscomp_dev *cdev, + struct dsscomp_setup_dispc_data *d, + const char *phase); +const char *dsscomp_get_color_name(enum omap_color_mode m); + +void dsscomp_dbg_comps(struct seq_file *s); +void dsscomp_dbg_gralloc(struct seq_file *s); + +#define log_state_str(s) (\ + (s) == DSSCOMP_STATE_ACTIVE ? "ACTIVE" : \ + (s) == DSSCOMP_STATE_APPLYING ? "APPLY'N" : \ + (s) == DSSCOMP_STATE_APPLIED ? "APPLIED" : \ + (s) == DSSCOMP_STATE_PROGRAMMED ? "PROGR'D" : \ + (s) == DSSCOMP_STATE_DISPLAYED ? "DISPL'D" : "INVALID") + +#define log_status_str(ev) ( \ + ((ev) & DSS_COMPLETION_CHANGED) ? "CHANGED" : \ + (ev) == DSS_COMPLETION_DISPLAYED ? "DISPLAYED" : \ + (ev) == DSS_COMPLETION_PROGRAMMED ? "PROGRAMMED" : \ + (ev) == DSS_COMPLETION_TORN ? "TORN" : \ + (ev) == DSS_COMPLETION_RELEASED ? "RELEASED" : \ + ((ev) & DSS_COMPLETION_RELEASED) ? "ECLIPSED" : "???") + +#ifdef CONFIG_DSSCOMP_DEBUG_LOG +extern struct dbg_event_t { + u32 ms, a1, a2, ix; + void *data; + const char *fmt; +} dbg_events[128]; +extern u32 dbg_event_ix; + +void dsscomp_dbg_events(struct seq_file *s); +#endif + +static inline +void __log_event(u32 ix, u32 ms, void *data, const char *fmt, u32 a1, u32 a2) +{ +#ifdef CONFIG_DSSCOMP_DEBUG_LOG + if (!ms) + ms = ktime_to_ms(ktime_get()); + dbg_events[dbg_event_ix].ms = ms; + dbg_events[dbg_event_ix].data = data; + dbg_events[dbg_event_ix].fmt = fmt; + dbg_events[dbg_event_ix].a1 = a1; + dbg_events[dbg_event_ix].a2 = a2; + dbg_events[dbg_event_ix].ix = ix; + dbg_event_ix = (dbg_event_ix + 1) % ARRAY_SIZE(dbg_events); +#endif +} + +#define log_event(ix, ms, data, fmt, a1, a2) \ + DO_IF_DEBUG_FS(__log_event(ix, ms, data, fmt, a1, a2)) + +#endif |