summaryrefslogtreecommitdiff
path: root/drivers/video/omap2/displays/panel-taal.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video/omap2/displays/panel-taal.c')
-rw-r--r--drivers/video/omap2/displays/panel-taal.c65
1 files changed, 59 insertions, 6 deletions
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,