From 8eeb7019a4d1e5402b4bd5371562fe93dc1ed3dc Mon Sep 17 00:00:00 2001 From: Archit Taneja Date: Wed, 22 Aug 2012 12:33:49 +0530 Subject: OMAPDSS: DISPC: Constify omap_overlay_info in dispc_ovl_setup() The struct omap_overlay_info passed to dispc_ovl_setup() is used to configure DISPC registers. It shouldn't modify the overlay_info structure. The pos_y field was being changed in dispc_ovl_setup in the case of interlaced displays. Fix this and const qualifier to the omap_overlay_info argument. Signed-off-by: Archit Taneja --- drivers/video/omap2/dss/dispc.c | 9 +++++---- drivers/video/omap2/dss/dss.h | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) (limited to 'drivers/video/omap2') diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c index 811fe381aaea..35d388b6aec1 100644 --- a/drivers/video/omap2/dss/dispc.c +++ b/drivers/video/omap2/dss/dispc.c @@ -2255,7 +2255,7 @@ static int dispc_ovl_calc_scaling(enum omap_plane plane, return 0; } -int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi, +int dispc_ovl_setup(enum omap_plane plane, const struct omap_overlay_info *oi, bool replication, const struct omap_video_timings *mgr_timings) { struct omap_overlay *ovl = omap_dss_get_overlay(plane); @@ -2273,6 +2273,7 @@ int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi, enum omap_channel channel; int x_predecim = 1, y_predecim = 1; bool ilace = mgr_timings->interlace; + u16 pos_y = oi->pos_y; channel = dispc_ovl_get_channel_out(plane); @@ -2295,12 +2296,12 @@ int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi, if (ilace) { if (fieldmode) in_height /= 2; - oi->pos_y /= 2; + pos_y /= 2; out_height /= 2; DSSDBG("adjusting for ilace: height %d, pos_y %d, " "out_height %d\n", - in_height, oi->pos_y, out_height); + in_height, pos_y, out_height); } if (!dss_feat_color_mode_supported(plane, oi->color_mode)) @@ -2384,7 +2385,7 @@ int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi, DSSDBG("%d,%d %dx%d -> %dx%d\n", oi->pos_x, oi->pos_y, in_width, in_height, out_width, out_height); - dispc_ovl_set_pos(plane, oi->pos_x, oi->pos_y); + dispc_ovl_set_pos(plane, oi->pos_x, pos_y); dispc_ovl_set_pic_size(plane, in_width, in_height); diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h index a14528bcfeab..e71a6f16fc4d 100644 --- a/drivers/video/omap2/dss/dss.h +++ b/drivers/video/omap2/dss/dss.h @@ -444,7 +444,7 @@ void dispc_ovl_set_fifo_threshold(enum omap_plane plane, u32 low, u32 high); void dispc_ovl_compute_fifo_thresholds(enum omap_plane plane, u32 *fifo_low, u32 *fifo_high, bool use_fifomerge, bool manual_update); -int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi, +int dispc_ovl_setup(enum omap_plane plane, const struct omap_overlay_info *oi, bool replication, const struct omap_video_timings *mgr_timings); int dispc_ovl_enable(enum omap_plane plane, bool enable); void dispc_ovl_set_channel_out(enum omap_plane plane, -- cgit v1.2.3 From 78b687fc4ffa27d48c793f9669d53a6f4351e239 Mon Sep 17 00:00:00 2001 From: Archit Taneja Date: Fri, 21 Sep 2012 14:51:49 +0530 Subject: OMAPDSS: DISPC: Simplify function names for setting pipeline input and output sizes The DISPC pipeline register names in the TRM for setting the buffer size and the output size are a bit misleading, for example, there are different register names for setting the buffer size for VID and GFX pipes. Things get more confusing when considering writeback pipeline. Rename the functions so that they tell whether they are configuring the input to the scalar or the output. These will be extended later to support writeback registers. Signed-off-by: Archit Taneja --- drivers/video/omap2/dss/dispc.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'drivers/video/omap2') diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c index 35d388b6aec1..56e23040df08 100644 --- a/drivers/video/omap2/dss/dispc.c +++ b/drivers/video/omap2/dss/dispc.c @@ -705,7 +705,8 @@ static void dispc_ovl_set_pos(enum omap_plane plane, int x, int y) dispc_write_reg(DISPC_OVL_POSITION(plane), val); } -static void dispc_ovl_set_pic_size(enum omap_plane plane, int width, int height) +static void dispc_ovl_set_input_size(enum omap_plane plane, int width, + int height) { u32 val = FLD_VAL(height - 1, 26, 16) | FLD_VAL(width - 1, 10, 0); @@ -715,7 +716,8 @@ static void dispc_ovl_set_pic_size(enum omap_plane plane, int width, int height) dispc_write_reg(DISPC_OVL_PICTURE_SIZE(plane), val); } -static void dispc_ovl_set_vid_size(enum omap_plane plane, int width, int height) +static void dispc_ovl_set_output_size(enum omap_plane plane, int width, + int height) { u32 val; @@ -2387,13 +2389,14 @@ int dispc_ovl_setup(enum omap_plane plane, const struct omap_overlay_info *oi, dispc_ovl_set_pos(plane, oi->pos_x, pos_y); - dispc_ovl_set_pic_size(plane, in_width, in_height); + dispc_ovl_set_input_size(plane, in_width, in_height); if (ovl->caps & OMAP_DSS_OVL_CAP_SCALE) { dispc_ovl_set_scaling(plane, in_width, in_height, out_width, out_height, ilace, five_taps, fieldmode, oi->color_mode, oi->rotation); - dispc_ovl_set_vid_size(plane, out_width, out_height); + + dispc_ovl_set_output_size(plane, out_width, out_height); dispc_ovl_set_vid_color_conv(plane, cconv); } -- cgit v1.2.3 From 5b54ed3ec36ddc8ac25aff9233c7d3fb3e2b629a Mon Sep 17 00:00:00 2001 From: Archit Taneja Date: Wed, 26 Sep 2012 16:55:27 +0530 Subject: OMAPDSS: DISPC: Pass overlay caps as a parameter to dispc plane functions Currently, the functions below take the omap_plane parameter and derive the overlay caps within them. Pass the overlay caps as a parameter to the function to allow these to be used by writeback too. - dispc_ovl_set_zorder() - dispc_ovl_set_pre_mult_alpha() - dispc_ovl_setup_global_alpha() - dispc_ovl_calc_scaling() - dispc_ovl_setup() These functions will be used for writeback later, and the caps will help in deciding if they are to be used for writeback or not. This allows reuse of overlay caps for writeback. Using omap_overlay_caps for writeback seems a bit incorrect, but caps is something already in use by users of OMAPDSS(omapfb/omap_vout), so we use overlay caps for overlay like features of writeback too. Signed-off-by: Archit Taneja --- drivers/video/omap2/dss/dispc.c | 36 +++++++++++++++++------------------- 1 file changed, 17 insertions(+), 19 deletions(-) (limited to 'drivers/video/omap2') diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c index 56e23040df08..334842a3b527 100644 --- a/drivers/video/omap2/dss/dispc.c +++ b/drivers/video/omap2/dss/dispc.c @@ -728,11 +728,10 @@ static void dispc_ovl_set_output_size(enum omap_plane plane, int width, dispc_write_reg(DISPC_OVL_SIZE(plane), val); } -static void dispc_ovl_set_zorder(enum omap_plane plane, u8 zorder) +static void dispc_ovl_set_zorder(enum omap_plane plane, + enum omap_overlay_caps caps, u8 zorder) { - struct omap_overlay *ovl = omap_dss_get_overlay(plane); - - if ((ovl->caps & OMAP_DSS_OVL_CAP_ZORDER) == 0) + if ((caps & OMAP_DSS_OVL_CAP_ZORDER) == 0) return; REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), zorder, 27, 26); @@ -749,23 +748,22 @@ static void dispc_ovl_enable_zorder_planes(void) REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(i), 1, 25, 25); } -static void dispc_ovl_set_pre_mult_alpha(enum omap_plane plane, bool enable) +static void dispc_ovl_set_pre_mult_alpha(enum omap_plane plane, + enum omap_overlay_caps caps, bool enable) { - struct omap_overlay *ovl = omap_dss_get_overlay(plane); - - if ((ovl->caps & OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA) == 0) + if ((caps & OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA) == 0) return; REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), enable ? 1 : 0, 28, 28); } -static void dispc_ovl_setup_global_alpha(enum omap_plane plane, u8 global_alpha) +static void dispc_ovl_setup_global_alpha(enum omap_plane plane, + enum omap_overlay_caps caps, u8 global_alpha) { static const unsigned shifts[] = { 0, 8, 16, 24, }; int shift; - struct omap_overlay *ovl = omap_dss_get_overlay(plane); - if ((ovl->caps & OMAP_DSS_OVL_CAP_GLOBAL_ALPHA) == 0) + if ((caps & OMAP_DSS_OVL_CAP_GLOBAL_ALPHA) == 0) return; shift = shifts[plane]; @@ -2193,14 +2191,13 @@ static int dispc_ovl_calc_scaling_44xx(enum omap_channel channel, } static int dispc_ovl_calc_scaling(enum omap_plane plane, - enum omap_channel channel, + enum omap_overlay_caps caps, enum omap_channel channel, const struct omap_video_timings *mgr_timings, u16 width, u16 height, u16 out_width, u16 out_height, enum omap_color_mode color_mode, bool *five_taps, int *x_predecim, int *y_predecim, u16 pos_x, enum omap_dss_rotation_type rotation_type) { - struct omap_overlay *ovl = omap_dss_get_overlay(plane); const int maxdownscale = dss_feat_get_param_max(FEAT_PARAM_DOWNSCALE); const int max_decim_limit = 16; unsigned long core_clk = 0; @@ -2209,7 +2206,7 @@ static int dispc_ovl_calc_scaling(enum omap_plane plane, if (width == out_width && height == out_height) return 0; - if ((ovl->caps & OMAP_DSS_OVL_CAP_SCALE) == 0) + if ((caps & OMAP_DSS_OVL_CAP_SCALE) == 0) return -EINVAL; *x_predecim = max_decim_limit; @@ -2261,6 +2258,7 @@ int dispc_ovl_setup(enum omap_plane plane, const struct omap_overlay_info *oi, bool replication, const struct omap_video_timings *mgr_timings) { struct omap_overlay *ovl = omap_dss_get_overlay(plane); + enum omap_overlay_caps caps = ovl->caps; bool five_taps = true; bool fieldmode = 0; int r, cconv = 0; @@ -2309,7 +2307,7 @@ int dispc_ovl_setup(enum omap_plane plane, const struct omap_overlay_info *oi, if (!dss_feat_color_mode_supported(plane, oi->color_mode)) return -EINVAL; - r = dispc_ovl_calc_scaling(plane, channel, mgr_timings, in_width, + r = dispc_ovl_calc_scaling(plane, caps, channel, mgr_timings, in_width, in_height, out_width, out_height, oi->color_mode, &five_taps, &x_predecim, &y_predecim, oi->pos_x, oi->rotation_type); @@ -2391,7 +2389,7 @@ int dispc_ovl_setup(enum omap_plane plane, const struct omap_overlay_info *oi, dispc_ovl_set_input_size(plane, in_width, in_height); - if (ovl->caps & OMAP_DSS_OVL_CAP_SCALE) { + if (caps & OMAP_DSS_OVL_CAP_SCALE) { dispc_ovl_set_scaling(plane, in_width, in_height, out_width, out_height, ilace, five_taps, fieldmode, oi->color_mode, oi->rotation); @@ -2403,9 +2401,9 @@ int dispc_ovl_setup(enum omap_plane plane, const struct omap_overlay_info *oi, dispc_ovl_set_rotation_attrs(plane, oi->rotation, oi->mirror, oi->color_mode); - dispc_ovl_set_zorder(plane, oi->zorder); - dispc_ovl_set_pre_mult_alpha(plane, oi->pre_mult_alpha); - dispc_ovl_setup_global_alpha(plane, oi->global_alpha); + dispc_ovl_set_zorder(plane, caps, oi->zorder); + dispc_ovl_set_pre_mult_alpha(plane, caps, oi->pre_mult_alpha); + dispc_ovl_setup_global_alpha(plane, caps, oi->global_alpha); dispc_ovl_enable_replication(plane, replication); -- cgit v1.2.3 From d79db853000c271fbfc944dc1d4f527805109b0c Mon Sep 17 00:00:00 2001 From: Archit Taneja Date: Sat, 22 Sep 2012 12:30:17 +0530 Subject: OMAPDSS: OVERLAY: Add position and replication as overlay caps Add position and replication as overlay caps, and pass overlay caps as an argument to the corresponding functions. Adding position and replication to overlay caps seems a bit unnecessary, but it allows us to use the corresponding functions for writeback too. These caps will be set for all overlays, but not for writeback. This is done so writeback can reuse dispc_ovl_setup() to the maximum. Signed-off-by: Archit Taneja --- drivers/video/omap2/dss/dispc.c | 20 +++++++++++++----- drivers/video/omap2/dss/dss_features.c | 38 ++++++++++++++++++++++------------ include/video/omapdss.h | 2 ++ 3 files changed, 42 insertions(+), 18 deletions(-) (limited to 'drivers/video/omap2') diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c index 334842a3b527..3e1007810f83 100644 --- a/drivers/video/omap2/dss/dispc.c +++ b/drivers/video/omap2/dss/dispc.c @@ -698,9 +698,15 @@ static void dispc_ovl_set_ba1_uv(enum omap_plane plane, u32 paddr) dispc_write_reg(DISPC_OVL_BA1_UV(plane), paddr); } -static void dispc_ovl_set_pos(enum omap_plane plane, int x, int y) +static void dispc_ovl_set_pos(enum omap_plane plane, + enum omap_overlay_caps caps, int x, int y) { - u32 val = FLD_VAL(y, 26, 16) | FLD_VAL(x, 10, 0); + u32 val; + + if ((caps & OMAP_DSS_OVL_CAP_POS) == 0) + return; + + val = FLD_VAL(y, 26, 16) | FLD_VAL(x, 10, 0); dispc_write_reg(DISPC_OVL_POSITION(plane), val); } @@ -1051,11 +1057,15 @@ static void dispc_ovl_set_vid_color_conv(enum omap_plane plane, bool enable) dispc_write_reg(DISPC_OVL_ATTRIBUTES(plane), val); } -static void dispc_ovl_enable_replication(enum omap_plane plane, bool enable) +static void dispc_ovl_enable_replication(enum omap_plane plane, + enum omap_overlay_caps caps, bool enable) { static const unsigned shifts[] = { 5, 10, 10, 10 }; int shift; + if ((caps & OMAP_DSS_OVL_CAP_REPLICATION) == 0) + return; + shift = shifts[plane]; REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), enable, shift, shift); } @@ -2385,7 +2395,7 @@ int dispc_ovl_setup(enum omap_plane plane, const struct omap_overlay_info *oi, DSSDBG("%d,%d %dx%d -> %dx%d\n", oi->pos_x, oi->pos_y, in_width, in_height, out_width, out_height); - dispc_ovl_set_pos(plane, oi->pos_x, pos_y); + dispc_ovl_set_pos(plane, caps, oi->pos_x, pos_y); dispc_ovl_set_input_size(plane, in_width, in_height); @@ -2405,7 +2415,7 @@ int dispc_ovl_setup(enum omap_plane plane, const struct omap_overlay_info *oi, dispc_ovl_set_pre_mult_alpha(plane, caps, oi->pre_mult_alpha); dispc_ovl_setup_global_alpha(plane, caps, oi->global_alpha); - dispc_ovl_enable_replication(plane, replication); + dispc_ovl_enable_replication(plane, caps, replication); return 0; } diff --git a/drivers/video/omap2/dss/dss_features.c b/drivers/video/omap2/dss/dss_features.c index bfe7fc7b8593..5a5c25b134b1 100644 --- a/drivers/video/omap2/dss/dss_features.c +++ b/drivers/video/omap2/dss/dss_features.c @@ -314,54 +314,66 @@ static const enum omap_color_mode omap4_dss_supported_color_modes[] = { static const enum omap_overlay_caps omap2_dss_overlay_caps[] = { /* OMAP_DSS_GFX */ - 0, + OMAP_DSS_OVL_CAP_POS | OMAP_DSS_OVL_CAP_REPLICATION, /* OMAP_DSS_VIDEO1 */ - OMAP_DSS_OVL_CAP_SCALE, + OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_POS | + OMAP_DSS_OVL_CAP_REPLICATION, /* OMAP_DSS_VIDEO2 */ - OMAP_DSS_OVL_CAP_SCALE, + OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_POS | + OMAP_DSS_OVL_CAP_REPLICATION, }; static const enum omap_overlay_caps omap3430_dss_overlay_caps[] = { /* OMAP_DSS_GFX */ - OMAP_DSS_OVL_CAP_GLOBAL_ALPHA, + OMAP_DSS_OVL_CAP_GLOBAL_ALPHA | OMAP_DSS_OVL_CAP_POS | + OMAP_DSS_OVL_CAP_REPLICATION, /* OMAP_DSS_VIDEO1 */ - OMAP_DSS_OVL_CAP_SCALE, + OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_POS | + OMAP_DSS_OVL_CAP_REPLICATION, /* OMAP_DSS_VIDEO2 */ - OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_GLOBAL_ALPHA, + OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_GLOBAL_ALPHA | + OMAP_DSS_OVL_CAP_POS | OMAP_DSS_OVL_CAP_REPLICATION, }; static const enum omap_overlay_caps omap3630_dss_overlay_caps[] = { /* OMAP_DSS_GFX */ - OMAP_DSS_OVL_CAP_GLOBAL_ALPHA | OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA, + OMAP_DSS_OVL_CAP_GLOBAL_ALPHA | OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA | + OMAP_DSS_OVL_CAP_POS | OMAP_DSS_OVL_CAP_REPLICATION, /* OMAP_DSS_VIDEO1 */ - OMAP_DSS_OVL_CAP_SCALE, + OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_POS | + OMAP_DSS_OVL_CAP_REPLICATION, /* OMAP_DSS_VIDEO2 */ OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_GLOBAL_ALPHA | - OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA, + OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA | OMAP_DSS_OVL_CAP_POS | + OMAP_DSS_OVL_CAP_REPLICATION, }; static const enum omap_overlay_caps omap4_dss_overlay_caps[] = { /* OMAP_DSS_GFX */ OMAP_DSS_OVL_CAP_GLOBAL_ALPHA | OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA | - OMAP_DSS_OVL_CAP_ZORDER, + OMAP_DSS_OVL_CAP_ZORDER | OMAP_DSS_OVL_CAP_POS | + OMAP_DSS_OVL_CAP_REPLICATION, /* OMAP_DSS_VIDEO1 */ OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_GLOBAL_ALPHA | - OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA | OMAP_DSS_OVL_CAP_ZORDER, + OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA | OMAP_DSS_OVL_CAP_ZORDER | + OMAP_DSS_OVL_CAP_POS | OMAP_DSS_OVL_CAP_REPLICATION, /* OMAP_DSS_VIDEO2 */ OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_GLOBAL_ALPHA | - OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA | OMAP_DSS_OVL_CAP_ZORDER, + OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA | OMAP_DSS_OVL_CAP_ZORDER | + OMAP_DSS_OVL_CAP_POS | OMAP_DSS_OVL_CAP_REPLICATION, /* OMAP_DSS_VIDEO3 */ OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_GLOBAL_ALPHA | - OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA | OMAP_DSS_OVL_CAP_ZORDER, + OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA | OMAP_DSS_OVL_CAP_ZORDER | + OMAP_DSS_OVL_CAP_POS | OMAP_DSS_OVL_CAP_REPLICATION, }; static const char * const omap2_dss_clk_source_names[] = { diff --git a/include/video/omapdss.h b/include/video/omapdss.h index e65e2e9e16eb..46097bd052a2 100644 --- a/include/video/omapdss.h +++ b/include/video/omapdss.h @@ -187,6 +187,8 @@ enum omap_overlay_caps { OMAP_DSS_OVL_CAP_GLOBAL_ALPHA = 1 << 1, OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA = 1 << 2, OMAP_DSS_OVL_CAP_ZORDER = 1 << 3, + OMAP_DSS_OVL_CAP_POS = 1 << 4, + OMAP_DSS_OVL_CAP_REPLICATION = 1 << 5, }; enum omap_overlay_manager_caps { -- cgit v1.2.3 From 84a880fd51cb528ae7499d0e971a3d4f4587401a Mon Sep 17 00:00:00 2001 From: Archit Taneja Date: Wed, 26 Sep 2012 16:57:37 +0530 Subject: OMAPDSS: DISPC: Make dispc_ovl_setup call dispc_ovl_setup_common Add a new static function called dispc_ovl_setup_common(). This function is used by dispc_ovl_setup() to configure the overlay registers. This split is done so that dispc_wb_setup() can reuse overlay register configuration related code. Signed-off-by: Archit Taneja --- drivers/video/omap2/dss/dispc.c | 130 ++++++++++++++++++++++------------------ 1 file changed, 72 insertions(+), 58 deletions(-) (limited to 'drivers/video/omap2') diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c index 3e1007810f83..9c23ce8aed49 100644 --- a/drivers/video/omap2/dss/dispc.c +++ b/drivers/video/omap2/dss/dispc.c @@ -2264,43 +2264,35 @@ static int dispc_ovl_calc_scaling(enum omap_plane plane, return 0; } -int dispc_ovl_setup(enum omap_plane plane, const struct omap_overlay_info *oi, +static int dispc_ovl_setup_common(enum omap_plane plane, + enum omap_channel channel, enum omap_overlay_caps caps, + u32 paddr, u32 p_uv_addr, u16 screen_width, int pos_x, + int pos_y, u16 width, u16 height, u16 out_width, u16 out_height, + enum omap_color_mode color_mode, u8 rotation, bool mirror, + u8 zorder, u8 pre_mult_alpha, u8 global_alpha, + enum omap_dss_rotation_type rotation_type, bool replication, const struct omap_video_timings *mgr_timings) { - struct omap_overlay *ovl = omap_dss_get_overlay(plane); - enum omap_overlay_caps caps = ovl->caps; bool five_taps = true; bool fieldmode = 0; int r, cconv = 0; unsigned offset0, offset1; s32 row_inc; s32 pix_inc; - u16 frame_height = oi->height; + u16 frame_height = height; unsigned int field_offset = 0; - u16 in_height = oi->height; - u16 in_width = oi->width; - u16 out_width, out_height; - enum omap_channel channel; + u16 in_height = height; + u16 in_width = width; int x_predecim = 1, y_predecim = 1; bool ilace = mgr_timings->interlace; - u16 pos_y = oi->pos_y; - - channel = dispc_ovl_get_channel_out(plane); - - DSSDBG("dispc_ovl_setup %d, pa %x, pa_uv %x, sw %d, %d,%d, %dx%d -> " - "%dx%d, cmode %x, rot %d, mir %d, ilace %d chan %d repl %d\n", - plane, oi->paddr, oi->p_uv_addr, - oi->screen_width, oi->pos_x, oi->pos_y, oi->width, oi->height, - oi->out_width, oi->out_height, oi->color_mode, oi->rotation, - oi->mirror, ilace, channel, replication); - if (oi->paddr == 0) + if (paddr == 0) return -EINVAL; - out_width = oi->out_width == 0 ? oi->width : oi->out_width; - out_height = oi->out_height == 0 ? oi->height : oi->out_height; + out_width = out_width == 0 ? width : out_width; + out_height = out_height == 0 ? height : out_height; - if (ilace && oi->height == out_height) + if (ilace && height == out_height) fieldmode = 1; if (ilace) { @@ -2310,26 +2302,26 @@ int dispc_ovl_setup(enum omap_plane plane, const struct omap_overlay_info *oi, out_height /= 2; DSSDBG("adjusting for ilace: height %d, pos_y %d, " - "out_height %d\n", - in_height, pos_y, out_height); + "out_height %d\n", in_height, pos_y, + out_height); } - if (!dss_feat_color_mode_supported(plane, oi->color_mode)) + if (!dss_feat_color_mode_supported(plane, color_mode)) return -EINVAL; r = dispc_ovl_calc_scaling(plane, caps, channel, mgr_timings, in_width, - in_height, out_width, out_height, oi->color_mode, - &five_taps, &x_predecim, &y_predecim, oi->pos_x, - oi->rotation_type); + in_height, out_width, out_height, color_mode, + &five_taps, &x_predecim, &y_predecim, pos_x, + rotation_type); if (r) return r; in_width = DIV_ROUND_UP(in_width, x_predecim); in_height = DIV_ROUND_UP(in_height, y_predecim); - if (oi->color_mode == OMAP_DSS_COLOR_YUV2 || - oi->color_mode == OMAP_DSS_COLOR_UYVY || - oi->color_mode == OMAP_DSS_COLOR_NV12) + if (color_mode == OMAP_DSS_COLOR_YUV2 || + color_mode == OMAP_DSS_COLOR_UYVY || + color_mode == OMAP_DSS_COLOR_NV12) cconv = 1; if (ilace && !fieldmode) { @@ -2355,71 +2347,93 @@ int dispc_ovl_setup(enum omap_plane plane, const struct omap_overlay_info *oi, row_inc = 0; pix_inc = 0; - if (oi->rotation_type == OMAP_DSS_ROT_TILER) - calc_tiler_rotation_offset(oi->screen_width, in_width, - oi->color_mode, fieldmode, field_offset, + if (rotation_type == OMAP_DSS_ROT_TILER) + calc_tiler_rotation_offset(screen_width, in_width, + color_mode, fieldmode, field_offset, &offset0, &offset1, &row_inc, &pix_inc, x_predecim, y_predecim); - else if (oi->rotation_type == OMAP_DSS_ROT_DMA) - calc_dma_rotation_offset(oi->rotation, oi->mirror, - oi->screen_width, in_width, frame_height, - oi->color_mode, fieldmode, field_offset, + else if (rotation_type == OMAP_DSS_ROT_DMA) + calc_dma_rotation_offset(rotation, mirror, + screen_width, in_width, frame_height, + color_mode, fieldmode, field_offset, &offset0, &offset1, &row_inc, &pix_inc, x_predecim, y_predecim); else - calc_vrfb_rotation_offset(oi->rotation, oi->mirror, - oi->screen_width, in_width, frame_height, - oi->color_mode, fieldmode, field_offset, + calc_vrfb_rotation_offset(rotation, mirror, + screen_width, in_width, frame_height, + color_mode, fieldmode, field_offset, &offset0, &offset1, &row_inc, &pix_inc, x_predecim, y_predecim); DSSDBG("offset0 %u, offset1 %u, row_inc %d, pix_inc %d\n", offset0, offset1, row_inc, pix_inc); - dispc_ovl_set_color_mode(plane, oi->color_mode); + dispc_ovl_set_color_mode(plane, color_mode); - dispc_ovl_configure_burst_type(plane, oi->rotation_type); + dispc_ovl_configure_burst_type(plane, rotation_type); - dispc_ovl_set_ba0(plane, oi->paddr + offset0); - dispc_ovl_set_ba1(plane, oi->paddr + offset1); + dispc_ovl_set_ba0(plane, paddr + offset0); + dispc_ovl_set_ba1(plane, paddr + offset1); - if (OMAP_DSS_COLOR_NV12 == oi->color_mode) { - dispc_ovl_set_ba0_uv(plane, oi->p_uv_addr + offset0); - dispc_ovl_set_ba1_uv(plane, oi->p_uv_addr + offset1); + if (OMAP_DSS_COLOR_NV12 == color_mode) { + dispc_ovl_set_ba0_uv(plane, p_uv_addr + offset0); + dispc_ovl_set_ba1_uv(plane, p_uv_addr + offset1); } - dispc_ovl_set_row_inc(plane, row_inc); dispc_ovl_set_pix_inc(plane, pix_inc); - DSSDBG("%d,%d %dx%d -> %dx%d\n", oi->pos_x, oi->pos_y, in_width, + DSSDBG("%d,%d %dx%d -> %dx%d\n", pos_x, pos_y, in_width, in_height, out_width, out_height); - dispc_ovl_set_pos(plane, caps, oi->pos_x, pos_y); + dispc_ovl_set_pos(plane, caps, pos_x, pos_y); dispc_ovl_set_input_size(plane, in_width, in_height); if (caps & OMAP_DSS_OVL_CAP_SCALE) { dispc_ovl_set_scaling(plane, in_width, in_height, out_width, out_height, ilace, five_taps, fieldmode, - oi->color_mode, oi->rotation); - + color_mode, rotation); dispc_ovl_set_output_size(plane, out_width, out_height); dispc_ovl_set_vid_color_conv(plane, cconv); } - dispc_ovl_set_rotation_attrs(plane, oi->rotation, oi->mirror, - oi->color_mode); + dispc_ovl_set_rotation_attrs(plane, rotation, mirror, color_mode); - dispc_ovl_set_zorder(plane, caps, oi->zorder); - dispc_ovl_set_pre_mult_alpha(plane, caps, oi->pre_mult_alpha); - dispc_ovl_setup_global_alpha(plane, caps, oi->global_alpha); + dispc_ovl_set_zorder(plane, caps, zorder); + dispc_ovl_set_pre_mult_alpha(plane, caps, pre_mult_alpha); + dispc_ovl_setup_global_alpha(plane, caps, global_alpha); dispc_ovl_enable_replication(plane, caps, replication); return 0; } +int dispc_ovl_setup(enum omap_plane plane, const struct omap_overlay_info *oi, + bool replication, const struct omap_video_timings *mgr_timings) +{ + int r; + struct omap_overlay *ovl = omap_dss_get_overlay(plane); + enum omap_channel channel; + + channel = dispc_ovl_get_channel_out(plane); + + DSSDBG("dispc_ovl_setup %d, pa %x, pa_uv %x, sw %d, %d,%d, %dx%d -> " + "%dx%d, cmode %x, rot %d, mir %d, chan %d repl %d\n", + plane, oi->paddr, oi->p_uv_addr, oi->screen_width, oi->pos_x, + oi->pos_y, oi->width, oi->height, oi->out_width, oi->out_height, + oi->color_mode, oi->rotation, oi->mirror, channel, replication); + + r = dispc_ovl_setup_common(plane, channel, ovl->caps, oi->paddr, + oi->p_uv_addr, oi->screen_width, oi->pos_x, oi->pos_y, + oi->width, oi->height, oi->out_width, oi->out_height, + oi->color_mode, oi->rotation, oi->mirror, oi->zorder, + oi->pre_mult_alpha, oi->global_alpha, oi->rotation_type, + replication, mgr_timings); + + return r; +} + int dispc_ovl_enable(enum omap_plane plane, bool enable) { DSSDBG("dispc_enable_plane %d, %d\n", plane, enable); -- cgit v1.2.3 From 3e8a6ff2489510f529364f3c3f8b8881d599fd5c Mon Sep 17 00:00:00 2001 From: Archit Taneja Date: Wed, 26 Sep 2012 16:58:52 +0530 Subject: OMAPDSS: DISPC: Don't pass channel out when configuring overlays dispc_ovl_setup_common() is to be used by both overlays and writeback. We pass channel out to figure out what manager the overlay is connected to, to determine the pixel clock rate. This is used to decide the scaling limitations for that overlay. writeback doesn't have a channel out, it has a channel in field which tells where writeback gets its input from. These are 2 different fields, and this prevents us reusing the overlay configuration code for writeback. To overcome this, we now pass omap_plane to overlay related functions rather than passing channel out. We create helper functions which can derive pclk/lclk from the omap_plane id. Signed-off-by: Archit Taneja --- drivers/video/omap2/dss/dispc.c | 110 +++++++++++++++++++++++----------------- 1 file changed, 64 insertions(+), 46 deletions(-) (limited to 'drivers/video/omap2') diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c index 9c23ce8aed49..d65568929ac8 100644 --- a/drivers/video/omap2/dss/dispc.c +++ b/drivers/video/omap2/dss/dispc.c @@ -86,13 +86,13 @@ struct dispc_features { u16 sw_max; u16 vp_max; u16 hp_max; - int (*calc_scaling) (enum omap_channel channel, + int (*calc_scaling) (enum omap_plane plane, const struct omap_video_timings *mgr_timings, u16 width, u16 height, u16 out_width, u16 out_height, enum omap_color_mode color_mode, bool *five_taps, int *x_predecim, int *y_predecim, int *decim_x, int *decim_y, u16 pos_x, unsigned long *core_clk); - unsigned long (*calc_core_clk) (enum omap_channel channel, + unsigned long (*calc_core_clk) (enum omap_plane plane, u16 width, u16 height, u16 out_width, u16 out_height); u8 num_fifos; @@ -236,6 +236,8 @@ static const struct { }; static void _omap_dispc_set_irqs(void); +static unsigned long dispc_plane_pclk_rate(enum omap_plane plane); +static unsigned long dispc_plane_lclk_rate(enum omap_plane plane); static inline void dispc_write_reg(const u16 idx, u32 val) { @@ -1919,22 +1921,19 @@ static void calc_tiler_rotation_offset(u16 screen_width, u16 width, * This function is used to avoid synclosts in OMAP3, because of some * undocumented horizontal position and timing related limitations. */ -static int check_horiz_timing_omap3(enum omap_channel channel, +static int check_horiz_timing_omap3(enum omap_plane plane, const struct omap_video_timings *t, u16 pos_x, u16 width, u16 height, u16 out_width, u16 out_height) { int DS = DIV_ROUND_UP(height, out_height); - unsigned long nonactive, lclk, pclk; + unsigned long nonactive; static const u8 limits[3] = { 8, 10, 20 }; u64 val, blank; + unsigned long pclk = dispc_plane_pclk_rate(plane); + unsigned long lclk = dispc_plane_lclk_rate(plane); int i; nonactive = t->x_res + t->hfp + t->hsw + t->hbp - out_width; - pclk = dispc_mgr_pclk_rate(channel); - if (dss_mgr_is_lcd(channel)) - lclk = dispc_mgr_lclk_rate(channel); - else - lclk = dispc_fclk_rate(); i = 0; if (out_height < height) @@ -1971,13 +1970,14 @@ static int check_horiz_timing_omap3(enum omap_channel channel, return 0; } -static unsigned long calc_core_clk_five_taps(enum omap_channel channel, +static unsigned long calc_core_clk_five_taps(enum omap_plane plane, const struct omap_video_timings *mgr_timings, u16 width, u16 height, u16 out_width, u16 out_height, enum omap_color_mode color_mode) { u32 core_clk = 0; - u64 tmp, pclk = dispc_mgr_pclk_rate(channel); + u64 tmp; + unsigned long pclk = dispc_plane_pclk_rate(plane); if (height <= out_height && width <= out_width) return (unsigned long) pclk; @@ -2011,10 +2011,10 @@ static unsigned long calc_core_clk_five_taps(enum omap_channel channel, return core_clk; } -static unsigned long calc_core_clk_24xx(enum omap_channel channel, u16 width, +static unsigned long calc_core_clk_24xx(enum omap_plane plane, u16 width, u16 height, u16 out_width, u16 out_height) { - unsigned long pclk = dispc_mgr_pclk_rate(channel); + unsigned long pclk = dispc_plane_pclk_rate(plane); if (height > out_height && width > out_width) return pclk * 4; @@ -2022,11 +2022,11 @@ static unsigned long calc_core_clk_24xx(enum omap_channel channel, u16 width, return pclk * 2; } -static unsigned long calc_core_clk_34xx(enum omap_channel channel, u16 width, +static unsigned long calc_core_clk_34xx(enum omap_plane plane, u16 width, u16 height, u16 out_width, u16 out_height) { unsigned int hf, vf; - unsigned long pclk = dispc_mgr_pclk_rate(channel); + unsigned long pclk = dispc_plane_pclk_rate(plane); /* * FIXME how to determine the 'A' factor @@ -2049,10 +2049,10 @@ static unsigned long calc_core_clk_34xx(enum omap_channel channel, u16 width, return pclk * vf * hf; } -static unsigned long calc_core_clk_44xx(enum omap_channel channel, u16 width, +static unsigned long calc_core_clk_44xx(enum omap_plane plane, u16 width, u16 height, u16 out_width, u16 out_height) { - unsigned long pclk = dispc_mgr_pclk_rate(channel); + unsigned long pclk = dispc_plane_pclk_rate(plane); if (width > out_width) return DIV_ROUND_UP(pclk, out_width) * width; @@ -2060,7 +2060,7 @@ static unsigned long calc_core_clk_44xx(enum omap_channel channel, u16 width, return pclk; } -static int dispc_ovl_calc_scaling_24xx(enum omap_channel channel, +static int dispc_ovl_calc_scaling_24xx(enum omap_plane plane, const struct omap_video_timings *mgr_timings, u16 width, u16 height, u16 out_width, u16 out_height, enum omap_color_mode color_mode, bool *five_taps, @@ -2072,12 +2072,13 @@ static int dispc_ovl_calc_scaling_24xx(enum omap_channel channel, int min_factor = min(*decim_x, *decim_y); const int maxsinglelinewidth = dss_feat_get_param_max(FEAT_PARAM_LINEWIDTH); + *five_taps = false; do { in_height = DIV_ROUND_UP(height, *decim_y); in_width = DIV_ROUND_UP(width, *decim_x); - *core_clk = dispc.feat->calc_core_clk(channel, in_width, + *core_clk = dispc.feat->calc_core_clk(plane, in_width, in_height, out_width, out_height); error = (in_width > maxsinglelinewidth || !*core_clk || *core_clk > dispc_core_clk_rate()); @@ -2100,7 +2101,7 @@ static int dispc_ovl_calc_scaling_24xx(enum omap_channel channel, return 0; } -static int dispc_ovl_calc_scaling_34xx(enum omap_channel channel, +static int dispc_ovl_calc_scaling_34xx(enum omap_plane plane, const struct omap_video_timings *mgr_timings, u16 width, u16 height, u16 out_width, u16 out_height, enum omap_color_mode color_mode, bool *five_taps, @@ -2116,18 +2117,19 @@ static int dispc_ovl_calc_scaling_34xx(enum omap_channel channel, do { in_height = DIV_ROUND_UP(height, *decim_y); in_width = DIV_ROUND_UP(width, *decim_x); - *core_clk = calc_core_clk_five_taps(channel, mgr_timings, + *core_clk = calc_core_clk_five_taps(plane, mgr_timings, in_width, in_height, out_width, out_height, color_mode); - error = check_horiz_timing_omap3(channel, mgr_timings, pos_x, - in_width, in_height, out_width, out_height); + error = check_horiz_timing_omap3(plane, mgr_timings, + pos_x, in_width, in_height, out_width, + out_height); if (in_width > maxsinglelinewidth) if (in_height > out_height && in_height < out_height * 2) *five_taps = false; if (!*five_taps) - *core_clk = dispc.feat->calc_core_clk(channel, in_width, + *core_clk = dispc.feat->calc_core_clk(plane, in_width, in_height, out_width, out_height); error = (error || in_width > maxsinglelinewidth * 2 || @@ -2145,7 +2147,7 @@ static int dispc_ovl_calc_scaling_34xx(enum omap_channel channel, } } while (*decim_x <= *x_predecim && *decim_y <= *y_predecim && error); - if (check_horiz_timing_omap3(channel, mgr_timings, pos_x, width, height, + if (check_horiz_timing_omap3(plane, mgr_timings, pos_x, width, height, out_width, out_height)){ DSSERR("horizontal timing too tight\n"); return -EINVAL; @@ -2164,7 +2166,7 @@ static int dispc_ovl_calc_scaling_34xx(enum omap_channel channel, return 0; } -static int dispc_ovl_calc_scaling_44xx(enum omap_channel channel, +static int dispc_ovl_calc_scaling_44xx(enum omap_plane plane, const struct omap_video_timings *mgr_timings, u16 width, u16 height, u16 out_width, u16 out_height, enum omap_color_mode color_mode, bool *five_taps, @@ -2176,9 +2178,10 @@ static int dispc_ovl_calc_scaling_44xx(enum omap_channel channel, u16 in_height = DIV_ROUND_UP(height, *decim_y); const int maxsinglelinewidth = dss_feat_get_param_max(FEAT_PARAM_LINEWIDTH); + unsigned long pclk = dispc_plane_pclk_rate(plane); + + in_width_max = dispc_core_clk_rate() / DIV_ROUND_UP(pclk, out_width); - in_width_max = dispc_core_clk_rate() / - DIV_ROUND_UP(dispc_mgr_pclk_rate(channel), out_width); *decim_x = DIV_ROUND_UP(width, in_width_max); *decim_x = *decim_x > decim_x_min ? *decim_x : decim_x_min; @@ -2195,13 +2198,13 @@ static int dispc_ovl_calc_scaling_44xx(enum omap_channel channel, return -EINVAL; } - *core_clk = dispc.feat->calc_core_clk(channel, in_width, in_height, + *core_clk = dispc.feat->calc_core_clk(plane, in_width, in_height, out_width, out_height); return 0; } static int dispc_ovl_calc_scaling(enum omap_plane plane, - enum omap_overlay_caps caps, enum omap_channel channel, + enum omap_overlay_caps caps, const struct omap_video_timings *mgr_timings, u16 width, u16 height, u16 out_width, u16 out_height, enum omap_color_mode color_mode, bool *five_taps, @@ -2242,9 +2245,9 @@ static int dispc_ovl_calc_scaling(enum omap_plane plane, if (decim_y > *y_predecim || out_height > height * 8) return -EINVAL; - ret = dispc.feat->calc_scaling(channel, mgr_timings, width, height, - out_width, out_height, color_mode, five_taps, x_predecim, - y_predecim, &decim_x, &decim_y, pos_x, &core_clk); + ret = dispc.feat->calc_scaling(plane, mgr_timings, width, height, + out_width, out_height, color_mode, five_taps, + x_predecim, y_predecim, &decim_x, &decim_y, pos_x, &core_clk); if (ret) return ret; @@ -2265,12 +2268,11 @@ static int dispc_ovl_calc_scaling(enum omap_plane plane, } static int dispc_ovl_setup_common(enum omap_plane plane, - enum omap_channel channel, enum omap_overlay_caps caps, - u32 paddr, u32 p_uv_addr, u16 screen_width, int pos_x, - int pos_y, u16 width, u16 height, u16 out_width, u16 out_height, - enum omap_color_mode color_mode, u8 rotation, bool mirror, - u8 zorder, u8 pre_mult_alpha, u8 global_alpha, - enum omap_dss_rotation_type rotation_type, + enum omap_overlay_caps caps, u32 paddr, u32 p_uv_addr, + u16 screen_width, int pos_x, int pos_y, u16 width, u16 height, + u16 out_width, u16 out_height, enum omap_color_mode color_mode, + u8 rotation, bool mirror, u8 zorder, u8 pre_mult_alpha, + u8 global_alpha, enum omap_dss_rotation_type rotation_type, bool replication, const struct omap_video_timings *mgr_timings) { bool five_taps = true; @@ -2309,7 +2311,7 @@ static int dispc_ovl_setup_common(enum omap_plane plane, if (!dss_feat_color_mode_supported(plane, color_mode)) return -EINVAL; - r = dispc_ovl_calc_scaling(plane, caps, channel, mgr_timings, in_width, + r = dispc_ovl_calc_scaling(plane, caps, mgr_timings, in_width, in_height, out_width, out_height, color_mode, &five_taps, &x_predecim, &y_predecim, pos_x, rotation_type); @@ -2424,12 +2426,11 @@ int dispc_ovl_setup(enum omap_plane plane, const struct omap_overlay_info *oi, oi->pos_y, oi->width, oi->height, oi->out_width, oi->out_height, oi->color_mode, oi->rotation, oi->mirror, channel, replication); - r = dispc_ovl_setup_common(plane, channel, ovl->caps, oi->paddr, - oi->p_uv_addr, oi->screen_width, oi->pos_x, oi->pos_y, - oi->width, oi->height, oi->out_width, oi->out_height, - oi->color_mode, oi->rotation, oi->mirror, oi->zorder, - oi->pre_mult_alpha, oi->global_alpha, oi->rotation_type, - replication, mgr_timings); + r = dispc_ovl_setup_common(plane, ovl->caps, oi->paddr, oi->p_uv_addr, + oi->screen_width, oi->pos_x, oi->pos_y, oi->width, oi->height, + oi->out_width, oi->out_height, oi->color_mode, oi->rotation, + oi->mirror, oi->zorder, oi->pre_mult_alpha, oi->global_alpha, + oi->rotation_type, replication, mgr_timings); return r; } @@ -2989,6 +2990,23 @@ unsigned long dispc_core_clk_rate(void) return fclk / lcd; } +static unsigned long dispc_plane_pclk_rate(enum omap_plane plane) +{ + enum omap_channel channel = dispc_ovl_get_channel_out(plane); + + return dispc_mgr_pclk_rate(channel); +} + +static unsigned long dispc_plane_lclk_rate(enum omap_plane plane) +{ + enum omap_channel channel = dispc_ovl_get_channel_out(plane); + + if (dss_mgr_is_lcd(channel)) + return dispc_mgr_lclk_rate(channel); + else + return dispc_fclk_rate(); + +} static void dispc_dump_clocks_channel(struct seq_file *s, enum omap_channel channel) { int lcd, pcd; -- cgit v1.2.3 From 8ba85306ba0fd87a3c15a02fe83d817832705a7d Mon Sep 17 00:00:00 2001 From: Archit Taneja Date: Wed, 26 Sep 2012 17:00:37 +0530 Subject: OMAPDSS: DIPSC: Relax scaling limitations when in memory to memory mode The scalers of overlays and writeback do not have any constraints on downscale ratio when operating in memory to memory mode. This is because in memory to memory mode, we aren't connected to a display which needs data output at the rate of pixel clock. The scalers can perform as much downscaling as needed, the rate at which the scaler outputs is adjusted accordingly. Relax constraints related to downscaling based on whether the input overlays are connected to writeback in memory to memory mode. We pass a mem_to_mem boolean parameter to dispc_ovl_setup() from APPLY. This is currently set to false, this will later be configured to the correct value based on whether the overlay is connected to writeback or not. Do the same later for writeback when writeback is configured. In the scaling calculation code, we calculate the minimum amount of core clock we need to achieve the required downscaling. If we are in memory to memory mode, we set this to a very small value(1 in this case), this value would always be lesser than the actual DISPC core clock value, and hence the scaling checks would succeed. We take care that pixel clock isn't calculated for writeback and the overlays connected to it when in memory to memory mode. A pixel clock in such cases doesn't make sense. Signed-off-by: Archit Taneja --- drivers/video/omap2/dss/apply.c | 2 +- drivers/video/omap2/dss/dispc.c | 59 ++++++++++++++++++++++++++++------------- drivers/video/omap2/dss/dss.h | 3 ++- 3 files changed, 43 insertions(+), 21 deletions(-) (limited to 'drivers/video/omap2') diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c index 2b1fa851a8b9..19d66f471b4b 100644 --- a/drivers/video/omap2/dss/apply.c +++ b/drivers/video/omap2/dss/apply.c @@ -584,7 +584,7 @@ static void dss_ovl_write_regs(struct omap_overlay *ovl) replication = dss_ovl_use_replication(mp->lcd_config, oi->color_mode); - r = dispc_ovl_setup(ovl->id, oi, replication, &mp->timings); + r = dispc_ovl_setup(ovl->id, oi, replication, &mp->timings, false); if (r) { /* * We can't do much here, as this function can be called from diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c index d65568929ac8..fd932b83ce43 100644 --- a/drivers/video/omap2/dss/dispc.c +++ b/drivers/video/omap2/dss/dispc.c @@ -91,9 +91,10 @@ struct dispc_features { u16 width, u16 height, u16 out_width, u16 out_height, enum omap_color_mode color_mode, bool *five_taps, int *x_predecim, int *y_predecim, int *decim_x, int *decim_y, - u16 pos_x, unsigned long *core_clk); + u16 pos_x, unsigned long *core_clk, bool mem_to_mem); unsigned long (*calc_core_clk) (enum omap_plane plane, - u16 width, u16 height, u16 out_width, u16 out_height); + u16 width, u16 height, u16 out_width, u16 out_height, + bool mem_to_mem); u8 num_fifos; /* swap GFX & WB fifos */ @@ -2012,7 +2013,7 @@ static unsigned long calc_core_clk_five_taps(enum omap_plane plane, } static unsigned long calc_core_clk_24xx(enum omap_plane plane, u16 width, - u16 height, u16 out_width, u16 out_height) + u16 height, u16 out_width, u16 out_height, bool mem_to_mem) { unsigned long pclk = dispc_plane_pclk_rate(plane); @@ -2023,7 +2024,7 @@ static unsigned long calc_core_clk_24xx(enum omap_plane plane, u16 width, } static unsigned long calc_core_clk_34xx(enum omap_plane plane, u16 width, - u16 height, u16 out_width, u16 out_height) + u16 height, u16 out_width, u16 out_height, bool mem_to_mem) { unsigned int hf, vf; unsigned long pclk = dispc_plane_pclk_rate(plane); @@ -2050,9 +2051,20 @@ static unsigned long calc_core_clk_34xx(enum omap_plane plane, u16 width, } static unsigned long calc_core_clk_44xx(enum omap_plane plane, u16 width, - u16 height, u16 out_width, u16 out_height) + u16 height, u16 out_width, u16 out_height, bool mem_to_mem) { - unsigned long pclk = dispc_plane_pclk_rate(plane); + unsigned long pclk; + + /* + * If the overlay/writeback is in mem to mem mode, there are no + * downscaling limitations with respect to pixel clock, return 1 as + * required core clock to represent that we have sufficient enough + * core clock to do maximum downscaling + */ + if (mem_to_mem) + return 1; + + pclk = dispc_plane_pclk_rate(plane); if (width > out_width) return DIV_ROUND_UP(pclk, out_width) * width; @@ -2065,7 +2077,7 @@ static int dispc_ovl_calc_scaling_24xx(enum omap_plane plane, u16 width, u16 height, u16 out_width, u16 out_height, enum omap_color_mode color_mode, bool *five_taps, int *x_predecim, int *y_predecim, int *decim_x, int *decim_y, - u16 pos_x, unsigned long *core_clk) + u16 pos_x, unsigned long *core_clk, bool mem_to_mem) { int error; u16 in_width, in_height; @@ -2079,7 +2091,7 @@ static int dispc_ovl_calc_scaling_24xx(enum omap_plane plane, in_height = DIV_ROUND_UP(height, *decim_y); in_width = DIV_ROUND_UP(width, *decim_x); *core_clk = dispc.feat->calc_core_clk(plane, in_width, - in_height, out_width, out_height); + in_height, out_width, out_height, mem_to_mem); error = (in_width > maxsinglelinewidth || !*core_clk || *core_clk > dispc_core_clk_rate()); if (error) { @@ -2106,7 +2118,7 @@ static int dispc_ovl_calc_scaling_34xx(enum omap_plane plane, u16 width, u16 height, u16 out_width, u16 out_height, enum omap_color_mode color_mode, bool *five_taps, int *x_predecim, int *y_predecim, int *decim_x, int *decim_y, - u16 pos_x, unsigned long *core_clk) + u16 pos_x, unsigned long *core_clk, bool mem_to_mem) { int error; u16 in_width, in_height; @@ -2130,7 +2142,8 @@ static int dispc_ovl_calc_scaling_34xx(enum omap_plane plane, *five_taps = false; if (!*five_taps) *core_clk = dispc.feat->calc_core_clk(plane, in_width, - in_height, out_width, out_height); + in_height, out_width, out_height, + mem_to_mem); error = (error || in_width > maxsinglelinewidth * 2 || (in_width > maxsinglelinewidth && *five_taps) || @@ -2171,7 +2184,7 @@ static int dispc_ovl_calc_scaling_44xx(enum omap_plane plane, u16 width, u16 height, u16 out_width, u16 out_height, enum omap_color_mode color_mode, bool *five_taps, int *x_predecim, int *y_predecim, int *decim_x, int *decim_y, - u16 pos_x, unsigned long *core_clk) + u16 pos_x, unsigned long *core_clk, bool mem_to_mem) { u16 in_width, in_width_max; int decim_x_min = *decim_x; @@ -2179,8 +2192,13 @@ static int dispc_ovl_calc_scaling_44xx(enum omap_plane plane, const int maxsinglelinewidth = dss_feat_get_param_max(FEAT_PARAM_LINEWIDTH); unsigned long pclk = dispc_plane_pclk_rate(plane); + const int maxdownscale = dss_feat_get_param_max(FEAT_PARAM_DOWNSCALE); - in_width_max = dispc_core_clk_rate() / DIV_ROUND_UP(pclk, out_width); + if (mem_to_mem) + in_width_max = DIV_ROUND_UP(out_width, maxdownscale); + else + in_width_max = dispc_core_clk_rate() / + DIV_ROUND_UP(pclk, out_width); *decim_x = DIV_ROUND_UP(width, in_width_max); @@ -2199,7 +2217,7 @@ static int dispc_ovl_calc_scaling_44xx(enum omap_plane plane, } *core_clk = dispc.feat->calc_core_clk(plane, in_width, in_height, - out_width, out_height); + out_width, out_height, mem_to_mem); return 0; } @@ -2209,7 +2227,7 @@ static int dispc_ovl_calc_scaling(enum omap_plane plane, u16 width, u16 height, u16 out_width, u16 out_height, enum omap_color_mode color_mode, bool *five_taps, int *x_predecim, int *y_predecim, u16 pos_x, - enum omap_dss_rotation_type rotation_type) + enum omap_dss_rotation_type rotation_type, bool mem_to_mem) { const int maxdownscale = dss_feat_get_param_max(FEAT_PARAM_DOWNSCALE); const int max_decim_limit = 16; @@ -2247,7 +2265,8 @@ static int dispc_ovl_calc_scaling(enum omap_plane plane, ret = dispc.feat->calc_scaling(plane, mgr_timings, width, height, out_width, out_height, color_mode, five_taps, - x_predecim, y_predecim, &decim_x, &decim_y, pos_x, &core_clk); + x_predecim, y_predecim, &decim_x, &decim_y, pos_x, &core_clk, + mem_to_mem); if (ret) return ret; @@ -2273,7 +2292,8 @@ static int dispc_ovl_setup_common(enum omap_plane plane, u16 out_width, u16 out_height, enum omap_color_mode color_mode, u8 rotation, bool mirror, u8 zorder, u8 pre_mult_alpha, u8 global_alpha, enum omap_dss_rotation_type rotation_type, - bool replication, const struct omap_video_timings *mgr_timings) + bool replication, const struct omap_video_timings *mgr_timings, + bool mem_to_mem) { bool five_taps = true; bool fieldmode = 0; @@ -2314,7 +2334,7 @@ static int dispc_ovl_setup_common(enum omap_plane plane, r = dispc_ovl_calc_scaling(plane, caps, mgr_timings, in_width, in_height, out_width, out_height, color_mode, &five_taps, &x_predecim, &y_predecim, pos_x, - rotation_type); + rotation_type, mem_to_mem); if (r) return r; @@ -2412,7 +2432,8 @@ static int dispc_ovl_setup_common(enum omap_plane plane, } int dispc_ovl_setup(enum omap_plane plane, const struct omap_overlay_info *oi, - bool replication, const struct omap_video_timings *mgr_timings) + bool replication, const struct omap_video_timings *mgr_timings, + bool mem_to_mem) { int r; struct omap_overlay *ovl = omap_dss_get_overlay(plane); @@ -2430,7 +2451,7 @@ int dispc_ovl_setup(enum omap_plane plane, const struct omap_overlay_info *oi, oi->screen_width, oi->pos_x, oi->pos_y, oi->width, oi->height, oi->out_width, oi->out_height, oi->color_mode, oi->rotation, oi->mirror, oi->zorder, oi->pre_mult_alpha, oi->global_alpha, - oi->rotation_type, replication, mgr_timings); + oi->rotation_type, replication, mgr_timings, mem_to_mem); return r; } diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h index e71a6f16fc4d..322a2be7b4c6 100644 --- a/drivers/video/omap2/dss/dss.h +++ b/drivers/video/omap2/dss/dss.h @@ -445,7 +445,8 @@ void dispc_ovl_compute_fifo_thresholds(enum omap_plane plane, u32 *fifo_low, u32 *fifo_high, bool use_fifomerge, bool manual_update); int dispc_ovl_setup(enum omap_plane plane, const struct omap_overlay_info *oi, - bool replication, const struct omap_video_timings *mgr_timings); + bool replication, const struct omap_video_timings *mgr_timings, + bool mem_to_mem); int dispc_ovl_enable(enum omap_plane plane, bool enable); void dispc_ovl_set_channel_out(enum omap_plane plane, enum omap_channel channel); -- cgit v1.2.3 From 20fbb50be4ff22b443183ffb4b5e6dd0691a4fc1 Mon Sep 17 00:00:00 2001 From: Archit Taneja Date: Wed, 22 Aug 2012 17:04:48 +0530 Subject: OMAPDSS: DISPC: Allow both upscaling and downscaling of chroma In the function dispc_plane_set_scaling_uv(), create a parameter which tells if we want to upscale or downscale the chroma plane. Downscaling of chroma is required by writeback pipeline for converting the input YUV444 color format to YUV422 or NV12. Signed-off-by: Archit Taneja --- drivers/video/omap2/dss/dispc.c | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) (limited to 'drivers/video/omap2') diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c index fd932b83ce43..b1b9e3f1be90 100644 --- a/drivers/video/omap2/dss/dispc.c +++ b/drivers/video/omap2/dss/dispc.c @@ -1457,6 +1457,7 @@ static void dispc_ovl_set_scaling_uv(enum omap_plane plane, { int scale_x = out_width != orig_width; int scale_y = out_height != orig_height; + bool chroma_upscale = true; if (!dss_has_feature(FEAT_HANDLE_UV_SEPARATE)) return; @@ -1473,23 +1474,34 @@ static void dispc_ovl_set_scaling_uv(enum omap_plane plane, switch (color_mode) { case OMAP_DSS_COLOR_NV12: - /* UV is subsampled by 2 vertically*/ - orig_height >>= 1; - /* UV is subsampled by 2 horz.*/ - orig_width >>= 1; + if (chroma_upscale) { + /* UV is subsampled by 2 horizontally and vertically */ + orig_height >>= 1; + orig_width >>= 1; + } else { + /* UV is downsampled by 2 horizontally and vertically */ + orig_height <<= 1; + orig_width <<= 1; + } + break; case OMAP_DSS_COLOR_YUV2: case OMAP_DSS_COLOR_UYVY: - /*For YUV422 with 90/270 rotation, - *we don't upsample chroma - */ + /* For YUV422 with 90/270 rotation, we don't upsample chroma */ if (rotation == OMAP_DSS_ROT_0 || - rotation == OMAP_DSS_ROT_180) - /* UV is subsampled by 2 hrz*/ - orig_width >>= 1; + rotation == OMAP_DSS_ROT_180) { + if (chroma_upscale) + /* UV is subsampled by 2 horizontally */ + orig_width >>= 1; + else + /* UV is downsampled by 2 horizontally */ + orig_width <<= 1; + } + /* must use FIR for YUV422 if rotated */ if (rotation != OMAP_DSS_ROT_0) scale_x = scale_y = true; + break; default: BUG(); -- cgit v1.2.3 From 7a155be39e95fa4bf61bdc4c4456316a52421185 Mon Sep 17 00:00:00 2001 From: Archit Taneja Date: Mon, 16 Jul 2012 15:54:24 +0530 Subject: OMAPDSS: DISPC: Add writeback register offsets and dss features structs Since writeback has many overlay like properties, and most of it's registers are similar to that of overlays, it's possible to reuse most of the overlay related DISPC code for writeback when considering it as a plane. Writeback was added as a plane in the omap_plane field as OMAP_DSS_WB. Add the writeback register offsets in dispc.h, add minimal WB plane related info needed in dss_features. Add a function which returns the number of writeback pipelines an OMAP version has. Signed-off-by: Archit Taneja --- drivers/video/omap2/dss/dispc.h | 33 +++++++++++++++++++++++++++++++++ drivers/video/omap2/dss/dss_features.c | 19 +++++++++++++++++++ drivers/video/omap2/dss/dss_features.h | 1 + 3 files changed, 53 insertions(+) (limited to 'drivers/video/omap2') diff --git a/drivers/video/omap2/dss/dispc.h b/drivers/video/omap2/dss/dispc.h index 42e56cc7cdbc..222363c6e623 100644 --- a/drivers/video/omap2/dss/dispc.h +++ b/drivers/video/omap2/dss/dispc.h @@ -373,6 +373,7 @@ static inline u16 DISPC_BA0_OFFSET(enum omap_plane plane) case OMAP_DSS_VIDEO2: return 0x0000; case OMAP_DSS_VIDEO3: + case OMAP_DSS_WB: return 0x0008; default: BUG(); @@ -388,6 +389,7 @@ static inline u16 DISPC_BA1_OFFSET(enum omap_plane plane) case OMAP_DSS_VIDEO2: return 0x0004; case OMAP_DSS_VIDEO3: + case OMAP_DSS_WB: return 0x000C; default: BUG(); @@ -407,6 +409,8 @@ static inline u16 DISPC_BA0_UV_OFFSET(enum omap_plane plane) return 0x04BC; case OMAP_DSS_VIDEO3: return 0x0310; + case OMAP_DSS_WB: + return 0x0118; default: BUG(); return 0; @@ -425,6 +429,8 @@ static inline u16 DISPC_BA1_UV_OFFSET(enum omap_plane plane) return 0x04C0; case OMAP_DSS_VIDEO3: return 0x0314; + case OMAP_DSS_WB: + return 0x011C; default: BUG(); return 0; @@ -454,6 +460,7 @@ static inline u16 DISPC_SIZE_OFFSET(enum omap_plane plane) case OMAP_DSS_VIDEO2: return 0x000C; case OMAP_DSS_VIDEO3: + case OMAP_DSS_WB: return 0x00A8; default: BUG(); @@ -470,6 +477,7 @@ static inline u16 DISPC_ATTR_OFFSET(enum omap_plane plane) case OMAP_DSS_VIDEO2: return 0x0010; case OMAP_DSS_VIDEO3: + case OMAP_DSS_WB: return 0x0070; default: BUG(); @@ -489,6 +497,8 @@ static inline u16 DISPC_ATTR2_OFFSET(enum omap_plane plane) return 0x04DC; case OMAP_DSS_VIDEO3: return 0x032C; + case OMAP_DSS_WB: + return 0x0310; default: BUG(); return 0; @@ -504,6 +514,7 @@ static inline u16 DISPC_FIFO_THRESH_OFFSET(enum omap_plane plane) case OMAP_DSS_VIDEO2: return 0x0014; case OMAP_DSS_VIDEO3: + case OMAP_DSS_WB: return 0x008C; default: BUG(); @@ -537,6 +548,7 @@ static inline u16 DISPC_ROW_INC_OFFSET(enum omap_plane plane) case OMAP_DSS_VIDEO2: return 0x001C; case OMAP_DSS_VIDEO3: + case OMAP_DSS_WB: return 0x00A4; default: BUG(); @@ -553,6 +565,7 @@ static inline u16 DISPC_PIX_INC_OFFSET(enum omap_plane plane) case OMAP_DSS_VIDEO2: return 0x0020; case OMAP_DSS_VIDEO3: + case OMAP_DSS_WB: return 0x0098; default: BUG(); @@ -602,6 +615,7 @@ static inline u16 DISPC_FIR_OFFSET(enum omap_plane plane) case OMAP_DSS_VIDEO2: return 0x0024; case OMAP_DSS_VIDEO3: + case OMAP_DSS_WB: return 0x0090; default: BUG(); @@ -621,6 +635,8 @@ static inline u16 DISPC_FIR2_OFFSET(enum omap_plane plane) return 0x055C; case OMAP_DSS_VIDEO3: return 0x0424; + case OMAP_DSS_WB: + return 0x290; default: BUG(); return 0; @@ -637,6 +653,7 @@ static inline u16 DISPC_PIC_SIZE_OFFSET(enum omap_plane plane) case OMAP_DSS_VIDEO2: return 0x0028; case OMAP_DSS_VIDEO3: + case OMAP_DSS_WB: return 0x0094; default: BUG(); @@ -655,6 +672,7 @@ static inline u16 DISPC_ACCU0_OFFSET(enum omap_plane plane) case OMAP_DSS_VIDEO2: return 0x002C; case OMAP_DSS_VIDEO3: + case OMAP_DSS_WB: return 0x0000; default: BUG(); @@ -674,6 +692,8 @@ static inline u16 DISPC_ACCU2_0_OFFSET(enum omap_plane plane) return 0x0560; case OMAP_DSS_VIDEO3: return 0x0428; + case OMAP_DSS_WB: + return 0x0294; default: BUG(); return 0; @@ -690,6 +710,7 @@ static inline u16 DISPC_ACCU1_OFFSET(enum omap_plane plane) case OMAP_DSS_VIDEO2: return 0x0030; case OMAP_DSS_VIDEO3: + case OMAP_DSS_WB: return 0x0004; default: BUG(); @@ -709,6 +730,8 @@ static inline u16 DISPC_ACCU2_1_OFFSET(enum omap_plane plane) return 0x0564; case OMAP_DSS_VIDEO3: return 0x042C; + case OMAP_DSS_WB: + return 0x0298; default: BUG(); return 0; @@ -726,6 +749,7 @@ static inline u16 DISPC_FIR_COEF_H_OFFSET(enum omap_plane plane, u16 i) case OMAP_DSS_VIDEO2: return 0x0034 + i * 0x8; case OMAP_DSS_VIDEO3: + case OMAP_DSS_WB: return 0x0010 + i * 0x8; default: BUG(); @@ -746,6 +770,8 @@ static inline u16 DISPC_FIR_COEF_H2_OFFSET(enum omap_plane plane, u16 i) return 0x0568 + i * 0x8; case OMAP_DSS_VIDEO3: return 0x0430 + i * 0x8; + case OMAP_DSS_WB: + return 0x02A0 + i * 0x8; default: BUG(); return 0; @@ -763,6 +789,7 @@ static inline u16 DISPC_FIR_COEF_HV_OFFSET(enum omap_plane plane, u16 i) case OMAP_DSS_VIDEO2: return 0x0038 + i * 0x8; case OMAP_DSS_VIDEO3: + case OMAP_DSS_WB: return 0x0014 + i * 0x8; default: BUG(); @@ -783,6 +810,8 @@ static inline u16 DISPC_FIR_COEF_HV2_OFFSET(enum omap_plane plane, u16 i) return 0x056C + i * 0x8; case OMAP_DSS_VIDEO3: return 0x0434 + i * 0x8; + case OMAP_DSS_WB: + return 0x02A4 + i * 0x8; default: BUG(); return 0; @@ -799,6 +828,7 @@ static inline u16 DISPC_CONV_COEF_OFFSET(enum omap_plane plane, u16 i) case OMAP_DSS_VIDEO1: case OMAP_DSS_VIDEO2: case OMAP_DSS_VIDEO3: + case OMAP_DSS_WB: return 0x0074 + i * 0x4; default: BUG(); @@ -818,6 +848,7 @@ static inline u16 DISPC_FIR_COEF_V_OFFSET(enum omap_plane plane, u16 i) case OMAP_DSS_VIDEO2: return 0x00B4 + i * 0x4; case OMAP_DSS_VIDEO3: + case OMAP_DSS_WB: return 0x0050 + i * 0x4; default: BUG(); @@ -838,6 +869,8 @@ static inline u16 DISPC_FIR_COEF_V2_OFFSET(enum omap_plane plane, u16 i) return 0x05A8 + i * 0x4; case OMAP_DSS_VIDEO3: return 0x0470 + i * 0x4; + case OMAP_DSS_WB: + return 0x02E0 + i * 0x4; default: BUG(); return 0; diff --git a/drivers/video/omap2/dss/dss_features.c b/drivers/video/omap2/dss/dss_features.c index 5a5c25b134b1..acbc1e1efba3 100644 --- a/drivers/video/omap2/dss/dss_features.c +++ b/drivers/video/omap2/dss/dss_features.c @@ -46,6 +46,7 @@ struct omap_dss_features { const int num_mgrs; const int num_ovls; + const int num_wbs; const enum omap_display_type *supported_displays; const enum omap_dss_output_id *supported_outputs; const enum omap_color_mode *supported_color_modes; @@ -310,6 +311,16 @@ static const enum omap_color_mode omap4_dss_supported_color_modes[] = { OMAP_DSS_COLOR_ARGB16 | OMAP_DSS_COLOR_XRGB16_1555 | OMAP_DSS_COLOR_ARGB32 | OMAP_DSS_COLOR_RGBX16 | OMAP_DSS_COLOR_RGBX32, + + /* OMAP_DSS_WB */ + OMAP_DSS_COLOR_RGB16 | OMAP_DSS_COLOR_RGB12U | + OMAP_DSS_COLOR_YUV2 | OMAP_DSS_COLOR_ARGB16_1555 | + OMAP_DSS_COLOR_RGBA32 | OMAP_DSS_COLOR_NV12 | + OMAP_DSS_COLOR_RGBA16 | OMAP_DSS_COLOR_RGB24U | + OMAP_DSS_COLOR_RGB24P | OMAP_DSS_COLOR_UYVY | + OMAP_DSS_COLOR_ARGB16 | OMAP_DSS_COLOR_XRGB16_1555 | + OMAP_DSS_COLOR_ARGB32 | OMAP_DSS_COLOR_RGBX16 | + OMAP_DSS_COLOR_RGBX32, }; static const enum omap_overlay_caps omap2_dss_overlay_caps[] = { @@ -710,6 +721,7 @@ static const struct omap_dss_features omap4430_es1_0_dss_features = { .num_mgrs = 3, .num_ovls = 4, + .num_wbs = 1, .supported_displays = omap4_dss_supported_displays, .supported_outputs = omap4_dss_supported_outputs, .supported_color_modes = omap4_dss_supported_color_modes, @@ -731,6 +743,7 @@ static const struct omap_dss_features omap4430_es2_0_1_2_dss_features = { .num_mgrs = 3, .num_ovls = 4, + .num_wbs = 1, .supported_displays = omap4_dss_supported_displays, .supported_outputs = omap4_dss_supported_outputs, .supported_color_modes = omap4_dss_supported_color_modes, @@ -752,6 +765,7 @@ static const struct omap_dss_features omap4_dss_features = { .num_mgrs = 3, .num_ovls = 4, + .num_wbs = 1, .supported_displays = omap4_dss_supported_displays, .supported_outputs = omap4_dss_supported_outputs, .supported_color_modes = omap4_dss_supported_color_modes, @@ -829,6 +843,11 @@ int dss_feat_get_num_ovls(void) return omap_current_dss_features->num_ovls; } +int dss_feat_get_num_wbs(void) +{ + return omap_current_dss_features->num_wbs; +} + unsigned long dss_feat_get_param_min(enum dss_range_param param) { return omap_current_dss_features->dss_params[param].min; diff --git a/drivers/video/omap2/dss/dss_features.h b/drivers/video/omap2/dss/dss_features.h index 89df2aa860d4..9218113b5e88 100644 --- a/drivers/video/omap2/dss/dss_features.h +++ b/drivers/video/omap2/dss/dss_features.h @@ -105,6 +105,7 @@ enum dss_range_param { /* DSS Feature Functions */ int dss_feat_get_num_mgrs(void); int dss_feat_get_num_ovls(void); +int dss_feat_get_num_wbs(void); unsigned long dss_feat_get_param_min(enum dss_range_param param); unsigned long dss_feat_get_param_max(enum dss_range_param param); enum omap_display_type dss_feat_get_supported_displays(enum omap_channel channel); -- cgit v1.2.3 From 36d87d95587825c39ee8e127d56aafeb7dda45da Mon Sep 17 00:00:00 2001 From: Archit Taneja Date: Sat, 28 Jul 2012 22:59:03 +0530 Subject: OMAPDSS: DISPC: Configure input and output sizes for writeback Writeback uses the WB_PICTURE_SIZE register to define the size of the content written to memory, this is the output of the scaler. It uses the WB_SIZE register to define the size of the content coming from the overlay/manager to which it is connected, this is the input to the scaler. This naming is different as compared to overlays. Add checks for writeback in dispc_ovl_set_input_size() and dispc_ovl_set_output_size() to write to the correct registers. Signed-off-by: Archit Taneja --- drivers/video/omap2/dss/dispc.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers/video/omap2') diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c index b1b9e3f1be90..b9e53b3cbe05 100644 --- a/drivers/video/omap2/dss/dispc.c +++ b/drivers/video/omap2/dss/dispc.c @@ -719,7 +719,7 @@ static void dispc_ovl_set_input_size(enum omap_plane plane, int width, { u32 val = FLD_VAL(height - 1, 26, 16) | FLD_VAL(width - 1, 10, 0); - if (plane == OMAP_DSS_GFX) + if (plane == OMAP_DSS_GFX || plane == OMAP_DSS_WB) dispc_write_reg(DISPC_OVL_SIZE(plane), val); else dispc_write_reg(DISPC_OVL_PICTURE_SIZE(plane), val); @@ -734,7 +734,10 @@ static void dispc_ovl_set_output_size(enum omap_plane plane, int width, val = FLD_VAL(height - 1, 26, 16) | FLD_VAL(width - 1, 10, 0); - dispc_write_reg(DISPC_OVL_SIZE(plane), val); + if (plane == OMAP_DSS_WB) + dispc_write_reg(DISPC_OVL_PICTURE_SIZE(plane), val); + else + dispc_write_reg(DISPC_OVL_SIZE(plane), val); } static void dispc_ovl_set_zorder(enum omap_plane plane, -- cgit v1.2.3 From f92afae2af702d209ac86bdb7642edb2f10bf8f3 Mon Sep 17 00:00:00 2001 From: Archit Taneja Date: Fri, 24 Aug 2012 11:11:14 +0530 Subject: OMAPDSS: DISPC: Downscale chroma if plane is writeback When converting YUYV444 content to YUV422 or NV12 formats through writeback pipeline, the scaler needs to downscale the chroma plane. Ensure that chroma is downscaled when the pipeline is writeback. Signed-off-by: Archit Taneja --- drivers/video/omap2/dss/dispc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/video/omap2') diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c index b9e53b3cbe05..435e565a7fc5 100644 --- a/drivers/video/omap2/dss/dispc.c +++ b/drivers/video/omap2/dss/dispc.c @@ -1460,7 +1460,7 @@ static void dispc_ovl_set_scaling_uv(enum omap_plane plane, { int scale_x = out_width != orig_width; int scale_y = out_height != orig_height; - bool chroma_upscale = true; + bool chroma_upscale = plane != OMAP_DSS_WB ? true : false; if (!dss_has_feature(FEAT_HANDLE_UV_SEPARATE)) return; -- cgit v1.2.3 From 2a5561b1f7a2c12db912b0d3c5fc830817d413a9 Mon Sep 17 00:00:00 2001 From: Archit Taneja Date: Mon, 16 Jul 2012 16:37:45 +0530 Subject: OMAPDSS: DISPC: Don't set chroma resampling bit for writeback The bit YUVCHROMARESAMPLING isn't there for writeback in DISPC_WB_ATTRIBUTES2. It isn't there because we don't upsample chroma like for video pipelines, we downsample chroma in writeback to get YUV422 or NV12 formats from the YUV444 input. Ignore this bit in dispc_ovl_set_scaling_uv() if the plane is OMAP_DSS_WB. Signed-off-by: Archit Taneja --- drivers/video/omap2/dss/dispc.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'drivers/video/omap2') diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c index 435e565a7fc5..d46cf29a90aa 100644 --- a/drivers/video/omap2/dss/dispc.c +++ b/drivers/video/omap2/dss/dispc.c @@ -1468,7 +1468,8 @@ static void dispc_ovl_set_scaling_uv(enum omap_plane plane, color_mode != OMAP_DSS_COLOR_UYVY && color_mode != OMAP_DSS_COLOR_NV12)) { /* reset chroma resampling for RGB formats */ - REG_FLD_MOD(DISPC_OVL_ATTRIBUTES2(plane), 0, 8, 8); + if (plane != OMAP_DSS_WB) + REG_FLD_MOD(DISPC_OVL_ATTRIBUTES2(plane), 0, 8, 8); return; } @@ -1520,8 +1521,10 @@ static void dispc_ovl_set_scaling_uv(enum omap_plane plane, out_width, out_height, five_taps, rotation, DISPC_COLOR_COMPONENT_UV); - REG_FLD_MOD(DISPC_OVL_ATTRIBUTES2(plane), - (scale_x || scale_y) ? 1 : 0, 8, 8); + if (plane != OMAP_DSS_WB) + REG_FLD_MOD(DISPC_OVL_ATTRIBUTES2(plane), + (scale_x || scale_y) ? 1 : 0, 8, 8); + /* set H scaling */ REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), scale_x ? 1 : 0, 5, 5); /* set V scaling */ -- cgit v1.2.3 From d9ac773cd0f285c6df45ac35c52d47d8e6fa7c13 Mon Sep 17 00:00:00 2001 From: Archit Taneja Date: Sat, 22 Sep 2012 12:38:19 +0530 Subject: OMAPDSS: DISPC: Add function to set channel in for writeback Writeback can take input from either one of the overlays, or one of the overlay managers. Add an enum which represents the channel_in for writeback, and maps to the register field programming. Add a function to configure channel in for writeback. This will be used later in APPLY. Signed-off-by: Archit Taneja --- drivers/video/omap2/dss/dispc.c | 7 +++++++ drivers/video/omap2/dss/dss.h | 13 +++++++++++++ 2 files changed, 20 insertions(+) (limited to 'drivers/video/omap2') diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c index d46cf29a90aa..f0796bafa74e 100644 --- a/drivers/video/omap2/dss/dispc.c +++ b/drivers/video/omap2/dss/dispc.c @@ -983,6 +983,13 @@ static enum omap_channel dispc_ovl_get_channel_out(enum omap_plane plane) return channel; } +void dispc_wb_set_channel_in(enum dss_writeback_channel channel) +{ + enum omap_plane plane = OMAP_DSS_WB; + + REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), channel, 18, 16); +} + static void dispc_ovl_set_burst_size(enum omap_plane plane, enum omap_burst_size burst_size) { diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h index 322a2be7b4c6..379e0782eefb 100644 --- a/drivers/video/omap2/dss/dss.h +++ b/drivers/video/omap2/dss/dss.h @@ -113,6 +113,17 @@ enum dss_dsi_content_type { DSS_DSI_CONTENT_GENERIC, }; +enum dss_writeback_channel { + DSS_WB_LCD1_MGR = 0, + DSS_WB_LCD2_MGR = 1, + DSS_WB_TV_MGR = 2, + DSS_WB_OVL0 = 3, + DSS_WB_OVL1 = 4, + DSS_WB_OVL2 = 5, + DSS_WB_OVL3 = 6, + DSS_WB_LCD3_MGR = 7, +}; + struct dss_clock_info { /* rates that we get with dividers below */ unsigned long fck; @@ -475,6 +486,8 @@ int dispc_mgr_get_clock_div(enum omap_channel channel, void dispc_mgr_setup(enum omap_channel channel, struct omap_overlay_manager_info *info); +void dispc_wb_set_channel_in(enum dss_writeback_channel channel); + /* VENC */ #ifdef CONFIG_OMAP2_DSS_VENC int venc_init_platform_driver(void) __init; -- cgit v1.2.3 From 749feffa6b697c15f6016063994ca9d0ec300235 Mon Sep 17 00:00:00 2001 From: Archit Taneja Date: Fri, 31 Aug 2012 12:32:52 +0530 Subject: OMAPDSS: DISPC: Configure overlay-like parameters in dispc_wb_setup Create struct omap_dss_writeback_info, this is similar to omap_overlay_info, the major difference is that there is no parameter which describes the input size to writeback, this is because this is always fixed, and decided by the connected overlay or overlay manager. One more difference is that screen_width is renamed to buf_width, to give the value of stride the writeback buffer has. Call dispc_ovl_setup_common() through dispc_wb_setup() to configure overlay-like parameters. The parameters in dispc_ovl_setup_common() which do not hold for writeback are filled passed as zeroes or false, the code takes care of not configuring them as they won't possess the needed overlay caps. Signed-off-by: Archit Taneja --- drivers/video/omap2/dss/dispc.c | 27 +++++++++++++++++++++++++++ drivers/video/omap2/dss/dss.h | 2 ++ include/video/omapdss.h | 13 +++++++++++++ 3 files changed, 42 insertions(+) (limited to 'drivers/video/omap2') diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c index f0796bafa74e..4d8e04583873 100644 --- a/drivers/video/omap2/dss/dispc.c +++ b/drivers/video/omap2/dss/dispc.c @@ -2481,6 +2481,33 @@ int dispc_ovl_setup(enum omap_plane plane, const struct omap_overlay_info *oi, return r; } +int dispc_wb_setup(const struct omap_dss_writeback_info *wi, + const struct omap_video_timings *mgr_timings) +{ + int r; + enum omap_plane plane = OMAP_DSS_WB; + const int pos_x = 0, pos_y = 0; + const u8 zorder = 0, global_alpha = 0; + const bool replication = false; + int in_width = mgr_timings->x_res; + int in_height = mgr_timings->y_res; + enum omap_overlay_caps caps = + OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA; + + DSSDBG("dispc_wb_setup, pa %x, pa_uv %x, %d,%d -> %dx%d, cmode %x, " + "rot %d, mir %d\n", wi->paddr, wi->p_uv_addr, in_width, + in_height, wi->width, wi->height, wi->color_mode, wi->rotation, + wi->mirror); + + r = dispc_ovl_setup_common(plane, caps, wi->paddr, wi->p_uv_addr, + wi->buf_width, pos_x, pos_y, in_width, in_height, wi->width, + wi->height, wi->color_mode, wi->rotation, wi->mirror, zorder, + wi->pre_mult_alpha, global_alpha, wi->rotation_type, + replication, mgr_timings, false); + + return r; +} + int dispc_ovl_enable(enum omap_plane plane, bool enable) { DSSDBG("dispc_enable_plane %d, %d\n", plane, enable); diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h index 379e0782eefb..3f9208e88203 100644 --- a/drivers/video/omap2/dss/dss.h +++ b/drivers/video/omap2/dss/dss.h @@ -487,6 +487,8 @@ void dispc_mgr_setup(enum omap_channel channel, struct omap_overlay_manager_info *info); void dispc_wb_set_channel_in(enum dss_writeback_channel channel); +int dispc_wb_setup(const struct omap_dss_writeback_info *wi, + const struct omap_video_timings *timings); /* VENC */ #ifdef CONFIG_OMAP2_DSS_VENC diff --git a/include/video/omapdss.h b/include/video/omapdss.h index 46097bd052a2..3729173b7fbc 100644 --- a/include/video/omapdss.h +++ b/include/video/omapdss.h @@ -510,6 +510,19 @@ struct omap_dsi_pin_config { int pins[OMAP_DSS_MAX_DSI_PINS]; }; +struct omap_dss_writeback_info { + u32 paddr; + u32 p_uv_addr; + u16 buf_width; + u16 width; + u16 height; + enum omap_color_mode color_mode; + u8 rotation; + enum omap_dss_rotation_type rotation_type; + bool mirror; + u8 pre_mult_alpha; +}; + struct omap_dss_output { struct list_head list; -- cgit v1.2.3 From 9e4a0fc76549e1105fd4a2c7e03871c31110387e Mon Sep 17 00:00:00 2001 From: Archit Taneja Date: Fri, 24 Aug 2012 16:59:26 +0530 Subject: OMAPDSS: DISPC: Configure writeback specific parameters in dispc_wb_setup() Configure some of the writeback specific parameters in dispc_wb_setup(). The writeback parameters configured are: truncation: This needs to be set if the color depth input to writeback is more than the color depth of the color mode we want to store in memory. writeback mode: This configures whether we want to use writeback in mem to mem or capture mode. This information will be directly passed by APPLY later. Signed-off-by: Archit Taneja --- drivers/video/omap2/dss/dispc.c | 28 ++++++++++++++++++++++++++-- drivers/video/omap2/dss/dss.h | 2 +- 2 files changed, 27 insertions(+), 3 deletions(-) (limited to 'drivers/video/omap2') diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c index 4d8e04583873..9f083a952747 100644 --- a/drivers/video/omap2/dss/dispc.c +++ b/drivers/video/omap2/dss/dispc.c @@ -2482,13 +2482,15 @@ int dispc_ovl_setup(enum omap_plane plane, const struct omap_overlay_info *oi, } int dispc_wb_setup(const struct omap_dss_writeback_info *wi, - const struct omap_video_timings *mgr_timings) + bool mem_to_mem, const struct omap_video_timings *mgr_timings) { int r; + u32 l; enum omap_plane plane = OMAP_DSS_WB; const int pos_x = 0, pos_y = 0; const u8 zorder = 0, global_alpha = 0; const bool replication = false; + bool truncation; int in_width = mgr_timings->x_res; int in_height = mgr_timings->y_res; enum omap_overlay_caps caps = @@ -2503,7 +2505,29 @@ int dispc_wb_setup(const struct omap_dss_writeback_info *wi, wi->buf_width, pos_x, pos_y, in_width, in_height, wi->width, wi->height, wi->color_mode, wi->rotation, wi->mirror, zorder, wi->pre_mult_alpha, global_alpha, wi->rotation_type, - replication, mgr_timings, false); + replication, mgr_timings, mem_to_mem); + + switch (wi->color_mode) { + case OMAP_DSS_COLOR_RGB16: + case OMAP_DSS_COLOR_RGB24P: + case OMAP_DSS_COLOR_ARGB16: + case OMAP_DSS_COLOR_RGBA16: + case OMAP_DSS_COLOR_RGB12U: + case OMAP_DSS_COLOR_ARGB16_1555: + case OMAP_DSS_COLOR_XRGB16_1555: + case OMAP_DSS_COLOR_RGBX16: + truncation = true; + break; + default: + truncation = false; + break; + } + + /* setup extra DISPC_WB_ATTRIBUTES */ + l = dispc_read_reg(DISPC_OVL_ATTRIBUTES(plane)); + l = FLD_MOD(l, truncation, 10, 10); /* TRUNCATIONENABLE */ + l = FLD_MOD(l, mem_to_mem, 19, 19); /* WRITEBACKMODE */ + dispc_write_reg(DISPC_OVL_ATTRIBUTES(plane), l); return r; } diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h index 3f9208e88203..8677f5157318 100644 --- a/drivers/video/omap2/dss/dss.h +++ b/drivers/video/omap2/dss/dss.h @@ -488,7 +488,7 @@ void dispc_mgr_setup(enum omap_channel channel, void dispc_wb_set_channel_in(enum dss_writeback_channel channel); int dispc_wb_setup(const struct omap_dss_writeback_info *wi, - const struct omap_video_timings *timings); + bool mem_to_mem, const struct omap_video_timings *timings); /* VENC */ #ifdef CONFIG_OMAP2_DSS_VENC -- cgit v1.2.3 From 8bbe09ee4d2c3f201c302f0af75a7c5e17d72625 Mon Sep 17 00:00:00 2001 From: Archit Taneja Date: Mon, 10 Sep 2012 17:31:39 +0530 Subject: OMAPDSS: DISPC: Configure writeback FIFOs Extend the DISPC fifo functions to also configure the writeback FIFO thresholds. The most optimal configuration for writeback is to push out data to the interconnect the moment writeback pushes enough pixels in the FIFO to form a burst. This reduces the chance of writeback overflowing it's FIFO. Signed-off-by: Archit Taneja --- drivers/video/omap2/dss/dispc.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'drivers/video/omap2') diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c index 9f083a952747..6f326765f341 100644 --- a/drivers/video/omap2/dss/dispc.c +++ b/drivers/video/omap2/dss/dispc.c @@ -993,7 +993,7 @@ void dispc_wb_set_channel_in(enum dss_writeback_channel channel) static void dispc_ovl_set_burst_size(enum omap_plane plane, enum omap_burst_size burst_size) { - static const unsigned shifts[] = { 6, 14, 14, 14, }; + static const unsigned shifts[] = { 6, 14, 14, 14, 14, }; int shift; shift = shifts[plane]; @@ -1225,6 +1225,14 @@ void dispc_ovl_compute_fifo_thresholds(enum omap_plane plane, if (manual_update && dss_has_feature(FEAT_OMAP3_DSI_FIFO_BUG)) { *fifo_low = ovl_fifo_size - burst_size * 2; *fifo_high = total_fifo_size - burst_size; + } else if (plane == OMAP_DSS_WB) { + /* + * Most optimal configuration for writeback is to push out data + * to the interconnect the moment writeback pushes enough pixels + * in the FIFO to form a burst + */ + *fifo_low = 0; + *fifo_high = burst_size; } else { *fifo_low = ovl_fifo_size - burst_size; *fifo_high = total_fifo_size - buf_unit; -- cgit v1.2.3 From 0b23e5b86850857192c589f837b92e1ac568b485 Mon Sep 17 00:00:00 2001 From: Archit Taneja Date: Sat, 22 Sep 2012 12:39:33 +0530 Subject: OMAPDSS: DISPC: Add manager like functions for writeback Add functions to enable writeback, and set/check state of GO bit. These bits are identical in behaviour with the corresponding overlay manager bits. Configure them in a similar way to mgr_enable() and mgr_go_* functions. Add a helper to get the FRAMEDONE irq corresponding to writeback. Signed-off-by: Archit Taneja --- drivers/video/omap2/dss/dispc.c | 70 +++++++++++++++++++++++++++++++++++++++++ drivers/video/omap2/dss/dss.h | 5 +++ 2 files changed, 75 insertions(+) (limited to 'drivers/video/omap2') diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c index 6f326765f341..3ca9a30473d3 100644 --- a/drivers/video/omap2/dss/dispc.c +++ b/drivers/video/omap2/dss/dispc.c @@ -536,6 +536,11 @@ u32 dispc_mgr_get_framedone_irq(enum omap_channel channel) return mgr_desc[channel].framedone_irq; } +u32 dispc_wb_get_framedone_irq(void) +{ + return DISPC_IRQ_FRAMEDONEWB; +} + bool dispc_mgr_go_busy(enum omap_channel channel) { return mgr_fld_read(channel, DISPC_MGR_FLD_GO) == 1; @@ -563,6 +568,30 @@ void dispc_mgr_go(enum omap_channel channel) mgr_fld_write(channel, DISPC_MGR_FLD_GO, 1); } +bool dispc_wb_go_busy(void) +{ + return REG_GET(DISPC_CONTROL2, 6, 6) == 1; +} + +void dispc_wb_go(void) +{ + enum omap_plane plane = OMAP_DSS_WB; + bool enable, go; + + enable = REG_GET(DISPC_OVL_ATTRIBUTES(plane), 0, 0) == 1; + + if (!enable) + return; + + go = REG_GET(DISPC_CONTROL2, 6, 6) == 1; + if (go) { + DSSERR("GO bit not down for WB\n"); + return; + } + + REG_FLD_MOD(DISPC_CONTROL2, 1, 6, 6); +} + static void dispc_ovl_write_firh_reg(enum omap_plane plane, int reg, u32 value) { dispc_write_reg(DISPC_OVL_FIR_COEF_H(plane, reg), value); @@ -2692,6 +2721,47 @@ void dispc_mgr_enable(enum omap_channel channel, bool enable) BUG(); } +void dispc_wb_enable(bool enable) +{ + enum omap_plane plane = OMAP_DSS_WB; + struct completion frame_done_completion; + bool is_on; + int r; + u32 irq; + + is_on = REG_GET(DISPC_OVL_ATTRIBUTES(plane), 0, 0); + irq = DISPC_IRQ_FRAMEDONEWB; + + if (!enable && is_on) { + init_completion(&frame_done_completion); + + r = omap_dispc_register_isr(dispc_disable_isr, + &frame_done_completion, irq); + if (r) + DSSERR("failed to register FRAMEDONEWB isr\n"); + } + + REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), enable ? 1 : 0, 0, 0); + + if (!enable && is_on) { + if (!wait_for_completion_timeout(&frame_done_completion, + msecs_to_jiffies(100))) + DSSERR("timeout waiting for FRAMEDONEWB\n"); + + r = omap_dispc_unregister_isr(dispc_disable_isr, + &frame_done_completion, irq); + if (r) + DSSERR("failed to unregister FRAMEDONEWB isr\n"); + } +} + +bool dispc_wb_is_enabled(void) +{ + enum omap_plane plane = OMAP_DSS_WB; + + return REG_GET(DISPC_OVL_ATTRIBUTES(plane), 0, 0); +} + void dispc_lcd_enable_signal_polarity(bool act_high) { if (!dss_has_feature(FEAT_LCDENABLEPOL)) diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h index 8677f5157318..6728892f9dad 100644 --- a/drivers/video/omap2/dss/dss.h +++ b/drivers/video/omap2/dss/dss.h @@ -486,6 +486,11 @@ int dispc_mgr_get_clock_div(enum omap_channel channel, void dispc_mgr_setup(enum omap_channel channel, struct omap_overlay_manager_info *info); +u32 dispc_wb_get_framedone_irq(void); +bool dispc_wb_go_busy(void); +void dispc_wb_go(void); +void dispc_wb_enable(bool enable); +bool dispc_wb_is_enabled(void); void dispc_wb_set_channel_in(enum dss_writeback_channel channel); int dispc_wb_setup(const struct omap_dss_writeback_info *wi, bool mem_to_mem, const struct omap_video_timings *timings); -- cgit v1.2.3 From 6e5264b0380593efda8157406ec40f00daac9f2d Mon Sep 17 00:00:00 2001 From: Archit Taneja Date: Tue, 11 Sep 2012 12:04:47 +0530 Subject: OMAPDSS: DISPC: Configure color conversion coefficients for writeback Writeback pipeline receives RGB data from one of the overlays or one of the overlay managers. If the target color mode is YUV422 or NV12, we need to convert the RGB pixels to YUV. The scaler in WB then converts it to the target color mode. Hence, the color conversion coefficients that need to be programmed are the ones which convert a RGB24 pixel to YUV444. Program these coefficients for writeback pipeline. Rearrange the code a bit to configure different coefficients for overlays and writeback. Signed-off-by: Archit Taneja --- drivers/video/omap2/dss/dispc.c | 61 ++++++++++++++++++++++------------------- 1 file changed, 33 insertions(+), 28 deletions(-) (limited to 'drivers/video/omap2') diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c index 3ca9a30473d3..a173a9481a23 100644 --- a/drivers/video/omap2/dss/dispc.c +++ b/drivers/video/omap2/dss/dispc.c @@ -236,6 +236,11 @@ static const struct { }, }; +struct color_conv_coef { + int ry, rcr, rcb, gy, gcr, gcb, by, bcr, bcb; + int full_range; +}; + static void _omap_dispc_set_irqs(void); static unsigned long dispc_plane_pclk_rate(enum omap_plane plane); static unsigned long dispc_plane_lclk_rate(enum omap_plane plane); @@ -674,41 +679,41 @@ static void dispc_ovl_set_scale_coef(enum omap_plane plane, int fir_hinc, } } -static void _dispc_setup_color_conv_coef(void) -{ - int i; - const struct color_conv_coef { - int ry, rcr, rcb, gy, gcr, gcb, by, bcr, bcb; - int full_range; - } ctbl_bt601_5 = { - 298, 409, 0, 298, -208, -100, 298, 0, 517, 0, - }; - - const struct color_conv_coef *ct; +static void dispc_ovl_write_color_conv_coef(enum omap_plane plane, + const struct color_conv_coef *ct) +{ #define CVAL(x, y) (FLD_VAL(x, 26, 16) | FLD_VAL(y, 10, 0)) - ct = &ctbl_bt601_5; + dispc_write_reg(DISPC_OVL_CONV_COEF(plane, 0), CVAL(ct->rcr, ct->ry)); + dispc_write_reg(DISPC_OVL_CONV_COEF(plane, 1), CVAL(ct->gy, ct->rcb)); + dispc_write_reg(DISPC_OVL_CONV_COEF(plane, 2), CVAL(ct->gcb, ct->gcr)); + dispc_write_reg(DISPC_OVL_CONV_COEF(plane, 3), CVAL(ct->bcr, ct->by)); + dispc_write_reg(DISPC_OVL_CONV_COEF(plane, 4), CVAL(0, ct->bcb)); - for (i = 1; i < dss_feat_get_num_ovls(); i++) { - dispc_write_reg(DISPC_OVL_CONV_COEF(i, 0), - CVAL(ct->rcr, ct->ry)); - dispc_write_reg(DISPC_OVL_CONV_COEF(i, 1), - CVAL(ct->gy, ct->rcb)); - dispc_write_reg(DISPC_OVL_CONV_COEF(i, 2), - CVAL(ct->gcb, ct->gcr)); - dispc_write_reg(DISPC_OVL_CONV_COEF(i, 3), - CVAL(ct->bcr, ct->by)); - dispc_write_reg(DISPC_OVL_CONV_COEF(i, 4), - CVAL(0, ct->bcb)); - - REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(i), ct->full_range, - 11, 11); - } + REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), ct->full_range, 11, 11); #undef CVAL } +static void dispc_setup_color_conv_coef(void) +{ + int i; + int num_ovl = dss_feat_get_num_ovls(); + int num_wb = dss_feat_get_num_wbs(); + const struct color_conv_coef ctbl_bt601_5_ovl = { + 298, 409, 0, 298, -208, -100, 298, 0, 517, 0, + }; + const struct color_conv_coef ctbl_bt601_5_wb = { + 66, 112, -38, 129, -94, -74, 25, -18, 112, 0, + }; + + for (i = 1; i < num_ovl; i++) + dispc_ovl_write_color_conv_coef(i, &ctbl_bt601_5_ovl); + + for (; i < num_wb; i++) + dispc_ovl_write_color_conv_coef(i, &ctbl_bt601_5_wb); +} static void dispc_ovl_set_ba0(enum omap_plane plane, u32 paddr) { @@ -3975,7 +3980,7 @@ static void _omap_dispc_initial_config(void) if (dss_has_feature(FEAT_FUNCGATED)) REG_FLD_MOD(DISPC_CONFIG, 1, 9, 9); - _dispc_setup_color_conv_coef(); + dispc_setup_color_conv_coef(); dispc_set_loadmode(OMAP_DSS_LOAD_FRAME_ONLY); -- cgit v1.2.3