summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArchit Taneja <archit@ti.com>2010-06-03 11:21:27 +0530
committerMayuresh Janorkar <mayur@ti.com>2010-06-08 22:26:22 +0530
commit725174c1c46ca745753d5104df2c1bc331ff48bf (patch)
treea85e827d4966bdffbb1bb5fc74852cd0c215077f
parentdc626abfc3b69a3745ab03287b203e29c3deb690 (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.c4
-rw-r--r--arch/arm/plat-omap/include/plat/display.h1
-rw-r--r--drivers/media/video/omap/omap_vout.c2
-rw-r--r--drivers/video/omap2/displays/panel-taal.c65
-rw-r--r--drivers/video/omap2/dss/dsi.c24
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;