diff options
Diffstat (limited to 'recipes/linux/linux-omap-2.6.29/dss2/0019-DSS2-Check-fclk-limits-when-configuring-video-plane.patch')
-rw-r--r-- | recipes/linux/linux-omap-2.6.29/dss2/0019-DSS2-Check-fclk-limits-when-configuring-video-plane.patch | 183 |
1 files changed, 183 insertions, 0 deletions
diff --git a/recipes/linux/linux-omap-2.6.29/dss2/0019-DSS2-Check-fclk-limits-when-configuring-video-plane.patch b/recipes/linux/linux-omap-2.6.29/dss2/0019-DSS2-Check-fclk-limits-when-configuring-video-plane.patch new file mode 100644 index 0000000000..daa95ca50d --- /dev/null +++ b/recipes/linux/linux-omap-2.6.29/dss2/0019-DSS2-Check-fclk-limits-when-configuring-video-plane.patch @@ -0,0 +1,183 @@ +From 67f3fc050ab4e2006d5b7ec6ec341896627181ab Mon Sep 17 00:00:00 2001 +From: =?utf-8?q?Ville=20Syrj=C3=A4l=C3=A4?= <ville.syrjala@nokia.com> +Date: Mon, 6 Apr 2009 17:32:04 +0200 +Subject: [PATCH] DSS2: Check fclk limits when configuring video planes +MIME-Version: 1.0 +Content-Type: text/plain; charset=utf-8 +Content-Transfer-Encoding: 8bit + +Check that the currect functional clock is fast enough to support +the requested scaling ratios. Also check if 5-tap filtering can be +used even though the downscaling ratio is less than 1:2 since the +functional clock rate required for 5-tap filtering can be less than +the requirement for 3-tap filtering, and 5-tap filtering should look +better. + +Signed-off-by: Ville Syrjälä <ville.syrjala@nokia.com> +--- + drivers/video/omap2/dss/dispc.c | 104 ++++++++++++++++++++++++++++++++++++--- + 1 files changed, 97 insertions(+), 7 deletions(-) + +diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c +index 41734f3..61861d8 100644 +--- a/drivers/video/omap2/dss/dispc.c ++++ b/drivers/video/omap2/dss/dispc.c +@@ -1026,11 +1026,11 @@ static void _dispc_set_vid_accu1(enum omap_plane plane, int haccu, int vaccu) + static void _dispc_set_scaling(enum omap_plane plane, + u16 orig_width, u16 orig_height, + u16 out_width, u16 out_height, +- bool ilace) ++ bool ilace, bool five_taps) + { + int fir_hinc; + int fir_vinc; +- int hscaleup, vscaleup, five_taps; ++ int hscaleup, vscaleup; + int fieldmode = 0; + int accu0 = 0; + int accu1 = 0; +@@ -1040,7 +1040,6 @@ static void _dispc_set_scaling(enum omap_plane plane, + + hscaleup = orig_width <= out_width; + vscaleup = orig_height <= out_height; +- five_taps = orig_height > out_height * 2; + + _dispc_set_scale_coef(plane, hscaleup, vscaleup, five_taps); + +@@ -1283,6 +1282,73 @@ static void calc_rotation_offset(u8 rotation, bool mirror, + } + } + ++static unsigned long calc_fclk_five_taps(u16 width, u16 height, ++ u16 out_width, u16 out_height, enum omap_color_mode color_mode) ++{ ++ u32 fclk = 0; ++ /* FIXME venc pclk? */ ++ u64 tmp, pclk = dispc_pclk_rate(); ++ ++ if (height > out_height) { ++ /* FIXME get real display PPL */ ++ unsigned int ppl = 800; ++ ++ tmp = pclk * height * out_width; ++ do_div(tmp, 2 * out_height * ppl); ++ fclk = tmp; ++ ++ if (height > 2 * out_height) { ++ tmp = pclk * (height - 2 * out_height) * out_width; ++ do_div(tmp, 2 * out_height * (ppl - out_width)); ++ fclk = max(fclk, (u32) tmp); ++ } ++ } ++ ++ if (width > out_width) { ++ tmp = pclk * width; ++ do_div(tmp, out_width); ++ fclk = max(fclk, (u32) tmp); ++ ++ if (color_mode == OMAP_DSS_COLOR_RGB24U) ++ fclk <<= 1; ++ } ++ ++ return fclk; ++} ++ ++static unsigned long calc_fclk(u16 width, u16 height, ++ u16 out_width, u16 out_height, ++ enum omap_color_mode color_mode, bool five_taps) ++{ ++ unsigned int hf, vf; ++ ++ if (five_taps) ++ return calc_fclk_five_taps(width, height, ++ out_width, out_height, color_mode); ++ ++ /* ++ * FIXME how to determine the 'A' factor ++ * for the no downscaling case ? ++ */ ++ ++ if (width > 3 * out_width) ++ hf = 4; ++ else if (width > 2 * out_width) ++ hf = 3; ++ else if (width > out_width) ++ hf = 2; ++ else ++ hf = 1; ++ ++ if (height > out_height) ++ vf = 2; ++ else ++ vf = 1; ++ ++ /* FIXME venc pclk? */ ++ return dispc_pclk_rate() * vf * hf; ++} ++ + static int _dispc_setup_plane(enum omap_plane plane, + enum omap_channel channel_out, + u32 paddr, u16 screen_width, +@@ -1294,7 +1360,7 @@ static int _dispc_setup_plane(enum omap_plane plane, + u8 rotation, int mirror) + { + const int maxdownscale = cpu_is_omap34xx() ? 4 : 2; +- bool five_taps = height > out_height * 2; ++ bool five_taps = 0; + bool fieldmode = 0; + int cconv = 0; + unsigned offset0, offset1; +@@ -1323,8 +1389,8 @@ static int _dispc_setup_plane(enum omap_plane plane, + } + } else { + /* video plane */ +- if (width > (2048 >> five_taps)) +- return -EINVAL; ++ ++ unsigned long fclk; + + if (out_width < width / maxdownscale || + out_width > width * 8) +@@ -1356,6 +1422,30 @@ static int _dispc_setup_plane(enum omap_plane plane, + default: + return -EINVAL; + } ++ ++ /* Must use 5-tap filter? */ ++ five_taps = height > out_height * 2; ++ ++ /* Try to use 5-tap filter whenever possible. */ ++ if (cpu_is_omap34xx() && !five_taps && ++ height > out_height && width <= 1024) { ++ fclk = calc_fclk_five_taps(width, height, ++ out_width, out_height, color_mode); ++ if (fclk <= dispc_fclk_rate()) ++ five_taps = true; ++ } ++ ++ if (width > (2048 >> five_taps)) ++ return -EINVAL; ++ ++ fclk = calc_fclk(width, height, out_width, out_height, ++ color_mode, five_taps); ++ ++ DSSDBG("required fclk rate = %lu Hz\n", fclk); ++ DSSDBG("current fclk rate = %lu Hz\n", dispc_fclk_rate()); ++ ++ if (fclk > dispc_fclk_rate()) ++ return -EINVAL; + } + + if (ilace && height >= out_height) +@@ -1399,7 +1489,7 @@ static int _dispc_setup_plane(enum omap_plane plane, + if (plane != OMAP_DSS_GFX) { + _dispc_set_scaling(plane, width, height, + out_width, out_height, +- ilace); ++ ilace, five_taps); + _dispc_set_vid_size(plane, out_width, out_height); + _dispc_set_vid_color_conv(plane, cconv); + } +-- +1.5.6.5 + |