Fill up dispc_wb_go(), dispc_wb_go_busy(), dispc_wb_enable() and dispc_wb_get_channel_in()/set_channel_in() with writeback register writes. Make a minor modification in dss_wb_write_regs_extra() to pass the plane_id instead of the writeback id when calling dispc_wb_set_channel_in(). Setup dispc_wb_enable() as dispc_enable_lcd_out() function and wait for the FRAMEDONEWB interrupt while disabling writeback. Signed-off-by: Archit Taneja <archit@xxxxxx> --- drivers/video/omap2/dss/apply.c | 2 +- drivers/video/omap2/dss/dispc.c | 68 +++++++++++++++++++++++++++++++++++---- drivers/video/omap2/dss/dss.h | 2 +- 3 files changed, 63 insertions(+), 9 deletions(-) diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c index dd1fd419..57b061f 100644 --- a/drivers/video/omap2/dss/apply.c +++ b/drivers/video/omap2/dss/apply.c @@ -690,7 +690,7 @@ static void dss_wb_write_regs_extra(struct omap_dss_writeback *wb) if (!wp->extra_info_dirty) return; - dispc_wb_set_channel_in(wb->id, wp->channel_in); + dispc_wb_set_channel_in(wb->plane_id, wp->channel_in); dispc_ovl_set_fifo_threshold(wb->plane_id, wp->fifo_low, wp->fifo_high); wp->extra_info_dirty = false; diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c index c7de56d..cbce120 100644 --- a/drivers/video/omap2/dss/dispc.c +++ b/drivers/video/omap2/dss/dispc.c @@ -510,12 +510,26 @@ void dispc_mgr_go(enum omap_channel channel) bool dispc_wb_go_busy(int id) { - return false; + return REG_GET(DISPC_CONTROL2, 6, 6) == 1; } void dispc_wb_go(int id) { - return; + struct omap_dss_writeback *wb = omap_dss_get_writeback(id); + bool enable, go; + + enable = REG_GET(DISPC_OVL_ATTRIBUTES(wb->plane_id), 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) @@ -903,16 +917,24 @@ static enum omap_channel dispc_ovl_get_channel_out(enum omap_plane plane) return channel; } -void dispc_wb_set_channel_in(int id, enum dss_writeback_channel_in ch_in) +void dispc_wb_set_channel_in(int plane, enum dss_writeback_channel_in ch_in) { - return; + REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), ch_in, 18, 16); } static enum omap_channel dispc_wb_get_channel_in(int plane) { - /* Return LCD channel for now */ + int channel_in = REG_GET(DISPC_OVL_ATTRIBUTES(plane), 18, 16); - return OMAP_DSS_CHANNEL_LCD; + switch (channel_in) { + case OMAP_DSS_WB_LCD2_MGR: + return OMAP_DSS_CHANNEL_LCD2; + case OMAP_DSS_WB_TV_MGR: + return OMAP_DSS_CHANNEL_DIGIT; + case OMAP_DSS_WB_LCD1_MGR: + default: + return OMAP_DSS_CHANNEL_LCD; + }; } static void dispc_ovl_set_burst_size(enum omap_plane plane, @@ -2138,7 +2160,39 @@ void dispc_mgr_enable(enum omap_channel channel, bool enable) void dispc_wb_enable(int id, bool enable) { - return; + struct omap_dss_writeback *wb = omap_dss_get_writeback(id); + enum omap_plane plane = wb->plane_id; + 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"); + } } void dispc_lcd_enable_signal_polarity(bool act_high) diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h index 69b4793..c05658b 100644 --- a/drivers/video/omap2/dss/dss.h +++ b/drivers/video/omap2/dss/dss.h @@ -498,7 +498,7 @@ void dispc_wb_go(int id); int dispc_wb_setup(int id, struct omap_dss_writeback_info *wi, u16 in_width, u16 in_height); void dispc_wb_enable(int id, bool enable); -void dispc_wb_set_channel_in(int id, enum dss_writeback_channel_in ch_in); +void dispc_wb_set_channel_in(int plane, enum dss_writeback_channel_in ch_in); /* VENC */ #ifdef CONFIG_OMAP2_DSS_VENC -- 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