From 5476e74a03f4be972708162050c8ac7fe150449f Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Thu, 3 Nov 2011 16:34:20 +0200 Subject: OMAPDSS: remove partial update from DSI Partial update for manual update displays has never worked quite well: * The HW has limitations on the update area, and the x and width need to be even. * Showing a part of a scaled overlay causes artifacts. * Makes the management of dispc very complex Considering the above points and the fact that partial update is not used anywhere, this and the following patches remove the partial update support. This will greatly simplify the following re-write of the apply mechanism to get proper locking and additional features like fifo-merge. This patch removes the partial update from the dsi.c. Signed-off-by: Tomi Valkeinen --- include/video/omapdss.h | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'include/video') diff --git a/include/video/omapdss.h b/include/video/omapdss.h index 378c7ed6760b..60bf4260253b 100644 --- a/include/video/omapdss.h +++ b/include/video/omapdss.h @@ -662,12 +662,7 @@ void omapdss_dsi_vc_enable_hs(struct omap_dss_device *dssdev, int channel, bool enable); int omapdss_dsi_enable_te(struct omap_dss_device *dssdev, bool enable); -int omap_dsi_prepare_update(struct omap_dss_device *dssdev, - u16 *x, u16 *y, u16 *w, u16 *h, - bool enlarge_update_area); -int omap_dsi_update(struct omap_dss_device *dssdev, - int channel, - u16 x, u16 y, u16 w, u16 h, +int omap_dsi_update(struct omap_dss_device *dssdev, int channel, void (*callback)(int, void *), void *data); int omap_dsi_request_vc(struct omap_dss_device *dssdev, int *channel); int omap_dsi_set_vc_id(struct omap_dss_device *dssdev, int channel, int vc_id); -- cgit v1.2.3-70-g09d2 From 7797c6da64852b06b585b7eca8d3f657bfc9fa47 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Fri, 4 Nov 2011 10:22:46 +0200 Subject: OMAPDSS: hide manager's enable/disable() omap_overlay_manager struct contains enable() and disable() functions. However, these are only meant to be used from inside omapdss, and thus it's bad to expose the functions. This patch adds dss_mgr_enable() and dss_mgr_disable() functions to apply.c, which handle enabling and disabling the output. Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/apply.c | 12 +++++++++++- drivers/video/omap2/dss/dpi.c | 4 ++-- drivers/video/omap2/dss/dsi.c | 4 ++-- drivers/video/omap2/dss/dss.h | 2 ++ drivers/video/omap2/dss/hdmi.c | 6 +++--- drivers/video/omap2/dss/manager.c | 15 --------------- drivers/video/omap2/dss/sdi.c | 4 ++-- drivers/video/omap2/dss/venc.c | 4 ++-- include/video/omapdss.h | 3 --- 9 files changed, 24 insertions(+), 30 deletions(-) (limited to 'include/video') diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c index c634c986293d..414cbd907239 100644 --- a/drivers/video/omap2/dss/apply.c +++ b/drivers/video/omap2/dss/apply.c @@ -424,7 +424,7 @@ void dss_mgr_start_update(struct omap_overlay_manager *mgr) mc->shadow_dirty = false; } - mgr->enable(mgr); + dispc_mgr_enable(mgr->id, true); } static void dss_apply_irq_handler(void *data, u32 mask) @@ -654,3 +654,13 @@ int omap_dss_mgr_apply(struct omap_overlay_manager *mgr) return r; } +void dss_mgr_enable(struct omap_overlay_manager *mgr) +{ + dispc_mgr_enable(mgr->id, true); +} + +void dss_mgr_disable(struct omap_overlay_manager *mgr) +{ + dispc_mgr_enable(mgr->id, false); +} + diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c index 976ac23dcd0c..79c4df3c9a88 100644 --- a/drivers/video/omap2/dss/dpi.c +++ b/drivers/video/omap2/dss/dpi.c @@ -223,7 +223,7 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev) mdelay(2); - dssdev->manager->enable(dssdev->manager); + dss_mgr_enable(dssdev->manager); return 0; @@ -249,7 +249,7 @@ EXPORT_SYMBOL(omapdss_dpi_display_enable); void omapdss_dpi_display_disable(struct omap_dss_device *dssdev) { - dssdev->manager->disable(dssdev->manager); + dss_mgr_disable(dssdev->manager); if (dpi_use_dsi_pll(dssdev)) { dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK); diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index 101e3b8e178b..9358afa2a77e 100644 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/omap2/dss/dsi.c @@ -4010,7 +4010,7 @@ int dsi_video_mode_enable(struct omap_dss_device *dssdev, int channel) dsi_vc_enable(dsidev, channel, true); dsi_if_enable(dsidev, true); - dssdev->manager->enable(dssdev->manager); + dss_mgr_enable(dssdev->manager); return 0; } @@ -4029,7 +4029,7 @@ void dsi_video_mode_disable(struct omap_dss_device *dssdev, int channel) dsi_vc_enable(dsidev, channel, true); dsi_if_enable(dsidev, true); - dssdev->manager->disable(dssdev->manager); + dss_mgr_disable(dssdev->manager); } EXPORT_SYMBOL(dsi_video_mode_disable); diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h index e6f961aa4362..03c724475bcc 100644 --- a/drivers/video/omap2/dss/dss.h +++ b/drivers/video/omap2/dss/dss.h @@ -169,6 +169,8 @@ 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); +void dss_mgr_enable(struct omap_overlay_manager *mgr); +void dss_mgr_disable(struct omap_overlay_manager *mgr); /* display */ int dss_suspend_all_devices(void); diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c index c56378c555b0..e245a2bbba9d 100644 --- a/drivers/video/omap2/dss/hdmi.c +++ b/drivers/video/omap2/dss/hdmi.c @@ -333,7 +333,7 @@ static int hdmi_power_on(struct omap_dss_device *dssdev) if (r) return r; - dispc_mgr_enable(OMAP_DSS_CHANNEL_DIGIT, 0); + dss_mgr_disable(dssdev->manager); p = &dssdev->panel.timings; @@ -387,7 +387,7 @@ static int hdmi_power_on(struct omap_dss_device *dssdev) hdmi.ip_data.ops->video_enable(&hdmi.ip_data, 1); - dispc_mgr_enable(OMAP_DSS_CHANNEL_DIGIT, 1); + dss_mgr_enable(dssdev->manager); return 0; err: @@ -397,7 +397,7 @@ err: static void hdmi_power_off(struct omap_dss_device *dssdev) { - dispc_mgr_enable(OMAP_DSS_CHANNEL_DIGIT, 0); + dss_mgr_disable(dssdev->manager); hdmi.ip_data.ops->video_enable(&hdmi.ip_data, 0); hdmi.ip_data.ops->phy_disable(&hdmi.ip_data); diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c index f9e691b4ba4a..780a307c815e 100644 --- a/drivers/video/omap2/dss/manager.c +++ b/drivers/video/omap2/dss/manager.c @@ -585,18 +585,6 @@ static void omap_dss_mgr_get_info(struct omap_overlay_manager *mgr, *info = mgr->info; } -static int dss_mgr_enable(struct omap_overlay_manager *mgr) -{ - dispc_mgr_enable(mgr->id, 1); - return 0; -} - -static int dss_mgr_disable(struct omap_overlay_manager *mgr) -{ - dispc_mgr_enable(mgr->id, 0); - return 0; -} - static void omap_dss_add_overlay_manager(struct omap_overlay_manager *manager) { ++num_managers; @@ -640,9 +628,6 @@ int dss_init_overlay_managers(struct platform_device *pdev) mgr->wait_for_go = &dss_mgr_wait_for_go; mgr->wait_for_vsync = &dss_mgr_wait_for_vsync; - mgr->enable = &dss_mgr_enable; - mgr->disable = &dss_mgr_disable; - mgr->caps = 0; mgr->supported_displays = dss_feat_get_supported_displays(mgr->id); diff --git a/drivers/video/omap2/dss/sdi.c b/drivers/video/omap2/dss/sdi.c index 40305ad7841e..02da8beb7304 100644 --- a/drivers/video/omap2/dss/sdi.c +++ b/drivers/video/omap2/dss/sdi.c @@ -123,7 +123,7 @@ int omapdss_sdi_display_enable(struct omap_dss_device *dssdev) goto err_sdi_enable; mdelay(2); - dssdev->manager->enable(dssdev->manager); + dss_mgr_enable(dssdev->manager); return 0; @@ -145,7 +145,7 @@ EXPORT_SYMBOL(omapdss_sdi_display_enable); void omapdss_sdi_display_disable(struct omap_dss_device *dssdev) { - dssdev->manager->disable(dssdev->manager); + dss_mgr_disable(dssdev->manager); dss_sdi_disable(); diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c index 7533458ba4d2..101fcd77a50d 100644 --- a/drivers/video/omap2/dss/venc.c +++ b/drivers/video/omap2/dss/venc.c @@ -447,7 +447,7 @@ static void venc_power_on(struct omap_dss_device *dssdev) if (dssdev->platform_enable) dssdev->platform_enable(dssdev); - dssdev->manager->enable(dssdev->manager); + dss_mgr_enable(dssdev->manager); } static void venc_power_off(struct omap_dss_device *dssdev) @@ -455,7 +455,7 @@ static void venc_power_off(struct omap_dss_device *dssdev) venc_write_reg(VENC_OUTPUT_CONTROL, 0); dss_set_dac_pwrdn_bgz(0); - dssdev->manager->disable(dssdev->manager); + dss_mgr_disable(dssdev->manager); if (dssdev->platform_disable) dssdev->platform_disable(dssdev); diff --git a/include/video/omapdss.h b/include/video/omapdss.h index 60bf4260253b..04741cd4c32a 100644 --- a/include/video/omapdss.h +++ b/include/video/omapdss.h @@ -448,9 +448,6 @@ struct omap_overlay_manager { int (*apply)(struct omap_overlay_manager *mgr); int (*wait_for_go)(struct omap_overlay_manager *mgr); int (*wait_for_vsync)(struct omap_overlay_manager *mgr); - - int (*enable)(struct omap_overlay_manager *mgr); - int (*disable)(struct omap_overlay_manager *mgr); }; struct omap_dss_device { -- cgit v1.2.3-70-g09d2 From be729178f0e0f31ab14b42b3fe5d6b4463fbeb3a Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Fri, 4 Nov 2011 10:30:47 +0200 Subject: OMAPDSS: APPLY: track whether a manager is enabled Add "enabled" field to struct omap_overlay_manager, which tells if the output is enabled or not. This will be used in apply.c in the following patches. Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/apply.c | 2 ++ include/video/omapdss.h | 2 ++ 2 files changed, 4 insertions(+) (limited to 'include/video') diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c index 414cbd907239..46fdb63a4dbc 100644 --- a/drivers/video/omap2/dss/apply.c +++ b/drivers/video/omap2/dss/apply.c @@ -657,10 +657,12 @@ int omap_dss_mgr_apply(struct omap_overlay_manager *mgr) void dss_mgr_enable(struct omap_overlay_manager *mgr) { dispc_mgr_enable(mgr->id, true); + mgr->enabled = true; } void dss_mgr_disable(struct omap_overlay_manager *mgr) { dispc_mgr_enable(mgr->id, false); + mgr->enabled = false; } diff --git a/include/video/omapdss.h b/include/video/omapdss.h index 04741cd4c32a..d61efc3105a7 100644 --- a/include/video/omapdss.h +++ b/include/video/omapdss.h @@ -432,6 +432,8 @@ struct omap_overlay_manager { struct omap_dss_device *device; struct omap_overlay_manager_info info; + bool enabled; + bool device_changed; /* if true, info has been changed but not applied() yet */ bool info_dirty; -- cgit v1.2.3-70-g09d2 From 5617ad097959cb39b96d08af0a9b3d51215deaba Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Sat, 5 Nov 2011 10:44:48 +0200 Subject: OMAPDSS: store managers in an array Overlay managers are stored in a linked list. There's no need for this list, as an array would do just as fine. This patch changes the code to use an array for overlay managers. Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/manager.c | 49 ++++++++++++++------------------------- include/video/omapdss.h | 1 - 2 files changed, 17 insertions(+), 33 deletions(-) (limited to 'include/video') diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c index 780a307c815e..a08cc6e7f5ca 100644 --- a/drivers/video/omap2/dss/manager.c +++ b/drivers/video/omap2/dss/manager.c @@ -34,7 +34,7 @@ #include "dss_features.h" static int num_managers; -static struct list_head manager_list; +static struct omap_overlay_manager *managers; static ssize_t manager_name_show(struct omap_overlay_manager *mgr, char *buf) { @@ -585,25 +585,19 @@ static void omap_dss_mgr_get_info(struct omap_overlay_manager *mgr, *info = mgr->info; } -static void omap_dss_add_overlay_manager(struct omap_overlay_manager *manager) -{ - ++num_managers; - list_add_tail(&manager->list, &manager_list); -} - int dss_init_overlay_managers(struct platform_device *pdev) { int i, r; - INIT_LIST_HEAD(&manager_list); + num_managers = dss_feat_get_num_mgrs(); - num_managers = 0; + managers = kzalloc(sizeof(struct omap_overlay_manager) * num_managers, + GFP_KERNEL); - for (i = 0; i < dss_feat_get_num_mgrs(); ++i) { - struct omap_overlay_manager *mgr; - mgr = kzalloc(sizeof(*mgr), GFP_KERNEL); + BUG_ON(managers == NULL); - BUG_ON(mgr == NULL); + for (i = 0; i < num_managers; ++i) { + struct omap_overlay_manager *mgr = &managers[i]; switch (i) { case 0: @@ -634,15 +628,11 @@ int dss_init_overlay_managers(struct platform_device *pdev) dss_overlay_setup_dispc_manager(mgr); - omap_dss_add_overlay_manager(mgr); - r = kobject_init_and_add(&mgr->kobj, &manager_ktype, &pdev->dev.kobj, "manager%d", i); - if (r) { + if (r) DSSERR("failed to create sysfs file\n"); - continue; - } } return 0; @@ -650,17 +640,17 @@ int dss_init_overlay_managers(struct platform_device *pdev) void dss_uninit_overlay_managers(struct platform_device *pdev) { - struct omap_overlay_manager *mgr; + int i; + + for (i = 0; i < num_managers; ++i) { + struct omap_overlay_manager *mgr = &managers[i]; - while (!list_empty(&manager_list)) { - mgr = list_first_entry(&manager_list, - struct omap_overlay_manager, list); - list_del(&mgr->list); kobject_del(&mgr->kobj); kobject_put(&mgr->kobj); - kfree(mgr); } + kfree(managers); + managers = NULL; num_managers = 0; } @@ -672,15 +662,10 @@ EXPORT_SYMBOL(omap_dss_get_num_overlay_managers); struct omap_overlay_manager *omap_dss_get_overlay_manager(int num) { - int i = 0; - struct omap_overlay_manager *mgr; - - list_for_each_entry(mgr, &manager_list, list) { - if (i++ == num) - return mgr; - } + if (num >= num_managers) + return NULL; - return NULL; + return &managers[num]; } EXPORT_SYMBOL(omap_dss_get_overlay_manager); diff --git a/include/video/omapdss.h b/include/video/omapdss.h index d61efc3105a7..fd5a96c5ecc5 100644 --- a/include/video/omapdss.h +++ b/include/video/omapdss.h @@ -418,7 +418,6 @@ struct omap_overlay_manager_info { struct omap_overlay_manager { struct kobject kobj; - struct list_head list; /* static fields */ const char *name; -- cgit v1.2.3-70-g09d2 From 07e327c9c18b382656bf455051759be8182627ae Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Sat, 5 Nov 2011 10:59:59 +0200 Subject: OMAPDSS: store overlays in a list for each manager Current way of handling overlay-manager links is a bit strange: each manager has a static array, containing pointers to all the overlays (even those used by other managers). The overlays contain a pointer to the manager being used. This patch makes the system a bit saner: each manager has a linked list of overlays, and only the overlays linked to that manager are in the list. Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/apply.c | 33 +++++++-------------------------- drivers/video/omap2/dss/manager.c | 10 ++++------ drivers/video/omap2/dss/overlay.c | 12 ++---------- include/video/omapdss.h | 3 +-- 4 files changed, 14 insertions(+), 44 deletions(-) (limited to 'include/video') diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c index ba1f73c136ce..34879d0628bd 100644 --- a/drivers/video/omap2/dss/apply.c +++ b/drivers/video/omap2/dss/apply.c @@ -398,8 +398,7 @@ void dss_mgr_start_update(struct omap_overlay_manager *mgr) { struct manager_cache_data *mc; struct overlay_cache_data *oc; - const int num_ovls = dss_feat_get_num_ovls(); - int i; + struct omap_overlay *ovl; mc = &dss_cache.manager_cache[mgr->id]; @@ -407,11 +406,8 @@ void dss_mgr_start_update(struct omap_overlay_manager *mgr) configure_dispc(); mc->do_manual_update = false; - for (i = 0; i < num_ovls; ++i) { - oc = &dss_cache.overlay_cache[i]; - if (oc->channel != mgr->id) - continue; - + list_for_each_entry(ovl, &mgr->overlays, list) { + oc = &dss_cache.overlay_cache[ovl->id]; oc->shadow_dirty = false; } @@ -584,8 +580,9 @@ static void omap_dss_mgr_apply_ovl_fifos(struct omap_overlay *ovl) int omap_dss_mgr_apply(struct omap_overlay_manager *mgr) { - int i, r; + int r; unsigned long flags; + struct omap_overlay *ovl; DSSDBG("omap_dss_mgr_apply(%s)\n", mgr->name); @@ -596,31 +593,15 @@ int omap_dss_mgr_apply(struct omap_overlay_manager *mgr) spin_lock_irqsave(&dss_cache.lock, flags); /* Configure overlays */ - for (i = 0; i < mgr->num_overlays; ++i) { - struct omap_overlay *ovl; - - ovl = mgr->overlays[i]; - - if (ovl->manager != mgr) - continue; - + list_for_each_entry(ovl, &mgr->overlays, list) omap_dss_mgr_apply_ovl(ovl); - } /* Configure manager */ omap_dss_mgr_apply_mgr(mgr); /* Configure overlay fifos */ - for (i = 0; i < mgr->num_overlays; ++i) { - struct omap_overlay *ovl; - - ovl = mgr->overlays[i]; - - if (ovl->manager != mgr) - continue; - + list_for_each_entry(ovl, &mgr->overlays, list) omap_dss_mgr_apply_ovl_fifos(ovl); - } r = 0; if (mgr->enabled && !mgr_manual_update(mgr)) { diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c index a08cc6e7f5ca..62bcc384e7ae 100644 --- a/drivers/video/omap2/dss/manager.c +++ b/drivers/video/omap2/dss/manager.c @@ -470,8 +470,8 @@ static struct kobj_type manager_ktype = { static int omap_dss_set_device(struct omap_overlay_manager *mgr, struct omap_dss_device *dssdev) { - int i; int r; + struct omap_overlay *ovl; if (dssdev->manager) { DSSERR("display '%s' already has a manager '%s'\n", @@ -485,10 +485,8 @@ static int omap_dss_set_device(struct omap_overlay_manager *mgr, return -EINVAL; } - for (i = 0; i < mgr->num_overlays; i++) { - struct omap_overlay *ovl = mgr->overlays[i]; - - if (ovl->manager != mgr || !ovl->info.enabled) + list_for_each_entry(ovl, &mgr->overlays, list) { + if (!ovl->info.enabled) continue; r = dss_check_overlay(ovl, dssdev); @@ -626,7 +624,7 @@ int dss_init_overlay_managers(struct platform_device *pdev) mgr->supported_displays = dss_feat_get_supported_displays(mgr->id); - dss_overlay_setup_dispc_manager(mgr); + INIT_LIST_HEAD(&mgr->overlays); r = kobject_init_and_add(&mgr->kobj, &manager_ktype, &pdev->dev.kobj, "manager%d", i); diff --git a/drivers/video/omap2/dss/overlay.c b/drivers/video/omap2/dss/overlay.c index ccd6127d2eef..3c940654ef91 100644 --- a/drivers/video/omap2/dss/overlay.c +++ b/drivers/video/omap2/dss/overlay.c @@ -566,6 +566,7 @@ static int omap_dss_set_manager(struct omap_overlay *ovl, } ovl->manager = mgr; + list_add_tail(&ovl->list, &mgr->overlays); ovl->manager_changed = true; /* XXX: When there is an overlay on a DSI manual update display, and @@ -597,6 +598,7 @@ static int omap_dss_unset_manager(struct omap_overlay *ovl) } ovl->manager = NULL; + list_del(&ovl->list); ovl->manager_changed = true; return 0; @@ -617,14 +619,6 @@ struct omap_overlay *omap_dss_get_overlay(int num) } EXPORT_SYMBOL(omap_dss_get_overlay); -static struct omap_overlay *dispc_overlays[MAX_DSS_OVERLAYS]; - -void dss_overlay_setup_dispc_manager(struct omap_overlay_manager *mgr) -{ - mgr->num_overlays = dss_feat_get_num_ovls(); - mgr->overlays = dispc_overlays; -} - void dss_init_overlays(struct platform_device *pdev) { int i, r; @@ -684,8 +678,6 @@ void dss_init_overlays(struct platform_device *pdev) if (r) DSSERR("failed to create sysfs file\n"); - - dispc_overlays[i] = ovl; } } diff --git a/include/video/omapdss.h b/include/video/omapdss.h index fd5a96c5ecc5..eaeca89de152 100644 --- a/include/video/omapdss.h +++ b/include/video/omapdss.h @@ -423,8 +423,7 @@ struct omap_overlay_manager { const char *name; enum omap_channel id; enum omap_overlay_manager_caps caps; - int num_overlays; - struct omap_overlay **overlays; + struct list_head overlays; enum omap_display_type supported_displays; /* dynamic fields */ -- cgit v1.2.3-70-g09d2 From 9a147a65de1ac89e506ef90413f41ebd96e03fd3 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Wed, 9 Nov 2011 15:30:11 +0200 Subject: OMAPDSS: DSI: call mgr_enable/disable for cmd mode displays The current code uses dsi_video_mode_enable/disable functions to enable/disable DISPC output for video mode displays. For command mode displays we have no notion in the DISPC side of whether the panel is enabled, except when a dss_mgr_start_update() call is made. However, to properly maintain the DISPC state in apply.c, we need to know if a manager used for a manual update display is currently in use. This patch achieves that by changing dsi_video_mode_enable/disable to dsi_enable/disable_video_output, which is called by both video and command mode displays. For video mode displays it starts the actual pixel stream, as it did before. For command mode displays it doesn't do anything else than mark that the manager is currently in use. Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/displays/panel-taal.c | 6 +++ drivers/video/omap2/dss/apply.c | 6 ++- drivers/video/omap2/dss/dsi.c | 73 +++++++++++++++++-------------- include/video/omapdss.h | 4 +- 4 files changed, 51 insertions(+), 38 deletions(-) (limited to 'include/video') diff --git a/drivers/video/omap2/displays/panel-taal.c b/drivers/video/omap2/displays/panel-taal.c index dd64bd13f4f8..00c5c615585f 100644 --- a/drivers/video/omap2/displays/panel-taal.c +++ b/drivers/video/omap2/displays/panel-taal.c @@ -1182,6 +1182,10 @@ static int taal_power_on(struct omap_dss_device *dssdev) if (r) goto err; + r = dsi_enable_video_output(dssdev, td->channel); + if (r) + goto err; + td->enabled = 1; if (!td->intro_printed) { @@ -1211,6 +1215,8 @@ static void taal_power_off(struct omap_dss_device *dssdev) struct taal_data *td = dev_get_drvdata(&dssdev->dev); int r; + dsi_disable_video_output(dssdev, td->channel); + r = taal_dcs_write_0(td, MIPI_DCS_SET_DISPLAY_OFF); if (!r) r = taal_sleep_in(td); diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c index eafa80846365..936571b7aace 100644 --- a/drivers/video/omap2/dss/apply.c +++ b/drivers/video/omap2/dss/apply.c @@ -648,7 +648,8 @@ void dss_mgr_enable(struct omap_overlay_manager *mgr) { mutex_lock(&apply_lock); - dispc_mgr_enable(mgr->id, true); + if (!mgr_manual_update(mgr)) + dispc_mgr_enable(mgr->id, true); mgr->enabled = true; mutex_unlock(&apply_lock); @@ -658,7 +659,8 @@ void dss_mgr_disable(struct omap_overlay_manager *mgr) { mutex_lock(&apply_lock); - dispc_mgr_enable(mgr->id, false); + if (!mgr_manual_update(mgr)) + dispc_mgr_enable(mgr->id, false); mgr->enabled = false; mutex_unlock(&apply_lock); diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index 9358afa2a77e..9cb2e827c001 100644 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/omap2/dss/dsi.c @@ -3973,65 +3973,70 @@ static void dsi_proto_timings(struct omap_dss_device *dssdev) } } -int dsi_video_mode_enable(struct omap_dss_device *dssdev, int channel) +int dsi_enable_video_output(struct omap_dss_device *dssdev, int channel) { struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); int bpp = dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt); u8 data_type; u16 word_count; - switch (dssdev->panel.dsi_pix_fmt) { - case OMAP_DSS_DSI_FMT_RGB888: - data_type = MIPI_DSI_PACKED_PIXEL_STREAM_24; - break; - case OMAP_DSS_DSI_FMT_RGB666: - data_type = MIPI_DSI_PIXEL_STREAM_3BYTE_18; - break; - case OMAP_DSS_DSI_FMT_RGB666_PACKED: - data_type = MIPI_DSI_PACKED_PIXEL_STREAM_18; - break; - case OMAP_DSS_DSI_FMT_RGB565: - data_type = MIPI_DSI_PACKED_PIXEL_STREAM_16; - break; - default: - BUG(); - }; + if (dssdev->panel.dsi_mode == OMAP_DSS_DSI_VIDEO_MODE) { + switch (dssdev->panel.dsi_pix_fmt) { + case OMAP_DSS_DSI_FMT_RGB888: + data_type = MIPI_DSI_PACKED_PIXEL_STREAM_24; + break; + case OMAP_DSS_DSI_FMT_RGB666: + data_type = MIPI_DSI_PIXEL_STREAM_3BYTE_18; + break; + case OMAP_DSS_DSI_FMT_RGB666_PACKED: + data_type = MIPI_DSI_PACKED_PIXEL_STREAM_18; + break; + case OMAP_DSS_DSI_FMT_RGB565: + data_type = MIPI_DSI_PACKED_PIXEL_STREAM_16; + break; + default: + BUG(); + }; - dsi_if_enable(dsidev, false); - dsi_vc_enable(dsidev, channel, false); + dsi_if_enable(dsidev, false); + dsi_vc_enable(dsidev, channel, false); - /* MODE, 1 = video mode */ - REG_FLD_MOD(dsidev, DSI_VC_CTRL(channel), 1, 4, 4); + /* MODE, 1 = video mode */ + REG_FLD_MOD(dsidev, DSI_VC_CTRL(channel), 1, 4, 4); - word_count = DIV_ROUND_UP(dssdev->panel.timings.x_res * bpp, 8); + word_count = DIV_ROUND_UP(dssdev->panel.timings.x_res * bpp, 8); - dsi_vc_write_long_header(dsidev, channel, data_type, word_count, 0); + dsi_vc_write_long_header(dsidev, channel, data_type, + word_count, 0); - dsi_vc_enable(dsidev, channel, true); - dsi_if_enable(dsidev, true); + dsi_vc_enable(dsidev, channel, true); + dsi_if_enable(dsidev, true); + } dss_mgr_enable(dssdev->manager); return 0; } -EXPORT_SYMBOL(dsi_video_mode_enable); +EXPORT_SYMBOL(dsi_enable_video_output); -void dsi_video_mode_disable(struct omap_dss_device *dssdev, int channel) +void dsi_disable_video_output(struct omap_dss_device *dssdev, int channel) { struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); - dsi_if_enable(dsidev, false); - dsi_vc_enable(dsidev, channel, false); + if (dssdev->panel.dsi_mode == OMAP_DSS_DSI_VIDEO_MODE) { + dsi_if_enable(dsidev, false); + dsi_vc_enable(dsidev, channel, false); - /* MODE, 0 = command mode */ - REG_FLD_MOD(dsidev, DSI_VC_CTRL(channel), 0, 4, 4); + /* MODE, 0 = command mode */ + REG_FLD_MOD(dsidev, DSI_VC_CTRL(channel), 0, 4, 4); - dsi_vc_enable(dsidev, channel, true); - dsi_if_enable(dsidev, true); + dsi_vc_enable(dsidev, channel, true); + dsi_if_enable(dsidev, true); + } dss_mgr_disable(dssdev->manager); } -EXPORT_SYMBOL(dsi_video_mode_disable); +EXPORT_SYMBOL(dsi_disable_video_output); static void dsi_update_screen_dispc(struct omap_dss_device *dssdev, u16 w, u16 h) diff --git a/include/video/omapdss.h b/include/video/omapdss.h index eaeca89de152..25ef771b0a31 100644 --- a/include/video/omapdss.h +++ b/include/video/omapdss.h @@ -294,8 +294,8 @@ int dsi_vc_set_max_rx_packet_size(struct omap_dss_device *dssdev, int channel, u16 len); int dsi_vc_send_null(struct omap_dss_device *dssdev, int channel); int dsi_vc_send_bta_sync(struct omap_dss_device *dssdev, int channel); -int dsi_video_mode_enable(struct omap_dss_device *dssdev, int channel); -void dsi_video_mode_disable(struct omap_dss_device *dssdev, int channel); +int dsi_enable_video_output(struct omap_dss_device *dssdev, int channel); +void dsi_disable_video_output(struct omap_dss_device *dssdev, int channel); /* Board specific data */ struct omap_dss_board_info { -- cgit v1.2.3-70-g09d2 From bf213523fe9708572a0b0a9149f7196a4f058564 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Tue, 15 Nov 2011 14:43:53 +0200 Subject: OMAPDSS: APPLY: move mgr->enabled to mgr_priv_data struct omap_overlay_manager contains "enabled"-field, used to track if the manager is enabled or not. This field should be internal to apply.c. This patch moves the field to mgr_priv_data, and applies the necessary locking when accessing the field. Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/apply.c | 26 +++++++++++++++++++++++--- include/video/omapdss.h | 2 -- 2 files changed, 23 insertions(+), 5 deletions(-) (limited to 'include/video') diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c index 936571b7aace..5bde08f19920 100644 --- a/drivers/video/omap2/dss/apply.c +++ b/drivers/video/omap2/dss/apply.c @@ -86,6 +86,9 @@ struct mgr_priv_data { bool manual_update; bool do_manual_update; + + /* If true, a display is enabled using this manager */ + bool enabled; }; static struct { @@ -609,6 +612,7 @@ int omap_dss_mgr_apply(struct omap_overlay_manager *mgr) int r; unsigned long flags; struct omap_overlay *ovl; + struct mgr_priv_data *mp = get_mgr_priv(mgr); DSSDBG("omap_dss_mgr_apply(%s)\n", mgr->name); @@ -630,7 +634,7 @@ int omap_dss_mgr_apply(struct omap_overlay_manager *mgr) omap_dss_mgr_apply_ovl_fifos(ovl); r = 0; - if (mgr->enabled && !mgr_manual_update(mgr)) { + if (mp->enabled && !mgr_manual_update(mgr)) { if (!dss_data.irq_enabled) dss_register_vsync_isr(); @@ -646,22 +650,38 @@ int omap_dss_mgr_apply(struct omap_overlay_manager *mgr) void dss_mgr_enable(struct omap_overlay_manager *mgr) { + struct mgr_priv_data *mp = get_mgr_priv(mgr); + unsigned long flags; + mutex_lock(&apply_lock); if (!mgr_manual_update(mgr)) dispc_mgr_enable(mgr->id, true); - mgr->enabled = true; + + spin_lock_irqsave(&data_lock, flags); + + mp->enabled = true; + + spin_unlock_irqrestore(&data_lock, flags); mutex_unlock(&apply_lock); } void dss_mgr_disable(struct omap_overlay_manager *mgr) { + struct mgr_priv_data *mp = get_mgr_priv(mgr); + unsigned long flags; + mutex_lock(&apply_lock); if (!mgr_manual_update(mgr)) dispc_mgr_enable(mgr->id, false); - mgr->enabled = false; + + spin_lock_irqsave(&data_lock, flags); + + mp->enabled = false; + + spin_unlock_irqrestore(&data_lock, flags); mutex_unlock(&apply_lock); } diff --git a/include/video/omapdss.h b/include/video/omapdss.h index 25ef771b0a31..6e3e7a716838 100644 --- a/include/video/omapdss.h +++ b/include/video/omapdss.h @@ -430,8 +430,6 @@ struct omap_overlay_manager { struct omap_dss_device *device; struct omap_overlay_manager_info info; - bool enabled; - bool device_changed; /* if true, info has been changed but not applied() yet */ bool info_dirty; -- cgit v1.2.3-70-g09d2 From aaa874a985158383c4b394c687c716ef26288741 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Tue, 15 Nov 2011 16:37:53 +0200 Subject: OMAPDSS: APPLY: rewrite overlay enable/disable Overlays are currently enabled and disabled with a boolean in the struct omap_overlay_info. The overlay info is set with ovl->set_overlay_info(), and made into use with mgr->apply(). This doesn't work properly, as the enable/disable status may affect also other overlays, for example when using fifo-merge. Thus the enabling and disabling of the overlay needs to be done outside the normal overlay configuration. This patch achieves that by doing the following things: 1) Add function pointers to struct omap_overlay: enable(), disable() and is_enabled(). These are used to do the obvious. The functions may block. 2) Move the "enabled" field from struct omap_overlay to ovl_priv_data. 3) Add a new route for settings to be applied to the HW, called "extra_info". The status of the normal info and extra_info are tracked separately. The point here is to allow the normal info to be changed and applied in non-blocking matter, whereas the extra_info can only be changed when holding the mutex. This makes it possible to, for example, set the overlay enable flag, apply it, and wait until the HW has taken the flag into use. This is not possible if the enable flag would be in the normal info, as a new value for the flag could be set at any time from the users of omapdss. Signed-off-by: Tomi Valkeinen --- drivers/media/video/omap/omap_vout.c | 33 +++--- drivers/video/omap2/dss/apply.c | 163 +++++++++++++++++++++++++----- drivers/video/omap2/dss/dss.h | 3 + drivers/video/omap2/dss/overlay.c | 20 ++-- drivers/video/omap2/omapfb/omapfb-ioctl.c | 30 +++--- drivers/video/omap2/omapfb/omapfb-main.c | 2 + drivers/video/omap2/omapfb/omapfb-sysfs.c | 4 +- drivers/video/omap2/omapfb/omapfb.h | 11 +- include/video/omapdss.h | 6 +- 9 files changed, 190 insertions(+), 82 deletions(-) (limited to 'include/video') diff --git a/drivers/media/video/omap/omap_vout.c b/drivers/media/video/omap/omap_vout.c index 9c5c19f142de..27c19fe78686 100644 --- a/drivers/media/video/omap/omap_vout.c +++ b/drivers/media/video/omap/omap_vout.c @@ -423,7 +423,7 @@ static int omapvid_setup_overlay(struct omap_vout_device *vout, "%s enable=%d addr=%x width=%d\n height=%d color_mode=%d\n" "rotation=%d mirror=%d posx=%d posy=%d out_width = %d \n" "out_height=%d rotation_type=%d screen_width=%d\n", - __func__, info.enabled, info.paddr, info.width, info.height, + __func__, ovl->is_enabled(ovl), info.paddr, info.width, info.height, info.color_mode, info.rotation, info.mirror, info.pos_x, info.pos_y, info.out_width, info.out_height, info.rotation_type, info.screen_width); @@ -942,12 +942,8 @@ static int omap_vout_release(struct file *file) /* Disable all the overlay managers connected with this interface */ for (i = 0; i < ovid->num_overlays; i++) { struct omap_overlay *ovl = ovid->overlays[i]; - if (ovl->manager && ovl->manager->device) { - struct omap_overlay_info info; - ovl->get_overlay_info(ovl, &info); - info.enabled = 0; - ovl->set_overlay_info(ovl, &info); - } + if (ovl->manager && ovl->manager->device) + ovl->disable(ovl); } /* Turn off the pipeline */ ret = omapvid_apply_changes(vout); @@ -1667,7 +1663,6 @@ static int vidioc_streamon(struct file *file, void *fh, enum v4l2_buf_type i) if (ovl->manager && ovl->manager->device) { struct omap_overlay_info info; ovl->get_overlay_info(ovl, &info); - info.enabled = 1; info.paddr = addr; if (ovl->set_overlay_info(ovl, &info)) { ret = -EINVAL; @@ -1686,6 +1681,16 @@ static int vidioc_streamon(struct file *file, void *fh, enum v4l2_buf_type i) if (ret) v4l2_err(&vout->vid_dev->v4l2_dev, "failed to change mode\n"); + for (j = 0; j < ovid->num_overlays; j++) { + struct omap_overlay *ovl = ovid->overlays[j]; + + if (ovl->manager && ovl->manager->device) { + ret = ovl->enable(ovl); + if (ret) + goto streamon_err1; + } + } + ret = 0; streamon_err1: @@ -1715,16 +1720,8 @@ static int vidioc_streamoff(struct file *file, void *fh, enum v4l2_buf_type i) for (j = 0; j < ovid->num_overlays; j++) { struct omap_overlay *ovl = ovid->overlays[j]; - if (ovl->manager && ovl->manager->device) { - struct omap_overlay_info info; - - ovl->get_overlay_info(ovl, &info); - info.enabled = 0; - ret = ovl->set_overlay_info(ovl, &info); - if (ret) - v4l2_err(&vout->vid_dev->v4l2_dev, - "failed to update overlay info in streamoff\n"); - } + if (ovl->manager && ovl->manager->device) + ovl->disable(ovl); } /* Turn of the pipeline */ diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c index 107a4ae6e5ac..eb28a7f178dd 100644 --- a/drivers/video/omap2/dss/apply.c +++ b/drivers/video/omap2/dss/apply.c @@ -63,14 +63,18 @@ struct ovl_priv_data { * VSYNC/EVSYNC */ bool shadow_dirty; - bool enabled; - struct omap_overlay_info info; enum omap_channel channel; u32 fifo_low; u32 fifo_high; + + bool extra_info_dirty; + bool shadow_extra_info_dirty; + + bool enabled; + }; struct mgr_priv_data { @@ -132,11 +136,6 @@ static bool mgr_manual_update(struct omap_overlay_manager *mgr) return mgr->device->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE; } -static int overlay_enabled(struct omap_overlay *ovl) -{ - return ovl->info.enabled && ovl->manager && ovl->manager->device; -} - int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr) { unsigned long timeout = msecs_to_jiffies(500); @@ -270,10 +269,8 @@ static int dss_ovl_write_regs(struct omap_overlay *ovl) op = get_ovl_priv(ovl); oi = &op->info; - if (!op->enabled) { - dispc_ovl_enable(ovl->id, 0); + if (!op->enabled) return 0; - } replication = dss_use_replication(ovl->manager->device, oi->color_mode); @@ -291,11 +288,21 @@ static int dss_ovl_write_regs(struct omap_overlay *ovl) dispc_ovl_set_fifo_threshold(ovl->id, op->fifo_low, op->fifo_high); - dispc_ovl_enable(ovl->id, 1); - return 0; } +static void dss_ovl_write_regs_extra(struct omap_overlay *ovl) +{ + struct ovl_priv_data *op = get_ovl_priv(ovl); + + DSSDBGF("%d", ovl->id); + + /* note: write also when op->enabled == false, so that the ovl gets + * disabled */ + + dispc_ovl_enable(ovl->id, op->enabled); +} + static void dss_mgr_write_regs(struct omap_overlay_manager *mgr) { struct mgr_priv_data *mp; @@ -356,6 +363,30 @@ static int dss_write_regs(void) mgr_go[op->channel] = true; } + for (i = 0; i < num_ovls; ++i) { + ovl = omap_dss_get_overlay(i); + op = get_ovl_priv(ovl); + + if (!op->extra_info_dirty) + continue; + + mp = get_mgr_priv(ovl->manager); + + if (mp->manual_update && !mp->do_manual_update) + continue; + + if (mp->busy) { + busy = true; + continue; + } + + dss_ovl_write_regs_extra(ovl); + + op->extra_info_dirty = false; + op->shadow_extra_info_dirty = true; + mgr_go[op->channel] = true; + } + /* Commit manager settings */ for (i = 0; i < num_mgrs; ++i) { mgr = omap_dss_get_overlay_manager(i); @@ -419,6 +450,7 @@ void dss_mgr_start_update(struct omap_overlay_manager *mgr) list_for_each_entry(ovl, &mgr->overlays, list) { op = get_ovl_priv(ovl); op->shadow_dirty = false; + op->shadow_extra_info_dirty = false; } mp->shadow_dirty = false; @@ -490,8 +522,10 @@ static void dss_apply_irq_handler(void *data, u32 mask) mp = get_mgr_priv(ovl->manager); - if (!mp->busy) + if (!mp->busy) { op->shadow_dirty = false; + op->shadow_extra_info_dirty = false; + } } for (i = 0; i < num_mgrs; ++i) { @@ -541,14 +575,6 @@ static void omap_dss_mgr_apply_ovl(struct omap_overlay *ovl) ovl->info_dirty = true; } - if (!overlay_enabled(ovl)) { - if (op->enabled) { - op->enabled = false; - op->dirty = true; - } - return; - } - if (!ovl->info_dirty) return; @@ -557,8 +583,6 @@ static void omap_dss_mgr_apply_ovl(struct omap_overlay *ovl) op->info = ovl->info; op->channel = ovl->manager->id; - - op->enabled = true; } static void omap_dss_mgr_apply_mgr(struct omap_overlay_manager *mgr) @@ -593,9 +617,6 @@ static void omap_dss_mgr_apply_ovl_fifos(struct omap_overlay *ovl) op = get_ovl_priv(ovl); - if (!op->enabled) - return; - dssdev = ovl->manager->device; size = dispc_ovl_get_fifo_size(ovl->id); @@ -828,6 +849,8 @@ void dss_ovl_get_info(struct omap_overlay *ovl, int dss_ovl_set_manager(struct omap_overlay *ovl, struct omap_overlay_manager *mgr) { + struct ovl_priv_data *op = get_ovl_priv(ovl); + unsigned long flags; int r; if (!mgr) @@ -842,7 +865,10 @@ int dss_ovl_set_manager(struct omap_overlay *ovl, goto err; } - if (ovl->info.enabled) { + spin_lock_irqsave(&data_lock, flags); + + if (op->enabled) { + spin_unlock_irqrestore(&data_lock, flags); DSSERR("overlay has to be disabled to change the manager\n"); r = -EINVAL; goto err; @@ -852,6 +878,8 @@ int dss_ovl_set_manager(struct omap_overlay *ovl, list_add_tail(&ovl->list, &mgr->overlays); ovl->manager_changed = true; + spin_unlock_irqrestore(&data_lock, flags); + /* XXX: When there is an overlay on a DSI manual update display, and * the overlay is first disabled, then moved to tv, and enabled, we * seem to get SYNC_LOST_DIGIT error. @@ -875,6 +903,8 @@ err: int dss_ovl_unset_manager(struct omap_overlay *ovl) { + struct ovl_priv_data *op = get_ovl_priv(ovl); + unsigned long flags; int r; mutex_lock(&apply_lock); @@ -885,7 +915,10 @@ int dss_ovl_unset_manager(struct omap_overlay *ovl) goto err; } - if (ovl->info.enabled) { + spin_lock_irqsave(&data_lock, flags); + + if (op->enabled) { + spin_unlock_irqrestore(&data_lock, flags); DSSERR("overlay has to be disabled to unset the manager\n"); r = -EINVAL; goto err; @@ -895,9 +928,83 @@ int dss_ovl_unset_manager(struct omap_overlay *ovl) list_del(&ovl->list); ovl->manager_changed = true; + spin_unlock_irqrestore(&data_lock, flags); + + mutex_unlock(&apply_lock); + + return 0; +err: + mutex_unlock(&apply_lock); + return r; +} + +bool dss_ovl_is_enabled(struct omap_overlay *ovl) +{ + struct ovl_priv_data *op = get_ovl_priv(ovl); + unsigned long flags; + bool e; + + spin_lock_irqsave(&data_lock, flags); + + e = op->enabled; + + spin_unlock_irqrestore(&data_lock, flags); + + return e; +} + +int dss_ovl_enable(struct omap_overlay *ovl) +{ + struct ovl_priv_data *op = get_ovl_priv(ovl); + unsigned long flags; + int r; + + mutex_lock(&apply_lock); + + if (ovl->manager == NULL || ovl->manager->device == NULL) { + r = -EINVAL; + goto err; + } + + spin_lock_irqsave(&data_lock, flags); + + op->enabled = true; + op->extra_info_dirty = true; + + spin_unlock_irqrestore(&data_lock, flags); + + mutex_unlock(&apply_lock); + + return 0; +err: + mutex_unlock(&apply_lock); + return r; +} + +int dss_ovl_disable(struct omap_overlay *ovl) +{ + struct ovl_priv_data *op = get_ovl_priv(ovl); + unsigned long flags; + int r; + + mutex_lock(&apply_lock); + + if (ovl->manager == NULL || ovl->manager->device == NULL) { + r = -EINVAL; + goto err; + } + + spin_lock_irqsave(&data_lock, flags); + + op->enabled = false; + op->extra_info_dirty = true; + + spin_unlock_irqrestore(&data_lock, flags); + mutex_unlock(&apply_lock); return 0; + err: mutex_unlock(&apply_lock); return r; diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h index a5493df14eee..7aac8a3367bc 100644 --- a/drivers/video/omap2/dss/dss.h +++ b/drivers/video/omap2/dss/dss.h @@ -180,6 +180,9 @@ int dss_mgr_set_device(struct omap_overlay_manager *mgr, struct omap_dss_device *dssdev); int dss_mgr_unset_device(struct omap_overlay_manager *mgr); +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, diff --git a/drivers/video/omap2/dss/overlay.c b/drivers/video/omap2/dss/overlay.c index 4dc6b92592d0..7d7cdf62059b 100644 --- a/drivers/video/omap2/dss/overlay.c +++ b/drivers/video/omap2/dss/overlay.c @@ -205,7 +205,7 @@ static ssize_t overlay_output_size_store(struct omap_overlay *ovl, static ssize_t overlay_enabled_show(struct omap_overlay *ovl, char *buf) { - return snprintf(buf, PAGE_SIZE, "%d\n", ovl->info.enabled); + return snprintf(buf, PAGE_SIZE, "%d\n", ovl->is_enabled(ovl)); } static ssize_t overlay_enabled_store(struct omap_overlay *ovl, const char *buf, @@ -213,26 +213,19 @@ static ssize_t overlay_enabled_store(struct omap_overlay *ovl, const char *buf, { int r; bool enable; - struct omap_overlay_info info; - - ovl->get_overlay_info(ovl, &info); r = strtobool(buf, &enable); if (r) return r; - info.enabled = enable; + if (enable) + r = ovl->enable(ovl); + else + r = ovl->disable(ovl); - r = ovl->set_overlay_info(ovl, &info); if (r) return r; - if (ovl->manager) { - r = ovl->manager->apply(ovl->manager); - if (r) - return r; - } - return size; } @@ -489,6 +482,9 @@ 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; diff --git a/drivers/video/omap2/omapfb/omapfb-ioctl.c b/drivers/video/omap2/omapfb/omapfb-ioctl.c index df7bcce5b107..562b5cc07609 100644 --- a/drivers/video/omap2/omapfb/omapfb-ioctl.c +++ b/drivers/video/omap2/omapfb/omapfb-ioctl.c @@ -111,28 +111,22 @@ static int omapfb_setup_plane(struct fb_info *fbi, struct omapfb_plane_info *pi) set_fb_fix(fbi); } - if (pi->enabled) { - struct omap_overlay_info info; + if (!pi->enabled) { + r = ovl->disable(ovl); + if (r) + goto undo; + } + if (pi->enabled) { r = omapfb_setup_overlay(fbi, ovl, pi->pos_x, pi->pos_y, pi->out_width, pi->out_height); if (r) goto undo; - - ovl->get_overlay_info(ovl, &info); - - if (!info.enabled) { - info.enabled = pi->enabled; - r = ovl->set_overlay_info(ovl, &info); - if (r) - goto undo; - } } else { struct omap_overlay_info info; ovl->get_overlay_info(ovl, &info); - info.enabled = pi->enabled; info.pos_x = pi->pos_x; info.pos_y = pi->pos_y; info.out_width = pi->out_width; @@ -146,6 +140,12 @@ static int omapfb_setup_plane(struct fb_info *fbi, struct omapfb_plane_info *pi) if (ovl->manager) ovl->manager->apply(ovl->manager); + if (pi->enabled) { + r = ovl->enable(ovl); + if (r) + goto undo; + } + /* Release the locks in a specific order to keep lockdep happy */ if (old_rg->id > new_rg->id) { omapfb_put_mem_region(old_rg); @@ -196,7 +196,7 @@ static int omapfb_query_plane(struct fb_info *fbi, struct omapfb_plane_info *pi) pi->pos_x = ovli->pos_x; pi->pos_y = ovli->pos_y; - pi->enabled = ovli->enabled; + pi->enabled = ovl->is_enabled(ovl); pi->channel_out = 0; /* xxx */ pi->mirror = 0; pi->mem_idx = get_mem_idx(ofbi); @@ -238,7 +238,9 @@ static int omapfb_setup_mem(struct fb_info *fbi, struct omapfb_mem_info *mi) continue; for (j = 0; j < ofbi2->num_overlays; j++) { - if (ofbi2->overlays[j]->info.enabled) { + struct omap_overlay *ovl; + ovl = ofbi2->overlays[j]; + if (ovl->is_enabled(ovl)) { r = -EBUSY; goto out; } diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c index 70aa47de7146..91b49b530695 100644 --- a/drivers/video/omap2/omapfb/omapfb-main.c +++ b/drivers/video/omap2/omapfb/omapfb-main.c @@ -2067,6 +2067,8 @@ static int omapfb_create_framebuffers(struct omapfb2_device *fbdev) if (ofbi->num_overlays > 0) { struct omap_overlay *ovl = ofbi->overlays[0]; + ovl->manager->apply(ovl->manager); + r = omapfb_overlay_enable(ovl, 1); if (r) { diff --git a/drivers/video/omap2/omapfb/omapfb-sysfs.c b/drivers/video/omap2/omapfb/omapfb-sysfs.c index 1694d5148f32..e8d8cc76a435 100644 --- a/drivers/video/omap2/omapfb/omapfb-sysfs.c +++ b/drivers/video/omap2/omapfb/omapfb-sysfs.c @@ -473,7 +473,9 @@ static ssize_t store_size(struct device *dev, struct device_attribute *attr, continue; for (j = 0; j < ofbi2->num_overlays; j++) { - if (ofbi2->overlays[j]->info.enabled) { + struct omap_overlay *ovl; + ovl = ofbi2->overlays[j]; + if (ovl->is_enabled(ovl)) { r = -EBUSY; goto out; } diff --git a/drivers/video/omap2/omapfb/omapfb.h b/drivers/video/omap2/omapfb/omapfb.h index fdf0edeccf4e..b03fb1365ce2 100644 --- a/drivers/video/omap2/omapfb/omapfb.h +++ b/drivers/video/omap2/omapfb/omapfb.h @@ -181,13 +181,10 @@ static inline void omapfb_unlock(struct omapfb2_device *fbdev) static inline int omapfb_overlay_enable(struct omap_overlay *ovl, int enable) { - struct omap_overlay_info info; - - ovl->get_overlay_info(ovl, &info); - if (info.enabled == enable) - return 0; - info.enabled = enable; - return ovl->set_overlay_info(ovl, &info); + if (enable) + return ovl->enable(ovl); + else + return ovl->disable(ovl); } static inline struct omapfb2_mem_region * diff --git a/include/video/omapdss.h b/include/video/omapdss.h index 6e3e7a716838..9d01ff66659f 100644 --- a/include/video/omapdss.h +++ b/include/video/omapdss.h @@ -352,8 +352,6 @@ struct omap_dss_cpr_coefs { }; struct omap_overlay_info { - bool enabled; - u32 paddr; u32 p_uv_addr; /* for NV12 format */ u16 screen_width; @@ -391,6 +389,10 @@ struct omap_overlay { /* if true, info has been changed, but not applied() yet */ bool info_dirty; + int (*enable)(struct omap_overlay *ovl); + int (*disable)(struct omap_overlay *ovl); + bool (*is_enabled)(struct omap_overlay *ovl); + int (*set_manager)(struct omap_overlay *ovl, struct omap_overlay_manager *mgr); int (*unset_manager)(struct omap_overlay *ovl); -- cgit v1.2.3-70-g09d2 From 388c4c6cbb335e69fe23c8d18bd4b0e8dd66901b Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Wed, 16 Nov 2011 13:58:07 +0200 Subject: OMAPDSS: APPLY: move mgr->info to apply.c struct omap_overlay_manager contains info and info_dirty fields, both of which should be internal to apply.c. This patch moves those fields into mgr_priv data, and names them user_info and user_info_dirty. Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/apply.c | 20 +++++++++++++------- drivers/video/omap2/dss/manager.c | 35 +++++++++++++++++++++++++++++------ include/video/omapdss.h | 3 --- 3 files changed, 42 insertions(+), 16 deletions(-) (limited to 'include/video') diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c index 8b157b03d4b6..62319b8328da 100644 --- a/drivers/video/omap2/dss/apply.c +++ b/drivers/video/omap2/dss/apply.c @@ -78,6 +78,10 @@ struct ovl_priv_data { }; struct mgr_priv_data { + + bool user_info_dirty; + struct omap_overlay_manager_info user_info; + /* If true, cache changed, but not written to shadow registers. Set * in apply(), cleared when registers written. */ bool dirty; @@ -592,15 +596,15 @@ static void omap_dss_mgr_apply_mgr(struct omap_overlay_manager *mgr) if (mgr->device_changed) { mgr->device_changed = false; - mgr->info_dirty = true; + mp->user_info_dirty = true; } - if (!mgr->info_dirty) + if (!mp->user_info_dirty) return; - mgr->info_dirty = false; + mp->user_info_dirty = false; mp->dirty = true; - mp->info = mgr->info; + mp->info = mp->user_info; } static void omap_dss_mgr_apply_ovl_fifos(struct omap_overlay *ovl) @@ -720,12 +724,13 @@ 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) { + struct mgr_priv_data *mp = get_mgr_priv(mgr); unsigned long flags; spin_lock_irqsave(&data_lock, flags); - mgr->info = *info; - mgr->info_dirty = true; + mp->user_info = *info; + mp->user_info_dirty = true; spin_unlock_irqrestore(&data_lock, flags); @@ -735,11 +740,12 @@ int dss_mgr_set_info(struct omap_overlay_manager *mgr, 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); unsigned long flags; spin_lock_irqsave(&data_lock, flags); - *info = mgr->info; + *info = mp->user_info; spin_unlock_irqrestore(&data_lock, flags); } diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c index d7fd494908d8..8c967ef2ae98 100644 --- a/drivers/video/omap2/dss/manager.c +++ b/drivers/video/omap2/dss/manager.c @@ -104,7 +104,11 @@ put_device: static ssize_t manager_default_color_show(struct omap_overlay_manager *mgr, char *buf) { - return snprintf(buf, PAGE_SIZE, "%#x\n", mgr->info.default_color); + struct omap_overlay_manager_info info; + + mgr->get_manager_info(mgr, &info); + + return snprintf(buf, PAGE_SIZE, "%#x\n", info.default_color); } static ssize_t manager_default_color_store(struct omap_overlay_manager *mgr, @@ -142,8 +146,11 @@ static ssize_t manager_trans_key_type_show(struct omap_overlay_manager *mgr, char *buf) { enum omap_dss_trans_key_type key_type; + struct omap_overlay_manager_info info; + + mgr->get_manager_info(mgr, &info); - key_type = mgr->info.trans_key_type; + key_type = info.trans_key_type; BUG_ON(key_type >= ARRAY_SIZE(trans_key_type_str)); return snprintf(buf, PAGE_SIZE, "%s\n", trans_key_type_str[key_type]); @@ -183,7 +190,11 @@ static ssize_t manager_trans_key_type_store(struct omap_overlay_manager *mgr, static ssize_t manager_trans_key_value_show(struct omap_overlay_manager *mgr, char *buf) { - return snprintf(buf, PAGE_SIZE, "%#x\n", mgr->info.trans_key); + struct omap_overlay_manager_info info; + + mgr->get_manager_info(mgr, &info); + + return snprintf(buf, PAGE_SIZE, "%#x\n", info.trans_key); } static ssize_t manager_trans_key_value_store(struct omap_overlay_manager *mgr, @@ -215,7 +226,11 @@ static ssize_t manager_trans_key_value_store(struct omap_overlay_manager *mgr, static ssize_t manager_trans_key_enabled_show(struct omap_overlay_manager *mgr, char *buf) { - return snprintf(buf, PAGE_SIZE, "%d\n", mgr->info.trans_enabled); + struct omap_overlay_manager_info info; + + mgr->get_manager_info(mgr, &info); + + return snprintf(buf, PAGE_SIZE, "%d\n", info.trans_enabled); } static ssize_t manager_trans_key_enabled_store(struct omap_overlay_manager *mgr, @@ -247,10 +262,14 @@ static ssize_t manager_trans_key_enabled_store(struct omap_overlay_manager *mgr, static ssize_t manager_alpha_blending_enabled_show( struct omap_overlay_manager *mgr, char *buf) { + struct omap_overlay_manager_info info; + + mgr->get_manager_info(mgr, &info); + WARN_ON(!dss_has_feature(FEAT_ALPHA_FIXED_ZORDER)); return snprintf(buf, PAGE_SIZE, "%d\n", - mgr->info.partial_alpha_enabled); + info.partial_alpha_enabled); } static ssize_t manager_alpha_blending_enabled_store( @@ -285,7 +304,11 @@ static ssize_t manager_alpha_blending_enabled_store( static ssize_t manager_cpr_enable_show(struct omap_overlay_manager *mgr, char *buf) { - return snprintf(buf, PAGE_SIZE, "%d\n", mgr->info.cpr_enable); + struct omap_overlay_manager_info info; + + mgr->get_manager_info(mgr, &info); + + return snprintf(buf, PAGE_SIZE, "%d\n", info.cpr_enable); } static ssize_t manager_cpr_enable_store(struct omap_overlay_manager *mgr, diff --git a/include/video/omapdss.h b/include/video/omapdss.h index 9d01ff66659f..0d5333f6e4a1 100644 --- a/include/video/omapdss.h +++ b/include/video/omapdss.h @@ -430,11 +430,8 @@ struct omap_overlay_manager { /* dynamic fields */ struct omap_dss_device *device; - struct omap_overlay_manager_info info; bool device_changed; - /* if true, info has been changed but not applied() yet */ - bool info_dirty; int (*set_device)(struct omap_overlay_manager *mgr, struct omap_dss_device *dssdev); -- cgit v1.2.3-70-g09d2 From c1a9febfafa2a9a9ac09b2de4c80aa96b41a03d1 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Wed, 16 Nov 2011 14:11:56 +0200 Subject: OMAPDSS: APPLY: move ovl->info to apply.c struct omap_overlayr contains info and info_dirty fields, both of which should be internal to apply.c. This patch moves those fields into ovl_priv data, and names them user_info and user_info_dirty. Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/apply.c | 51 +++++++++++++++++++++++++---- drivers/video/omap2/dss/overlay.c | 53 ++++++++++++++++++++----------- drivers/video/omap2/omapfb/omapfb-ioctl.c | 12 +++---- drivers/video/omap2/omapfb/omapfb-main.c | 12 ++++--- include/video/omapdss.h | 3 -- 5 files changed, 93 insertions(+), 38 deletions(-) (limited to 'include/video') diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c index 62319b8328da..debd37aa9128 100644 --- a/drivers/video/omap2/dss/apply.c +++ b/drivers/video/omap2/dss/apply.c @@ -55,6 +55,10 @@ */ struct ovl_priv_data { + + bool user_info_dirty; + struct omap_overlay_info user_info; + /* If true, cache changed, but not written to shadow registers. Set * in apply(), cleared when registers written. */ bool dirty; @@ -129,7 +133,38 @@ static struct mgr_priv_data *get_mgr_priv(struct omap_overlay_manager *mgr) void dss_apply_init(void) { + const int num_ovls = dss_feat_get_num_ovls(); + int i; + spin_lock_init(&data_lock); + + for (i = 0; i < num_ovls; ++i) { + struct ovl_priv_data *op; + + op = &dss_data.ovl_priv_data_array[i]; + + op->info.global_alpha = 255; + + switch (i) { + case 0: + op->info.zorder = 0; + break; + case 1: + op->info.zorder = + dss_has_feature(FEAT_ALPHA_FREE_ZORDER) ? 3 : 0; + break; + case 2: + op->info.zorder = + dss_has_feature(FEAT_ALPHA_FREE_ZORDER) ? 2 : 0; + break; + case 3: + op->info.zorder = + dss_has_feature(FEAT_ALPHA_FREE_ZORDER) ? 1 : 0; + break; + } + + op->user_info = op->info; + } } static bool ovl_manual_update(struct omap_overlay *ovl) @@ -575,15 +610,15 @@ static void omap_dss_mgr_apply_ovl(struct omap_overlay *ovl) if (ovl->manager_changed) { ovl->manager_changed = false; - ovl->info_dirty = true; + op->user_info_dirty = true; } - if (!ovl->info_dirty) + if (!op->user_info_dirty) return; - ovl->info_dirty = false; + op->user_info_dirty = false; op->dirty = true; - op->info = ovl->info; + op->info = op->user_info; op->channel = ovl->manager->id; } @@ -821,12 +856,13 @@ err: int dss_ovl_set_info(struct omap_overlay *ovl, struct omap_overlay_info *info) { + struct ovl_priv_data *op = get_ovl_priv(ovl); unsigned long flags; spin_lock_irqsave(&data_lock, flags); - ovl->info = *info; - ovl->info_dirty = true; + op->user_info = *info; + op->user_info_dirty = true; spin_unlock_irqrestore(&data_lock, flags); @@ -836,11 +872,12 @@ int dss_ovl_set_info(struct omap_overlay *ovl, void dss_ovl_get_info(struct omap_overlay *ovl, struct omap_overlay_info *info) { + struct ovl_priv_data *op = get_ovl_priv(ovl); unsigned long flags; spin_lock_irqsave(&data_lock, flags); - *info = ovl->info; + *info = op->user_info; spin_unlock_irqrestore(&data_lock, flags); } diff --git a/drivers/video/omap2/dss/overlay.c b/drivers/video/omap2/dss/overlay.c index 7d7cdf62059b..8d036e661a26 100644 --- a/drivers/video/omap2/dss/overlay.c +++ b/drivers/video/omap2/dss/overlay.c @@ -124,19 +124,31 @@ err: static ssize_t overlay_input_size_show(struct omap_overlay *ovl, char *buf) { + struct omap_overlay_info info; + + ovl->get_overlay_info(ovl, &info); + return snprintf(buf, PAGE_SIZE, "%d,%d\n", - ovl->info.width, ovl->info.height); + info.width, info.height); } static ssize_t overlay_screen_width_show(struct omap_overlay *ovl, char *buf) { - return snprintf(buf, PAGE_SIZE, "%d\n", ovl->info.screen_width); + struct omap_overlay_info info; + + ovl->get_overlay_info(ovl, &info); + + return snprintf(buf, PAGE_SIZE, "%d\n", info.screen_width); } static ssize_t overlay_position_show(struct omap_overlay *ovl, char *buf) { + struct omap_overlay_info info; + + ovl->get_overlay_info(ovl, &info); + return snprintf(buf, PAGE_SIZE, "%d,%d\n", - ovl->info.pos_x, ovl->info.pos_y); + info.pos_x, info.pos_y); } static ssize_t overlay_position_store(struct omap_overlay *ovl, @@ -170,8 +182,12 @@ static ssize_t overlay_position_store(struct omap_overlay *ovl, static ssize_t overlay_output_size_show(struct omap_overlay *ovl, char *buf) { + struct omap_overlay_info info; + + ovl->get_overlay_info(ovl, &info); + return snprintf(buf, PAGE_SIZE, "%d,%d\n", - ovl->info.out_width, ovl->info.out_height); + info.out_width, info.out_height); } static ssize_t overlay_output_size_store(struct omap_overlay *ovl, @@ -231,8 +247,12 @@ static ssize_t overlay_enabled_store(struct omap_overlay *ovl, const char *buf, static ssize_t overlay_global_alpha_show(struct omap_overlay *ovl, char *buf) { + struct omap_overlay_info info; + + ovl->get_overlay_info(ovl, &info); + return snprintf(buf, PAGE_SIZE, "%d\n", - ovl->info.global_alpha); + info.global_alpha); } static ssize_t overlay_global_alpha_store(struct omap_overlay *ovl, @@ -269,8 +289,12 @@ static ssize_t overlay_global_alpha_store(struct omap_overlay *ovl, static ssize_t overlay_pre_mult_alpha_show(struct omap_overlay *ovl, char *buf) { + struct omap_overlay_info info; + + ovl->get_overlay_info(ovl, &info); + return snprintf(buf, PAGE_SIZE, "%d\n", - ovl->info.pre_mult_alpha); + info.pre_mult_alpha); } static ssize_t overlay_pre_mult_alpha_store(struct omap_overlay *ovl, @@ -306,7 +330,11 @@ static ssize_t overlay_pre_mult_alpha_store(struct omap_overlay *ovl, static ssize_t overlay_zorder_show(struct omap_overlay *ovl, char *buf) { - return snprintf(buf, PAGE_SIZE, "%d\n", ovl->info.zorder); + struct omap_overlay_info info; + + ovl->get_overlay_info(ovl, &info); + + return snprintf(buf, PAGE_SIZE, "%d\n", info.zorder); } static ssize_t overlay_zorder_store(struct omap_overlay *ovl, @@ -456,29 +484,18 @@ void dss_init_overlays(struct platform_device *pdev) case 0: ovl->name = "gfx"; ovl->id = OMAP_DSS_GFX; - ovl->info.global_alpha = 255; - ovl->info.zorder = 0; break; case 1: ovl->name = "vid1"; ovl->id = OMAP_DSS_VIDEO1; - ovl->info.global_alpha = 255; - ovl->info.zorder = - dss_has_feature(FEAT_ALPHA_FREE_ZORDER) ? 3 : 0; break; case 2: ovl->name = "vid2"; ovl->id = OMAP_DSS_VIDEO2; - ovl->info.global_alpha = 255; - ovl->info.zorder = - dss_has_feature(FEAT_ALPHA_FREE_ZORDER) ? 2 : 0; break; case 3: ovl->name = "vid3"; ovl->id = OMAP_DSS_VIDEO3; - ovl->info.global_alpha = 255; - ovl->info.zorder = - dss_has_feature(FEAT_ALPHA_FREE_ZORDER) ? 1 : 0; break; } diff --git a/drivers/video/omap2/omapfb/omapfb-ioctl.c b/drivers/video/omap2/omapfb/omapfb-ioctl.c index 562b5cc07609..16ba6196f330 100644 --- a/drivers/video/omap2/omapfb/omapfb-ioctl.c +++ b/drivers/video/omap2/omapfb/omapfb-ioctl.c @@ -189,19 +189,19 @@ static int omapfb_query_plane(struct fb_info *fbi, struct omapfb_plane_info *pi) memset(pi, 0, sizeof(*pi)); } else { struct omap_overlay *ovl; - struct omap_overlay_info *ovli; + struct omap_overlay_info ovli; ovl = ofbi->overlays[0]; - ovli = &ovl->info; + ovl->get_overlay_info(ovl, &ovli); - pi->pos_x = ovli->pos_x; - pi->pos_y = ovli->pos_y; + pi->pos_x = ovli.pos_x; + pi->pos_y = ovli.pos_y; pi->enabled = ovl->is_enabled(ovl); pi->channel_out = 0; /* xxx */ pi->mirror = 0; pi->mem_idx = get_mem_idx(ofbi); - pi->out_width = ovli->out_width; - pi->out_height = ovli->out_height; + pi->out_width = ovli.out_width; + pi->out_height = ovli.out_height; } return 0; diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c index 91b49b530695..46024ab9dae6 100644 --- a/drivers/video/omap2/omapfb/omapfb-main.c +++ b/drivers/video/omap2/omapfb/omapfb-main.c @@ -970,16 +970,20 @@ int omapfb_apply_changes(struct fb_info *fbi, int init) outh = var->yres; } } else { - outw = ovl->info.out_width; - outh = ovl->info.out_height; + struct omap_overlay_info info; + ovl->get_overlay_info(ovl, &info); + outw = info.out_width; + outh = info.out_height; } if (init) { posx = 0; posy = 0; } else { - posx = ovl->info.pos_x; - posy = ovl->info.pos_y; + struct omap_overlay_info info; + ovl->get_overlay_info(ovl, &info); + posx = info.pos_x; + posy = info.pos_y; } r = omapfb_setup_overlay(fbi, ovl, posx, posy, outw, outh); diff --git a/include/video/omapdss.h b/include/video/omapdss.h index 0d5333f6e4a1..2e2c53f5e7ca 100644 --- a/include/video/omapdss.h +++ b/include/video/omapdss.h @@ -383,11 +383,8 @@ struct omap_overlay { /* dynamic fields */ struct omap_overlay_manager *manager; - struct omap_overlay_info info; bool manager_changed; - /* if true, info has been changed, but not applied() yet */ - bool info_dirty; int (*enable)(struct omap_overlay *ovl); int (*disable)(struct omap_overlay *ovl); -- cgit v1.2.3-70-g09d2 From 5d5a97a6fbf98f82ae50c837eba3ebcfea0902f8 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Wed, 16 Nov 2011 14:17:54 +0200 Subject: OMAPDSS: APPLY: move channel-field to extra_info set Setting overlay's output channel is currently handled at the same time as other overlay attributes. This is not right, as the normal attributes should only affect one overlay and manager, but changing the channel affects two managers. This patch moves the channel field into the "extra_info" set, handled together with enabled-status. Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/apply.c | 21 +++++++-------------- include/video/omapdss.h | 2 -- 2 files changed, 7 insertions(+), 16 deletions(-) (limited to 'include/video') diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c index debd37aa9128..3fd2ea163f05 100644 --- a/drivers/video/omap2/dss/apply.c +++ b/drivers/video/omap2/dss/apply.c @@ -69,8 +69,6 @@ struct ovl_priv_data { struct omap_overlay_info info; - enum omap_channel channel; - u32 fifo_low; u32 fifo_high; @@ -78,7 +76,7 @@ struct ovl_priv_data { bool shadow_extra_info_dirty; bool enabled; - + enum omap_channel channel; }; struct mgr_priv_data { @@ -384,8 +382,6 @@ static void dss_ovl_write_regs(struct omap_overlay *ovl) ilace = ovl->manager->device->type == OMAP_DISPLAY_TYPE_VENC; - dispc_ovl_set_channel_out(ovl->id, op->channel); - r = dispc_ovl_setup(ovl->id, oi, ilace, replication); if (r) { /* @@ -423,6 +419,7 @@ static void dss_ovl_write_regs_extra(struct omap_overlay *ovl) * disabled */ dispc_ovl_enable(ovl->id, op->enabled); + dispc_ovl_set_channel_out(ovl->id, op->channel); mp = get_mgr_priv(ovl->manager); @@ -608,19 +605,12 @@ static void omap_dss_mgr_apply_ovl(struct omap_overlay *ovl) op = get_ovl_priv(ovl); - if (ovl->manager_changed) { - ovl->manager_changed = false; - op->user_info_dirty = true; - } - if (!op->user_info_dirty) return; op->user_info_dirty = false; op->dirty = true; op->info = op->user_info; - - op->channel = ovl->manager->id; } static void omap_dss_mgr_apply_mgr(struct omap_overlay_manager *mgr) @@ -910,9 +900,11 @@ int dss_ovl_set_manager(struct omap_overlay *ovl, goto err; } + op->channel = mgr->id; + op->extra_info_dirty = true; + ovl->manager = mgr; list_add_tail(&ovl->list, &mgr->overlays); - ovl->manager_changed = true; spin_unlock_irqrestore(&data_lock, flags); @@ -960,9 +952,10 @@ int dss_ovl_unset_manager(struct omap_overlay *ovl) goto err; } + op->channel = -1; + ovl->manager = NULL; list_del(&ovl->list); - ovl->manager_changed = true; spin_unlock_irqrestore(&data_lock, flags); diff --git a/include/video/omapdss.h b/include/video/omapdss.h index 2e2c53f5e7ca..e629b0de3262 100644 --- a/include/video/omapdss.h +++ b/include/video/omapdss.h @@ -384,8 +384,6 @@ struct omap_overlay { /* dynamic fields */ struct omap_overlay_manager *manager; - bool manager_changed; - int (*enable)(struct omap_overlay *ovl); int (*disable)(struct omap_overlay *ovl); bool (*is_enabled)(struct omap_overlay *ovl); -- cgit v1.2.3-70-g09d2 From ff4733dcf56480bebcd3801adde27213b893635d Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Wed, 16 Nov 2011 14:54:42 +0200 Subject: OMAPDSS: APPLY: remove device_changed field omap_overlay_manager contains device_changed field, which no longer has any use. So remove the field and the few places where it is touched. Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/apply.c | 7 ------- include/video/omapdss.h | 2 -- 2 files changed, 9 deletions(-) (limited to 'include/video') diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c index 9916eb8e20d5..70154092d731 100644 --- a/drivers/video/omap2/dss/apply.c +++ b/drivers/video/omap2/dss/apply.c @@ -608,11 +608,6 @@ static void omap_dss_mgr_apply_mgr(struct omap_overlay_manager *mgr) mp = get_mgr_priv(mgr); - if (mgr->device_changed) { - mgr->device_changed = false; - mp->user_info_dirty = true; - } - if (!mp->user_info_dirty) return; @@ -807,7 +802,6 @@ int dss_mgr_set_device(struct omap_overlay_manager *mgr, dssdev->manager = mgr; mgr->device = dssdev; - mgr->device_changed = true; mutex_unlock(&apply_lock); @@ -840,7 +834,6 @@ int dss_mgr_unset_device(struct omap_overlay_manager *mgr) mgr->device->manager = NULL; mgr->device = NULL; - mgr->device_changed = true; mutex_unlock(&apply_lock); diff --git a/include/video/omapdss.h b/include/video/omapdss.h index e629b0de3262..98fc0267dd9e 100644 --- a/include/video/omapdss.h +++ b/include/video/omapdss.h @@ -426,8 +426,6 @@ struct omap_overlay_manager { /* dynamic fields */ struct omap_dss_device *device; - bool device_changed; - int (*set_device)(struct omap_overlay_manager *mgr, struct omap_dss_device *dssdev); int (*unset_device)(struct omap_overlay_manager *mgr); -- cgit v1.2.3-70-g09d2 From 9d11c321a84266db2dba82cfb0d9d3bc17c326a8 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Fri, 18 Nov 2011 12:38:38 +0200 Subject: OMAPDSS: Add comments about blocking of ovl/mgr functions Add comments specifying what ovl/mgr functions may block. Signed-off-by: Tomi Valkeinen --- include/video/omapdss.h | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'include/video') diff --git a/include/video/omapdss.h b/include/video/omapdss.h index 98fc0267dd9e..39862b8c9805 100644 --- a/include/video/omapdss.h +++ b/include/video/omapdss.h @@ -384,6 +384,17 @@ struct omap_overlay { /* dynamic fields */ struct omap_overlay_manager *manager; + /* + * The following functions do not block: + * + * is_enabled + * set_overlay_info + * get_overlay_info + * + * The rest of the functions may block and cannot be called from + * interrupt context + */ + int (*enable)(struct omap_overlay *ovl); int (*disable)(struct omap_overlay *ovl); bool (*is_enabled)(struct omap_overlay *ovl); @@ -426,6 +437,17 @@ struct omap_overlay_manager { /* dynamic fields */ struct omap_dss_device *device; + /* + * The following functions do not block: + * + * set_manager_info + * get_manager_info + * apply + * + * The rest of the functions may block and cannot be called from + * interrupt context + */ + int (*set_device)(struct omap_overlay_manager *mgr, struct omap_dss_device *dssdev); int (*unset_device)(struct omap_overlay_manager *mgr); -- cgit v1.2.3-70-g09d2 From ee9dfd82ff1317ac5c0147fe21508ad6d7df4cff Mon Sep 17 00:00:00 2001 From: Mythri P K Date: Mon, 2 Jan 2012 14:02:37 +0530 Subject: OMAPDSS: HDMI: Move duplicate code from boardfile Move duplicate HDMI mux_init code from omap4 and panda board file to display file. Signed-off-by: Mythri P K Signed-off-by: Tomi Valkeinen --- arch/arm/mach-omap2/board-4430sdp.c | 16 +--------------- arch/arm/mach-omap2/board-omap4panda.c | 17 +---------------- arch/arm/mach-omap2/display.c | 23 +++++++++++++++++++++++ include/video/omapdss.h | 2 ++ 4 files changed, 27 insertions(+), 31 deletions(-) (limited to 'include/video') diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c index 515646886b59..312b158240ed 100644 --- a/arch/arm/mach-omap2/board-4430sdp.c +++ b/arch/arm/mach-omap2/board-4430sdp.c @@ -595,20 +595,6 @@ static void __init omap_sfh7741prox_init(void) __func__, OMAP4_SFH7741_ENABLE_GPIO, error); } -static void sdp4430_hdmi_mux_init(void) -{ - /* PAD0_HDMI_HPD_PAD1_HDMI_CEC */ - omap_mux_init_signal("hdmi_hpd", - OMAP_PIN_INPUT_PULLUP); - omap_mux_init_signal("hdmi_cec", - OMAP_PIN_INPUT_PULLUP); - /* PAD0_HDMI_DDC_SCL_PAD1_HDMI_DDC_SDA */ - omap_mux_init_signal("hdmi_ddc_scl", - OMAP_PIN_INPUT_PULLUP); - omap_mux_init_signal("hdmi_ddc_sda", - OMAP_PIN_INPUT_PULLUP); -} - static struct gpio sdp4430_hdmi_gpios[] = { { HDMI_GPIO_HPD, GPIOF_OUT_INIT_HIGH, "hdmi_gpio_hpd" }, { HDMI_GPIO_LS_OE, GPIOF_OUT_INIT_HIGH, "hdmi_gpio_ls_oe" }, @@ -826,9 +812,9 @@ static void omap_4430sdp_display_init(void) pr_err("%s: Could not get display_sel GPIO\n", __func__); sdp4430_lcd_init(); - sdp4430_hdmi_mux_init(); sdp4430_picodlp_init(); omap_display_init(&sdp4430_dss_data); + omap_hdmi_init(); } #ifdef CONFIG_OMAP_MUX diff --git a/arch/arm/mach-omap2/board-omap4panda.c b/arch/arm/mach-omap2/board-omap4panda.c index a8c2c4263e38..9cc41ce29dab 100644 --- a/arch/arm/mach-omap2/board-omap4panda.c +++ b/arch/arm/mach-omap2/board-omap4panda.c @@ -478,21 +478,6 @@ int __init omap4_panda_dvi_init(void) return r; } - -static void omap4_panda_hdmi_mux_init(void) -{ - /* PAD0_HDMI_HPD_PAD1_HDMI_CEC */ - omap_mux_init_signal("hdmi_hpd", - OMAP_PIN_INPUT_PULLUP); - omap_mux_init_signal("hdmi_cec", - OMAP_PIN_INPUT_PULLUP); - /* PAD0_HDMI_DDC_SCL_PAD1_HDMI_DDC_SDA */ - omap_mux_init_signal("hdmi_ddc_scl", - OMAP_PIN_INPUT_PULLUP); - omap_mux_init_signal("hdmi_ddc_sda", - OMAP_PIN_INPUT_PULLUP); -} - static struct gpio panda_hdmi_gpios[] = { { HDMI_GPIO_HPD, GPIOF_OUT_INIT_HIGH, "hdmi_gpio_hpd" }, { HDMI_GPIO_LS_OE, GPIOF_OUT_INIT_HIGH, "hdmi_gpio_ls_oe" }, @@ -544,8 +529,8 @@ void omap4_panda_display_init(void) if (r) pr_err("error initializing panda DVI\n"); - omap4_panda_hdmi_mux_init(); omap_display_init(&omap4_panda_dss_data); + omap_hdmi_init(); } static void __init omap4_panda_init(void) diff --git a/arch/arm/mach-omap2/display.c b/arch/arm/mach-omap2/display.c index dce9905d64bb..8436088ffe13 100644 --- a/arch/arm/mach-omap2/display.c +++ b/arch/arm/mach-omap2/display.c @@ -29,6 +29,7 @@ #include #include +#include "mux.h" #include "control.h" #include "display.h" @@ -96,6 +97,20 @@ static const struct omap_dss_hwmod_data omap4_dss_hwmod_data[] __initdata = { { "dss_hdmi", "omapdss_hdmi", -1 }, }; +static void omap4_hdmi_mux_pads() +{ + /* PAD0_HDMI_HPD_PAD1_HDMI_CEC */ + omap_mux_init_signal("hdmi_hpd", + OMAP_PIN_INPUT_PULLUP); + omap_mux_init_signal("hdmi_cec", + OMAP_PIN_INPUT_PULLUP); + /* PAD0_HDMI_DDC_SCL_PAD1_HDMI_DDC_SDA */ + omap_mux_init_signal("hdmi_ddc_scl", + OMAP_PIN_INPUT_PULLUP); + omap_mux_init_signal("hdmi_ddc_sda", + OMAP_PIN_INPUT_PULLUP); +} + static int omap4_dsi_mux_pads(int dsi_id, unsigned lanes) { u32 enable_mask, enable_shift; @@ -129,6 +144,14 @@ static int omap4_dsi_mux_pads(int dsi_id, unsigned lanes) return 0; } +int omap_hdmi_init(void) +{ + if (cpu_is_omap44xx()) + omap4_hdmi_mux_pads(); + + return 0; +} + static int omap_dsi_enable_pads(int dsi_id, unsigned lane_mask) { if (cpu_is_omap44xx()) diff --git a/include/video/omapdss.h b/include/video/omapdss.h index 39862b8c9805..c1e3cb0d2c5e 100644 --- a/include/video/omapdss.h +++ b/include/video/omapdss.h @@ -309,6 +309,8 @@ struct omap_dss_board_info { /* Init with the board info */ extern int omap_display_init(struct omap_dss_board_info *board_data); +/* HDMI mux init*/ +extern int omap_hdmi_init(void); struct omap_display_platform_data { struct omap_dss_board_info *board_data; -- cgit v1.2.3-70-g09d2 From 9a9016832d2601a290db4dce6dd55552bdae5b1a Mon Sep 17 00:00:00 2001 From: Mythri P K Date: Mon, 2 Jan 2012 14:02:38 +0530 Subject: OMAPDSS: HDMI: Disable DDC internal pull up Disables the internal pull resistor for SDA and SCL which are enabled by default, as there are external pull up's in 4460 and 4430 ES2.3 SDP, Blaze and Panda Boards, It is done to avoid the EDID read failure. Signed-off-by: Ricardo Salveti de Araujo Signed-off-by: Mythri P K Signed-off-by: Tomi Valkeinen --- arch/arm/mach-omap2/board-4430sdp.c | 9 ++++++++- arch/arm/mach-omap2/board-omap4panda.c | 10 +++++++++- arch/arm/mach-omap2/display.c | 22 +++++++++++++++++++--- include/video/omapdss.h | 6 +++++- 4 files changed, 41 insertions(+), 6 deletions(-) (limited to 'include/video') diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c index 312b158240ed..e1fe304ce361 100644 --- a/arch/arm/mach-omap2/board-4430sdp.c +++ b/arch/arm/mach-omap2/board-4430sdp.c @@ -814,7 +814,14 @@ static void omap_4430sdp_display_init(void) sdp4430_lcd_init(); sdp4430_picodlp_init(); omap_display_init(&sdp4430_dss_data); - omap_hdmi_init(); + /* + * OMAP4460SDP/Blaze and OMAP4430 ES2.3 SDP/Blaze boards and + * later have external pull up on the HDMI I2C lines + */ + if (cpu_is_omap446x() || omap_rev() > OMAP4430_REV_ES2_2) + omap_hdmi_init(OMAP_HDMI_SDA_SCL_EXTERNAL_PULLUP); + else + omap_hdmi_init(0); } #ifdef CONFIG_OMAP_MUX diff --git a/arch/arm/mach-omap2/board-omap4panda.c b/arch/arm/mach-omap2/board-omap4panda.c index 9cc41ce29dab..3e1c507fb01f 100644 --- a/arch/arm/mach-omap2/board-omap4panda.c +++ b/arch/arm/mach-omap2/board-omap4panda.c @@ -530,7 +530,15 @@ void omap4_panda_display_init(void) pr_err("error initializing panda DVI\n"); omap_display_init(&omap4_panda_dss_data); - omap_hdmi_init(); + + /* + * OMAP4460SDP/Blaze and OMAP4430 ES2.3 SDP/Blaze boards and + * later have external pull up on the HDMI I2C lines + */ + if (cpu_is_omap446x() || omap_rev() > OMAP4430_REV_ES2_2) + omap_hdmi_init(OMAP_HDMI_SDA_SCL_EXTERNAL_PULLUP); + else + omap_hdmi_init(0); } static void __init omap4_panda_init(void) diff --git a/arch/arm/mach-omap2/display.c b/arch/arm/mach-omap2/display.c index 8436088ffe13..ffd9bd983023 100644 --- a/arch/arm/mach-omap2/display.c +++ b/arch/arm/mach-omap2/display.c @@ -97,8 +97,11 @@ static const struct omap_dss_hwmod_data omap4_dss_hwmod_data[] __initdata = { { "dss_hdmi", "omapdss_hdmi", -1 }, }; -static void omap4_hdmi_mux_pads() +static void omap4_hdmi_mux_pads(enum omap_hdmi_flags flags) { + u32 reg; + u16 control_i2c_1; + /* PAD0_HDMI_HPD_PAD1_HDMI_CEC */ omap_mux_init_signal("hdmi_hpd", OMAP_PIN_INPUT_PULLUP); @@ -109,6 +112,19 @@ static void omap4_hdmi_mux_pads() OMAP_PIN_INPUT_PULLUP); omap_mux_init_signal("hdmi_ddc_sda", OMAP_PIN_INPUT_PULLUP); + + /* + * CONTROL_I2C_1: HDMI_DDC_SDA_PULLUPRESX (bit 28) and + * HDMI_DDC_SCL_PULLUPRESX (bit 24) are set to disable + * internal pull up resistor. + */ + if (flags & OMAP_HDMI_SDA_SCL_EXTERNAL_PULLUP) { + control_i2c_1 = OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_I2C_1; + reg = omap4_ctrl_pad_readl(control_i2c_1); + reg |= (OMAP4_HDMI_DDC_SDA_PULLUPRESX_MASK | + OMAP4_HDMI_DDC_SCL_PULLUPRESX_MASK); + omap4_ctrl_pad_writel(reg, control_i2c_1); + } } static int omap4_dsi_mux_pads(int dsi_id, unsigned lanes) @@ -144,10 +160,10 @@ static int omap4_dsi_mux_pads(int dsi_id, unsigned lanes) return 0; } -int omap_hdmi_init(void) +int omap_hdmi_init(enum omap_hdmi_flags flags) { if (cpu_is_omap44xx()) - omap4_hdmi_mux_pads(); + omap4_hdmi_mux_pads(flags); return 0; } diff --git a/include/video/omapdss.h b/include/video/omapdss.h index c1e3cb0d2c5e..062b3b24ff10 100644 --- a/include/video/omapdss.h +++ b/include/video/omapdss.h @@ -200,6 +200,10 @@ enum omap_dss_clk_source { OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DSI, /* OMAP4: PLL2_CLK2 */ }; +enum omap_hdmi_flags { + OMAP_HDMI_SDA_SCL_EXTERNAL_PULLUP = 1 << 0, +}; + /* RFBI */ struct rfbi_timings { @@ -310,7 +314,7 @@ struct omap_dss_board_info { /* Init with the board info */ extern int omap_display_init(struct omap_dss_board_info *board_data); /* HDMI mux init*/ -extern int omap_hdmi_init(void); +extern int omap_hdmi_init(enum omap_hdmi_flags flags); struct omap_display_platform_data { struct omap_dss_board_info *board_data; -- cgit v1.2.3-70-g09d2