From 8dd2491a4216778a81668581041ba1c06453ed6c Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Wed, 10 Oct 2012 10:26:45 +0300 Subject: [PATCH 01/17] OMAPDSS: add omapdss_compat_init() Add two new exported functions, omapdss_compat_init and omapdss_compat_uninit, which are to be used by omapfb, omap_vout to enable compatibility mode for omapdss. The functions are called by omapdss internally for now, and moved to other drivers later. The compatibility mode is implemented fully in the following patches. For now, enabling compat mode only sets up the private data in apply.c. Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/apply.c | 33 ++++++++++++++++++++++++++++++++- drivers/video/omap2/dss/core.c | 4 +++- drivers/video/omap2/dss/dss.h | 1 - include/video/omapdss.h | 3 +++ 4 files changed, 38 insertions(+), 3 deletions(-) diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c index 4a5cc5c64d4b..ba1343274bb7 100644 --- a/drivers/video/omap2/dss/apply.c +++ b/drivers/video/omap2/dss/apply.c @@ -18,6 +18,7 @@ #define DSS_SUBSYS_NAME "APPLY" #include +#include #include #include #include @@ -131,7 +132,7 @@ static struct mgr_priv_data *get_mgr_priv(struct omap_overlay_manager *mgr) return &dss_data.mgr_priv_data_array[mgr->id]; } -void dss_apply_init(void) +static void apply_init_priv(void) { const int num_ovls = dss_feat_get_num_ovls(); struct mgr_priv_data *mp; @@ -1463,3 +1464,33 @@ int dss_ovl_disable(struct omap_overlay *ovl) return r; } +static int compat_refcnt; +static DEFINE_MUTEX(compat_init_lock); + +int omapdss_compat_init(void) +{ + mutex_lock(&compat_init_lock); + + if (compat_refcnt++ > 0) + goto out; + + apply_init_priv(); + +out: + mutex_unlock(&compat_init_lock); + + return 0; +} +EXPORT_SYMBOL(omapdss_compat_init); + +void omapdss_compat_uninit(void) +{ + mutex_lock(&compat_init_lock); + + if (--compat_refcnt > 0) + goto out; + +out: + mutex_unlock(&compat_init_lock); +} +EXPORT_SYMBOL(omapdss_compat_uninit); diff --git a/drivers/video/omap2/dss/core.c b/drivers/video/omap2/dss/core.c index 5c5e59190586..86c743f5ed2e 100644 --- a/drivers/video/omap2/dss/core.c +++ b/drivers/video/omap2/dss/core.c @@ -232,7 +232,7 @@ static int __init omap_dss_probe(struct platform_device *pdev) dss_features_init(omapdss_get_version()); - dss_apply_init(); + omapdss_compat_init(); dss_init_overlay_managers(pdev); dss_init_overlays(pdev); @@ -264,6 +264,8 @@ static int omap_dss_remove(struct platform_device *pdev) dss_uninit_overlays(pdev); dss_uninit_overlay_managers(pdev); + omapdss_compat_uninit(); + return 0; } diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h index bdf843135661..9da3d61b8a56 100644 --- a/drivers/video/omap2/dss/dss.h +++ b/drivers/video/omap2/dss/dss.h @@ -178,7 +178,6 @@ void dss_copy_device_pdata(struct omap_dss_device *dst, const struct omap_dss_device *src); /* apply */ -void dss_apply_init(void); int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr); int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl); void dss_mgr_start_update(struct omap_overlay_manager *mgr); diff --git a/include/video/omapdss.h b/include/video/omapdss.h index b1248c2d36e1..a9402362d817 100644 --- a/include/video/omapdss.h +++ b/include/video/omapdss.h @@ -836,4 +836,7 @@ void omapdss_rfbi_set_data_lines(struct omap_dss_device *dssdev, void omapdss_rfbi_set_interface_timings(struct omap_dss_device *dssdev, struct rfbi_timings *timings); +int omapdss_compat_init(void); +void omapdss_compat_uninit(void); + #endif From 23dfd1ac87b56652e618fda24b035505c89c4b8c Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Tue, 23 Oct 2012 13:46:12 +0300 Subject: [PATCH 02/17] OMAPDSS: move ovl & ovl-mgr init to apply.c Overlay and overlay_manager structs will only be needed in the compat mode. This patch moves initialization of overlay and overlay_manager structs to apply.c, so that they are handled in omapdss_compat_init(). Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/apply.c | 9 +++++++++ drivers/video/omap2/dss/core.c | 6 ------ 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c index ba1343274bb7..6f60d0e0b7ee 100644 --- a/drivers/video/omap2/dss/apply.c +++ b/drivers/video/omap2/dss/apply.c @@ -1469,6 +1469,8 @@ static DEFINE_MUTEX(compat_init_lock); int omapdss_compat_init(void) { + struct platform_device *pdev = dss_get_core_pdev(); + mutex_lock(&compat_init_lock); if (compat_refcnt++ > 0) @@ -1476,6 +1478,9 @@ int omapdss_compat_init(void) apply_init_priv(); + dss_init_overlay_managers(pdev); + dss_init_overlays(pdev); + out: mutex_unlock(&compat_init_lock); @@ -1485,11 +1490,15 @@ EXPORT_SYMBOL(omapdss_compat_init); void omapdss_compat_uninit(void) { + struct platform_device *pdev = dss_get_core_pdev(); + mutex_lock(&compat_init_lock); if (--compat_refcnt > 0) goto out; + dss_uninit_overlay_managers(pdev); + dss_uninit_overlays(pdev); out: mutex_unlock(&compat_init_lock); } diff --git a/drivers/video/omap2/dss/core.c b/drivers/video/omap2/dss/core.c index 86c743f5ed2e..1751c1f511ad 100644 --- a/drivers/video/omap2/dss/core.c +++ b/drivers/video/omap2/dss/core.c @@ -234,9 +234,6 @@ static int __init omap_dss_probe(struct platform_device *pdev) omapdss_compat_init(); - dss_init_overlay_managers(pdev); - dss_init_overlays(pdev); - r = dss_initialize_debugfs(); if (r) goto err_debugfs; @@ -261,9 +258,6 @@ static int omap_dss_remove(struct platform_device *pdev) dss_uninitialize_debugfs(); - dss_uninit_overlays(pdev); - dss_uninit_overlay_managers(pdev); - omapdss_compat_uninit(); return 0; From 0c49ff747a4656e24b8990764f5ee4cd047ee982 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Tue, 23 Oct 2012 13:44:12 +0300 Subject: [PATCH 03/17] OMAPDSS: move ovl-mgr function setup to apply.c Most of the functions that are assigned to the fields in ovl-mgr struct are in apply.c. By moving the function pointer setup into apply.c we can make these functions static. Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/apply.c | 58 +++++++++++++++++++++++++++---- drivers/video/omap2/dss/dss.h | 10 ------ drivers/video/omap2/dss/manager.c | 39 --------------------- 3 files changed, 52 insertions(+), 55 deletions(-) diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c index 6f60d0e0b7ee..98cebe30318a 100644 --- a/drivers/video/omap2/dss/apply.c +++ b/drivers/video/omap2/dss/apply.c @@ -416,7 +416,37 @@ static void wait_pending_extra_info_updates(void) DSSWARN("timeout in wait_pending_extra_info_updates\n"); } -int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr) +static inline struct omap_dss_device *dss_mgr_get_device(struct omap_overlay_manager *mgr) +{ + return mgr->output ? mgr->output->device : NULL; +} + +static int dss_mgr_wait_for_vsync(struct omap_overlay_manager *mgr) +{ + unsigned long timeout = msecs_to_jiffies(500); + struct omap_dss_device *dssdev = mgr->get_device(mgr); + u32 irq; + int r; + + r = dispc_runtime_get(); + if (r) + return r; + + if (dssdev->type == OMAP_DISPLAY_TYPE_VENC) + irq = DISPC_IRQ_EVSYNC_ODD; + else if (dssdev->type == OMAP_DISPLAY_TYPE_HDMI) + irq = DISPC_IRQ_EVSYNC_EVEN; + else + irq = dispc_mgr_get_vsync_irq(mgr->id); + + r = omap_dispc_wait_for_irq_interruptible_timeout(irq, timeout); + + dispc_runtime_put(); + + return r; +} + +static int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr) { unsigned long timeout = msecs_to_jiffies(500); struct mgr_priv_data *mp = get_mgr_priv(mgr); @@ -885,7 +915,7 @@ static void omap_dss_mgr_apply_mgr(struct omap_overlay_manager *mgr) mp->info = mp->user_info; } -int omap_dss_mgr_apply(struct omap_overlay_manager *mgr) +static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr) { unsigned long flags; struct omap_overlay *ovl; @@ -1058,7 +1088,7 @@ void dss_mgr_disable(struct omap_overlay_manager *mgr) mutex_unlock(&apply_lock); } -int dss_mgr_set_info(struct omap_overlay_manager *mgr, +static int dss_mgr_set_info(struct omap_overlay_manager *mgr, struct omap_overlay_manager_info *info) { struct mgr_priv_data *mp = get_mgr_priv(mgr); @@ -1079,7 +1109,7 @@ int dss_mgr_set_info(struct omap_overlay_manager *mgr, return 0; } -void dss_mgr_get_info(struct omap_overlay_manager *mgr, +static void dss_mgr_get_info(struct omap_overlay_manager *mgr, struct omap_overlay_manager_info *info) { struct mgr_priv_data *mp = get_mgr_priv(mgr); @@ -1092,7 +1122,7 @@ void dss_mgr_get_info(struct omap_overlay_manager *mgr, spin_unlock_irqrestore(&data_lock, flags); } -int dss_mgr_set_output(struct omap_overlay_manager *mgr, +static int dss_mgr_set_output(struct omap_overlay_manager *mgr, struct omap_dss_output *output) { int r; @@ -1124,7 +1154,7 @@ int dss_mgr_set_output(struct omap_overlay_manager *mgr, return r; } -int dss_mgr_unset_output(struct omap_overlay_manager *mgr) +static int dss_mgr_unset_output(struct omap_overlay_manager *mgr) { int r; struct mgr_priv_data *mp = get_mgr_priv(mgr); @@ -1470,6 +1500,7 @@ static DEFINE_MUTEX(compat_init_lock); int omapdss_compat_init(void) { struct platform_device *pdev = dss_get_core_pdev(); + int i; mutex_lock(&compat_init_lock); @@ -1481,6 +1512,21 @@ int omapdss_compat_init(void) dss_init_overlay_managers(pdev); dss_init_overlays(pdev); + for (i = 0; i < omap_dss_get_num_overlay_managers(); i++) { + struct omap_overlay_manager *mgr; + + mgr = omap_dss_get_overlay_manager(i); + + mgr->set_output = &dss_mgr_set_output; + mgr->unset_output = &dss_mgr_unset_output; + mgr->apply = &omap_dss_mgr_apply; + mgr->set_manager_info = &dss_mgr_set_info; + mgr->get_manager_info = &dss_mgr_get_info; + mgr->wait_for_go = &dss_mgr_wait_for_go; + mgr->wait_for_vsync = &dss_mgr_wait_for_vsync; + mgr->get_device = &dss_mgr_get_device; + } + out: mutex_unlock(&compat_init_lock); diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h index 9da3d61b8a56..9e093bc81b5f 100644 --- a/drivers/video/omap2/dss/dss.h +++ b/drivers/video/omap2/dss/dss.h @@ -178,20 +178,10 @@ void dss_copy_device_pdata(struct omap_dss_device *dst, const struct omap_dss_device *src); /* apply */ -int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr); int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl); void dss_mgr_start_update(struct omap_overlay_manager *mgr); -int omap_dss_mgr_apply(struct omap_overlay_manager *mgr); - int dss_mgr_enable(struct omap_overlay_manager *mgr); void dss_mgr_disable(struct omap_overlay_manager *mgr); -int dss_mgr_set_info(struct omap_overlay_manager *mgr, - struct omap_overlay_manager_info *info); -void dss_mgr_get_info(struct omap_overlay_manager *mgr, - struct omap_overlay_manager_info *info); -int dss_mgr_set_output(struct omap_overlay_manager *mgr, - struct omap_dss_output *output); -int dss_mgr_unset_output(struct omap_overlay_manager *mgr); void dss_mgr_set_timings(struct omap_overlay_manager *mgr, const struct omap_video_timings *timings); void dss_mgr_set_lcd_config(struct omap_overlay_manager *mgr, diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c index c54d2f620ce3..2551eaa14c42 100644 --- a/drivers/video/omap2/dss/manager.c +++ b/drivers/video/omap2/dss/manager.c @@ -36,36 +36,6 @@ static int num_managers; static struct omap_overlay_manager *managers; -static inline struct omap_dss_device *dss_mgr_get_device(struct omap_overlay_manager *mgr) -{ - return mgr->output ? mgr->output->device : NULL; -} - -static int dss_mgr_wait_for_vsync(struct omap_overlay_manager *mgr) -{ - unsigned long timeout = msecs_to_jiffies(500); - struct omap_dss_device *dssdev = mgr->get_device(mgr); - u32 irq; - int r; - - r = dispc_runtime_get(); - if (r) - return r; - - if (dssdev->type == OMAP_DISPLAY_TYPE_VENC) - irq = DISPC_IRQ_EVSYNC_ODD; - else if (dssdev->type == OMAP_DISPLAY_TYPE_HDMI) - irq = DISPC_IRQ_EVSYNC_EVEN; - else - irq = dispc_mgr_get_vsync_irq(mgr->id); - - r = omap_dispc_wait_for_irq_interruptible_timeout(irq, timeout); - - dispc_runtime_put(); - - return r; -} - int dss_init_overlay_managers(struct platform_device *pdev) { int i, r; @@ -99,15 +69,6 @@ int dss_init_overlay_managers(struct platform_device *pdev) break; } - mgr->set_output = &dss_mgr_set_output; - mgr->unset_output = &dss_mgr_unset_output; - mgr->apply = &omap_dss_mgr_apply; - mgr->set_manager_info = &dss_mgr_set_info; - mgr->get_manager_info = &dss_mgr_get_info; - mgr->wait_for_go = &dss_mgr_wait_for_go; - mgr->wait_for_vsync = &dss_mgr_wait_for_vsync; - mgr->get_device = &dss_mgr_get_device; - mgr->caps = 0; mgr->supported_displays = dss_feat_get_supported_displays(mgr->id); From 6abae7a18a8c9dbec96915eb924dc06288a47b02 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Tue, 23 Oct 2012 13:45:07 +0300 Subject: [PATCH 04/17] OMAPDSS: move ovl function setup to apply.c Most of the functions that are assigned to the fields in ovl struct are in apply.c. By moving the function pointer setup into apply.c we can make these functions static. Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/apply.c | 37 ++++++++++++++++++++++++------- drivers/video/omap2/dss/dss.h | 12 ---------- drivers/video/omap2/dss/overlay.c | 17 -------------- 3 files changed, 29 insertions(+), 37 deletions(-) diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c index 98cebe30318a..038876a68d1a 100644 --- a/drivers/video/omap2/dss/apply.c +++ b/drivers/video/omap2/dss/apply.c @@ -416,6 +416,13 @@ static void wait_pending_extra_info_updates(void) DSSWARN("timeout in wait_pending_extra_info_updates\n"); } +static inline struct omap_dss_device *dss_ovl_get_device(struct omap_overlay *ovl) +{ + return ovl->manager ? + (ovl->manager->output ? ovl->manager->output->device : NULL) : + NULL; +} + static inline struct omap_dss_device *dss_mgr_get_device(struct omap_overlay_manager *mgr) { return mgr->output ? mgr->output->device : NULL; @@ -516,7 +523,7 @@ static int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr) return r; } -int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl) +static int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl) { unsigned long timeout = msecs_to_jiffies(500); struct ovl_priv_data *op; @@ -1248,7 +1255,7 @@ void dss_mgr_set_lcd_config(struct omap_overlay_manager *mgr, spin_unlock_irqrestore(&data_lock, flags); } -int dss_ovl_set_info(struct omap_overlay *ovl, +static int dss_ovl_set_info(struct omap_overlay *ovl, struct omap_overlay_info *info) { struct ovl_priv_data *op = get_ovl_priv(ovl); @@ -1269,7 +1276,7 @@ int dss_ovl_set_info(struct omap_overlay *ovl, return 0; } -void dss_ovl_get_info(struct omap_overlay *ovl, +static void dss_ovl_get_info(struct omap_overlay *ovl, struct omap_overlay_info *info) { struct ovl_priv_data *op = get_ovl_priv(ovl); @@ -1282,7 +1289,7 @@ void dss_ovl_get_info(struct omap_overlay *ovl, spin_unlock_irqrestore(&data_lock, flags); } -int dss_ovl_set_manager(struct omap_overlay *ovl, +static int dss_ovl_set_manager(struct omap_overlay *ovl, struct omap_overlay_manager *mgr) { struct ovl_priv_data *op = get_ovl_priv(ovl); @@ -1334,7 +1341,7 @@ int dss_ovl_set_manager(struct omap_overlay *ovl, return r; } -int dss_ovl_unset_manager(struct omap_overlay *ovl) +static int dss_ovl_unset_manager(struct omap_overlay *ovl) { struct ovl_priv_data *op = get_ovl_priv(ovl); unsigned long flags; @@ -1394,7 +1401,7 @@ int dss_ovl_unset_manager(struct omap_overlay *ovl) return r; } -bool dss_ovl_is_enabled(struct omap_overlay *ovl) +static bool dss_ovl_is_enabled(struct omap_overlay *ovl) { struct ovl_priv_data *op = get_ovl_priv(ovl); unsigned long flags; @@ -1409,7 +1416,7 @@ bool dss_ovl_is_enabled(struct omap_overlay *ovl) return e; } -int dss_ovl_enable(struct omap_overlay *ovl) +static int dss_ovl_enable(struct omap_overlay *ovl) { struct ovl_priv_data *op = get_ovl_priv(ovl); unsigned long flags; @@ -1459,7 +1466,7 @@ int dss_ovl_enable(struct omap_overlay *ovl) return r; } -int dss_ovl_disable(struct omap_overlay *ovl) +static int dss_ovl_disable(struct omap_overlay *ovl) { struct ovl_priv_data *op = get_ovl_priv(ovl); unsigned long flags; @@ -1527,6 +1534,20 @@ int omapdss_compat_init(void) mgr->get_device = &dss_mgr_get_device; } + for (i = 0; i < omap_dss_get_num_overlays(); i++) { + struct omap_overlay *ovl = omap_dss_get_overlay(i); + + ovl->is_enabled = &dss_ovl_is_enabled; + ovl->enable = &dss_ovl_enable; + ovl->disable = &dss_ovl_disable; + ovl->set_manager = &dss_ovl_set_manager; + ovl->unset_manager = &dss_ovl_unset_manager; + ovl->set_overlay_info = &dss_ovl_set_info; + ovl->get_overlay_info = &dss_ovl_get_info; + ovl->wait_for_go = &dss_mgr_wait_for_go_ovl; + ovl->get_device = &dss_ovl_get_device; + } + out: mutex_unlock(&compat_init_lock); diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h index 9e093bc81b5f..9ce798645b2d 100644 --- a/drivers/video/omap2/dss/dss.h +++ b/drivers/video/omap2/dss/dss.h @@ -178,7 +178,6 @@ void dss_copy_device_pdata(struct omap_dss_device *dst, const struct omap_dss_device *src); /* apply */ -int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl); void dss_mgr_start_update(struct omap_overlay_manager *mgr); int dss_mgr_enable(struct omap_overlay_manager *mgr); void dss_mgr_disable(struct omap_overlay_manager *mgr); @@ -187,17 +186,6 @@ void dss_mgr_set_timings(struct omap_overlay_manager *mgr, void dss_mgr_set_lcd_config(struct omap_overlay_manager *mgr, const struct dss_lcd_mgr_config *config); -bool dss_ovl_is_enabled(struct omap_overlay *ovl); -int dss_ovl_enable(struct omap_overlay *ovl); -int dss_ovl_disable(struct omap_overlay *ovl); -int dss_ovl_set_info(struct omap_overlay *ovl, - struct omap_overlay_info *info); -void dss_ovl_get_info(struct omap_overlay *ovl, - struct omap_overlay_info *info); -int dss_ovl_set_manager(struct omap_overlay *ovl, - struct omap_overlay_manager *mgr); -int dss_ovl_unset_manager(struct omap_overlay *ovl); - /* output */ void dss_register_output(struct omap_dss_output *out); void dss_unregister_output(struct omap_dss_output *out); diff --git a/drivers/video/omap2/dss/overlay.c b/drivers/video/omap2/dss/overlay.c index 45f4994bc6b0..eccde322c28a 100644 --- a/drivers/video/omap2/dss/overlay.c +++ b/drivers/video/omap2/dss/overlay.c @@ -38,13 +38,6 @@ static int num_overlays; static struct omap_overlay *overlays; -static inline struct omap_dss_device *dss_ovl_get_device(struct omap_overlay *ovl) -{ - return ovl->manager ? - (ovl->manager->output ? ovl->manager->output->device : NULL) : - NULL; -} - int omap_dss_get_num_overlays(void) { return num_overlays; @@ -93,16 +86,6 @@ void dss_init_overlays(struct platform_device *pdev) break; } - ovl->is_enabled = &dss_ovl_is_enabled; - ovl->enable = &dss_ovl_enable; - ovl->disable = &dss_ovl_disable; - ovl->set_manager = &dss_ovl_set_manager; - ovl->unset_manager = &dss_ovl_unset_manager; - ovl->set_overlay_info = &dss_ovl_set_info; - ovl->get_overlay_info = &dss_ovl_get_info; - ovl->wait_for_go = &dss_mgr_wait_for_go_ovl; - ovl->get_device = &dss_ovl_get_device; - ovl->caps = dss_feat_get_overlay_caps(ovl->id); ovl->supported_modes = dss_feat_get_supported_color_modes(ovl->id); From 74b65ec24560ab0df0e7b789fa91cde4a442f169 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Wed, 10 Oct 2012 10:56:05 +0300 Subject: [PATCH 05/17] 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 --- drivers/video/omap2/dss/apply.c | 36 +++++++++++++++++++++----- drivers/video/omap2/dss/dss.h | 13 ++++++++++ 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 @@ int dss_mgr_enable(struct omap_overlay_manager *mgr) 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 @@ static int dss_ovl_disable(struct omap_overlay *ovl) 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); +} From 1550202d4a7593655a2aca99e39a58751073c92a Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Wed, 10 Oct 2012 13:59:07 +0300 Subject: [PATCH 06/17] OMAPDSS: manage framedone irq with mgr ops Some of the output drivers need to handle FRAMEDONE interrupt from DISPC. This creates a direct dependency to dispc code, and we need to avoid this to make the compat code to work. Instead of the output drivers registering for dispc interrupts, we create new mgr-ops that are used to register a framedone handler. The code implementing the mgr-ops is responsible for calling the handler when DISPC FRAMEDONE interrupt happens. The compat layer is improved accordingly to do the call to the framedone handler. Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/apply.c | 46 ++++++++++++++++++++++++++++++++ drivers/video/omap2/dss/dsi.c | 26 +++++++----------- drivers/video/omap2/dss/dss.h | 8 ++++++ drivers/video/omap2/dss/output.c | 12 +++++++++ drivers/video/omap2/dss/rfbi.c | 12 +++++---- 5 files changed, 82 insertions(+), 22 deletions(-) diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c index 70eaa8f70e97..5952f149c91a 100644 --- a/drivers/video/omap2/dss/apply.c +++ b/drivers/video/omap2/dss/apply.c @@ -105,6 +105,9 @@ struct mgr_priv_data { struct omap_video_timings timings; struct dss_lcd_mgr_config lcd_config; + + void (*framedone_handler)(void *); + void *framedone_handler_data; }; static struct { @@ -888,6 +891,21 @@ static void dss_apply_irq_handler(void *data, u32 mask) if (!extra_updating) complete_all(&extra_updated_completion); + /* call framedone handlers for manual update displays */ + for (i = 0; i < num_mgrs; i++) { + struct omap_overlay_manager *mgr; + struct mgr_priv_data *mp; + + mgr = omap_dss_get_overlay_manager(i); + mp = get_mgr_priv(mgr); + + if (!mgr_manual_update(mgr) || !mp->framedone_handler) + continue; + + if (mask & dispc_mgr_get_framedone_irq(i)) + mp->framedone_handler(mp->framedone_handler_data); + } + if (!need_isr()) dss_unregister_vsync_isr(); @@ -1501,12 +1519,40 @@ static int dss_ovl_disable(struct omap_overlay *ovl) return r; } +static int dss_mgr_register_framedone_handler_compat(struct omap_overlay_manager *mgr, + void (*handler)(void *), void *data) +{ + struct mgr_priv_data *mp = get_mgr_priv(mgr); + + if (mp->framedone_handler) + return -EBUSY; + + mp->framedone_handler = handler; + mp->framedone_handler_data = data; + + return 0; +} + +static void dss_mgr_unregister_framedone_handler_compat(struct omap_overlay_manager *mgr, + void (*handler)(void *), void *data) +{ + struct mgr_priv_data *mp = get_mgr_priv(mgr); + + WARN_ON(mp->framedone_handler != handler || + mp->framedone_handler_data != data); + + mp->framedone_handler = NULL; + mp->framedone_handler_data = NULL; +} + 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, + .register_framedone_handler = dss_mgr_register_framedone_handler_compat, + .unregister_framedone_handler = dss_mgr_unregister_framedone_handler_compat, }; static int compat_refcnt; diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index db9663dcfbd0..28d41d16b7be 100644 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/omap2/dss/dsi.c @@ -4535,7 +4535,7 @@ static void dsi_framedone_timeout_work_callback(struct work_struct *work) dsi_handle_framedone(dsi->pdev, -ETIMEDOUT); } -static void dsi_framedone_irq_callback(void *data, u32 mask) +static void dsi_framedone_irq_callback(void *data) { struct platform_device *dsidev = (struct platform_device *) data; struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); @@ -4609,7 +4609,6 @@ static int dsi_display_init_dispc(struct omap_dss_device *dssdev) struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); struct omap_overlay_manager *mgr = dssdev->output->manager; int r; - u32 irq = 0; if (dsi->mode == OMAP_DSS_DSI_CMD_MODE) { dsi->timings.hsw = 1; @@ -4619,12 +4618,10 @@ static int dsi_display_init_dispc(struct omap_dss_device *dssdev) dsi->timings.vfp = 0; dsi->timings.vbp = 0; - irq = dispc_mgr_get_framedone_irq(mgr->id); - - r = omap_dispc_register_isr(dsi_framedone_irq_callback, - (void *) dsidev, irq); + r = dss_mgr_register_framedone_handler(mgr, + dsi_framedone_irq_callback, dsidev); if (r) { - DSSERR("can't get FRAMEDONE irq\n"); + DSSERR("can't register FRAMEDONE handler\n"); goto err; } @@ -4662,8 +4659,8 @@ static int dsi_display_init_dispc(struct omap_dss_device *dssdev) return 0; err1: if (dsi->mode == OMAP_DSS_DSI_CMD_MODE) - omap_dispc_unregister_isr(dsi_framedone_irq_callback, - (void *) dsidev, irq); + dss_mgr_unregister_framedone_handler(mgr, + dsi_framedone_irq_callback, dsidev); err: return r; } @@ -4674,14 +4671,9 @@ static void dsi_display_uninit_dispc(struct omap_dss_device *dssdev) struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); struct omap_overlay_manager *mgr = dssdev->output->manager; - if (dsi->mode == OMAP_DSS_DSI_CMD_MODE) { - u32 irq; - - irq = dispc_mgr_get_framedone_irq(mgr->id); - - omap_dispc_unregister_isr(dsi_framedone_irq_callback, - (void *) dsidev, irq); - } + if (dsi->mode == OMAP_DSS_DSI_CMD_MODE) + dss_mgr_unregister_framedone_handler(mgr, + dsi_framedone_irq_callback, dsidev); } static int dsi_configure_dsi_clocks(struct omap_dss_device *dssdev) diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h index 5cc13ea2b5a7..8ae73670aa37 100644 --- a/drivers/video/omap2/dss/dss.h +++ b/drivers/video/omap2/dss/dss.h @@ -185,6 +185,10 @@ void dss_mgr_set_timings(struct omap_overlay_manager *mgr, const struct omap_video_timings *timings); void dss_mgr_set_lcd_config(struct omap_overlay_manager *mgr, const struct dss_lcd_mgr_config *config); +int dss_mgr_register_framedone_handler(struct omap_overlay_manager *mgr, + void (*handler)(void *), void *data); +void dss_mgr_unregister_framedone_handler(struct omap_overlay_manager *mgr, + void (*handler)(void *), void *data); /* output */ void dss_register_output(struct omap_dss_output *out); @@ -531,6 +535,10 @@ struct dss_mgr_ops { const struct omap_video_timings *timings); void (*set_lcd_config)(struct omap_overlay_manager *mgr, const struct dss_lcd_mgr_config *config); + int (*register_framedone_handler)(struct omap_overlay_manager *mgr, + void (*handler)(void *), void *data); + void (*unregister_framedone_handler)(struct omap_overlay_manager *mgr, + void (*handler)(void *), void *data); }; int dss_install_mgr_ops(const struct dss_mgr_ops *mgr_ops); diff --git a/drivers/video/omap2/dss/output.c b/drivers/video/omap2/dss/output.c index 9527ee6a769e..6def0d7bbd05 100644 --- a/drivers/video/omap2/dss/output.c +++ b/drivers/video/omap2/dss/output.c @@ -157,3 +157,15 @@ void dss_mgr_start_update(struct omap_overlay_manager *mgr) { dss_mgr_ops->start_update(mgr); } + +int dss_mgr_register_framedone_handler(struct omap_overlay_manager *mgr, + void (*handler)(void *), void *data) +{ + return dss_mgr_ops->register_framedone_handler(mgr, handler, data); +} + +void dss_mgr_unregister_framedone_handler(struct omap_overlay_manager *mgr, + void (*handler)(void *), void *data) +{ + dss_mgr_ops->unregister_framedone_handler(mgr, handler, data); +} diff --git a/drivers/video/omap2/dss/rfbi.c b/drivers/video/omap2/dss/rfbi.c index ec9fde52716c..e903dd3f54d9 100644 --- a/drivers/video/omap2/dss/rfbi.c +++ b/drivers/video/omap2/dss/rfbi.c @@ -342,7 +342,7 @@ static int rfbi_transfer_area(struct omap_dss_device *dssdev, return 0; } -static void framedone_callback(void *data, u32 mask) +static void framedone_callback(void *data) { void (*callback)(void *data); @@ -908,8 +908,8 @@ int omapdss_rfbi_display_enable(struct omap_dss_device *dssdev) goto err0; } - r = omap_dispc_register_isr(framedone_callback, NULL, - DISPC_IRQ_FRAMEDONE); + r = dss_mgr_register_framedone_handler(out->manager, + framedone_callback, NULL); if (r) { DSSERR("can't get FRAMEDONE irq\n"); goto err1; @@ -933,8 +933,10 @@ EXPORT_SYMBOL(omapdss_rfbi_display_enable); void omapdss_rfbi_display_disable(struct omap_dss_device *dssdev) { - omap_dispc_unregister_isr(framedone_callback, NULL, - DISPC_IRQ_FRAMEDONE); + struct omap_dss_output *out = dssdev->output; + + dss_mgr_unregister_framedone_handler(out->manager, + framedone_callback, NULL); omap_dss_stop_device(dssdev); rfbi_runtime_put(); From bb39813413db782cc77b94d55cb5d044f42079df Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Wed, 24 Oct 2012 12:39:53 +0300 Subject: [PATCH 07/17] OMAPDSS: move blocking mgr enable/disable to compat layer dispc_mgr_enable_sync and dispc_mgr_disable_sync are only used with the compat mode. Non-compat will use the simpler enable and disable functions. This patch moves the synchronous enable/disable code to the compat layer. A new file is created, dispc-compat.c, which contains low level dispc compat code (versus apply.c, which contains slightly higher level compat code). Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/Makefile | 2 +- drivers/video/omap2/dss/apply.c | 1 + drivers/video/omap2/dss/dispc-compat.c | 207 +++++++++++++++++++++++++ drivers/video/omap2/dss/dispc-compat.h | 24 +++ drivers/video/omap2/dss/dispc.c | 175 --------------------- drivers/video/omap2/dss/dss.h | 2 - 6 files changed, 233 insertions(+), 178 deletions(-) create mode 100644 drivers/video/omap2/dss/dispc-compat.c create mode 100644 drivers/video/omap2/dss/dispc-compat.h diff --git a/drivers/video/omap2/dss/Makefile b/drivers/video/omap2/dss/Makefile index af866d0b7942..c834f9c42008 100644 --- a/drivers/video/omap2/dss/Makefile +++ b/drivers/video/omap2/dss/Makefile @@ -1,7 +1,7 @@ obj-$(CONFIG_OMAP2_DSS) += omapdss.o omapdss-y := core.o dss.o dss_features.o dispc.o dispc_coefs.o display.o \ manager.o manager-sysfs.o overlay.o overlay-sysfs.o output.o apply.o \ - display-sysfs.o + display-sysfs.o dispc-compat.o omapdss-$(CONFIG_OMAP2_DSS_DPI) += dpi.o omapdss-$(CONFIG_OMAP2_DSS_RFBI) += rfbi.o omapdss-$(CONFIG_OMAP2_DSS_VENC) += venc.o venc_panel.o diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c index 5952f149c91a..0de0d3cf1764 100644 --- a/drivers/video/omap2/dss/apply.c +++ b/drivers/video/omap2/dss/apply.c @@ -27,6 +27,7 @@ #include "dss.h" #include "dss_features.h" +#include "dispc-compat.h" /* * We have 4 levels of cache for the dispc settings. First two are in SW and diff --git a/drivers/video/omap2/dss/dispc-compat.c b/drivers/video/omap2/dss/dispc-compat.c new file mode 100644 index 000000000000..cca38488ab27 --- /dev/null +++ b/drivers/video/omap2/dss/dispc-compat.c @@ -0,0 +1,207 @@ +/* + * Copyright (C) 2012 Texas Instruments + * Author: Tomi Valkeinen + * + * 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 . + */ + +#define DSS_SUBSYS_NAME "APPLY" + +#include +#include +#include +#include +#include +#include + +#include