Calculate writeback specific parameters capture mode, truncation and delay count in dss_wb_calc_params(). The writeback parameters calculated are: truncation: This is 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. A helper function called wb_manual_update() is created, it returns true if we are in mem to mem mode. It will be used later again when mem to mem support is added. delay_count: This specifies the time(in lines) when the HW flushes writeback FIFOs and takes in new register configurations after the VSYNC is generated by the manager to which writeback is connected. Pass these parameters to dispc_wb_setup() so that they can be written in writeback registers. Signed-off-by: Archit Taneja <archit@xxxxxx> --- drivers/video/omap2/dss/apply.c | 15 +++++++++++++-- drivers/video/omap2/dss/dispc.c | 28 +++++++++++++++++++++------- drivers/video/omap2/dss/dss.h | 5 +++-- drivers/video/omap2/dss/writeback.c | 31 +++++++++++++++++++++++++++---- 4 files changed, 64 insertions(+), 15 deletions(-) diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c index 57b061f..b941d95 100644 --- a/drivers/video/omap2/dss/apply.c +++ b/drivers/video/omap2/dss/apply.c @@ -208,6 +208,13 @@ static bool mgr_manual_update(struct omap_overlay_manager *mgr) return dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE; } +static bool wb_manual_update(struct omap_dss_writeback *wb) +{ + struct omap_overlay_manager *mgr = wb->dssdev->manager; + + return mgr->get_display(mgr) ? false : true; +} + static int dss_check_settings_low(struct omap_overlay_manager *mgr, struct omap_dss_device *dssdev, bool applying) { @@ -662,6 +669,8 @@ static void dss_wb_write_regs(struct omap_dss_writeback *wb) struct wb_priv_data *wp = get_wb_priv(wb); struct omap_dss_writeback_info *wi; u16 in_width, in_height; + bool truncation; + int delay_count; int r; if (!wp->enabled || !wp->info_dirty) @@ -671,9 +680,11 @@ static void dss_wb_write_regs(struct omap_dss_writeback *wb) wi = &wp->info; - dss_wb_calc_params(wb, wi, &in_width, &in_height); + dss_wb_calc_params(wb, wi, &in_width, &in_height, &truncation, + &delay_count); - r = dispc_wb_setup(wb->id, wi, in_width, in_height); + r = dispc_wb_setup(wb->id, wi, in_width, in_height, + wb_manual_update(wb), truncation, delay_count); if (r) { DSSERR("dispc_wb_setup failed\n"); return; diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c index cbce120..73ba7cd 100644 --- a/drivers/video/omap2/dss/dispc.c +++ b/drivers/video/omap2/dss/dispc.c @@ -1965,29 +1965,43 @@ int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi, } int dispc_wb_setup(int id, struct omap_dss_writeback_info *wi, - u16 in_width, u16 in_height) + u16 in_width, u16 in_height, bool mem_to_mem_mode, + bool truncation, int delay_count) { int r; struct omap_dss_writeback *wb = omap_dss_get_writeback(id); + enum omap_plane plane = wb->plane_id; const int pos_x = 0, pos_y = 0; const u8 zorder = 0, global_alpha = 0; const bool chroma_upscale = false, ilace = false, replication = false; enum omap_channel channel; + u32 l; - channel = dispc_wb_get_channel_in(wb->plane_id); + channel = dispc_wb_get_channel_in(plane); DSSDBG("dispc_wb_setup %d, pa %x, pa_uv %x, %d,%d -> %dx%d, cmode %x, " - "rot %d, mir %d, chan %d\n", - wb->id, wi->paddr, wi->p_uv_addr, in_width, in_height, - wi->buf_width, wi->buf_height, wi->color_mode, wi->rotation, - wi->mirror, channel); + "rot %d, mir %d, chan %d, wb_mode %d, trunc %d, " + "delay_count %d\n", wb->id, wi->paddr, wi->p_uv_addr, in_width, + in_height, wi->buf_width, wi->buf_height, wi->color_mode, + wi->rotation, wi->mirror, channel, mem_to_mem_mode, truncation, + delay_count); - r = dispc_plane_setup(wb->plane_id, channel, wb->caps, wi->paddr, + r = dispc_plane_setup(plane, channel, wb->caps, wi->paddr, wi->p_uv_addr, in_width, pos_x, pos_y, in_width, in_height, wi->buf_width, wi->buf_height, wi->color_mode, wi->rotation, wi->mirror, zorder, wi->pre_mult_alpha, global_alpha, wi->rotation_type, chroma_upscale, ilace, replication); + /* 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_mode, 19, 19); /* WRITEBACKMODE */ + l = FLD_MOD(l, wi->capture_rate, 26, 24); /* CAPTUREMODE */ + dispc_write_reg(DISPC_OVL_ATTRIBUTES(plane), l); + + /* setup DISPC_WB_ATTRIBUTES2 */ + REG_FLD_MOD(DISPC_OVL_ATTRIBUTES2(plane), delay_count, 7, 0); + return r; } diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h index c05658b..c656aed 100644 --- a/drivers/video/omap2/dss/dss.h +++ b/drivers/video/omap2/dss/dss.h @@ -251,7 +251,7 @@ int writeback_init_display(struct omap_dss_device *dssdev); enum dss_writeback_channel_in dss_wb_calc_channel_in(struct omap_dss_writeback *wb); void dss_wb_calc_params(struct omap_dss_writeback *wb, struct omap_dss_writeback_info *wi, u16 *in_width, - u16 *in_height); + u16 *in_height, bool *truncation, int *delay_count); int dss_wb_simple_check(struct omap_dss_writeback *wb, const struct omap_dss_writeback_info *info); @@ -496,7 +496,8 @@ void dispc_mgr_setup(enum omap_channel channel, bool dispc_wb_go_busy(int id); void dispc_wb_go(int id); int dispc_wb_setup(int id, struct omap_dss_writeback_info *wi, - u16 in_width, u16 in_height); + u16 in_width, u16 in_height, bool mem_to_mem_mode, + bool truncation, int delay_count); void dispc_wb_enable(int id, bool enable); void dispc_wb_set_channel_in(int plane, enum dss_writeback_channel_in ch_in); diff --git a/drivers/video/omap2/dss/writeback.c b/drivers/video/omap2/dss/writeback.c index 7c4e9c0..82d601c 100644 --- a/drivers/video/omap2/dss/writeback.c +++ b/drivers/video/omap2/dss/writeback.c @@ -143,7 +143,7 @@ enum dss_writeback_channel_in dss_wb_calc_channel_in(struct omap_dss_writeback * void dss_wb_calc_params(struct omap_dss_writeback *wb, struct omap_dss_writeback_info *wi, u16 *in_width, - u16 *in_height) + u16 *in_height, bool *truncation, int *delay_count) { struct omap_video_timings timings; struct omap_dss_device *dssdev; @@ -152,10 +152,33 @@ void dss_wb_calc_params(struct omap_dss_writeback *wb, mgr = wb->dssdev->manager; dssdev = mgr->get_display(mgr); - dssdev->driver->get_timings(dssdev, &timings); + if (dssdev) { + /* we are in capture mode */ + dssdev->driver->get_timings(dssdev, &timings); - *in_width = timings.x_res; - *in_height = timings.y_res; + *in_width = timings.x_res; + *in_height = timings.y_res; + + /* TODO: Find more optimal values of delay_count */ + *delay_count = timings.vsw + timings.vbp + timings.vfp - 1; + *delay_count = *delay_count < 255 ? : 255; + } + + 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; + } } int dss_wb_simple_check(struct omap_dss_writeback *wb, -- 1.7.4.1 -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html