diff options
author | Archit Taneja <archit@ti.com> | 2010-06-03 11:21:27 +0530 |
---|---|---|
committer | Mayuresh Janorkar <mayur@ti.com> | 2010-06-08 22:26:22 +0530 |
commit | 725174c1c46ca745753d5104df2c1bc331ff48bf (patch) | |
tree | a85e827d4966bdffbb1bb5fc74852cd0c215077f | |
parent | dc626abfc3b69a3745ab03287b203e29c3deb690 (diff) |
DSS2: Use external tearing in panel-taal
Signed-off-by: Archit Taneja <archit@ti.com>
-rw-r--r-- | arch/arm/mach-omap2/board-4430sdp.c | 4 | ||||
-rw-r--r-- | arch/arm/plat-omap/include/plat/display.h | 1 | ||||
-rw-r--r-- | drivers/media/video/omap/omap_vout.c | 2 | ||||
-rw-r--r-- | drivers/video/omap2/displays/panel-taal.c | 65 | ||||
-rw-r--r-- | drivers/video/omap2/dss/dsi.c | 24 |
5 files changed, 77 insertions, 19 deletions
diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c index 2b1e75db20da..d71a8767f268 100644 --- a/arch/arm/mach-omap2/board-4430sdp.c +++ b/arch/arm/mach-omap2/board-4430sdp.c @@ -390,7 +390,7 @@ static struct omap_dss_device sdp4430_lcd_device = { .data1_pol = 0, .data2_lane = 3, .data2_pol = 0, - .ext_te = false, + .ext_te = true, .ext_te_gpio = 101, .div = { .lck_div = 1, @@ -419,7 +419,7 @@ static struct omap_dss_device sdp4430_lcd2_device = { .data1_pol = 0, .data2_lane = 3, .data2_pol = 0, - .ext_te = false, + .ext_te = true, .ext_te_gpio = 103, .div = { .lck_div = 1, diff --git a/arch/arm/plat-omap/include/plat/display.h b/arch/arm/plat-omap/include/plat/display.h index 3adfb2cc6f90..c5a54458d72a 100644 --- a/arch/arm/plat-omap/include/plat/display.h +++ b/arch/arm/plat-omap/include/plat/display.h @@ -619,6 +619,7 @@ struct omap_dss_driver { int (*enable_te)(struct omap_dss_device *dssdev, bool enable); int (*get_te)(struct omap_dss_device *dssdev); + int (*wait_for_te)(struct omap_dss_device *dssdev); u8 (*get_rotate)(struct omap_dss_device *dssdev); int (*set_rotate)(struct omap_dss_device *dssdev, u8 rotate); diff --git a/drivers/media/video/omap/omap_vout.c b/drivers/media/video/omap/omap_vout.c index 8cbb0f70b409..91913a2a3f8e 100644 --- a/drivers/media/video/omap/omap_vout.c +++ b/drivers/media/video/omap/omap_vout.c @@ -2857,7 +2857,7 @@ static int __init omap_vout_probe(struct platform_device *pdev) OMAP_DSS_UPDATE_AUTO); #else /* MANUAL_UPDATE */ if (dssdrv->enable_te) - dssdrv->enable_te(def_display, 0); + dssdrv->enable_te(def_display, 1); if (dssdrv->set_update_mode) dssdrv->set_update_mode(def_display, OMAP_DSS_UPDATE_MANUAL); diff --git a/drivers/video/omap2/displays/panel-taal.c b/drivers/video/omap2/displays/panel-taal.c index 3cca04f4bd84..ec73d29a4c6e 100644 --- a/drivers/video/omap2/displays/panel-taal.c +++ b/drivers/video/omap2/displays/panel-taal.c @@ -365,6 +365,15 @@ static irqreturn_t taal_te_isr(int irq, void *data) return IRQ_HANDLED; } +static irqreturn_t taal_te_isr2(int irq, void *data) +{ + struct omap_dss_device *dssdev = data; + struct taal_data *td = dev_get_drvdata(&dssdev->dev); + complete_all(&td->te_completion); + + return IRQ_HANDLED; +} + static ssize_t taal_num_errors_show(struct device *dev, struct device_attribute *attr, char *buf) { @@ -543,6 +552,7 @@ static int taal_probe(struct omap_dss_device *dssdev) r = -ENOMEM; goto err1; } + INIT_DELAYED_WORK_DEFERRABLE(&td->esd_work, taal_esd_work); dev_set_drvdata(&dssdev->dev, td); @@ -582,6 +592,22 @@ static int taal_probe(struct omap_dss_device *dssdev) if (dssdev->phy.dsi.ext_te) { int gpio = dssdev->phy.dsi.ext_te_gpio; + void __iomem *phymux_base = NULL; + int val; + + phymux_base = ioremap(0x4A100000, 0x1000); + + if (dssdev->channel == OMAP_DSS_CHANNEL_LCD) { + val = __raw_readl(phymux_base + 0x90); + val = val & 0xFFFFFFE0; + val = val | 0x11B; + __raw_writel(val, phymux_base + 0x90); + } else { + val = __raw_readl(phymux_base + 0x94); + val = val & 0xFFFFFFE0; + val = val | 0x11B; + __raw_writel(val, phymux_base + 0x94); + } r = gpio_request(gpio, "taal irq"); if (r) { @@ -591,10 +617,15 @@ static int taal_probe(struct omap_dss_device *dssdev) gpio_direction_input(gpio); - r = request_irq(gpio_to_irq(gpio), taal_te_isr, + if (dssdev->channel == OMAP_DSS_CHANNEL_LCD) { + r = request_irq(gpio_to_irq(gpio), taal_te_isr, + IRQF_DISABLED | IRQF_TRIGGER_RISING, + "taal vsync", dssdev); + } else { + r = request_irq(gpio_to_irq(gpio), taal_te_isr2, IRQF_DISABLED | IRQF_TRIGGER_RISING, - "taal vsync", dssdev); - + "taal vsync2", dssdev); + } if (r) { dev_err(&dssdev->dev, "IRQ request failed\n"); gpio_free(gpio); @@ -604,6 +635,7 @@ static int taal_probe(struct omap_dss_device *dssdev) init_completion(&td->te_completion); td->use_ext_te = true; + iounmap(phymux_base); } r = sysfs_create_group(&dssdev->dev.kobj, &taal_attr_group); @@ -712,7 +744,7 @@ static int taal_power_on(struct omap_dss_device *dssdev) if (r) goto err; -#ifdef TAAL_USE_ESD_CHECK +#if TAAL_USE_ESD_CHECK queue_delayed_work(td->esd_wq, &td->esd_work, TAAL_ESD_CHECK_PERIOD); #endif @@ -873,6 +905,24 @@ err: return r; } +static int taal_wait_te(struct omap_dss_device *dssdev) +{ + struct taal_data *td = dev_get_drvdata(&dssdev->dev); + long wait = msecs_to_jiffies(500); + + if (!td->use_ext_te || !td->te_enabled) + return 0; + + INIT_COMPLETION(td->te_completion); + wait = wait_for_completion_timeout(&td->te_completion, wait); + if (wait == 0) { + dev_err(&dssdev->dev, "timeout waiting TE\n"); + return -ETIME; + } + + return 0; +} + static void taal_framedone_cb(int err, void *data) { struct omap_dss_device *dssdev = data; @@ -914,6 +964,9 @@ static int taal_update(struct omap_dss_device *dssdev, if (r) goto err; + if (dssdev->phy.dsi.ext_te) + dssdev->driver->wait_for_te(dssdev); + /* We use VC(1) for VideoPort Data and VC(0) for L4 data */ if (cpu_is_omap44xx()) r = omap_dsi_update(dssdev, 1, x, y, w, h, @@ -1308,7 +1361,7 @@ static struct omap_dss_driver taal_driver = { .enable_te = taal_enable_te, .get_te = taal_get_te, - + .wait_for_te = taal_wait_te, .set_rotate = taal_rotate, .get_rotate = taal_get_rotate, .set_mirror = taal_mirror, @@ -1344,7 +1397,7 @@ static struct omap_dss_driver taal2_driver = { .enable_te = taal_enable_te, .get_te = taal_get_te, - + .wait_for_te = taal_wait_te, .set_rotate = taal_rotate, .get_rotate = taal_get_rotate, .set_mirror = taal_mirror, diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index 178f0fdf2548..45f6b90e0b9d 100644 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/omap2/dss/dsi.c @@ -251,7 +251,7 @@ static struct dsi_struct struct dsi_update_region update_region; bool te_enabled; - + bool use_ext_te; struct work_struct framedone_work; void (*framedone_callback)(int, void *); void *framedone_data; @@ -2985,6 +2985,7 @@ static void dsi_update_screen_dispc(struct omap_dss_device *dssdev, struct dsi_struct *p_dsi; enum omap_dsi_index ix; unsigned channel; + bool use_te_trigger; /* line buffer is 1024 x 24bits */ /* XXX: for some reason using full buffer size causes considerable TX * slowdown with update sizes that fill the whole buffer */ @@ -2995,6 +2996,8 @@ static void dsi_update_screen_dispc(struct omap_dss_device *dssdev, channel = p_dsi->update_channel; + use_te_trigger = p_dsi->te_enabled && !p_dsi->use_ext_te; + DSSDBG("dsi_update_screen_dispc(%d,%d %dx%d)\n", x, y, w, h); @@ -3024,7 +3027,7 @@ static void dsi_update_screen_dispc(struct omap_dss_device *dssdev, dsi_vc_write_long_header(ix, channel, DSI_DT_DCS_LONG_WRITE, packet_len, 0); - if (p_dsi->te_enabled) + if (use_te_trigger) l = FLD_MOD(l, 1, 30, 30); /* TE_EN */ else l = FLD_MOD(l, 1, 31, 31); /* TE_START */ @@ -3045,7 +3048,7 @@ static void dsi_update_screen_dispc(struct omap_dss_device *dssdev, dss_start_update(dssdev); - if (p_dsi->te_enabled) { + if (use_te_trigger) { /* disable LP_RX_TO, so that we can receive TE. Time to wait * for TE is longer than the timer allows */ REG_FLD_MOD(ix, DSI_TIMING2, 0, 15, 15); /* LP_RX_TO */ @@ -3087,11 +3090,9 @@ static void dsi_framedone_timeout_work_callback(struct work_struct *work) /* SIDLEMODE back to smart-idle */ dispc_enable_sidle(); - if (cpu_is_omap44xx()) { + if (cpu_is_omap44xx()) /* Ensures recovery of DISPC after a failed lcd_enable*/ dispc_enable_lcd_out(OMAP_DSS_CHANNEL_LCD, 0); - dsi_reset_tx_fifo(DSI1, 0); - } if (dsi1.te_enabled) { /* enable LP_RX_TO again after the TE */ @@ -3135,11 +3136,9 @@ static void dsi2_framedone_timeout_work_callback(struct work_struct *work) /* SIDLEMODE back to smart-idle */ dispc_enable_sidle(); - if (cpu_is_omap44xx()) { + if (cpu_is_omap44xx()) /* Ensures recovery of DISPC after a failed lcd_enable*/ dispc_enable_lcd_out(OMAP_DSS_CHANNEL_LCD2, 0); - dsi_reset_tx_fifo(DSI2, 0); - } if (dsi2.te_enabled) { /* enable LP_RX_TO again after the TE */ @@ -3197,8 +3196,11 @@ static void dsi_handle_framedone(enum omap_dsi_index ix) int r; int channel; struct dsi_struct *p_dsi; + bool use_te_trigger; p_dsi = (ix == DSI1) ? &dsi1 : &dsi2; + use_te_trigger = p_dsi->te_enabled && !p_dsi->use_ext_te; + if (!cpu_is_omap44xx()) channel = p_dsi->update_channel; else @@ -3206,7 +3208,7 @@ static void dsi_handle_framedone(enum omap_dsi_index ix) DSSDBG("FRAMEDONE\n"); - if (p_dsi->te_enabled) { + if (use_te_trigger) { /* enable LP_RX_TO again after the TE */ REG_FLD_MOD(ix, DSI_TIMING2, 1, 15, 15); /* LP_RX_TO */ } @@ -3611,6 +3613,8 @@ int omapdss_dsi_display_enable(struct omap_dss_device *dssdev) if (r) goto err2; + p_dsi->use_ext_te = dssdev->phy.dsi.ext_te; + mutex_unlock(&p_dsi->lock); return 0; |