OMAP: DSS2: Taal: Add panel hardware reset

Issue a proper reset pulse on the reset line instead of just doing power
on/off.

Signed-off-by: Jani Nikula <ext-jani.1.nikula@nokia.com>
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@nokia.com>
diff --git a/drivers/video/omap2/displays/panel-taal.c b/drivers/video/omap2/displays/panel-taal.c
index d2e2ac7..8fbb94e 100644
--- a/drivers/video/omap2/displays/panel-taal.c
+++ b/drivers/video/omap2/displays/panel-taal.c
@@ -490,6 +490,22 @@
 	.attrs = taal_attrs,
 };
 
+static void taal_hw_reset(struct omap_dss_device *dssdev)
+{
+	if (dssdev->reset_gpio == -1)
+		return;
+
+	gpio_set_value(dssdev->reset_gpio, 1);
+	udelay(10);
+	/* reset the panel */
+	gpio_set_value(dssdev->reset_gpio, 0);
+	/* assert reset for at least 10us */
+	udelay(10);
+	gpio_set_value(dssdev->reset_gpio, 1);
+	/* wait 5ms after releasing reset */
+	msleep(5);
+}
+
 static int taal_probe(struct omap_dss_device *dssdev)
 {
 	struct backlight_properties props;
@@ -527,6 +543,8 @@
 
 	dev_set_drvdata(&dssdev->dev, td);
 
+	taal_hw_reset(dssdev);
+
 	/* if no platform set_backlight() defined, presume DSI backlight
 	 * control */
 	memset(&props, 0, sizeof(struct backlight_properties));
@@ -628,6 +646,9 @@
 	cancel_delayed_work_sync(&td->esd_work);
 	destroy_workqueue(td->esd_wq);
 
+	/* reset, to be sure that the panel is in a valid state */
+	taal_hw_reset(dssdev);
+
 	kfree(td);
 }
 
@@ -654,6 +675,8 @@
 		goto err0;
 	}
 
+	taal_hw_reset(dssdev);
+
 	omapdss_dsi_vc_enable_hs(TCH, false);
 
 	r = taal_sleep_out(td);
@@ -704,6 +727,10 @@
 
 	return 0;
 err:
+	dev_err(&dssdev->dev, "error while enabling panel, issuing HW reset\n");
+
+	taal_hw_reset(dssdev);
+
 	omapdss_dsi_display_disable(dssdev);
 err0:
 	dsi_bus_unlock();
@@ -716,16 +743,24 @@
 static void taal_power_off(struct omap_dss_device *dssdev)
 {
 	struct taal_data *td = dev_get_drvdata(&dssdev->dev);
+	int r;
 
 	dsi_bus_lock();
 
 	cancel_delayed_work(&td->esd_work);
 
-	taal_dcs_write_0(DCS_DISPLAY_OFF);
-	taal_sleep_in(td);
+	r = taal_dcs_write_0(DCS_DISPLAY_OFF);
+	if (!r) {
+		r = taal_sleep_in(td);
+		/* wait a bit so that the message goes through */
+		msleep(10);
+	}
 
-	/* wait a bit so that the message goes through */
-	msleep(10);
+	if (r) {
+		dev_err(&dssdev->dev,
+				"error disabling panel, issuing HW reset\n");
+		taal_hw_reset(dssdev);
+	}
 
 	omapdss_dsi_display_disable(dssdev);
 
@@ -1186,6 +1221,7 @@
 	dev_err(&dssdev->dev, "performing LCD reset\n");
 
 	taal_power_off(dssdev);
+	taal_hw_reset(dssdev);
 	taal_power_on(dssdev);
 
 	dsi_bus_unlock();