diff options
author | Erik Gilling <konkers@android.com> | 2011-05-20 16:03:44 -0700 |
---|---|---|
committer | Erik Gilling <konkers@android.com> | 2011-06-13 13:45:17 -0700 |
commit | 51157eda471eb8b65a9ed9be709fd969aa497291 (patch) | |
tree | 03a27090f3e4fd10bd11df553b1574f720e723f4 | |
parent | 4195e29a1bd9e3141ccfd147386f4b4c66a4b2b2 (diff) | |
download | kernel_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.c | 16 | ||||
-rw-r--r-- | drivers/video/omap2/dss/dsi.c | 250 | ||||
-rw-r--r-- | drivers/video/omap2/dss/manager.c | 6 | ||||
-rw-r--r-- | include/video/omapdss.h | 16 |
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) |