aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/omap2/dss/dispc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video/omap2/dss/dispc.c')
-rw-r--r--drivers/video/omap2/dss/dispc.c51
1 files changed, 23 insertions, 28 deletions
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)
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