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.c66
1 files changed, 46 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;