diff --git a/drivers/video/omap2/displays/panel-taal.c b/drivers/video/omap2/displays/panel-taal.c
index f5a1422..508207c 100644
--- a/drivers/video/omap2/displays/panel-taal.c
+++ b/drivers/video/omap2/displays/panel-taal.c
@@ -68,6 +68,58 @@ static irqreturn_t taal_te_isr(int irq, void *data);
 static void taal_te_timeout_work_callback(struct work_struct *work);
 static int _taal_enable_te(struct omap_dss_device *dssdev, bool enable);
 
+/**
+ * struct panel_config - panel configuration
+ * @name: panel name
+ * @type: panel type
+ * @timings: panel resolution
+ * @sleep: various panel specific delays, passed to msleep() if non-zero
+ * @reset_sequence: reset sequence timings, passed to udelay() if non-zero
+ */
+struct panel_config {
+	const char *name;
+	int type;
+
+	struct omap_video_timings timings;
+
+	struct {
+		unsigned int sleep_in;
+		unsigned int sleep_out;
+		unsigned int hw_reset;
+		unsigned int enable_te;
+	} sleep;
+
+	struct {
+		unsigned int high;
+		unsigned int low;
+	} reset_sequence;
+};
+
+enum {
+	PANEL_TAAL,
+};
+
+static struct panel_config panel_configs[] = {
+	{
+		.name		= "taal",
+		.type		= PANEL_TAAL,
+		.timings	= {
+			.x_res		= 864,
+			.y_res		= 480,
+		},
+		.sleep		= {
+			.sleep_in	= 5,
+			.sleep_out	= 5,
+			.hw_reset	= 5,
+			.enable_te	= 100, /* possible panel bug */
+		},
+		.reset_sequence	= {
+			.high		= 10,
+			.low		= 10,
+		},
+	},
+};
+
 struct taal_data {
 	struct mutex lock;
 
@@ -104,6 +156,8 @@ struct taal_data {
 
 	struct workqueue_struct *esd_wq;
 	struct delayed_work esd_work;
+
+	struct panel_config *panel_config;
 };
 
 static inline struct nokia_dsi_panel_data
@@ -173,7 +227,8 @@ static int taal_sleep_in(struct taal_data *td)
 
 	hw_guard_start(td, 120);
 
-	msleep(5);
+	if (td->panel_config->sleep.sleep_in)
+		msleep(td->panel_config->sleep.sleep_in);
 
 	return 0;
 }
@@ -190,7 +245,8 @@ static int taal_sleep_out(struct taal_data *td)
 
 	hw_guard_start(td, 120);
 
-	msleep(5);
+	if (td->panel_config->sleep.sleep_out)
+		msleep(td->panel_config->sleep.sleep_out);
 
 	return 0;
 }
@@ -509,20 +565,24 @@ static struct attribute_group taal_attr_group = {
 
 static void taal_hw_reset(struct omap_dss_device *dssdev)
 {
+	struct taal_data *td = dev_get_drvdata(&dssdev->dev);
 	struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
 
 	if (panel_data->reset_gpio == -1)
 		return;
 
 	gpio_set_value(panel_data->reset_gpio, 1);
-	udelay(10);
+	if (td->panel_config->reset_sequence.high)
+		udelay(td->panel_config->reset_sequence.high);
 	/* reset the panel */
 	gpio_set_value(panel_data->reset_gpio, 0);
-	/* assert reset for at least 10us */
-	udelay(10);
+	/* assert reset */
+	if (td->panel_config->reset_sequence.low)
+		udelay(td->panel_config->reset_sequence.low);
 	gpio_set_value(panel_data->reset_gpio, 1);
-	/* wait 5ms after releasing reset */
-	msleep(5);
+	/* wait after releasing reset */
+	if (td->panel_config->sleep.hw_reset)
+		msleep(td->panel_config->sleep.hw_reset);
 }
 
 static int taal_probe(struct omap_dss_device *dssdev)
@@ -531,12 +591,8 @@ static int taal_probe(struct omap_dss_device *dssdev)
 	struct taal_data *td;
 	struct backlight_device *bldev;
 	struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
-	int r;
-
-	const struct omap_video_timings taal_panel_timings = {
-		.x_res		= 864,
-		.y_res		= 480,
-	};
+	struct panel_config *panel_config = NULL;
+	int r, i;
 
 	dev_dbg(&dssdev->dev, "probe\n");
 
@@ -545,8 +601,20 @@ static int taal_probe(struct omap_dss_device *dssdev)
 		goto err;
 	}
 
+	for (i = 0; i < ARRAY_SIZE(panel_configs); i++) {
+		if (strcmp(panel_data->name, panel_configs[i].name) == 0) {
+			panel_config = &panel_configs[i];
+			break;
+		}
+	}
+
+	if (!panel_config) {
+		r = -EINVAL;
+		goto err;
+	}
+
 	dssdev->panel.config = OMAP_DSS_LCD_TFT;
-	dssdev->panel.timings = taal_panel_timings;
+	dssdev->panel.timings = panel_config->timings;
 	dssdev->ctrl.pixel_size = 24;
 
 	td = kzalloc(sizeof(*td), GFP_KERNEL);
@@ -555,6 +623,7 @@ static int taal_probe(struct omap_dss_device *dssdev)
 		goto err;
 	}
 	td->dssdev = dssdev;
+	td->panel_config = panel_config;
 
 	mutex_init(&td->lock);
 
@@ -687,9 +756,6 @@ static int taal_power_on(struct omap_dss_device *dssdev)
 	u8 id1, id2, id3;
 	int r;
 
-	/* it seems we have to wait a bit until taal is ready */
-	msleep(5);
-
 	r = omapdss_dsi_display_enable(dssdev);
 	if (r) {
 		dev_err(&dssdev->dev, "failed to enable DSI\n");
@@ -775,7 +841,7 @@ static void taal_power_off(struct omap_dss_device *dssdev)
 	r = taal_dcs_write_0(DCS_DISPLAY_OFF);
 	if (!r) {
 		r = taal_sleep_in(td);
-		/* wait a bit so that the message goes through */
+		/* HACK: wait a bit so that the message goes through */
 		msleep(10);
 	}
 
@@ -1051,9 +1117,8 @@ static int _taal_enable_te(struct omap_dss_device *dssdev, bool enable)
 	if (!panel_data->use_ext_te)
 		omapdss_dsi_enable_te(dssdev, enable);
 
-	/* XXX for some reason, DSI TE breaks if we don't wait here.
-	 * Panel bug? Needs more studying */
-	msleep(100);
+	if (td->panel_config->sleep.enable_te)
+		msleep(td->panel_config->sleep.enable_te);
 
 	return r;
 }
