summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/video/mcde/display-samsung_s6d16d0.c3
-rw-r--r--drivers/video/mcde/display-sony_acx424akp_dsi.c3
-rw-r--r--drivers/video/mcde/mcde_hw.c162
-rw-r--r--include/video/mcde.h8
4 files changed, 117 insertions, 59 deletions
diff --git a/drivers/video/mcde/display-samsung_s6d16d0.c b/drivers/video/mcde/display-samsung_s6d16d0.c
index ac46a37130c..900c3f70aa6 100644
--- a/drivers/video/mcde/display-samsung_s6d16d0.c
+++ b/drivers/video/mcde/display-samsung_s6d16d0.c
@@ -170,7 +170,8 @@ static int __devinit samsung_s6d16d0_probe(struct mcde_display_device *ddev)
di->port.type = MCDE_PORTTYPE_DSI;
di->port.mode = MCDE_PORTMODE_CMD;
di->port.pixel_format = MCDE_PORTPIXFMT_DSI_24BPP;
- di->port.sync_src = MCDE_SYNCSRC_BTA;
+ di->port.sync_src = ddev->port->sync_src;
+ di->port.frame_trig = ddev->port->frame_trig;
di->port.phy.dsi.num_data_lanes = 2;
di->port.phy.dsi.host_eot_gen = true;
/* TODO: Move UI to mcde_hw.c when clk_get_rate(dsi) is done */
diff --git a/drivers/video/mcde/display-sony_acx424akp_dsi.c b/drivers/video/mcde/display-sony_acx424akp_dsi.c
index 78b1477c15c..a197f5cc1df 100644
--- a/drivers/video/mcde/display-sony_acx424akp_dsi.c
+++ b/drivers/video/mcde/display-sony_acx424akp_dsi.c
@@ -268,7 +268,8 @@ static int __devinit sony_acx424akp_probe(struct mcde_display_device *dev)
di->port.type = MCDE_PORTTYPE_DSI;
di->port.mode = MCDE_PORTMODE_CMD;
di->port.pixel_format = MCDE_PORTPIXFMT_DSI_24BPP;
- di->port.sync_src = MCDE_SYNCSRC_BTA;
+ di->port.sync_src = dev->port->sync_src;
+ di->port.frame_trig = dev->port->frame_trig;
di->port.phy.dsi.num_data_lanes = 2;
di->port.link = port->link;
di->port.phy.dsi.host_eot_gen = true;
diff --git a/drivers/video/mcde/mcde_hw.c b/drivers/video/mcde/mcde_hw.c
index 3b394106416..220b6dcb8e9 100644
--- a/drivers/video/mcde/mcde_hw.c
+++ b/drivers/video/mcde/mcde_hw.c
@@ -975,7 +975,8 @@ static void handle_dsi_irq(struct mcde_chnl_state *chnl, int i)
dsi_wreg(i, DSI_DIRECT_CMD_STS_CLR,
DSI_DIRECT_CMD_STS_CLR_TE_RECEIVED_CLR(true));
dev_vdbg(&mcde_dev->dev, "BTA TE DSI%d\n", i);
- do_softwaretrig(chnl);
+ if (chnl->port.frame_trig == MCDE_TRIG_SW)
+ do_softwaretrig(chnl);
}
irq_status = dsi_rfld(i, DSI_CMD_MODE_STS_FLAG, ERR_NO_TE_FLAG);
@@ -1984,13 +1985,94 @@ static void update_vid_frame_parameters(struct mcde_port *port,
blkline_pck - 6);
}
+static void set_vsync_method(u8 idx, struct mcde_port *port)
+{
+ u32 out_synch_src;
+ u32 src_synch;
+
+ if (port->type == MCDE_PORTTYPE_DSI) {
+ switch (port->frame_trig) {
+ case MCDE_TRIG_HW:
+ src_synch = MCDE_CHNL0SYNCHMOD_SRC_SYNCH_HARDWARE;
+ break;
+ case MCDE_TRIG_SW:
+ src_synch = MCDE_CHNL0SYNCHMOD_SRC_SYNCH_SOFTWARE;
+ break;
+ default:
+ src_synch = MCDE_CHNL0SYNCHMOD_SRC_SYNCH_HARDWARE;
+ break;
+ }
+
+ switch (port->sync_src) {
+ case MCDE_SYNCSRC_OFF:
+ out_synch_src =
+ MCDE_CHNL0SYNCHMOD_OUT_SYNCH_SRC_FORMATTER;
+ break;
+ case MCDE_SYNCSRC_TE0:
+ out_synch_src = MCDE_CHNL0SYNCHMOD_OUT_SYNCH_SRC_TE0;
+ if (src_synch ==
+ MCDE_CHNL0SYNCHMOD_SRC_SYNCH_SOFTWARE) {
+ dev_dbg(&mcde_dev->dev, "%s: badly configured "
+ "frame sync, TE0 defaulting "
+ "to hw frame trig\n", __func__);
+ src_synch =
+ MCDE_CHNL0SYNCHMOD_SRC_SYNCH_HARDWARE;
+ }
+ break;
+ case MCDE_SYNCSRC_TE1:
+ out_synch_src = MCDE_CHNL0SYNCHMOD_OUT_SYNCH_SRC_TE1;
+ if (src_synch ==
+ MCDE_CHNL0SYNCHMOD_SRC_SYNCH_SOFTWARE) {
+ dev_dbg(&mcde_dev->dev, "%s: badly configured "
+ "frame sync, TE1 defaulting "
+ "to hw frame trig\n", __func__);
+ src_synch =
+ MCDE_CHNL0SYNCHMOD_SRC_SYNCH_HARDWARE;
+ }
+ break;
+ case MCDE_SYNCSRC_BTA:
+ out_synch_src =
+ MCDE_CHNL0SYNCHMOD_OUT_SYNCH_SRC_FORMATTER;
+ break;
+ case MCDE_SYNCSRC_TE_POLLING:
+ out_synch_src =
+ MCDE_CHNL0SYNCHMOD_OUT_SYNCH_SRC_FORMATTER;
+ if (src_synch ==
+ MCDE_CHNL0SYNCHMOD_SRC_SYNCH_SOFTWARE) {
+ dev_dbg(&mcde_dev->dev, "%s: badly configured "
+ "frame sync, TE_POLLING defaulting "
+ "to hw frame trig\n", __func__);
+ src_synch =
+ MCDE_CHNL0SYNCHMOD_SRC_SYNCH_HARDWARE;
+ }
+ break;
+ default:
+ out_synch_src =
+ MCDE_CHNL0SYNCHMOD_OUT_SYNCH_SRC_FORMATTER;
+ src_synch = MCDE_CHNL0SYNCHMOD_SRC_SYNCH_HARDWARE;
+ dev_dbg(&mcde_dev->dev, "%s: no sync src selected, "
+ "defaulting to DSI BTA with "
+ "hw frame trig\n", __func__);
+ break;
+ }
+ } else if (port->type == MCDE_PORTTYPE_DPI) {
+ out_synch_src = MCDE_CHNL0SYNCHMOD_OUT_SYNCH_SRC_FORMATTER;
+ src_synch = port->update_auto_trig ?
+ MCDE_CHNL0SYNCHMOD_SRC_SYNCH_HARDWARE :
+ MCDE_CHNL0SYNCHMOD_SRC_SYNCH_SOFTWARE;
+ }
+
+ mcde_wreg(MCDE_CHNL0SYNCHMOD +
+ idx * MCDE_CHNL0SYNCHMOD_GROUPOFFSET,
+ MCDE_CHNL0SYNCHMOD_SRC_SYNCH(src_synch) |
+ MCDE_CHNL0SYNCHMOD_OUT_SYNCH_SRC(out_synch_src));
+}
+
void update_channel_registers(enum mcde_chnl chnl_id, struct chnl_regs *regs,
struct mcde_port *port, enum mcde_fifo fifo,
struct mcde_video_mode *video_mode)
{
u8 idx = chnl_id;
- u32 out_synch_src = MCDE_CHNL0SYNCHMOD_OUT_SYNCH_SRC_FORMATTER;
- u32 src_synch = MCDE_CHNL0SYNCHMOD_SRC_SYNCH_SOFTWARE;
u32 fifo_wtrmrk = 0;
dev_vdbg(&mcde_dev->dev, "%s\n", __func__);
@@ -2022,51 +2104,7 @@ void update_channel_registers(enum mcde_chnl chnl_id, struct chnl_regs *regs,
break;
}
- /* Channel */
- if (port->type == MCDE_PORTTYPE_DSI) {
- if (port->update_auto_trig) {
- switch (port->sync_src) {
- case MCDE_SYNCSRC_TE0:
- out_synch_src =
- MCDE_CHNL0SYNCHMOD_OUT_SYNCH_SRC_TE0;
- src_synch =
- MCDE_CHNL0SYNCHMOD_SRC_SYNCH_HARDWARE;
- break;
- case MCDE_SYNCSRC_OFF:
- src_synch =
- MCDE_CHNL0SYNCHMOD_SRC_SYNCH_SOFTWARE;
- break;
- case MCDE_SYNCSRC_TE1:
- default:
- out_synch_src =
- MCDE_CHNL0SYNCHMOD_OUT_SYNCH_SRC_TE1;
- src_synch =
- MCDE_CHNL0SYNCHMOD_SRC_SYNCH_HARDWARE;
- break;
- case MCDE_SYNCSRC_TE_POLLING:
- src_synch =
- MCDE_CHNL0SYNCHMOD_SRC_SYNCH_HARDWARE;
- break;
- case MCDE_SYNCSRC_FORMATTER:
- out_synch_src =
- MCDE_CHNL0SYNCHMOD_OUT_SYNCH_SRC_FORMATTER;
- src_synch =
- MCDE_CHNL0SYNCHMOD_SRC_SYNCH_HARDWARE;
- break;
- }
- } else {
- if (port->sync_src == MCDE_SYNCSRC_TE0) {
- out_synch_src =
- MCDE_CHNL0SYNCHMOD_OUT_SYNCH_SRC_TE0;
- src_synch =
- MCDE_CHNL0SYNCHMOD_SRC_SYNCH_HARDWARE;
- }
- }
- } else if (port->type == MCDE_PORTTYPE_DPI) {
- src_synch = port->update_auto_trig ?
- MCDE_CHNL0SYNCHMOD_SRC_SYNCH_HARDWARE :
- MCDE_CHNL0SYNCHMOD_SRC_SYNCH_SOFTWARE;
- }
+ set_vsync_method(idx, port);
mcde_wreg(MCDE_CHNL0CONF + idx * MCDE_CHNL0CONF_GROUPOFFSET,
MCDE_CHNL0CONF_PPL(regs->ppl-1) |
@@ -2074,10 +2112,6 @@ void update_channel_registers(enum mcde_chnl chnl_id, struct chnl_regs *regs,
mcde_wreg(MCDE_CHNL0STAT + idx * MCDE_CHNL0STAT_GROUPOFFSET,
MCDE_CHNL0STAT_CHNLBLBCKGND_EN(false) |
MCDE_CHNL0STAT_CHNLRD(true));
- mcde_wreg(MCDE_CHNL0SYNCHMOD +
- idx * MCDE_CHNL0SYNCHMOD_GROUPOFFSET,
- MCDE_CHNL0SYNCHMOD_SRC_SYNCH(src_synch) |
- MCDE_CHNL0SYNCHMOD_OUT_SYNCH_SRC(out_synch_src));
mcde_wreg(MCDE_CHNL0BCKGNDCOL + idx * MCDE_CHNL0BCKGNDCOL_GROUPOFFSET,
MCDE_CHNL0BCKGNDCOL_B(0) |
MCDE_CHNL0BCKGNDCOL_G(0) |
@@ -2807,14 +2841,30 @@ static void chnl_update_non_continous(struct mcde_chnl_state *chnl)
if (chnl->port.type == MCDE_PORTTYPE_DSI) {
if (chnl->port.sync_src == MCDE_SYNCSRC_OFF) {
- do_softwaretrig(chnl);
+ if (chnl->port.frame_trig == MCDE_TRIG_SW) {
+ do_softwaretrig(chnl);
+ } else {
+ enable_flow(chnl);
+ disable_flow(chnl);
+ }
dev_vdbg(&mcde_dev->dev, "Channel update (no sync), "
"chnl=%d\n", chnl->id);
} else if (chnl->port.sync_src == MCDE_SYNCSRC_BTA) {
- if (chnl->power_mode == MCDE_DISPLAY_PM_ON)
+ if (chnl->power_mode == MCDE_DISPLAY_PM_ON) {
dsi_te_request(chnl);
- else
- do_softwaretrig(chnl);
+ } else {
+ if (chnl->port.frame_trig == MCDE_TRIG_SW)
+ do_softwaretrig(chnl);
+ }
+ if (chnl->port.frame_trig == MCDE_TRIG_HW) {
+ /*
+ * During BTA TE the MCDE block will be stalled,
+ * once the TE is received the DMA trig will
+ * happen
+ */
+ enable_flow(chnl);
+ disable_flow(chnl);
+ }
}
}
}
diff --git a/include/video/mcde.h b/include/video/mcde.h
index 94344812f33..b9f6a6b55fd 100644
--- a/include/video/mcde.h
+++ b/include/video/mcde.h
@@ -46,7 +46,12 @@ enum mcde_sync_src {
MCDE_SYNCSRC_TE1 = 2, /* MCDE ext TE1 */
MCDE_SYNCSRC_BTA = 3, /* DSI BTA */
MCDE_SYNCSRC_TE_POLLING = 4, /* DSI TE_POLLING */
- MCDE_SYNCSRC_FORMATTER = 5, /* Sync from formatter */
+};
+
+/* Frame trig method */
+enum mcde_trig_method {
+ MCDE_TRIG_HW = 0, /* frame trig from MCDE formatter */
+ MCDE_TRIG_SW = 1, /* frame trig from software */
};
/* Interface pixel formats (output) */
@@ -118,6 +123,7 @@ struct mcde_port {
u8 ifc;
u8 link;
enum mcde_sync_src sync_src;
+ enum mcde_trig_method frame_trig;
bool update_auto_trig;
enum mcde_hdmi_sdtv_switch hdmi_sdtv_switch;
union {