diff options
author | Tomi Valkeinen <tomi.valkeinen@ti.com> | 2012-10-10 10:56:05 +0300 |
---|---|---|
committer | Tomi Valkeinen <tomi.valkeinen@ti.com> | 2012-12-07 17:05:55 +0200 |
commit | 74b65ec24560ab0df0e7b789fa91cde4a442f169 (patch) | |
tree | 2d322869cb9ea6d9196e6743dbb7d67138b2cd30 /drivers/video/omap2 | |
parent | 6abae7a18a8c9dbec96915eb924dc06288a47b02 (diff) | |
download | linux-74b65ec24560ab0df0e7b789fa91cde4a442f169.tar.bz2 |
OMAPDSS: add manager ops
The output drivers need some operations from the overlay managers, like
enable and set_timings. These will affect the dispc registers, and need
to be synchronized with the composition-side changes with overlays and
overlay managers.
We want to handle these calls in the apply.c in the compatibility mode,
but when in non-compat mode, the calls need to be handled by some other
component (e.g. omapdrm).
To make this possible, this patch creates a set of function pointers in
a dss_mgr_ops struct, that is used to redirect the calls into the
correct destination.
The non-compat users can install their mgr ops with
dss_install_mgr_ops() function.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Diffstat (limited to 'drivers/video/omap2')
-rw-r--r-- | drivers/video/omap2/dss/apply.c | 36 | ||||
-rw-r--r-- | drivers/video/omap2/dss/dss.h | 13 | ||||
-rw-r--r-- | drivers/video/omap2/dss/output.c | 44 |
3 files changed, 87 insertions, 6 deletions
diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c index 038876a68d1a..70eaa8f70e97 100644 --- a/drivers/video/omap2/dss/apply.c +++ b/drivers/video/omap2/dss/apply.c @@ -781,7 +781,7 @@ static void mgr_clear_shadow_dirty(struct omap_overlay_manager *mgr) } } -void dss_mgr_start_update(struct omap_overlay_manager *mgr) +static void dss_mgr_start_update_compat(struct omap_overlay_manager *mgr) { struct mgr_priv_data *mp = get_mgr_priv(mgr); unsigned long flags; @@ -1021,7 +1021,7 @@ static void dss_setup_fifos(void) } } -int dss_mgr_enable(struct omap_overlay_manager *mgr) +static int dss_mgr_enable_compat(struct omap_overlay_manager *mgr) { struct mgr_priv_data *mp = get_mgr_priv(mgr); unsigned long flags; @@ -1071,7 +1071,7 @@ err: return r; } -void dss_mgr_disable(struct omap_overlay_manager *mgr) +static void dss_mgr_disable_compat(struct omap_overlay_manager *mgr) { struct mgr_priv_data *mp = get_mgr_priv(mgr); unsigned long flags; @@ -1208,7 +1208,7 @@ static void dss_apply_mgr_timings(struct omap_overlay_manager *mgr, mp->extra_info_dirty = true; } -void dss_mgr_set_timings(struct omap_overlay_manager *mgr, +static void dss_mgr_set_timings_compat(struct omap_overlay_manager *mgr, const struct omap_video_timings *timings) { unsigned long flags; @@ -1236,7 +1236,7 @@ static void dss_apply_mgr_lcd_config(struct omap_overlay_manager *mgr, mp->extra_info_dirty = true; } -void dss_mgr_set_lcd_config(struct omap_overlay_manager *mgr, +static void dss_mgr_set_lcd_config_compat(struct omap_overlay_manager *mgr, const struct dss_lcd_mgr_config *config) { unsigned long flags; @@ -1501,13 +1501,21 @@ err: return r; } +static const struct dss_mgr_ops apply_mgr_ops = { + .start_update = dss_mgr_start_update_compat, + .enable = dss_mgr_enable_compat, + .disable = dss_mgr_disable_compat, + .set_timings = dss_mgr_set_timings_compat, + .set_lcd_config = dss_mgr_set_lcd_config_compat, +}; + static int compat_refcnt; static DEFINE_MUTEX(compat_init_lock); int omapdss_compat_init(void) { struct platform_device *pdev = dss_get_core_pdev(); - int i; + int i, r; mutex_lock(&compat_init_lock); @@ -1548,10 +1556,24 @@ int omapdss_compat_init(void) ovl->get_device = &dss_ovl_get_device; } + r = dss_install_mgr_ops(&apply_mgr_ops); + if (r) + goto err_mgr_ops; + out: mutex_unlock(&compat_init_lock); return 0; + +err_mgr_ops: + dss_uninit_overlay_managers(pdev); + dss_uninit_overlays(pdev); + + compat_refcnt--; + + mutex_unlock(&compat_init_lock); + + return r; } EXPORT_SYMBOL(omapdss_compat_init); @@ -1564,6 +1586,8 @@ void omapdss_compat_uninit(void) if (--compat_refcnt > 0) goto out; + dss_uninstall_mgr_ops(); + dss_uninit_overlay_managers(pdev); dss_uninit_overlays(pdev); out: diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h index 9ce798645b2d..5cc13ea2b5a7 100644 --- a/drivers/video/omap2/dss/dss.h +++ b/drivers/video/omap2/dss/dss.h @@ -523,4 +523,17 @@ static inline void dss_collect_irq_stats(u32 irqstatus, unsigned *irq_arr) } #endif +struct dss_mgr_ops { + void (*start_update)(struct omap_overlay_manager *mgr); + int (*enable)(struct omap_overlay_manager *mgr); + void (*disable)(struct omap_overlay_manager *mgr); + void (*set_timings)(struct omap_overlay_manager *mgr, + const struct omap_video_timings *timings); + void (*set_lcd_config)(struct omap_overlay_manager *mgr, + const struct dss_lcd_mgr_config *config); +}; + +int dss_install_mgr_ops(const struct dss_mgr_ops *mgr_ops); +void dss_uninstall_mgr_ops(void); + #endif diff --git a/drivers/video/omap2/dss/output.c b/drivers/video/omap2/dss/output.c index 1a84b79d5580..9527ee6a769e 100644 --- a/drivers/video/omap2/dss/output.c +++ b/drivers/video/omap2/dss/output.c @@ -113,3 +113,47 @@ struct omap_dss_output *omap_dss_get_output(enum omap_dss_output_id id) return NULL; } + +static const struct dss_mgr_ops *dss_mgr_ops; + +int dss_install_mgr_ops(const struct dss_mgr_ops *mgr_ops) +{ + if (dss_mgr_ops) + return -EBUSY; + + dss_mgr_ops = mgr_ops; + + return 0; +} + +void dss_uninstall_mgr_ops(void) +{ + dss_mgr_ops = NULL; +} + +void dss_mgr_set_timings(struct omap_overlay_manager *mgr, + const struct omap_video_timings *timings) +{ + dss_mgr_ops->set_timings(mgr, timings); +} + +void dss_mgr_set_lcd_config(struct omap_overlay_manager *mgr, + const struct dss_lcd_mgr_config *config) +{ + dss_mgr_ops->set_lcd_config(mgr, config); +} + +int dss_mgr_enable(struct omap_overlay_manager *mgr) +{ + return dss_mgr_ops->enable(mgr); +} + +void dss_mgr_disable(struct omap_overlay_manager *mgr) +{ + dss_mgr_ops->disable(mgr); +} + +void dss_mgr_start_update(struct omap_overlay_manager *mgr) +{ + dss_mgr_ops->start_update(mgr); +} |