diff options
-rw-r--r-- | drivers/video/omap2/dss/dispc.c | 125 | ||||
-rw-r--r-- | drivers/video/omap2/dss/dss.h | 1 | ||||
-rw-r--r-- | drivers/video/omap2/dss/manager.c | 13 |
3 files changed, 84 insertions, 55 deletions
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c index ac6f483..2873063 100644 --- a/drivers/video/omap2/dss/dispc.c +++ b/drivers/video/omap2/dss/dispc.c @@ -1254,6 +1254,32 @@ void dispc_set_channel_out(enum omap_plane plane, dispc_write_reg(DISPC_OVL_ATTRIBUTES(plane), val); } +void dispc_set_wb_channel_out(enum omap_plane plane) +{ + int shift; + u32 val; + + switch (plane) { + case OMAP_DSS_GFX: + shift = 8; + break; + case OMAP_DSS_VIDEO1: + case OMAP_DSS_VIDEO2: + case OMAP_DSS_VIDEO3: + shift = 16; + break; + default: + BUG(); + return; + } + + val = dispc_read_reg(DISPC_OVL_ATTRIBUTES(plane)); + val = FLD_MOD(val, 0, shift, shift); + val = FLD_MOD(val, 3, 31, 30); + + dispc_write_reg(DISPC_OVL_ATTRIBUTES(plane), val); +} + void dispc_set_burst_size(enum omap_plane plane, enum omap_burst_size burst_size) { @@ -1697,58 +1723,61 @@ static void _dispc_set_rotation_attrs(enum omap_plane plane, u8 rotation, bool mirroring, enum omap_color_mode color_mode, enum omap_dss_rotation_type type) { - bool row_repeat = false; - int vidrot = 0; + if (plane != OMAP_DSS_WB) { + bool row_repeat = false; + int vidrot = 0; - if (color_mode == OMAP_DSS_COLOR_YUV2 || - color_mode == OMAP_DSS_COLOR_UYVY) { + if (color_mode == OMAP_DSS_COLOR_YUV2 || + color_mode == OMAP_DSS_COLOR_UYVY) { - if (mirroring) { - switch (rotation) { - case OMAP_DSS_ROT_0: - vidrot = 2; - break; - case OMAP_DSS_ROT_90: - vidrot = 1; - break; - case OMAP_DSS_ROT_180: - vidrot = 0; - break; - case OMAP_DSS_ROT_270: - vidrot = 3; - break; - } - } else { - switch (rotation) { - case OMAP_DSS_ROT_0: - vidrot = 0; - break; - case OMAP_DSS_ROT_90: - vidrot = 1; - break; - case OMAP_DSS_ROT_180: - vidrot = 2; - break; - case OMAP_DSS_ROT_270: - vidrot = 3; - break; + if (mirroring) { + switch (rotation) { + case OMAP_DSS_ROT_0: + vidrot = 2; + break; + case OMAP_DSS_ROT_90: + vidrot = 1; + break; + case OMAP_DSS_ROT_180: + vidrot = 0; + break; + case OMAP_DSS_ROT_270: + vidrot = 3; + break; + } + } else { + switch (rotation) { + case OMAP_DSS_ROT_0: + vidrot = 0; + break; + case OMAP_DSS_ROT_90: + vidrot = 1; + break; + case OMAP_DSS_ROT_180: + vidrot = 2; + break; + case OMAP_DSS_ROT_270: + vidrot = 3; + break; + } } + + if (rotation == OMAP_DSS_ROT_90 || + rotation == OMAP_DSS_ROT_270) + row_repeat = true; + else + row_repeat = false; + } else if (color_mode == OMAP_DSS_COLOR_NV12) { + /* WA for OMAP4+ UV plane overread HW bug */ + vidrot = 1; } - if (rotation == OMAP_DSS_ROT_90 || rotation == OMAP_DSS_ROT_270) - row_repeat = true; - else - row_repeat = false; - } else if (color_mode == OMAP_DSS_COLOR_NV12) { - /* WA for OMAP4+ UV plane overread HW bug */ - vidrot = 1; + REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), vidrot, 13, 12); + if (dss_has_feature(FEAT_ROWREPEATENABLE)) + REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), + row_repeat ? 1 : 0, 18, 18); } - REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), vidrot, 13, 12); - if (dss_has_feature(FEAT_ROWREPEATENABLE)) - REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), - row_repeat ? 1 : 0, 18, 18); - if (color_mode == OMAP_DSS_COLOR_NV12) { /* this will never happen for GFX */ /* 1D NV12 buffer is always non-rotated or vert. mirrored */ @@ -2693,11 +2722,11 @@ int dispc_setup_wb(struct writeback_cache_data *wb) if (OMAP_DSS_COLOR_NV12 == color_mode) { _dispc_set_plane_ba0_uv(plane, puv_addr + offset0); _dispc_set_plane_ba1_uv(plane, puv_addr + offset1); - - /* DOUBLESTRIDE */ - REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), 0x1, 22, 22); } + _dispc_set_rotation_attrs(plane, rotation, mirror, + color_mode, wb->rotation_type); + _dispc_set_row_inc(plane, row_inc); _dispc_set_pix_inc(plane, pix_inc); diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h index 61e6676..59f4a73 100644 --- a/drivers/video/omap2/dss/dss.h +++ b/drivers/video/omap2/dss/dss.h @@ -462,6 +462,7 @@ void dispc_set_plane_pos(enum omap_plane plane, u16 x, u16 y); void dispc_set_plane_size(enum omap_plane plane, u16 width, u16 height); void dispc_set_channel_out(enum omap_plane plane, enum omap_channel channel_out); +void dispc_set_wb_channel_out(enum omap_plane plane); void dispc_enable_gamma_table(bool enable); int dispc_setup_plane(enum omap_plane plane, diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c index df94c54..0bf9a0e 100644 --- a/drivers/video/omap2/dss/manager.c +++ b/drivers/video/omap2/dss/manager.c @@ -1150,9 +1150,12 @@ static int configure_overlay(enum omap_plane plane) if (plane != OMAP_DSS_GFX) _dispc_setup_color_conv_coef(plane, &c->cconv); - /* for WB source, enable plane along with WB */ if (!source_of_wb) - dispc_enable_plane(plane, 1); + dispc_set_channel_out(plane, c->channel); + else + dispc_set_wb_channel_out(plane); + + dispc_enable_plane(plane, 1); return 0; } @@ -1295,14 +1298,13 @@ static int configure_dispc(void) case OMAP_WB_VID1: case OMAP_WB_VID2: case OMAP_WB_VID3: - dispc_enable_plane(wbc->source - 3, 1); wbc->shadow_dirty = false; dispc_enable_plane(OMAP_DSS_WB, 1); break; case OMAP_WB_LCD1: case OMAP_WB_LCD2: case OMAP_WB_TV: - dispc_enable_plane(OMAP_DSS_WB, true); + dispc_enable_plane(OMAP_DSS_WB, 1); /* WB GO bit has to be used only in case of * capture mode and not in memory mode */ @@ -2091,9 +2093,6 @@ int omap_dss_wb_apply(struct omap_overlay_manager *mgr, wbc = &dss_cache.writeback_cache; if (wb && wb->info.enabled) { - /* mem2mem mode not supported as of now */ - if (wb->info.source >= OMAP_WB_GFX) - return -EINVAL; /* if source is an overlay, mode cannot be capture */ if ((wb->info.source >= OMAP_WB_GFX) && (wb->info.mode != OMAP_WB_MEM2MEM_MODE)) |