Linux Framebuffer Layer development
 help / color / mirror / Atom feed
* [PATCH 11/23] OMAPDSS: DSI: Remove dsi_pdev_map global struct
From: Archit Taneja @ 2012-08-21  6:10 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, rob, sumit.semwal, Archit Taneja
In-Reply-To: <1345528711-27801-1-git-send-email-archit@ti.com>

dsi_pdev_map is a struct visible globally in the DSI driver to get the platform
device pointer of the DSI device corresponding to it's module ID. This was
required because there was no clean way to derive the platform device from
the DSI module instance number or from the connected panel.

With the new output entity, it is possible to retrieve the platform device
pointer if the omap_dss_output pointer is available. Modify the functions
dsi_get_dsidev_from_dssdev() dsi_get_dsidev_from_id() so that they use output
instead of dsi_pdev_map to retrieve the dsi platform device pointer.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/dss/dsi.c |   14 +++++++++-----
 1 file changed, 9 insertions(+), 5 deletions(-)

diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index 22e0873..19a4d4d 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -344,8 +344,6 @@ struct dsi_packet_sent_handler_data {
 	struct completion *completion;
 };
 
-static struct platform_device *dsi_pdev_map[MAX_NUM_DSI];
-
 #ifdef DEBUG
 static bool dsi_perf;
 module_param(dsi_perf, bool, 0644);
@@ -358,12 +356,19 @@ static inline struct dsi_data *dsi_get_dsidrv_data(struct platform_device *dside
 
 static inline struct platform_device *dsi_get_dsidev_from_dssdev(struct omap_dss_device *dssdev)
 {
-	return dsi_pdev_map[dssdev->phy.dsi.module];
+	return dssdev->output->pdev;
 }
 
 struct platform_device *dsi_get_dsidev_from_id(int module)
 {
-	return dsi_pdev_map[module];
+	struct omap_dss_output *out;
+	enum omap_dss_output_id	id;
+
+	id = module = 0 ? OMAP_DSS_OUTPUT_DSI1 : OMAP_DSS_OUTPUT_DSI2;
+
+	out = omap_dss_get_output(id);
+
+	return out->pdev;
 }
 
 static inline void dsi_write_reg(struct platform_device *dsidev,
@@ -4934,7 +4939,6 @@ static int __init omap_dsihw_probe(struct platform_device *dsidev)
 
 	dsi->module_id = dsidev->id;
 	dsi->pdev = dsidev;
-	dsi_pdev_map[dsi->module_id] = dsidev;
 	dev_set_drvdata(&dsidev->dev, dsi);
 
 	spin_lock_init(&dsi->irq_lock);
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH 12/23] OMAPDSS: DSI: Pass outputs from panel driver to DSI interface driver
From: Archit Taneja @ 2012-08-21  6:10 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, rob, sumit.semwal, Archit Taneja
In-Reply-To: <1345528711-27801-1-git-send-email-archit@ti.com>

With outputs introduces as new entities, we can now pass output pointer to
functions used to configure the connected interface. These functions currently
pass the omap_dss_device pointer, and extract output information via
omap_dss_device. This is unnecessary, and it doesn't make sense for interface
related functions to get the panel's/device's pointer, it should receive a
pointer related to the connected interface, which in our case is the output
entity.

With the addition of outputs. There is a possibility that an omap_dss_device
isn't connected to an output yet. Ensure that panel drivers call the interface
functions only if outputs are non NULL.

Modify DSI functions to pass omap_dss_output pointer instead of omap_dss_device
pointer. Modify the panel drivers to call the updated functions.

There is a lack of clarity about how to deal with functions called in the probe
of panel drivers. For the case of DSI, it's the functions which request for a
VC. There is no guarantee in the panel's probe that it would be connected to an
output. Another panel of higher priority may have already grabbed this
interface.

Interface specific functions should either be removed from the panel's probe and
be called later, or, we should figure out a better way to deal with this. We
currently don't face the above issue on any platform, but it's possible for
sure.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/displays/panel-taal.c |  201 ++++++++++++---------
 drivers/video/omap2/dss/dsi.c             |  269 +++++++++++++++--------------
 include/video/omapdss.h                   |   69 ++++----
 3 files changed, 296 insertions(+), 243 deletions(-)

diff --git a/drivers/video/omap2/displays/panel-taal.c b/drivers/video/omap2/displays/panel-taal.c
index 77aed0e..cd88145 100644
--- a/drivers/video/omap2/displays/panel-taal.c
+++ b/drivers/video/omap2/displays/panel-taal.c
@@ -176,10 +176,11 @@ static void hw_guard_wait(struct taal_data *td)
 
 static int taal_dcs_read_1(struct taal_data *td, u8 dcs_cmd, u8 *data)
 {
+	struct omap_dss_output *out = td->dssdev->output;
 	int r;
 	u8 buf[1];
 
-	r = dsi_vc_dcs_read(td->dssdev, td->channel, dcs_cmd, buf, 1);
+	r = dsi_vc_dcs_read(out, td->channel, dcs_cmd, buf, 1);
 
 	if (r < 0)
 		return r;
@@ -191,27 +192,33 @@ static int taal_dcs_read_1(struct taal_data *td, u8 dcs_cmd, u8 *data)
 
 static int taal_dcs_write_0(struct taal_data *td, u8 dcs_cmd)
 {
-	return dsi_vc_dcs_write(td->dssdev, td->channel, &dcs_cmd, 1);
+	struct omap_dss_output *out = td->dssdev->output;
+
+	return dsi_vc_dcs_write(out, td->channel, &dcs_cmd, 1);
 }
 
 static int taal_dcs_write_1(struct taal_data *td, u8 dcs_cmd, u8 param)
 {
+	struct omap_dss_output *out = td->dssdev->output;
 	u8 buf[2];
+
 	buf[0] = dcs_cmd;
 	buf[1] = param;
-	return dsi_vc_dcs_write(td->dssdev, td->channel, buf, 2);
+
+	return dsi_vc_dcs_write(out, td->channel, buf, 2);
 }
 
 static int taal_sleep_in(struct taal_data *td)
 
 {
+	struct omap_dss_output *out = td->dssdev->output;
 	u8 cmd;
 	int r;
 
 	hw_guard_wait(td);
 
 	cmd = MIPI_DCS_ENTER_SLEEP_MODE;
-	r = dsi_vc_dcs_write_nosync(td->dssdev, td->channel, &cmd, 1);
+	r = dsi_vc_dcs_write_nosync(out, td->channel, &cmd, 1);
 	if (r)
 		return r;
 
@@ -304,6 +311,7 @@ static int taal_set_addr_mode(struct taal_data *td, u8 rotate, bool mirror)
 static int taal_set_update_window(struct taal_data *td,
 		u16 x, u16 y, u16 w, u16 h)
 {
+	struct omap_dss_output *out = td->dssdev->output;
 	int r;
 	u16 x1 = x;
 	u16 x2 = x + w - 1;
@@ -317,7 +325,7 @@ static int taal_set_update_window(struct taal_data *td,
 	buf[3] = (x2 >> 8) & 0xff;
 	buf[4] = (x2 >> 0) & 0xff;
 
-	r = dsi_vc_dcs_write_nosync(td->dssdev, td->channel, buf, sizeof(buf));
+	r = dsi_vc_dcs_write_nosync(out, td->channel, buf, sizeof(buf));
 	if (r)
 		return r;
 
@@ -327,11 +335,11 @@ static int taal_set_update_window(struct taal_data *td,
 	buf[3] = (y2 >> 8) & 0xff;
 	buf[4] = (y2 >> 0) & 0xff;
 
-	r = dsi_vc_dcs_write_nosync(td->dssdev, td->channel, buf, sizeof(buf));
+	r = dsi_vc_dcs_write_nosync(out, td->channel, buf, sizeof(buf));
 	if (r)
 		return r;
 
-	dsi_vc_send_bta_sync(td->dssdev, td->channel);
+	dsi_vc_send_bta_sync(out, td->channel);
 
 	return r;
 }
@@ -371,6 +379,7 @@ static void taal_cancel_ulps_work(struct omap_dss_device *dssdev)
 static int taal_enter_ulps(struct omap_dss_device *dssdev)
 {
 	struct taal_data *td = dev_get_drvdata(&dssdev->dev);
+	struct omap_dss_output *out = dssdev->output;
 	struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
 	int r;
 
@@ -385,7 +394,7 @@ static int taal_enter_ulps(struct omap_dss_device *dssdev)
 
 	disable_irq(gpio_to_irq(panel_data->ext_te_gpio));
 
-	omapdss_dsi_display_disable(dssdev, false, true);
+	omapdss_dsi_display_disable(out, false, true);
 
 	td->ulps_enabled = true;
 
@@ -405,19 +414,20 @@ err:
 static int taal_exit_ulps(struct omap_dss_device *dssdev)
 {
 	struct taal_data *td = dev_get_drvdata(&dssdev->dev);
+	struct omap_dss_output *out = dssdev->output;
 	struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
 	int r;
 
 	if (!td->ulps_enabled)
 		return 0;
 
-	r = omapdss_dsi_display_enable(dssdev);
+	r = omapdss_dsi_display_enable(out);
 	if (r) {
 		dev_err(&dssdev->dev, "failed to enable DSI\n");
 		goto err1;
 	}
 
-	omapdss_dsi_vc_enable_hs(dssdev, td->channel, true);
+	omapdss_dsi_vc_enable_hs(out, td->channel, true);
 
 	r = _taal_enable_te(dssdev, true);
 	if (r) {
@@ -462,6 +472,7 @@ static int taal_wake_up(struct omap_dss_device *dssdev)
 static int taal_bl_update_status(struct backlight_device *dev)
 {
 	struct omap_dss_device *dssdev = dev_get_drvdata(&dev->dev);
+	struct omap_dss_output *out = dssdev->output;
 	struct taal_data *td = dev_get_drvdata(&dssdev->dev);
 	int r;
 	int level;
@@ -477,13 +488,13 @@ static int taal_bl_update_status(struct backlight_device *dev)
 	mutex_lock(&td->lock);
 
 	if (td->enabled) {
-		dsi_bus_lock(dssdev);
+		dsi_bus_lock(out);
 
 		r = taal_wake_up(dssdev);
 		if (!r)
 			r = taal_dcs_write_1(td, DCS_BRIGHTNESS, level);
 
-		dsi_bus_unlock(dssdev);
+		dsi_bus_unlock(out);
 	} else {
 		r = 0;
 	}
@@ -525,6 +536,7 @@ static ssize_t taal_num_errors_show(struct device *dev,
 		struct device_attribute *attr, char *buf)
 {
 	struct omap_dss_device *dssdev = to_dss_device(dev);
+	struct omap_dss_output *out = dssdev->output;
 	struct taal_data *td = dev_get_drvdata(&dssdev->dev);
 	u8 errors = 0;
 	int r;
@@ -532,13 +544,13 @@ static ssize_t taal_num_errors_show(struct device *dev,
 	mutex_lock(&td->lock);
 
 	if (td->enabled) {
-		dsi_bus_lock(dssdev);
+		dsi_bus_lock(out);
 
 		r = taal_wake_up(dssdev);
 		if (!r)
 			r = taal_dcs_read_1(td, DCS_READ_NUM_ERRORS, &errors);
 
-		dsi_bus_unlock(dssdev);
+		dsi_bus_unlock(out);
 	} else {
 		r = -ENODEV;
 	}
@@ -555,6 +567,7 @@ static ssize_t taal_hw_revision_show(struct device *dev,
 		struct device_attribute *attr, char *buf)
 {
 	struct omap_dss_device *dssdev = to_dss_device(dev);
+	struct omap_dss_output *out = dssdev->output;
 	struct taal_data *td = dev_get_drvdata(&dssdev->dev);
 	u8 id1, id2, id3;
 	int r;
@@ -562,13 +575,13 @@ static ssize_t taal_hw_revision_show(struct device *dev,
 	mutex_lock(&td->lock);
 
 	if (td->enabled) {
-		dsi_bus_lock(dssdev);
+		dsi_bus_lock(out);
 
 		r = taal_wake_up(dssdev);
 		if (!r)
 			r = taal_get_id(td, &id1, &id2, &id3);
 
-		dsi_bus_unlock(dssdev);
+		dsi_bus_unlock(out);
 	} else {
 		r = -ENODEV;
 	}
@@ -613,6 +626,7 @@ static ssize_t store_cabc_mode(struct device *dev,
 		const char *buf, size_t count)
 {
 	struct omap_dss_device *dssdev = to_dss_device(dev);
+	struct omap_dss_output *out = dssdev->output;
 	struct taal_data *td = dev_get_drvdata(&dssdev->dev);
 	int i;
 	int r;
@@ -628,7 +642,7 @@ static ssize_t store_cabc_mode(struct device *dev,
 	mutex_lock(&td->lock);
 
 	if (td->enabled) {
-		dsi_bus_lock(dssdev);
+		dsi_bus_lock(out);
 
 		if (!td->cabc_broken) {
 			r = taal_wake_up(dssdev);
@@ -640,7 +654,7 @@ static ssize_t store_cabc_mode(struct device *dev,
 				goto err;
 		}
 
-		dsi_bus_unlock(dssdev);
+		dsi_bus_unlock(out);
 	}
 
 	td->cabc_mode = i;
@@ -649,7 +663,7 @@ static ssize_t store_cabc_mode(struct device *dev,
 
 	return count;
 err:
-	dsi_bus_unlock(dssdev);
+	dsi_bus_unlock(out);
 	mutex_unlock(&td->lock);
 	return r;
 }
@@ -714,6 +728,7 @@ static ssize_t taal_store_ulps(struct device *dev,
 		const char *buf, size_t count)
 {
 	struct omap_dss_device *dssdev = to_dss_device(dev);
+	struct omap_dss_output *out = dssdev->output;
 	struct taal_data *td = dev_get_drvdata(&dssdev->dev);
 	unsigned long t;
 	int r;
@@ -725,14 +740,14 @@ static ssize_t taal_store_ulps(struct device *dev,
 	mutex_lock(&td->lock);
 
 	if (td->enabled) {
-		dsi_bus_lock(dssdev);
+		dsi_bus_lock(out);
 
 		if (t)
 			r = taal_enter_ulps(dssdev);
 		else
 			r = taal_wake_up(dssdev);
 
-		dsi_bus_unlock(dssdev);
+		dsi_bus_unlock(out);
 	}
 
 	mutex_unlock(&td->lock);
@@ -763,6 +778,7 @@ static ssize_t taal_store_ulps_timeout(struct device *dev,
 		const char *buf, size_t count)
 {
 	struct omap_dss_device *dssdev = to_dss_device(dev);
+	struct omap_dss_output *out = dssdev->output;
 	struct taal_data *td = dev_get_drvdata(&dssdev->dev);
 	unsigned long t;
 	int r;
@@ -776,9 +792,9 @@ static ssize_t taal_store_ulps_timeout(struct device *dev,
 
 	if (td->enabled) {
 		/* taal_wake_up will restart the timer */
-		dsi_bus_lock(dssdev);
+		dsi_bus_lock(out);
 		r = taal_wake_up(dssdev);
-		dsi_bus_unlock(dssdev);
+		dsi_bus_unlock(out);
 	}
 
 	mutex_unlock(&td->lock);
@@ -968,13 +984,13 @@ static int taal_probe(struct omap_dss_device *dssdev)
 		dev_dbg(&dssdev->dev, "Using GPIO TE\n");
 	}
 
-	r = omap_dsi_request_vc(dssdev, &td->channel);
+	r = omap_dsi_request_vc(dssdev->output, &td->channel);
 	if (r) {
 		dev_err(&dssdev->dev, "failed to get virtual channel\n");
 		goto err_req_vc;
 	}
 
-	r = omap_dsi_set_vc_id(dssdev, td->channel, TCH);
+	r = omap_dsi_set_vc_id(dssdev->output, td->channel, TCH);
 	if (r) {
 		dev_err(&dssdev->dev, "failed to set VC_ID\n");
 		goto err_vc_id;
@@ -989,7 +1005,7 @@ static int taal_probe(struct omap_dss_device *dssdev)
 	return 0;
 
 err_vc_id:
-	omap_dsi_release_vc(dssdev, td->channel);
+	omap_dsi_release_vc(dssdev->output, td->channel);
 err_req_vc:
 	if (panel_data->use_ext_te)
 		free_irq(gpio_to_irq(panel_data->ext_te_gpio), dssdev);
@@ -1019,7 +1035,7 @@ static void __exit taal_remove(struct omap_dss_device *dssdev)
 	dev_dbg(&dssdev->dev, "remove\n");
 
 	sysfs_remove_group(&dssdev->dev.kobj, &taal_attr_group);
-	omap_dsi_release_vc(dssdev, td->channel);
+	omap_dsi_release_vc(dssdev->output, td->channel);
 
 	if (panel_data->use_ext_te) {
 		int gpio = panel_data->ext_te_gpio;
@@ -1051,21 +1067,28 @@ static int taal_power_on(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);
+	struct omap_dss_output *out = dssdev->output;
 	u8 id1, id2, id3;
 	int r;
 
-	r = omapdss_dsi_configure_pins(dssdev, &panel_data->pin_config);
+	if (out = NULL) {
+		dev_err(&dssdev->dev, "not output connected to display\n");
+		r = -ENODEV;
+		goto err0;
+	}
+
+	r = omapdss_dsi_configure_pins(out, &panel_data->pin_config);
 	if (r) {
 		dev_err(&dssdev->dev, "failed to configure DSI pins\n");
 		goto err0;
 	};
 
-	omapdss_dsi_set_size(dssdev, dssdev->panel.timings.x_res,
+	omapdss_dsi_set_size(out, dssdev->panel.timings.x_res,
 		dssdev->panel.timings.y_res);
-	omapdss_dsi_set_pixel_format(dssdev, OMAP_DSS_DSI_FMT_RGB888);
-	omapdss_dsi_set_operation_mode(dssdev, OMAP_DSS_DSI_CMD_MODE);
+	omapdss_dsi_set_pixel_format(out, OMAP_DSS_DSI_FMT_RGB888);
+	omapdss_dsi_set_operation_mode(out, OMAP_DSS_DSI_CMD_MODE);
 
-	r = omapdss_dsi_display_enable(dssdev);
+	r = omapdss_dsi_display_enable(out);
 	if (r) {
 		dev_err(&dssdev->dev, "failed to enable DSI\n");
 		goto err0;
@@ -1073,7 +1096,7 @@ static int taal_power_on(struct omap_dss_device *dssdev)
 
 	taal_hw_reset(dssdev);
 
-	omapdss_dsi_vc_enable_hs(dssdev, td->channel, false);
+	omapdss_dsi_vc_enable_hs(out, td->channel, false);
 
 	r = taal_sleep_out(td);
 	if (r)
@@ -1120,7 +1143,7 @@ static int taal_power_on(struct omap_dss_device *dssdev)
 	if (r)
 		goto err;
 
-	r = dsi_enable_video_output(dssdev, td->channel);
+	r = dsi_enable_video_output(out, td->channel);
 	if (r)
 		goto err;
 
@@ -1135,7 +1158,7 @@ static int taal_power_on(struct omap_dss_device *dssdev)
 		td->intro_printed = true;
 	}
 
-	omapdss_dsi_vc_enable_hs(dssdev, td->channel, true);
+	omapdss_dsi_vc_enable_hs(out, td->channel, true);
 
 	return 0;
 err:
@@ -1143,7 +1166,7 @@ err:
 
 	taal_hw_reset(dssdev);
 
-	omapdss_dsi_display_disable(dssdev, true, false);
+	omapdss_dsi_display_disable(out, true, false);
 err0:
 	return r;
 }
@@ -1151,9 +1174,10 @@ err0:
 static void taal_power_off(struct omap_dss_device *dssdev)
 {
 	struct taal_data *td = dev_get_drvdata(&dssdev->dev);
+	struct omap_dss_output *out = dssdev->output;
 	int r;
 
-	dsi_disable_video_output(dssdev, td->channel);
+	dsi_disable_video_output(out, td->channel);
 
 	r = taal_dcs_write_0(td, MIPI_DCS_SET_DISPLAY_OFF);
 	if (!r)
@@ -1165,7 +1189,7 @@ static void taal_power_off(struct omap_dss_device *dssdev)
 		taal_hw_reset(dssdev);
 	}
 
-	omapdss_dsi_display_disable(dssdev, true, false);
+	omapdss_dsi_display_disable(out, true, false);
 
 	td->enabled = 0;
 }
@@ -1182,6 +1206,7 @@ static int taal_panel_reset(struct omap_dss_device *dssdev)
 static int taal_enable(struct omap_dss_device *dssdev)
 {
 	struct taal_data *td = dev_get_drvdata(&dssdev->dev);
+	struct omap_dss_output *out = dssdev->output;
 	int r;
 
 	dev_dbg(&dssdev->dev, "enable\n");
@@ -1193,11 +1218,11 @@ static int taal_enable(struct omap_dss_device *dssdev)
 		goto err;
 	}
 
-	dsi_bus_lock(dssdev);
+	dsi_bus_lock(out);
 
 	r = taal_power_on(dssdev);
 
-	dsi_bus_unlock(dssdev);
+	dsi_bus_unlock(out);
 
 	if (r)
 		goto err;
@@ -1218,6 +1243,7 @@ err:
 static void taal_disable(struct omap_dss_device *dssdev)
 {
 	struct taal_data *td = dev_get_drvdata(&dssdev->dev);
+	struct omap_dss_output *out = dssdev->output;
 
 	dev_dbg(&dssdev->dev, "disable\n");
 
@@ -1226,7 +1252,7 @@ static void taal_disable(struct omap_dss_device *dssdev)
 	taal_cancel_ulps_work(dssdev);
 	taal_cancel_esd_work(dssdev);
 
-	dsi_bus_lock(dssdev);
+	dsi_bus_lock(out);
 
 	if (dssdev->state = OMAP_DSS_DISPLAY_ACTIVE) {
 		int r;
@@ -1236,7 +1262,7 @@ static void taal_disable(struct omap_dss_device *dssdev)
 			taal_power_off(dssdev);
 	}
 
-	dsi_bus_unlock(dssdev);
+	dsi_bus_unlock(out);
 
 	dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
 
@@ -1246,6 +1272,7 @@ static void taal_disable(struct omap_dss_device *dssdev)
 static int taal_suspend(struct omap_dss_device *dssdev)
 {
 	struct taal_data *td = dev_get_drvdata(&dssdev->dev);
+	struct omap_dss_output *out = dssdev->output;
 	int r;
 
 	dev_dbg(&dssdev->dev, "suspend\n");
@@ -1260,13 +1287,13 @@ static int taal_suspend(struct omap_dss_device *dssdev)
 	taal_cancel_ulps_work(dssdev);
 	taal_cancel_esd_work(dssdev);
 
-	dsi_bus_lock(dssdev);
+	dsi_bus_lock(out);
 
 	r = taal_wake_up(dssdev);
 	if (!r)
 		taal_power_off(dssdev);
 
-	dsi_bus_unlock(dssdev);
+	dsi_bus_unlock(out);
 
 	dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
 
@@ -1281,6 +1308,7 @@ err:
 static int taal_resume(struct omap_dss_device *dssdev)
 {
 	struct taal_data *td = dev_get_drvdata(&dssdev->dev);
+	struct omap_dss_output *out = dssdev->output;
 	int r;
 
 	dev_dbg(&dssdev->dev, "resume\n");
@@ -1292,11 +1320,11 @@ static int taal_resume(struct omap_dss_device *dssdev)
 		goto err;
 	}
 
-	dsi_bus_lock(dssdev);
+	dsi_bus_lock(out);
 
 	r = taal_power_on(dssdev);
 
-	dsi_bus_unlock(dssdev);
+	dsi_bus_unlock(out);
 
 	if (r) {
 		dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
@@ -1317,13 +1345,14 @@ static void taal_framedone_cb(int err, void *data)
 {
 	struct omap_dss_device *dssdev = data;
 	dev_dbg(&dssdev->dev, "framedone, err %d\n", err);
-	dsi_bus_unlock(dssdev);
+	dsi_bus_unlock(dssdev->output);
 }
 
 static irqreturn_t taal_te_isr(int irq, void *data)
 {
 	struct omap_dss_device *dssdev = data;
 	struct taal_data *td = dev_get_drvdata(&dssdev->dev);
+	struct omap_dss_output *out = dssdev->output;
 	int old;
 	int r;
 
@@ -1332,7 +1361,7 @@ static irqreturn_t taal_te_isr(int irq, void *data)
 	if (old) {
 		cancel_delayed_work(&td->te_timeout_work);
 
-		r = omap_dsi_update(dssdev, td->channel, taal_framedone_cb,
+		r = omap_dsi_update(out, td->channel, taal_framedone_cb,
 				dssdev);
 		if (r)
 			goto err;
@@ -1341,7 +1370,7 @@ static irqreturn_t taal_te_isr(int irq, void *data)
 	return IRQ_HANDLED;
 err:
 	dev_err(&dssdev->dev, "start update failed\n");
-	dsi_bus_unlock(dssdev);
+	dsi_bus_unlock(out);
 	return IRQ_HANDLED;
 }
 
@@ -1350,11 +1379,12 @@ static void taal_te_timeout_work_callback(struct work_struct *work)
 	struct taal_data *td = container_of(work, struct taal_data,
 					te_timeout_work.work);
 	struct omap_dss_device *dssdev = td->dssdev;
+	struct omap_dss_output *out = dssdev->output;
 
 	dev_err(&dssdev->dev, "TE not received for 250ms!\n");
 
 	atomic_set(&td->do_update, 0);
-	dsi_bus_unlock(dssdev);
+	dsi_bus_unlock(out);
 }
 
 static int taal_update(struct omap_dss_device *dssdev,
@@ -1362,12 +1392,16 @@ static int taal_update(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);
+	struct omap_dss_output *out = dssdev->output;
 	int r;
 
 	dev_dbg(&dssdev->dev, "update %d, %d, %d x %d\n", x, y, w, h);
 
+	if (out = NULL)
+		return -ENODEV;
+
 	mutex_lock(&td->lock);
-	dsi_bus_lock(dssdev);
+	dsi_bus_lock(out);
 
 	r = taal_wake_up(dssdev);
 	if (r)
@@ -1390,7 +1424,7 @@ static int taal_update(struct omap_dss_device *dssdev,
 				msecs_to_jiffies(250));
 		atomic_set(&td->do_update, 1);
 	} else {
-		r = omap_dsi_update(dssdev, td->channel, taal_framedone_cb,
+		r = omap_dsi_update(out, td->channel, taal_framedone_cb,
 				dssdev);
 		if (r)
 			goto err;
@@ -1400,20 +1434,21 @@ static int taal_update(struct omap_dss_device *dssdev,
 	mutex_unlock(&td->lock);
 	return 0;
 err:
-	dsi_bus_unlock(dssdev);
+	dsi_bus_unlock(out);
 	mutex_unlock(&td->lock);
 	return r;
 }
 
 static int taal_sync(struct omap_dss_device *dssdev)
 {
+	struct omap_dss_output *out = dssdev->output;
 	struct taal_data *td = dev_get_drvdata(&dssdev->dev);
 
 	dev_dbg(&dssdev->dev, "sync\n");
 
 	mutex_lock(&td->lock);
-	dsi_bus_lock(dssdev);
-	dsi_bus_unlock(dssdev);
+	dsi_bus_lock(out);
+	dsi_bus_unlock(out);
 	mutex_unlock(&td->lock);
 
 	dev_dbg(&dssdev->dev, "sync done\n");
@@ -1425,6 +1460,7 @@ static int _taal_enable_te(struct omap_dss_device *dssdev, bool enable)
 {
 	struct taal_data *td = dev_get_drvdata(&dssdev->dev);
 	struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
+	struct omap_dss_output *out = dssdev->output;
 	int r;
 
 	if (enable)
@@ -1433,7 +1469,7 @@ static int _taal_enable_te(struct omap_dss_device *dssdev, bool enable)
 		r = taal_dcs_write_0(td, MIPI_DCS_SET_TEAR_OFF);
 
 	if (!panel_data->use_ext_te)
-		omapdss_dsi_enable_te(dssdev, enable);
+		omapdss_dsi_enable_te(out, enable);
 
 	if (td->panel_config->sleep.enable_te)
 		msleep(td->panel_config->sleep.enable_te);
@@ -1444,6 +1480,7 @@ static int _taal_enable_te(struct omap_dss_device *dssdev, bool enable)
 static int taal_enable_te(struct omap_dss_device *dssdev, bool enable)
 {
 	struct taal_data *td = dev_get_drvdata(&dssdev->dev);
+	struct omap_dss_output *out = dssdev->output;
 	int r;
 
 	mutex_lock(&td->lock);
@@ -1451,7 +1488,7 @@ static int taal_enable_te(struct omap_dss_device *dssdev, bool enable)
 	if (td->te_enabled = enable)
 		goto end;
 
-	dsi_bus_lock(dssdev);
+	dsi_bus_lock(out);
 
 	if (td->enabled) {
 		r = taal_wake_up(dssdev);
@@ -1465,13 +1502,13 @@ static int taal_enable_te(struct omap_dss_device *dssdev, bool enable)
 
 	td->te_enabled = enable;
 
-	dsi_bus_unlock(dssdev);
+	dsi_bus_unlock(out);
 end:
 	mutex_unlock(&td->lock);
 
 	return 0;
 err:
-	dsi_bus_unlock(dssdev);
+	dsi_bus_unlock(out);
 	mutex_unlock(&td->lock);
 
 	return r;
@@ -1493,6 +1530,7 @@ static int taal_rotate(struct omap_dss_device *dssdev, u8 rotate)
 {
 	struct taal_data *td = dev_get_drvdata(&dssdev->dev);
 	u16 dw, dh;
+	struct omap_dss_output *out = dssdev->output;
 	int r;
 
 	dev_dbg(&dssdev->dev, "rotate %d\n", rotate);
@@ -1502,7 +1540,7 @@ static int taal_rotate(struct omap_dss_device *dssdev, u8 rotate)
 	if (td->rotate = rotate)
 		goto end;
 
-	dsi_bus_lock(dssdev);
+	dsi_bus_lock(out);
 
 	if (td->enabled) {
 		r = taal_wake_up(dssdev);
@@ -1522,16 +1560,16 @@ static int taal_rotate(struct omap_dss_device *dssdev, u8 rotate)
 		dh = dssdev->panel.timings.x_res;
 	}
 
-	omapdss_dsi_set_size(dssdev, dw, dh);
+	omapdss_dsi_set_size(out, dw, dh);
 
 	td->rotate = rotate;
 
-	dsi_bus_unlock(dssdev);
+	dsi_bus_unlock(out);
 end:
 	mutex_unlock(&td->lock);
 	return 0;
 err:
-	dsi_bus_unlock(dssdev);
+	dsi_bus_unlock(out);
 	mutex_unlock(&td->lock);
 	return r;
 }
@@ -1551,6 +1589,7 @@ static u8 taal_get_rotate(struct omap_dss_device *dssdev)
 static int taal_mirror(struct omap_dss_device *dssdev, bool enable)
 {
 	struct taal_data *td = dev_get_drvdata(&dssdev->dev);
+	struct omap_dss_output *out = dssdev->output;
 	int r;
 
 	dev_dbg(&dssdev->dev, "mirror %d\n", enable);
@@ -1560,7 +1599,7 @@ static int taal_mirror(struct omap_dss_device *dssdev, bool enable)
 	if (td->mirror = enable)
 		goto end;
 
-	dsi_bus_lock(dssdev);
+	dsi_bus_lock(out);
 	if (td->enabled) {
 		r = taal_wake_up(dssdev);
 		if (r)
@@ -1573,12 +1612,12 @@ static int taal_mirror(struct omap_dss_device *dssdev, bool enable)
 
 	td->mirror = enable;
 
-	dsi_bus_unlock(dssdev);
+	dsi_bus_unlock(out);
 end:
 	mutex_unlock(&td->lock);
 	return 0;
 err:
-	dsi_bus_unlock(dssdev);
+	dsi_bus_unlock(out);
 	mutex_unlock(&td->lock);
 	return r;
 }
@@ -1598,6 +1637,7 @@ static bool taal_get_mirror(struct omap_dss_device *dssdev)
 static int taal_run_test(struct omap_dss_device *dssdev, int test_num)
 {
 	struct taal_data *td = dev_get_drvdata(&dssdev->dev);
+	struct omap_dss_output *out = dssdev->output;
 	u8 id1, id2, id3;
 	int r;
 
@@ -1608,7 +1648,7 @@ static int taal_run_test(struct omap_dss_device *dssdev, int test_num)
 		goto err1;
 	}
 
-	dsi_bus_lock(dssdev);
+	dsi_bus_lock(out);
 
 	r = taal_wake_up(dssdev);
 	if (r)
@@ -1624,11 +1664,11 @@ static int taal_run_test(struct omap_dss_device *dssdev, int test_num)
 	if (r)
 		goto err2;
 
-	dsi_bus_unlock(dssdev);
+	dsi_bus_unlock(out);
 	mutex_unlock(&td->lock);
 	return 0;
 err2:
-	dsi_bus_unlock(dssdev);
+	dsi_bus_unlock(out);
 err1:
 	mutex_unlock(&td->lock);
 	return r;
@@ -1643,6 +1683,7 @@ static int taal_memory_read(struct omap_dss_device *dssdev,
 	int plen;
 	unsigned buf_used = 0;
 	struct taal_data *td = dev_get_drvdata(&dssdev->dev);
+	struct omap_dss_output *out = dssdev->output;
 
 	if (size < w * h * 3)
 		return -ENOMEM;
@@ -1658,7 +1699,7 @@ static int taal_memory_read(struct omap_dss_device *dssdev,
 			dssdev->panel.timings.x_res *
 			dssdev->panel.timings.y_res * 3);
 
-	dsi_bus_lock(dssdev);
+	dsi_bus_lock(out);
 
 	r = taal_wake_up(dssdev);
 	if (r)
@@ -1674,7 +1715,7 @@ static int taal_memory_read(struct omap_dss_device *dssdev,
 
 	taal_set_update_window(td, x, y, w, h);
 
-	r = dsi_vc_set_max_rx_packet_size(dssdev, td->channel, plen);
+	r = dsi_vc_set_max_rx_packet_size(out, td->channel, plen);
 	if (r)
 		goto err2;
 
@@ -1682,7 +1723,7 @@ static int taal_memory_read(struct omap_dss_device *dssdev,
 		u8 dcs_cmd = first ? 0x2e : 0x3e;
 		first = 0;
 
-		r = dsi_vc_dcs_read(dssdev, td->channel, dcs_cmd,
+		r = dsi_vc_dcs_read(out, td->channel, dcs_cmd,
 				buf + buf_used, size - buf_used);
 
 		if (r < 0) {
@@ -1708,9 +1749,9 @@ static int taal_memory_read(struct omap_dss_device *dssdev,
 	r = buf_used;
 
 err3:
-	dsi_vc_set_max_rx_packet_size(dssdev, td->channel, 1);
+	dsi_vc_set_max_rx_packet_size(out, td->channel, 1);
 err2:
-	dsi_bus_unlock(dssdev);
+	dsi_bus_unlock(out);
 err1:
 	mutex_unlock(&td->lock);
 	return r;
@@ -1721,6 +1762,7 @@ static void taal_ulps_work(struct work_struct *work)
 	struct taal_data *td = container_of(work, struct taal_data,
 			ulps_work.work);
 	struct omap_dss_device *dssdev = td->dssdev;
+	struct omap_dss_output *out = dssdev->output;
 
 	mutex_lock(&td->lock);
 
@@ -1729,11 +1771,11 @@ static void taal_ulps_work(struct work_struct *work)
 		return;
 	}
 
-	dsi_bus_lock(dssdev);
+	dsi_bus_lock(out);
 
 	taal_enter_ulps(dssdev);
 
-	dsi_bus_unlock(dssdev);
+	dsi_bus_unlock(out);
 	mutex_unlock(&td->lock);
 }
 
@@ -1742,6 +1784,7 @@ static void taal_esd_work(struct work_struct *work)
 	struct taal_data *td = container_of(work, struct taal_data,
 			esd_work.work);
 	struct omap_dss_device *dssdev = td->dssdev;
+	struct omap_dss_output *out = dssdev->output;
 	struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
 	u8 state1, state2;
 	int r;
@@ -1753,7 +1796,7 @@ static void taal_esd_work(struct work_struct *work)
 		return;
 	}
 
-	dsi_bus_lock(dssdev);
+	dsi_bus_lock(out);
 
 	r = taal_wake_up(dssdev);
 	if (r) {
@@ -1795,7 +1838,7 @@ static void taal_esd_work(struct work_struct *work)
 			goto err;
 	}
 
-	dsi_bus_unlock(dssdev);
+	dsi_bus_unlock(out);
 
 	taal_queue_esd_work(dssdev);
 
@@ -1806,7 +1849,7 @@ err:
 
 	taal_panel_reset(dssdev);
 
-	dsi_bus_unlock(dssdev);
+	dsi_bus_unlock(out);
 
 	taal_queue_esd_work(dssdev);
 
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index 19a4d4d..2eb3b75 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -354,9 +354,9 @@ static inline struct dsi_data *dsi_get_dsidrv_data(struct platform_device *dside
 	return dev_get_drvdata(&dsidev->dev);
 }
 
-static inline struct platform_device *dsi_get_dsidev_from_dssdev(struct omap_dss_device *dssdev)
+static inline struct platform_device *dsi_get_dsidev_from_output(struct omap_dss_output *out)
 {
-	return dssdev->output->pdev;
+	return out->pdev;
 }
 
 struct platform_device *dsi_get_dsidev_from_id(int module)
@@ -387,18 +387,18 @@ static inline u32 dsi_read_reg(struct platform_device *dsidev,
 	return __raw_readl(dsi->base + idx.idx);
 }
 
-void dsi_bus_lock(struct omap_dss_device *dssdev)
+void dsi_bus_lock(struct omap_dss_output *out)
 {
-	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+	struct platform_device *dsidev = dsi_get_dsidev_from_output(out);
 	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
 
 	down(&dsi->bus_lock);
 }
 EXPORT_SYMBOL(dsi_bus_lock);
 
-void dsi_bus_unlock(struct omap_dss_device *dssdev)
+void dsi_bus_unlock(struct omap_dss_output *out)
 {
-	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+	struct platform_device *dsidev = dsi_get_dsidev_from_output(out);
 	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
 
 	up(&dsi->bus_lock);
@@ -1203,10 +1203,11 @@ static unsigned long dsi_fclk_rate(struct platform_device *dsidev)
 	return r;
 }
 
-static int dsi_set_lp_clk_divisor(struct omap_dss_device *dssdev)
+static int dsi_set_lp_clk_divisor(struct omap_dss_output *out)
 {
-	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+	struct platform_device *dsidev = dsi_get_dsidev_from_output(out);
 	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
+	struct omap_dss_device *dssdev = out->device;
 	unsigned long dsi_fclk;
 	unsigned lp_clk_div;
 	unsigned long lp_clk;
@@ -2684,10 +2685,10 @@ static int dsi_vc_config_source(struct platform_device *dsidev, int channel,
 	return 0;
 }
 
-void omapdss_dsi_vc_enable_hs(struct omap_dss_device *dssdev, int channel,
+void omapdss_dsi_vc_enable_hs(struct omap_dss_output *out, int channel,
 		bool enable)
 {
-	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+	struct platform_device *dsidev = dsi_get_dsidev_from_output(out);
 	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
 
 	DSSDBG("dsi_vc_enable_hs(%d, %d)\n", channel, enable);
@@ -2706,7 +2707,7 @@ void omapdss_dsi_vc_enable_hs(struct omap_dss_device *dssdev, int channel,
 
 	/* start the DDR clock by sending a NULL packet */
 	if (dsi->vm_timings.ddr_clk_always_on && enable)
-		dsi_vc_send_null(dssdev, channel);
+		dsi_vc_send_null(out, channel);
 }
 EXPORT_SYMBOL(omapdss_dsi_vc_enable_hs);
 
@@ -2813,9 +2814,9 @@ static int dsi_vc_send_bta(struct platform_device *dsidev, int channel)
 	return 0;
 }
 
-int dsi_vc_send_bta_sync(struct omap_dss_device *dssdev, int channel)
+int dsi_vc_send_bta_sync(struct omap_dss_output *out, int channel)
 {
-	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+	struct platform_device *dsidev = dsi_get_dsidev_from_output(out);
 	DECLARE_COMPLETION_ONSTACK(completion);
 	int r = 0;
 	u32 err;
@@ -2982,9 +2983,9 @@ static int dsi_vc_send_short(struct platform_device *dsidev, int channel,
 	return 0;
 }
 
-int dsi_vc_send_null(struct omap_dss_device *dssdev, int channel)
+int dsi_vc_send_null(struct omap_dss_output *out, int channel)
 {
-	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+	struct platform_device *dsidev = dsi_get_dsidev_from_output(out);
 
 	return dsi_vc_send_long(dsidev, channel, MIPI_DSI_NULL_PACKET, NULL,
 		0, 0);
@@ -3021,37 +3022,37 @@ static int dsi_vc_write_nosync_common(struct platform_device *dsidev,
 	return r;
 }
 
-int dsi_vc_dcs_write_nosync(struct omap_dss_device *dssdev, int channel,
+int dsi_vc_dcs_write_nosync(struct omap_dss_output *out, int channel,
 		u8 *data, int len)
 {
-	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+	struct platform_device *dsidev = dsi_get_dsidev_from_output(out);
 
 	return dsi_vc_write_nosync_common(dsidev, channel, data, len,
 			DSS_DSI_CONTENT_DCS);
 }
 EXPORT_SYMBOL(dsi_vc_dcs_write_nosync);
 
-int dsi_vc_generic_write_nosync(struct omap_dss_device *dssdev, int channel,
+int dsi_vc_generic_write_nosync(struct omap_dss_output *out, int channel,
 		u8 *data, int len)
 {
-	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+	struct platform_device *dsidev = dsi_get_dsidev_from_output(out);
 
 	return dsi_vc_write_nosync_common(dsidev, channel, data, len,
 			DSS_DSI_CONTENT_GENERIC);
 }
 EXPORT_SYMBOL(dsi_vc_generic_write_nosync);
 
-static int dsi_vc_write_common(struct omap_dss_device *dssdev, int channel,
+static int dsi_vc_write_common(struct omap_dss_output *out, int channel,
 		u8 *data, int len, enum dss_dsi_content_type type)
 {
-	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+	struct platform_device *dsidev = dsi_get_dsidev_from_output(out);
 	int r;
 
 	r = dsi_vc_write_nosync_common(dsidev, channel, data, len, type);
 	if (r)
 		goto err;
 
-	r = dsi_vc_send_bta_sync(dssdev, channel);
+	r = dsi_vc_send_bta_sync(out, channel);
 	if (r)
 		goto err;
 
@@ -3070,58 +3071,58 @@ err:
 	return r;
 }
 
-int dsi_vc_dcs_write(struct omap_dss_device *dssdev, int channel, u8 *data,
+int dsi_vc_dcs_write(struct omap_dss_output *out, int channel, u8 *data,
 		int len)
 {
-	return dsi_vc_write_common(dssdev, channel, data, len,
+	return dsi_vc_write_common(out, channel, data, len,
 			DSS_DSI_CONTENT_DCS);
 }
 EXPORT_SYMBOL(dsi_vc_dcs_write);
 
-int dsi_vc_generic_write(struct omap_dss_device *dssdev, int channel, u8 *data,
+int dsi_vc_generic_write(struct omap_dss_output *out, int channel, u8 *data,
 		int len)
 {
-	return dsi_vc_write_common(dssdev, channel, data, len,
+	return dsi_vc_write_common(out, channel, data, len,
 			DSS_DSI_CONTENT_GENERIC);
 }
 EXPORT_SYMBOL(dsi_vc_generic_write);
 
-int dsi_vc_dcs_write_0(struct omap_dss_device *dssdev, int channel, u8 dcs_cmd)
+int dsi_vc_dcs_write_0(struct omap_dss_output *out, int channel, u8 dcs_cmd)
 {
-	return dsi_vc_dcs_write(dssdev, channel, &dcs_cmd, 1);
+	return dsi_vc_dcs_write(out, channel, &dcs_cmd, 1);
 }
 EXPORT_SYMBOL(dsi_vc_dcs_write_0);
 
-int dsi_vc_generic_write_0(struct omap_dss_device *dssdev, int channel)
+int dsi_vc_generic_write_0(struct omap_dss_output *out, int channel)
 {
-	return dsi_vc_generic_write(dssdev, channel, NULL, 0);
+	return dsi_vc_generic_write(out, channel, NULL, 0);
 }
 EXPORT_SYMBOL(dsi_vc_generic_write_0);
 
-int dsi_vc_dcs_write_1(struct omap_dss_device *dssdev, int channel, u8 dcs_cmd,
+int dsi_vc_dcs_write_1(struct omap_dss_output *out, int channel, u8 dcs_cmd,
 		u8 param)
 {
 	u8 buf[2];
 	buf[0] = dcs_cmd;
 	buf[1] = param;
-	return dsi_vc_dcs_write(dssdev, channel, buf, 2);
+	return dsi_vc_dcs_write(out, channel, buf, 2);
 }
 EXPORT_SYMBOL(dsi_vc_dcs_write_1);
 
-int dsi_vc_generic_write_1(struct omap_dss_device *dssdev, int channel,
+int dsi_vc_generic_write_1(struct omap_dss_output *out, int channel,
 		u8 param)
 {
-	return dsi_vc_generic_write(dssdev, channel, &param, 1);
+	return dsi_vc_generic_write(out, channel, &param, 1);
 }
 EXPORT_SYMBOL(dsi_vc_generic_write_1);
 
-int dsi_vc_generic_write_2(struct omap_dss_device *dssdev, int channel,
+int dsi_vc_generic_write_2(struct omap_dss_output *out, int channel,
 		u8 param1, u8 param2)
 {
 	u8 buf[2];
 	buf[0] = param1;
 	buf[1] = param2;
-	return dsi_vc_generic_write(dssdev, channel, buf, 2);
+	return dsi_vc_generic_write(out, channel, buf, 2);
 }
 EXPORT_SYMBOL(dsi_vc_generic_write_2);
 
@@ -3290,17 +3291,17 @@ err:
 	return r;
 }
 
-int dsi_vc_dcs_read(struct omap_dss_device *dssdev, int channel, u8 dcs_cmd,
+int dsi_vc_dcs_read(struct omap_dss_output *out, int channel, u8 dcs_cmd,
 		u8 *buf, int buflen)
 {
-	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+	struct platform_device *dsidev = dsi_get_dsidev_from_output(out);
 	int r;
 
 	r = dsi_vc_dcs_send_read_request(dsidev, channel, dcs_cmd);
 	if (r)
 		goto err;
 
-	r = dsi_vc_send_bta_sync(dssdev, channel);
+	r = dsi_vc_send_bta_sync(out, channel);
 	if (r)
 		goto err;
 
@@ -3321,17 +3322,17 @@ err:
 }
 EXPORT_SYMBOL(dsi_vc_dcs_read);
 
-static int dsi_vc_generic_read(struct omap_dss_device *dssdev, int channel,
+static int dsi_vc_generic_read(struct omap_dss_output *out, int channel,
 		u8 *reqdata, int reqlen, u8 *buf, int buflen)
 {
-	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+	struct platform_device *dsidev = dsi_get_dsidev_from_output(out);
 	int r;
 
 	r = dsi_vc_generic_send_read_request(dsidev, channel, reqdata, reqlen);
 	if (r)
 		return r;
 
-	r = dsi_vc_send_bta_sync(dssdev, channel);
+	r = dsi_vc_send_bta_sync(out, channel);
 	if (r)
 		return r;
 
@@ -3348,12 +3349,12 @@ static int dsi_vc_generic_read(struct omap_dss_device *dssdev, int channel,
 	return 0;
 }
 
-int dsi_vc_generic_read_0(struct omap_dss_device *dssdev, int channel, u8 *buf,
+int dsi_vc_generic_read_0(struct omap_dss_output *out, int channel, u8 *buf,
 		int buflen)
 {
 	int r;
 
-	r = dsi_vc_generic_read(dssdev, channel, NULL, 0, buf, buflen);
+	r = dsi_vc_generic_read(out, channel, NULL, 0, buf, buflen);
 	if (r) {
 		DSSERR("dsi_vc_generic_read_0(ch %d) failed\n", channel);
 		return r;
@@ -3363,12 +3364,12 @@ int dsi_vc_generic_read_0(struct omap_dss_device *dssdev, int channel, u8 *buf,
 }
 EXPORT_SYMBOL(dsi_vc_generic_read_0);
 
-int dsi_vc_generic_read_1(struct omap_dss_device *dssdev, int channel, u8 param,
+int dsi_vc_generic_read_1(struct omap_dss_output *out, int channel, u8 param,
 		u8 *buf, int buflen)
 {
 	int r;
 
-	r = dsi_vc_generic_read(dssdev, channel, &param, 1, buf, buflen);
+	r = dsi_vc_generic_read(out, channel, &param, 1, buf, buflen);
 	if (r) {
 		DSSERR("dsi_vc_generic_read_1(ch %d) failed\n", channel);
 		return r;
@@ -3378,7 +3379,7 @@ int dsi_vc_generic_read_1(struct omap_dss_device *dssdev, int channel, u8 param,
 }
 EXPORT_SYMBOL(dsi_vc_generic_read_1);
 
-int dsi_vc_generic_read_2(struct omap_dss_device *dssdev, int channel,
+int dsi_vc_generic_read_2(struct omap_dss_output *out, int channel,
 		u8 param1, u8 param2, u8 *buf, int buflen)
 {
 	int r;
@@ -3387,7 +3388,7 @@ int dsi_vc_generic_read_2(struct omap_dss_device *dssdev, int channel,
 	reqdata[0] = param1;
 	reqdata[1] = param2;
 
-	r = dsi_vc_generic_read(dssdev, channel, reqdata, 2, buf, buflen);
+	r = dsi_vc_generic_read(out, channel, reqdata, 2, buf, buflen);
 	if (r) {
 		DSSERR("dsi_vc_generic_read_2(ch %d) failed\n", channel);
 		return r;
@@ -3397,10 +3398,10 @@ int dsi_vc_generic_read_2(struct omap_dss_device *dssdev, int channel,
 }
 EXPORT_SYMBOL(dsi_vc_generic_read_2);
 
-int dsi_vc_set_max_rx_packet_size(struct omap_dss_device *dssdev, int channel,
+int dsi_vc_set_max_rx_packet_size(struct omap_dss_output *out, int channel,
 		u16 len)
 {
-	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+	struct platform_device *dsidev = dsi_get_dsidev_from_output(out);
 
 	return dsi_vc_send_short(dsidev, channel,
 			MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE, len, 0);
@@ -3736,10 +3737,11 @@ static int dsi_compute_interleave_lp(int blank, int enter_hs, int exit_hs,
 	return max(lp_inter, 0);
 }
 
-static void dsi_config_cmd_mode_interleaving(struct omap_dss_device *dssdev)
+static void dsi_config_cmd_mode_interleaving(struct omap_dss_output *out)
 {
-	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+	struct platform_device *dsidev = dsi_get_dsidev_from_output(out);
 	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
+	struct omap_dss_device *dssdev = out->device;
 	int blanking_mode;
 	int hfp_blanking_mode, hbp_blanking_mode, hsa_blanking_mode;
 	int hsa, hfp, hbp, width_bytes, bllp, lp_clk_div;
@@ -3854,9 +3856,9 @@ static void dsi_config_cmd_mode_interleaving(struct omap_dss_device *dssdev)
 	dsi_write_reg(dsidev, DSI_VM_TIMING6, r);
 }
 
-static int dsi_proto_config(struct omap_dss_device *dssdev)
+static int dsi_proto_config(struct omap_dss_output *out)
 {
-	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+	struct platform_device *dsidev = dsi_get_dsidev_from_output(out);
 	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
 	u32 r;
 	int buswidth = 0;
@@ -3914,7 +3916,7 @@ static int dsi_proto_config(struct omap_dss_device *dssdev)
 	if (dsi->mode = OMAP_DSS_DSI_VIDEO_MODE) {
 		dsi_config_vp_sync_events(dsidev);
 		dsi_config_blanking_modes(dsidev);
-		dsi_config_cmd_mode_interleaving(dssdev);
+		dsi_config_cmd_mode_interleaving(out);
 	}
 
 	dsi_vc_initial_config(dsidev, 0);
@@ -4037,10 +4039,10 @@ static void dsi_proto_timings(struct platform_device *dsidev)
 	}
 }
 
-int omapdss_dsi_configure_pins(struct omap_dss_device *dssdev,
+int omapdss_dsi_configure_pins(struct omap_dss_output *out,
 		const struct omap_dsi_pin_config *pin_cfg)
 {
-	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+	struct platform_device *dsidev = dsi_get_dsidev_from_output(out);
 	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
 	int num_pins;
 	const int *pins;
@@ -4105,9 +4107,9 @@ int omapdss_dsi_configure_pins(struct omap_dss_device *dssdev,
 }
 EXPORT_SYMBOL(omapdss_dsi_configure_pins);
 
-int dsi_enable_video_output(struct omap_dss_device *dssdev, int channel)
+int dsi_enable_video_output(struct omap_dss_output *out, int channel)
 {
-	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+	struct platform_device *dsidev = dsi_get_dsidev_from_output(out);
 	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
 	int bpp = dsi_get_pixel_size(dsi->pix_fmt);
 	u8 data_type;
@@ -4148,7 +4150,7 @@ int dsi_enable_video_output(struct omap_dss_device *dssdev, int channel)
 		dsi_if_enable(dsidev, true);
 	}
 
-	r = dss_mgr_enable(dssdev->manager);
+	r = dss_mgr_enable(out->manager);
 	if (r) {
 		if (dsi->mode = OMAP_DSS_DSI_VIDEO_MODE) {
 			dsi_if_enable(dsidev, false);
@@ -4162,9 +4164,9 @@ int dsi_enable_video_output(struct omap_dss_device *dssdev, int channel)
 }
 EXPORT_SYMBOL(dsi_enable_video_output);
 
-void dsi_disable_video_output(struct omap_dss_device *dssdev, int channel)
+void dsi_disable_video_output(struct omap_dss_output *out, int channel)
 {
-	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+	struct platform_device *dsidev = dsi_get_dsidev_from_output(out);
 	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
 
 	if (dsi->mode = OMAP_DSS_DSI_VIDEO_MODE) {
@@ -4178,13 +4180,13 @@ void dsi_disable_video_output(struct omap_dss_device *dssdev, int channel)
 		dsi_if_enable(dsidev, true);
 	}
 
-	dss_mgr_disable(dssdev->manager);
+	dss_mgr_disable(out->manager);
 }
 EXPORT_SYMBOL(dsi_disable_video_output);
 
-static void dsi_update_screen_dispc(struct omap_dss_device *dssdev)
+static void dsi_update_screen_dispc(struct omap_dss_output *out)
 {
-	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+	struct platform_device *dsidev = dsi_get_dsidev_from_output(out);
 	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
 	unsigned bytespp;
 	unsigned bytespl;
@@ -4247,9 +4249,9 @@ static void dsi_update_screen_dispc(struct omap_dss_device *dssdev)
 		msecs_to_jiffies(250));
 	BUG_ON(r = 0);
 
-	dss_mgr_set_timings(dssdev->manager, &dsi->timings);
+	dss_mgr_set_timings(out->manager, &dsi->timings);
 
-	dss_mgr_start_update(dssdev->manager);
+	dss_mgr_start_update(out->manager);
 
 	if (dsi->te_enabled) {
 		/* disable LP_RX_TO, so that we can receive TE.  Time to wait
@@ -4320,10 +4322,10 @@ static void dsi_framedone_irq_callback(void *data, u32 mask)
 	dsi_handle_framedone(dsidev, 0);
 }
 
-int omap_dsi_update(struct omap_dss_device *dssdev, int channel,
+int omap_dsi_update(struct omap_dss_output *out, int channel,
 		void (*callback)(int, void *), void *data)
 {
-	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+	struct platform_device *dsidev = dsi_get_dsidev_from_output(out);
 	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
 	u16 dw, dh;
 
@@ -4341,7 +4343,7 @@ int omap_dsi_update(struct omap_dss_device *dssdev, int channel,
 	dsi->update_bytes = dw * dh *
 		dsi_get_pixel_size(dsi->pix_fmt) / 8;
 #endif
-	dsi_update_screen_dispc(dssdev);
+	dsi_update_screen_dispc(out);
 
 	return 0;
 }
@@ -4349,10 +4351,11 @@ EXPORT_SYMBOL(omap_dsi_update);
 
 /* Display funcs */
 
-static int dsi_configure_dispc_clocks(struct omap_dss_device *dssdev)
+static int dsi_configure_dispc_clocks(struct omap_dss_output *out)
 {
-	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+	struct platform_device *dsidev = dsi_get_dsidev_from_output(out);
 	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
+	struct omap_dss_device *dssdev = out->device;
 	struct dispc_clock_info dispc_cinfo;
 	int r;
 	unsigned long long fck;
@@ -4373,10 +4376,11 @@ static int dsi_configure_dispc_clocks(struct omap_dss_device *dssdev)
 	return 0;
 }
 
-static int dsi_display_init_dispc(struct omap_dss_device *dssdev)
+static int dsi_display_init_dispc(struct omap_dss_output *out)
 {
-	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+	struct platform_device *dsidev = dsi_get_dsidev_from_output(out);
 	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
+	struct omap_overlay_manager *mgr = out->manager;
 	int r;
 	u32 irq = 0;
 
@@ -4388,7 +4392,7 @@ static int dsi_display_init_dispc(struct omap_dss_device *dssdev)
 		dsi->timings.vfp = 0;
 		dsi->timings.vbp = 0;
 
-		irq = dispc_mgr_get_framedone_irq(dssdev->manager->id);
+		irq = dispc_mgr_get_framedone_irq(mgr->id);
 
 		r = omap_dispc_register_isr(dsi_framedone_irq_callback,
 			(void *) dsidev, irq);
@@ -4415,9 +4419,9 @@ static int dsi_display_init_dispc(struct omap_dss_device *dssdev)
 	dsi->timings.de_level = OMAPDSS_SIG_ACTIVE_HIGH;
 	dsi->timings.sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES;
 
-	dss_mgr_set_timings(dssdev->manager, &dsi->timings);
+	dss_mgr_set_timings(mgr, &dsi->timings);
 
-	r = dsi_configure_dispc_clocks(dssdev);
+	r = dsi_configure_dispc_clocks(out);
 	if (r)
 		goto err1;
 
@@ -4426,7 +4430,7 @@ static int dsi_display_init_dispc(struct omap_dss_device *dssdev)
 			dsi_get_pixel_size(dsi->pix_fmt);
 	dsi->mgr_config.lcden_sig_polarity = 0;
 
-	dss_mgr_set_lcd_config(dssdev->manager, &dsi->mgr_config);
+	dss_mgr_set_lcd_config(mgr, &dsi->mgr_config);
 
 	return 0;
 err1:
@@ -4437,24 +4441,25 @@ err:
 	return r;
 }
 
-static void dsi_display_uninit_dispc(struct omap_dss_device *dssdev)
+static void dsi_display_uninit_dispc(struct omap_dss_output *out)
 {
-	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+	struct platform_device *dsidev = dsi_get_dsidev_from_output(out);
 	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
 
 	if (dsi->mode = OMAP_DSS_DSI_CMD_MODE) {
 		u32 irq;
 
-		irq = dispc_mgr_get_framedone_irq(dssdev->manager->id);
+		irq = dispc_mgr_get_framedone_irq(out->manager->id);
 
 		omap_dispc_unregister_isr(dsi_framedone_irq_callback,
 			(void *) dsidev, irq);
 	}
 }
 
-static int dsi_configure_dsi_clocks(struct omap_dss_device *dssdev)
+static int dsi_configure_dsi_clocks(struct omap_dss_output *out)
 {
-	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+	struct platform_device *dsidev = dsi_get_dsidev_from_output(out);
+	struct omap_dss_device *dssdev = out->device;
 	struct dsi_clock_info cinfo;
 	int r;
 
@@ -4477,23 +4482,25 @@ static int dsi_configure_dsi_clocks(struct omap_dss_device *dssdev)
 	return 0;
 }
 
-static int dsi_display_init_dsi(struct omap_dss_device *dssdev)
+static int dsi_display_init_dsi(struct omap_dss_output *out)
 {
-	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+	struct platform_device *dsidev = dsi_get_dsidev_from_output(out);
 	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
+	struct omap_overlay_manager *mgr = out->manager;
+	struct omap_dss_device *dssdev = out->device;
 	int r;
 
 	r = dsi_pll_init(dsidev, true, true);
 	if (r)
 		goto err0;
 
-	r = dsi_configure_dsi_clocks(dssdev);
+	r = dsi_configure_dsi_clocks(out);
 	if (r)
 		goto err1;
 
 	dss_select_dispc_clk_source(dssdev->clocks.dispc.dispc_fclk_src);
 	dss_select_dsi_clk_source(dsi->module_id, dssdev->clocks.dsi.dsi_fclk_src);
-	dss_select_lcd_clk_source(dssdev->manager->id,
+	dss_select_lcd_clk_source(out->manager->id,
 			dssdev->clocks.dispc.channel.lcd_clk_src);
 
 	DSSDBG("PLL OK\n");
@@ -4505,12 +4512,12 @@ static int dsi_display_init_dsi(struct omap_dss_device *dssdev)
 	_dsi_print_reset_status(dsidev);
 
 	dsi_proto_timings(dsidev);
-	dsi_set_lp_clk_divisor(dssdev);
+	dsi_set_lp_clk_divisor(out);
 
 	if (1)
 		_dsi_print_reset_status(dsidev);
 
-	r = dsi_proto_config(dssdev);
+	r = dsi_proto_config(out);
 	if (r)
 		goto err3;
 
@@ -4528,7 +4535,7 @@ err3:
 err2:
 	dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK);
 	dss_select_dsi_clk_source(dsi->module_id, OMAP_DSS_CLK_SRC_FCK);
-	dss_select_lcd_clk_source(dssdev->manager->id, OMAP_DSS_CLK_SRC_FCK);
+	dss_select_lcd_clk_source(mgr->id, OMAP_DSS_CLK_SRC_FCK);
 
 err1:
 	dsi_pll_uninit(dsidev, true);
@@ -4536,11 +4543,12 @@ err0:
 	return r;
 }
 
-static void dsi_display_uninit_dsi(struct omap_dss_device *dssdev,
+static void dsi_display_uninit_dsi(struct omap_dss_output *out,
 		bool disconnect_lanes, bool enter_ulps)
 {
-	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+	struct platform_device *dsidev = dsi_get_dsidev_from_output(out);
 	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
+	struct omap_overlay_manager *mgr = out->manager;
 
 	if (enter_ulps && !dsi->ulps_enabled)
 		dsi_enter_ulps(dsidev);
@@ -4554,14 +4562,14 @@ static void dsi_display_uninit_dsi(struct omap_dss_device *dssdev,
 
 	dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK);
 	dss_select_dsi_clk_source(dsi->module_id, OMAP_DSS_CLK_SRC_FCK);
-	dss_select_lcd_clk_source(dssdev->manager->id, OMAP_DSS_CLK_SRC_FCK);
+	dss_select_lcd_clk_source(mgr->id, OMAP_DSS_CLK_SRC_FCK);
 	dsi_cio_uninit(dsidev);
 	dsi_pll_uninit(dsidev, disconnect_lanes);
 }
 
-int omapdss_dsi_display_enable(struct omap_dss_device *dssdev)
+int omapdss_dsi_display_enable(struct omap_dss_output *out)
 {
-	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+	struct platform_device *dsidev = dsi_get_dsidev_from_output(out);
 	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
 	int r = 0;
 
@@ -4571,13 +4579,13 @@ int omapdss_dsi_display_enable(struct omap_dss_device *dssdev)
 
 	mutex_lock(&dsi->lock);
 
-	if (dssdev->manager = NULL) {
+	if (out->manager = NULL) {
 		DSSERR("failed to enable display: no manager\n");
 		r = -ENODEV;
 		goto err_start_dev;
 	}
 
-	r = omap_dss_start_device(dssdev);
+	r = omap_dss_start_device(out->device);
 	if (r) {
 		DSSERR("failed to start device\n");
 		goto err_start_dev;
@@ -4591,11 +4599,11 @@ int omapdss_dsi_display_enable(struct omap_dss_device *dssdev)
 
 	_dsi_initialize_irq(dsidev);
 
-	r = dsi_display_init_dispc(dssdev);
+	r = dsi_display_init_dispc(out);
 	if (r)
 		goto err_init_dispc;
 
-	r = dsi_display_init_dsi(dssdev);
+	r = dsi_display_init_dsi(out);
 	if (r)
 		goto err_init_dsi;
 
@@ -4604,12 +4612,12 @@ int omapdss_dsi_display_enable(struct omap_dss_device *dssdev)
 	return 0;
 
 err_init_dsi:
-	dsi_display_uninit_dispc(dssdev);
+	dsi_display_uninit_dispc(out);
 err_init_dispc:
 	dsi_enable_pll_clock(dsidev, 0);
 	dsi_runtime_put(dsidev);
 err_get_dsi:
-	omap_dss_stop_device(dssdev);
+	omap_dss_stop_device(out->device);
 err_start_dev:
 	mutex_unlock(&dsi->lock);
 	DSSDBG("dsi_display_enable FAILED\n");
@@ -4617,10 +4625,10 @@ err_start_dev:
 }
 EXPORT_SYMBOL(omapdss_dsi_display_enable);
 
-void omapdss_dsi_display_disable(struct omap_dss_device *dssdev,
+void omapdss_dsi_display_disable(struct omap_dss_output *out,
 		bool disconnect_lanes, bool enter_ulps)
 {
-	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+	struct platform_device *dsidev = dsi_get_dsidev_from_output(out);
 	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
 
 	DSSDBG("dsi_display_disable\n");
@@ -4634,22 +4642,22 @@ void omapdss_dsi_display_disable(struct omap_dss_device *dssdev,
 	dsi_sync_vc(dsidev, 2);
 	dsi_sync_vc(dsidev, 3);
 
-	dsi_display_uninit_dispc(dssdev);
+	dsi_display_uninit_dispc(out);
 
-	dsi_display_uninit_dsi(dssdev, disconnect_lanes, enter_ulps);
+	dsi_display_uninit_dsi(out, disconnect_lanes, enter_ulps);
 
 	dsi_runtime_put(dsidev);
 	dsi_enable_pll_clock(dsidev, 0);
 
-	omap_dss_stop_device(dssdev);
+	omap_dss_stop_device(out->device);
 
 	mutex_unlock(&dsi->lock);
 }
 EXPORT_SYMBOL(omapdss_dsi_display_disable);
 
-int omapdss_dsi_enable_te(struct omap_dss_device *dssdev, bool enable)
+int omapdss_dsi_enable_te(struct omap_dss_output *out, bool enable)
 {
-	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+	struct platform_device *dsidev = dsi_get_dsidev_from_output(out);
 	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
 
 	dsi->te_enabled = enable;
@@ -4657,10 +4665,10 @@ int omapdss_dsi_enable_te(struct omap_dss_device *dssdev, bool enable)
 }
 EXPORT_SYMBOL(omapdss_dsi_enable_te);
 
-void omapdss_dsi_set_timings(struct omap_dss_device *dssdev,
+void omapdss_dsi_set_timings(struct omap_dss_output *out,
 		struct omap_video_timings *timings)
 {
-	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+	struct platform_device *dsidev = dsi_get_dsidev_from_output(out);
 	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
 
 	mutex_lock(&dsi->lock);
@@ -4671,9 +4679,9 @@ void omapdss_dsi_set_timings(struct omap_dss_device *dssdev,
 }
 EXPORT_SYMBOL(omapdss_dsi_set_timings);
 
-void omapdss_dsi_set_size(struct omap_dss_device *dssdev, u16 w, u16 h)
+void omapdss_dsi_set_size(struct omap_dss_output *out, u16 w, u16 h)
 {
-	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+	struct platform_device *dsidev = dsi_get_dsidev_from_output(out);
 	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
 
 	mutex_lock(&dsi->lock);
@@ -4685,10 +4693,10 @@ void omapdss_dsi_set_size(struct omap_dss_device *dssdev, u16 w, u16 h)
 }
 EXPORT_SYMBOL(omapdss_dsi_set_size);
 
-void omapdss_dsi_set_pixel_format(struct omap_dss_device *dssdev,
+void omapdss_dsi_set_pixel_format(struct omap_dss_output *out,
 		enum omap_dss_dsi_pixel_format fmt)
 {
-	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+	struct platform_device *dsidev = dsi_get_dsidev_from_output(out);
 	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
 
 	mutex_lock(&dsi->lock);
@@ -4699,10 +4707,10 @@ void omapdss_dsi_set_pixel_format(struct omap_dss_device *dssdev,
 }
 EXPORT_SYMBOL(omapdss_dsi_set_pixel_format);
 
-void omapdss_dsi_set_operation_mode(struct omap_dss_device *dssdev,
+void omapdss_dsi_set_operation_mode(struct omap_dss_output *out,
 		enum omap_dss_dsi_mode mode)
 {
-	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+	struct platform_device *dsidev = dsi_get_dsidev_from_output(out);
 	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
 
 	mutex_lock(&dsi->lock);
@@ -4713,10 +4721,10 @@ void omapdss_dsi_set_operation_mode(struct omap_dss_device *dssdev,
 }
 EXPORT_SYMBOL(omapdss_dsi_set_operation_mode);
 
-void omapdss_dsi_set_videomode_timings(struct omap_dss_device *dssdev,
+void omapdss_dsi_set_videomode_timings(struct omap_dss_output *out,
 		struct omap_dss_dsi_videomode_timings *timings)
 {
-	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+	struct platform_device *dsidev = dsi_get_dsidev_from_output(out);
 	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
 
 	mutex_lock(&dsi->lock);
@@ -4729,7 +4737,8 @@ EXPORT_SYMBOL(omapdss_dsi_set_videomode_timings);
 
 static int __init dsi_init_display(struct omap_dss_device *dssdev)
 {
-	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+	struct platform_device *dsidev +			dsi_get_dsidev_from_id(dssdev->phy.dsi.module);
 	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
 
 	DSSDBG("DSI init\n");
@@ -4755,28 +4764,28 @@ static int __init dsi_init_display(struct omap_dss_device *dssdev)
 	return 0;
 }
 
-int omap_dsi_request_vc(struct omap_dss_device *dssdev, int *channel)
+int omap_dsi_request_vc(struct omap_dss_output *out, int *channel)
 {
-	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+	struct platform_device *dsidev = dsi_get_dsidev_from_output(out);
 	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
 	int i;
 
 	for (i = 0; i < ARRAY_SIZE(dsi->vc); i++) {
 		if (!dsi->vc[i].dssdev) {
-			dsi->vc[i].dssdev = dssdev;
+			dsi->vc[i].dssdev = out->device;
 			*channel = i;
 			return 0;
 		}
 	}
 
-	DSSERR("cannot get VC for display %s", dssdev->name);
+	DSSERR("cannot get VC for display %s", out->device->name);
 	return -ENOSPC;
 }
 EXPORT_SYMBOL(omap_dsi_request_vc);
 
-int omap_dsi_set_vc_id(struct omap_dss_device *dssdev, int channel, int vc_id)
+int omap_dsi_set_vc_id(struct omap_dss_output *out, int channel, int vc_id)
 {
-	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+	struct platform_device *dsidev = dsi_get_dsidev_from_output(out);
 	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
 
 	if (vc_id < 0 || vc_id > 3) {
@@ -4789,9 +4798,9 @@ int omap_dsi_set_vc_id(struct omap_dss_device *dssdev, int channel, int vc_id)
 		return -EINVAL;
 	}
 
-	if (dsi->vc[channel].dssdev != dssdev) {
+	if (dsi->vc[channel].dssdev != out->device) {
 		DSSERR("Virtual Channel not allocated to display %s\n",
-			dssdev->name);
+			out->device->name);
 		return -EINVAL;
 	}
 
@@ -4801,13 +4810,13 @@ int omap_dsi_set_vc_id(struct omap_dss_device *dssdev, int channel, int vc_id)
 }
 EXPORT_SYMBOL(omap_dsi_set_vc_id);
 
-void omap_dsi_release_vc(struct omap_dss_device *dssdev, int channel)
+void omap_dsi_release_vc(struct omap_dss_output *out, int channel)
 {
-	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+	struct platform_device *dsidev = dsi_get_dsidev_from_output(out);
 	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
 
 	if ((channel >= 0 && channel <= 3) &&
-		dsi->vc[channel].dssdev = dssdev) {
+		dsi->vc[channel].dssdev = out->device) {
 		dsi->vc[channel].dssdev = NULL;
 		dsi->vc[channel].vc_id = 0;
 	}
diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index da3f070..f8902f9 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -54,6 +54,7 @@
 #define DISPC_IRQ_SYNC_LOST3		(1 << 29)
 
 struct omap_dss_device;
+struct omap_dss_output;
 struct omap_overlay_manager;
 struct snd_aes_iec958;
 struct snd_cea_861_aud_if;
@@ -278,38 +279,38 @@ struct omap_dss_dsi_videomode_timings {
 	int window_sync;
 };
 
-void dsi_bus_lock(struct omap_dss_device *dssdev);
-void dsi_bus_unlock(struct omap_dss_device *dssdev);
-int dsi_vc_dcs_write(struct omap_dss_device *dssdev, int channel, u8 *data,
+void dsi_bus_lock(struct omap_dss_output *out);
+void dsi_bus_unlock(struct omap_dss_output *out);
+int dsi_vc_dcs_write(struct omap_dss_output *out, int channel, u8 *data,
 		int len);
-int dsi_vc_generic_write(struct omap_dss_device *dssdev, int channel, u8 *data,
+int dsi_vc_generic_write(struct omap_dss_output *out, int channel, u8 *data,
 		int len);
-int dsi_vc_dcs_write_0(struct omap_dss_device *dssdev, int channel, u8 dcs_cmd);
-int dsi_vc_generic_write_0(struct omap_dss_device *dssdev, int channel);
-int dsi_vc_dcs_write_1(struct omap_dss_device *dssdev, int channel, u8 dcs_cmd,
+int dsi_vc_dcs_write_0(struct omap_dss_output *out, int channel, u8 dcs_cmd);
+int dsi_vc_generic_write_0(struct omap_dss_output *out, int channel);
+int dsi_vc_dcs_write_1(struct omap_dss_output *out, int channel, u8 dcs_cmd,
 		u8 param);
-int dsi_vc_generic_write_1(struct omap_dss_device *dssdev, int channel,
+int dsi_vc_generic_write_1(struct omap_dss_output *out, int channel,
 		u8 param);
-int dsi_vc_generic_write_2(struct omap_dss_device *dssdev, int channel,
+int dsi_vc_generic_write_2(struct omap_dss_output *out, int channel,
 		u8 param1, u8 param2);
-int dsi_vc_dcs_write_nosync(struct omap_dss_device *dssdev, int channel,
+int dsi_vc_dcs_write_nosync(struct omap_dss_output *out, int channel,
 		u8 *data, int len);
-int dsi_vc_generic_write_nosync(struct omap_dss_device *dssdev, int channel,
+int dsi_vc_generic_write_nosync(struct omap_dss_output *out, int channel,
 		u8 *data, int len);
-int dsi_vc_dcs_read(struct omap_dss_device *dssdev, int channel, u8 dcs_cmd,
+int dsi_vc_dcs_read(struct omap_dss_output *out, int channel, u8 dcs_cmd,
 		u8 *buf, int buflen);
-int dsi_vc_generic_read_0(struct omap_dss_device *dssdev, int channel, u8 *buf,
+int dsi_vc_generic_read_0(struct omap_dss_output *out, int channel, u8 *buf,
 		int buflen);
-int dsi_vc_generic_read_1(struct omap_dss_device *dssdev, int channel, u8 param,
+int dsi_vc_generic_read_1(struct omap_dss_output *out, int channel, u8 param,
 		u8 *buf, int buflen);
-int dsi_vc_generic_read_2(struct omap_dss_device *dssdev, int channel,
+int dsi_vc_generic_read_2(struct omap_dss_output *out, int channel,
 		u8 param1, u8 param2, u8 *buf, int buflen);
-int dsi_vc_set_max_rx_packet_size(struct omap_dss_device *dssdev, int channel,
+int dsi_vc_set_max_rx_packet_size(struct omap_dss_output *out, int channel,
 		u16 len);
-int dsi_vc_send_null(struct omap_dss_device *dssdev, int channel);
-int dsi_vc_send_bta_sync(struct omap_dss_device *dssdev, int channel);
-int dsi_enable_video_output(struct omap_dss_device *dssdev, int channel);
-void dsi_disable_video_output(struct omap_dss_device *dssdev, int channel);
+int dsi_vc_send_null(struct omap_dss_output *out, int channel);
+int dsi_vc_send_bta_sync(struct omap_dss_output *out, int channel);
+int dsi_enable_video_output(struct omap_dss_output *out, int channel);
+void dsi_disable_video_output(struct omap_dss_output *out, int channel);
 
 /* Board specific data */
 struct omap_dss_board_info {
@@ -758,29 +759,29 @@ int omap_dispc_wait_for_irq_interruptible_timeout(u32 irqmask,
 #define to_dss_driver(x) container_of((x), struct omap_dss_driver, driver)
 #define to_dss_device(x) container_of((x), struct omap_dss_device, dev)
 
-void omapdss_dsi_vc_enable_hs(struct omap_dss_device *dssdev, int channel,
+void omapdss_dsi_vc_enable_hs(struct omap_dss_output *out, int channel,
 		bool enable);
-int omapdss_dsi_enable_te(struct omap_dss_device *dssdev, bool enable);
-void omapdss_dsi_set_timings(struct omap_dss_device *dssdev,
+int omapdss_dsi_enable_te(struct omap_dss_output *out, bool enable);
+void omapdss_dsi_set_timings(struct omap_dss_output *out,
 		struct omap_video_timings *timings);
-void omapdss_dsi_set_size(struct omap_dss_device *dssdev, u16 w, u16 h);
-void omapdss_dsi_set_pixel_format(struct omap_dss_device *dssdev,
+void omapdss_dsi_set_size(struct omap_dss_output *out, u16 w, u16 h);
+void omapdss_dsi_set_pixel_format(struct omap_dss_output *out,
 		enum omap_dss_dsi_pixel_format fmt);
-void omapdss_dsi_set_operation_mode(struct omap_dss_device *dssdev,
+void omapdss_dsi_set_operation_mode(struct omap_dss_output *out,
 		enum omap_dss_dsi_mode mode);
-void omapdss_dsi_set_videomode_timings(struct omap_dss_device *dssdev,
+void omapdss_dsi_set_videomode_timings(struct omap_dss_output *out,
 		struct omap_dss_dsi_videomode_timings *timings);
 
-int omap_dsi_update(struct omap_dss_device *dssdev, int channel,
+int omap_dsi_update(struct omap_dss_output *out, int channel,
 		void (*callback)(int, void *), void *data);
-int omap_dsi_request_vc(struct omap_dss_device *dssdev, int *channel);
-int omap_dsi_set_vc_id(struct omap_dss_device *dssdev, int channel, int vc_id);
-void omap_dsi_release_vc(struct omap_dss_device *dssdev, int channel);
-int omapdss_dsi_configure_pins(struct omap_dss_device *dssdev,
+int omap_dsi_request_vc(struct omap_dss_output *out, int *channel);
+int omap_dsi_set_vc_id(struct omap_dss_output *out, int channel, int vc_id);
+void omap_dsi_release_vc(struct omap_dss_output *out, int channel);
+int omapdss_dsi_configure_pins(struct omap_dss_output *out,
 		const struct omap_dsi_pin_config *pin_cfg);
 
-int omapdss_dsi_display_enable(struct omap_dss_device *dssdev);
-void omapdss_dsi_display_disable(struct omap_dss_device *dssdev,
+int omapdss_dsi_display_enable(struct omap_dss_output *out);
+void omapdss_dsi_display_disable(struct omap_dss_output *out,
 		bool disconnect_lanes, bool enter_ulps);
 
 int omapdss_dpi_display_enable(struct omap_dss_output *out);
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH 13/23] OMAPDSS: SDI: Pass outputs from panel driver to SDI interface driver
From: Archit Taneja @ 2012-08-21  6:10 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, rob, sumit.semwal, Archit Taneja
In-Reply-To: <1345528711-27801-1-git-send-email-archit@ti.com>

With outputs introduces as new entities, we can now pass output pointer to
functions used to configure the connected interface. These functions currently
pass the omap_dss_device pointer, and extract output information via
omap_dss_device. This is unnecessary, and it doesn't make sense for interface
related functions to get the panel's/device's pointer, it should receive a
pointer related to the connected interface, which in our case is the output
entity.

With the addition of outputs. There is a possibility that an omap_dss_device
isn't connected to an output yet. Ensure that panel drivers call the interface
functions only if outputs are non NULL.

Modify SDI functions to pass omap_dss_output pointer instead of omap_dss_device
pointer. Modify the panel drivers to call the updated functions.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/displays/panel-acx565akm.c |   22 ++++++++++-----
 drivers/video/omap2/dss/sdi.c                  |   34 ++++++++++++------------
 include/video/omapdss.h                        |    8 +++---
 3 files changed, 37 insertions(+), 27 deletions(-)

diff --git a/drivers/video/omap2/displays/panel-acx565akm.c b/drivers/video/omap2/displays/panel-acx565akm.c
index c835aa7..c517b29 100644
--- a/drivers/video/omap2/displays/panel-acx565akm.c
+++ b/drivers/video/omap2/displays/panel-acx565akm.c
@@ -591,19 +591,23 @@ static void acx_panel_remove(struct omap_dss_device *dssdev)
 static int acx_panel_power_on(struct omap_dss_device *dssdev)
 {
 	struct acx565akm_device *md = &acx_dev;
+	struct omap_dss_output *out = dssdev->output;
 	int r;
 
 	dev_dbg(&dssdev->dev, "%s\n", __func__);
 
+	if (out = NULL)
+		return -ENODEV;
+
 	if (dssdev->state = OMAP_DSS_DISPLAY_ACTIVE)
 		return 0;
 
 	mutex_lock(&md->mutex);
 
-	omapdss_sdi_set_timings(dssdev, &dssdev->panel.timings);
-	omapdss_sdi_set_datapairs(dssdev, dssdev->phy.sdi.datapairs);
+	omapdss_sdi_set_timings(out, &dssdev->panel.timings);
+	omapdss_sdi_set_datapairs(out, dssdev->phy.sdi.datapairs);
 
-	r = omapdss_sdi_display_enable(dssdev);
+	r = omapdss_sdi_display_enable(out);
 	if (r) {
 		pr_err("%s sdi enable failed\n", __func__);
 		goto fail_unlock;
@@ -646,7 +650,7 @@ static int acx_panel_power_on(struct omap_dss_device *dssdev)
 
 	return acx565akm_bl_update_status(md->bl_dev);
 fail:
-	omapdss_sdi_display_disable(dssdev);
+	omapdss_sdi_display_disable(out);
 fail_unlock:
 	mutex_unlock(&md->mutex);
 	return r;
@@ -655,6 +659,7 @@ fail_unlock:
 static void acx_panel_power_off(struct omap_dss_device *dssdev)
 {
 	struct acx565akm_device *md = &acx_dev;
+	struct omap_dss_output *out = dssdev->output;
 
 	dev_dbg(&dssdev->dev, "%s\n", __func__);
 
@@ -684,7 +689,7 @@ static void acx_panel_power_off(struct omap_dss_device *dssdev)
 	/* FIXME need to tweak this delay */
 	msleep(100);
 
-	omapdss_sdi_display_disable(dssdev);
+	omapdss_sdi_display_disable(out);
 
 	mutex_unlock(&md->mutex);
 }
@@ -734,7 +739,12 @@ static int acx_panel_resume(struct omap_dss_device *dssdev)
 static void acx_panel_set_timings(struct omap_dss_device *dssdev,
 		struct omap_video_timings *timings)
 {
-	omapdss_sdi_set_timings(dssdev, timings);
+	struct omap_dss_output *out = dssdev->output;
+
+	if (out = NULL)
+		return;
+
+	omapdss_sdi_set_timings(out, timings);
 
 	dssdev->panel.timings = *timings;
 }
diff --git a/drivers/video/omap2/dss/sdi.c b/drivers/video/omap2/dss/sdi.c
index a5632d0..4f669be 100644
--- a/drivers/video/omap2/dss/sdi.c
+++ b/drivers/video/omap2/dss/sdi.c
@@ -38,7 +38,7 @@ static struct {
 	int datapairs;
 } sdi;
 
-static void sdi_config_lcd_manager(struct omap_dss_device *dssdev)
+static void sdi_config_lcd_manager(struct omap_dss_output *out)
 {
 	sdi.mgr_config.io_pad_mode = DSS_IO_PAD_MODE_BYPASS;
 
@@ -48,10 +48,10 @@ static void sdi_config_lcd_manager(struct omap_dss_device *dssdev)
 	sdi.mgr_config.video_port_width = 24;
 	sdi.mgr_config.lcden_sig_polarity = 1;
 
-	dss_mgr_set_lcd_config(dssdev->manager, &sdi.mgr_config);
+	dss_mgr_set_lcd_config(out->manager, &sdi.mgr_config);
 }
 
-int omapdss_sdi_display_enable(struct omap_dss_device *dssdev)
+int omapdss_sdi_display_enable(struct omap_dss_output *out)
 {
 	struct omap_video_timings *t = &sdi.timings;
 	struct dss_clock_info dss_cinfo;
@@ -59,12 +59,12 @@ int omapdss_sdi_display_enable(struct omap_dss_device *dssdev)
 	unsigned long pck;
 	int r;
 
-	if (dssdev->manager = NULL) {
+	if (out->manager = NULL) {
 		DSSERR("failed to enable display: no manager\n");
 		return -ENODEV;
 	}
 
-	r = omap_dss_start_device(dssdev);
+	r = omap_dss_start_device(out->device);
 	if (r) {
 		DSSERR("failed to start device\n");
 		goto err_start_dev;
@@ -98,14 +98,13 @@ int omapdss_sdi_display_enable(struct omap_dss_device *dssdev)
 		t->pixel_clock = pck;
 	}
 
-
-	dss_mgr_set_timings(dssdev->manager, t);
+	dss_mgr_set_timings(out->manager, t);
 
 	r = dss_set_clock_div(&dss_cinfo);
 	if (r)
 		goto err_set_dss_clock_div;
 
-	sdi_config_lcd_manager(dssdev);
+	sdi_config_lcd_manager(out);
 
 	dss_sdi_init(sdi.datapairs);
 
@@ -114,7 +113,7 @@ int omapdss_sdi_display_enable(struct omap_dss_device *dssdev)
 		goto err_sdi_enable;
 	mdelay(2);
 
-	r = dss_mgr_enable(dssdev->manager);
+	r = dss_mgr_enable(out->manager);
 	if (r)
 		goto err_mgr_enable;
 
@@ -129,15 +128,15 @@ err_calc_clock_div:
 err_get_dispc:
 	regulator_disable(sdi.vdds_sdi_reg);
 err_reg_enable:
-	omap_dss_stop_device(dssdev);
+	omap_dss_stop_device(out->device);
 err_start_dev:
 	return r;
 }
 EXPORT_SYMBOL(omapdss_sdi_display_enable);
 
-void omapdss_sdi_display_disable(struct omap_dss_device *dssdev)
+void omapdss_sdi_display_disable(struct omap_dss_output *out)
 {
-	dss_mgr_disable(dssdev->manager);
+	dss_mgr_disable(out->manager);
 
 	dss_sdi_disable();
 
@@ -145,28 +144,29 @@ void omapdss_sdi_display_disable(struct omap_dss_device *dssdev)
 
 	regulator_disable(sdi.vdds_sdi_reg);
 
-	omap_dss_stop_device(dssdev);
+	omap_dss_stop_device(out->device);
 }
 EXPORT_SYMBOL(omapdss_sdi_display_disable);
 
-void omapdss_sdi_set_timings(struct omap_dss_device *dssdev,
+void omapdss_sdi_set_timings(struct omap_dss_output *out,
 		struct omap_video_timings *timings)
 {
 	int r;
+	struct omap_dss_device *dssdev = out->device;
 
 	sdi.timings = *timings;
 
 	if (dssdev->state = OMAP_DSS_DISPLAY_ACTIVE) {
-		omapdss_sdi_display_disable(dssdev);
+		omapdss_sdi_display_disable(out);
 
-		r = omapdss_sdi_display_enable(dssdev);
+		r = omapdss_sdi_display_enable(out);
 		if (r)
 			DSSERR("failed to set new timings\n");
 	}
 }
 EXPORT_SYMBOL(omapdss_sdi_set_timings);
 
-void omapdss_sdi_set_datapairs(struct omap_dss_device *dssdev, int datapairs)
+void omapdss_sdi_set_datapairs(struct omap_dss_output *out, int datapairs)
 {
 	sdi.datapairs = datapairs;
 }
diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index f8902f9..cf881c0 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -792,11 +792,11 @@ int dpi_check_timings(struct omap_dss_output *out,
 		struct omap_video_timings *timings);
 void omapdss_dpi_set_data_lines(struct omap_dss_output *out, int data_lines);
 
-int omapdss_sdi_display_enable(struct omap_dss_device *dssdev);
-void omapdss_sdi_display_disable(struct omap_dss_device *dssdev);
-void omapdss_sdi_set_timings(struct omap_dss_device *dssdev,
+int omapdss_sdi_display_enable(struct omap_dss_output *out);
+void omapdss_sdi_display_disable(struct omap_dss_output *out);
+void omapdss_sdi_set_timings(struct omap_dss_output *out,
 		struct omap_video_timings *timings);
-void omapdss_sdi_set_datapairs(struct omap_dss_device *dssdev, int datapairs);
+void omapdss_sdi_set_datapairs(struct omap_dss_output *out, int datapairs);
 
 int omapdss_rfbi_display_enable(struct omap_dss_device *dssdev);
 void omapdss_rfbi_display_disable(struct omap_dss_device *dssdev);
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH 14/23] OMAPDSS: RFBI: Pass outputs from panel driver to RFBI interface driver
From: Archit Taneja @ 2012-08-21  6:10 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, rob, sumit.semwal, Archit Taneja
In-Reply-To: <1345528711-27801-1-git-send-email-archit@ti.com>

With outputs introduces as new entities, we can now pass output pointer to
functions used to configure the connected interface. These functions currently
pass the omap_dss_device pointer, and extract output information via
omap_dss_device. This is unnecessary, and it doesn't make sense for interface
related functions to get the panel's/device's pointer, it should receive a
pointer related to the connected interface, which in our case is the output
entity.

With the addition of outputs. There is a possibility that an omap_dss_device
isn't connected to an output yet. Ensure that panel drivers call the interface
functions only if outputs are non NULL.

Modify DSI functions to pass omap_dss_output pointer instead of omap_dss_device
pointer. Modify the panel drivers to call the updated functions.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/displays/panel-n8x0.c |   38 +++++++++++++++++----------
 drivers/video/omap2/dss/rfbi.c            |   40 +++++++++++++++--------------
 include/video/omapdss.h                   |   16 ++++++------
 3 files changed, 53 insertions(+), 41 deletions(-)

diff --git a/drivers/video/omap2/displays/panel-n8x0.c b/drivers/video/omap2/displays/panel-n8x0.c
index 17ae85e..3601c59 100644
--- a/drivers/video/omap2/displays/panel-n8x0.c
+++ b/drivers/video/omap2/displays/panel-n8x0.c
@@ -116,6 +116,7 @@ static void blizzard_ctrl_setup_update(struct omap_dss_device *dssdev,
 		int x, int y, int w, int h)
 {
 	struct panel_drv_data *ddata = get_drv_data(dssdev);
+	struct omap_dss_output *out = dssdev->output;
 	u8 tmp[18];
 	int x_end, y_end;
 
@@ -150,17 +151,17 @@ static void blizzard_ctrl_setup_update(struct omap_dss_device *dssdev,
 			BLIZZARD_SRC_WRITE_LCD :
 			BLIZZARD_SRC_WRITE_LCD_DESTRUCTIVE;
 
-	omapdss_rfbi_set_pixel_size(dssdev, 16);
-	omapdss_rfbi_set_data_lines(dssdev, 8);
+	omapdss_rfbi_set_pixel_size(out, 16);
+	omapdss_rfbi_set_data_lines(out, 8);
 
-	omap_rfbi_configure(dssdev);
+	omap_rfbi_configure(out);
 
 	blizzard_write(BLIZZARD_INPUT_WIN_X_START_0, tmp, 18);
 
-	omapdss_rfbi_set_pixel_size(dssdev, 16);
-	omapdss_rfbi_set_data_lines(dssdev, 16);
+	omapdss_rfbi_set_pixel_size(out, 16);
+	omapdss_rfbi_set_data_lines(out, 16);
 
-	omap_rfbi_configure(dssdev);
+	omap_rfbi_configure(out);
 }
 
 static void mipid_transfer(struct spi_device *spi, int cmd, const u8 *wbuf,
@@ -288,10 +289,14 @@ static int n8x0_panel_power_on(struct omap_dss_device *dssdev)
 	struct panel_n8x0_data *bdata = get_board_data(dssdev);
 	struct panel_drv_data *ddata = get_drv_data(dssdev);
 	struct spi_device *spi = ddata->spidev;
+	struct omap_dss_output *out = dssdev->output;
 	u8 rev, conf;
 	u8 display_id[3];
 	const char *panel_name;
 
+	if (out = NULL)
+		return -ENODEV;
+
 	if (dssdev->state = OMAP_DSS_DISPLAY_ACTIVE)
 		return 0;
 
@@ -303,13 +308,13 @@ static int n8x0_panel_power_on(struct omap_dss_device *dssdev)
 			goto err_plat_en;
 	}
 
-	omapdss_rfbi_set_size(dssdev, dssdev->panel.timings.x_res,
+	omapdss_rfbi_set_size(out, dssdev->panel.timings.x_res,
 		dssdev->panel.timings.y_res);
-	omapdss_rfbi_set_pixel_size(dssdev, dssdev->ctrl.pixel_size);
-	omapdss_rfbi_set_data_lines(dssdev, dssdev->phy.rfbi.data_lines);
-	omapdss_rfbi_set_interface_timings(dssdev, &dssdev->ctrl.rfbi_timings);
+	omapdss_rfbi_set_pixel_size(out, dssdev->ctrl.pixel_size);
+	omapdss_rfbi_set_data_lines(out, dssdev->phy.rfbi.data_lines);
+	omapdss_rfbi_set_interface_timings(out, &dssdev->ctrl.rfbi_timings);
 
-	r = omapdss_rfbi_display_enable(dssdev);
+	r = omapdss_rfbi_display_enable(out);
 	if (r)
 		goto err_rfbi_en;
 
@@ -373,7 +378,7 @@ err_inv_panel:
 	 */
 	/* gpio_direction_output(bdata->panel_reset, 0); */
 err_inv_chip:
-	omapdss_rfbi_display_disable(dssdev);
+	omapdss_rfbi_display_disable(out);
 err_rfbi_en:
 	if (bdata->platform_disable)
 		bdata->platform_disable(dssdev);
@@ -386,6 +391,7 @@ static void n8x0_panel_power_off(struct omap_dss_device *dssdev)
 {
 	struct panel_n8x0_data *bdata = get_board_data(dssdev);
 	struct panel_drv_data *ddata = get_drv_data(dssdev);
+	struct omap_dss_output *out = dssdev->output;
 	struct spi_device *spi = ddata->spidev;
 
 	if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
@@ -404,7 +410,7 @@ static void n8x0_panel_power_off(struct omap_dss_device *dssdev)
 	 */
 	/* gpio_direction_output(bdata->panel_reset, 0); */
 	gpio_direction_output(bdata->ctrl_pwrdown, 0);
-	omapdss_rfbi_display_disable(dssdev);
+	omapdss_rfbi_display_disable(out);
 }
 
 static const struct rfbi_timings n8x0_panel_timings = {
@@ -637,10 +643,14 @@ static int n8x0_panel_update(struct omap_dss_device *dssdev,
 		u16 x, u16 y, u16 w, u16 h)
 {
 	struct panel_drv_data *ddata = get_drv_data(dssdev);
+	struct omap_dss_output *out = dssdev->output;
 	u16 dw, dh;
 
 	dev_dbg(&dssdev->dev, "update\n");
 
+	if (out = NULL)
+		return -ENODEV;
+
 	dw = dssdev->panel.timings.x_res;
 	dh = dssdev->panel.timings.y_res;
 
@@ -655,7 +665,7 @@ static int n8x0_panel_update(struct omap_dss_device *dssdev,
 
 	blizzard_ctrl_setup_update(dssdev, x, y, w, h);
 
-	omap_rfbi_update(dssdev, update_done, NULL);
+	omap_rfbi_update(out, update_done, NULL);
 
 	mutex_unlock(&ddata->lock);
 
diff --git a/drivers/video/omap2/dss/rfbi.c b/drivers/video/omap2/dss/rfbi.c
index 9d9244c..ca264e8 100644
--- a/drivers/video/omap2/dss/rfbi.c
+++ b/drivers/video/omap2/dss/rfbi.c
@@ -305,11 +305,12 @@ void omap_rfbi_write_pixels(const void __iomem *buf, int scr_width,
 }
 EXPORT_SYMBOL(omap_rfbi_write_pixels);
 
-static int rfbi_transfer_area(struct omap_dss_device *dssdev,
+static int rfbi_transfer_area(struct omap_dss_output *out,
 		void (*callback)(void *data), void *data)
 {
 	u32 l;
 	int r;
+	struct omap_overlay_manager *mgr = out->manager;
 	u16 width = rfbi.timings.x_res;
 	u16 height = rfbi.timings.y_res;
 
@@ -318,9 +319,9 @@ static int rfbi_transfer_area(struct omap_dss_device *dssdev,
 
 	DSSDBG("rfbi_transfer_area %dx%d\n", width, height);
 
-	dss_mgr_set_timings(dssdev->manager, &rfbi.timings);
+	dss_mgr_set_timings(mgr, &rfbi.timings);
 
-	r = dss_mgr_enable(dssdev->manager);
+	r = dss_mgr_enable(mgr);
 	if (r)
 		return r;
 
@@ -767,40 +768,40 @@ static int rfbi_configure(int rfbi_module, int bpp, int lines)
 	return 0;
 }
 
-int omap_rfbi_configure(struct omap_dss_device *dssdev)
+int omap_rfbi_configure(struct omap_dss_output *out)
 {
-	return rfbi_configure(dssdev->phy.rfbi.channel, rfbi.pixel_size,
+	return rfbi_configure(out->device->phy.rfbi.channel, rfbi.pixel_size,
 			rfbi.data_lines);
 }
 EXPORT_SYMBOL(omap_rfbi_configure);
 
-int omap_rfbi_update(struct omap_dss_device *dssdev, void (*callback)(void *),
+int omap_rfbi_update(struct omap_dss_output *out, void (*callback)(void *),
 		void *data)
 {
-	return rfbi_transfer_area(dssdev, callback, data);
+	return rfbi_transfer_area(out, callback, data);
 }
 EXPORT_SYMBOL(omap_rfbi_update);
 
-void omapdss_rfbi_set_size(struct omap_dss_device *dssdev, u16 w, u16 h)
+void omapdss_rfbi_set_size(struct omap_dss_output *out, u16 w, u16 h)
 {
 	rfbi.timings.x_res = w;
 	rfbi.timings.y_res = h;
 }
 EXPORT_SYMBOL(omapdss_rfbi_set_size);
 
-void omapdss_rfbi_set_pixel_size(struct omap_dss_device *dssdev, int pixel_size)
+void omapdss_rfbi_set_pixel_size(struct omap_dss_output *out, int pixel_size)
 {
 	rfbi.pixel_size = pixel_size;
 }
 EXPORT_SYMBOL(omapdss_rfbi_set_pixel_size);
 
-void omapdss_rfbi_set_data_lines(struct omap_dss_device *dssdev, int data_lines)
+void omapdss_rfbi_set_data_lines(struct omap_dss_output *out, int data_lines)
 {
 	rfbi.data_lines = data_lines;
 }
 EXPORT_SYMBOL(omapdss_rfbi_set_data_lines);
 
-void omapdss_rfbi_set_interface_timings(struct omap_dss_device *dssdev,
+void omapdss_rfbi_set_interface_timings(struct omap_dss_output *out,
 		struct rfbi_timings *timings)
 {
 	rfbi.intf_timings = *timings;
@@ -847,7 +848,7 @@ static void rfbi_dump_regs(struct seq_file *s)
 #undef DUMPREG
 }
 
-static void rfbi_config_lcd_manager(struct omap_dss_device *dssdev)
+static void rfbi_config_lcd_manager(struct omap_dss_output *out)
 {
 	struct dss_lcd_mgr_config mgr_config;
 
@@ -860,7 +861,7 @@ static void rfbi_config_lcd_manager(struct omap_dss_device *dssdev)
 	mgr_config.video_port_width = rfbi.pixel_size;
 	mgr_config.lcden_sig_polarity = 0;
 
-	dss_mgr_set_lcd_config(dssdev->manager, &mgr_config);
+	dss_mgr_set_lcd_config(out->manager, &mgr_config);
 
 	/*
 	 * Set rfbi.timings with default values, the x_res and y_res fields
@@ -881,14 +882,15 @@ static void rfbi_config_lcd_manager(struct omap_dss_device *dssdev)
 	rfbi.timings.de_level = OMAPDSS_SIG_ACTIVE_HIGH;
 	rfbi.timings.sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES;
 
-	dss_mgr_set_timings(dssdev->manager, &rfbi.timings);
+	dss_mgr_set_timings(out->manager, &rfbi.timings);
 }
 
-int omapdss_rfbi_display_enable(struct omap_dss_device *dssdev)
+int omapdss_rfbi_display_enable(struct omap_dss_output *out)
 {
 	int r;
+	struct omap_dss_device *dssdev = out->device;
 
-	if (dssdev->manager = NULL) {
+	if (out->manager = NULL) {
 		DSSERR("failed to enable display: no manager\n");
 		return -ENODEV;
 	}
@@ -910,7 +912,7 @@ int omapdss_rfbi_display_enable(struct omap_dss_device *dssdev)
 		goto err1;
 	}
 
-	rfbi_config_lcd_manager(dssdev);
+	rfbi_config_lcd_manager(out);
 
 	rfbi_configure(dssdev->phy.rfbi.channel, rfbi.pixel_size,
 			rfbi.data_lines);
@@ -926,11 +928,11 @@ err0:
 }
 EXPORT_SYMBOL(omapdss_rfbi_display_enable);
 
-void omapdss_rfbi_display_disable(struct omap_dss_device *dssdev)
+void omapdss_rfbi_display_disable(struct omap_dss_output *out)
 {
 	omap_dispc_unregister_isr(framedone_callback, NULL,
 			DISPC_IRQ_FRAMEDONE);
-	omap_dss_stop_device(dssdev);
+	omap_dss_stop_device(out->device);
 
 	rfbi_runtime_put();
 }
diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index cf881c0..723f091 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -798,17 +798,17 @@ void omapdss_sdi_set_timings(struct omap_dss_output *out,
 		struct omap_video_timings *timings);
 void omapdss_sdi_set_datapairs(struct omap_dss_output *out, int datapairs);
 
-int omapdss_rfbi_display_enable(struct omap_dss_device *dssdev);
-void omapdss_rfbi_display_disable(struct omap_dss_device *dssdev);
-int omap_rfbi_update(struct omap_dss_device *dssdev, void (*callback)(void *),
+int omapdss_rfbi_display_enable(struct omap_dss_output *out);
+void omapdss_rfbi_display_disable(struct omap_dss_output *out);
+int omap_rfbi_update(struct omap_dss_output *out, void (*callback)(void *),
 		void *data);
-int omap_rfbi_configure(struct omap_dss_device *dssdev);
-void omapdss_rfbi_set_size(struct omap_dss_device *dssdev, u16 w, u16 h);
-void omapdss_rfbi_set_pixel_size(struct omap_dss_device *dssdev,
+int omap_rfbi_configure(struct omap_dss_output *out);
+void omapdss_rfbi_set_size(struct omap_dss_output *out, u16 w, u16 h);
+void omapdss_rfbi_set_pixel_size(struct omap_dss_output *out,
 		int pixel_size);
-void omapdss_rfbi_set_data_lines(struct omap_dss_device *dssdev,
+void omapdss_rfbi_set_data_lines(struct omap_dss_output *out,
 		int data_lines);
-void omapdss_rfbi_set_interface_timings(struct omap_dss_device *dssdev,
+void omapdss_rfbi_set_interface_timings(struct omap_dss_output *out,
 		struct rfbi_timings *timings);
 
 #endif
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH 15/23] OMAPDSS: RFBI: Add output pointers as arguments to all exported functions
From: Archit Taneja @ 2012-08-21  6:10 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, rob, sumit.semwal, Archit Taneja
In-Reply-To: <1345528711-27801-1-git-send-email-archit@ti.com>

All functions of an interface driver used by a panel driver should have an
omap_dss_output pointer as an argument. This may not be needed by some of the
interfaces now as driver data is globally visible in them. The correct way
to retrieve driver data is to extract the platform device from the output,
and then extract the driver data from the platform device.

Add output arguments from functions used by panel drivers which currently miss
it. This will come to use when the RFBI functions retrieve the driver data
in the correct manner.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/displays/panel-n8x0.c |   78 +++++++++++++++++++----------
 drivers/video/omap2/dss/rfbi.c            |   18 ++++---
 include/video/omapdss.h                   |   20 +++++---
 3 files changed, 74 insertions(+), 42 deletions(-)

diff --git a/drivers/video/omap2/displays/panel-n8x0.c b/drivers/video/omap2/displays/panel-n8x0.c
index 3601c59..23fbb25 100644
--- a/drivers/video/omap2/displays/panel-n8x0.c
+++ b/drivers/video/omap2/displays/panel-n8x0.c
@@ -88,27 +88,34 @@ struct panel_drv_data *get_drv_data(const struct omap_dss_device *dssdev)
 }
 
 
-static inline void blizzard_cmd(u8 cmd)
+static inline void blizzard_cmd(struct omap_dss_device *dssdev, u8 cmd)
 {
-	omap_rfbi_write_command(&cmd, 1);
+	omap_rfbi_write_command(dssdev->output, &cmd, 1);
 }
 
-static inline void blizzard_write(u8 cmd, const u8 *buf, int len)
+static inline void blizzard_write(struct omap_dss_device *dssdev, u8 cmd,
+		const u8 *buf, int len)
 {
-	omap_rfbi_write_command(&cmd, 1);
-	omap_rfbi_write_data(buf, len);
+	struct omap_dss_output *out = dssdev->output;
+
+	omap_rfbi_write_command(out, &cmd, 1);
+	omap_rfbi_write_data(out, buf, len);
 }
 
-static inline void blizzard_read(u8 cmd, u8 *buf, int len)
+static inline void blizzard_read(struct omap_dss_device *dssdev, u8 cmd,
+		u8 *buf, int len)
 {
-	omap_rfbi_write_command(&cmd, 1);
-	omap_rfbi_read_data(buf, len);
+	struct omap_dss_output *out = dssdev->output;
+
+	omap_rfbi_write_command(out, &cmd, 1);
+	omap_rfbi_read_data(out, buf, len);
 }
 
-static u8 blizzard_read_reg(u8 cmd)
+static u8 blizzard_read_reg(struct omap_dss_device *dssdev, u8 cmd)
 {
 	u8 data;
-	blizzard_read(cmd, &data, 1);
+
+	blizzard_read(dssdev, cmd, &data, 1);
 	return data;
 }
 
@@ -156,7 +163,7 @@ static void blizzard_ctrl_setup_update(struct omap_dss_device *dssdev,
 
 	omap_rfbi_configure(out);
 
-	blizzard_write(BLIZZARD_INPUT_WIN_X_START_0, tmp, 18);
+	blizzard_write(dssdev, BLIZZARD_INPUT_WIN_X_START_0, tmp, 18);
 
 	omapdss_rfbi_set_pixel_size(out, 16);
 	omapdss_rfbi_set_data_lines(out, 16);
@@ -318,8 +325,8 @@ static int n8x0_panel_power_on(struct omap_dss_device *dssdev)
 	if (r)
 		goto err_rfbi_en;
 
-	rev = blizzard_read_reg(BLIZZARD_REV_CODE);
-	conf = blizzard_read_reg(BLIZZARD_CONFIG);
+	rev = blizzard_read_reg(dssdev, BLIZZARD_REV_CODE);
+	conf = blizzard_read_reg(dssdev, BLIZZARD_CONFIG);
 
 	switch (rev & 0xfc) {
 	case 0x9c:
@@ -536,17 +543,21 @@ static void n8x0_panel_remove(struct omap_dss_device *dssdev)
 static int n8x0_panel_enable(struct omap_dss_device *dssdev)
 {
 	struct panel_drv_data *ddata = get_drv_data(dssdev);
+	struct omap_dss_output *out = dssdev->output;
 	int r;
 
 	dev_dbg(&dssdev->dev, "enable\n");
 
+	if (out = NULL)
+		return -ENODEV;
+
 	mutex_lock(&ddata->lock);
 
-	rfbi_bus_lock();
+	rfbi_bus_lock(out);
 
 	r = n8x0_panel_power_on(dssdev);
 
-	rfbi_bus_unlock();
+	rfbi_bus_unlock(out);
 
 	if (r) {
 		mutex_unlock(&ddata->lock);
@@ -563,16 +574,20 @@ static int n8x0_panel_enable(struct omap_dss_device *dssdev)
 static void n8x0_panel_disable(struct omap_dss_device *dssdev)
 {
 	struct panel_drv_data *ddata = get_drv_data(dssdev);
+	struct omap_dss_output *out = dssdev->output;
 
 	dev_dbg(&dssdev->dev, "disable\n");
 
+	if (out = NULL)
+		return;
+
 	mutex_lock(&ddata->lock);
 
-	rfbi_bus_lock();
+	rfbi_bus_lock(out);
 
 	n8x0_panel_power_off(dssdev);
 
-	rfbi_bus_unlock();
+	rfbi_bus_unlock(out);
 
 	dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
 
@@ -582,16 +597,20 @@ static void n8x0_panel_disable(struct omap_dss_device *dssdev)
 static int n8x0_panel_suspend(struct omap_dss_device *dssdev)
 {
 	struct panel_drv_data *ddata = get_drv_data(dssdev);
+	struct omap_dss_output *out = dssdev->output;
 
 	dev_dbg(&dssdev->dev, "suspend\n");
 
+	if (out = NULL)
+		return -ENODEV;
+
 	mutex_lock(&ddata->lock);
 
-	rfbi_bus_lock();
+	rfbi_bus_lock(out);
 
 	n8x0_panel_power_off(dssdev);
 
-	rfbi_bus_unlock();
+	rfbi_bus_unlock(out);
 
 	dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
 
@@ -603,17 +622,21 @@ static int n8x0_panel_suspend(struct omap_dss_device *dssdev)
 static int n8x0_panel_resume(struct omap_dss_device *dssdev)
 {
 	struct panel_drv_data *ddata = get_drv_data(dssdev);
+	struct omap_dss_output *out = dssdev->output;
 	int r;
 
 	dev_dbg(&dssdev->dev, "resume\n");
 
+	if (out = NULL)
+		return -ENODEV;
+
 	mutex_lock(&ddata->lock);
 
-	rfbi_bus_lock();
+	rfbi_bus_lock(out);
 
 	r = n8x0_panel_power_on(dssdev);
 
-	rfbi_bus_unlock();
+	rfbi_bus_unlock(out);
 
 	if (r) {
 		mutex_unlock(&ddata->lock);
@@ -636,7 +659,9 @@ static void n8x0_panel_get_resolution(struct omap_dss_device *dssdev,
 
 static void update_done(void *data)
 {
-	rfbi_bus_unlock();
+	struct omap_dss_device *dssdev = (struct omap_dss_device *) data;
+
+	rfbi_bus_unlock(dssdev->output);
 }
 
 static int n8x0_panel_update(struct omap_dss_device *dssdev,
@@ -661,11 +686,11 @@ static int n8x0_panel_update(struct omap_dss_device *dssdev,
 	}
 
 	mutex_lock(&ddata->lock);
-	rfbi_bus_lock();
+	rfbi_bus_lock(out);
 
 	blizzard_ctrl_setup_update(dssdev, x, y, w, h);
 
-	omap_rfbi_update(out, update_done, NULL);
+	omap_rfbi_update(out, update_done, dssdev);
 
 	mutex_unlock(&ddata->lock);
 
@@ -675,12 +700,13 @@ static int n8x0_panel_update(struct omap_dss_device *dssdev,
 static int n8x0_panel_sync(struct omap_dss_device *dssdev)
 {
 	struct panel_drv_data *ddata = get_drv_data(dssdev);
+	struct omap_dss_output *out = dssdev->output;
 
 	dev_dbg(&dssdev->dev, "sync\n");
 
 	mutex_lock(&ddata->lock);
-	rfbi_bus_lock();
-	rfbi_bus_unlock();
+	rfbi_bus_lock(out);
+	rfbi_bus_unlock(out);
 	mutex_unlock(&ddata->lock);
 
 	return 0;
diff --git a/drivers/video/omap2/dss/rfbi.c b/drivers/video/omap2/dss/rfbi.c
index ca264e8..36bbe9a 100644
--- a/drivers/video/omap2/dss/rfbi.c
+++ b/drivers/video/omap2/dss/rfbi.c
@@ -149,19 +149,20 @@ static void rfbi_runtime_put(void)
 	WARN_ON(r < 0 && r != -ENOSYS);
 }
 
-void rfbi_bus_lock(void)
+void rfbi_bus_lock(struct omap_dss_output *out)
 {
 	down(&rfbi.bus_lock);
 }
 EXPORT_SYMBOL(rfbi_bus_lock);
 
-void rfbi_bus_unlock(void)
+void rfbi_bus_unlock(struct omap_dss_output *out)
 {
 	up(&rfbi.bus_lock);
 }
 EXPORT_SYMBOL(rfbi_bus_unlock);
 
-void omap_rfbi_write_command(const void *buf, u32 len)
+void omap_rfbi_write_command(struct omap_dss_output *out, const void *buf,
+		u32 len)
 {
 	switch (rfbi.parallelmode) {
 	case OMAP_DSS_RFBI_PARALLELMODE_8:
@@ -189,7 +190,7 @@ void omap_rfbi_write_command(const void *buf, u32 len)
 }
 EXPORT_SYMBOL(omap_rfbi_write_command);
 
-void omap_rfbi_read_data(void *buf, u32 len)
+void omap_rfbi_read_data(struct omap_dss_output *out, void *buf, u32 len)
 {
 	switch (rfbi.parallelmode) {
 	case OMAP_DSS_RFBI_PARALLELMODE_8:
@@ -221,7 +222,7 @@ void omap_rfbi_read_data(void *buf, u32 len)
 }
 EXPORT_SYMBOL(omap_rfbi_read_data);
 
-void omap_rfbi_write_data(const void *buf, u32 len)
+void omap_rfbi_write_data(struct omap_dss_output *out, const void *buf, u32 len)
 {
 	switch (rfbi.parallelmode) {
 	case OMAP_DSS_RFBI_PARALLELMODE_8:
@@ -250,7 +251,8 @@ void omap_rfbi_write_data(const void *buf, u32 len)
 }
 EXPORT_SYMBOL(omap_rfbi_write_data);
 
-void omap_rfbi_write_pixels(const void __iomem *buf, int scr_width,
+void omap_rfbi_write_pixels(struct omap_dss_output *out,
+		const void __iomem *buf, int scr_width,
 		u16 x, u16 y,
 		u16 w, u16 h)
 {
@@ -572,7 +574,7 @@ static int rfbi_convert_timings(struct rfbi_timings *t)
 }
 
 /* xxx FIX module selection missing */
-int omap_rfbi_setup_te(enum omap_rfbi_te_mode mode,
+int omap_rfbi_setup_te(struct omap_dss_output *out, enum omap_rfbi_te_mode mode,
 			     unsigned hs_pulse_time, unsigned vs_pulse_time,
 			     int hs_pol_inv, int vs_pol_inv, int extif_div)
 {
@@ -614,7 +616,7 @@ int omap_rfbi_setup_te(enum omap_rfbi_te_mode mode,
 EXPORT_SYMBOL(omap_rfbi_setup_te);
 
 /* xxx FIX module selection missing */
-int omap_rfbi_enable_te(bool enable, unsigned line)
+int omap_rfbi_enable_te(struct omap_dss_output *out, bool enable, unsigned line)
 {
 	u32 l;
 
diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index 723f091..b3faea7 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -239,18 +239,22 @@ struct rfbi_timings {
 	int converted;
 };
 
-void omap_rfbi_write_command(const void *buf, u32 len);
-void omap_rfbi_read_data(void *buf, u32 len);
-void omap_rfbi_write_data(const void *buf, u32 len);
-void omap_rfbi_write_pixels(const void __iomem *buf, int scr_width,
+void omap_rfbi_write_command(struct omap_dss_output *out, const void *buf,
+		u32 len);
+void omap_rfbi_read_data(struct omap_dss_output *out, void *buf, u32 len);
+void omap_rfbi_write_data(struct omap_dss_output *out, const void *buf,
+		u32 len);
+void omap_rfbi_write_pixels(struct omap_dss_output *out,
+		const void __iomem *buf, int scr_width,
 		u16 x, u16 y,
 		u16 w, u16 h);
-int omap_rfbi_enable_te(bool enable, unsigned line);
-int omap_rfbi_setup_te(enum omap_rfbi_te_mode mode,
+int omap_rfbi_enable_te(struct omap_dss_output *out, bool enable,
+		unsigned line);
+int omap_rfbi_setup_te(struct omap_dss_output *out, enum omap_rfbi_te_mode mode,
 			     unsigned hs_pulse_time, unsigned vs_pulse_time,
 			     int hs_pol_inv, int vs_pol_inv, int extif_div);
-void rfbi_bus_lock(void);
-void rfbi_bus_unlock(void);
+void rfbi_bus_lock(struct omap_dss_output *out);
+void rfbi_bus_unlock(struct omap_dss_output *out);
 
 /* DSI */
 
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH 16/23] OMAPDSS: VENC: Pass outputs from panel driver to VENC interface driver
From: Archit Taneja @ 2012-08-21  6:10 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, rob, sumit.semwal, Archit Taneja
In-Reply-To: <1345528711-27801-1-git-send-email-archit@ti.com>

With outputs introduces as new entities, we can now pass output pointer to
functions used to configure the connected interface. These functions currently
pass the omap_dss_device pointer, and extract output information via
omap_dss_device. This is unnecessary, and it doesn't make sense for interface
related functions to get the panel's/device's pointer, it should receive a
pointer related to the connected interface, which in our case is the output
entity.

With the addition of outputs. There is a possibility that an omap_dss_device
isn't connected to an output yet. Ensure that the venc panel driver calls the
interface functions only if output is non NULL.

Modify VENC functions to pass omap_dss_output pointer instead of omap_dss_device
pointer. Modify the venc panel driver to call the updated functions.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/dss/dss.h        |   16 +++++-----
 drivers/video/omap2/dss/venc.c       |   58 +++++++++++++++++-----------------
 drivers/video/omap2/dss/venc_panel.c |   53 ++++++++++++++++++++++++-------
 3 files changed, 78 insertions(+), 49 deletions(-)

diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index a119506..5fd3cc5 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -476,17 +476,17 @@ static inline unsigned long venc_get_pixel_clock(void)
 	return 0;
 }
 #endif
-int omapdss_venc_display_enable(struct omap_dss_device *dssdev);
-void omapdss_venc_display_disable(struct omap_dss_device *dssdev);
-void omapdss_venc_set_timings(struct omap_dss_device *dssdev,
+int omapdss_venc_display_enable(struct omap_dss_output *out);
+void omapdss_venc_display_disable(struct omap_dss_output *out);
+void omapdss_venc_set_timings(struct omap_dss_output *out,
 		struct omap_video_timings *timings);
-int omapdss_venc_check_timings(struct omap_dss_device *dssdev,
+int omapdss_venc_check_timings(struct omap_dss_output *out,
 		struct omap_video_timings *timings);
-u32 omapdss_venc_get_wss(struct omap_dss_device *dssdev);
-int omapdss_venc_set_wss(struct omap_dss_device *dssdev, u32 wss);
-void omapdss_venc_set_type(struct omap_dss_device *dssdev,
+u32 omapdss_venc_get_wss(struct omap_dss_output *out);
+int omapdss_venc_set_wss(struct omap_dss_output *out, u32 wss);
+void omapdss_venc_set_type(struct omap_dss_output *out,
 		enum omap_dss_venc_type type);
-void omapdss_venc_invert_vid_out_polarity(struct omap_dss_device *dssdev,
+void omapdss_venc_invert_vid_out_polarity(struct omap_dss_output *out,
 		bool invert_polarity);
 int venc_panel_init(void);
 void venc_panel_exit(void);
diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c
index 264c5ec..7b399e7 100644
--- a/drivers/video/omap2/dss/venc.c
+++ b/drivers/video/omap2/dss/venc.c
@@ -426,7 +426,7 @@ static const struct venc_config *venc_timings_to_config(
 	return NULL;
 }
 
-static int venc_power_on(struct omap_dss_device *dssdev)
+static int venc_power_on(struct omap_dss_output *out)
 {
 	u32 l;
 	int r;
@@ -453,13 +453,13 @@ static int venc_power_on(struct omap_dss_device *dssdev)
 
 	venc_write_reg(VENC_OUTPUT_CONTROL, l);
 
-	dss_mgr_set_timings(dssdev->manager, &venc.timings);
+	dss_mgr_set_timings(out->manager, &venc.timings);
 
 	r = regulator_enable(venc.vdda_dac_reg);
 	if (r)
 		goto err1;
 
-	r = dss_mgr_enable(dssdev->manager);
+	r = dss_mgr_enable(out->manager);
 	if (r)
 		goto err2;
 
@@ -476,12 +476,12 @@ err0:
 	return r;
 }
 
-static void venc_power_off(struct omap_dss_device *dssdev)
+static void venc_power_off(struct omap_dss_output *out)
 {
 	venc_write_reg(VENC_OUTPUT_CONTROL, 0);
 	dss_set_dac_pwrdn_bgz(0);
 
-	dss_mgr_disable(dssdev->manager);
+	dss_mgr_disable(out->manager);
 
 	regulator_disable(venc.vdda_dac_reg);
 
@@ -494,7 +494,7 @@ unsigned long venc_get_pixel_clock(void)
 	return 13500000;
 }
 
-int omapdss_venc_display_enable(struct omap_dss_device *dssdev)
+int omapdss_venc_display_enable(struct omap_dss_output *out)
 {
 	int r;
 
@@ -502,23 +502,23 @@ int omapdss_venc_display_enable(struct omap_dss_device *dssdev)
 
 	mutex_lock(&venc.venc_lock);
 
-	if (dssdev->manager = NULL) {
+	if (out->manager = NULL) {
 		DSSERR("Failed to enable display: no manager\n");
 		r = -ENODEV;
 		goto err0;
 	}
 
-	r = omap_dss_start_device(dssdev);
+	r = omap_dss_start_device(out->device);
 	if (r) {
 		DSSERR("failed to start device\n");
 		goto err0;
 	}
 
-	if (dssdev->platform_enable)
-		dssdev->platform_enable(dssdev);
+	if (out->device->platform_enable)
+		out->device->platform_enable(out->device);
 
 
-	r = venc_power_on(dssdev);
+	r = venc_power_on(out);
 	if (r)
 		goto err1;
 
@@ -528,31 +528,31 @@ int omapdss_venc_display_enable(struct omap_dss_device *dssdev)
 
 	return 0;
 err1:
-	if (dssdev->platform_disable)
-		dssdev->platform_disable(dssdev);
-	omap_dss_stop_device(dssdev);
+	if (out->device->platform_disable)
+		out->device->platform_disable(out->device);
+	omap_dss_stop_device(out->device);
 err0:
 	mutex_unlock(&venc.venc_lock);
 	return r;
 }
 
-void omapdss_venc_display_disable(struct omap_dss_device *dssdev)
+void omapdss_venc_display_disable(struct omap_dss_output *out)
 {
 	DSSDBG("venc_display_disable\n");
 
 	mutex_lock(&venc.venc_lock);
 
-	venc_power_off(dssdev);
+	venc_power_off(out);
 
-	omap_dss_stop_device(dssdev);
+	omap_dss_stop_device(out->device);
 
-	if (dssdev->platform_disable)
-		dssdev->platform_disable(dssdev);
+	if (out->device->platform_disable)
+		out->device->platform_disable(out->device);
 
 	mutex_unlock(&venc.venc_lock);
 }
 
-void omapdss_venc_set_timings(struct omap_dss_device *dssdev,
+void omapdss_venc_set_timings(struct omap_dss_output *out,
 		struct omap_video_timings *timings)
 {
 	DSSDBG("venc_set_timings\n");
@@ -565,23 +565,23 @@ void omapdss_venc_set_timings(struct omap_dss_device *dssdev,
 
 	venc.timings = *timings;
 
-	if (dssdev->state = OMAP_DSS_DISPLAY_ACTIVE) {
+	if (out->device->state = OMAP_DSS_DISPLAY_ACTIVE) {
 		int r;
 
 		/* turn the venc off and on to get new timings to use */
-		venc_power_off(dssdev);
+		venc_power_off(out);
 
-		r = venc_power_on(dssdev);
+		r = venc_power_on(out);
 		if (r)
 			DSSERR("failed to power on VENC\n");
 	} else {
-		dss_mgr_set_timings(dssdev->manager, timings);
+		dss_mgr_set_timings(out->manager, timings);
 	}
 
 	mutex_unlock(&venc.venc_lock);
 }
 
-int omapdss_venc_check_timings(struct omap_dss_device *dssdev,
+int omapdss_venc_check_timings(struct omap_dss_output *out,
 		struct omap_video_timings *timings)
 {
 	DSSDBG("venc_check_timings\n");
@@ -595,13 +595,13 @@ int omapdss_venc_check_timings(struct omap_dss_device *dssdev,
 	return -EINVAL;
 }
 
-u32 omapdss_venc_get_wss(struct omap_dss_device *dssdev)
+u32 omapdss_venc_get_wss(struct omap_dss_output *out)
 {
 	/* Invert due to VENC_L21_WC_CTL:INV=1 */
 	return (venc.wss_data >> 8) ^ 0xfffff;
 }
 
-int omapdss_venc_set_wss(struct omap_dss_device *dssdev, u32 wss)
+int omapdss_venc_set_wss(struct omap_dss_output *out, u32 wss)
 {
 	const struct venc_config *config;
 	int r;
@@ -630,7 +630,7 @@ err:
 	return r;
 }
 
-void omapdss_venc_set_type(struct omap_dss_device *dssdev,
+void omapdss_venc_set_type(struct omap_dss_output *out,
 		enum omap_dss_venc_type type)
 {
 	mutex_lock(&venc.venc_lock);
@@ -640,7 +640,7 @@ void omapdss_venc_set_type(struct omap_dss_device *dssdev,
 	mutex_unlock(&venc.venc_lock);
 }
 
-void omapdss_venc_invert_vid_out_polarity(struct omap_dss_device *dssdev,
+void omapdss_venc_invert_vid_out_polarity(struct omap_dss_output *out,
 		bool invert_polarity)
 {
 	mutex_lock(&venc.venc_lock);
diff --git a/drivers/video/omap2/dss/venc_panel.c b/drivers/video/omap2/dss/venc_panel.c
index d55b878..0669f10 100644
--- a/drivers/video/omap2/dss/venc_panel.c
+++ b/drivers/video/omap2/dss/venc_panel.c
@@ -67,11 +67,14 @@ static ssize_t display_output_type_store(struct device *dev,
 	mutex_lock(&venc_panel.lock);
 
 	if (dssdev->phy.venc.type != new_type) {
+		struct omap_dss_output *out = dssdev->output;
+
 		dssdev->phy.venc.type = new_type;
-		omapdss_venc_set_type(dssdev, new_type);
+		omapdss_venc_set_type(out, new_type);
+
 		if (dssdev->state = OMAP_DSS_DISPLAY_ACTIVE) {
-			omapdss_venc_display_disable(dssdev);
-			omapdss_venc_display_enable(dssdev);
+			omapdss_venc_display_disable(out);
+			omapdss_venc_display_enable(out);
 		}
 	}
 
@@ -117,10 +120,14 @@ static void venc_panel_remove(struct omap_dss_device *dssdev)
 
 static int venc_panel_enable(struct omap_dss_device *dssdev)
 {
+	struct omap_dss_output *out = dssdev->output;
 	int r;
 
 	dev_dbg(&dssdev->dev, "venc_panel_enable\n");
 
+	if (out = NULL)
+		return -ENODEV;
+
 	mutex_lock(&venc_panel.lock);
 
 	if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) {
@@ -128,12 +135,12 @@ static int venc_panel_enable(struct omap_dss_device *dssdev)
 		goto err;
 	}
 
-	omapdss_venc_set_timings(dssdev, &dssdev->panel.timings);
-	omapdss_venc_set_type(dssdev, dssdev->phy.venc.type);
-	omapdss_venc_invert_vid_out_polarity(dssdev,
+	omapdss_venc_set_timings(out, &dssdev->panel.timings);
+	omapdss_venc_set_type(out, dssdev->phy.venc.type);
+	omapdss_venc_invert_vid_out_polarity(out,
 		dssdev->phy.venc.invert_polarity);
 
-	r = omapdss_venc_display_enable(dssdev);
+	r = omapdss_venc_display_enable(out);
 	if (r)
 		goto err;
 
@@ -150,6 +157,8 @@ err:
 
 static void venc_panel_disable(struct omap_dss_device *dssdev)
 {
+	struct omap_dss_output *out = dssdev->output;
+
 	dev_dbg(&dssdev->dev, "venc_panel_disable\n");
 
 	mutex_lock(&venc_panel.lock);
@@ -163,7 +172,7 @@ static void venc_panel_disable(struct omap_dss_device *dssdev)
 		goto end;
 	}
 
-	omapdss_venc_display_disable(dssdev);
+	omapdss_venc_display_disable(out);
 
 	dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
 end:
@@ -184,11 +193,16 @@ static int venc_panel_resume(struct omap_dss_device *dssdev)
 static void venc_panel_set_timings(struct omap_dss_device *dssdev,
 		struct omap_video_timings *timings)
 {
+	struct omap_dss_output *out = dssdev->output;
+
 	dev_dbg(&dssdev->dev, "venc_panel_set_timings\n");
 
+	if (out = NULL)
+		return;
+
 	mutex_lock(&venc_panel.lock);
 
-	omapdss_venc_set_timings(dssdev, timings);
+	omapdss_venc_set_timings(out, timings);
 	dssdev->panel.timings = *timings;
 
 	mutex_unlock(&venc_panel.lock);
@@ -197,23 +211,38 @@ static void venc_panel_set_timings(struct omap_dss_device *dssdev,
 static int venc_panel_check_timings(struct omap_dss_device *dssdev,
 		struct omap_video_timings *timings)
 {
+	struct omap_dss_output *out = dssdev->output;
+
 	dev_dbg(&dssdev->dev, "venc_panel_check_timings\n");
 
-	return omapdss_venc_check_timings(dssdev, timings);
+	if (out = NULL)
+		return -ENODEV;
+
+	return omapdss_venc_check_timings(out, timings);
 }
 
 static u32 venc_panel_get_wss(struct omap_dss_device *dssdev)
 {
+	struct omap_dss_output *out = dssdev->output;
+
 	dev_dbg(&dssdev->dev, "venc_panel_get_wss\n");
 
-	return omapdss_venc_get_wss(dssdev);
+	if (out = NULL)
+		return -ENODEV;
+
+	return omapdss_venc_get_wss(out);
 }
 
 static int venc_panel_set_wss(struct omap_dss_device *dssdev, u32 wss)
 {
+	struct omap_dss_output *out = dssdev->output;
+
 	dev_dbg(&dssdev->dev, "venc_panel_set_wss\n");
 
-	return omapdss_venc_set_wss(dssdev, wss);
+	if (out = NULL)
+		return -ENODEV;
+
+	return omapdss_venc_set_wss(out, wss);
 }
 
 static struct omap_dss_driver venc_driver = {
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH 17/23] OMAPDSS: HDMI: Pass outputs from panel driver to HDMI interface driver
From: Archit Taneja @ 2012-08-21  6:10 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, rob, sumit.semwal, Archit Taneja
In-Reply-To: <1345528711-27801-1-git-send-email-archit@ti.com>

With outputs introduces as new entities, we can now pass output pointer to
functions used to configure the connected interface. These functions currently
pass the omap_dss_device pointer, and extract output information via
omap_dss_device. This is unnecessary, and it doesn't make sense for interface
related functions to get the panel's/device's pointer, it should receive a
pointer related to the connected interface, which in our case is the output
entity.

With the addition of outputs. There is a possibility that an omap_dss_device
isn't connected to an output yet. Ensure that panel drivers call the interface
functions only if outputs are non NULL.

Modify HDMI functions to pass omap_dss_output pointer instead of omap_dss_device
pointer. Modify the panel drivers to call the updated functions.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/dss/dss.h        |   10 +++----
 drivers/video/omap2/dss/hdmi.c       |   50 +++++++++++++++++++---------------
 drivers/video/omap2/dss/hdmi_panel.c |   47 ++++++++++++++++++++++++--------
 3 files changed, 69 insertions(+), 38 deletions(-)

diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index 5fd3cc5..bfa8b4d 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -503,12 +503,12 @@ static inline unsigned long hdmi_get_pixel_clock(void)
 	return 0;
 }
 #endif
-int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev);
-void omapdss_hdmi_display_disable(struct omap_dss_device *dssdev);
-void omapdss_hdmi_display_set_timing(struct omap_dss_device *dssdev,
+int omapdss_hdmi_display_enable(struct omap_dss_output *out);
+void omapdss_hdmi_display_disable(struct omap_dss_output *out);
+void omapdss_hdmi_display_set_timing(struct omap_dss_output *out,
+		struct omap_video_timings *timings);
+int omapdss_hdmi_display_check_timing(struct omap_dss_output *out,
 		struct omap_video_timings *timings);
-int omapdss_hdmi_display_check_timing(struct omap_dss_device *dssdev,
-					struct omap_video_timings *timings);
 int omapdss_hdmi_read_edid(u8 *buf, int len);
 bool omapdss_hdmi_detect(void);
 int hdmi_panel_init(void);
diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c
index d32dbc3..16b745c 100644
--- a/drivers/video/omap2/dss/hdmi.c
+++ b/drivers/video/omap2/dss/hdmi.c
@@ -405,9 +405,10 @@ unsigned long hdmi_get_pixel_clock(void)
 	return hdmi.ip_data.cfg.timings.pixel_clock * 1000;
 }
 
-static void hdmi_compute_pll(struct omap_dss_device *dssdev, int phy,
+static void hdmi_compute_pll(struct omap_dss_output *out, int phy,
 		struct hdmi_pll_info *pi)
 {
+	struct omap_dss_device *dssdev = out->device;
 	unsigned long clkin, refclk;
 	u32 mf;
 
@@ -456,7 +457,7 @@ static void hdmi_compute_pll(struct omap_dss_device *dssdev, int phy,
 	DSSDBG("range = %d sd = %d\n", pi->dcofreq, pi->regsd);
 }
 
-static int hdmi_power_on(struct omap_dss_device *dssdev)
+static int hdmi_power_on(struct omap_dss_output *out)
 {
 	int r;
 	struct omap_video_timings *p;
@@ -466,7 +467,7 @@ static int hdmi_power_on(struct omap_dss_device *dssdev)
 	if (r)
 		return r;
 
-	dss_mgr_disable(dssdev->manager);
+	dss_mgr_disable(out->manager);
 
 	p = &hdmi.ip_data.cfg.timings;
 
@@ -474,7 +475,7 @@ static int hdmi_power_on(struct omap_dss_device *dssdev)
 
 	phy = p->pixel_clock;
 
-	hdmi_compute_pll(dssdev, phy, &hdmi.ip_data.pll_data);
+	hdmi_compute_pll(out, phy, &hdmi.ip_data.pll_data);
 
 	hdmi.ip_data.ops->video_disable(&hdmi.ip_data);
 
@@ -502,19 +503,19 @@ static int hdmi_power_on(struct omap_dss_device *dssdev)
 	 * dynamically by user. This can be moved to single location , say
 	 * Boardfile.
 	 */
-	dss_select_dispc_clk_source(dssdev->clocks.dispc.dispc_fclk_src);
+	dss_select_dispc_clk_source(out->device->clocks.dispc.dispc_fclk_src);
 
 	/* bypass TV gamma table */
 	dispc_enable_gamma_table(0);
 
 	/* tv size */
-	dss_mgr_set_timings(dssdev->manager, p);
+	dss_mgr_set_timings(out->manager, p);
 
 	r = hdmi.ip_data.ops->video_enable(&hdmi.ip_data);
 	if (r)
 		goto err_vid_enable;
 
-	r = dss_mgr_enable(dssdev->manager);
+	r = dss_mgr_enable(out->manager);
 	if (r)
 		goto err_mgr_enable;
 
@@ -531,9 +532,9 @@ err:
 	return -EIO;
 }
 
-static void hdmi_power_off(struct omap_dss_device *dssdev)
+static void hdmi_power_off(struct omap_dss_output *out)
 {
-	dss_mgr_disable(dssdev->manager);
+	dss_mgr_disable(out->manager);
 
 	hdmi.ip_data.ops->video_disable(&hdmi.ip_data);
 	hdmi.ip_data.ops->phy_disable(&hdmi.ip_data);
@@ -541,8 +542,8 @@ static void hdmi_power_off(struct omap_dss_device *dssdev)
 	hdmi_runtime_put();
 }
 
-int omapdss_hdmi_display_check_timing(struct omap_dss_device *dssdev,
-					struct omap_video_timings *timings)
+int omapdss_hdmi_display_check_timing(struct omap_dss_output *out,
+		struct omap_video_timings *timings)
 {
 	struct hdmi_cm cm;
 
@@ -555,7 +556,7 @@ int omapdss_hdmi_display_check_timing(struct omap_dss_device *dssdev,
 
 }
 
-void omapdss_hdmi_display_set_timing(struct omap_dss_device *dssdev,
+void omapdss_hdmi_display_set_timing(struct omap_dss_output *out,
 		struct omap_video_timings *timings)
 {
 	struct hdmi_cm cm;
@@ -570,16 +571,16 @@ void omapdss_hdmi_display_set_timing(struct omap_dss_device *dssdev,
 	if (t != NULL)
 		hdmi.ip_data.cfg = *t;
 
-	if (dssdev->state = OMAP_DSS_DISPLAY_ACTIVE) {
+	if (out->device->state = OMAP_DSS_DISPLAY_ACTIVE) {
 		int r;
 
-		hdmi_power_off(dssdev);
+		hdmi_power_off(out);
 
-		r = hdmi_power_on(dssdev);
+		r = hdmi_power_on(out);
 		if (r)
 			DSSERR("failed to power on device\n");
 	} else {
-		dss_mgr_set_timings(dssdev->manager, &t->timings);
+		dss_mgr_set_timings(out->manager, &t->timings);
 	}
 
 	mutex_unlock(&hdmi.lock);
@@ -635,21 +636,24 @@ bool omapdss_hdmi_detect(void)
 	return r = 1;
 }
 
-int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev)
+int omapdss_hdmi_display_enable(struct omap_dss_output *out)
 {
-	struct omap_dss_hdmi_data *priv = dssdev->data;
+	struct omap_dss_device *dssdev = out->device;
+	struct omap_dss_hdmi_data *priv;
 	int r = 0;
 
 	DSSDBG("ENTER hdmi_display_enable\n");
 
 	mutex_lock(&hdmi.lock);
 
-	if (dssdev->manager = NULL) {
+	if (out = NULL || out->manager = NULL || dssdev = NULL) {
 		DSSERR("failed to enable display: no manager\n");
 		r = -ENODEV;
 		goto err0;
 	}
 
+	priv = dssdev->data;
+
 	hdmi.ip_data.hpd_gpio = priv->hpd_gpio;
 
 	r = omap_dss_start_device(dssdev);
@@ -666,7 +670,7 @@ int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev)
 		}
 	}
 
-	r = hdmi_power_on(dssdev);
+	r = hdmi_power_on(out);
 	if (r) {
 		DSSERR("failed to power on device\n");
 		goto err2;
@@ -685,13 +689,15 @@ err0:
 	return r;
 }
 
-void omapdss_hdmi_display_disable(struct omap_dss_device *dssdev)
+void omapdss_hdmi_display_disable(struct omap_dss_output *out)
 {
+	struct omap_dss_device *dssdev = out->device;
+
 	DSSDBG("Enter hdmi_display_disable\n");
 
 	mutex_lock(&hdmi.lock);
 
-	hdmi_power_off(dssdev);
+	hdmi_power_off(out);
 
 	if (dssdev->platform_disable)
 		dssdev->platform_disable(dssdev);
diff --git a/drivers/video/omap2/dss/hdmi_panel.c b/drivers/video/omap2/dss/hdmi_panel.c
index 2feb2cd..fb35bbb 100644
--- a/drivers/video/omap2/dss/hdmi_panel.c
+++ b/drivers/video/omap2/dss/hdmi_panel.c
@@ -233,9 +233,13 @@ static int hdmi_panel_audio_config(struct omap_dss_device *dssdev,
 
 static int hdmi_panel_enable(struct omap_dss_device *dssdev)
 {
+	struct omap_dss_output *out = dssdev->output;
 	int r = 0;
 	DSSDBG("ENTER hdmi_panel_enable\n");
 
+	if (out = NULL)
+		return -ENODEV;
+
 	mutex_lock(&hdmi.lock);
 
 	if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) {
@@ -243,9 +247,9 @@ static int hdmi_panel_enable(struct omap_dss_device *dssdev)
 		goto err;
 	}
 
-	omapdss_hdmi_display_set_timing(dssdev, &dssdev->panel.timings);
+	omapdss_hdmi_display_set_timing(out, &dssdev->panel.timings);
 
-	r = omapdss_hdmi_display_enable(dssdev);
+	r = omapdss_hdmi_display_enable(out);
 	if (r) {
 		DSSERR("failed to power on\n");
 		goto err;
@@ -261,6 +265,7 @@ err:
 
 static void hdmi_panel_disable(struct omap_dss_device *dssdev)
 {
+	struct omap_dss_output *out = dssdev->output;
 	mutex_lock(&hdmi.lock);
 
 	if (dssdev->state = OMAP_DSS_DISPLAY_ACTIVE) {
@@ -270,7 +275,7 @@ static void hdmi_panel_disable(struct omap_dss_device *dssdev)
 		 * machine.
 		 */
 		hdmi_panel_audio_disable(dssdev);
-		omapdss_hdmi_display_disable(dssdev);
+		omapdss_hdmi_display_disable(out);
 	}
 
 	dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
@@ -280,6 +285,7 @@ static void hdmi_panel_disable(struct omap_dss_device *dssdev)
 
 static int hdmi_panel_suspend(struct omap_dss_device *dssdev)
 {
+	struct omap_dss_output *out = dssdev->output;
 	int r = 0;
 
 	mutex_lock(&hdmi.lock);
@@ -296,7 +302,7 @@ static int hdmi_panel_suspend(struct omap_dss_device *dssdev)
 	hdmi_panel_audio_disable(dssdev);
 
 	dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
-	omapdss_hdmi_display_disable(dssdev);
+	omapdss_hdmi_display_disable(out);
 
 err:
 	mutex_unlock(&hdmi.lock);
@@ -306,6 +312,7 @@ err:
 
 static int hdmi_panel_resume(struct omap_dss_device *dssdev)
 {
+	struct omap_dss_output *out = dssdev->output;
 	int r = 0;
 
 	mutex_lock(&hdmi.lock);
@@ -315,7 +322,7 @@ static int hdmi_panel_resume(struct omap_dss_device *dssdev)
 		goto err;
 	}
 
-	r = omapdss_hdmi_display_enable(dssdev);
+	r = omapdss_hdmi_display_enable(out);
 	if (r) {
 		DSSERR("failed to power on\n");
 		goto err;
@@ -343,8 +350,13 @@ static void hdmi_get_timings(struct omap_dss_device *dssdev,
 static void hdmi_set_timings(struct omap_dss_device *dssdev,
 			struct omap_video_timings *timings)
 {
+	struct omap_dss_output *out = dssdev->output;
+
 	DSSDBG("hdmi_set_timings\n");
 
+	if (out = NULL)
+		return;
+
 	mutex_lock(&hdmi.lock);
 
 	/*
@@ -353,7 +365,8 @@ static void hdmi_set_timings(struct omap_dss_device *dssdev,
 	 */
 	hdmi_panel_audio_disable(dssdev);
 
-	omapdss_hdmi_display_set_timing(dssdev, timings);
+	omapdss_hdmi_display_set_timing(out, timings);
+
 	dssdev->panel.timings = *timings;
 
 	mutex_unlock(&hdmi.lock);
@@ -362,13 +375,17 @@ static void hdmi_set_timings(struct omap_dss_device *dssdev,
 static int hdmi_check_timings(struct omap_dss_device *dssdev,
 			struct omap_video_timings *timings)
 {
+	struct omap_dss_output *out = dssdev->output;
 	int r = 0;
 
 	DSSDBG("hdmi_check_timings\n");
 
+	if (out = NULL)
+		return -ENODEV;
+
 	mutex_lock(&hdmi.lock);
 
-	r = omapdss_hdmi_display_check_timing(dssdev, timings);
+	r = omapdss_hdmi_display_check_timing(out, timings);
 
 	mutex_unlock(&hdmi.lock);
 	return r;
@@ -376,12 +393,16 @@ static int hdmi_check_timings(struct omap_dss_device *dssdev,
 
 static int hdmi_read_edid(struct omap_dss_device *dssdev, u8 *buf, int len)
 {
+	struct omap_dss_output *out = dssdev->output;
 	int r;
 
+	if (out = NULL)
+		return -ENODEV;
+
 	mutex_lock(&hdmi.lock);
 
 	if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) {
-		r = omapdss_hdmi_display_enable(dssdev);
+		r = omapdss_hdmi_display_enable(out);
 		if (r)
 			goto err;
 	}
@@ -390,7 +411,7 @@ static int hdmi_read_edid(struct omap_dss_device *dssdev, u8 *buf, int len)
 
 	if (dssdev->state = OMAP_DSS_DISPLAY_DISABLED ||
 			dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED)
-		omapdss_hdmi_display_disable(dssdev);
+		omapdss_hdmi_display_disable(out);
 err:
 	mutex_unlock(&hdmi.lock);
 
@@ -399,12 +420,16 @@ err:
 
 static bool hdmi_detect(struct omap_dss_device *dssdev)
 {
+	struct omap_dss_output *out = dssdev->output;
 	int r;
 
+	if (out = NULL)
+		return false;
+
 	mutex_lock(&hdmi.lock);
 
 	if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) {
-		r = omapdss_hdmi_display_enable(dssdev);
+		r = omapdss_hdmi_display_enable(out);
 		if (r)
 			goto err;
 	}
@@ -413,7 +438,7 @@ static bool hdmi_detect(struct omap_dss_device *dssdev)
 
 	if (dssdev->state = OMAP_DSS_DISPLAY_DISABLED ||
 			dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED)
-		omapdss_hdmi_display_disable(dssdev);
+		omapdss_hdmi_display_disable(out);
 err:
 	mutex_unlock(&hdmi.lock);
 
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH 18/23] OMAPDSS: HDMI: Add output pointers as arguments to all functions used by hdmi panel dr
From: Archit Taneja @ 2012-08-21  6:10 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, rob, sumit.semwal, Archit Taneja
In-Reply-To: <1345528711-27801-1-git-send-email-archit@ti.com>

All functions of an output driver used by a panel driver should have an
omap_dss_output pointer as an argument. This is needed as the function would
somehow need to retrieve the output driver's private data. It may not be needed
by some of the outputs for now as driver data is globally visible within them.
The correct way to retrieve driver data is to extract the platform device from
the output, and then extract the driver data from the platform device.

Add output arguments from functions used by panel drivers which currently miss
it. This will come to use when the HDMI functions retrieve the driver data
in the correct manner.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/dss/dss.h        |   17 ++++++++-------
 drivers/video/omap2/dss/hdmi.c       |   16 +++++++-------
 drivers/video/omap2/dss/hdmi_panel.c |   38 +++++++++++++++++++++++++---------
 3 files changed, 45 insertions(+), 26 deletions(-)

diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index bfa8b4d..dfbc3d9 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -509,17 +509,18 @@ void omapdss_hdmi_display_set_timing(struct omap_dss_output *out,
 		struct omap_video_timings *timings);
 int omapdss_hdmi_display_check_timing(struct omap_dss_output *out,
 		struct omap_video_timings *timings);
-int omapdss_hdmi_read_edid(u8 *buf, int len);
-bool omapdss_hdmi_detect(void);
+int omapdss_hdmi_read_edid(struct omap_dss_output *out, u8 *buf, int len);
+bool omapdss_hdmi_detect(struct omap_dss_output *out);
 int hdmi_panel_init(void);
 void hdmi_panel_exit(void);
 #ifdef CONFIG_OMAP4_DSS_HDMI_AUDIO
-int hdmi_audio_enable(void);
-void hdmi_audio_disable(void);
-int hdmi_audio_start(void);
-void hdmi_audio_stop(void);
-bool hdmi_mode_has_audio(void);
-int hdmi_audio_config(struct omap_dss_audio *audio);
+int hdmi_audio_enable(struct omap_dss_output *out);
+void hdmi_audio_disable(struct omap_dss_output *out);
+int hdmi_audio_start(struct omap_dss_output *out);
+void hdmi_audio_stop(struct omap_dss_output *out);
+bool hdmi_mode_has_audio(struct omap_dss_output *out);
+int hdmi_audio_config(struct omap_dss_output *out,
+		struct omap_dss_audio *audio);
 #endif
 
 /* RFBI */
diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c
index 16b745c..39dfc2b 100644
--- a/drivers/video/omap2/dss/hdmi.c
+++ b/drivers/video/omap2/dss/hdmi.c
@@ -602,7 +602,7 @@ static void hdmi_dump_regs(struct seq_file *s)
 	mutex_unlock(&hdmi.lock);
 }
 
-int omapdss_hdmi_read_edid(u8 *buf, int len)
+int omapdss_hdmi_read_edid(struct omap_dss_output *out, u8 *buf, int len)
 {
 	int r;
 
@@ -619,7 +619,7 @@ int omapdss_hdmi_read_edid(u8 *buf, int len)
 	return r;
 }
 
-bool omapdss_hdmi_detect(void)
+bool omapdss_hdmi_detect(struct omap_dss_output *out)
 {
 	int r;
 
@@ -829,35 +829,35 @@ int hdmi_compute_acr(u32 sample_freq, u32 *n, u32 *cts)
 	return 0;
 }
 
-int hdmi_audio_enable(void)
+int hdmi_audio_enable(struct omap_dss_output *out)
 {
 	DSSDBG("audio_enable\n");
 
 	return hdmi.ip_data.ops->audio_enable(&hdmi.ip_data);
 }
 
-void hdmi_audio_disable(void)
+void hdmi_audio_disable(struct omap_dss_output *out)
 {
 	DSSDBG("audio_disable\n");
 
 	hdmi.ip_data.ops->audio_disable(&hdmi.ip_data);
 }
 
-int hdmi_audio_start(void)
+int hdmi_audio_start(struct omap_dss_output *out)
 {
 	DSSDBG("audio_start\n");
 
 	return hdmi.ip_data.ops->audio_start(&hdmi.ip_data);
 }
 
-void hdmi_audio_stop(void)
+void hdmi_audio_stop(struct omap_dss_output *out)
 {
 	DSSDBG("audio_stop\n");
 
 	hdmi.ip_data.ops->audio_stop(&hdmi.ip_data);
 }
 
-bool hdmi_mode_has_audio(void)
+bool hdmi_mode_has_audio(struct omap_dss_output *out)
 {
 	if (hdmi.ip_data.cfg.cm.mode = HDMI_HDMI)
 		return true;
@@ -865,7 +865,7 @@ bool hdmi_mode_has_audio(void)
 		return false;
 }
 
-int hdmi_audio_config(struct omap_dss_audio *audio)
+int hdmi_audio_config(struct omap_dss_output *out, struct omap_dss_audio *audio)
 {
 	return hdmi.ip_data.ops->audio_config(&hdmi.ip_data, audio);
 }
diff --git a/drivers/video/omap2/dss/hdmi_panel.c b/drivers/video/omap2/dss/hdmi_panel.c
index fb35bbb..532882d 100644
--- a/drivers/video/omap2/dss/hdmi_panel.c
+++ b/drivers/video/omap2/dss/hdmi_panel.c
@@ -78,21 +78,25 @@ static void hdmi_panel_remove(struct omap_dss_device *dssdev)
 #if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO)
 static int hdmi_panel_audio_enable(struct omap_dss_device *dssdev)
 {
+	struct omap_dss_output *out = dssdev->output;
 	unsigned long flags;
 	int r;
 
+	if (out = NULL)
+		return -ENODEV;
+
 	mutex_lock(&hdmi.lock);
 	spin_lock_irqsave(&hdmi.audio_lock, flags);
 
 	/* enable audio only if the display is active and supports audio */
 	if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE ||
-	    !hdmi_mode_has_audio()) {
+	    !hdmi_mode_has_audio(out)) {
 		DSSERR("audio not supported or display is off\n");
 		r = -EPERM;
 		goto err;
 	}
 
-	r = hdmi_audio_enable();
+	r = hdmi_audio_enable(out);
 
 	if (!r)
 		dssdev->audio_state = OMAP_DSS_AUDIO_ENABLED;
@@ -105,11 +109,12 @@ err:
 
 static void hdmi_panel_audio_disable(struct omap_dss_device *dssdev)
 {
+	struct omap_dss_output *out = dssdev->output;
 	unsigned long flags;
 
 	spin_lock_irqsave(&hdmi.audio_lock, flags);
 
-	hdmi_audio_disable();
+	hdmi_audio_disable(out);
 
 	dssdev->audio_state = OMAP_DSS_AUDIO_DISABLED;
 
@@ -118,9 +123,13 @@ static void hdmi_panel_audio_disable(struct omap_dss_device *dssdev)
 
 static int hdmi_panel_audio_start(struct omap_dss_device *dssdev)
 {
+	struct omap_dss_output *out = dssdev->output;
 	unsigned long flags;
 	int r;
 
+	if (out = NULL)
+		return -ENODEV;
+
 	spin_lock_irqsave(&hdmi.audio_lock, flags);
 	/*
 	 * No need to check the panel state. It was checked when trasitioning
@@ -132,7 +141,7 @@ static int hdmi_panel_audio_start(struct omap_dss_device *dssdev)
 		goto err;
 	}
 
-	r = hdmi_audio_start();
+	r = hdmi_audio_start(out);
 
 	if (!r)
 		dssdev->audio_state = OMAP_DSS_AUDIO_PLAYING;
@@ -144,11 +153,12 @@ err:
 
 static void hdmi_panel_audio_stop(struct omap_dss_device *dssdev)
 {
+	struct omap_dss_output *out = dssdev->output;
 	unsigned long flags;
 
 	spin_lock_irqsave(&hdmi.audio_lock, flags);
 
-	hdmi_audio_stop();
+	hdmi_audio_stop(out);
 	dssdev->audio_state = OMAP_DSS_AUDIO_ENABLED;
 
 	spin_unlock_irqrestore(&hdmi.audio_lock, flags);
@@ -156,14 +166,18 @@ static void hdmi_panel_audio_stop(struct omap_dss_device *dssdev)
 
 static bool hdmi_panel_audio_supported(struct omap_dss_device *dssdev)
 {
+	struct omap_dss_output *out = dssdev->output;
 	bool r = false;
 
+	if (out = NULL)
+		return r;
+
 	mutex_lock(&hdmi.lock);
 
 	if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
 		goto err;
 
-	if (!hdmi_mode_has_audio())
+	if (!hdmi_mode_has_audio(out))
 		goto err;
 
 	r = true;
@@ -175,21 +189,25 @@ err:
 static int hdmi_panel_audio_config(struct omap_dss_device *dssdev,
 		struct omap_dss_audio *audio)
 {
+	struct omap_dss_output *out = dssdev->output;
 	unsigned long flags;
 	int r;
 
+	if (out = NULL)
+		return -ENODEV;
+
 	mutex_lock(&hdmi.lock);
 	spin_lock_irqsave(&hdmi.audio_lock, flags);
 
 	/* config audio only if the display is active and supports audio */
 	if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE ||
-	    !hdmi_mode_has_audio()) {
+	    !hdmi_mode_has_audio(out)) {
 		DSSERR("audio not supported or display is off\n");
 		r = -EPERM;
 		goto err;
 	}
 
-	r = hdmi_audio_config(audio);
+	r = hdmi_audio_config(out, audio);
 
 	if (!r)
 		dssdev->audio_state = OMAP_DSS_AUDIO_CONFIGURED;
@@ -407,7 +425,7 @@ static int hdmi_read_edid(struct omap_dss_device *dssdev, u8 *buf, int len)
 			goto err;
 	}
 
-	r = omapdss_hdmi_read_edid(buf, len);
+	r = omapdss_hdmi_read_edid(out, buf, len);
 
 	if (dssdev->state = OMAP_DSS_DISPLAY_DISABLED ||
 			dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED)
@@ -434,7 +452,7 @@ static bool hdmi_detect(struct omap_dss_device *dssdev)
 			goto err;
 	}
 
-	r = omapdss_hdmi_detect();
+	r = omapdss_hdmi_detect(out);
 
 	if (dssdev->state = OMAP_DSS_DISPLAY_DISABLED ||
 			dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED)
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH 19/23] OMAPDSS/OMAPFB: Change dssdev->manager references
From: Archit Taneja @ 2012-08-21  6:10 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, rob, sumit.semwal, Archit Taneja
In-Reply-To: <1345528711-27801-1-git-send-email-archit@ti.com>

To retrieve the manager pointer via a device, we need to now access it via the
output to which the device is connected. Make this change in the places where
such a reference is made.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/dss/display.c         |   11 +++++++++--
 drivers/video/omap2/omapfb/omapfb-ioctl.c |    4 ++--
 2 files changed, 11 insertions(+), 4 deletions(-)

diff --git a/drivers/video/omap2/dss/display.c b/drivers/video/omap2/dss/display.c
index 5bd957e..07fd1c7 100644
--- a/drivers/video/omap2/dss/display.c
+++ b/drivers/video/omap2/dss/display.c
@@ -349,8 +349,15 @@ void dss_uninit_device(struct platform_device *pdev,
 	while ((attr = display_sysfs_attrs[i++]) != NULL)
 		device_remove_file(&dssdev->dev, attr);
 
-	if (dssdev->manager)
-		dssdev->manager->unset_device(dssdev->manager);
+	if (dssdev->output) {
+		if (dssdev->output->manager) {
+			struct omap_overlay_manager *mgr +					dssdev->output->manager;
+
+			mgr->unset_output(mgr);
+		}
+		dssdev->output->unset_device(dssdev->output);
+	}
 }
 
 static int dss_suspend_device(struct device *dev, void *data)
diff --git a/drivers/video/omap2/omapfb/omapfb-ioctl.c b/drivers/video/omap2/omapfb/omapfb-ioctl.c
index c6cf372..25c0097 100644
--- a/drivers/video/omap2/omapfb/omapfb-ioctl.c
+++ b/drivers/video/omap2/omapfb/omapfb-ioctl.c
@@ -786,12 +786,12 @@ int omapfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg)
 
 	case OMAPFB_WAITFORVSYNC:
 		DBG("ioctl WAITFORVSYNC\n");
-		if (!display) {
+		if (!display && !display->output && !display->output->manager) {
 			r = -EINVAL;
 			break;
 		}
 
-		r = display->manager->wait_for_vsync(display->manager);
+		r = display->output->manager->wait_for_vsync(display->output->manager);
 		break;
 
 	case OMAPFB_WAITFORGO:
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH 20/23] OMAPDSS: MANAGER: Update display sysfs store
From: Archit Taneja @ 2012-08-21  6:10 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, rob, sumit.semwal, Archit Taneja
In-Reply-To: <1345528711-27801-1-git-send-email-archit@ti.com>

The display sysfs attribute's store function needs to be changed with the
introduction of outputs.

Providing a manager to the display isn't enough to create a link now, the
manager needs and output to connect to. A manager's display store file only
has the information of the manager and the desired display, it is not aware
of which output should the manager connect to.

Because of this, a new constraint needs to be set up when setting a display via
this sysfs file. The constraint is that the desired display should already be
connected to an output before calling this sysfs function.

This might break some existing user space stuff which uses sysfs directly. But
in most cases dss_recheck_connections will connect displays to floating outputs.
DSS sysfs files are being planned to be remove anyway, so it's not much of a
harm.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/dss/manager.c |   25 ++++++++++++++++++++-----
 1 file changed, 20 insertions(+), 5 deletions(-)

diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c
index fd39f66..d808ce2 100644
--- a/drivers/video/omap2/dss/manager.c
+++ b/drivers/video/omap2/dss/manager.c
@@ -74,18 +74,33 @@ static ssize_t manager_display_store(struct omap_overlay_manager *mgr,
 	if (dssdev)
 		DSSDBG("display %s found\n", dssdev->name);
 
-	if (mgr->get_device(mgr)) {
-		r = mgr->unset_device(mgr);
+	if (mgr->output) {
+		if (mgr->output->device) {
+			r = mgr->output->unset_device(mgr->output);
+			if (r) {
+				goto put_device;
+				DSSERR("failed to unset device from output\n");
+			}
+		}
+
+		r = mgr->unset_output(mgr);
 		if (r) {
-			DSSERR("failed to unset display\n");
+			DSSERR("failed to unset current output\n");
 			goto put_device;
 		}
 	}
 
 	if (dssdev) {
-		r = mgr->set_device(mgr, dssdev);
+		struct omap_dss_output *out = dssdev->output;
+
+		if (!out) {
+			DSSERR("no output connected to device\n");
+			goto put_device;
+		}
+
+		r = mgr->set_output(mgr, out);
 		if (r) {
-			DSSERR("failed to set manager\n");
+			DSSERR("failed to set manager output\n");
 			goto put_device;
 		}
 
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH 21/23] OMAPDSS: MANAGER: Get device via output
From: Archit Taneja @ 2012-08-21  6:10 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, rob, sumit.semwal, Archit Taneja
In-Reply-To: <1345528711-27801-1-git-send-email-archit@ti.com>

A manager is not connected to a device directly any more. It first connects
to an output, and then to the display. Update the manager's get_device op to
return the device via the connected output.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/dss/manager.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c
index d808ce2..d14ffc5 100644
--- a/drivers/video/omap2/dss/manager.c
+++ b/drivers/video/omap2/dss/manager.c
@@ -509,7 +509,7 @@ static struct kobj_type manager_ktype = {
 
 static inline struct omap_dss_device *dss_mgr_get_device(struct omap_overlay_manager *mgr)
 {
-	return mgr->device;
+	return mgr->output ? mgr->output->device : NULL;
 }
 
 static int dss_mgr_wait_for_vsync(struct omap_overlay_manager *mgr)
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH 22/23] OMAPDSS: APPLY: Remove omap_dss_device references from dss_ovl_enable/disable
From: Archit Taneja @ 2012-08-21  6:10 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, rob, sumit.semwal, Archit Taneja
In-Reply-To: <1345528711-27801-1-git-send-email-archit@ti.com>

An overlay isn't allowed to be enabled/disabled if it isn't connected to an
omap_dss_device. This requirement isn't needed any more. An overlay can be
enabled/disabled as long as it has an output connected to it. The output may
not be connected to a device, but we can be assured that the connected
manager's output is in use by an output interface.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/dss/apply.c |    6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c
index 8a05cbc..d584f0c 100644
--- a/drivers/video/omap2/dss/apply.c
+++ b/drivers/video/omap2/dss/apply.c
@@ -1607,8 +1607,7 @@ int dss_ovl_enable(struct omap_overlay *ovl)
 		goto err1;
 	}
 
-	if (ovl->manager = NULL ||
-			ovl->manager->get_device(ovl->manager) = NULL) {
+	if (ovl->manager = NULL || ovl->manager->output = NULL) {
 		r = -EINVAL;
 		goto err1;
 	}
@@ -1677,8 +1676,7 @@ int dss_ovl_disable(struct omap_overlay *ovl)
 		goto err;
 	}
 
-	if (ovl->manager = NULL ||
-			ovl->manager->get_device(ovl->manager) = NULL) {
+	if (ovl->manager = NULL || ovl->manager->output = NULL) {
 		r = -EINVAL;
 		goto err;
 	}
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH 23/23] OMAPDSS: Remove old way of setting manager and device links
From: Archit Taneja @ 2012-08-21  6:10 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, rob, sumit.semwal, Archit Taneja
In-Reply-To: <1345528711-27801-1-git-send-email-archit@ti.com>

Now that an omap_dss_output can be used to link between managers and devices, we
can remove the old way of setting manager and device links. This involves
removing the device and manager pointers from omap_overlay_manager and
omap_dss_device respectively, and removing the set_device/unset_device ops from
omap_overlay_manager.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/dss/apply.c   |   64 -------------------------------------
 drivers/video/omap2/dss/manager.c |    2 --
 include/video/omapdss.h           |    5 ---
 3 files changed, 71 deletions(-)

diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c
index d584f0c..0ae70ab 100644
--- a/drivers/video/omap2/dss/apply.c
+++ b/drivers/video/omap2/dss/apply.c
@@ -1247,70 +1247,6 @@ void dss_mgr_get_info(struct omap_overlay_manager *mgr,
 	spin_unlock_irqrestore(&data_lock, flags);
 }
 
-int dss_mgr_set_device(struct omap_overlay_manager *mgr,
-		struct omap_dss_device *dssdev)
-{
-	int r;
-
-	mutex_lock(&apply_lock);
-
-	if (dssdev->manager) {
-		DSSERR("display '%s' already has a manager '%s'\n",
-			       dssdev->name, dssdev->manager->name);
-		r = -EINVAL;
-		goto err;
-	}
-
-	if ((mgr->supported_displays & dssdev->type) = 0) {
-		DSSERR("display '%s' does not support manager '%s'\n",
-			       dssdev->name, mgr->name);
-		r = -EINVAL;
-		goto err;
-	}
-
-	dssdev->manager = mgr;
-	mgr->device = dssdev;
-
-	mutex_unlock(&apply_lock);
-
-	return 0;
-err:
-	mutex_unlock(&apply_lock);
-	return r;
-}
-
-int dss_mgr_unset_device(struct omap_overlay_manager *mgr)
-{
-	int r;
-
-	mutex_lock(&apply_lock);
-
-	if (!mgr->device) {
-		DSSERR("failed to unset display, display not set.\n");
-		r = -EINVAL;
-		goto err;
-	}
-
-	/*
-	 * Don't allow currently enabled displays to have the overlay manager
-	 * pulled out from underneath them
-	 */
-	if (mgr->device->state != OMAP_DSS_DISPLAY_DISABLED) {
-		r = -EINVAL;
-		goto err;
-	}
-
-	mgr->device->manager = NULL;
-	mgr->device = NULL;
-
-	mutex_unlock(&apply_lock);
-
-	return 0;
-err:
-	mutex_unlock(&apply_lock);
-	return r;
-}
-
 int dss_mgr_set_output(struct omap_overlay_manager *mgr,
 		struct omap_dss_output *output)
 {
diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c
index d14ffc5..953f5ee 100644
--- a/drivers/video/omap2/dss/manager.c
+++ b/drivers/video/omap2/dss/manager.c
@@ -570,8 +570,6 @@ int dss_init_overlay_managers(struct platform_device *pdev)
 			break;
 		}
 
-		mgr->set_device = &dss_mgr_set_device;
-		mgr->unset_device = &dss_mgr_unset_device;
 		mgr->set_output = &dss_mgr_set_output;
 		mgr->unset_output = &dss_mgr_unset_output;
 		mgr->apply = &omap_dss_mgr_apply;
diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index b3faea7..2be7629 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -466,7 +466,6 @@ struct omap_overlay_manager {
 	enum omap_dss_output_id supported_outputs;
 
 	/* dynamic fields */
-	struct omap_dss_device *device;
 	struct omap_dss_output *output;
 
 	/*
@@ -480,9 +479,6 @@ struct omap_overlay_manager {
 	 * interrupt context
 	 */
 
-	int (*set_device)(struct omap_overlay_manager *mgr,
-		struct omap_dss_device *dssdev);
-	int (*unset_device)(struct omap_overlay_manager *mgr);
 	int (*set_output)(struct omap_overlay_manager *mgr,
 		struct omap_dss_output *output);
 	int (*unset_output)(struct omap_overlay_manager *mgr);
@@ -634,7 +630,6 @@ struct omap_dss_device {
 
 	enum omap_display_caps caps;
 
-	struct omap_overlay_manager *manager;
 	struct omap_dss_output *output;
 
 	enum omap_dss_display_state state;
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH] fbcon: fix race condition between console lock and cursor timer
From: Dave Airlie @ 2012-08-21  6:40 UTC (permalink / raw)
  To: linux-fbdev
  Cc: dri-devel, linux-kernel, Linus, Alan Cox, Randy Dunlap,
	Josh Boyer, Dave Airlie

So we've had a fair few reports of fbcon handover breakage between
efi/vesafb and i915 surface recently, so I dedicated a couple of
days to finding the problem.

Essentially the last thing we saw was the conflicting framebuffer
message and that was all.

So after much tracing with direct netconsole writes (printks
under console_lock not so useful), I think I found the race.

Thread A (driver load)    Thread B (timer thread)
  unbind_con_driver ->              |
  bind_con_driver ->                |
  vc->vc_sw->con_deinit ->          |
  fbcon_deinit ->                   |
  console_lock()                    |
      |                             |
      |                       fbcon_flashcursor timer fires
      |                       console_lock() <- blocked for A
      |
      |
fbcon_del_cursor_timer ->
  del_timer_sync
  (BOOM)

Of course because all of this is under the console lock,
we never see anything, also since we also just unbound the active
console guess what we never see anything.

Hopefully this fixes the problem for anyone seeing vesafb->kms
driver handoff.

Signed-off-by: David Airlie <airlied@redhat.com>
---
 drivers/video/console/fbcon.c |    6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
index 2e471c2..f8a79fc 100644
--- a/drivers/video/console/fbcon.c
+++ b/drivers/video/console/fbcon.c
@@ -372,8 +372,12 @@ static void fb_flashcursor(struct work_struct *work)
 	struct vc_data *vc = NULL;
 	int c;
 	int mode;
+	int ret;
+
+	ret = console_trylock();
+	if (ret = 0)
+		return;
 
-	console_lock();
 	if (ops && ops->currcon != -1)
 		vc = vc_cons[ops->currcon].d;
 
-- 
1.7.10.2


^ permalink raw reply related

* Re: [PATCH v4 1/3] Runtime Interpreted Power Sequences
From: Tomi Valkeinen @ 2012-08-21  7:44 UTC (permalink / raw)
  To: Alexandre Courbot
  Cc: Stephen Warren, Thierry Reding, Simon Glass, Grant Likely,
	Rob Herring, Mark Brown, Anton Vorontsov, David Woodhouse,
	Arnd Bergmann, Leela Krishna Amudala,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-fbdev-u79uwXL29TY76Z2rM5mHXA,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	linux-doc-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <1345097337-24170-2-git-send-email-acourbot-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>

[-- Attachment #1: Type: text/plain, Size: 1387 bytes --]

Hi,

On Thu, 2012-08-16 at 15:08 +0900, Alexandre Courbot wrote:

> +Problem
> +-------
> +One very common board-dependent code is the out-of-driver code that is used to
> +turn a device on or off. For instance, SoC boards very commonly use a GPIO
> +(abstracted to a regulator or not) to control the power supply of a backlight,
> +disabling it when the backlight is not used in order to save power. The GPIO
> +that should be used, however, as well as the exact power sequence that may
> +also involve other resources, is board-dependent and thus unknown of the driver.
> +
> +This was previously addressed by having hooks in the device's platform data that
> +are called whenever the state of the device might reflect a power change. This
> +approach, however, introduces board-dependant code into the kernel and is not
> +compatible with the device tree.

I've been having the same problems on OMAP display related code, but the
problem has always been fixable by just having the driver to use a
common framework to do the job (a framework which may not have existed
at the time). The problems have never been board specific in the end,
but device specific.

Can you describe your particular HW problem a bit more? In the backlight
case, what exactly requires the delays and the sequence you show in the
example to enable/disable the backlight?

 Tomi


[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply

* Re: [PATCH v4 1/3] Runtime Interpreted Power Sequences
From: Alex Courbot @ 2012-08-21  8:22 UTC (permalink / raw)
  To: Tomi Valkeinen
  Cc: Stephen Warren, Thierry Reding, Simon Glass, Grant Likely,
	Rob Herring, Mark Brown, Anton Vorontsov, David Woodhouse,
	Arnd Bergmann, Leela Krishna Amudala, linux-tegra@vger.kernel.org,
	linux-kernel@vger.kernel.org, linux-fbdev@vger.kernel.org,
	devicetree-discuss@lists.ozlabs.org, linux-doc@vger.kernel.org
In-Reply-To: <1345535069.4085.7.camel@deskari>

Hi Tomi,

On Tuesday 21 August 2012 15:44:29 Tomi Valkeinen wrote:
> > +Problem
> > +-------
> > +One very common board-dependent code is the out-of-driver code that is
> > used to +turn a device on or off. For instance, SoC boards very commonly
> > use a GPIO +(abstracted to a regulator or not) to control the power
> > supply of a backlight, +disabling it when the backlight is not used in
> > order to save power. The GPIO +that should be used, however, as well as
> > the exact power sequence that may +also involve other resources, is
> > board-dependent and thus unknown of the driver. +
> > +This was previously addressed by having hooks in the device's platform
> > data that +are called whenever the state of the device might reflect a
> > power change. This +approach, however, introduces board-dependant code
> > into the kernel and is not +compatible with the device tree.
> 
> I've been having the same problems on OMAP display related code, but the
> problem has always been fixable by just having the driver to use a
> common framework to do the job (a framework which may not have existed
> at the time). The problems have never been board specific in the end,
> but device specific.
> 
> Can you describe your particular HW problem a bit more? In the backlight
> case, what exactly requires the delays and the sequence you show in the
> example to enable/disable the backlight?

In the example, the sequence (including delays) is clearly stated by the 
backlight specification, which is part of the panel specification. The backlight 
uses a PWM, which makes it suitable to use the generic PWM backlight driver, 
but how to turn the backlight on and off is very backlight specific. The power 
sequences allow to replace the board-specific backlight callbacks by sequences 
in the DT.

On the other hand, I saw your discussion with Laurent about the panel 
framework, and I wonder how this would fit into it. Backlights are typically 
embedded within panels. Power sequences are a good way to deal with the 
absence of specific drivers for every panels, since they allow to tailor the 
behavior of generic drivers to fit particular needs. But if every panel comes 
with its own driver (which would define the backlight device using the most 
appropriate driver), then it could just as well perform its backlight's 
sequences via regular callbacks. In this particular case, there would be no 
need for power sequences.

Power sequences are supposed to go beyond backlight drivers and support all 
sort of devices (I have heard that it could be useful for modems as well), but 
I wonder how relevant they are when there is a proper driver for a device. I 
hate to question my own work but now I cannot help but think that a proper 
driver could do the same job. So what are we trying to achieve with power 
sequences? Are we trying to avoid a drivers' explosion by keeping some of the 
specifics out of them? Which approach would be preferable? Are there cases 
where a dedicated driver could not replace power sequences?

Alex.


^ permalink raw reply

* Re: [PATCH v4 1/3] Runtime Interpreted Power Sequences
From: Thierry Reding @ 2012-08-21  8:33 UTC (permalink / raw)
  To: Alex Courbot
  Cc: Tomi Valkeinen, Stephen Warren, Simon Glass, Grant Likely,
	Rob Herring, Mark Brown, Anton Vorontsov, David Woodhouse,
	Arnd Bergmann, Leela Krishna Amudala, linux-tegra@vger.kernel.org,
	linux-kernel@vger.kernel.org, linux-fbdev@vger.kernel.org,
	devicetree-discuss@lists.ozlabs.org, linux-doc@vger.kernel.org
In-Reply-To: <1562509.b0FYTUZ1D8@percival>

[-- Attachment #1: Type: text/plain, Size: 3880 bytes --]

On Tue, Aug 21, 2012 at 05:22:12PM +0900, Alex Courbot wrote:
> Hi Tomi,
> 
> On Tuesday 21 August 2012 15:44:29 Tomi Valkeinen wrote:
> > > +Problem
> > > +-------
> > > +One very common board-dependent code is the out-of-driver code that is
> > > used to +turn a device on or off. For instance, SoC boards very commonly
> > > use a GPIO +(abstracted to a regulator or not) to control the power
> > > supply of a backlight, +disabling it when the backlight is not used in
> > > order to save power. The GPIO +that should be used, however, as well as
> > > the exact power sequence that may +also involve other resources, is
> > > board-dependent and thus unknown of the driver. +
> > > +This was previously addressed by having hooks in the device's platform
> > > data that +are called whenever the state of the device might reflect a
> > > power change. This +approach, however, introduces board-dependant code
> > > into the kernel and is not +compatible with the device tree.
> > 
> > I've been having the same problems on OMAP display related code, but the
> > problem has always been fixable by just having the driver to use a
> > common framework to do the job (a framework which may not have existed
> > at the time). The problems have never been board specific in the end,
> > but device specific.
> > 
> > Can you describe your particular HW problem a bit more? In the backlight
> > case, what exactly requires the delays and the sequence you show in the
> > example to enable/disable the backlight?
> 
> In the example, the sequence (including delays) is clearly stated by the 
> backlight specification, which is part of the panel specification. The backlight 
> uses a PWM, which makes it suitable to use the generic PWM backlight driver, 
> but how to turn the backlight on and off is very backlight specific. The power 
> sequences allow to replace the board-specific backlight callbacks by sequences 
> in the DT.
> 
> On the other hand, I saw your discussion with Laurent about the panel 
> framework, and I wonder how this would fit into it. Backlights are typically 
> embedded within panels. Power sequences are a good way to deal with the 
> absence of specific drivers for every panels, since they allow to tailor the 
> behavior of generic drivers to fit particular needs. But if every panel comes 
> with its own driver (which would define the backlight device using the most 
> appropriate driver), then it could just as well perform its backlight's 
> sequences via regular callbacks. In this particular case, there would be no 
> need for power sequences.
> 
> Power sequences are supposed to go beyond backlight drivers and support all 
> sort of devices (I have heard that it could be useful for modems as well), but 
> I wonder how relevant they are when there is a proper driver for a device. I 
> hate to question my own work but now I cannot help but think that a proper 
> driver could do the same job. So what are we trying to achieve with power 
> sequences? Are we trying to avoid a drivers' explosion by keeping some of the 
> specifics out of them? Which approach would be preferable? Are there cases 
> where a dedicated driver could not replace power sequences?

I suppose power sequences aren't needed if you have a specific driver
for every panel out there. However that also means that you'd have to
write drivers for literally every panel that requires support. In the
end this will just result in discussion down the road how the common
functionality can be refactored and we may end up with power sequences
again.

Also as you mentioned, power sequences are useful for a number of other
use-cases. Without power sequences you'll have to potentially create
extra frameworks tha reimplement parts of the power sequence code for
their specific hardware needs.

Thierry

[-- Attachment #2: Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply

* Re: [PATCH v4 1/3] Runtime Interpreted Power Sequences
From: Alex Courbot @ 2012-08-21  8:53 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Tomi Valkeinen, Stephen Warren, Simon Glass, Grant Likely,
	Rob Herring, Mark Brown, Anton Vorontsov, David Woodhouse,
	Arnd Bergmann, Leela Krishna Amudala, linux-tegra@vger.kernel.org,
	linux-kernel@vger.kernel.org, linux-fbdev@vger.kernel.org,
	devicetree-discuss@lists.ozlabs.org, linux-doc@vger.kernel.org
In-Reply-To: <20120821083329.GA28992@avionic-0098.adnet.avionic-design.de>

On Tuesday 21 August 2012 16:33:30 Thierry Reding wrote:
> I suppose power sequences aren't needed if you have a specific driver
> for every panel out there. However that also means that you'd have to
> write drivers for literally every panel that requires support. In the
> end this will just result in discussion down the road how the common
> functionality can be refactored and we may end up with power sequences
> again.
> 
> Also as you mentioned, power sequences are useful for a number of other
> use-cases. Without power sequences you'll have to potentially create
> extra frameworks tha reimplement parts of the power sequence code for
> their specific hardware needs.

Yes, I can imagine what a mess it would become it we had one driver for every 
panel out there which sole purpose would be to define power sequences over more 
generic drivers. That reassures me about the usefulness of this work.

Another (small) benefit of power sequences over specific drivers is that being 
defined in the DT, they would allow an old kernel to operate a newer device if 
the base driver is the same.

Alex.


^ permalink raw reply

* Re: [PATCH v4 1/3] Runtime Interpreted Power Sequences
From: Tomi Valkeinen @ 2012-08-21  8:57 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Alex Courbot, Stephen Warren, Simon Glass, Grant Likely,
	Rob Herring, Mark Brown, Anton Vorontsov, David Woodhouse,
	Arnd Bergmann, Leela Krishna Amudala, linux-tegra@vger.kernel.org,
	linux-kernel@vger.kernel.org, linux-fbdev@vger.kernel.org,
	devicetree-discuss@lists.ozlabs.org, linux-doc@vger.kernel.org
In-Reply-To: <20120821083329.GA28992@avionic-0098.adnet.avionic-design.de>

[-- Attachment #1: Type: text/plain, Size: 1912 bytes --]

On Tue, 2012-08-21 at 10:33 +0200, Thierry Reding wrote:

> I suppose power sequences aren't needed if you have a specific driver
> for every panel out there. However that also means that you'd have to
> write drivers for literally every panel that requires support. In the
> end this will just result in discussion down the road how the common
> functionality can be refactored and we may end up with power sequences
> again.
> 
> Also as you mentioned, power sequences are useful for a number of other
> use-cases. Without power sequences you'll have to potentially create
> extra frameworks tha reimplement parts of the power sequence code for
> their specific hardware needs.

Right. I think my main concern is the use of DT data, not power
sequences as such. I've been going back and forth in my mind with this
issue with OMAP also.

The question is: what stuff belongs to DT data and what belongs to the
kernel? I've been trying to go to the direction where DT is used to
describe the HW connections of different IP blocks and to pass board
specific configuration. Everything else is in the driver.

This doesn't mean that we'd have a separate driver for each device. For
example, we have a generic panel driver in OMAP, which contains a kind
of small panel database. The panel database contains the name of the
panel as a key, and panel specific configuration as a value. This
configuration could also contain some kind of generic power sequence.

I'd like to require the board developer to only fill in to the DT data
what panel he is using, and how it's connected on his board. Not panel's
internal functionality.

The one benefit I see with DT based approach is that if we have, say,
10000 panels, we'd have quite a big database in kernel memory and a
board may only need one or two of those. But perhaps that could be
helped with the use of __initdata.

 Tomi


[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply

* Re: [PATCH v4 1/3] Runtime Interpreted Power Sequences
From: Thierry Reding @ 2012-08-21  9:13 UTC (permalink / raw)
  To: Tomi Valkeinen
  Cc: Alex Courbot, Stephen Warren, Simon Glass, Grant Likely,
	Rob Herring, Mark Brown, Anton Vorontsov, David Woodhouse,
	Arnd Bergmann, Leela Krishna Amudala, linux-tegra@vger.kernel.org,
	linux-kernel@vger.kernel.org, linux-fbdev@vger.kernel.org,
	devicetree-discuss@lists.ozlabs.org, linux-doc@vger.kernel.org
In-Reply-To: <1345539465.4085.22.camel@deskari>

[-- Attachment #1: Type: text/plain, Size: 2921 bytes --]

On Tue, Aug 21, 2012 at 11:57:45AM +0300, Tomi Valkeinen wrote:
> On Tue, 2012-08-21 at 10:33 +0200, Thierry Reding wrote:
> 
> > I suppose power sequences aren't needed if you have a specific driver
> > for every panel out there. However that also means that you'd have to
> > write drivers for literally every panel that requires support. In the
> > end this will just result in discussion down the road how the common
> > functionality can be refactored and we may end up with power sequences
> > again.
> > 
> > Also as you mentioned, power sequences are useful for a number of other
> > use-cases. Without power sequences you'll have to potentially create
> > extra frameworks tha reimplement parts of the power sequence code for
> > their specific hardware needs.
> 
> Right. I think my main concern is the use of DT data, not power
> sequences as such. I've been going back and forth in my mind with this
> issue with OMAP also.
> 
> The question is: what stuff belongs to DT data and what belongs to the
> kernel? I've been trying to go to the direction where DT is used to
> describe the HW connections of different IP blocks and to pass board
> specific configuration. Everything else is in the driver.
> 
> This doesn't mean that we'd have a separate driver for each device. For
> example, we have a generic panel driver in OMAP, which contains a kind
> of small panel database. The panel database contains the name of the
> panel as a key, and panel specific configuration as a value. This
> configuration could also contain some kind of generic power sequence.

I see. I do like the idea of it, because it is more straightforward than
representing the whole sequence in DT. Matching could be done using the
standard compatible property.

However this also means we'll essentially just be moving the board code.
Being in a central location it would be easier to refactor commonalities
though.

> I'd like to require the board developer to only fill in to the DT data
> what panel he is using, and how it's connected on his board. Not panel's
> internal functionality.

The amount of work required by the board developer would largely depend
on whether support for the panel is already present or not. For new
panels this would mean that a new driver needs to be written, while
representing the power sequence in DT might be easier to do, and readily
available from some datasheet.

> The one benefit I see with DT based approach is that if we have, say,
> 10000 panels, we'd have quite a big database in kernel memory and a
> board may only need one or two of those. But perhaps that could be
> helped with the use of __initdata.

I haven't worked with many different panels, so maybe I can't judge this
too well, but if panel drivers were kept in a central location, then the
number can be reduced by generalizing parts of existing drivers.

Thierry

[-- Attachment #2: Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply

* Re: [PATCH] fbcon: fix race condition between console lock and cursor timer
From: Alan Cox @ 2012-08-21  9:15 UTC (permalink / raw)
  To: Dave Airlie
  Cc: linux-fbdev, dri-devel, linux-kernel, Linus, Randy Dunlap,
	Josh Boyer
In-Reply-To: <1345531207-24926-1-git-send-email-airlied@redhat.com>

> So after much tracing with direct netconsole writes (printks
> under console_lock not so useful), I think I found the race.

Direct netconsole write would be a useful patch to have mainline I think
8)

> Hopefully this fixes the problem for anyone seeing vesafb->kms
> driver handoff.

Not really the proper fix but its clear and is probably the best thing to
go in initially with a cc: stable. Can you at least stick a large 

+ /* FIXME: we should sort out the unbind locking instead */

on the patch however.

^ permalink raw reply

* Re: [RFC 0/5] Generic panel framework
From: Laurent Pinchart @ 2012-08-21  9:23 UTC (permalink / raw)
  To: Tomi Valkeinen
  Cc: linux-fbdev, dri-devel, linux-leds, linux-media, Bryan Wu,
	Richard Purdie, Marcus Lorentzon, Sumit Semwal, Archit Taneja,
	Sebastien Guiriec, Inki Dae, Kyungmin Park
In-Reply-To: <1345528197.15491.8.camel@lappyti>

Hi Tomi,

On Tuesday 21 August 2012 08:49:57 Tomi Valkeinen wrote:
> On Tue, 2012-08-21 at 01:29 +0200, Laurent Pinchart wrote:
> > On Monday 20 August 2012 14:39:30 Tomi Valkeinen wrote:
> > > On Sat, 2012-08-18 at 03:16 +0200, Laurent Pinchart wrote:
> > > > Hi Tomi,
> > > > 
> > > > mipi-dbi-bus might not belong to include/video/panel/ though, as it
> > > > can be used for non-panel devices (at least in theory). The future
> > > > mipi-dsi-bus certainly will.
> > > 
> > > They are both display busses. So while they could be used for anything,
> > > I find it quite unlikely as there are much better alternatives for
> > > generic bus needs.
> > 
> > My point is that they could be used for display devices other than panels.
> > This is especially true for DSI, as there are DSI to HDMI converters.
> > Technically speaking that's also true for DBI, as DBI chips convert from
> > DBI to DPI, but we can group both the DBI-to-DPI chip and the panel in a
> > single panel object.
> 
> Ah, ok. I thought "panels" would include these buffer/converter chips.
> 
> I think we should have one driver for one indivisible hardware entity.
> So if you've got a panel module that contains DBI receiver, buffer
> memory and a DPI panel, let's just have one "DBI panel" driver for it.
> 
> If we get lots of different panel modules containing the same DBI RX IP,
> we could have the DBI IP part as a common library, but still have one
> panel driver per panel module.

Sounds good to me.

> But how do you see the case for separate converter/buffer chips? Are
> they part of the generic panel framework? I guess they kinda have to be.
> On one side they use the "panel" API control the bus they are connected
> to, and on the other they offer an API for the connected panel to use
> the bus they provide.

The DBI/DSI APIs will not be panel-specific (they won't contain any reference 
to "panel") I'm thus thinking of moving them from drivers/video/panel/ to 
drivers/video/.

Furthermore, a DSI-to-HDMI converter chip is not a panel, but needs to expose 
display-related operations in a way similar to panels. I was thus wondering if 
we shouldn't replace the panel structure with some kind of video entity 
structure that would expose operations similar to panels. We could then extend 
that structure with converter-specific operations later. The framework would 
become a bit more generic, while remaining display-specific.

> Did you just mean we should have a separate directory for them, while
> still part of the same framework, or...?

-- 
Regards,

Laurent Pinchart


^ permalink raw reply

* Re: [PATCH v4 1/3] Runtime Interpreted Power Sequences
From: Tomi Valkeinen @ 2012-08-21  9:54 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Alex Courbot, Stephen Warren, Simon Glass, Grant Likely,
	Rob Herring, Mark Brown, Anton Vorontsov, David Woodhouse,
	Arnd Bergmann, Leela Krishna Amudala,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	linux-fbdev-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org,
	linux-doc-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
In-Reply-To: <20120821091306.GA4819-RM9K5IK7kjIQXX3q8xo1gnVAuStQJXxyR5q1nwbD4aMs9pC9oP6+/A@public.gmane.org>

[-- Attachment #1: Type: text/plain, Size: 2466 bytes --]

On Tue, 2012-08-21 at 11:13 +0200, Thierry Reding wrote:
> On Tue, Aug 21, 2012 at 11:57:45AM +0300, Tomi Valkeinen wrote:

> > This doesn't mean that we'd have a separate driver for each device. For
> > example, we have a generic panel driver in OMAP, which contains a kind
> > of small panel database. The panel database contains the name of the
> > panel as a key, and panel specific configuration as a value. This
> > configuration could also contain some kind of generic power sequence.
> 
> I see. I do like the idea of it, because it is more straightforward than
> representing the whole sequence in DT. Matching could be done using the
> standard compatible property.

Right.

> However this also means we'll essentially just be moving the board code.

What do you mean "just"? Wasn't the point of the whole "arm board file
mess" to get rid of the code from the board files? If the code in the
board file is device specific code, not board specific, then the driver
of the device is a logical place to place it.

And as I said, I don't have any problems with some kind of generic power
sequences. So the code in the board file could be moved and converted to
use the power sequences, if that is better than just plain c code.

> Being in a central location it would be easier to refactor commonalities
> though.
> 
> > I'd like to require the board developer to only fill in to the DT data
> > what panel he is using, and how it's connected on his board. Not panel's
> > internal functionality.
> 
> The amount of work required by the board developer would largely depend
> on whether support for the panel is already present or not. For new
> panels this would mean that a new driver needs to be written, while
> representing the power sequence in DT might be easier to do, and readily
> available from some datasheet.

That's true.

However, if we already have a generic driver for that type of panel,
(which we would need anyway for the DT based approach), the developer
only needs to add the name of the panel and the data for the power
sequence to the panel driver's database, which is about the same amount
of work as with DT.

So it's really just a question of where to put the data in question, DT
or driver. Both contain the same data, and the data structure may also
be the same. In DT's case it just needs to be parsed first, whereas in
database case you'll enter the data in structs.

 Tomi


[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply

* Re: [PATCH V5 1/6] OMAPDSS: DISPC: cleanup cpu_is_xxxx checks
From: Tomi Valkeinen @ 2012-08-21 10:31 UTC (permalink / raw)
  To: Chandrabhanu Mahapatra; +Cc: linux-omap, linux-fbdev
In-Reply-To: <978118e2c23e2da40ceb740665fd19f86810b58a.1345468541.git.cmahapatra@ti.com>

[-- Attachment #1: Type: text/plain, Size: 2558 bytes --]

On Mon, 2012-08-20 at 18:52 +0530, Chandrabhanu Mahapatra wrote:
> All the cpu_is checks have been moved to dispc_init_features function providing
> a much more generic and cleaner interface. The OMAP version and revision
> specific functions and data are initialized by dispc_features structure which is
> local to dispc.c.
> 
> Signed-off-by: Chandrabhanu Mahapatra <cmahapatra@ti.com>
> ---
>  drivers/video/omap2/dss/dispc.c |  433 +++++++++++++++++++++++++--------------
>  1 file changed, 278 insertions(+), 155 deletions(-)
> 
> diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
> index ff52702..3fad33a 100644
> --- a/drivers/video/omap2/dss/dispc.c
> +++ b/drivers/video/omap2/dss/dispc.c
> @@ -81,6 +81,23 @@ struct dispc_irq_stats {
>  	unsigned irqs[32];
>  };
>  
> +struct dispc_features {
> +	int hp_max;
> +	int vp_max;
> +	int sw_max;
> +	int sw_start;
> +	int fp_start;
> +	int bp_start;

Here you could use a bit smaller datatype. u16 should probably be more
than enough.

> +static int __init dispc_init_features(struct device *dev)
> +{
> +	struct dispc_features *feat = devm_kzalloc(dev, sizeof(*feat),
> +								GFP_KERNEL);
> +	if (!feat) {
> +		dev_err(dev, "Failed to allocate DISPC Features\n");
> +		return -ENOMEM;
> +	}
> +
> +	if (cpu_is_omap24xx()) {
> +		memcpy(feat, &omap24xx_dispc_feats, sizeof(*feat));
> +	} else if (cpu_is_omap34xx()) {
> +		if (omap_rev() < OMAP3430_REV_ES3_0)
> +			memcpy(feat, &omap34xx_rev1_0_dispc_feats,
> +							sizeof(*feat));
> +		else
> +			memcpy(feat, &omap34xx_rev3_0_dispc_feats,
> +							sizeof(*feat));
> +	} else if (cpu_is_omap44xx()) {
> +		memcpy(feat, &omap44xx_dispc_feats, sizeof(*feat));
> +	} else {
> +		return -ENODEV;
> +	}
> +
> +	dispc.feat = feat;
> +
> +	return 0;
> +}

This becomes much cleaner with something like the following (same could
be used in dss.c also):

	const struct dispc_features *src;
	struct dispc_features *dst;

	dst = devm_kzalloc(dev, sizeof(*dst), GFP_KERNEL);
	if (!dsst) {
		dev_err(dev, "Failed to allocate DISPC Features\n");
		return -ENOMEM;
	}

	if (cpu_is_omap24xx()) {
		src = &omap24xx_dispc_feats;
	} else if (cpu_is_omap34xx()) {
		if (omap_rev() < OMAP3430_REV_ES3_0)
			src = &omap34xx_rev1_0_dispc_feats;
		else
			src = &omap34xx_rev3_0_dispc_feats;
	} else if (cpu_is_omap44xx()) {
		src = &omap44xx_dispc_feats;
	} else {
		return -ENODEV;
	}

	memcpy(dst, src, sizeof(*dst));

	dispc.feat = dst;

 Tomi


[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply

* Re: [PATCH V5 5/6] ARM: OMAP: Disable venc for OMAP4
From: Tomi Valkeinen @ 2012-08-21 10:32 UTC (permalink / raw)
  To: Chandrabhanu Mahapatra; +Cc: tony, paul, linux-omap, linux-fbdev
In-Reply-To: <a07a3a216827e830cfa249f4f39ad26e75dc0afd.1345468541.git.cmahapatra@ti.com>

[-- Attachment #1: Type: text/plain, Size: 1288 bytes --]

On Mon, 2012-08-20 at 18:54 +0530, Chandrabhanu Mahapatra wrote:
> This is a alternative to "HACK: OMAP: DSS2: VENC: disable VENC on OMAP4 to
> prevent crash" (ba02fa37de) by Tomi Valkeinen <tomi.valkeinen@ti.com> to prevent
> VENC from crashing OMAP4 kernel. This prevents OMAPDSS from initial registration
> of a device for VENC on OMAP4.
> 
> Signed-off-by: Chandrabhanu Mahapatra <cmahapatra@ti.com>
> ---
>  arch/arm/mach-omap2/display.c |    1 -
>  1 file changed, 1 deletion(-)
> 
> diff --git a/arch/arm/mach-omap2/display.c b/arch/arm/mach-omap2/display.c
> index af1ed7d..ee40739 100644
> --- a/arch/arm/mach-omap2/display.c
> +++ b/arch/arm/mach-omap2/display.c
> @@ -95,7 +95,6 @@ static const struct omap_dss_hwmod_data omap4_dss_hwmod_data[] __initdata = {
>  	{ "dss_core", "omapdss_dss", -1 },
>  	{ "dss_dispc", "omapdss_dispc", -1 },
>  	{ "dss_rfbi", "omapdss_rfbi", -1 },
> -	{ "dss_venc", "omapdss_venc", -1 },
>  	{ "dss_dsi1", "omapdss_dsi", 0 },
>  	{ "dss_dsi2", "omapdss_dsi", 1 },
>  	{ "dss_hdmi", "omapdss_hdmi", -1 },

You need to reorder this and the previous patch. If you first remove the
workaround from the previous patch, the kernel will crash if after that
patch. So this one should be before the previous patch.

 Tomi


[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox