aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorArchit Taneja <archit@ti.com>2012-05-18 05:06:54 -0400
committerTomi Valkeinen <tomi.valkeinen@ti.com>2012-05-22 04:00:01 -0400
commit2aefad49d8e3a898cf629d4c5264ffd061113531 (patch)
tree0fb4f039679cfcb544d795b21eb3c148fe9c1287 /drivers
parent65e006ff4bb06d42b532f866a846db6e4e637723 (diff)
OMAPDSS: VENC/DISPC: Delay dividing Y resolution for managers connected to VENC
DSS2 driver uses the timings in manager's private data to check the validity of overlay and manager infos written by the user. For VENC interface, we divide the Y resolution by half when writing to the DISPC_DIGIT_SIZE register as the content is interlaced. However, the height of the manager/display with respect to the content shown through VENC still remains the same. The VENC driver divides the y_res parameter in omap_video_timings by half, and then applies the configuration. This leads to manager's private data storing the wrong Y resolution. Hence, overlay related checks fail. Ensure that manager's private data stores the original timings, and the Y resolution is halved only when we write to the DISPC register. This is a hack, the proper solution would be to pass some sort of interlace parameter which makes the call whether we should divide y_res or not. Signed-off-by: Archit Taneja <archit@ti.com> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/video/omap2/dss/dispc.c29
-rw-r--r--drivers/video/omap2/dss/venc.c6
2 files changed, 17 insertions, 18 deletions
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index 9626b2c0c9e1..4749ac356469 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -2665,37 +2665,40 @@ void dispc_mgr_set_timings(enum omap_channel channel,
2665{ 2665{
2666 unsigned xtot, ytot; 2666 unsigned xtot, ytot;
2667 unsigned long ht, vt; 2667 unsigned long ht, vt;
2668 struct omap_video_timings t = *timings;
2668 2669
2669 DSSDBG("channel %d xres %u yres %u\n", channel, timings->x_res, 2670 DSSDBG("channel %d xres %u yres %u\n", channel, t.x_res, t.y_res);
2670 timings->y_res);
2671 2671
2672 if (!dispc_mgr_timings_ok(channel, timings)) { 2672 if (!dispc_mgr_timings_ok(channel, &t)) {
2673 BUG(); 2673 BUG();
2674 return; 2674 return;
2675 } 2675 }
2676 2676
2677 if (dispc_mgr_is_lcd(channel)) { 2677 if (dispc_mgr_is_lcd(channel)) {
2678 _dispc_mgr_set_lcd_timings(channel, timings->hsw, timings->hfp, 2678 _dispc_mgr_set_lcd_timings(channel, t.hsw, t.hfp, t.hbp, t.vsw,
2679 timings->hbp, timings->vsw, timings->vfp, 2679 t.vfp, t.vbp);
2680 timings->vbp);
2681 2680
2682 xtot = timings->x_res + timings->hfp + timings->hsw + 2681 xtot = t.x_res + t.hfp + t.hsw + t.hbp;
2683 timings->hbp; 2682 ytot = t.y_res + t.vfp + t.vsw + t.vbp;
2684 ytot = timings->y_res + timings->vfp + timings->vsw +
2685 timings->vbp;
2686 2683
2687 ht = (timings->pixel_clock * 1000) / xtot; 2684 ht = (timings->pixel_clock * 1000) / xtot;
2688 vt = (timings->pixel_clock * 1000) / xtot / ytot; 2685 vt = (timings->pixel_clock * 1000) / xtot / ytot;
2689 2686
2690 DSSDBG("pck %u\n", timings->pixel_clock); 2687 DSSDBG("pck %u\n", timings->pixel_clock);
2691 DSSDBG("hsw %d hfp %d hbp %d vsw %d vfp %d vbp %d\n", 2688 DSSDBG("hsw %d hfp %d hbp %d vsw %d vfp %d vbp %d\n",
2692 timings->hsw, timings->hfp, timings->hbp, 2689 t.hsw, t.hfp, t.hbp, t.vsw, t.vfp, t.vbp);
2693 timings->vsw, timings->vfp, timings->vbp);
2694 2690
2695 DSSDBG("hsync %luHz, vsync %luHz\n", ht, vt); 2691 DSSDBG("hsync %luHz, vsync %luHz\n", ht, vt);
2692 } else {
2693 enum dss_hdmi_venc_clk_source_select source;
2694
2695 source = dss_get_hdmi_venc_clk_source();
2696
2697 if (source == DSS_VENC_TV_CLK)
2698 t.y_res /= 2;
2696 } 2699 }
2697 2700
2698 dispc_mgr_set_size(channel, timings->x_res, timings->y_res); 2701 dispc_mgr_set_size(channel, t.x_res, t.y_res);
2699} 2702}
2700 2703
2701static void dispc_mgr_set_lcd_divisor(enum omap_channel channel, u16 lck_div, 2704static void dispc_mgr_set_lcd_divisor(enum omap_channel channel, u16 lck_div,
diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c
index 1dbf1550773e..09be43d02adf 100644
--- a/drivers/video/omap2/dss/venc.c
+++ b/drivers/video/omap2/dss/venc.c
@@ -422,7 +422,6 @@ static int venc_power_on(struct omap_dss_device *dssdev)
422{ 422{
423 u32 l; 423 u32 l;
424 int r; 424 int r;
425 struct omap_video_timings timings;
426 425
427 venc_reset(); 426 venc_reset();
428 venc_write_config(venc_timings_to_config(&dssdev->panel.timings)); 427 venc_write_config(venc_timings_to_config(&dssdev->panel.timings));
@@ -442,10 +441,7 @@ static int venc_power_on(struct omap_dss_device *dssdev)
442 441
443 venc_write_reg(VENC_OUTPUT_CONTROL, l); 442 venc_write_reg(VENC_OUTPUT_CONTROL, l);
444 443
445 timings = dssdev->panel.timings; 444 dss_mgr_set_timings(dssdev->manager, &dssdev->panel.timings);
446 timings.y_res /= 2;
447
448 dss_mgr_set_timings(dssdev->manager, &timings);
449 445
450 r = regulator_enable(venc.vdda_dac_reg); 446 r = regulator_enable(venc.vdda_dac_reg);
451 if (r) 447 if (r)