]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
OMAPDSS: add manager ops
authorTomi Valkeinen <tomi.valkeinen@ti.com>
Wed, 10 Oct 2012 07:56:05 +0000 (10:56 +0300)
committerTomi Valkeinen <tomi.valkeinen@ti.com>
Fri, 7 Dec 2012 15:05:55 +0000 (17:05 +0200)
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>
drivers/video/omap2/dss/apply.c
drivers/video/omap2/dss/dss.h
drivers/video/omap2/dss/output.c

index 038876a68d1ae3708c5eb6cbbf81281d92b1816f..70eaa8f70e9783e6e764848dec92a0eb2bbdf713 100644 (file)
@@ -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:
index 9ce798645b2d20318f09fa89e3831b5f299db255..5cc13ea2b5a7e7f79e4cf195009caeb30af47eab 100644 (file)
@@ -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
index 1a84b79d5580c1d27e3aeebabf25b556fdbaa281..9527ee6a769e8c9a8c72552adc2c644c74e269e6 100644 (file)
@@ -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);
+}