aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorErik Gilling <konkers@android.com>2011-05-20 16:03:44 -0700
committerErik Gilling <konkers@android.com>2011-06-13 13:45:17 -0700
commit51157eda471eb8b65a9ed9be709fd969aa497291 (patch)
tree03a27090f3e4fd10bd11df553b1574f720e723f4
parent4195e29a1bd9e3141ccfd147386f4b4c66a4b2b2 (diff)
downloadkernel_samsung_tuna-51157eda471eb8b65a9ed9be709fd969aa497291.zip
kernel_samsung_tuna-51157eda471eb8b65a9ed9be709fd969aa497291.tar.gz
kernel_samsung_tuna-51157eda471eb8b65a9ed9be709fd969aa497291.tar.bz2
video: omap: add dsi video mode support
Change-Id: I318ac11fbdb57e13cc9a4d4c8f0de3212493a6ec Signed-off-by: Erik Gilling <konkers@android.com>
-rw-r--r--drivers/video/omap2/dss/dispc.c16
-rw-r--r--drivers/video/omap2/dss/dsi.c250
-rw-r--r--drivers/video/omap2/dss/manager.c6
-rw-r--r--include/video/omapdss.h16
4 files changed, 258 insertions, 30 deletions
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index 73f1105..62aa77c 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -104,6 +104,8 @@ static struct {
u32 fifo_size[3];
+ u32 channel_irq[3]; /* Max channels hardcoded to 3*/
+
spinlock_t irq_lock;
u32 irq_error_mask;
struct omap_dispc_isr_data registered_isr[DISPC_MAX_NR_ISRS];
@@ -2022,6 +2024,17 @@ static void _enable_lcd_out(enum omap_channel channel, bool enable)
REG_FLD_MOD(DISPC_CONTROL, enable ? 1 : 0, 0, 0);
}
+void omap_dispc_set_irq_type(int channel, enum omap_dispc_irq_type type)
+{
+ if (type == OMAP_DISPC_IRQ_TYPE_VSYNC) {
+ dispc.channel_irq[channel] = channel == OMAP_DSS_CHANNEL_LCD2 ?
+ DISPC_IRQ_VSYNC2 : DISPC_IRQ_VSYNC;
+ } else {
+ dispc.channel_irq[channel] = channel == OMAP_DSS_CHANNEL_LCD2 ?
+ DISPC_IRQ_FRAMEDONE2 : DISPC_IRQ_FRAMEDONE;
+ }
+}
+
static void dispc_enable_lcd_out(enum omap_channel channel, bool enable)
{
struct completion frame_done_completion;
@@ -2036,8 +2049,7 @@ static void dispc_enable_lcd_out(enum omap_channel channel, bool enable)
REG_GET(DISPC_CONTROL2, 0, 0) :
REG_GET(DISPC_CONTROL, 0, 0);
- irq = channel == OMAP_DSS_CHANNEL_LCD2 ? DISPC_IRQ_FRAMEDONE2 :
- DISPC_IRQ_FRAMEDONE;
+ irq = dispc.channel_irq[channel];
if (!enable && is_on) {
init_completion(&frame_done_completion);
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index 89c4203..716f645 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -1604,6 +1604,9 @@ int dsi_pll_set_clock_div(struct platform_device *dsidev,
l = FLD_MOD(l, 1, 13, 13); /* DSI_PLL_REFEN */
l = FLD_MOD(l, 0, 14, 14); /* DSIPHY_CLKINEN */
l = FLD_MOD(l, 1, 20, 20); /* DSI_HSDIVBYPASS */
+
+ if (cpu_is_omap44xx())
+ l = FLD_MOD(l, 3, 22, 21); /* DSI_REF_SEL */
dsi_write_reg(dsidev, DSI_PLL_CONFIGURATION2, l);
REG_FLD_MOD(dsidev, DSI_PLL_GO, 1, 0, 0); /* DSI_PLL_GO */
@@ -2058,6 +2061,10 @@ static int dsi_cio_power(struct platform_device *dsidev,
/* PWR_CMD */
REG_FLD_MOD(dsidev, DSI_COMPLEXIO_CFG1, state, 28, 27);
+ if (cpu_is_omap44xx())
+ /*bit 30 has to be set to 1 to GO in omap4*/
+ REG_FLD_MOD(dsidev, DSI_COMPLEXIO_CFG1, 1, 30, 30);
+
/* PWR_STATUS */
while (FLD_GET(dsi_read_reg(dsidev, DSI_COMPLEXIO_CFG1),
26, 25) != state) {
@@ -2418,6 +2425,13 @@ static int dsi_cio_init(struct omap_dss_device *dssdev)
if (dsi->dsi_mux_pads)
dsi->dsi_mux_pads(true);
+ if (cpu_is_omap44xx()) {
+ /* DDR_CLK_ALWAYS_ON */
+ REG_FLD_MOD(dsidev, DSI_CLK_CTRL, 1, 13, 13);
+ /* HS_AUTO_STOP_ENABLE */
+ REG_FLD_MOD(dsidev, DSI_CLK_CTRL, 1, 18, 18);
+ }
+
dsi_enable_scp_clk(dsidev);
/* A dummy read using the SCP interface to any DSIPHY register is
@@ -2764,6 +2778,8 @@ static void dsi_vc_initial_config(struct platform_device *dsidev, int channel)
r = FLD_MOD(r, 0, 9, 9); /* MODE_SPEED, high speed on/off */
if (dss_has_feature(FEAT_DSI_VC_OCP_WIDTH))
r = FLD_MOD(r, 3, 11, 10); /* OCP_WIDTH = 32 bit */
+ if (channel == 0)
+ r = FLD_MOD(r, 1, 11, 10); /* OCP_WIDTH = 32 bit */
r = FLD_MOD(r, 4, 29, 27); /* DMA_RX_REQ_NB = no dma */
r = FLD_MOD(r, 4, 23, 21); /* DMA_TX_REQ_NB = no dma */
@@ -3447,7 +3463,7 @@ err:
}
static void dsi_set_lp_rx_timeout(struct platform_device *dsidev,
- unsigned ticks, bool x4, bool x16)
+ unsigned ticks, bool x4, bool x16, bool to)
{
unsigned long fck;
unsigned long total_ticks;
@@ -3459,7 +3475,7 @@ static void dsi_set_lp_rx_timeout(struct platform_device *dsidev,
fck = dsi_fclk_rate(dsidev);
r = dsi_read_reg(dsidev, DSI_TIMING2);
- r = FLD_MOD(r, 1, 15, 15); /* LP_RX_TO */
+ r = FLD_MOD(r, to ? 1 : 0, 15, 15); /* LP_RX_TO */
r = FLD_MOD(r, x16 ? 1 : 0, 14, 14); /* LP_RX_TO_X16 */
r = FLD_MOD(r, x4 ? 1 : 0, 13, 13); /* LP_RX_TO_X4 */
r = FLD_MOD(r, ticks, 12, 0); /* LP_RX_COUNTER */
@@ -3474,7 +3490,7 @@ static void dsi_set_lp_rx_timeout(struct platform_device *dsidev,
}
static void dsi_set_ta_timeout(struct platform_device *dsidev, unsigned ticks,
- bool x8, bool x16)
+ bool x8, bool x16, bool to)
{
unsigned long fck;
unsigned long total_ticks;
@@ -3486,7 +3502,7 @@ static void dsi_set_ta_timeout(struct platform_device *dsidev, unsigned ticks,
fck = dsi_fclk_rate(dsidev);
r = dsi_read_reg(dsidev, DSI_TIMING1);
- r = FLD_MOD(r, 1, 31, 31); /* TA_TO */
+ r = FLD_MOD(r, to ? 1 : 0, 31, 31); /* TA_TO */
r = FLD_MOD(r, x16 ? 1 : 0, 30, 30); /* TA_TO_X16 */
r = FLD_MOD(r, x8 ? 1 : 0, 29, 29); /* TA_TO_X8 */
r = FLD_MOD(r, ticks, 28, 16); /* TA_TO_COUNTER */
@@ -3501,7 +3517,8 @@ static void dsi_set_ta_timeout(struct platform_device *dsidev, unsigned ticks,
}
static void dsi_set_stop_state_counter(struct platform_device *dsidev,
- unsigned ticks, bool x4, bool x16)
+ unsigned ticks, bool x4, bool x16,
+ bool stop_mode)
{
unsigned long fck;
unsigned long total_ticks;
@@ -3513,7 +3530,7 @@ static void dsi_set_stop_state_counter(struct platform_device *dsidev,
fck = dsi_fclk_rate(dsidev);
r = dsi_read_reg(dsidev, DSI_TIMING1);
- r = FLD_MOD(r, 1, 15, 15); /* FORCE_TX_STOP_MODE_IO */
+ r = FLD_MOD(r, stop_mode ? 1 : 0, 15, 15); /* FORCE_TX_STOP_MODE_IO */
r = FLD_MOD(r, x16 ? 1 : 0, 14, 14); /* STOP_STATE_X16_IO */
r = FLD_MOD(r, x4 ? 1 : 0, 13, 13); /* STOP_STATE_X4_IO */
r = FLD_MOD(r, ticks, 12, 0); /* STOP_STATE_COUNTER_IO */
@@ -3528,7 +3545,7 @@ static void dsi_set_stop_state_counter(struct platform_device *dsidev,
}
static void dsi_set_hs_tx_timeout(struct platform_device *dsidev,
- unsigned ticks, bool x4, bool x16)
+ unsigned ticks, bool x4, bool x16, bool to)
{
unsigned long fck;
unsigned long total_ticks;
@@ -3540,7 +3557,7 @@ static void dsi_set_hs_tx_timeout(struct platform_device *dsidev,
fck = dsi_get_txbyteclkhs(dsidev);
r = dsi_read_reg(dsidev, DSI_TIMING2);
- r = FLD_MOD(r, 1, 31, 31); /* HS_TX_TO */
+ r = FLD_MOD(r, to ? 1 : 0, 31, 31); /* HS_TX_TO */
r = FLD_MOD(r, x16 ? 1 : 0, 30, 30); /* HS_TX_TO_X16 */
r = FLD_MOD(r, x4 ? 1 : 0, 29, 29); /* HS_TX_TO_X8 (4 really) */
r = FLD_MOD(r, ticks, 28, 16); /* HS_TX_TO_COUNTER */
@@ -3553,7 +3570,8 @@ static void dsi_set_hs_tx_timeout(struct platform_device *dsidev,
ticks, x4 ? " x4" : "", x16 ? " x16" : "",
(total_ticks * 1000) / (fck / 1000 / 1000));
}
-static int dsi_proto_config(struct omap_dss_device *dssdev)
+
+static int dsi_cmd_proto_config(struct omap_dss_device *dssdev)
{
struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
u32 r;
@@ -3570,10 +3588,10 @@ static int dsi_proto_config(struct omap_dss_device *dssdev)
DSI_FIFO_SIZE_32);
/* XXX what values for the timeouts? */
- dsi_set_stop_state_counter(dsidev, 0x1000, false, false);
- dsi_set_ta_timeout(dsidev, 0x1fff, true, true);
- dsi_set_lp_rx_timeout(dsidev, 0x1fff, true, true);
- dsi_set_hs_tx_timeout(dsidev, 0x1fff, true, true);
+ dsi_set_stop_state_counter(dsidev, 0x1000, false, false, true);
+ dsi_set_ta_timeout(dsidev, 0x1fff, true, true, true);
+ dsi_set_lp_rx_timeout(dsidev, 0x1fff, true, true, true);
+ dsi_set_hs_tx_timeout(dsidev, 0x1fff, true, true, true);
switch (dssdev->ctrl.pixel_size) {
case 16:
@@ -3615,6 +3633,156 @@ static int dsi_proto_config(struct omap_dss_device *dssdev)
return 0;
}
+static int dispc_to_dsi_clock(int val, int bytes_per_pixel, int lanes)
+{
+ return (val * bytes_per_pixel + lanes / 2) / lanes;
+}
+static int dsi_video_proto_config(struct omap_dss_device *dssdev)
+{
+ struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+ struct omap_video_timings *timings = &dssdev->panel.timings;
+ int buswidth = 0;
+ u32 r;
+ int bytes_per_pixel;
+ int hbp, hfp, hsa, tl;
+
+ dsi_config_tx_fifo(dsidev, DSI_FIFO_SIZE_32,
+ DSI_FIFO_SIZE_32,
+ DSI_FIFO_SIZE_32,
+ DSI_FIFO_SIZE_32);
+
+ dsi_config_rx_fifo(dsidev, DSI_FIFO_SIZE_32,
+ DSI_FIFO_SIZE_32,
+ DSI_FIFO_SIZE_32,
+ DSI_FIFO_SIZE_32);
+
+ dsi_set_stop_state_counter(dsidev, 0x1fff, true, true, false);
+ dsi_set_ta_timeout(dsidev, 0x1fff, true, true, true);
+ dsi_set_lp_rx_timeout(dsidev, 0x1fff, true, true, false);
+ dsi_set_hs_tx_timeout(dsidev, 0x1fff, true, true, true);
+
+ switch (dssdev->ctrl.pixel_size) {
+ case 16:
+ buswidth = 0;
+ bytes_per_pixel = 2;
+ break;
+ case 18:
+ buswidth = 1;
+ bytes_per_pixel = 3;
+ break;
+ case 24:
+ buswidth = 2;
+ bytes_per_pixel = 3;
+ break;
+ default:
+ BUG();
+ }
+
+ r = dsi_read_reg(dsidev, DSI_CTRL);
+ r = FLD_MOD(r, 1, 3, 3); /* TX_FIFO_ARBITRATION */
+ r = FLD_MOD(r, 1, 4, 4); /* VP_CLK_RATIO, always 1, see errata*/
+ r = FLD_MOD(r, buswidth, 7, 6); /* VP_DATA_BUS_WIDTH */
+ r = FLD_MOD(r, 0, 8, 8); /* VP_CLK_POL */
+ r = FLD_MOD(r, 1, 9, 9); /* VP_DE_POL */
+ r = FLD_MOD(r, 0, 10, 10); /* VP_HSYNC_POL */
+ r = FLD_MOD(r, 1, 11, 11); /* VP_VSYNC_POL */
+ r = FLD_MOD(r, 2, 13, 12); /* LINE_BUFFER */
+ r = FLD_MOD(r, 1, 14, 14); /* TRIGGER_RESET_MODE */
+ r = FLD_MOD(r, 1, 15, 15); /* VP_VSYNC_START */
+ r = FLD_MOD(r, 1, 17, 17); /* VP_HSYNC_START */
+ r = FLD_MOD(r, 1, 19, 19); /* EOT_ENABLE */
+ r = FLD_MOD(r, 1, 21, 21); /* HFP_BLANKING */
+ r = FLD_MOD(r, 1, 22, 22); /* HBP_BLANKING */
+ r = FLD_MOD(r, 1, 23, 23); /* HSA_BLANKING */
+ dsi_write_reg(dsidev, DSI_CTRL, r);
+
+ dsi_vc_initial_config(dsidev, 0);
+ dsi_vc_initial_config(dsidev, 1);
+ dsi_vc_initial_config(dsidev, 2);
+ dsi_vc_initial_config(dsidev, 3);
+
+ hbp = dispc_to_dsi_clock(timings->hbp, bytes_per_pixel, 4);
+ hfp = dispc_to_dsi_clock(timings->hfp, bytes_per_pixel, 4);
+ hsa = dispc_to_dsi_clock(timings->hsw, bytes_per_pixel, 4);
+ tl = hbp + hfp + hsa +
+ dispc_to_dsi_clock(timings->x_res, bytes_per_pixel, 4);
+
+ r = dsi_read_reg(dsidev, DSI_VM_TIMING1);
+ r = FLD_MOD(r, hbp - 1, 11, 0); /* HBP */
+ r = FLD_MOD(r, hfp - 1, 23, 12); /* HFP */
+ r = FLD_MOD(r, hsa - 1, 31, 24); /* HSA */
+ dsi_write_reg(dsidev, DSI_VM_TIMING1, r);
+
+ r = dsi_read_reg(dsidev, DSI_VM_TIMING2);
+ r = FLD_MOD(r, timings->vbp, 7, 0); /* VBP */
+ r = FLD_MOD(r, timings->vfp, 15, 8); /* VFP */
+ r = FLD_MOD(r, timings->vsw, 23, 16); /* VSA */
+ r = FLD_MOD(r, 4, 27, 24); /* WINDOW_SYNC */
+ dsi_write_reg(dsidev, DSI_VM_TIMING2, r);
+
+ r = dsi_read_reg(dsidev, DSI_VM_TIMING3);
+ r = FLD_MOD(r, timings->y_res, 14, 0);
+ r = FLD_MOD(r, tl - 1, 31, 16);
+ dsi_write_reg(dsidev, DSI_VM_TIMING3, r);
+
+ /* TODO: either calculate these values or make them configurable */
+ r = FLD_VAL(72, 23, 16) | /* HSA_HS_INTERLEAVING */
+ FLD_VAL(114, 15, 8) | /* HFB_HS_INTERLEAVING */
+ FLD_VAL(150, 7, 0); /* HbB_HS_INTERLEAVING */
+ dsi_write_reg(dsidev, DSI_VM_TIMING4, r);
+
+ r = FLD_VAL(130, 23, 16) | /* HSA_LP_INTERLEAVING */
+ FLD_VAL(223, 15, 8) | /* HFB_LP_INTERLEAVING */
+ FLD_VAL(59, 7, 0); /* HBB_LP_INTERLEAVING */
+ dsi_write_reg(dsidev, DSI_VM_TIMING5, r);
+
+ r = FLD_VAL(0x7A67, 31, 16) | /* BL_HS_INTERLEAVING */
+ FLD_VAL(0x31D1, 15, 0); /* BL_LP_INTERLEAVING */
+ dsi_write_reg(dsidev, DSI_VM_TIMING6, r);
+
+ r = FLD_VAL(18, 31, 16) | /* ENTER_HS_MODE_LATENCY */
+ FLD_VAL(15, 15, 0); /* EXIT_HS_MODE_LATENCY */
+ dsi_write_reg(dsidev, DSI_VM_TIMING7, r);
+
+ return 0;
+}
+
+int dsi_video_mode_enable(struct omap_dss_device *dssdev, u8 data_type)
+{
+ struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+ u16 word_count;
+ u32 r;
+ u32 header;
+
+ dsi_if_enable(dsidev, 0);
+ dsi_vc_enable(dsidev, 1, 0);
+ dsi_vc_enable(dsidev, 0, 0);
+
+ r = dsi_read_reg(dsidev, DSI_TIMING1);
+ r = FLD_MOD(r, 1, 15, 15); /* FORCE_TX_STOP_MODE_IO */
+ dsi_write_reg(dsidev, DSI_TIMING1, r);
+
+ if (wait_for_bit_change(dsidev, DSI_PLL_STATUS, 15, 0) != 0)
+ BUG();
+
+ r = dsi_read_reg(dsidev, DSI_VC_CTRL(0));
+ r = FLD_MOD(r, 1, 4, 4);
+ r = FLD_MOD(r, 1, 9, 9);
+ dsi_write_reg(dsidev, DSI_VC_CTRL(0), r);
+
+ word_count = dssdev->panel.timings.x_res * 3;
+ header = FLD_VAL(0, 31, 24) | /* ECC */
+ FLD_VAL(word_count, 23, 8) | /* WORD_COUNT */
+ FLD_VAL(0, 7, 6) | /* VC_ID */
+ FLD_VAL(data_type, 5, 0);
+ dsi_write_reg(dsidev, DSI_VC_LONG_PACKET_HEADER(0), header);
+
+ dsi_vc_enable(dsidev, 0, 1);
+ dsi_if_enable(dsidev, 1);
+
+ return 0;
+}
+
static void dsi_proto_timings(struct omap_dss_device *dssdev)
{
struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
@@ -3853,6 +4021,11 @@ static void dsi_update_screen_dispc(struct omap_dss_device *dssdev,
DSSDBG("dsi_update_screen_dispc(%d,%d %dx%d)\n",
x, y, w, h);
+ if (dssdev->phy.dsi.type == OMAP_DSS_DSI_TYPE_VIDEO_MODE) {
+ dss_start_update(dssdev);
+ return;
+ }
+
dsi_vc_config_vp(dsidev, channel);
bytespp = dssdev->ctrl.pixel_size / 8;
@@ -4063,23 +4236,30 @@ static int dsi_display_init_dispc(struct omap_dss_device *dssdev)
irq = dssdev->manager->id == OMAP_DSS_CHANNEL_LCD ?
DISPC_IRQ_FRAMEDONE : DISPC_IRQ_FRAMEDONE2;
- r = omap_dispc_register_isr(dsi_framedone_irq_callback, (void *) dssdev,
- irq);
- if (r) {
- DSSERR("can't get FRAMEDONE irq\n");
- return r;
+ if (dssdev->phy.dsi.type == OMAP_DSS_DSI_TYPE_CMD_MODE) {
+ r = omap_dispc_register_isr(dsi_framedone_irq_callback, (void *) dssdev,
+ DISPC_IRQ_FRAMEDONE);
+ if (r) {
+ DSSERR("can't get FRAMEDONE irq\n");
+ return r;
+ }
+
+ dispc_set_parallel_interface_mode(dssdev->manager->id,
+ OMAP_DSS_PARALLELMODE_DSI);
+ dispc_enable_fifohandcheck(dssdev->manager->id, 1);
+ } else {
+ dispc_set_parallel_interface_mode(dssdev->manager->id,
+ OMAP_DSS_PARALLELMODE_BYPASS);
+ dispc_enable_fifohandcheck(dssdev->manager->id, 0);
}
dispc_set_lcd_display_type(dssdev->manager->id,
OMAP_DSS_LCD_DISPLAY_TFT);
- dispc_set_parallel_interface_mode(dssdev->manager->id,
- OMAP_DSS_PARALLELMODE_DSI);
- dispc_enable_fifohandcheck(dssdev->manager->id, 1);
dispc_set_tft_data_lines(dssdev->manager->id, dssdev->ctrl.pixel_size);
- {
+ if(dssdev->phy.dsi.type == OMAP_DSS_DSI_TYPE_CMD_MODE) {
struct omap_video_timings timings = {
.hsw = 1,
.hfp = 1,
@@ -4090,6 +4270,9 @@ static int dsi_display_init_dispc(struct omap_dss_device *dssdev)
};
dispc_set_lcd_timings(dssdev->manager->id, &timings);
+ } else {
+ dispc_set_lcd_timings(dssdev->manager->id,
+ &dssdev->panel.timings);
}
return 0;
@@ -4102,8 +4285,9 @@ static void dsi_display_uninit_dispc(struct omap_dss_device *dssdev)
irq = dssdev->manager->id == OMAP_DSS_CHANNEL_LCD ?
DISPC_IRQ_FRAMEDONE : DISPC_IRQ_FRAMEDONE2;
- omap_dispc_unregister_isr(dsi_framedone_irq_callback, (void *) dssdev,
- irq);
+ if(dssdev->phy.dsi.type == OMAP_DSS_DSI_TYPE_CMD_MODE)
+ omap_dispc_unregister_isr(dsi_framedone_irq_callback, (void *) dssdev,
+ irq);
}
static int dsi_configure_dsi_clocks(struct omap_dss_device *dssdev)
@@ -4166,7 +4350,12 @@ static int dsi_display_init_dsi(struct omap_dss_device *dssdev)
int dsi_module = dsi_get_dsidev_id(dsidev);
int r;
+ /* The SCPClk is required for PLL and complexio registers on OMAP4 */
+ if (cpu_is_omap44xx())
+ REG_FLD_MOD(dsidev, DSI_CLK_CTRL, 1, 14, 14);
+
r = dsi_pll_init(dsidev, true, true);
+
if (r)
goto err0;
@@ -4197,7 +4386,11 @@ static int dsi_display_init_dsi(struct omap_dss_device *dssdev)
if (1)
_dsi_print_reset_status(dsidev);
- r = dsi_proto_config(dssdev);
+ if(dssdev->phy.dsi.type == OMAP_DSS_DSI_TYPE_CMD_MODE)
+ r = dsi_cmd_proto_config(dssdev);
+ else
+ r = dsi_video_proto_config(dssdev);
+
if (r)
goto err3;
@@ -4352,9 +4545,12 @@ int dsi_init_display(struct omap_dss_device *dssdev)
DSSDBG("DSI init\n");
- /* XXX these should be figured out dynamically */
- dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE |
+ if(dssdev->phy.dsi.type == OMAP_DSS_DSI_TYPE_CMD_MODE) {
+ dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE |
OMAP_DSS_DISPLAY_CAP_TEAR_ELIM;
+ } else {
+ dssdev->caps = 0;
+ }
if (dsi->vdds_dsi_reg == NULL) {
struct regulator *vdds_dsi;
diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c
index a148a80..b1126b6 100644
--- a/drivers/video/omap2/dss/manager.c
+++ b/drivers/video/omap2/dss/manager.c
@@ -492,6 +492,12 @@ static int omap_dss_set_device(struct omap_overlay_manager *mgr,
mgr->device = dssdev;
mgr->device_changed = true;
+ if (dssdev->type == OMAP_DISPLAY_TYPE_DSI &&
+ !(dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE))
+ omap_dispc_set_irq_type(mgr->id, OMAP_DISPC_IRQ_TYPE_VSYNC);
+ else
+ omap_dispc_set_irq_type(mgr->id, OMAP_DISPC_IRQ_TYPE_FRAMEDONE);
+
return 0;
}
diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index 06914b1..25fc1f3 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -124,6 +124,11 @@ enum omap_panel_config {
OMAP_DSS_LCD_TFT = 1<<20,
};
+enum omap_dss_dsi_type {
+ OMAP_DSS_DSI_TYPE_CMD_MODE = 0,
+ OMAP_DSS_DSI_TYPE_VIDEO_MODE,
+};
+
enum omap_dss_venc_type {
OMAP_DSS_VENC_TYPE_COMPOSITE,
OMAP_DSS_VENC_TYPE_SVIDEO,
@@ -146,6 +151,11 @@ enum omap_dss_display_state {
OMAP_DSS_DISPLAY_SUSPENDED,
};
+enum omap_dispc_irq_type {
+ OMAP_DISPC_IRQ_TYPE_FRAMEDONE,
+ OMAP_DISPC_IRQ_TYPE_VSYNC,
+};
+
/* XXX perhaps this should be removed */
enum omap_dss_overlay_managers {
OMAP_DSS_OVL_MGR_LCD,
@@ -242,6 +252,8 @@ int dsi_vc_set_max_rx_packet_size(struct omap_dss_device *dssdev, int channel,
int dsi_vc_send_null(struct omap_dss_device *dssdev, int channel);
int dsi_vc_send_bta_sync(struct omap_dss_device *dssdev, int channel);
+int dsi_video_mode_enable(struct omap_dss_device *dssdev, u8 data_type);
+
/* Board specific data */
struct omap_dss_board_info {
int (*get_context_loss_count)(struct device *dev);
@@ -416,6 +428,7 @@ struct omap_dss_device {
} sdi;
struct {
+ enum omap_dss_dsi_type type;
u8 clk_lane;
u8 clk_pol;
u8 data1_lane;
@@ -426,7 +439,6 @@ struct omap_dss_device {
u8 data3_pol;
u8 data4_lane;
u8 data4_pol;
-
int module;
bool ext_te;
@@ -592,6 +604,8 @@ int omap_dispc_wait_for_irq_timeout(u32 irqmask, unsigned long timeout);
int omap_dispc_wait_for_irq_interruptible_timeout(u32 irqmask,
unsigned long timeout);
+void omap_dispc_set_irq_type(int channel, enum omap_dispc_irq_type type);
+
#define to_dss_driver(x) container_of((x), struct omap_dss_driver, driver)
#define to_dss_device(x) container_of((x), struct omap_dss_device, dev)