diff options
Diffstat (limited to 'drivers')
-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 |
3 files changed, 74 insertions, 17 deletions
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; |