aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTomi Valkeinen <tomi.valkeinen@ti.com>2012-05-09 06:50:32 -0400
committerTomi Valkeinen <tomi.valkeinen@ti.com>2012-05-09 06:53:52 -0400
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 {
99 99
100 /* If true, a display is enabled using this manager */ 100 /* If true, a display is enabled using this manager */
101 bool enabled; 101 bool enabled;
102
103 bool extra_info_dirty;
104 bool shadow_extra_info_dirty;
105
106 struct omap_video_timings timings;
102}; 107};
103 108
104static struct { 109static struct {
@@ -176,7 +181,7 @@ static bool mgr_manual_update(struct omap_overlay_manager *mgr)
176} 181}
177 182
178static int dss_check_settings_low(struct omap_overlay_manager *mgr, 183static int dss_check_settings_low(struct omap_overlay_manager *mgr,
179 struct omap_dss_device *dssdev, bool applying) 184 bool applying)
180{ 185{
181 struct omap_overlay_info *oi; 186 struct omap_overlay_info *oi;
182 struct omap_overlay_manager_info *mi; 187 struct omap_overlay_manager_info *mi;
@@ -187,6 +192,9 @@ static int dss_check_settings_low(struct omap_overlay_manager *mgr,
187 192
188 mp = get_mgr_priv(mgr); 193 mp = get_mgr_priv(mgr);
189 194
195 if (!mp->enabled)
196 return 0;
197
190 if (applying && mp->user_info_dirty) 198 if (applying && mp->user_info_dirty)
191 mi = &mp->user_info; 199 mi = &mp->user_info;
192 else 200 else
@@ -206,26 +214,24 @@ static int dss_check_settings_low(struct omap_overlay_manager *mgr,
206 ois[ovl->id] = oi; 214 ois[ovl->id] = oi;
207 } 215 }
208 216
209 return dss_mgr_check(mgr, dssdev, mi, ois); 217 return dss_mgr_check(mgr, mi, &mp->timings, ois);
210} 218}
211 219
212/* 220/*
213 * check manager and overlay settings using overlay_info from data->info 221 * check manager and overlay settings using overlay_info from data->info
214 */ 222 */
215static int dss_check_settings(struct omap_overlay_manager *mgr, 223static int dss_check_settings(struct omap_overlay_manager *mgr)
216 struct omap_dss_device *dssdev)
217{ 224{
218 return dss_check_settings_low(mgr, dssdev, false); 225 return dss_check_settings_low(mgr, false);
219} 226}
220 227
221/* 228/*
222 * check manager and overlay settings using overlay_info from ovl->info if 229 * check manager and overlay settings using overlay_info from ovl->info if
223 * dirty and from data->info otherwise 230 * dirty and from data->info otherwise
224 */ 231 */
225static int dss_check_settings_apply(struct omap_overlay_manager *mgr, 232static int dss_check_settings_apply(struct omap_overlay_manager *mgr)
226 struct omap_dss_device *dssdev)
227{ 233{
228 return dss_check_settings_low(mgr, dssdev, true); 234 return dss_check_settings_low(mgr, true);
229} 235}
230 236
231static bool need_isr(void) 237static bool need_isr(void)
@@ -261,6 +267,20 @@ static bool need_isr(void)
261 if (mp->shadow_info_dirty) 267 if (mp->shadow_info_dirty)
262 return true; 268 return true;
263 269
270 /*
271 * NOTE: we don't check extra_info flags for disabled
272 * managers, once the manager is enabled, the extra_info
273 * related manager changes will be taken in by HW.
274 */
275
276 /* to write new values to registers */
277 if (mp->extra_info_dirty)
278 return true;
279
280 /* to set GO bit */
281 if (mp->shadow_extra_info_dirty)
282 return true;
283
264 list_for_each_entry(ovl, &mgr->overlays, list) { 284 list_for_each_entry(ovl, &mgr->overlays, list) {
265 struct ovl_priv_data *op; 285 struct ovl_priv_data *op;
266 286
@@ -305,7 +325,7 @@ static bool need_go(struct omap_overlay_manager *mgr)
305 325
306 mp = get_mgr_priv(mgr); 326 mp = get_mgr_priv(mgr);
307 327
308 if (mp->shadow_info_dirty) 328 if (mp->shadow_info_dirty || mp->shadow_extra_info_dirty)
309 return true; 329 return true;
310 330
311 list_for_each_entry(ovl, &mgr->overlays, list) { 331 list_for_each_entry(ovl, &mgr->overlays, list) {
@@ -320,20 +340,16 @@ static bool need_go(struct omap_overlay_manager *mgr)
320/* returns true if an extra_info field is currently being updated */ 340/* returns true if an extra_info field is currently being updated */
321static bool extra_info_update_ongoing(void) 341static bool extra_info_update_ongoing(void)
322{ 342{
323 const int num_ovls = omap_dss_get_num_overlays(); 343 const int num_mgrs = dss_feat_get_num_mgrs();
324 struct ovl_priv_data *op;
325 struct omap_overlay *ovl;
326 struct mgr_priv_data *mp;
327 int i; 344 int i;
328 345
329 for (i = 0; i < num_ovls; ++i) { 346 for (i = 0; i < num_mgrs; ++i) {
330 ovl = omap_dss_get_overlay(i); 347 struct omap_overlay_manager *mgr;
331 op = get_ovl_priv(ovl); 348 struct omap_overlay *ovl;
332 349 struct mgr_priv_data *mp;
333 if (!ovl->manager)
334 continue;
335 350
336 mp = get_mgr_priv(ovl->manager); 351 mgr = omap_dss_get_overlay_manager(i);
352 mp = get_mgr_priv(mgr);
337 353
338 if (!mp->enabled) 354 if (!mp->enabled)
339 continue; 355 continue;
@@ -341,8 +357,15 @@ static bool extra_info_update_ongoing(void)
341 if (!mp->updating) 357 if (!mp->updating)
342 continue; 358 continue;
343 359
344 if (op->extra_info_dirty || op->shadow_extra_info_dirty) 360 if (mp->extra_info_dirty || mp->shadow_extra_info_dirty)
345 return true; 361 return true;
362
363 list_for_each_entry(ovl, &mgr->overlays, list) {
364 struct ovl_priv_data *op = get_ovl_priv(ovl);
365
366 if (op->extra_info_dirty || op->shadow_extra_info_dirty)
367 return true;
368 }
346 } 369 }
347 370
348 return false; 371 return false;
@@ -525,11 +548,13 @@ static void dss_ovl_write_regs(struct omap_overlay *ovl)
525 548
526 oi = &op->info; 549 oi = &op->info;
527 550
551 mp = get_mgr_priv(ovl->manager);
552
528 replication = dss_use_replication(ovl->manager->device, oi->color_mode); 553 replication = dss_use_replication(ovl->manager->device, oi->color_mode);
529 554
530 ilace = ovl->manager->device->type == OMAP_DISPLAY_TYPE_VENC; 555 ilace = ovl->manager->device->type == OMAP_DISPLAY_TYPE_VENC;
531 556
532 r = dispc_ovl_setup(ovl->id, oi, ilace, replication); 557 r = dispc_ovl_setup(ovl->id, oi, ilace, replication, &mp->timings);
533 if (r) { 558 if (r) {
534 /* 559 /*
535 * We can't do much here, as this function can be called from 560 * 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)
543 return; 568 return;
544 } 569 }
545 570
546 mp = get_mgr_priv(ovl->manager);
547
548 op->info_dirty = false; 571 op->info_dirty = false;
549 if (mp->updating) 572 if (mp->updating)
550 op->shadow_info_dirty = true; 573 op->shadow_info_dirty = true;
@@ -601,6 +624,22 @@ static void dss_mgr_write_regs(struct omap_overlay_manager *mgr)
601 } 624 }
602} 625}
603 626
627static void dss_mgr_write_regs_extra(struct omap_overlay_manager *mgr)
628{
629 struct mgr_priv_data *mp = get_mgr_priv(mgr);
630
631 DSSDBGF("%d", mgr->id);
632
633 if (!mp->extra_info_dirty)
634 return;
635
636 dispc_mgr_set_timings(mgr->id, &mp->timings);
637
638 mp->extra_info_dirty = false;
639 if (mp->updating)
640 mp->shadow_extra_info_dirty = true;
641}
642
604static void dss_write_regs_common(void) 643static void dss_write_regs_common(void)
605{ 644{
606 const int num_mgrs = omap_dss_get_num_overlay_managers(); 645 const int num_mgrs = omap_dss_get_num_overlay_managers();
@@ -646,7 +685,7 @@ static void dss_write_regs(void)
646 if (!mp->enabled || mgr_manual_update(mgr) || mp->busy) 685 if (!mp->enabled || mgr_manual_update(mgr) || mp->busy)
647 continue; 686 continue;
648 687
649 r = dss_check_settings(mgr, mgr->device); 688 r = dss_check_settings(mgr);
650 if (r) { 689 if (r) {
651 DSSERR("cannot write registers for manager %s: " 690 DSSERR("cannot write registers for manager %s: "
652 "illegal configuration\n", mgr->name); 691 "illegal configuration\n", mgr->name);
@@ -654,6 +693,7 @@ static void dss_write_regs(void)
654 } 693 }
655 694
656 dss_mgr_write_regs(mgr); 695 dss_mgr_write_regs(mgr);
696 dss_mgr_write_regs_extra(mgr);
657 } 697 }
658} 698}
659 699
@@ -693,6 +733,7 @@ static void mgr_clear_shadow_dirty(struct omap_overlay_manager *mgr)
693 733
694 mp = get_mgr_priv(mgr); 734 mp = get_mgr_priv(mgr);
695 mp->shadow_info_dirty = false; 735 mp->shadow_info_dirty = false;
736 mp->shadow_extra_info_dirty = false;
696 737
697 list_for_each_entry(ovl, &mgr->overlays, list) { 738 list_for_each_entry(ovl, &mgr->overlays, list) {
698 op = get_ovl_priv(ovl); 739 op = get_ovl_priv(ovl);
@@ -711,7 +752,7 @@ void dss_mgr_start_update(struct omap_overlay_manager *mgr)
711 752
712 WARN_ON(mp->updating); 753 WARN_ON(mp->updating);
713 754
714 r = dss_check_settings(mgr, mgr->device); 755 r = dss_check_settings(mgr);
715 if (r) { 756 if (r) {
716 DSSERR("cannot start manual update: illegal configuration\n"); 757 DSSERR("cannot start manual update: illegal configuration\n");
717 spin_unlock_irqrestore(&data_lock, flags); 758 spin_unlock_irqrestore(&data_lock, flags);
@@ -719,6 +760,7 @@ void dss_mgr_start_update(struct omap_overlay_manager *mgr)
719 } 760 }
720 761
721 dss_mgr_write_regs(mgr); 762 dss_mgr_write_regs(mgr);
763 dss_mgr_write_regs_extra(mgr);
722 764
723 dss_write_regs_common(); 765 dss_write_regs_common();
724 766
@@ -857,7 +899,7 @@ int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
857 899
858 spin_lock_irqsave(&data_lock, flags); 900 spin_lock_irqsave(&data_lock, flags);
859 901
860 r = dss_check_settings_apply(mgr, mgr->device); 902 r = dss_check_settings_apply(mgr);
861 if (r) { 903 if (r) {
862 spin_unlock_irqrestore(&data_lock, flags); 904 spin_unlock_irqrestore(&data_lock, flags);
863 DSSERR("failed to apply settings: illegal configuration.\n"); 905 DSSERR("failed to apply settings: illegal configuration.\n");
@@ -918,14 +960,11 @@ static void dss_ovl_setup_fifo(struct omap_overlay *ovl,
918 bool use_fifo_merge) 960 bool use_fifo_merge)
919{ 961{
920 struct ovl_priv_data *op = get_ovl_priv(ovl); 962 struct ovl_priv_data *op = get_ovl_priv(ovl);
921 struct omap_dss_device *dssdev;
922 u32 fifo_low, fifo_high; 963 u32 fifo_low, fifo_high;
923 964
924 if (!op->enabled && !op->enabling) 965 if (!op->enabled && !op->enabling)
925 return; 966 return;
926 967
927 dssdev = ovl->manager->device;
928
929 dispc_ovl_compute_fifo_thresholds(ovl->id, &fifo_low, &fifo_high, 968 dispc_ovl_compute_fifo_thresholds(ovl->id, &fifo_low, &fifo_high,
930 use_fifo_merge); 969 use_fifo_merge);
931 970
@@ -1050,7 +1089,7 @@ int dss_mgr_enable(struct omap_overlay_manager *mgr)
1050 1089
1051 mp->enabled = true; 1090 mp->enabled = true;
1052 1091
1053 r = dss_check_settings(mgr, mgr->device); 1092 r = dss_check_settings(mgr);
1054 if (r) { 1093 if (r) {
1055 DSSERR("failed to enable manager %d: check_settings failed\n", 1094 DSSERR("failed to enable manager %d: check_settings failed\n",
1056 mgr->id); 1095 mgr->id);
@@ -1225,6 +1264,35 @@ err:
1225 return r; 1264 return r;
1226} 1265}
1227 1266
1267static void dss_apply_mgr_timings(struct omap_overlay_manager *mgr,
1268 struct omap_video_timings *timings)
1269{
1270 struct mgr_priv_data *mp = get_mgr_priv(mgr);
1271
1272 mp->timings = *timings;
1273 mp->extra_info_dirty = true;
1274}
1275
1276void dss_mgr_set_timings(struct omap_overlay_manager *mgr,
1277 struct omap_video_timings *timings)
1278{
1279 unsigned long flags;
1280
1281 mutex_lock(&apply_lock);
1282
1283 spin_lock_irqsave(&data_lock, flags);
1284
1285 dss_apply_mgr_timings(mgr, timings);
1286
1287 dss_write_regs();
1288 dss_set_go_bits();
1289
1290 spin_unlock_irqrestore(&data_lock, flags);
1291
1292 wait_pending_extra_info_updates();
1293
1294 mutex_unlock(&apply_lock);
1295}
1228 1296
1229int dss_ovl_set_info(struct omap_overlay *ovl, 1297int dss_ovl_set_info(struct omap_overlay *ovl,
1230 struct omap_overlay_info *info) 1298 struct omap_overlay_info *info)
@@ -1393,7 +1461,7 @@ int dss_ovl_enable(struct omap_overlay *ovl)
1393 1461
1394 op->enabling = true; 1462 op->enabling = true;
1395 1463
1396 r = dss_check_settings(ovl->manager, ovl->manager->device); 1464 r = dss_check_settings(ovl->manager);
1397 if (r) { 1465 if (r) {
1398 DSSERR("failed to enable overlay %d: check_settings failed\n", 1466 DSSERR("failed to enable overlay %d: check_settings failed\n",
1399 ovl->id); 1467 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)
413 return false; 413 return false;
414} 414}
415 415
416static struct omap_dss_device *dispc_mgr_get_device(enum omap_channel channel)
417{
418 struct omap_overlay_manager *mgr =
419 omap_dss_get_overlay_manager(channel);
420
421 return mgr ? mgr->device : NULL;
422}
423
424u32 dispc_mgr_get_vsync_irq(enum omap_channel channel) 416u32 dispc_mgr_get_vsync_irq(enum omap_channel channel)
425{ 417{
426 switch (channel) { 418 switch (channel) {
@@ -1661,18 +1653,17 @@ static void calc_dma_rotation_offset(u8 rotation, bool mirror,
1661 * This function is used to avoid synclosts in OMAP3, because of some 1653 * This function is used to avoid synclosts in OMAP3, because of some
1662 * undocumented horizontal position and timing related limitations. 1654 * undocumented horizontal position and timing related limitations.
1663 */ 1655 */
1664static int check_horiz_timing_omap3(enum omap_channel channel, u16 pos_x, 1656static int check_horiz_timing_omap3(enum omap_channel channel,
1657 const struct omap_video_timings *t, u16 pos_x,
1665 u16 width, u16 height, u16 out_width, u16 out_height) 1658 u16 width, u16 height, u16 out_width, u16 out_height)
1666{ 1659{
1667 int DS = DIV_ROUND_UP(height, out_height); 1660 int DS = DIV_ROUND_UP(height, out_height);
1668 struct omap_dss_device *dssdev = dispc_mgr_get_device(channel);
1669 struct omap_video_timings t = dssdev->panel.timings;
1670 unsigned long nonactive, lclk, pclk; 1661 unsigned long nonactive, lclk, pclk;
1671 static const u8 limits[3] = { 8, 10, 20 }; 1662 static const u8 limits[3] = { 8, 10, 20 };
1672 u64 val, blank; 1663 u64 val, blank;
1673 int i; 1664 int i;
1674 1665
1675 nonactive = t.x_res + t.hfp + t.hsw + t.hbp - out_width; 1666 nonactive = t->x_res + t->hfp + t->hsw + t->hbp - out_width;
1676 pclk = dispc_mgr_pclk_rate(channel); 1667 pclk = dispc_mgr_pclk_rate(channel);
1677 if (dispc_mgr_is_lcd(channel)) 1668 if (dispc_mgr_is_lcd(channel))
1678 lclk = dispc_mgr_lclk_rate(channel); 1669 lclk = dispc_mgr_lclk_rate(channel);
@@ -1684,7 +1675,7 @@ static int check_horiz_timing_omap3(enum omap_channel channel, u16 pos_x,
1684 i++; 1675 i++;
1685 if (out_width < width) 1676 if (out_width < width)
1686 i++; 1677 i++;
1687 blank = div_u64((u64)(t.hbp + t.hsw + t.hfp) * lclk, pclk); 1678 blank = div_u64((u64)(t->hbp + t->hsw + t->hfp) * lclk, pclk);
1688 DSSDBG("blanking period + ppl = %llu (limit = %u)\n", blank, limits[i]); 1679 DSSDBG("blanking period + ppl = %llu (limit = %u)\n", blank, limits[i]);
1689 if (blank <= limits[i]) 1680 if (blank <= limits[i])
1690 return -EINVAL; 1681 return -EINVAL;
@@ -1715,7 +1706,8 @@ static int check_horiz_timing_omap3(enum omap_channel channel, u16 pos_x,
1715} 1706}
1716 1707
1717static unsigned long calc_core_clk_five_taps(enum omap_channel channel, 1708static unsigned long calc_core_clk_five_taps(enum omap_channel channel,
1718 u16 width, u16 height, u16 out_width, u16 out_height, 1709 const struct omap_video_timings *mgr_timings, u16 width,
1710 u16 height, u16 out_width, u16 out_height,
1719 enum omap_color_mode color_mode) 1711 enum omap_color_mode color_mode)
1720{ 1712{
1721 u32 core_clk = 0; 1713 u32 core_clk = 0;
@@ -1725,8 +1717,7 @@ static unsigned long calc_core_clk_five_taps(enum omap_channel channel,
1725 return (unsigned long) pclk; 1717 return (unsigned long) pclk;
1726 1718
1727 if (height > out_height) { 1719 if (height > out_height) {
1728 struct omap_dss_device *dssdev = dispc_mgr_get_device(channel); 1720 unsigned int ppl = mgr_timings->x_res;
1729 unsigned int ppl = dssdev->panel.timings.x_res;
1730 1721
1731 tmp = pclk * height * out_width; 1722 tmp = pclk * height * out_width;
1732 do_div(tmp, 2 * out_height * ppl); 1723 do_div(tmp, 2 * out_height * ppl);
@@ -1795,8 +1786,9 @@ static unsigned long calc_core_clk(enum omap_channel channel, u16 width,
1795} 1786}
1796 1787
1797static int dispc_ovl_calc_scaling(enum omap_plane plane, 1788static int dispc_ovl_calc_scaling(enum omap_plane plane,
1798 enum omap_channel channel, u16 width, u16 height, 1789 enum omap_channel channel,
1799 u16 out_width, u16 out_height, 1790 const struct omap_video_timings *mgr_timings,
1791 u16 width, u16 height, u16 out_width, u16 out_height,
1800 enum omap_color_mode color_mode, bool *five_taps, 1792 enum omap_color_mode color_mode, bool *five_taps,
1801 int *x_predecim, int *y_predecim, u16 pos_x) 1793 int *x_predecim, int *y_predecim, u16 pos_x)
1802{ 1794{
@@ -1871,11 +1863,13 @@ static int dispc_ovl_calc_scaling(enum omap_plane plane,
1871 do { 1863 do {
1872 in_height = DIV_ROUND_UP(height, decim_y); 1864 in_height = DIV_ROUND_UP(height, decim_y);
1873 in_width = DIV_ROUND_UP(width, decim_x); 1865 in_width = DIV_ROUND_UP(width, decim_x);
1874 core_clk = calc_core_clk_five_taps(channel, in_width, 1866 core_clk = calc_core_clk_five_taps(channel, mgr_timings,
1875 in_height, out_width, out_height, color_mode); 1867 in_width, in_height, out_width, out_height,
1868 color_mode);
1876 1869
1877 error = check_horiz_timing_omap3(channel, pos_x, 1870 error = check_horiz_timing_omap3(channel, mgr_timings,
1878 in_width, in_height, out_width, out_height); 1871 pos_x, in_width, in_height, out_width,
1872 out_height);
1879 1873
1880 if (in_width > maxsinglelinewidth) 1874 if (in_width > maxsinglelinewidth)
1881 if (in_height > out_height && 1875 if (in_height > out_height &&
@@ -1900,8 +1894,8 @@ static int dispc_ovl_calc_scaling(enum omap_plane plane,
1900 } while (decim_x <= *x_predecim && decim_y <= *y_predecim 1894 } while (decim_x <= *x_predecim && decim_y <= *y_predecim
1901 && error); 1895 && error);
1902 1896
1903 if (check_horiz_timing_omap3(channel, pos_x, width, height, 1897 if (check_horiz_timing_omap3(channel, mgr_timings, pos_x, width,
1904 out_width, out_height)){ 1898 height, out_width, out_height)){
1905 DSSERR("horizontal timing too tight\n"); 1899 DSSERR("horizontal timing too tight\n");
1906 return -EINVAL; 1900 return -EINVAL;
1907 } 1901 }
@@ -1959,7 +1953,8 @@ static int dispc_ovl_calc_scaling(enum omap_plane plane,
1959} 1953}
1960 1954
1961int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi, 1955int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi,
1962 bool ilace, bool replication) 1956 bool ilace, bool replication,
1957 const struct omap_video_timings *mgr_timings)
1963{ 1958{
1964 struct omap_overlay *ovl = omap_dss_get_overlay(plane); 1959 struct omap_overlay *ovl = omap_dss_get_overlay(plane);
1965 bool five_taps = true; 1960 bool five_taps = true;
@@ -2008,9 +2003,9 @@ int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi,
2008 if (!dss_feat_color_mode_supported(plane, oi->color_mode)) 2003 if (!dss_feat_color_mode_supported(plane, oi->color_mode))
2009 return -EINVAL; 2004 return -EINVAL;
2010 2005
2011 r = dispc_ovl_calc_scaling(plane, channel, in_width, in_height, 2006 r = dispc_ovl_calc_scaling(plane, channel, mgr_timings, in_width,
2012 out_width, out_height, oi->color_mode, &five_taps, 2007 in_height, out_width, out_height, oi->color_mode,
2013 &x_predecim, &y_predecim, oi->pos_x); 2008 &five_taps, &x_predecim, &y_predecim, oi->pos_x);
2014 if (r) 2009 if (r)
2015 return r; 2010 return r;
2016 2011
@@ -2479,7 +2474,7 @@ static bool _dispc_lcd_timings_ok(int hsw, int hfp, int hbp,
2479} 2474}
2480 2475
2481bool dispc_mgr_timings_ok(enum omap_channel channel, 2476bool dispc_mgr_timings_ok(enum omap_channel channel,
2482 struct omap_video_timings *timings) 2477 const struct omap_video_timings *timings)
2483{ 2478{
2484 bool timings_ok; 2479 bool timings_ok;
2485 2480
@@ -2643,13 +2638,14 @@ unsigned long dispc_mgr_pclk_rate(enum omap_channel channel)
2643 2638
2644 return r / pcd; 2639 return r / pcd;
2645 } else { 2640 } else {
2646 struct omap_dss_device *dssdev = 2641 enum dss_hdmi_venc_clk_source_select source;
2647 dispc_mgr_get_device(channel); 2642
2643 source = dss_get_hdmi_venc_clk_source();
2648 2644
2649 switch (dssdev->type) { 2645 switch (source) {
2650 case OMAP_DISPLAY_TYPE_VENC: 2646 case DSS_VENC_TV_CLK:
2651 return venc_get_pixel_clock(); 2647 return venc_get_pixel_clock();
2652 case OMAP_DISPLAY_TYPE_HDMI: 2648 case DSS_HDMI_M_PCLK:
2653 return hdmi_get_pixel_clock(); 2649 return hdmi_get_pixel_clock();
2654 default: 2650 default:
2655 BUG(); 2651 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)
156 t->pixel_clock = pck; 156 t->pixel_clock = pck;
157 } 157 }
158 158
159 dispc_mgr_set_timings(dssdev->manager->id, t); 159 dss_mgr_set_timings(dssdev->manager, t);
160 160
161 return 0; 161 return 0;
162} 162}
@@ -294,10 +294,11 @@ void dpi_set_timings(struct omap_dss_device *dssdev,
294 } 294 }
295 295
296 dpi_set_mode(dssdev); 296 dpi_set_mode(dssdev);
297 dispc_mgr_go(dssdev->manager->id);
298 297
299 dispc_runtime_put(); 298 dispc_runtime_put();
300 dss_runtime_put(); 299 dss_runtime_put();
300 } else {
301 dss_mgr_set_timings(dssdev->manager, timings);
301 } 302 }
302} 303}
303EXPORT_SYMBOL(dpi_set_timings); 304EXPORT_SYMBOL(dpi_set_timings);
@@ -312,7 +313,7 @@ int dpi_check_timings(struct omap_dss_device *dssdev,
312 unsigned long pck; 313 unsigned long pck;
313 struct dispc_clock_info dispc_cinfo; 314 struct dispc_clock_info dispc_cinfo;
314 315
315 if (!dispc_mgr_timings_ok(dssdev->manager->id, timings)) 316 if (dss_mgr_check_timings(dssdev->manager, timings))
316 return -EINVAL; 317 return -EINVAL;
317 318
318 if (timings->pixel_clock == 0) 319 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)
4215 dispc_mgr_enable_stallmode(dssdev->manager->id, true); 4215 dispc_mgr_enable_stallmode(dssdev->manager->id, true);
4216 dispc_mgr_enable_fifohandcheck(dssdev->manager->id, 1); 4216 dispc_mgr_enable_fifohandcheck(dssdev->manager->id, 1);
4217 4217
4218 dispc_mgr_set_timings(dssdev->manager->id, &timings); 4218 dss_mgr_set_timings(dssdev->manager, &timings);
4219 } else { 4219 } else {
4220 dispc_mgr_enable_stallmode(dssdev->manager->id, false); 4220 dispc_mgr_enable_stallmode(dssdev->manager->id, false);
4221 dispc_mgr_enable_fifohandcheck(dssdev->manager->id, 0); 4221 dispc_mgr_enable_fifohandcheck(dssdev->manager->id, 0);
4222 4222
4223 dispc_mgr_set_timings(dssdev->manager->id, 4223 dss_mgr_set_timings(dssdev->manager, &dssdev->panel.timings);
4224 &dssdev->panel.timings);
4225 } 4224 }
4226 4225
4227 dispc_mgr_set_lcd_display_type(dssdev->manager->id, 4226 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,
177int dss_mgr_set_device(struct omap_overlay_manager *mgr, 177int dss_mgr_set_device(struct omap_overlay_manager *mgr,
178 struct omap_dss_device *dssdev); 178 struct omap_dss_device *dssdev);
179int dss_mgr_unset_device(struct omap_overlay_manager *mgr); 179int dss_mgr_unset_device(struct omap_overlay_manager *mgr);
180void dss_mgr_set_timings(struct omap_overlay_manager *mgr,
181 struct omap_video_timings *timings);
182const struct omap_video_timings *dss_mgr_get_timings(struct omap_overlay_manager *mgr);
180 183
181bool dss_ovl_is_enabled(struct omap_overlay *ovl); 184bool dss_ovl_is_enabled(struct omap_overlay *ovl);
182int dss_ovl_enable(struct omap_overlay *ovl); 185int dss_ovl_enable(struct omap_overlay *ovl);
@@ -206,9 +209,11 @@ int dss_init_overlay_managers(struct platform_device *pdev);
206void dss_uninit_overlay_managers(struct platform_device *pdev); 209void dss_uninit_overlay_managers(struct platform_device *pdev);
207int dss_mgr_simple_check(struct omap_overlay_manager *mgr, 210int dss_mgr_simple_check(struct omap_overlay_manager *mgr,
208 const struct omap_overlay_manager_info *info); 211 const struct omap_overlay_manager_info *info);
212int dss_mgr_check_timings(struct omap_overlay_manager *mgr,
213 const struct omap_video_timings *timings);
209int dss_mgr_check(struct omap_overlay_manager *mgr, 214int dss_mgr_check(struct omap_overlay_manager *mgr,
210 struct omap_dss_device *dssdev,
211 struct omap_overlay_manager_info *info, 215 struct omap_overlay_manager_info *info,
216 const struct omap_video_timings *mgr_timings,
212 struct omap_overlay_info **overlay_infos); 217 struct omap_overlay_info **overlay_infos);
213 218
214/* overlay */ 219/* overlay */
@@ -218,8 +223,8 @@ void dss_overlay_setup_dispc_manager(struct omap_overlay_manager *mgr);
218void dss_recheck_connections(struct omap_dss_device *dssdev, bool force); 223void dss_recheck_connections(struct omap_dss_device *dssdev, bool force);
219int dss_ovl_simple_check(struct omap_overlay *ovl, 224int dss_ovl_simple_check(struct omap_overlay *ovl,
220 const struct omap_overlay_info *info); 225 const struct omap_overlay_info *info);
221int dss_ovl_check(struct omap_overlay *ovl, 226int dss_ovl_check(struct omap_overlay *ovl, struct omap_overlay_info *info,
222 struct omap_overlay_info *info, struct omap_dss_device *dssdev); 227 const struct omap_video_timings *mgr_timings);
223 228
224/* DSS */ 229/* DSS */
225int dss_init_platform_driver(void); 230int dss_init_platform_driver(void);
@@ -411,7 +416,7 @@ void dispc_enable_gamma_table(bool enable);
411void dispc_set_loadmode(enum omap_dss_load_mode mode); 416void dispc_set_loadmode(enum omap_dss_load_mode mode);
412 417
413bool dispc_mgr_timings_ok(enum omap_channel channel, 418bool dispc_mgr_timings_ok(enum omap_channel channel,
414 struct omap_video_timings *timings); 419 const struct omap_video_timings *timings);
415unsigned long dispc_fclk_rate(void); 420unsigned long dispc_fclk_rate(void);
416void dispc_find_clk_divs(bool is_tft, unsigned long req_pck, unsigned long fck, 421void dispc_find_clk_divs(bool is_tft, unsigned long req_pck, unsigned long fck,
417 struct dispc_clock_info *cinfo); 422 struct dispc_clock_info *cinfo);
@@ -423,7 +428,8 @@ void dispc_ovl_set_fifo_threshold(enum omap_plane plane, u32 low, u32 high);
423void dispc_ovl_compute_fifo_thresholds(enum omap_plane plane, 428void dispc_ovl_compute_fifo_thresholds(enum omap_plane plane,
424 u32 *fifo_low, u32 *fifo_high, bool use_fifomerge); 429 u32 *fifo_low, u32 *fifo_high, bool use_fifomerge);
425int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi, 430int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi,
426 bool ilace, bool replication); 431 bool ilace, bool replication,
432 const struct omap_video_timings *mgr_timings);
427int dispc_ovl_enable(enum omap_plane plane, bool enable); 433int dispc_ovl_enable(enum omap_plane plane, bool enable);
428void dispc_ovl_set_channel_out(enum omap_plane plane, 434void dispc_ovl_set_channel_out(enum omap_plane plane,
429 enum omap_channel channel); 435 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)
376 dispc_enable_gamma_table(0); 376 dispc_enable_gamma_table(0);
377 377
378 /* tv size */ 378 /* tv size */
379 dispc_mgr_set_timings(dssdev->manager->id, &dssdev->panel.timings); 379 dss_mgr_set_timings(dssdev->manager, &dssdev->panel.timings);
380 380
381 hdmi.ip_data.ops->video_enable(&hdmi.ip_data, 1); 381 hdmi.ip_data.ops->video_enable(&hdmi.ip_data, 1);
382 382
@@ -435,6 +435,8 @@ void omapdss_hdmi_display_set_timing(struct omap_dss_device *dssdev)
435 r = hdmi_power_on(dssdev); 435 r = hdmi_power_on(dssdev);
436 if (r) 436 if (r)
437 DSSERR("failed to power on device\n"); 437 DSSERR("failed to power on device\n");
438 } else {
439 dss_mgr_set_timings(dssdev->manager, &dssdev->panel.timings);
438 } 440 }
439} 441}
440 442
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,
654 return 0; 654 return 0;
655} 655}
656 656
657int dss_mgr_check_timings(struct omap_overlay_manager *mgr,
658 const struct omap_video_timings *timings)
659{
660 if (!dispc_mgr_timings_ok(mgr->id, timings)) {
661 DSSERR("check_manager: invalid timings\n");
662 return -EINVAL;
663 }
664
665 return 0;
666}
667
657int dss_mgr_check(struct omap_overlay_manager *mgr, 668int dss_mgr_check(struct omap_overlay_manager *mgr,
658 struct omap_dss_device *dssdev,
659 struct omap_overlay_manager_info *info, 669 struct omap_overlay_manager_info *info,
670 const struct omap_video_timings *mgr_timings,
660 struct omap_overlay_info **overlay_infos) 671 struct omap_overlay_info **overlay_infos)
661{ 672{
662 struct omap_overlay *ovl; 673 struct omap_overlay *ovl;
@@ -668,6 +679,10 @@ int dss_mgr_check(struct omap_overlay_manager *mgr,
668 return r; 679 return r;
669 } 680 }
670 681
682 r = dss_mgr_check_timings(mgr, mgr_timings);
683 if (r)
684 return r;
685
671 list_for_each_entry(ovl, &mgr->overlays, list) { 686 list_for_each_entry(ovl, &mgr->overlays, list) {
672 struct omap_overlay_info *oi; 687 struct omap_overlay_info *oi;
673 int r; 688 int r;
@@ -677,7 +692,7 @@ int dss_mgr_check(struct omap_overlay_manager *mgr,
677 if (oi == NULL) 692 if (oi == NULL)
678 continue; 693 continue;
679 694
680 r = dss_ovl_check(ovl, oi, dssdev); 695 r = dss_ovl_check(ovl, oi, mgr_timings);
681 if (r) 696 if (r)
682 return r; 697 return r;
683 } 698 }
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,
631 return 0; 631 return 0;
632} 632}
633 633
634int dss_ovl_check(struct omap_overlay *ovl, 634int dss_ovl_check(struct omap_overlay *ovl, struct omap_overlay_info *info,
635 struct omap_overlay_info *info, struct omap_dss_device *dssdev) 635 const struct omap_video_timings *mgr_timings)
636{ 636{
637 u16 outw, outh; 637 u16 outw, outh;
638 u16 dw, dh; 638 u16 dw, dh;
639 639
640 if (dssdev == NULL) 640 dw = mgr_timings->x_res;
641 return 0; 641 dh = mgr_timings->y_res;
642
643 dssdev->driver->get_resolution(dssdev, &dw, &dh);
644 642
645 if ((ovl->caps & OMAP_DSS_OVL_CAP_SCALE) == 0) { 643 if ((ovl->caps & OMAP_DSS_OVL_CAP_SCALE) == 0) {
646 outw = info->width; 644 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,
320 320
321 DSSDBG("rfbi_transfer_area %dx%d\n", width, height); 321 DSSDBG("rfbi_transfer_area %dx%d\n", width, height);
322 322
323 dispc_mgr_set_timings(dssdev->manager->id, &timings); 323 dss_mgr_set_timings(dssdev->manager, &timings);
324 324
325 dispc_mgr_enable(dssdev->manager->id, true); 325 dispc_mgr_enable(dssdev->manager->id, true);
326 326
@@ -804,7 +804,7 @@ int omap_rfbi_prepare_update(struct omap_dss_device *dssdev,
804 if (*w == 0 || *h == 0) 804 if (*w == 0 || *h == 0)
805 return -EINVAL; 805 return -EINVAL;
806 806
807 dispc_mgr_set_timings(dssdev->manager->id, &timings); 807 dss_mgr_set_timings(dssdev->manager, &timings);
808 808
809 return 0; 809 return 0;
810} 810}
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)
107 } 107 }
108 108
109 109
110 dispc_mgr_set_timings(dssdev->manager->id, t); 110 dss_mgr_set_timings(dssdev->manager, t);
111 111
112 r = dss_set_clock_div(&dss_cinfo); 112 r = dss_set_clock_div(&dss_cinfo);
113 if (r) 113 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)
444 timings = dssdev->panel.timings; 444 timings = dssdev->panel.timings;
445 timings.y_res /= 2; 445 timings.y_res /= 2;
446 446
447 dispc_mgr_set_timings(dssdev->manager->id, &timings); 447 dss_mgr_set_timings(dssdev->manager, &timings);
448 448
449 r = regulator_enable(venc.vdda_dac_reg); 449 r = regulator_enable(venc.vdda_dac_reg);
450 if (r) 450 if (r)