From 45324a2648bcfa96adeae71ae992da931eed79f6 Mon Sep 17 00:00:00 2001 From: Archit Taneja Date: Thu, 26 Apr 2012 19:31:22 +0530 Subject: OMAPDSS: APPLY: Add manager timings as extra_info in private data DISPC manager size and DISPC manager blanking parameters(for LCD managers) follow the shadow register programming model. Currently, they are programmed directly by the interface drivers. To configure manager timings using APPLY, there is a need to introduce extra info flags for managers, similar to what is done for overlays. This is needed because timings aren't a part of overlay_manager_info struct configured by a user of DSS, they are configured internally by the interface or panel drivers. Add dirty and shadow_dirty extra_info flags for managers, update these flags at the appropriate places. Rewrite the function extra_info_update_ongoing() slightly as checking for manager's extra_info flags can simplify the code a bit. Create function dss_mgr_set_timings() which applies the new manager timings to extra_info. Signed-off-by: Archit Taneja --- drivers/video/omap2/dss/apply.c | 96 +++++++++++++++++++++++++++++++++++------ drivers/video/omap2/dss/dss.h | 2 + 2 files changed, 85 insertions(+), 13 deletions(-) diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c index b10b3bc1931e..57686f66411c 100644 --- a/drivers/video/omap2/dss/apply.c +++ b/drivers/video/omap2/dss/apply.c @@ -99,6 +99,11 @@ struct mgr_priv_data { /* If true, a display is enabled using this manager */ bool enabled; + + bool extra_info_dirty; + bool shadow_extra_info_dirty; + + struct omap_video_timings timings; }; static struct { @@ -261,6 +266,20 @@ static bool need_isr(void) if (mp->shadow_info_dirty) return true; + /* + * NOTE: we don't check extra_info flags for disabled + * managers, once the manager is enabled, the extra_info + * related manager changes will be taken in by HW. + */ + + /* to write new values to registers */ + if (mp->extra_info_dirty) + return true; + + /* to set GO bit */ + if (mp->shadow_extra_info_dirty) + return true; + list_for_each_entry(ovl, &mgr->overlays, list) { struct ovl_priv_data *op; @@ -305,7 +324,7 @@ static bool need_go(struct omap_overlay_manager *mgr) mp = get_mgr_priv(mgr); - if (mp->shadow_info_dirty) + if (mp->shadow_info_dirty || mp->shadow_extra_info_dirty) return true; list_for_each_entry(ovl, &mgr->overlays, list) { @@ -320,20 +339,16 @@ static bool need_go(struct omap_overlay_manager *mgr) /* returns true if an extra_info field is currently being updated */ static bool extra_info_update_ongoing(void) { - const int num_ovls = omap_dss_get_num_overlays(); - struct ovl_priv_data *op; - struct omap_overlay *ovl; - struct mgr_priv_data *mp; + const int num_mgrs = dss_feat_get_num_mgrs(); int i; - for (i = 0; i < num_ovls; ++i) { - ovl = omap_dss_get_overlay(i); - op = get_ovl_priv(ovl); - - if (!ovl->manager) - continue; + for (i = 0; i < num_mgrs; ++i) { + struct omap_overlay_manager *mgr; + struct omap_overlay *ovl; + struct mgr_priv_data *mp; - mp = get_mgr_priv(ovl->manager); + mgr = omap_dss_get_overlay_manager(i); + mp = get_mgr_priv(mgr); if (!mp->enabled) continue; @@ -341,8 +356,15 @@ static bool extra_info_update_ongoing(void) if (!mp->updating) continue; - if (op->extra_info_dirty || op->shadow_extra_info_dirty) + if (mp->extra_info_dirty || mp->shadow_extra_info_dirty) return true; + + list_for_each_entry(ovl, &mgr->overlays, list) { + struct ovl_priv_data *op = get_ovl_priv(ovl); + + if (op->extra_info_dirty || op->shadow_extra_info_dirty) + return true; + } } return false; @@ -601,6 +623,22 @@ static void dss_mgr_write_regs(struct omap_overlay_manager *mgr) } } +static void dss_mgr_write_regs_extra(struct omap_overlay_manager *mgr) +{ + struct mgr_priv_data *mp = get_mgr_priv(mgr); + + DSSDBGF("%d", mgr->id); + + if (!mp->extra_info_dirty) + return; + + dispc_mgr_set_timings(mgr->id, &mp->timings); + + mp->extra_info_dirty = false; + if (mp->updating) + mp->shadow_extra_info_dirty = true; +} + static void dss_write_regs_common(void) { const int num_mgrs = omap_dss_get_num_overlay_managers(); @@ -654,6 +692,7 @@ static void dss_write_regs(void) } dss_mgr_write_regs(mgr); + dss_mgr_write_regs_extra(mgr); } } @@ -693,6 +732,7 @@ static void mgr_clear_shadow_dirty(struct omap_overlay_manager *mgr) mp = get_mgr_priv(mgr); mp->shadow_info_dirty = false; + mp->shadow_extra_info_dirty = false; list_for_each_entry(ovl, &mgr->overlays, list) { op = get_ovl_priv(ovl); @@ -719,6 +759,7 @@ void dss_mgr_start_update(struct omap_overlay_manager *mgr) } dss_mgr_write_regs(mgr); + dss_mgr_write_regs_extra(mgr); dss_write_regs_common(); @@ -1225,6 +1266,35 @@ err: return r; } +static void dss_apply_mgr_timings(struct omap_overlay_manager *mgr, + struct omap_video_timings *timings) +{ + struct mgr_priv_data *mp = get_mgr_priv(mgr); + + mp->timings = *timings; + mp->extra_info_dirty = true; +} + +void dss_mgr_set_timings(struct omap_overlay_manager *mgr, + struct omap_video_timings *timings) +{ + unsigned long flags; + + mutex_lock(&apply_lock); + + spin_lock_irqsave(&data_lock, flags); + + dss_apply_mgr_timings(mgr, timings); + + dss_write_regs(); + dss_set_go_bits(); + + spin_unlock_irqrestore(&data_lock, flags); + + wait_pending_extra_info_updates(); + + mutex_unlock(&apply_lock); +} int dss_ovl_set_info(struct omap_overlay *ovl, struct omap_overlay_info *info) diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h index 94d82344894f..b17a2120dc25 100644 --- a/drivers/video/omap2/dss/dss.h +++ b/drivers/video/omap2/dss/dss.h @@ -177,6 +177,8 @@ void dss_mgr_get_info(struct omap_overlay_manager *mgr, 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); +void dss_mgr_set_timings(struct omap_overlay_manager *mgr, + struct omap_video_timings *timings); bool dss_ovl_is_enabled(struct omap_overlay *ovl); int dss_ovl_enable(struct omap_overlay *ovl); -- cgit v1.2.3 From 4172116385ede7abcfbbcc6eb6b7133385695001 Mon Sep 17 00:00:00 2001 From: Archit Taneja Date: Thu, 26 Apr 2012 20:10:46 +0530 Subject: OMAPDSS: Apply manager timings instead of direct DISPC writes Replace the function dispc_mgr_set_timings() with dss_mgr_set_timings() in the interface drivers. The latter function ensures that the timing related DISPC registers are configured according to the shadow register programming model. Remove the call to dispc_mgr_go() in dpi_set_timings() as the manager's go bit is set by dss_mgr_set_timings(). Signed-off-by: Archit Taneja --- drivers/video/omap2/dss/dpi.c | 3 +-- drivers/video/omap2/dss/dsi.c | 5 ++--- drivers/video/omap2/dss/hdmi.c | 2 +- drivers/video/omap2/dss/rfbi.c | 4 ++-- drivers/video/omap2/dss/sdi.c | 2 +- drivers/video/omap2/dss/venc.c | 2 +- 6 files changed, 8 insertions(+), 10 deletions(-) diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c index cec116684365..e65cf1f9a694 100644 --- a/drivers/video/omap2/dss/dpi.c +++ b/drivers/video/omap2/dss/dpi.c @@ -156,7 +156,7 @@ static int dpi_set_mode(struct omap_dss_device *dssdev) t->pixel_clock = pck; } - dispc_mgr_set_timings(dssdev->manager->id, t); + dss_mgr_set_timings(dssdev->manager, t); return 0; } @@ -294,7 +294,6 @@ void dpi_set_timings(struct omap_dss_device *dssdev, } dpi_set_mode(dssdev); - dispc_mgr_go(dssdev->manager->id); dispc_runtime_put(); dss_runtime_put(); diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index 6c4b034d7685..95bc9964ab9c 100644 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/omap2/dss/dsi.c @@ -4215,13 +4215,12 @@ static int dsi_display_init_dispc(struct omap_dss_device *dssdev) dispc_mgr_enable_stallmode(dssdev->manager->id, true); dispc_mgr_enable_fifohandcheck(dssdev->manager->id, 1); - dispc_mgr_set_timings(dssdev->manager->id, &timings); + dss_mgr_set_timings(dssdev->manager, &timings); } else { dispc_mgr_enable_stallmode(dssdev->manager->id, false); dispc_mgr_enable_fifohandcheck(dssdev->manager->id, 0); - dispc_mgr_set_timings(dssdev->manager->id, - &dssdev->panel.timings); + dss_mgr_set_timings(dssdev->manager, &dssdev->panel.timings); } dispc_mgr_set_lcd_display_type(dssdev->manager->id, diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c index 56f6e9ce126f..8d4ff8c3d318 100644 --- a/drivers/video/omap2/dss/hdmi.c +++ b/drivers/video/omap2/dss/hdmi.c @@ -376,7 +376,7 @@ static int hdmi_power_on(struct omap_dss_device *dssdev) dispc_enable_gamma_table(0); /* tv size */ - dispc_mgr_set_timings(dssdev->manager->id, &dssdev->panel.timings); + dss_mgr_set_timings(dssdev->manager, &dssdev->panel.timings); hdmi.ip_data.ops->video_enable(&hdmi.ip_data, 1); diff --git a/drivers/video/omap2/dss/rfbi.c b/drivers/video/omap2/dss/rfbi.c index a81ffcbfa68a..feadfab27ec2 100644 --- a/drivers/video/omap2/dss/rfbi.c +++ b/drivers/video/omap2/dss/rfbi.c @@ -320,7 +320,7 @@ static void rfbi_transfer_area(struct omap_dss_device *dssdev, u16 width, DSSDBG("rfbi_transfer_area %dx%d\n", width, height); - dispc_mgr_set_timings(dssdev->manager->id, &timings); + dss_mgr_set_timings(dssdev->manager, &timings); dispc_mgr_enable(dssdev->manager->id, true); @@ -804,7 +804,7 @@ int omap_rfbi_prepare_update(struct omap_dss_device *dssdev, if (*w == 0 || *h == 0) return -EINVAL; - dispc_mgr_set_timings(dssdev->manager->id, &timings); + dss_mgr_set_timings(dssdev->manager, &timings); return 0; } diff --git a/drivers/video/omap2/dss/sdi.c b/drivers/video/omap2/dss/sdi.c index 741b8341439f..67fbe7cee412 100644 --- a/drivers/video/omap2/dss/sdi.c +++ b/drivers/video/omap2/dss/sdi.c @@ -107,7 +107,7 @@ int omapdss_sdi_display_enable(struct omap_dss_device *dssdev) } - dispc_mgr_set_timings(dssdev->manager->id, t); + dss_mgr_set_timings(dssdev->manager, t); r = dss_set_clock_div(&dss_cinfo); if (r) diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c index 30bbb63421b9..e2374645a442 100644 --- a/drivers/video/omap2/dss/venc.c +++ b/drivers/video/omap2/dss/venc.c @@ -444,7 +444,7 @@ static int venc_power_on(struct omap_dss_device *dssdev) timings = dssdev->panel.timings; timings.y_res /= 2; - dispc_mgr_set_timings(dssdev->manager->id, &timings); + dss_mgr_set_timings(dssdev->manager, &timings); r = regulator_enable(venc.vdda_dac_reg); if (r) -- cgit v1.2.3 From b917fa3961448903f4ee823917194bdf20709fbd Mon Sep 17 00:00:00 2001 From: Archit Taneja Date: Fri, 27 Apr 2012 01:07:28 +0530 Subject: OMAPDSS: MANAGER: Create a function to check manager timings Create a function dss_mgr_check_timings() which wraps around the function dispc_mgr_timings_ok(). This is mainly a clean up to hide dispc functions from interface drivers. dss_mgr_check_timings() is added in the function dss_mgr_check(), it currently takes the timings maintained in the omap_dss_device struct. This would be later replaced by the timings stored in the manager's private data. Make dss_mgr_check_timings() and dispc_mgr_timings_ok() take a const omap_video_timings pointer since these functions just check the timings. Signed-off-by: Archit Taneja --- drivers/video/omap2/dss/dispc.c | 2 +- drivers/video/omap2/dss/dpi.c | 2 +- drivers/video/omap2/dss/dss.h | 4 +++- drivers/video/omap2/dss/manager.c | 15 +++++++++++++++ 4 files changed, 20 insertions(+), 3 deletions(-) diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c index 82012d15884b..6eec08400094 100644 --- a/drivers/video/omap2/dss/dispc.c +++ b/drivers/video/omap2/dss/dispc.c @@ -2479,7 +2479,7 @@ static bool _dispc_lcd_timings_ok(int hsw, int hfp, int hbp, } bool dispc_mgr_timings_ok(enum omap_channel channel, - struct omap_video_timings *timings) + const struct omap_video_timings *timings) { bool timings_ok; diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c index e65cf1f9a694..e01ab9825930 100644 --- a/drivers/video/omap2/dss/dpi.c +++ b/drivers/video/omap2/dss/dpi.c @@ -311,7 +311,7 @@ int dpi_check_timings(struct omap_dss_device *dssdev, unsigned long pck; struct dispc_clock_info dispc_cinfo; - if (!dispc_mgr_timings_ok(dssdev->manager->id, timings)) + if (dss_mgr_check_timings(dssdev->manager, timings)) return -EINVAL; if (timings->pixel_clock == 0) diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h index b17a2120dc25..a13b3055a447 100644 --- a/drivers/video/omap2/dss/dss.h +++ b/drivers/video/omap2/dss/dss.h @@ -208,6 +208,8 @@ int dss_init_overlay_managers(struct platform_device *pdev); void dss_uninit_overlay_managers(struct platform_device *pdev); int dss_mgr_simple_check(struct omap_overlay_manager *mgr, const struct omap_overlay_manager_info *info); +int dss_mgr_check_timings(struct omap_overlay_manager *mgr, + const struct omap_video_timings *timings); int dss_mgr_check(struct omap_overlay_manager *mgr, struct omap_dss_device *dssdev, struct omap_overlay_manager_info *info, @@ -413,7 +415,7 @@ void dispc_enable_gamma_table(bool enable); void dispc_set_loadmode(enum omap_dss_load_mode mode); bool dispc_mgr_timings_ok(enum omap_channel channel, - struct omap_video_timings *timings); + const struct omap_video_timings *timings); unsigned long dispc_fclk_rate(void); void dispc_find_clk_divs(bool is_tft, unsigned long req_pck, unsigned long fck, struct dispc_clock_info *cinfo); diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c index e7364603f6a1..566fbba16774 100644 --- a/drivers/video/omap2/dss/manager.c +++ b/drivers/video/omap2/dss/manager.c @@ -654,6 +654,17 @@ static int dss_mgr_check_zorder(struct omap_overlay_manager *mgr, return 0; } +int dss_mgr_check_timings(struct omap_overlay_manager *mgr, + const struct omap_video_timings *timings) +{ + if (!dispc_mgr_timings_ok(mgr->id, timings)) { + DSSERR("check_manager: invalid timings\n"); + return -EINVAL; + } + + return 0; +} + int dss_mgr_check(struct omap_overlay_manager *mgr, struct omap_dss_device *dssdev, struct omap_overlay_manager_info *info, @@ -668,6 +679,10 @@ int dss_mgr_check(struct omap_overlay_manager *mgr, return r; } + r = dss_mgr_check_timings(mgr, &dssdev->panel.timings); + if (r) + return r; + list_for_each_entry(ovl, &mgr->overlays, list) { struct omap_overlay_info *oi; int r; -- cgit v1.2.3 From 5dd747e8892a63a5d4cc1d2765c0f533a5d74cfd Mon Sep 17 00:00:00 2001 From: Archit Taneja Date: Tue, 8 May 2012 18:19:15 +0530 Subject: OMAPDSS: APPLY: Don't check manager settings if it is disabled If a manager is disabled, there is no guarantee at any point in time that all it's parameters are configured. There is always a chance that some more parameters are yet to be configured by a user of DSS, or by DSS itself. However, when the manager is enabled, we can be certain that all the parameters have been configured, as we can't enable a manager with an incomplete configuration. Therefore, if a manager is disabled, don't check for the validity of it's parameters or the parameters of the overlays connected to it. Only check once it is enabled. Add a check in dss_check_settings_low() to achieve the same. Signed-off-by: Archit Taneja --- drivers/video/omap2/dss/apply.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c index 57686f66411c..ad349b3083c1 100644 --- a/drivers/video/omap2/dss/apply.c +++ b/drivers/video/omap2/dss/apply.c @@ -192,6 +192,9 @@ static int dss_check_settings_low(struct omap_overlay_manager *mgr, mp = get_mgr_priv(mgr); + if (!mp->enabled) + return 0; + if (applying && mp->user_info_dirty) mi = &mp->user_info; else -- cgit v1.2.3 From 228b21349db4ca5636ec1efdb3b3d54fe18092de Mon Sep 17 00:00:00 2001 From: Archit Taneja Date: Fri, 27 Apr 2012 01:22:28 +0530 Subject: OMAPDSS: APPLY: Remove display dependency from overlay and manager checks In order to check the validity of overlay and manager info, there was a need to use the omap_dss_device struct to get the panel resolution. The manager's private data in APPLY now contains the manager timings. Hence, we don't need to rely on the display resolution any more. Pass the manager's timings in private data to dss_mgr_check(). Remove the need to pass omap_dss_device structs in the functions which check for the validity of overlay and manager parameters. Signed-off-by: Archit Taneja --- drivers/video/omap2/dss/apply.c | 24 +++++++++++------------- drivers/video/omap2/dss/dss.h | 7 ++++--- drivers/video/omap2/dss/manager.c | 6 +++--- drivers/video/omap2/dss/overlay.c | 10 ++++------ 4 files changed, 22 insertions(+), 25 deletions(-) diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c index ad349b3083c1..0ffe4e101c56 100644 --- a/drivers/video/omap2/dss/apply.c +++ b/drivers/video/omap2/dss/apply.c @@ -181,7 +181,7 @@ static bool mgr_manual_update(struct omap_overlay_manager *mgr) } static int dss_check_settings_low(struct omap_overlay_manager *mgr, - struct omap_dss_device *dssdev, bool applying) + bool applying) { struct omap_overlay_info *oi; struct omap_overlay_manager_info *mi; @@ -214,26 +214,24 @@ static int dss_check_settings_low(struct omap_overlay_manager *mgr, ois[ovl->id] = oi; } - return dss_mgr_check(mgr, dssdev, mi, ois); + return dss_mgr_check(mgr, mi, &mp->timings, ois); } /* * check manager and overlay settings using overlay_info from data->info */ -static int dss_check_settings(struct omap_overlay_manager *mgr, - struct omap_dss_device *dssdev) +static int dss_check_settings(struct omap_overlay_manager *mgr) { - return dss_check_settings_low(mgr, dssdev, false); + return dss_check_settings_low(mgr, false); } /* * check manager and overlay settings using overlay_info from ovl->info if * dirty and from data->info otherwise */ -static int dss_check_settings_apply(struct omap_overlay_manager *mgr, - struct omap_dss_device *dssdev) +static int dss_check_settings_apply(struct omap_overlay_manager *mgr) { - return dss_check_settings_low(mgr, dssdev, true); + return dss_check_settings_low(mgr, true); } static bool need_isr(void) @@ -687,7 +685,7 @@ static void dss_write_regs(void) if (!mp->enabled || mgr_manual_update(mgr) || mp->busy) continue; - r = dss_check_settings(mgr, mgr->device); + r = dss_check_settings(mgr); if (r) { DSSERR("cannot write registers for manager %s: " "illegal configuration\n", mgr->name); @@ -754,7 +752,7 @@ void dss_mgr_start_update(struct omap_overlay_manager *mgr) WARN_ON(mp->updating); - r = dss_check_settings(mgr, mgr->device); + r = dss_check_settings(mgr); if (r) { DSSERR("cannot start manual update: illegal configuration\n"); spin_unlock_irqrestore(&data_lock, flags); @@ -901,7 +899,7 @@ int omap_dss_mgr_apply(struct omap_overlay_manager *mgr) spin_lock_irqsave(&data_lock, flags); - r = dss_check_settings_apply(mgr, mgr->device); + r = dss_check_settings_apply(mgr); if (r) { spin_unlock_irqrestore(&data_lock, flags); DSSERR("failed to apply settings: illegal configuration.\n"); @@ -1094,7 +1092,7 @@ int dss_mgr_enable(struct omap_overlay_manager *mgr) mp->enabled = true; - r = dss_check_settings(mgr, mgr->device); + r = dss_check_settings(mgr); if (r) { DSSERR("failed to enable manager %d: check_settings failed\n", mgr->id); @@ -1466,7 +1464,7 @@ int dss_ovl_enable(struct omap_overlay *ovl) op->enabling = true; - r = dss_check_settings(ovl->manager, ovl->manager->device); + r = dss_check_settings(ovl->manager); if (r) { DSSERR("failed to enable overlay %d: check_settings failed\n", ovl->id); diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h index a13b3055a447..f3fa4454446e 100644 --- a/drivers/video/omap2/dss/dss.h +++ b/drivers/video/omap2/dss/dss.h @@ -179,6 +179,7 @@ int dss_mgr_set_device(struct omap_overlay_manager *mgr, int dss_mgr_unset_device(struct omap_overlay_manager *mgr); void dss_mgr_set_timings(struct omap_overlay_manager *mgr, struct omap_video_timings *timings); +const struct omap_video_timings *dss_mgr_get_timings(struct omap_overlay_manager *mgr); bool dss_ovl_is_enabled(struct omap_overlay *ovl); int dss_ovl_enable(struct omap_overlay *ovl); @@ -211,8 +212,8 @@ int dss_mgr_simple_check(struct omap_overlay_manager *mgr, int dss_mgr_check_timings(struct omap_overlay_manager *mgr, const struct omap_video_timings *timings); int dss_mgr_check(struct omap_overlay_manager *mgr, - struct omap_dss_device *dssdev, struct omap_overlay_manager_info *info, + const struct omap_video_timings *mgr_timings, struct omap_overlay_info **overlay_infos); /* overlay */ @@ -222,8 +223,8 @@ void dss_overlay_setup_dispc_manager(struct omap_overlay_manager *mgr); void dss_recheck_connections(struct omap_dss_device *dssdev, bool force); int dss_ovl_simple_check(struct omap_overlay *ovl, const struct omap_overlay_info *info); -int dss_ovl_check(struct omap_overlay *ovl, - struct omap_overlay_info *info, struct omap_dss_device *dssdev); +int dss_ovl_check(struct omap_overlay *ovl, struct omap_overlay_info *info, + const struct omap_video_timings *mgr_timings); /* DSS */ int dss_init_platform_driver(void); diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c index 566fbba16774..0cbcde4c688a 100644 --- a/drivers/video/omap2/dss/manager.c +++ b/drivers/video/omap2/dss/manager.c @@ -666,8 +666,8 @@ int dss_mgr_check_timings(struct omap_overlay_manager *mgr, } int dss_mgr_check(struct omap_overlay_manager *mgr, - struct omap_dss_device *dssdev, struct omap_overlay_manager_info *info, + const struct omap_video_timings *mgr_timings, struct omap_overlay_info **overlay_infos) { struct omap_overlay *ovl; @@ -679,7 +679,7 @@ int dss_mgr_check(struct omap_overlay_manager *mgr, return r; } - r = dss_mgr_check_timings(mgr, &dssdev->panel.timings); + r = dss_mgr_check_timings(mgr, mgr_timings); if (r) return r; @@ -692,7 +692,7 @@ int dss_mgr_check(struct omap_overlay_manager *mgr, if (oi == NULL) continue; - r = dss_ovl_check(ovl, oi, dssdev); + r = dss_ovl_check(ovl, oi, mgr_timings); if (r) return r; } diff --git a/drivers/video/omap2/dss/overlay.c b/drivers/video/omap2/dss/overlay.c index 6e821810deec..0da5eb654ae9 100644 --- a/drivers/video/omap2/dss/overlay.c +++ b/drivers/video/omap2/dss/overlay.c @@ -631,16 +631,14 @@ int dss_ovl_simple_check(struct omap_overlay *ovl, return 0; } -int dss_ovl_check(struct omap_overlay *ovl, - struct omap_overlay_info *info, struct omap_dss_device *dssdev) +int dss_ovl_check(struct omap_overlay *ovl, struct omap_overlay_info *info, + const struct omap_video_timings *mgr_timings) { u16 outw, outh; u16 dw, dh; - if (dssdev == NULL) - return 0; - - dssdev->driver->get_resolution(dssdev, &dw, &dh); + dw = mgr_timings->x_res; + dh = mgr_timings->y_res; if ((ovl->caps & OMAP_DSS_OVL_CAP_SCALE) == 0) { outw = info->width; -- cgit v1.2.3 From fcc36619901064a76e15a545ea36d38ba0e54192 Mon Sep 17 00:00:00 2001 From: Archit Taneja Date: Thu, 3 May 2012 20:03:11 +0530 Subject: OMAPDSS: DPI/HDMI: Apply manager timings even if panel is disabled The DPI and HDMI interfaces use their 'set_timing' functions to take in a new set of timings. If the panel is disabled, they do not disable and re-enable the interface. Currently, the manager timings are applied in hdmi_power_on() and dpi_set_mode() respectively, these are not called by set_timings if the panel is disabled. When checking overlay and manager data, the DSS driver uses the last applied manager timings, and not the timings held by omap_dss_device struct. Hence, there is a need to apply the new manager timings even if the panel is disabled. Apply the manager timings if the panel is disabled. Eventually, there should be one common place where the timings are applied independent of the state of the panel. Signed-off-by: Archit Taneja --- drivers/video/omap2/dss/dpi.c | 2 ++ drivers/video/omap2/dss/hdmi.c | 2 ++ 2 files changed, 4 insertions(+) diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c index e01ab9825930..d6e8fe776152 100644 --- a/drivers/video/omap2/dss/dpi.c +++ b/drivers/video/omap2/dss/dpi.c @@ -297,6 +297,8 @@ void dpi_set_timings(struct omap_dss_device *dssdev, dispc_runtime_put(); dss_runtime_put(); + } else { + dss_mgr_set_timings(dssdev->manager, timings); } } EXPORT_SYMBOL(dpi_set_timings); diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c index 8d4ff8c3d318..32ad7124a952 100644 --- a/drivers/video/omap2/dss/hdmi.c +++ b/drivers/video/omap2/dss/hdmi.c @@ -435,6 +435,8 @@ void omapdss_hdmi_display_set_timing(struct omap_dss_device *dssdev) r = hdmi_power_on(dssdev); if (r) DSSERR("failed to power on device\n"); + } else { + dss_mgr_set_timings(dssdev->manager, &dssdev->panel.timings); } } -- cgit v1.2.3 From b3d795abb253c7605f8b6257f2e25e7ebaaf4b57 Mon Sep 17 00:00:00 2001 From: Archit Taneja Date: Mon, 9 Apr 2012 14:36:08 +0530 Subject: OMAPDSS: APPLY: Remove an unnecessary omap_dss_device pointer The omap_dss_device pointer declared in dss_ovl_setup_fifo() isn't used. Remove the pointer variable declaration and it's assignment. Signed-off-by: Archit Taneja --- drivers/video/omap2/dss/apply.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c index 0ffe4e101c56..15c070cc695f 100644 --- a/drivers/video/omap2/dss/apply.c +++ b/drivers/video/omap2/dss/apply.c @@ -960,14 +960,11 @@ static void dss_ovl_setup_fifo(struct omap_overlay *ovl, bool use_fifo_merge) { struct ovl_priv_data *op = get_ovl_priv(ovl); - struct omap_dss_device *dssdev; u32 fifo_low, fifo_high; if (!op->enabled && !op->enabling) return; - dssdev = ovl->manager->device; - dispc_ovl_compute_fifo_thresholds(ovl->id, &fifo_low, &fifo_high, use_fifo_merge); -- cgit v1.2.3 From 3fa03ba8542c40b90c95facfecd9b2789f71c0b6 Mon Sep 17 00:00:00 2001 From: Archit Taneja Date: Mon, 9 Apr 2012 15:06:41 +0530 Subject: OMAPDSS: DISPC: Remove omap_dss_device pointer usage from dispc_mgr_pclk_rate() The pixel clock rate for the TV manager is calculated by checking the device type connected to the manager, and then requesting the VENC/HDMI interface for the pixel clock rate. Remove the use of omap_dss_device pointer from here by checking which interface generates the pixel clock by reading the DSS_CTRL.VENC_HDMI_SWITCH bit. Signed-off-by: Archit Taneja --- drivers/video/omap2/dss/dispc.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c index 6eec08400094..cd0a3979c5d1 100644 --- a/drivers/video/omap2/dss/dispc.c +++ b/drivers/video/omap2/dss/dispc.c @@ -2643,13 +2643,14 @@ unsigned long dispc_mgr_pclk_rate(enum omap_channel channel) return r / pcd; } else { - struct omap_dss_device *dssdev = - dispc_mgr_get_device(channel); + enum dss_hdmi_venc_clk_source_select source; - switch (dssdev->type) { - case OMAP_DISPLAY_TYPE_VENC: + source = dss_get_hdmi_venc_clk_source(); + + switch (source) { + case DSS_VENC_TV_CLK: return venc_get_pixel_clock(); - case OMAP_DISPLAY_TYPE_HDMI: + case DSS_HDMI_M_PCLK: return hdmi_get_pixel_clock(); default: BUG(); -- cgit v1.2.3 From 81ab95b7ec91e47c81e5e6ef4aac7b08c1ae90aa Mon Sep 17 00:00:00 2001 From: Archit Taneja Date: Tue, 8 May 2012 15:53:20 +0530 Subject: OMAPDSS: DISPC: Remove usage of dispc_mgr_get_device() The functions calc_fclk_five_taps() and check_horiz_timing_omap3() use the function dispc_mgr_get_device() to get the omap_dss_device pointer to which the manager is connected, the width of the panel is derived from that. The manager's timing is stored in it's private data in APPLY. This contains the latest timings applied to the manager. Pass these timings to dispc_ovl_setup() and use them in the above functions. Remove the function dispc_mgr_get_device() as it isn't used any more. Signed-off-by: Archit Taneja --- drivers/video/omap2/dss/apply.c | 6 ++--- drivers/video/omap2/dss/dispc.c | 51 +++++++++++++++++++---------------------- drivers/video/omap2/dss/dss.h | 3 ++- 3 files changed, 28 insertions(+), 32 deletions(-) diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c index 15c070cc695f..dd88b8f936c4 100644 --- a/drivers/video/omap2/dss/apply.c +++ b/drivers/video/omap2/dss/apply.c @@ -548,11 +548,13 @@ static void dss_ovl_write_regs(struct omap_overlay *ovl) oi = &op->info; + mp = get_mgr_priv(ovl->manager); + replication = dss_use_replication(ovl->manager->device, oi->color_mode); ilace = ovl->manager->device->type == OMAP_DISPLAY_TYPE_VENC; - r = dispc_ovl_setup(ovl->id, oi, ilace, replication); + r = dispc_ovl_setup(ovl->id, oi, ilace, replication, &mp->timings); if (r) { /* * We can't do much here, as this function can be called from @@ -566,8 +568,6 @@ static void dss_ovl_write_regs(struct omap_overlay *ovl) return; } - mp = get_mgr_priv(ovl->manager); - op->info_dirty = false; if (mp->updating) op->shadow_info_dirty = true; diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c index cd0a3979c5d1..727e15b29a14 100644 --- a/drivers/video/omap2/dss/dispc.c +++ b/drivers/video/omap2/dss/dispc.c @@ -413,14 +413,6 @@ static inline bool dispc_mgr_is_lcd(enum omap_channel channel) return false; } -static struct omap_dss_device *dispc_mgr_get_device(enum omap_channel channel) -{ - struct omap_overlay_manager *mgr = - omap_dss_get_overlay_manager(channel); - - return mgr ? mgr->device : NULL; -} - u32 dispc_mgr_get_vsync_irq(enum omap_channel channel) { switch (channel) { @@ -1661,18 +1653,17 @@ static void calc_dma_rotation_offset(u8 rotation, bool mirror, * This function is used to avoid synclosts in OMAP3, because of some * undocumented horizontal position and timing related limitations. */ -static int check_horiz_timing_omap3(enum omap_channel channel, u16 pos_x, +static int check_horiz_timing_omap3(enum omap_channel channel, + const struct omap_video_timings *t, u16 pos_x, u16 width, u16 height, u16 out_width, u16 out_height) { int DS = DIV_ROUND_UP(height, out_height); - struct omap_dss_device *dssdev = dispc_mgr_get_device(channel); - struct omap_video_timings t = dssdev->panel.timings; unsigned long nonactive, lclk, pclk; static const u8 limits[3] = { 8, 10, 20 }; u64 val, blank; int i; - nonactive = t.x_res + t.hfp + t.hsw + t.hbp - out_width; + nonactive = t->x_res + t->hfp + t->hsw + t->hbp - out_width; pclk = dispc_mgr_pclk_rate(channel); if (dispc_mgr_is_lcd(channel)) lclk = dispc_mgr_lclk_rate(channel); @@ -1684,7 +1675,7 @@ static int check_horiz_timing_omap3(enum omap_channel channel, u16 pos_x, i++; if (out_width < width) i++; - blank = div_u64((u64)(t.hbp + t.hsw + t.hfp) * lclk, pclk); + blank = div_u64((u64)(t->hbp + t->hsw + t->hfp) * lclk, pclk); DSSDBG("blanking period + ppl = %llu (limit = %u)\n", blank, limits[i]); if (blank <= limits[i]) return -EINVAL; @@ -1715,7 +1706,8 @@ static int check_horiz_timing_omap3(enum omap_channel channel, u16 pos_x, } static unsigned long calc_core_clk_five_taps(enum omap_channel channel, - u16 width, u16 height, u16 out_width, u16 out_height, + const struct omap_video_timings *mgr_timings, u16 width, + u16 height, u16 out_width, u16 out_height, enum omap_color_mode color_mode) { u32 core_clk = 0; @@ -1725,8 +1717,7 @@ static unsigned long calc_core_clk_five_taps(enum omap_channel channel, return (unsigned long) pclk; if (height > out_height) { - struct omap_dss_device *dssdev = dispc_mgr_get_device(channel); - unsigned int ppl = dssdev->panel.timings.x_res; + unsigned int ppl = mgr_timings->x_res; tmp = pclk * height * out_width; do_div(tmp, 2 * out_height * ppl); @@ -1795,8 +1786,9 @@ static unsigned long calc_core_clk(enum omap_channel channel, u16 width, } static int dispc_ovl_calc_scaling(enum omap_plane plane, - enum omap_channel channel, u16 width, u16 height, - u16 out_width, u16 out_height, + enum omap_channel channel, + const struct omap_video_timings *mgr_timings, + u16 width, u16 height, u16 out_width, u16 out_height, enum omap_color_mode color_mode, bool *five_taps, int *x_predecim, int *y_predecim, u16 pos_x) { @@ -1871,11 +1863,13 @@ static int dispc_ovl_calc_scaling(enum omap_plane plane, do { in_height = DIV_ROUND_UP(height, decim_y); in_width = DIV_ROUND_UP(width, decim_x); - core_clk = calc_core_clk_five_taps(channel, in_width, - in_height, out_width, out_height, color_mode); + core_clk = calc_core_clk_five_taps(channel, mgr_timings, + in_width, in_height, out_width, out_height, + color_mode); - error = check_horiz_timing_omap3(channel, pos_x, - in_width, in_height, out_width, out_height); + error = check_horiz_timing_omap3(channel, mgr_timings, + pos_x, in_width, in_height, out_width, + out_height); if (in_width > maxsinglelinewidth) if (in_height > out_height && @@ -1900,8 +1894,8 @@ static int dispc_ovl_calc_scaling(enum omap_plane plane, } while (decim_x <= *x_predecim && decim_y <= *y_predecim && error); - if (check_horiz_timing_omap3(channel, pos_x, width, height, - out_width, out_height)){ + if (check_horiz_timing_omap3(channel, mgr_timings, pos_x, width, + height, out_width, out_height)){ DSSERR("horizontal timing too tight\n"); return -EINVAL; } @@ -1959,7 +1953,8 @@ static int dispc_ovl_calc_scaling(enum omap_plane plane, } int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi, - bool ilace, bool replication) + bool ilace, bool replication, + const struct omap_video_timings *mgr_timings) { struct omap_overlay *ovl = omap_dss_get_overlay(plane); bool five_taps = true; @@ -2008,9 +2003,9 @@ int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi, if (!dss_feat_color_mode_supported(plane, oi->color_mode)) return -EINVAL; - r = dispc_ovl_calc_scaling(plane, channel, in_width, in_height, - out_width, out_height, oi->color_mode, &five_taps, - &x_predecim, &y_predecim, oi->pos_x); + r = dispc_ovl_calc_scaling(plane, channel, mgr_timings, in_width, + in_height, out_width, out_height, oi->color_mode, + &five_taps, &x_predecim, &y_predecim, oi->pos_x); if (r) return r; diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h index f3fa4454446e..8e9e9a5765fa 100644 --- a/drivers/video/omap2/dss/dss.h +++ b/drivers/video/omap2/dss/dss.h @@ -428,7 +428,8 @@ void dispc_ovl_set_fifo_threshold(enum omap_plane plane, u32 low, u32 high); void dispc_ovl_compute_fifo_thresholds(enum omap_plane plane, u32 *fifo_low, u32 *fifo_high, bool use_fifomerge); int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi, - bool ilace, bool replication); + bool ilace, bool replication, + const struct omap_video_timings *mgr_timings); int dispc_ovl_enable(enum omap_plane plane, bool enable); void dispc_ovl_set_channel_out(enum omap_plane plane, enum omap_channel channel); -- cgit v1.2.3