diff options
author | Chandrabhanu Mahapatra <cmahapatra@ti.com> | 2012-04-23 02:46:50 -0400 |
---|---|---|
committer | Tomi Valkeinen <tomi.valkeinen@ti.com> | 2012-05-03 09:13:01 -0400 |
commit | 8b53d9911982794b3f6d5513741495c3f70962cd (patch) | |
tree | 2932bf95e14f4d890704983918d19e4a482593f7 | |
parent | 7faa92339bbb1e6b9a80983b206642517327eb75 (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.c | 67 | ||||
-rw-r--r-- | drivers/video/omap2/dss/dss.h | 1 |
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 | ||
1717 | static unsigned long calc_fclk_five_taps(enum omap_channel channel, u16 width, | 1717 | static 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 | ||
1757 | static unsigned long calc_fclk(enum omap_channel channel, u16 width, | 1757 | static 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 | ||
2660 | unsigned 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 | |||
2660 | void dispc_dump_clocks(struct seq_file *s) | 2673 | void 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); |
449 | unsigned long dispc_mgr_lclk_rate(enum omap_channel channel); | 449 | unsigned long dispc_mgr_lclk_rate(enum omap_channel channel); |
450 | unsigned long dispc_mgr_pclk_rate(enum omap_channel channel); | 450 | unsigned long dispc_mgr_pclk_rate(enum omap_channel channel); |
451 | unsigned long dispc_core_clk_rate(void); | ||
451 | int dispc_mgr_set_clock_div(enum omap_channel channel, | 452 | int dispc_mgr_set_clock_div(enum omap_channel channel, |
452 | struct dispc_clock_info *cinfo); | 453 | struct dispc_clock_info *cinfo); |
453 | int dispc_mgr_get_clock_div(enum omap_channel channel, | 454 | int dispc_mgr_get_clock_div(enum omap_channel channel, |