aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTomi Valkeinen <tomi.valkeinen@ti.com>2012-05-09 13:50:32 +0300
committerTomi Valkeinen <tomi.valkeinen@ti.com>2012-05-09 13:53:52 +0300
commit1dfafbc655b3723e37120d4b30e82d1c87767dd1 (patch)
treef20c901613fa622b2e05d0d20c0aa001925d5dd2
parent408d9dbbc4eebd8c4f2cd5d487f1b9c3c12c2c59 (diff)
parent81ab95b7ec91e47c81e5e6ef4aac7b08c1ae90aa (diff)
Merge branch 'archit/set-timing-work'
An overlay manager's timings (the manager size, and blanking parameters if an LCD manager) are DISPC shadow registers, and they should hence follow the correct programming model. This series makes the video timings an extra_info parameter in manager's private data. The interface drivers now apply the timings instead of directly writing to registers. This change also prevents the need to use display resolution for overlay checks, hence making some of the APPLY functions less dependent on the display. Some DISPC functions that needed display width can also use these privately stored timings. Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
-rw-r--r--drivers/video/omap2/dss/apply.c132
-rw-r--r--drivers/video/omap2/dss/dispc.c64
-rw-r--r--drivers/video/omap2/dss/dpi.c7
-rw-r--r--drivers/video/omap2/dss/dsi.c5
-rw-r--r--drivers/video/omap2/dss/dss.h16
-rw-r--r--drivers/video/omap2/dss/hdmi.c4
-rw-r--r--drivers/video/omap2/dss/manager.c19
-rw-r--r--drivers/video/omap2/dss/overlay.c10
-rw-r--r--drivers/video/omap2/dss/rfbi.c4
-rw-r--r--drivers/video/omap2/dss/sdi.c2
-rw-r--r--drivers/video/omap2/dss/venc.c2
11 files changed, 175 insertions, 90 deletions
diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c
index b10b3bc1931..dd88b8f936c 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 {
@@ -176,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;
@@ -187,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
@@ -206,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)
@@ -261,6 +267,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 +325,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 +340,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 +357,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;
@@ -525,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
@@ -543,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;
@@ -601,6 +624,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();
@@ -646,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);
@@ -654,6 +693,7 @@ static void dss_write_regs(void)
}
dss_mgr_write_regs(mgr);
+ dss_mgr_write_regs_extra(mgr);
}
}
@@ -693,6 +733,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);
@@ -711,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);
@@ -719,6 +760,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();
@@ -857,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");
@@ -918,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);
@@ -1050,7 +1089,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);
@@ -1225,6 +1264,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)
@@ -1393,7 +1461,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/dispc.c b/drivers/video/omap2/dss/dispc.c
index 82012d15884..727e15b29a1 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;
@@ -2479,7 +2474,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;
@@ -2643,13 +2638,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;
+
+ source = dss_get_hdmi_venc_clk_source();
- switch (dssdev->type) {
- case OMAP_DISPLAY_TYPE_VENC:
+ 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();
diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c
index cec11668436..d6e8fe77615 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,10 +294,11 @@ 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();
+ } else {
+ dss_mgr_set_timings(dssdev->manager, timings);
}
}
EXPORT_SYMBOL(dpi_set_timings);
@@ -312,7 +313,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/dsi.c b/drivers/video/omap2/dss/dsi.c
index 6c4b034d768..95bc9964ab9 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/dss.h b/drivers/video/omap2/dss/dss.h
index 94d82344894..8e9e9a5765f 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -177,6 +177,9 @@ 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);
+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);
@@ -206,9 +209,11 @@ 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,
+ const struct omap_video_timings *mgr_timings,
struct omap_overlay_info **overlay_infos);
/* overlay */
@@ -218,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);
@@ -411,7 +416,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);
@@ -423,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);
diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c
index 56f6e9ce126..32ad7124a95 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);
@@ -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);
}
}
diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c
index e7364603f6a..0cbcde4c688 100644
--- a/drivers/video/omap2/dss/manager.c
+++ b/drivers/video/omap2/dss/manager.c
@@ -654,9 +654,20 @@ 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,
+ const struct omap_video_timings *mgr_timings,
struct omap_overlay_info **overlay_infos)
{
struct omap_overlay *ovl;
@@ -668,6 +679,10 @@ int dss_mgr_check(struct omap_overlay_manager *mgr,
return r;
}
+ r = dss_mgr_check_timings(mgr, mgr_timings);
+ if (r)
+ return r;
+
list_for_each_entry(ovl, &mgr->overlays, list) {
struct omap_overlay_info *oi;
int r;
@@ -677,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 6e821810dee..0da5eb654ae 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;
diff --git a/drivers/video/omap2/dss/rfbi.c b/drivers/video/omap2/dss/rfbi.c
index a81ffcbfa68..feadfab27ec 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 741b8341439..67fbe7cee41 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 30bbb63421b..e2374645a44 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)