aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChandrabhanu Mahapatra <cmahapatra@ti.com>2012-04-23 02:46:50 -0400
committerTomi Valkeinen <tomi.valkeinen@ti.com>2012-05-03 09:13:01 -0400
commit8b53d9911982794b3f6d5513741495c3f70962cd (patch)
tree2932bf95e14f4d890704983918d19e4a482593f7
parent7faa92339bbb1e6b9a80983b206642517327eb75 (diff)
OMAPDSS: DISPC: Correct DISPC functional clock usage
DISPC_FCLK is incorrectly used as functional clock of DISPC in scaling calculations. So, DISPC_CORE_CLK replaces as functional clock of DISPC. DISPC_CORE_CLK is derived from DISPC_FCLK divided by an independent DISPC divisor LCD. Signed-off-by: Chandrabhanu Mahapatra <cmahapatra@ti.com> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
-rw-r--r--drivers/video/omap2/dss/dispc.c67
-rw-r--r--drivers/video/omap2/dss/dss.h1
2 files changed, 41 insertions, 27 deletions
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index bea37bbd0e3e..49015b8a9e4a 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -1714,11 +1714,11 @@ static int check_horiz_timing_omap3(enum omap_channel channel, u16 pos_x,
1714 return 0; 1714 return 0;
1715} 1715}
1716 1716
1717static unsigned long calc_fclk_five_taps(enum omap_channel channel, u16 width, 1717static unsigned long calc_core_clk_five_taps(enum omap_channel channel,
1718 u16 height, u16 out_width, u16 out_height, 1718 u16 width, u16 height, u16 out_width, u16 out_height,
1719 enum omap_color_mode color_mode) 1719 enum omap_color_mode color_mode)
1720{ 1720{
1721 u32 fclk = 0; 1721 u32 core_clk = 0;
1722 u64 tmp, pclk = dispc_mgr_pclk_rate(channel); 1722 u64 tmp, pclk = dispc_mgr_pclk_rate(channel);
1723 1723
1724 if (height <= out_height && width <= out_width) 1724 if (height <= out_height && width <= out_width)
@@ -1730,7 +1730,7 @@ static unsigned long calc_fclk_five_taps(enum omap_channel channel, u16 width,
1730 1730
1731 tmp = pclk * height * out_width; 1731 tmp = pclk * height * out_width;
1732 do_div(tmp, 2 * out_height * ppl); 1732 do_div(tmp, 2 * out_height * ppl);
1733 fclk = tmp; 1733 core_clk = tmp;
1734 1734
1735 if (height > 2 * out_height) { 1735 if (height > 2 * out_height) {
1736 if (ppl == out_width) 1736 if (ppl == out_width)
@@ -1738,23 +1738,23 @@ static unsigned long calc_fclk_five_taps(enum omap_channel channel, u16 width,
1738 1738
1739 tmp = pclk * (height - 2 * out_height) * out_width; 1739 tmp = pclk * (height - 2 * out_height) * out_width;
1740 do_div(tmp, 2 * out_height * (ppl - out_width)); 1740 do_div(tmp, 2 * out_height * (ppl - out_width));
1741 fclk = max(fclk, (u32) tmp); 1741 core_clk = max_t(u32, core_clk, tmp);
1742 } 1742 }
1743 } 1743 }
1744 1744
1745 if (width > out_width) { 1745 if (width > out_width) {
1746 tmp = pclk * width; 1746 tmp = pclk * width;
1747 do_div(tmp, out_width); 1747 do_div(tmp, out_width);
1748 fclk = max(fclk, (u32) tmp); 1748 core_clk = max_t(u32, core_clk, tmp);
1749 1749
1750 if (color_mode == OMAP_DSS_COLOR_RGB24U) 1750 if (color_mode == OMAP_DSS_COLOR_RGB24U)
1751 fclk <<= 1; 1751 core_clk <<= 1;
1752 } 1752 }
1753 1753
1754 return fclk; 1754 return core_clk;
1755} 1755}
1756 1756
1757static unsigned long calc_fclk(enum omap_channel channel, u16 width, 1757static unsigned long calc_core_clk(enum omap_channel channel, u16 width,
1758 u16 height, u16 out_width, u16 out_height) 1758 u16 height, u16 out_width, u16 out_height)
1759{ 1759{
1760 unsigned int hf, vf; 1760 unsigned int hf, vf;
@@ -1805,7 +1805,7 @@ static int dispc_ovl_calc_scaling(enum omap_plane plane,
1805 const int maxsinglelinewidth = 1805 const int maxsinglelinewidth =
1806 dss_feat_get_param_max(FEAT_PARAM_LINEWIDTH); 1806 dss_feat_get_param_max(FEAT_PARAM_LINEWIDTH);
1807 const int max_decim_limit = 16; 1807 const int max_decim_limit = 16;
1808 unsigned long fclk = 0; 1808 unsigned long core_clk = 0;
1809 int decim_x, decim_y, error, min_factor; 1809 int decim_x, decim_y, error, min_factor;
1810 u16 in_width, in_height, in_width_max = 0; 1810 u16 in_width, in_height, in_width_max = 0;
1811 1811
@@ -1845,10 +1845,10 @@ static int dispc_ovl_calc_scaling(enum omap_plane plane,
1845 do { 1845 do {
1846 in_height = DIV_ROUND_UP(height, decim_y); 1846 in_height = DIV_ROUND_UP(height, decim_y);
1847 in_width = DIV_ROUND_UP(width, decim_x); 1847 in_width = DIV_ROUND_UP(width, decim_x);
1848 fclk = calc_fclk(channel, in_width, in_height, 1848 core_clk = calc_core_clk(channel, in_width, in_height,
1849 out_width, out_height); 1849 out_width, out_height);
1850 error = (in_width > maxsinglelinewidth || !fclk || 1850 error = (in_width > maxsinglelinewidth || !core_clk ||
1851 fclk > dispc_fclk_rate()); 1851 core_clk > dispc_core_clk_rate());
1852 if (error) { 1852 if (error) {
1853 if (decim_x == decim_y) { 1853 if (decim_x == decim_y) {
1854 decim_x = min_factor; 1854 decim_x = min_factor;
@@ -1871,8 +1871,8 @@ static int dispc_ovl_calc_scaling(enum omap_plane plane,
1871 do { 1871 do {
1872 in_height = DIV_ROUND_UP(height, decim_y); 1872 in_height = DIV_ROUND_UP(height, decim_y);
1873 in_width = DIV_ROUND_UP(width, decim_x); 1873 in_width = DIV_ROUND_UP(width, decim_x);
1874 fclk = calc_fclk_five_taps(channel, in_width, in_height, 1874 core_clk = calc_core_clk_five_taps(channel, in_width,
1875 out_width, out_height, color_mode); 1875 in_height, out_width, out_height, color_mode);
1876 1876
1877 error = check_horiz_timing_omap3(channel, pos_x, 1877 error = check_horiz_timing_omap3(channel, pos_x,
1878 in_width, in_height, out_width, out_height); 1878 in_width, in_height, out_width, out_height);
@@ -1882,11 +1882,11 @@ static int dispc_ovl_calc_scaling(enum omap_plane plane,
1882 in_height < out_height * 2) 1882 in_height < out_height * 2)
1883 *five_taps = false; 1883 *five_taps = false;
1884 if (!*five_taps) 1884 if (!*five_taps)
1885 fclk = calc_fclk(channel, in_width, in_height, 1885 core_clk = calc_core_clk(channel, in_width,
1886 out_width, out_height); 1886 in_height, out_width, out_height);
1887 error = (error || in_width > maxsinglelinewidth * 2 || 1887 error = (error || in_width > maxsinglelinewidth * 2 ||
1888 (in_width > maxsinglelinewidth && *five_taps) || 1888 (in_width > maxsinglelinewidth && *five_taps) ||
1889 !fclk || fclk > dispc_fclk_rate()); 1889 !core_clk || core_clk > dispc_core_clk_rate());
1890 if (error) { 1890 if (error) {
1891 if (decim_x == decim_y) { 1891 if (decim_x == decim_y) {
1892 decim_x = min_factor; 1892 decim_x = min_factor;
@@ -1919,7 +1919,7 @@ static int dispc_ovl_calc_scaling(enum omap_plane plane,
1919 } else { 1919 } else {
1920 int decim_x_min = decim_x; 1920 int decim_x_min = decim_x;
1921 in_height = DIV_ROUND_UP(height, decim_y); 1921 in_height = DIV_ROUND_UP(height, decim_y);
1922 in_width_max = dispc_fclk_rate() / 1922 in_width_max = dispc_core_clk_rate() /
1923 DIV_ROUND_UP(dispc_mgr_pclk_rate(channel), 1923 DIV_ROUND_UP(dispc_mgr_pclk_rate(channel),
1924 out_width); 1924 out_width);
1925 decim_x = DIV_ROUND_UP(width, in_width_max); 1925 decim_x = DIV_ROUND_UP(width, in_width_max);
@@ -1938,18 +1938,18 @@ static int dispc_ovl_calc_scaling(enum omap_plane plane,
1938 return -EINVAL; 1938 return -EINVAL;
1939 } 1939 }
1940 1940
1941 fclk = calc_fclk(channel, in_width, in_height, out_width, 1941 core_clk = calc_core_clk(channel, in_width, in_height,
1942 out_height); 1942 out_width, out_height);
1943 } 1943 }
1944 1944
1945 DSSDBG("required fclk rate = %lu Hz\n", fclk); 1945 DSSDBG("required core clk rate = %lu Hz\n", core_clk);
1946 DSSDBG("current fclk rate = %lu Hz\n", dispc_fclk_rate()); 1946 DSSDBG("current core clk rate = %lu Hz\n", dispc_core_clk_rate());
1947 1947
1948 if (!fclk || fclk > dispc_fclk_rate()) { 1948 if (!core_clk || core_clk > dispc_core_clk_rate()) {
1949 DSSERR("failed to set up scaling, " 1949 DSSERR("failed to set up scaling, "
1950 "required fclk rate = %lu Hz, " 1950 "required core clk rate = %lu Hz, "
1951 "current fclk rate = %lu Hz\n", 1951 "current core clk rate = %lu Hz\n",
1952 fclk, dispc_fclk_rate()); 1952 core_clk, dispc_core_clk_rate());
1953 return -EINVAL; 1953 return -EINVAL;
1954 } 1954 }
1955 1955
@@ -2657,6 +2657,19 @@ unsigned long dispc_mgr_pclk_rate(enum omap_channel channel)
2657 } 2657 }
2658} 2658}
2659 2659
2660unsigned long dispc_core_clk_rate(void)
2661{
2662 int lcd;
2663 unsigned long fclk = dispc_fclk_rate();
2664
2665 if (dss_has_feature(FEAT_CORE_CLK_DIV))
2666 lcd = REG_GET(DISPC_DIVISOR, 23, 16);
2667 else
2668 lcd = REG_GET(DISPC_DIVISORo(OMAP_DSS_CHANNEL_LCD), 23, 16);
2669
2670 return fclk / lcd;
2671}
2672
2660void dispc_dump_clocks(struct seq_file *s) 2673void dispc_dump_clocks(struct seq_file *s)
2661{ 2674{
2662 int lcd, pcd; 2675 int lcd, pcd;
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index 1dc336b8bb69..5ca67f111d09 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -448,6 +448,7 @@ void dispc_mgr_set_pol_freq(enum omap_channel channel,
448 enum omap_panel_config config, u8 acbi, u8 acb); 448 enum omap_panel_config config, u8 acbi, u8 acb);
449unsigned long dispc_mgr_lclk_rate(enum omap_channel channel); 449unsigned long dispc_mgr_lclk_rate(enum omap_channel channel);
450unsigned long dispc_mgr_pclk_rate(enum omap_channel channel); 450unsigned long dispc_mgr_pclk_rate(enum omap_channel channel);
451unsigned long dispc_core_clk_rate(void);
451int dispc_mgr_set_clock_div(enum omap_channel channel, 452int dispc_mgr_set_clock_div(enum omap_channel channel,
452 struct dispc_clock_info *cinfo); 453 struct dispc_clock_info *cinfo);
453int dispc_mgr_get_clock_div(enum omap_channel channel, 454int dispc_mgr_get_clock_div(enum omap_channel channel,