aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/video/omap2/dss/dispc.c66
-rw-r--r--drivers/video/omap2/dss/dss_features.c7
-rw-r--r--drivers/video/omap2/dss/dss_features.h1
3 files changed, 54 insertions, 20 deletions
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index 78e51d953629..a5ec7f37c185 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -1614,6 +1614,9 @@ static unsigned long calc_fclk_five_taps(enum omap_channel channel, u16 width,
1614 u32 fclk = 0; 1614 u32 fclk = 0;
1615 u64 tmp, pclk = dispc_mgr_pclk_rate(channel); 1615 u64 tmp, pclk = dispc_mgr_pclk_rate(channel);
1616 1616
1617 if (height <= out_height && width <= out_width)
1618 return (unsigned long) pclk;
1619
1617 if (height > out_height) { 1620 if (height > out_height) {
1618 struct omap_dss_device *dssdev = dispc_mgr_get_device(channel); 1621 struct omap_dss_device *dssdev = dispc_mgr_get_device(channel);
1619 unsigned int ppl = dssdev->panel.timings.x_res; 1622 unsigned int ppl = dssdev->panel.timings.x_res;
@@ -1668,7 +1671,16 @@ static unsigned long calc_fclk(enum omap_channel channel, u16 width,
1668 else 1671 else
1669 vf = 1; 1672 vf = 1;
1670 1673
1671 return dispc_mgr_pclk_rate(channel) * vf * hf; 1674 if (cpu_is_omap24xx()) {
1675 if (vf > 1 && hf > 1)
1676 return dispc_mgr_pclk_rate(channel) * 4;
1677 else
1678 return dispc_mgr_pclk_rate(channel) * 2;
1679 } else if (cpu_is_omap34xx()) {
1680 return dispc_mgr_pclk_rate(channel) * vf * hf;
1681 } else {
1682 return dispc_mgr_pclk_rate(channel) * hf;
1683 }
1672} 1684}
1673 1685
1674static int dispc_ovl_calc_scaling(enum omap_plane plane, 1686static int dispc_ovl_calc_scaling(enum omap_plane plane,
@@ -1678,6 +1690,8 @@ static int dispc_ovl_calc_scaling(enum omap_plane plane,
1678{ 1690{
1679 struct omap_overlay *ovl = omap_dss_get_overlay(plane); 1691 struct omap_overlay *ovl = omap_dss_get_overlay(plane);
1680 const int maxdownscale = dss_feat_get_param_max(FEAT_PARAM_DOWNSCALE); 1692 const int maxdownscale = dss_feat_get_param_max(FEAT_PARAM_DOWNSCALE);
1693 const int maxsinglelinewidth =
1694 dss_feat_get_param_max(FEAT_PARAM_LINEWIDTH);
1681 unsigned long fclk = 0; 1695 unsigned long fclk = 0;
1682 1696
1683 if (width == out_width && height == out_height) 1697 if (width == out_width && height == out_height)
@@ -1694,28 +1708,40 @@ static int dispc_ovl_calc_scaling(enum omap_plane plane,
1694 out_height > height * 8) 1708 out_height > height * 8)
1695 return -EINVAL; 1709 return -EINVAL;
1696 1710
1697 /* Must use 5-tap filter? */ 1711 if (cpu_is_omap24xx()) {
1698 *five_taps = height > out_height * 2; 1712 if (width > maxsinglelinewidth)
1699 1713 DSSERR("Cannot scale max input width exceeded");
1700 if (!*five_taps) { 1714 *five_taps = false;
1715 fclk = calc_fclk(channel, width, height, out_width,
1716 out_height);
1717 } else if (cpu_is_omap34xx()) {
1718 if (width > (maxsinglelinewidth * 2)) {
1719 DSSERR("Cannot setup scaling");
1720 DSSERR("width exceeds maximum width possible");
1721 return -EINVAL;
1722 }
1723 fclk = calc_fclk_five_taps(channel, width, height, out_width,
1724 out_height, color_mode);
1725 if (width > maxsinglelinewidth) {
1726 if (height > out_height && height < out_height * 2)
1727 *five_taps = false;
1728 else {
1729 DSSERR("cannot setup scaling with five taps");
1730 return -EINVAL;
1731 }
1732 }
1733 if (!*five_taps)
1734 fclk = calc_fclk(channel, width, height, out_width,
1735 out_height);
1736 } else {
1737 if (width > maxsinglelinewidth) {
1738 DSSERR("Cannot scale width exceeds max line width");
1739 return -EINVAL;
1740 }
1701 fclk = calc_fclk(channel, width, height, out_width, 1741 fclk = calc_fclk(channel, width, height, out_width,
1702 out_height); 1742 out_height);
1703
1704 /* Try 5-tap filter if 3-tap fclk is too high */
1705 if (cpu_is_omap34xx() && height > out_height &&
1706 fclk > dispc_fclk_rate())
1707 *five_taps = true;
1708 } 1743 }
1709 1744
1710 if (width > (2048 >> *five_taps)) {
1711 DSSERR("failed to set up scaling, fclk too low\n");
1712 return -EINVAL;
1713 }
1714
1715 if (*five_taps)
1716 fclk = calc_fclk_five_taps(channel, width, height,
1717 out_width, out_height, color_mode);
1718
1719 DSSDBG("required fclk rate = %lu Hz\n", fclk); 1745 DSSDBG("required fclk rate = %lu Hz\n", fclk);
1720 DSSDBG("current fclk rate = %lu Hz\n", dispc_fclk_rate()); 1746 DSSDBG("current fclk rate = %lu Hz\n", dispc_fclk_rate());
1721 1747
@@ -1734,7 +1760,7 @@ int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi,
1734 bool ilace, bool replication) 1760 bool ilace, bool replication)
1735{ 1761{
1736 struct omap_overlay *ovl = omap_dss_get_overlay(plane); 1762 struct omap_overlay *ovl = omap_dss_get_overlay(plane);
1737 bool five_taps = false; 1763 bool five_taps = true;
1738 bool fieldmode = 0; 1764 bool fieldmode = 0;
1739 int r, cconv = 0; 1765 int r, cconv = 0;
1740 unsigned offset0, offset1; 1766 unsigned offset0, offset1;
diff --git a/drivers/video/omap2/dss/dss_features.c b/drivers/video/omap2/dss/dss_features.c
index b402699168a5..5e4b829605da 100644
--- a/drivers/video/omap2/dss/dss_features.c
+++ b/drivers/video/omap2/dss/dss_features.c
@@ -304,6 +304,11 @@ static const struct dss_param_range omap2_dss_param_range[] = {
304 [FEAT_PARAM_DSIPLL_FINT] = { 0, 0 }, 304 [FEAT_PARAM_DSIPLL_FINT] = { 0, 0 },
305 [FEAT_PARAM_DSIPLL_LPDIV] = { 0, 0 }, 305 [FEAT_PARAM_DSIPLL_LPDIV] = { 0, 0 },
306 [FEAT_PARAM_DOWNSCALE] = { 1, 2 }, 306 [FEAT_PARAM_DOWNSCALE] = { 1, 2 },
307 /*
308 * Assuming the line width buffer to be 768 pixels as OMAP2 DISPC
309 * scaler cannot scale a image with width more than 768.
310 */
311 [FEAT_PARAM_LINEWIDTH] = { 1, 768 },
307}; 312};
308 313
309static const struct dss_param_range omap3_dss_param_range[] = { 314static const struct dss_param_range omap3_dss_param_range[] = {
@@ -316,6 +321,7 @@ static const struct dss_param_range omap3_dss_param_range[] = {
316 [FEAT_PARAM_DSIPLL_FINT] = { 750000, 2100000 }, 321 [FEAT_PARAM_DSIPLL_FINT] = { 750000, 2100000 },
317 [FEAT_PARAM_DSIPLL_LPDIV] = { 1, (1 << 13) - 1}, 322 [FEAT_PARAM_DSIPLL_LPDIV] = { 1, (1 << 13) - 1},
318 [FEAT_PARAM_DOWNSCALE] = { 1, 4 }, 323 [FEAT_PARAM_DOWNSCALE] = { 1, 4 },
324 [FEAT_PARAM_LINEWIDTH] = { 1, 1024 },
319}; 325};
320 326
321static const struct dss_param_range omap4_dss_param_range[] = { 327static const struct dss_param_range omap4_dss_param_range[] = {
@@ -328,6 +334,7 @@ static const struct dss_param_range omap4_dss_param_range[] = {
328 [FEAT_PARAM_DSIPLL_FINT] = { 500000, 2500000 }, 334 [FEAT_PARAM_DSIPLL_FINT] = { 500000, 2500000 },
329 [FEAT_PARAM_DSIPLL_LPDIV] = { 0, (1 << 13) - 1 }, 335 [FEAT_PARAM_DSIPLL_LPDIV] = { 0, (1 << 13) - 1 },
330 [FEAT_PARAM_DOWNSCALE] = { 1, 4 }, 336 [FEAT_PARAM_DOWNSCALE] = { 1, 4 },
337 [FEAT_PARAM_LINEWIDTH] = { 1, 2048 },
331}; 338};
332 339
333/* OMAP2 DSS Features */ 340/* OMAP2 DSS Features */
diff --git a/drivers/video/omap2/dss/dss_features.h b/drivers/video/omap2/dss/dss_features.h
index 6a6c05dd45ce..cd833bbaac3d 100644
--- a/drivers/video/omap2/dss/dss_features.h
+++ b/drivers/video/omap2/dss/dss_features.h
@@ -86,6 +86,7 @@ enum dss_range_param {
86 FEAT_PARAM_DSIPLL_FINT, 86 FEAT_PARAM_DSIPLL_FINT,
87 FEAT_PARAM_DSIPLL_LPDIV, 87 FEAT_PARAM_DSIPLL_LPDIV,
88 FEAT_PARAM_DOWNSCALE, 88 FEAT_PARAM_DOWNSCALE,
89 FEAT_PARAM_LINEWIDTH,
89}; 90};
90 91
91/* DSS Feature Functions */ 92/* DSS Feature Functions */