All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/23] OMAPDSS: Create output entities
@ 2012-08-21  6:10 ` Archit Taneja
  0 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-08-21  5:58 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, rob, sumit.semwal, Archit Taneja

Create a new entity in OMAPDSS called outputs. These represent the
interfaces/outputs like DSI, HDMI etc. that a panel connects to. An output
sits in between an overlay manager and a panel. More details about outputs
are explained in the first patch of the series.

This series adds omap_dss_output as an entity along with omap_overlay,
omap_overlay_manager and omap_dss_device. It changes the code to establish
links between managers and outputs, and outputs and devices. The rest of the
patches replace omap_dss_device with omap_dss_output as the argument exposed
by interface driver functions(DSI, HDMI etc) for panel drivers.

Reference tree:

git://gitorious.org/~boddob/linux-omap-dss2/archit-dss2-clone.git 2-add-outputs

Archit Taneja (23):
  OMAPDSS: outputs: Create a new entity called outputs
  OMAPDSS: outputs: Create and initialize output instances
  OMAPDSS: output: Add set/unset device ops for omap_dss_output
  OMAPDSS: APPLY: Add manager set/unset output ops for
    omap_overlay_manager
  OMAPDSS: Remove manager->device references
  OMAP_VOUT: Remove manager->device references
  OMAPFB: remove manager->device references
  OMAPDRM: Remove manager->device references
  OMAPDSS: Create links between managers, outputs and devices
  OMAPDSS: DPI: Pass outputs from panel driver to DPI interface driver
  OMAPDSS: DSI: Remove dsi_pdev_map global struct
  OMAPDSS: DSI: Pass outputs from panel driver to DSI interface driver
  OMAPDSS: SDI: Pass outputs from panel driver to SDI interface driver
  OMAPDSS: RFBI: Pass outputs from panel driver to RFBI interface
    driver
  OMAPDSS: RFBI: Add output pointers as arguments to all exported
    functions
  OMAPDSS: VENC: Pass outputs from panel driver to VENC interface
    driver
  OMAPDSS: HDMI: Pass outputs from panel driver to HDMI interface
    driver
  OMAPDSS: HDMI: Add output pointers as arguments to all functions used
    by hdmi panel driver
  OMAPDSS/OMAPFB: Change dssdev->manager references
  OMAPDSS: MANAGER: Update display sysfs store
  OMAPDSS: MANAGER: Get device via output
  OMAPDSS: APPLY: Remove omap_dss_device references from
    dss_ovl_enable/disable
  OMAPDSS: Remove old way of setting manager and device links

 drivers/media/video/omap/omap_vout.c               |   81 ++++--
 drivers/staging/omapdrm/omap_drv.c                 |    5 +-
 drivers/video/omap2/displays/panel-acx565akm.c     |   22 +-
 drivers/video/omap2/displays/panel-generic-dpi.c   |   27 +-
 .../omap2/displays/panel-lgphilips-lb035q02.c      |   16 +-
 drivers/video/omap2/displays/panel-n8x0.c          |  114 +++++---
 .../omap2/displays/panel-nec-nl8048hl11-01b.c      |   15 +-
 drivers/video/omap2/displays/panel-picodlp.c       |   15 +-
 .../video/omap2/displays/panel-sharp-ls037v7dw01.c |   16 +-
 drivers/video/omap2/displays/panel-taal.c          |  201 ++++++++-----
 drivers/video/omap2/displays/panel-tfp410.c        |   17 +-
 .../video/omap2/displays/panel-tpo-td043mtea1.c    |   29 +-
 drivers/video/omap2/dss/Makefile                   |    2 +-
 drivers/video/omap2/dss/apply.c                    |   52 ++--
 drivers/video/omap2/dss/core.c                     |    1 +
 drivers/video/omap2/dss/dispc.c                    |   10 +-
 drivers/video/omap2/dss/display.c                  |   11 +-
 drivers/video/omap2/dss/dpi.c                      |   84 ++++--
 drivers/video/omap2/dss/dsi.c                      |  307 +++++++++++---------
 drivers/video/omap2/dss/dss.h                      |   50 ++--
 drivers/video/omap2/dss/dss_features.c             |   52 ++++
 drivers/video/omap2/dss/dss_features.h             |    1 +
 drivers/video/omap2/dss/hdmi.c                     |   84 ++++--
 drivers/video/omap2/dss/hdmi_panel.c               |   85 ++++--
 drivers/video/omap2/dss/manager.c                  |   48 ++-
 drivers/video/omap2/dss/output.c                   |  125 ++++++++
 drivers/video/omap2/dss/overlay.c                  |   96 +++---
 drivers/video/omap2/dss/rfbi.c                     |   77 +++--
 drivers/video/omap2/dss/sdi.c                      |   54 ++--
 drivers/video/omap2/dss/venc.c                     |   78 +++--
 drivers/video/omap2/dss/venc_panel.c               |   53 +++-
 drivers/video/omap2/omapfb/omapfb-ioctl.c          |    4 +-
 drivers/video/omap2/omapfb/omapfb-main.c           |    7 +-
 drivers/video/omap2/omapfb/omapfb.h                |    5 +-
 include/video/omapdss.h                            |  172 ++++++-----
 35 files changed, 1350 insertions(+), 666 deletions(-)
 create mode 100644 drivers/video/omap2/dss/output.c

-- 
1.7.9.5


^ permalink raw reply	[flat|nested] 148+ messages in thread

* [PATCH 01/23] OMAPDSS: outputs: Create a new entity called outputs
  2012-08-21  6:10 ` Archit Taneja
@ 2012-08-21  6:10   ` Archit Taneja
  -1 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-08-21  5:58 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, rob, sumit.semwal, Archit Taneja

The current OMAPDSS design contains 3 software entities: Overlays, Managers and
Devices. These map to pipelines, overlay managers and the panels respectively in
hardware. One or more overlays connect to a manager to represent a composition,
the manager connects to a device(generally a display) to display the content.

The part of DSS hardware which isn't represented by any of the above entities
are interfaces/outputs that connect to an overlay manager, i.e blocks like DSI,
HDMI, VENC and so on. Currently, an overlay manager directly connects to the
display, and the output to which it is actually connected is ignored. The panel
driver of the display is responsible of calling output specific functions to
configure the output.

Adding outputs as a new software entity gives us the following benefits:

- Have exact information on the possible connections between managers and
  outputs: A manager can't connect to each and every output, there only limited
  hardware links between a manager's video port and some of the outputs.

- Remove hacks related to connecting managers and devices: Currently, default
  links between managers and devices are set in a not so clean way. Matching is
  done via comparing the device type, and the display types supported by the
  manager. This isn't sufficient to establish all the possible links between
  managers, outputs and devices in hardware.

- Make panel drivers more generic: The DSS panel drivers currently call
  interface/output specific functions to configure the hardware IP. When making
  these calls, the driver isn't actually aware of the underlying output. The
  output driver extracts information from the panel's omap_dss_device pointer
  to figure out which interface it is connected to, and then configures the
  corresponding output block. An example of this is when a DSI panel calls
  dsi functions, the dsi driver figures out whether the panel is connected
  to DSI1 or DSI2. This isn't correct, and having output as entities will
  give the panel driver the exact information on which output to configure.
  Having outputs also gives the opportunity to make panel drivers generic
  across different platforms/SoCs, this is achieved as omap specific output
  calls can be replaced by ops of a particular output type.

- Have more complex connections between managers, outputs and devices: OMAPDSS
  currently doesn't support use cases like 2 outputs connect to a single
  device. This can be achieved by extending properties of outputs to connect to
  more managers or devices.

- Represent writeback as an output: The writeback pipeline fits well in OMAPDSS
  as compared to overlays, managers or devices.

Add a new struct to represent outputs. An output struct holds pointers to the
manager and device structs to which it is connected. Add functions which can
add an output, or look for one. Create an enum which represent each output
instance.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/dss/Makefile |    2 +-
 drivers/video/omap2/dss/core.c   |    1 +
 drivers/video/omap2/dss/dss.h    |    4 +++
 drivers/video/omap2/dss/output.c |   58 ++++++++++++++++++++++++++++++++++++++
 include/video/omapdss.h          |   30 ++++++++++++++++++++
 5 files changed, 94 insertions(+), 1 deletion(-)
 create mode 100644 drivers/video/omap2/dss/output.c

diff --git a/drivers/video/omap2/dss/Makefile b/drivers/video/omap2/dss/Makefile
index 30a48fb..645f8c3 100644
--- a/drivers/video/omap2/dss/Makefile
+++ b/drivers/video/omap2/dss/Makefile
@@ -1,6 +1,6 @@
 obj-$(CONFIG_OMAP2_DSS) += omapdss.o
 omapdss-y := core.o dss.o dss_features.o dispc.o dispc_coefs.o display.o \
-	manager.o overlay.o apply.o
+	manager.o overlay.o output.o apply.o
 omapdss-$(CONFIG_OMAP2_DSS_DPI) += dpi.o
 omapdss-$(CONFIG_OMAP2_DSS_RFBI) += rfbi.o
 omapdss-$(CONFIG_OMAP2_DSS_VENC) += venc.o venc_panel.o
diff --git a/drivers/video/omap2/dss/core.c b/drivers/video/omap2/dss/core.c
index c35a248..2eccd74 100644
--- a/drivers/video/omap2/dss/core.c
+++ b/drivers/video/omap2/dss/core.c
@@ -239,6 +239,7 @@ static int __init omap_dss_probe(struct platform_device *pdev)
 
 	dss_init_overlay_managers(pdev);
 	dss_init_overlays(pdev);
+	dss_init_outputs();
 
 	r = dss_initialize_debugfs();
 	if (r)
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index 41c00dc..8a7c94c 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -222,6 +222,10 @@ int dss_ovl_set_manager(struct omap_overlay *ovl,
 		struct omap_overlay_manager *mgr);
 int dss_ovl_unset_manager(struct omap_overlay *ovl);
 
+/* output */
+struct omap_dss_output *dss_create_output(struct platform_device *pdev);
+void dss_init_outputs(void);
+
 /* display */
 int dss_suspend_all_devices(void);
 int dss_resume_all_devices(void);
diff --git a/drivers/video/omap2/dss/output.c b/drivers/video/omap2/dss/output.c
new file mode 100644
index 0000000..034ebbe
--- /dev/null
+++ b/drivers/video/omap2/dss/output.c
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2012 Texas Instruments Ltd
+ * Author: Archit Taneja <archit@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#include <video/omapdss.h>
+
+#include "dss.h"
+
+static struct list_head output_list;
+
+struct omap_dss_output *dss_create_output(struct platform_device *pdev)
+{
+	struct omap_dss_output *out;
+
+	out = kzalloc(sizeof(struct omap_dss_output *), GFP_KERNEL);
+	if (!out)
+		return NULL;
+
+	out->pdev = pdev;
+
+	list_add_tail(&out->list, &output_list);
+
+	return out;
+}
+
+struct omap_dss_output *omap_dss_get_output(enum omap_dss_output_id id)
+{
+	struct omap_dss_output *out;
+
+	list_for_each_entry(out, &output_list, list) {
+		if (out->id == id)
+			return out;
+	}
+
+	return NULL;
+}
+
+void dss_init_outputs(void)
+{
+	INIT_LIST_HEAD(&output_list);
+}
diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index b868123..0ba613f 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -207,6 +207,16 @@ enum omap_hdmi_flags {
 	OMAP_HDMI_SDA_SCL_EXTERNAL_PULLUP = 1 << 0,
 };
 
+enum omap_dss_output_id {
+	OMAP_DSS_OUTPUT_DPI	= 1 << 0,
+	OMAP_DSS_OUTPUT_DBI	= 1 << 1,
+	OMAP_DSS_OUTPUT_SDI	= 1 << 2,
+	OMAP_DSS_OUTPUT_DSI1	= 1 << 3,
+	OMAP_DSS_OUTPUT_VENC	= 1 << 4,
+	OMAP_DSS_OUTPUT_DSI2	= 1 << 5,
+	OMAP_DSS_OUTPUT_HDMI	= 1 << 6,
+};
+
 /* RFBI */
 
 struct rfbi_timings {
@@ -492,6 +502,24 @@ struct omap_dsi_pin_config {
 	int pins[OMAP_DSS_MAX_DSI_PINS];
 };
 
+struct omap_dss_output {
+	struct list_head list;
+
+	/* display type supported by the output */
+	enum omap_display_type type;
+
+	/* output instance */
+	enum omap_dss_output_id id;
+
+	/* output's platform device pointer */
+	struct platform_device *pdev;
+
+	/* dynamic fields */
+	struct omap_overlay_manager *manager;
+
+	struct omap_dss_device *device;
+};
+
 struct omap_dss_device {
 	struct device dev;
 
@@ -699,6 +727,8 @@ struct omap_overlay_manager *omap_dss_get_overlay_manager(int num);
 int omap_dss_get_num_overlays(void);
 struct omap_overlay *omap_dss_get_overlay(int num);
 
+struct omap_dss_output *omap_dss_get_output(enum omap_dss_output_id id);
+
 void omapdss_default_get_resolution(struct omap_dss_device *dssdev,
 		u16 *xres, u16 *yres);
 int omapdss_default_get_recommended_bpp(struct omap_dss_device *dssdev);
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [PATCH 02/23] OMAPDSS: outputs: Create and initialize output instances
  2012-08-21  6:10 ` Archit Taneja
@ 2012-08-21  6:10   ` Archit Taneja
  -1 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-08-21  5:58 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, rob, sumit.semwal, Archit Taneja

Create output instances by having an init function in the probes of the platform
device drivers for different interfaces. Create a small function for each
interface to initialize the output entity's fields type and id.

In the probe of each interface driver, the output entities are created before
the *_probe_pdata() functions intentionally. This is done to ensure that the
output entity is prepared before the panels connected to the output are
registered. We need the output entities to be ready because OMAPDSS will try
to make connections between overlays, managers, outputs and devices during the
panel's probe.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/dss/dpi.c  |   20 ++++++++++++++++++++
 drivers/video/omap2/dss/dsi.c  |   26 ++++++++++++++++++++++++--
 drivers/video/omap2/dss/hdmi.c |   18 ++++++++++++++++++
 drivers/video/omap2/dss/rfbi.c |   19 +++++++++++++++++++
 drivers/video/omap2/dss/sdi.c  |   20 ++++++++++++++++++++
 drivers/video/omap2/dss/venc.c |   20 ++++++++++++++++++++
 6 files changed, 121 insertions(+), 2 deletions(-)

diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c
index f260343..4eca2e7 100644
--- a/drivers/video/omap2/dss/dpi.c
+++ b/drivers/video/omap2/dss/dpi.c
@@ -408,10 +408,30 @@ static void __init dpi_probe_pdata(struct platform_device *pdev)
 	}
 }
 
+static int __init dpi_init_output(struct platform_device *pdev)
+{
+	struct omap_dss_output *out;
+
+	out = dss_create_output(pdev);
+	if (!out)
+		return -ENOMEM;
+
+	out->id = OMAP_DSS_OUTPUT_DPI;
+	out->type = OMAP_DISPLAY_TYPE_DPI;
+
+	return 0;
+}
+
 static int __init omap_dpi_probe(struct platform_device *pdev)
 {
+	int r;
+
 	mutex_init(&dpi.lock);
 
+	r = dpi_init_output(pdev);
+	if (r)
+		return r;
+
 	dpi_probe_pdata(pdev);
 
 	return 0;
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index 659b6cd..22e0873 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -4903,6 +4903,23 @@ static void __init dsi_probe_pdata(struct platform_device *dsidev)
 	}
 }
 
+static int __init dsi_init_output(struct platform_device *dsidev,
+		struct dsi_data *dsi)
+{
+	struct omap_dss_output *out;
+
+	out = dss_create_output(dsidev);
+	if (!out)
+		return -ENOMEM;
+
+	out->id = dsi->module_id == 0 ?
+			OMAP_DSS_OUTPUT_DSI1 : OMAP_DSS_OUTPUT_DSI2;
+
+	out->type = OMAP_DISPLAY_TYPE_DSI;
+
+	return 0;
+}
+
 /* DSI1 HW IP initialisation */
 static int __init omap_dsihw_probe(struct platform_device *dsidev)
 {
@@ -4997,10 +5014,14 @@ static int __init omap_dsihw_probe(struct platform_device *dsidev)
 	else
 		dsi->num_lanes_supported = 3;
 
-	dsi_probe_pdata(dsidev);
-
 	dsi_runtime_put(dsidev);
 
+	r = dsi_init_output(dsidev, dsi);
+	if (r)
+		goto err_init_output;
+
+	dsi_probe_pdata(dsidev);
+
 	if (dsi->module_id == 0)
 		dss_debugfs_create_file("dsi1_regs", dsi1_dump_regs);
 	else if (dsi->module_id == 1)
@@ -5014,6 +5035,7 @@ static int __init omap_dsihw_probe(struct platform_device *dsidev)
 #endif
 	return 0;
 
+err_init_output:
 err_runtime_get:
 	pm_runtime_disable(&dsidev->dev);
 	dsi_put_clocks(dsidev);
diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c
index 0cdf246..d32dbc3 100644
--- a/drivers/video/omap2/dss/hdmi.c
+++ b/drivers/video/omap2/dss/hdmi.c
@@ -890,6 +890,20 @@ static void __init hdmi_probe_pdata(struct platform_device *pdev)
 	}
 }
 
+static int __init hdmi_init_output(struct platform_device *pdev)
+{
+	struct omap_dss_output *out;
+
+	out = dss_create_output(pdev);
+	if (!out)
+		return -ENOMEM;
+
+	out->id = OMAP_DSS_OUTPUT_HDMI;
+	out->type = OMAP_DISPLAY_TYPE_HDMI;
+
+	return 0;
+}
+
 /* HDMI HW IP initialisation */
 static int __init omapdss_hdmihw_probe(struct platform_device *pdev)
 {
@@ -933,6 +947,10 @@ static int __init omapdss_hdmihw_probe(struct platform_device *pdev)
 
 	dss_debugfs_create_file("hdmi", hdmi_dump_regs);
 
+	r = hdmi_init_output(pdev);
+	if (r)
+		return r;
+
 	hdmi_probe_pdata(pdev);
 
 	return 0;
diff --git a/drivers/video/omap2/dss/rfbi.c b/drivers/video/omap2/dss/rfbi.c
index 5a9c0e9..9d9244c 100644
--- a/drivers/video/omap2/dss/rfbi.c
+++ b/drivers/video/omap2/dss/rfbi.c
@@ -967,6 +967,20 @@ static void __init rfbi_probe_pdata(struct platform_device *pdev)
 	}
 }
 
+static int __init rfbi_init_output(struct platform_device *pdev)
+{
+	struct omap_dss_output *out;
+
+	out = dss_create_output(pdev);
+	if (!out)
+		return -ENOMEM;
+
+	out->id = OMAP_DSS_OUTPUT_DBI;
+	out->type = OMAP_DISPLAY_TYPE_DBI;
+
+	return 0;
+}
+
 /* RFBI HW IP initialisation */
 static int __init omap_rfbihw_probe(struct platform_device *pdev)
 {
@@ -1018,10 +1032,15 @@ static int __init omap_rfbihw_probe(struct platform_device *pdev)
 
 	dss_debugfs_create_file("rfbi", rfbi_dump_regs);
 
+	r = rfbi_init_output(pdev);
+	if (r)
+		goto err_init_output;
+
 	rfbi_probe_pdata(pdev);
 
 	return 0;
 
+err_init_output:
 err_runtime_get:
 	pm_runtime_disable(&pdev->dev);
 	return r;
diff --git a/drivers/video/omap2/dss/sdi.c b/drivers/video/omap2/dss/sdi.c
index 3bf1bfe..a5632d0 100644
--- a/drivers/video/omap2/dss/sdi.c
+++ b/drivers/video/omap2/dss/sdi.c
@@ -216,8 +216,28 @@ static void __init sdi_probe_pdata(struct platform_device *pdev)
 	}
 }
 
+static int __init sdi_init_output(struct platform_device *pdev)
+{
+	struct omap_dss_output *out;
+
+	out = dss_create_output(pdev);
+	if (!out)
+		return -ENOMEM;
+
+	out->id = OMAP_DSS_OUTPUT_SDI;
+	out->type = OMAP_DISPLAY_TYPE_SDI;
+
+	return 0;
+}
+
 static int __init omap_sdi_probe(struct platform_device *pdev)
 {
+	int r;
+
+	r = sdi_init_output(pdev);
+	if (r)
+		return r;
+
 	sdi_probe_pdata(pdev);
 
 	return 0;
diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c
index 7d3eef8..264c5ec 100644
--- a/drivers/video/omap2/dss/venc.c
+++ b/drivers/video/omap2/dss/venc.c
@@ -778,6 +778,20 @@ static void __init venc_probe_pdata(struct platform_device *pdev)
 	}
 }
 
+static int __init venc_init_output(struct platform_device *pdev)
+{
+	struct omap_dss_output *out;
+
+	out = dss_create_output(pdev);
+	if (!out)
+		return -ENOMEM;
+
+	out->id = OMAP_DSS_OUTPUT_VENC;
+	out->type = OMAP_DISPLAY_TYPE_VENC;
+
+	return 0;
+}
+
 /* VENC HW IP initialisation */
 static int __init omap_venchw_probe(struct platform_device *pdev)
 {
@@ -825,10 +839,16 @@ static int __init omap_venchw_probe(struct platform_device *pdev)
 
 	dss_debugfs_create_file("venc", venc_dump_regs);
 
+	r = venc_init_output(pdev);
+	if (r)
+		goto err_init_output;
+
 	venc_probe_pdata(pdev);
 
 	return 0;
 
+err_init_output:
+	venc_panel_exit();
 err_panel_init:
 err_runtime_get:
 	pm_runtime_disable(&pdev->dev);
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [PATCH 03/23] OMAPDSS: output: Add set/unset device ops for omap_dss_output
  2012-08-21  6:10 ` Archit Taneja
@ 2012-08-21  6:10   ` Archit Taneja
  -1 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-08-21  5:58 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, rob, sumit.semwal, Archit Taneja

An output entity represented by the struct omap_dss_output connects to a
omap_dss_device entity. Add functions to set or unset an output's device. This
is similar to how managers and devices were connected previously. An output can
connect to a device without being connected to a manager. However, the output
needs to eventually connect to a manager so that the connected panel can be
enabled.

Keep the omap_overlay_manager pointer in omap_dss_device for now to prevent
breaking things. This will be removed later when outputs are supported
completely.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/dss/output.c |   67 ++++++++++++++++++++++++++++++++++++++
 include/video/omapdss.h          |    5 +++
 2 files changed, 72 insertions(+)

diff --git a/drivers/video/omap2/dss/output.c b/drivers/video/omap2/dss/output.c
index 034ebbe..ac57b19 100644
--- a/drivers/video/omap2/dss/output.c
+++ b/drivers/video/omap2/dss/output.c
@@ -24,6 +24,70 @@
 #include "dss.h"
 
 static struct list_head output_list;
+static DEFINE_MUTEX(output_lock);
+
+static int dss_output_set_device(struct omap_dss_output *out,
+		struct omap_dss_device *dssdev)
+{
+	int r;
+
+	mutex_lock(&output_lock);
+
+	if (out->device) {
+		DSSERR("output already has device %s connected to it\n",
+			out->device->name);
+		r = -EINVAL;
+		goto err;
+	}
+
+	if (out->type != dssdev->type) {
+		DSSERR("output type and display type don't match\n");
+		r = -EINVAL;
+		goto err;
+	}
+
+	out->device = dssdev;
+	dssdev->output = out;
+
+	mutex_unlock(&output_lock);
+
+	return 0;
+err:
+	mutex_unlock(&output_lock);
+
+	return r;
+}
+
+static int dss_output_unset_device(struct omap_dss_output *out)
+{
+	int r;
+
+	mutex_lock(&output_lock);
+
+	if (!out->device) {
+		DSSERR("output doesn't have a device connected to it\n");
+		r = -EINVAL;
+		goto err;
+	}
+
+	if (out->device->state != OMAP_DSS_DISPLAY_DISABLED) {
+		DSSERR("device %s is not disabled, cannot unset device\n",
+				out->device->name);
+		r = -EINVAL;
+		goto err;
+	}
+
+	out->device->output = NULL;
+	out->device = NULL;
+
+	mutex_unlock(&output_lock);
+
+	return 0;
+err:
+	mutex_unlock(&output_lock);
+
+	return r;
+}
 
 struct omap_dss_output *dss_create_output(struct platform_device *pdev)
 {
@@ -35,6 +99,9 @@ struct omap_dss_output *dss_create_output(struct platform_device *pdev)
 
 	out->pdev = pdev;
 
+	out->set_device = &dss_output_set_device;
+	out->unset_device = &dss_output_unset_device;
+
 	list_add_tail(&out->list, &output_list);
 
 	return out;
diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index 0ba613f..2e40f27 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -518,6 +518,10 @@ struct omap_dss_output {
 	struct omap_overlay_manager *manager;
 
 	struct omap_dss_device *device;
+
+	int (*set_device) (struct omap_dss_output *out,
+		struct omap_dss_device *dssdev);
+	int (*unset_device) (struct omap_dss_output *out);
 };
 
 struct omap_dss_device {
@@ -619,6 +623,7 @@ 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	[flat|nested] 148+ messages in thread

* [PATCH 04/23] OMAPDSS: APPLY: Add manager set/unset output ops for omap_overlay_manager
  2012-08-21  6:10 ` Archit Taneja
@ 2012-08-21  6:10   ` Archit Taneja
  -1 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-08-21  5:58 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, rob, sumit.semwal, Archit Taneja

Add set_output/unset_output ops for overlay managers, these form links between
managers and outputs. Create a function in dss features which tell all the
output instances that connect to a manager, use it when a manager tries to set
an output. Add a constraint of not unsetting an output when the manager is
enabled.

Keep the omap_dss_device pointer and set/unset_device ops in overlay_manager for
now to not break things. Keep the dss feature function get_supported_displays
as it's used in some places. These will be removed later.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/dss/apply.c        |   70 ++++++++++++++++++++++++++++++++
 drivers/video/omap2/dss/dss.h          |    3 ++
 drivers/video/omap2/dss/dss_features.c |   52 ++++++++++++++++++++++++
 drivers/video/omap2/dss/dss_features.h |    1 +
 drivers/video/omap2/dss/manager.c      |    4 ++
 include/video/omapdss.h                |    5 +++
 6 files changed, 135 insertions(+)

diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c
index 74f1a58..d241407 100644
--- a/drivers/video/omap2/dss/apply.c
+++ b/drivers/video/omap2/dss/apply.c
@@ -1311,6 +1311,76 @@ err:
 	return r;
 }
 
+int dss_mgr_set_output(struct omap_overlay_manager *mgr,
+		struct omap_dss_output *output)
+{
+	int r;
+
+	mutex_lock(&apply_lock);
+
+	if (mgr->output) {
+		DSSERR("manager %s is already connected to an output\n",
+			mgr->name);
+		r = -EINVAL;
+		goto err;
+	}
+
+	if ((mgr->supported_outputs & output->id) == 0) {
+		DSSERR("output does not support manager %s\n",
+			mgr->name);
+		r = -EINVAL;
+		goto err;
+	}
+
+	output->manager = mgr;
+	mgr->output = output;
+
+	mutex_unlock(&apply_lock);
+
+	return 0;
+err:
+	mutex_unlock(&apply_lock);
+	return r;
+}
+
+int dss_mgr_unset_output(struct omap_overlay_manager *mgr)
+{
+	int r;
+	struct mgr_priv_data *mp = get_mgr_priv(mgr);
+	unsigned long flags;
+
+	mutex_lock(&apply_lock);
+
+	if (!mgr->output) {
+		DSSERR("failed to unset output, output not set\n");
+		r = -EINVAL;
+		goto err;
+	}
+
+	spin_lock_irqsave(&data_lock, flags);
+
+	if (mp->enabled) {
+		DSSERR("output can't be unset when manager is enabled\n");
+		r = -EINVAL;
+		goto err1;
+	}
+
+	spin_unlock_irqrestore(&data_lock, flags);
+
+	mgr->output->manager = NULL;
+	mgr->output = NULL;
+
+	mutex_unlock(&apply_lock);
+
+	return 0;
+err1:
+	spin_unlock_irqrestore(&data_lock, flags);
+err:
+	mutex_unlock(&apply_lock);
+
+	return r;
+}
+
 static void dss_apply_mgr_timings(struct omap_overlay_manager *mgr,
 		const struct omap_video_timings *timings)
 {
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index 8a7c94c..a119506 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -205,6 +205,9 @@ void dss_mgr_get_info(struct omap_overlay_manager *mgr,
 int dss_mgr_set_device(struct omap_overlay_manager *mgr,
 		struct omap_dss_device *dssdev);
 int dss_mgr_unset_device(struct omap_overlay_manager *mgr);
+int dss_mgr_set_output(struct omap_overlay_manager *mgr,
+		struct omap_dss_output *output);
+int dss_mgr_unset_output(struct omap_overlay_manager *mgr);
 void dss_mgr_set_timings(struct omap_overlay_manager *mgr,
 		const struct omap_video_timings *timings);
 void dss_mgr_set_lcd_config(struct omap_overlay_manager *mgr,
diff --git a/drivers/video/omap2/dss/dss_features.c b/drivers/video/omap2/dss/dss_features.c
index 9387097..43f8491 100644
--- a/drivers/video/omap2/dss/dss_features.c
+++ b/drivers/video/omap2/dss/dss_features.c
@@ -47,6 +47,7 @@ struct omap_dss_features {
 	const int num_mgrs;
 	const int num_ovls;
 	const enum omap_display_type *supported_displays;
+	const enum omap_dss_output_id *supported_outputs;
 	const enum omap_color_mode *supported_color_modes;
 	const enum omap_overlay_caps *overlay_caps;
 	const char * const *clksrc_names;
@@ -144,6 +145,46 @@ static const enum omap_display_type omap4_dss_supported_displays[] = {
 	OMAP_DISPLAY_TYPE_DSI,
 };
 
+static const enum omap_dss_output_id omap2_dss_supported_outputs[] = {
+	/* OMAP_DSS_CHANNEL_LCD */
+	OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI,
+
+	/* OMAP_DSS_CHANNEL_DIGIT */
+	OMAP_DSS_OUTPUT_VENC,
+};
+
+static const enum omap_dss_output_id omap3430_dss_supported_outputs[] = {
+	/* OMAP_DSS_CHANNEL_LCD */
+	OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI |
+	OMAP_DSS_OUTPUT_SDI | OMAP_DSS_OUTPUT_DSI1,
+
+	/* OMAP_DSS_CHANNEL_DIGIT */
+	OMAP_DSS_OUTPUT_VENC,
+};
+
+static const enum omap_dss_output_id omap3630_dss_supported_outputs[] = {
+	/* OMAP_DSS_CHANNEL_LCD */
+	OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI |
+	OMAP_DSS_OUTPUT_DSI1,
+
+	/* OMAP_DSS_CHANNEL_DIGIT */
+	OMAP_DSS_OUTPUT_VENC,
+};
+
+static const enum omap_dss_output_id omap4_dss_supported_outputs[] = {
+	/* OMAP_DSS_CHANNEL_LCD */
+	OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI |
+	OMAP_DSS_OUTPUT_DSI1,
+
+	/* OMAP_DSS_CHANNEL_DIGIT */
+	OMAP_DSS_OUTPUT_VENC | OMAP_DSS_OUTPUT_HDMI |
+	OMAP_DSS_OUTPUT_DPI,
+
+	/* OMAP_DSS_CHANNEL_LCD2 */
+	OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI |
+	OMAP_DSS_OUTPUT_DSI2,
+};
+
 static const enum omap_color_mode omap2_dss_supported_color_modes[] = {
 	/* OMAP_DSS_GFX */
 	OMAP_DSS_COLOR_CLUT1 | OMAP_DSS_COLOR_CLUT2 |
@@ -458,6 +499,7 @@ static const struct omap_dss_features omap2_dss_features = {
 	.num_mgrs = 2,
 	.num_ovls = 3,
 	.supported_displays = omap2_dss_supported_displays,
+	.supported_outputs = omap2_dss_supported_outputs,
 	.supported_color_modes = omap2_dss_supported_color_modes,
 	.overlay_caps = omap2_dss_overlay_caps,
 	.clksrc_names = omap2_dss_clk_source_names,
@@ -478,6 +520,7 @@ static const struct omap_dss_features omap3430_dss_features = {
 	.num_mgrs = 2,
 	.num_ovls = 3,
 	.supported_displays = omap3430_dss_supported_displays,
+	.supported_outputs = omap3430_dss_supported_outputs,
 	.supported_color_modes = omap3_dss_supported_color_modes,
 	.overlay_caps = omap3430_dss_overlay_caps,
 	.clksrc_names = omap3_dss_clk_source_names,
@@ -497,6 +540,7 @@ static const struct omap_dss_features omap3630_dss_features = {
 	.num_mgrs = 2,
 	.num_ovls = 3,
 	.supported_displays = omap3630_dss_supported_displays,
+	.supported_outputs = omap3630_dss_supported_outputs,
 	.supported_color_modes = omap3_dss_supported_color_modes,
 	.overlay_caps = omap3630_dss_overlay_caps,
 	.clksrc_names = omap3_dss_clk_source_names,
@@ -518,6 +562,7 @@ static const struct omap_dss_features omap4430_es1_0_dss_features  = {
 	.num_mgrs = 3,
 	.num_ovls = 4,
 	.supported_displays = omap4_dss_supported_displays,
+	.supported_outputs = omap4_dss_supported_outputs,
 	.supported_color_modes = omap4_dss_supported_color_modes,
 	.overlay_caps = omap4_dss_overlay_caps,
 	.clksrc_names = omap4_dss_clk_source_names,
@@ -538,6 +583,7 @@ static const struct omap_dss_features omap4430_es2_0_1_2_dss_features = {
 	.num_mgrs = 3,
 	.num_ovls = 4,
 	.supported_displays = omap4_dss_supported_displays,
+	.supported_outputs = omap4_dss_supported_outputs,
 	.supported_color_modes = omap4_dss_supported_color_modes,
 	.overlay_caps = omap4_dss_overlay_caps,
 	.clksrc_names = omap4_dss_clk_source_names,
@@ -558,6 +604,7 @@ static const struct omap_dss_features omap4_dss_features = {
 	.num_mgrs = 3,
 	.num_ovls = 4,
 	.supported_displays = omap4_dss_supported_displays,
+	.supported_outputs = omap4_dss_supported_outputs,
 	.supported_color_modes = omap4_dss_supported_color_modes,
 	.overlay_caps = omap4_dss_overlay_caps,
 	.clksrc_names = omap4_dss_clk_source_names,
@@ -627,6 +674,11 @@ enum omap_display_type dss_feat_get_supported_displays(enum omap_channel channel
 	return omap_current_dss_features->supported_displays[channel];
 }
 
+enum omap_dss_output_id dss_feat_get_supported_outputs(enum omap_channel channel)
+{
+	return omap_current_dss_features->supported_outputs[channel];
+}
+
 enum omap_color_mode dss_feat_get_supported_color_modes(enum omap_plane plane)
 {
 	return omap_current_dss_features->supported_color_modes[plane];
diff --git a/drivers/video/omap2/dss/dss_features.h b/drivers/video/omap2/dss/dss_features.h
index 996ffcb..89a71d1 100644
--- a/drivers/video/omap2/dss/dss_features.h
+++ b/drivers/video/omap2/dss/dss_features.h
@@ -103,6 +103,7 @@ int dss_feat_get_num_ovls(void);
 unsigned long dss_feat_get_param_min(enum dss_range_param param);
 unsigned long dss_feat_get_param_max(enum dss_range_param param);
 enum omap_display_type dss_feat_get_supported_displays(enum omap_channel channel);
+enum omap_dss_output_id dss_feat_get_supported_outputs(enum omap_channel channel);
 enum omap_color_mode dss_feat_get_supported_color_modes(enum omap_plane plane);
 enum omap_overlay_caps dss_feat_get_overlay_caps(enum omap_plane plane);
 bool dss_feat_color_mode_supported(enum omap_plane plane,
diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c
index 53710fa..e15fa5f 100644
--- a/drivers/video/omap2/dss/manager.c
+++ b/drivers/video/omap2/dss/manager.c
@@ -549,6 +549,8 @@ int dss_init_overlay_managers(struct platform_device *pdev)
 
 		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;
 		mgr->set_manager_info = &dss_mgr_set_info;
 		mgr->get_manager_info = &dss_mgr_get_info;
@@ -558,6 +560,8 @@ int dss_init_overlay_managers(struct platform_device *pdev)
 		mgr->caps = 0;
 		mgr->supported_displays =
 			dss_feat_get_supported_displays(mgr->id);
+		mgr->supported_outputs =
+			dss_feat_get_supported_outputs(mgr->id);
 
 		INIT_LIST_HEAD(&mgr->overlays);
 
diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index 2e40f27..813672b 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -458,9 +458,11 @@ struct omap_overlay_manager {
 	enum omap_overlay_manager_caps caps;
 	struct list_head overlays;
 	enum omap_display_type supported_displays;
+	enum omap_dss_output_id supported_outputs;
 
 	/* dynamic fields */
 	struct omap_dss_device *device;
+	struct omap_dss_output *output;
 
 	/*
 	 * The following functions do not block:
@@ -476,6 +478,9 @@ struct omap_overlay_manager {
 	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);
 
 	int (*set_manager_info)(struct omap_overlay_manager *mgr,
 			struct omap_overlay_manager_info *info);
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [PATCH 05/23] OMAPDSS: Remove manager->device references
  2012-08-21  6:10 ` Archit Taneja
@ 2012-08-21  6:10   ` Archit Taneja
  -1 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-08-21  5:58 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, rob, sumit.semwal, Archit Taneja

With the introduction of output entities, managers will now connect to outputs.
Create a helper op for managers named get_device. This will abstract away the
information on how to get the device from an overlay manager. The get_device
op currently retrieves the output via a manager->device reference. This will
be later replaced by a manager->output->device reference.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/dss/apply.c   |    6 ++++--
 drivers/video/omap2/dss/dispc.c   |   10 +++++++---
 drivers/video/omap2/dss/manager.c |   19 ++++++++++++++-----
 include/video/omapdss.h           |    2 ++
 4 files changed, 27 insertions(+), 10 deletions(-)

diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c
index d241407..8a05cbc 100644
--- a/drivers/video/omap2/dss/apply.c
+++ b/drivers/video/omap2/dss/apply.c
@@ -1607,7 +1607,8 @@ int dss_ovl_enable(struct omap_overlay *ovl)
 		goto err1;
 	}
 
-	if (ovl->manager == NULL || ovl->manager->device == NULL) {
+	if (ovl->manager == NULL ||
+			ovl->manager->get_device(ovl->manager) == NULL) {
 		r = -EINVAL;
 		goto err1;
 	}
@@ -1676,7 +1677,8 @@ int dss_ovl_disable(struct omap_overlay *ovl)
 		goto err;
 	}
 
-	if (ovl->manager == NULL || ovl->manager->device == NULL) {
+	if (ovl->manager == NULL ||
+			ovl->manager->get_device(ovl->manager) == NULL) {
 		r = -EINVAL;
 		goto err;
 	}
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index ff52702..33061f5 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -3503,7 +3503,7 @@ static void dispc_error_worker(struct work_struct *work)
 		bit = mgr_desc[i].sync_lost_irq;
 
 		if (bit & errors) {
-			struct omap_dss_device *dssdev = mgr->device;
+			struct omap_dss_device *dssdev = mgr->get_device(mgr);
 			bool enable;
 
 			DSSERR("SYNC_LOST on channel %s, restarting the output "
@@ -3534,9 +3534,13 @@ static void dispc_error_worker(struct work_struct *work)
 		DSSERR("OCP_ERR\n");
 		for (i = 0; i < omap_dss_get_num_overlay_managers(); ++i) {
 			struct omap_overlay_manager *mgr;
+			struct omap_dss_device *dssdev;
+
 			mgr = omap_dss_get_overlay_manager(i);
-			if (mgr->device && mgr->device->driver)
-				mgr->device->driver->disable(mgr->device);
+			dssdev = mgr->get_device(mgr);
+
+			if (dssdev && dssdev->driver)
+				dssdev->driver->disable(dssdev);
 		}
 	}
 
diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c
index e15fa5f..fd39f66 100644
--- a/drivers/video/omap2/dss/manager.c
+++ b/drivers/video/omap2/dss/manager.c
@@ -43,8 +43,10 @@ static ssize_t manager_name_show(struct omap_overlay_manager *mgr, char *buf)
 
 static ssize_t manager_display_show(struct omap_overlay_manager *mgr, char *buf)
 {
-	return snprintf(buf, PAGE_SIZE, "%s\n",
-			mgr->device ? mgr->device->name : "<none>");
+	struct omap_dss_device *dssdev = mgr->get_device(mgr);
+
+	return snprintf(buf, PAGE_SIZE, "%s\n", dssdev ?
+			dssdev->name : "<none>");
 }
 
 static ssize_t manager_display_store(struct omap_overlay_manager *mgr,
@@ -72,7 +74,7 @@ static ssize_t manager_display_store(struct omap_overlay_manager *mgr,
 	if (dssdev)
 		DSSDBG("display %s found\n", dssdev->name);
 
-	if (mgr->device) {
+	if (mgr->get_device(mgr)) {
 		r = mgr->unset_device(mgr);
 		if (r) {
 			DSSERR("failed to unset display\n");
@@ -490,9 +492,15 @@ static struct kobj_type manager_ktype = {
 	.default_attrs = manager_sysfs_attrs,
 };
 
+static inline struct omap_dss_device *dss_mgr_get_device(struct omap_overlay_manager *mgr)
+{
+	return mgr->device;
+}
+
 static int dss_mgr_wait_for_vsync(struct omap_overlay_manager *mgr)
 {
 	unsigned long timeout = msecs_to_jiffies(500);
+	struct omap_dss_device *dssdev = mgr->get_device(mgr);
 	u32 irq;
 	int r;
 
@@ -500,9 +508,9 @@ static int dss_mgr_wait_for_vsync(struct omap_overlay_manager *mgr)
 	if (r)
 		return r;
 
-	if (mgr->device->type == OMAP_DISPLAY_TYPE_VENC)
+	if (dssdev->type == OMAP_DISPLAY_TYPE_VENC)
 		irq = DISPC_IRQ_EVSYNC_ODD;
-	else if (mgr->device->type == OMAP_DISPLAY_TYPE_HDMI)
+	else if (dssdev->type == OMAP_DISPLAY_TYPE_HDMI)
 		irq = DISPC_IRQ_EVSYNC_EVEN;
 	else
 		irq = dispc_mgr_get_vsync_irq(mgr->id);
@@ -556,6 +564,7 @@ int dss_init_overlay_managers(struct platform_device *pdev)
 		mgr->get_manager_info = &dss_mgr_get_info;
 		mgr->wait_for_go = &dss_mgr_wait_for_go;
 		mgr->wait_for_vsync = &dss_mgr_wait_for_vsync;
+		mgr->get_device = &dss_mgr_get_device;
 
 		mgr->caps = 0;
 		mgr->supported_displays =
diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index 813672b..361d41e 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -490,6 +490,8 @@ struct omap_overlay_manager {
 	int (*apply)(struct omap_overlay_manager *mgr);
 	int (*wait_for_go)(struct omap_overlay_manager *mgr);
 	int (*wait_for_vsync)(struct omap_overlay_manager *mgr);
+
+	struct omap_dss_device *(*get_device)(struct omap_overlay_manager *mgr);
 };
 
 /* 22 pins means 1 clk lane and 10 data lanes */
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [PATCH 06/23] OMAP_VOUT: Remove manager->device references
  2012-08-21  6:10 ` Archit Taneja
@ 2012-08-21  6:10   ` Archit Taneja
  -1 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-08-21  5:58 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, rob, sumit.semwal, Archit Taneja

With the introduction of output entities, managers will now connect to outputs.
Use the helper op for managers named get_device. This will abstract away the
information on how to get the device from an overlay manager.

Using the helper function will reduce the number of pointer dereferences a user
of OMAPDSS needs to do and reduce risk of a NULL dereference.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/media/video/omap/omap_vout.c |   81 ++++++++++++++++++++++++----------
 1 file changed, 57 insertions(+), 24 deletions(-)

diff --git a/drivers/media/video/omap/omap_vout.c b/drivers/media/video/omap/omap_vout.c
index 88cf9d9..0ebf87e 100644
--- a/drivers/media/video/omap/omap_vout.c
+++ b/drivers/media/video/omap/omap_vout.c
@@ -454,11 +454,16 @@ static int omapvid_init(struct omap_vout_device *vout, u32 addr)
 
 	win = &vout->win;
 	for (i = 0; i < ovid->num_overlays; i++) {
+		struct omap_dss_device *dssdev;
+
 		ovl = ovid->overlays[i];
-		if (!ovl->manager || !ovl->manager->device)
+		dssdev = ovl->manager ?
+			ovl->manager->get_device(ovl->manager) : NULL;
+
+		if (!dssdev)
 			return -EINVAL;
 
-		timing = &ovl->manager->device->panel.timings;
+		timing = &dssdev->panel.timings;
 
 		outw = win->w.width;
 		outh = win->w.height;
@@ -515,8 +520,12 @@ static int omapvid_apply_changes(struct omap_vout_device *vout)
 	struct omapvideo_info *ovid = &vout->vid_info;
 
 	for (i = 0; i < ovid->num_overlays; i++) {
+		struct omap_dss_device *dssdev;
+
 		ovl = ovid->overlays[i];
-		if (!ovl->manager || !ovl->manager->device)
+		dssdev = ovl->manager ?
+			ovl->manager->get_device(ovl->manager) : NULL;
+		if (!dssdev)
 			return -EINVAL;
 		ovl->manager->apply(ovl->manager);
 	}
@@ -579,12 +588,15 @@ static void omap_vout_isr(void *arg, unsigned int irqstatus)
 
 	ovid = &vout->vid_info;
 	ovl = ovid->overlays[0];
-	/* get the display device attached to the overlay */
-	if (!ovl->manager || !ovl->manager->device)
-		return;
 
 	mgr_id = ovl->manager->id;
-	cur_display = ovl->manager->device;
+
+	/* get the display device attached to the overlay */
+	cur_display = ovl->manager ?
+		ovl->manager->get_device(ovl->manager) : NULL;
+
+	if (!cur_display)
+		return;
 
 	spin_lock(&vout->vbq_lock);
 	do_gettimeofday(&timevalue);
@@ -948,7 +960,10 @@ static int omap_vout_release(struct file *file)
 	/* Disable all the overlay managers connected with this interface */
 	for (i = 0; i < ovid->num_overlays; i++) {
 		struct omap_overlay *ovl = ovid->overlays[i];
-		if (ovl->manager && ovl->manager->device)
+		struct omap_dss_device *dssdev = ovl->manager ?
+			ovl->manager->get_device(ovl->manager) : NULL;
+
+		if (dssdev)
 			ovl->disable(ovl);
 	}
 	/* Turn off the pipeline */
@@ -1081,14 +1096,17 @@ static int vidioc_try_fmt_vid_out(struct file *file, void *fh,
 	struct omapvideo_info *ovid;
 	struct omap_video_timings *timing;
 	struct omap_vout_device *vout = fh;
+	struct omap_dss_device *dssdev;
 
 	ovid = &vout->vid_info;
 	ovl = ovid->overlays[0];
+	/* get the display device attached to the overlay */
+	dssdev = ovl->manager ? ovl->manager->get_device(ovl->manager) : NULL;
 
-	if (!ovl->manager || !ovl->manager->device)
+	if (!dssdev)
 		return -EINVAL;
-	/* get the display device attached to the overlay */
-	timing = &ovl->manager->device->panel.timings;
+
+	timing = &dssdev->panel.timings;
 
 	vout->fbuf.fmt.height = timing->y_res;
 	vout->fbuf.fmt.width = timing->x_res;
@@ -1105,6 +1123,7 @@ static int vidioc_s_fmt_vid_out(struct file *file, void *fh,
 	struct omapvideo_info *ovid;
 	struct omap_video_timings *timing;
 	struct omap_vout_device *vout = fh;
+	struct omap_dss_device *dssdev;
 
 	if (vout->streaming)
 		return -EBUSY;
@@ -1113,13 +1132,14 @@ static int vidioc_s_fmt_vid_out(struct file *file, void *fh,
 
 	ovid = &vout->vid_info;
 	ovl = ovid->overlays[0];
+	dssdev = ovl->manager ? ovl->manager->get_device(ovl->manager) : NULL;
 
 	/* get the display device attached to the overlay */
-	if (!ovl->manager || !ovl->manager->device) {
+	if (!dssdev) {
 		ret = -EINVAL;
 		goto s_fmt_vid_out_exit;
 	}
-	timing = &ovl->manager->device->panel.timings;
+	timing = &dssdev->panel.timings;
 
 	/* We dont support RGB24-packed mode if vrfb rotation
 	 * is enabled*/
@@ -1298,6 +1318,7 @@ static int vidioc_s_crop(struct file *file, void *fh, struct v4l2_crop *crop)
 	struct omapvideo_info *ovid;
 	struct omap_overlay *ovl;
 	struct omap_video_timings *timing;
+	struct omap_dss_device *dssdev;
 
 	if (vout->streaming)
 		return -EBUSY;
@@ -1305,13 +1326,15 @@ static int vidioc_s_crop(struct file *file, void *fh, struct v4l2_crop *crop)
 	mutex_lock(&vout->lock);
 	ovid = &vout->vid_info;
 	ovl = ovid->overlays[0];
+	/* get the display device attached to the overlay */
+	dssdev = ovl->manager ? ovl->manager->get_device(ovl->manager) : NULL;
 
-	if (!ovl->manager || !ovl->manager->device) {
+	if (!dssdev) {
 		ret = -EINVAL;
 		goto s_crop_err;
 	}
-	/* get the display device attached to the overlay */
-	timing = &ovl->manager->device->panel.timings;
+
+	timing = &dssdev->panel.timings;
 
 	if (is_rotation_90_or_270(vout)) {
 		vout->fbuf.fmt.height = timing->x_res;
@@ -1666,8 +1689,9 @@ static int vidioc_streamon(struct file *file, void *fh, enum v4l2_buf_type i)
 
 	for (j = 0; j < ovid->num_overlays; j++) {
 		struct omap_overlay *ovl = ovid->overlays[j];
+		struct omap_overlay_manager *mgr = ovl->manager;
 
-		if (ovl->manager && ovl->manager->device) {
+		if (mgr && mgr->get_device(mgr)) {
 			struct omap_overlay_info info;
 			ovl->get_overlay_info(ovl, &info);
 			info.paddr = addr;
@@ -1690,8 +1714,10 @@ static int vidioc_streamon(struct file *file, void *fh, enum v4l2_buf_type i)
 
 	for (j = 0; j < ovid->num_overlays; j++) {
 		struct omap_overlay *ovl = ovid->overlays[j];
+		struct omap_dss_device *dssdev = ovl->manager ?
+			ovl->manager->get_device(ovl->manager) : NULL;
 
-		if (ovl->manager && ovl->manager->device) {
+		if (dssdev) {
 			ret = ovl->enable(ovl);
 			if (ret)
 				goto streamon_err1;
@@ -1726,8 +1752,10 @@ static int vidioc_streamoff(struct file *file, void *fh, enum v4l2_buf_type i)
 
 	for (j = 0; j < ovid->num_overlays; j++) {
 		struct omap_overlay *ovl = ovid->overlays[j];
+		struct omap_dss_device *dssdev = ovl->manager ?
+			ovl->manager->get_device(ovl->manager) : NULL;
 
-		if (ovl->manager && ovl->manager->device)
+		if (dssdev)
 			ovl->disable(ovl);
 	}
 
@@ -1890,8 +1918,9 @@ static int __init omap_vout_setup_video_data(struct omap_vout_device *vout)
 	struct video_device *vfd;
 	struct v4l2_pix_format *pix;
 	struct v4l2_control *control;
+	struct omap_overlay *ovl = vout->vid_info.overlays[0];
 	struct omap_dss_device *display =
-		vout->vid_info.overlays[0]->manager->device;
+		ovl->manager->get_device(ovl->manager);
 
 	/* set the default pix */
 	pix = &vout->pix;
@@ -2205,8 +2234,10 @@ static int __init omap_vout_probe(struct platform_device *pdev)
 	 */
 	for (i = 1; i < vid_dev->num_overlays; i++) {
 		ovl = omap_dss_get_overlay(i);
-		if (ovl->manager && ovl->manager->device) {
-			def_display = ovl->manager->device;
+		dssdev = ovl->manager ? ovl->manager->get_device(ovl->manager) :
+				NULL;
+		if (dssdev) {
+			def_display = dssdev;
 		} else {
 			dev_warn(&pdev->dev, "cannot find display\n");
 			def_display = NULL;
@@ -2253,8 +2284,10 @@ probe_err1:
 	for (i = 1; i < vid_dev->num_overlays; i++) {
 		def_display = NULL;
 		ovl = omap_dss_get_overlay(i);
-		if (ovl->manager && ovl->manager->device)
-			def_display = ovl->manager->device;
+		dssdev = ovl->manager ? ovl->manager->get_device(ovl->manager) :
+				NULL;
+		if (dssdev)
+			def_display = dssdev;
 
 		if (def_display && def_display->driver)
 			def_display->driver->disable(def_display);
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [PATCH 07/23] OMAPFB: remove manager->device references
  2012-08-21  6:10 ` Archit Taneja
@ 2012-08-21  6:10   ` Archit Taneja
  -1 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-08-21  5:58 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, rob, sumit.semwal, Archit Taneja

With the introduction of output entities, managers will now connect to outputs.
Use the helper op for managers named get_device. This will abstract away the
information on how to get the device from an overlay manager.

Using the helper function will reduce the number of pointer dereferences a user
of OMAPDSS needs to do and reduce risk of a NULL dereference.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/omapfb/omapfb-main.c |    7 +++++--
 drivers/video/omap2/omapfb/omapfb.h      |    5 +++--
 2 files changed, 8 insertions(+), 4 deletions(-)

diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c
index fc671d3..c6992be 100644
--- a/drivers/video/omap2/omapfb/omapfb-main.c
+++ b/drivers/video/omap2/omapfb/omapfb-main.c
@@ -2353,6 +2353,7 @@ static int __init omapfb_probe(struct platform_device *pdev)
 	struct omap_overlay *ovl;
 	struct omap_dss_device *def_display;
 	struct omap_dss_device *dssdev;
+	struct omap_dss_device *mgr_device;
 
 	DBG("omapfb_probe\n");
 
@@ -2426,8 +2427,10 @@ static int __init omapfb_probe(struct platform_device *pdev)
 	/* gfx overlay should be the default one. find a display
 	 * connected to that, and use it as default display */
 	ovl = omap_dss_get_overlay(0);
-	if (ovl->manager && ovl->manager->device) {
-		def_display = ovl->manager->device;
+	mgr_device = ovl->manager ?
+		ovl->manager->get_device(ovl->manager) : NULL;
+	if (mgr_device) {
+		def_display = mgr_device;
 	} else {
 		dev_warn(&pdev->dev, "cannot find default display\n");
 		def_display = NULL;
diff --git a/drivers/video/omap2/omapfb/omapfb.h b/drivers/video/omap2/omapfb/omapfb.h
index 30361a0..2782b1f 100644
--- a/drivers/video/omap2/omapfb/omapfb.h
+++ b/drivers/video/omap2/omapfb/omapfb.h
@@ -148,8 +148,9 @@ static inline struct omap_dss_device *fb2display(struct fb_info *fbi)
 
 	/* XXX: returns the display connected to first attached overlay */
 	for (i = 0; i < ofbi->num_overlays; i++) {
-		if (ofbi->overlays[i]->manager)
-			return ofbi->overlays[i]->manager->device;
+		struct omap_overlay_manager *mgr = ofbi->overlays[i]->manager;
+		if (mgr)
+			return mgr->get_device(mgr);
 	}
 
 	return NULL;
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [PATCH 08/23] OMAPDRM: Remove manager->device references
  2012-08-21  6:10 ` Archit Taneja
@ 2012-08-21  6:10   ` Archit Taneja
  -1 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-08-21  5:58 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, rob, sumit.semwal, Archit Taneja

With the introduction of output entities, managers will now connect to outputs.
Use the helper op for managers named get_device. This will abstract away the
information on how to get the device from an overlay manager.

Using the helper function will reduce the number of pointer dereferences a user
of OMAPDSS needs to do and reduce risk of a NULL dereference.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/staging/omapdrm/omap_drv.c |    5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/staging/omapdrm/omap_drv.c b/drivers/staging/omapdrm/omap_drv.c
index 4beab94..64a354a 100644
--- a/drivers/staging/omapdrm/omap_drv.c
+++ b/drivers/staging/omapdrm/omap_drv.c
@@ -106,7 +106,8 @@ static void dump_video_chains(void)
 	for (i = 0; i < omap_dss_get_num_overlays(); i++) {
 		struct omap_overlay *ovl = omap_dss_get_overlay(i);
 		struct omap_overlay_manager *mgr = ovl->manager;
-		struct omap_dss_device *dssdev = mgr ? mgr->device : NULL;
+		struct omap_dss_device *dssdev = mgr ?
+					mgr->get_device(mgr) : NULL;
 		if (dssdev) {
 			DBG("%d: %s -> %s -> %s", i, ovl->name, mgr->name,
 						dssdev->name);
@@ -185,7 +186,7 @@ static int create_connector(struct drm_device *dev,
 	for (j = 0; j < priv->num_encoders; j++) {
 		struct omap_overlay_manager *mgr =
 			omap_encoder_get_manager(priv->encoders[j]);
-		if (mgr->device == dssdev) {
+		if (mgr->get_device(mgr) == dssdev) {
 			drm_mode_connector_attach_encoder(connector,
 					priv->encoders[j]);
 		}
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [PATCH 09/23] OMAPDSS: Create links between managers, outputs and devices
  2012-08-21  6:10 ` Archit Taneja
@ 2012-08-21  6:10   ` Archit Taneja
  -1 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-08-21  5:58 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, rob, sumit.semwal, Archit Taneja

Links between DSS entities are made in dss_recheck_connections when a new panel
is probed. Rewrite the code in dss_recheck_connections to link managers to
outputs, and outputs to devices.

The fields in omap_dss_device struct gives information on which output and
manager to connect to. The desired manager and output pointers are retrieved and
prepared(existing outputs/devices unset, if default display)) to form the
desired links. The output is linked to the device, and then the manager to the
output. If a probed device's required manager isn't free, the required output
is still connected to the device so that it's easier to use the panel in the
future.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/dss/overlay.c |   96 +++++++++++++++++++++----------------
 1 file changed, 56 insertions(+), 40 deletions(-)

diff --git a/drivers/video/omap2/dss/overlay.c b/drivers/video/omap2/dss/overlay.c
index 952c6fa..07605f1 100644
--- a/drivers/video/omap2/dss/overlay.c
+++ b/drivers/video/omap2/dss/overlay.c
@@ -525,51 +525,67 @@ void dss_init_overlays(struct platform_device *pdev)
 void dss_recheck_connections(struct omap_dss_device *dssdev, bool force)
 {
 	int i;
-	struct omap_overlay_manager *lcd_mgr;
-	struct omap_overlay_manager *tv_mgr;
-	struct omap_overlay_manager *lcd2_mgr = NULL;
-	struct omap_overlay_manager *lcd3_mgr = NULL;
 	struct omap_overlay_manager *mgr = NULL;
+	struct omap_dss_output *out = NULL;
+	enum omap_dss_output_id id;
+
+	switch (dssdev->type) {
+	case OMAP_DISPLAY_TYPE_DPI:
+		out = omap_dss_get_output(OMAP_DSS_OUTPUT_DPI);
+		break;
+	case OMAP_DISPLAY_TYPE_DBI:
+		out = omap_dss_get_output(OMAP_DSS_OUTPUT_DBI);
+		break;
+	case OMAP_DISPLAY_TYPE_SDI:
+		out = omap_dss_get_output(OMAP_DSS_OUTPUT_SDI);
+		break;
+	case OMAP_DISPLAY_TYPE_VENC:
+		out = omap_dss_get_output(OMAP_DSS_OUTPUT_VENC);
+		break;
+	case OMAP_DISPLAY_TYPE_HDMI:
+		out = omap_dss_get_output(OMAP_DSS_OUTPUT_HDMI);
+		break;
+	case OMAP_DISPLAY_TYPE_DSI:
+		id = dssdev->phy.dsi.module == 0 ? OMAP_DSS_OUTPUT_DSI1 :
+					OMAP_DSS_OUTPUT_DSI2;
+		out = omap_dss_get_output(id);
+		break;
+	default:
+		break;
+	}
 
-	lcd_mgr = omap_dss_get_overlay_manager(OMAP_DSS_CHANNEL_LCD);
-	tv_mgr = omap_dss_get_overlay_manager(OMAP_DSS_CHANNEL_DIGIT);
-	if (dss_has_feature(FEAT_MGR_LCD3))
-		lcd3_mgr = omap_dss_get_overlay_manager(OMAP_DSS_CHANNEL_LCD3);
-	if (dss_has_feature(FEAT_MGR_LCD2))
-		lcd2_mgr = omap_dss_get_overlay_manager(OMAP_DSS_CHANNEL_LCD2);
-
-	if (dssdev->channel == OMAP_DSS_CHANNEL_LCD3) {
-		if (!lcd3_mgr->device || force) {
-			if (lcd3_mgr->device)
-				lcd3_mgr->unset_device(lcd3_mgr);
-			lcd3_mgr->set_device(lcd3_mgr, dssdev);
-			mgr = lcd3_mgr;
-		}
-	} else if (dssdev->channel == OMAP_DSS_CHANNEL_LCD2) {
-		if (!lcd2_mgr->device || force) {
-			if (lcd2_mgr->device)
-				lcd2_mgr->unset_device(lcd2_mgr);
-			lcd2_mgr->set_device(lcd2_mgr, dssdev);
-			mgr = lcd2_mgr;
-		}
-	} else if (dssdev->type != OMAP_DISPLAY_TYPE_VENC
-			&& dssdev->type != OMAP_DISPLAY_TYPE_HDMI) {
-		if (!lcd_mgr->device || force) {
-			if (lcd_mgr->device)
-				lcd_mgr->unset_device(lcd_mgr);
-			lcd_mgr->set_device(lcd_mgr, dssdev);
-			mgr = lcd_mgr;
-		}
+	/*
+	 * We don't want to touch board files and mention channel for VENC
+	 * devices. Force the channel as DIGIT for HDMI and VENC devices
+	 */
+	if (dssdev->type == OMAP_DISPLAY_TYPE_VENC ||
+			dssdev->type == OMAP_DISPLAY_TYPE_HDMI)
+		dssdev->channel = OMAP_DSS_CHANNEL_DIGIT;
+
+	mgr = omap_dss_get_overlay_manager(dssdev->channel);
+
+	if (!mgr || !out) {
+		DSSERR("Incorrect manager or output\n");
+		return;
 	}
 
-	if (dssdev->type == OMAP_DISPLAY_TYPE_VENC
-			|| dssdev->type == OMAP_DISPLAY_TYPE_HDMI) {
-		if (!tv_mgr->device || force) {
-			if (tv_mgr->device)
-				tv_mgr->unset_device(tv_mgr);
-			tv_mgr->set_device(tv_mgr, dssdev);
-			mgr = tv_mgr;
+	if (!mgr->output || force) {
+		struct omap_dss_output *curr_out = mgr->output;
+
+		if (curr_out) {
+			if (curr_out->device)
+				curr_out->unset_device(curr_out);
+			mgr->unset_output(mgr);
 		}
+		out->set_device(out, dssdev);
+		mgr->set_output(mgr, out);
+	} else {
+		/*
+		 * connect a floating output to the device even if the desired
+		 * manager is in use
+		 */
+		if (!out->manager && !out->device)
+			out->set_device(out, dssdev);
 	}
 
 	if (mgr) {
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [PATCH 10/23] OMAPDSS: DPI: Pass outputs from panel driver to DPI interface driver
  2012-08-21  6:10 ` Archit Taneja
@ 2012-08-21  6:10   ` Archit Taneja
  -1 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-08-21  5:58 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, rob, sumit.semwal, Archit Taneja

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 DPI 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-generic-dpi.c   |   27 ++++++---
 .../omap2/displays/panel-lgphilips-lb035q02.c      |   16 +++--
 .../omap2/displays/panel-nec-nl8048hl11-01b.c      |   15 +++--
 drivers/video/omap2/displays/panel-picodlp.c       |   15 +++--
 .../video/omap2/displays/panel-sharp-ls037v7dw01.c |   16 +++--
 drivers/video/omap2/displays/panel-tfp410.c        |   17 ++++--
 .../video/omap2/displays/panel-tpo-td043mtea1.c    |   29 ++++++---
 drivers/video/omap2/dss/dpi.c                      |   64 ++++++++++----------
 include/video/omapdss.h                            |   12 ++--
 9 files changed, 133 insertions(+), 78 deletions(-)

diff --git a/drivers/video/omap2/displays/panel-generic-dpi.c b/drivers/video/omap2/displays/panel-generic-dpi.c
index 88295c5..76ee8df 100644
--- a/drivers/video/omap2/displays/panel-generic-dpi.c
+++ b/drivers/video/omap2/displays/panel-generic-dpi.c
@@ -561,14 +561,18 @@ static int generic_dpi_panel_power_on(struct omap_dss_device *dssdev)
 	struct panel_generic_dpi_data *panel_data = get_panel_data(dssdev);
 	struct panel_drv_data *drv_data = dev_get_drvdata(&dssdev->dev);
 	struct panel_config *panel_config = drv_data->panel_config;
+	struct omap_dss_output *out = dssdev->output;
+
+	if (out == NULL)
+		return -ENODEV;
 
 	if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
 		return 0;
 
-	omapdss_dpi_set_timings(dssdev, &dssdev->panel.timings);
-	omapdss_dpi_set_data_lines(dssdev, dssdev->phy.dpi.data_lines);
+	omapdss_dpi_set_timings(out, &dssdev->panel.timings);
+	omapdss_dpi_set_data_lines(out, dssdev->phy.dpi.data_lines);
 
-	r = omapdss_dpi_display_enable(dssdev);
+	r = omapdss_dpi_display_enable(out);
 	if (r)
 		goto err0;
 
@@ -584,7 +588,7 @@ static int generic_dpi_panel_power_on(struct omap_dss_device *dssdev)
 
 	return 0;
 err1:
-	omapdss_dpi_display_disable(dssdev);
+	omapdss_dpi_display_disable(out);
 err0:
 	return r;
 }
@@ -594,6 +598,7 @@ static void generic_dpi_panel_power_off(struct omap_dss_device *dssdev)
 	struct panel_generic_dpi_data *panel_data = get_panel_data(dssdev);
 	struct panel_drv_data *drv_data = dev_get_drvdata(&dssdev->dev);
 	struct panel_config *panel_config = drv_data->panel_config;
+	struct omap_dss_output *out = dssdev->output;
 
 	if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
 		return;
@@ -605,7 +610,7 @@ static void generic_dpi_panel_power_off(struct omap_dss_device *dssdev)
 	if (panel_config->power_off_delay)
 		msleep(panel_config->power_off_delay);
 
-	omapdss_dpi_display_disable(dssdev);
+	omapdss_dpi_display_disable(out);
 }
 
 static int generic_dpi_panel_probe(struct omap_dss_device *dssdev)
@@ -726,10 +731,14 @@ static void generic_dpi_panel_set_timings(struct omap_dss_device *dssdev,
 		struct omap_video_timings *timings)
 {
 	struct panel_drv_data *drv_data = dev_get_drvdata(&dssdev->dev);
+	struct omap_dss_output *out = dssdev->output;
+
+	if (out == NULL)
+		return;
 
 	mutex_lock(&drv_data->lock);
 
-	omapdss_dpi_set_timings(dssdev, timings);
+	omapdss_dpi_set_timings(out, timings);
 
 	dssdev->panel.timings = *timings;
 
@@ -752,11 +761,15 @@ static int generic_dpi_panel_check_timings(struct omap_dss_device *dssdev,
 		struct omap_video_timings *timings)
 {
 	struct panel_drv_data *drv_data = dev_get_drvdata(&dssdev->dev);
+	struct omap_dss_output *out = dssdev->output;
 	int r;
 
+	if (out == NULL)
+		return -ENODEV;
+
 	mutex_lock(&drv_data->lock);
 
-	r = dpi_check_timings(dssdev, timings);
+	r = dpi_check_timings(out, timings);
 
 	mutex_unlock(&drv_data->lock);
 
diff --git a/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c b/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c
index 90c1cab..2764c32 100644
--- a/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c
+++ b/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c
@@ -50,15 +50,19 @@ static struct omap_video_timings lb035q02_timings = {
 
 static int lb035q02_panel_power_on(struct omap_dss_device *dssdev)
 {
+	struct omap_dss_output *out = dssdev->output;
 	int r;
 
+	if (out == NULL)
+		return -ENODEV;
+
 	if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
 		return 0;
 
-	omapdss_dpi_set_timings(dssdev, &dssdev->panel.timings);
-	omapdss_dpi_set_data_lines(dssdev, dssdev->phy.dpi.data_lines);
+	omapdss_dpi_set_timings(out, &dssdev->panel.timings);
+	omapdss_dpi_set_data_lines(out, dssdev->phy.dpi.data_lines);
 
-	r = omapdss_dpi_display_enable(dssdev);
+	r = omapdss_dpi_display_enable(out);
 	if (r)
 		goto err0;
 
@@ -70,20 +74,22 @@ static int lb035q02_panel_power_on(struct omap_dss_device *dssdev)
 
 	return 0;
 err1:
-	omapdss_dpi_display_disable(dssdev);
+	omapdss_dpi_display_disable(out);
 err0:
 	return r;
 }
 
 static void lb035q02_panel_power_off(struct omap_dss_device *dssdev)
 {
+	struct omap_dss_output *out = dssdev->output;
+
 	if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
 		return;
 
 	if (dssdev->platform_disable)
 		dssdev->platform_disable(dssdev);
 
-	omapdss_dpi_display_disable(dssdev);
+	omapdss_dpi_display_disable(out);
 }
 
 static int lb035q02_panel_probe(struct omap_dss_device *dssdev)
diff --git a/drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c b/drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c
index 908fd26..906bc48 100644
--- a/drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c
+++ b/drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c
@@ -171,14 +171,18 @@ static int nec_8048_panel_power_on(struct omap_dss_device *dssdev)
 	int r;
 	struct nec_8048_data *necd = dev_get_drvdata(&dssdev->dev);
 	struct backlight_device *bl = necd->bl;
+	struct omap_dss_output *out = dssdev->output;
+
+	if (out == NULL)
+		return -ENODEV;
 
 	if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
 		return 0;
 
-	omapdss_dpi_set_timings(dssdev, &dssdev->panel.timings);
-	omapdss_dpi_set_data_lines(dssdev, dssdev->phy.dpi.data_lines);
+	omapdss_dpi_set_timings(out, &dssdev->panel.timings);
+	omapdss_dpi_set_data_lines(out, dssdev->phy.dpi.data_lines);
 
-	r = omapdss_dpi_display_enable(dssdev);
+	r = omapdss_dpi_display_enable(out);
 	if (r)
 		goto err0;
 
@@ -194,7 +198,7 @@ static int nec_8048_panel_power_on(struct omap_dss_device *dssdev)
 
 	return 0;
 err1:
-	omapdss_dpi_display_disable(dssdev);
+	omapdss_dpi_display_disable(out);
 err0:
 	return r;
 }
@@ -203,6 +207,7 @@ static void nec_8048_panel_power_off(struct omap_dss_device *dssdev)
 {
 	struct nec_8048_data *necd = dev_get_drvdata(&dssdev->dev);
 	struct backlight_device *bl = necd->bl;
+	struct omap_dss_output *out = dssdev->output;
 
 	if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
 		return;
@@ -213,7 +218,7 @@ static void nec_8048_panel_power_off(struct omap_dss_device *dssdev)
 	if (dssdev->platform_disable)
 		dssdev->platform_disable(dssdev);
 
-	omapdss_dpi_display_disable(dssdev);
+	omapdss_dpi_display_disable(out);
 }
 
 static int nec_8048_panel_enable(struct omap_dss_device *dssdev)
diff --git a/drivers/video/omap2/displays/panel-picodlp.c b/drivers/video/omap2/displays/panel-picodlp.c
index 9df8764..2bd4f7b 100644
--- a/drivers/video/omap2/displays/panel-picodlp.c
+++ b/drivers/video/omap2/displays/panel-picodlp.c
@@ -352,6 +352,10 @@ static int picodlp_panel_power_on(struct omap_dss_device *dssdev)
 	int r, trial = 100;
 	struct picodlp_data *picod = dev_get_drvdata(&dssdev->dev);
 	struct picodlp_panel_data *picodlp_pdata = get_panel_data(dssdev);
+	struct omap_dss_output *out = dssdev->output;
+
+	if (out == NULL)
+		return -ENODEV;
 
 	if (dssdev->platform_enable) {
 		r = dssdev->platform_enable(dssdev);
@@ -378,10 +382,10 @@ static int picodlp_panel_power_on(struct omap_dss_device *dssdev)
 	 */
 	msleep(1000);
 
-	omapdss_dpi_set_timings(dssdev, &dssdev->panel.timings);
-	omapdss_dpi_set_data_lines(dssdev, dssdev->phy.dpi.data_lines);
+	omapdss_dpi_set_timings(out, &dssdev->panel.timings);
+	omapdss_dpi_set_data_lines(out, dssdev->phy.dpi.data_lines);
 
-	r = omapdss_dpi_display_enable(dssdev);
+	r = omapdss_dpi_display_enable(out);
 	if (r) {
 		dev_err(&dssdev->dev, "failed to enable DPI\n");
 		goto err1;
@@ -395,7 +399,7 @@ static int picodlp_panel_power_on(struct omap_dss_device *dssdev)
 
 	return r;
 err:
-	omapdss_dpi_display_disable(dssdev);
+	omapdss_dpi_display_disable(out);
 err1:
 	if (dssdev->platform_disable)
 		dssdev->platform_disable(dssdev);
@@ -406,8 +410,9 @@ err1:
 static void picodlp_panel_power_off(struct omap_dss_device *dssdev)
 {
 	struct picodlp_panel_data *picodlp_pdata = get_panel_data(dssdev);
+	struct omap_dss_output *out = dssdev->output;
 
-	omapdss_dpi_display_disable(dssdev);
+	omapdss_dpi_display_disable(out);
 
 	gpio_set_value(picodlp_pdata->emu_done_gpio, 0);
 	gpio_set_value(picodlp_pdata->pwrgood_gpio, 0);
diff --git a/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c b/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c
index 1ec3b27..dffd85a 100644
--- a/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c
+++ b/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c
@@ -137,15 +137,19 @@ static void __exit sharp_ls_panel_remove(struct omap_dss_device *dssdev)
 
 static int sharp_ls_power_on(struct omap_dss_device *dssdev)
 {
+	struct omap_dss_output *out = dssdev->output;
 	int r = 0;
 
+	if (out == NULL)
+		return -ENODEV;
+
 	if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
 		return 0;
 
-	omapdss_dpi_set_timings(dssdev, &dssdev->panel.timings);
-	omapdss_dpi_set_data_lines(dssdev, dssdev->phy.dpi.data_lines);
+	omapdss_dpi_set_timings(out, &dssdev->panel.timings);
+	omapdss_dpi_set_data_lines(out, dssdev->phy.dpi.data_lines);
 
-	r = omapdss_dpi_display_enable(dssdev);
+	r = omapdss_dpi_display_enable(out);
 	if (r)
 		goto err0;
 
@@ -160,13 +164,15 @@ static int sharp_ls_power_on(struct omap_dss_device *dssdev)
 
 	return 0;
 err1:
-	omapdss_dpi_display_disable(dssdev);
+	omapdss_dpi_display_disable(out);
 err0:
 	return r;
 }
 
 static void sharp_ls_power_off(struct omap_dss_device *dssdev)
 {
+	struct omap_dss_output *out = dssdev->output;
+
 	if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
 		return;
 
@@ -177,7 +183,7 @@ static void sharp_ls_power_off(struct omap_dss_device *dssdev)
 
 	msleep(100);
 
-	omapdss_dpi_display_disable(dssdev);
+	omapdss_dpi_display_disable(out);
 }
 
 static int sharp_ls_panel_enable(struct omap_dss_device *dssdev)
diff --git a/drivers/video/omap2/displays/panel-tfp410.c b/drivers/video/omap2/displays/panel-tfp410.c
index 4be9a59..88a1507 100644
--- a/drivers/video/omap2/displays/panel-tfp410.c
+++ b/drivers/video/omap2/displays/panel-tfp410.c
@@ -60,15 +60,19 @@ struct panel_drv_data {
 static int tfp410_power_on(struct omap_dss_device *dssdev)
 {
 	struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev);
+	struct omap_dss_output *out = dssdev->output;
 	int r;
 
+	if (out == NULL)
+		return -ENODEV;
+
 	if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
 		return 0;
 
-	omapdss_dpi_set_timings(dssdev, &dssdev->panel.timings);
-	omapdss_dpi_set_data_lines(dssdev, dssdev->phy.dpi.data_lines);
+	omapdss_dpi_set_timings(out, &dssdev->panel.timings);
+	omapdss_dpi_set_data_lines(out, dssdev->phy.dpi.data_lines);
 
-	r = omapdss_dpi_display_enable(dssdev);
+	r = omapdss_dpi_display_enable(out);
 	if (r)
 		goto err0;
 
@@ -83,6 +87,7 @@ err0:
 static void tfp410_power_off(struct omap_dss_device *dssdev)
 {
 	struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev);
+	struct omap_dss_output *out = dssdev->output;
 
 	if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
 		return;
@@ -90,7 +95,7 @@ static void tfp410_power_off(struct omap_dss_device *dssdev)
 	if (gpio_is_valid(ddata->pd_gpio))
 		gpio_set_value_cansleep(ddata->pd_gpio, 0);
 
-	omapdss_dpi_display_disable(dssdev);
+	omapdss_dpi_display_disable(out);
 }
 
 static int tfp410_probe(struct omap_dss_device *dssdev)
@@ -234,7 +239,7 @@ static void tfp410_set_timings(struct omap_dss_device *dssdev,
 	struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev);
 
 	mutex_lock(&ddata->lock);
-	omapdss_dpi_set_timings(dssdev, timings);
+	omapdss_dpi_set_timings(dssdev->output, timings);
 	dssdev->panel.timings = *timings;
 	mutex_unlock(&ddata->lock);
 }
@@ -256,7 +261,7 @@ static int tfp410_check_timings(struct omap_dss_device *dssdev,
 	int r;
 
 	mutex_lock(&ddata->lock);
-	r = dpi_check_timings(dssdev, timings);
+	r = dpi_check_timings(dssdev->output, timings);
 	mutex_unlock(&ddata->lock);
 
 	return r;
diff --git a/drivers/video/omap2/displays/panel-tpo-td043mtea1.c b/drivers/video/omap2/displays/panel-tpo-td043mtea1.c
index b5e6dbc..792e9ff 100644
--- a/drivers/video/omap2/displays/panel-tpo-td043mtea1.c
+++ b/drivers/video/omap2/displays/panel-tpo-td043mtea1.c
@@ -331,16 +331,20 @@ static void tpo_td043_power_off(struct tpo_td043_device *tpo_td043)
 
 static int tpo_td043_enable_dss(struct omap_dss_device *dssdev)
 {
+	struct omap_dss_output *out = dssdev->output;
 	struct tpo_td043_device *tpo_td043 = dev_get_drvdata(&dssdev->dev);
 	int r;
 
+	if (out == NULL)
+		return -ENODEV;
+
 	if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
 		return 0;
 
-	omapdss_dpi_set_timings(dssdev, &dssdev->panel.timings);
-	omapdss_dpi_set_data_lines(dssdev, dssdev->phy.dpi.data_lines);
+	omapdss_dpi_set_timings(out, &dssdev->panel.timings);
+	omapdss_dpi_set_data_lines(out, dssdev->phy.dpi.data_lines);
 
-	r = omapdss_dpi_display_enable(dssdev);
+	r = omapdss_dpi_display_enable(out);
 	if (r)
 		goto err0;
 
@@ -364,7 +368,7 @@ static int tpo_td043_enable_dss(struct omap_dss_device *dssdev)
 
 	return 0;
 err1:
-	omapdss_dpi_display_disable(dssdev);
+	omapdss_dpi_display_disable(out);
 err0:
 	return r;
 }
@@ -372,6 +376,7 @@ err0:
 static void tpo_td043_disable_dss(struct omap_dss_device *dssdev)
 {
 	struct tpo_td043_device *tpo_td043 = dev_get_drvdata(&dssdev->dev);
+	struct omap_dss_output *out = dssdev->output;
 
 	if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
 		return;
@@ -379,7 +384,7 @@ static void tpo_td043_disable_dss(struct omap_dss_device *dssdev)
 	if (dssdev->platform_disable)
 		dssdev->platform_disable(dssdev);
 
-	omapdss_dpi_display_disable(dssdev);
+	omapdss_dpi_display_disable(out);
 
 	if (!tpo_td043->spi_suspended)
 		tpo_td043_power_off(tpo_td043);
@@ -483,7 +488,12 @@ static void tpo_td043_remove(struct omap_dss_device *dssdev)
 static void tpo_td043_set_timings(struct omap_dss_device *dssdev,
 		struct omap_video_timings *timings)
 {
-	omapdss_dpi_set_timings(dssdev, timings);
+	struct omap_dss_output *out = dssdev->output;
+
+	if (out == NULL)
+		return;
+
+	omapdss_dpi_set_timings(out, timings);
 
 	dssdev->panel.timings = *timings;
 }
@@ -491,7 +501,12 @@ static void tpo_td043_set_timings(struct omap_dss_device *dssdev,
 static int tpo_td043_check_timings(struct omap_dss_device *dssdev,
 		struct omap_video_timings *timings)
 {
-	return dpi_check_timings(dssdev, timings);
+	struct omap_dss_output *out = dssdev->output;
+
+	if (out == NULL)
+		return -ENODEV;
+
+	return dpi_check_timings(out, timings);
 }
 
 static struct omap_dss_driver tpo_td043_driver = {
diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c
index 4eca2e7..6506e40 100644
--- a/drivers/video/omap2/dss/dpi.c
+++ b/drivers/video/omap2/dss/dpi.c
@@ -70,7 +70,7 @@ static bool dpi_use_dsi_pll(struct omap_dss_device *dssdev)
 		return false;
 }
 
-static int dpi_set_dsi_clk(struct omap_dss_device *dssdev,
+static int dpi_set_dsi_clk(struct omap_dss_output *out,
 		unsigned long pck_req, unsigned long *fck, int *lck_div,
 		int *pck_div)
 {
@@ -87,7 +87,7 @@ static int dpi_set_dsi_clk(struct omap_dss_device *dssdev,
 	if (r)
 		return r;
 
-	dss_select_dispc_clk_source(dssdev->clocks.dispc.dispc_fclk_src);
+	dss_select_dispc_clk_source(out->device->clocks.dispc.dispc_fclk_src);
 
 	dpi.mgr_config.clock_info = dispc_cinfo;
 
@@ -98,7 +98,7 @@ static int dpi_set_dsi_clk(struct omap_dss_device *dssdev,
 	return 0;
 }
 
-static int dpi_set_dispc_clk(struct omap_dss_device *dssdev,
+static int dpi_set_dispc_clk(struct omap_dss_output *out,
 		unsigned long pck_req, unsigned long *fck, int *lck_div,
 		int *pck_div)
 {
@@ -123,7 +123,7 @@ static int dpi_set_dispc_clk(struct omap_dss_device *dssdev,
 	return 0;
 }
 
-static int dpi_set_mode(struct omap_dss_device *dssdev)
+static int dpi_set_mode(struct omap_dss_output *out)
 {
 	struct omap_video_timings *t = &dpi.timings;
 	int lck_div = 0, pck_div = 0;
@@ -131,11 +131,11 @@ static int dpi_set_mode(struct omap_dss_device *dssdev)
 	unsigned long pck;
 	int r = 0;
 
-	if (dpi_use_dsi_pll(dssdev))
-		r = dpi_set_dsi_clk(dssdev, t->pixel_clock * 1000, &fck,
+	if (dpi_use_dsi_pll(out->device))
+		r = dpi_set_dsi_clk(out, t->pixel_clock * 1000, &fck,
 				&lck_div, &pck_div);
 	else
-		r = dpi_set_dispc_clk(dssdev, t->pixel_clock * 1000, &fck,
+		r = dpi_set_dispc_clk(out, t->pixel_clock * 1000, &fck,
 				&lck_div, &pck_div);
 	if (r)
 		return r;
@@ -150,12 +150,12 @@ static int dpi_set_mode(struct omap_dss_device *dssdev)
 		t->pixel_clock = pck;
 	}
 
-	dss_mgr_set_timings(dssdev->manager, t);
+	dss_mgr_set_timings(out->manager, t);
 
 	return 0;
 }
 
-static void dpi_config_lcd_manager(struct omap_dss_device *dssdev)
+static void dpi_config_lcd_manager(struct omap_dss_output *out)
 {
 	dpi.mgr_config.io_pad_mode = DSS_IO_PAD_MODE_BYPASS;
 
@@ -166,10 +166,10 @@ static void dpi_config_lcd_manager(struct omap_dss_device *dssdev)
 
 	dpi.mgr_config.lcden_sig_polarity = 0;
 
-	dss_mgr_set_lcd_config(dssdev->manager, &dpi.mgr_config);
+	dss_mgr_set_lcd_config(out->manager, &dpi.mgr_config);
 }
 
-int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
+int omapdss_dpi_display_enable(struct omap_dss_output *out)
 {
 	int r;
 
@@ -181,13 +181,13 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
 		goto err_no_reg;
 	}
 
-	if (dssdev->manager == NULL) {
+	if (out->manager == NULL) {
 		DSSERR("failed to enable display: no manager\n");
 		r = -ENODEV;
 		goto err_no_mgr;
 	}
 
-	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;
@@ -203,7 +203,7 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
 	if (r)
 		goto err_get_dispc;
 
-	if (dpi_use_dsi_pll(dssdev)) {
+	if (dpi_use_dsi_pll(out->device)) {
 		r = dsi_runtime_get(dpi.dsidev);
 		if (r)
 			goto err_get_dsi;
@@ -213,15 +213,15 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
 			goto err_dsi_pll_init;
 	}
 
-	r = dpi_set_mode(dssdev);
+	r = dpi_set_mode(out);
 	if (r)
 		goto err_set_mode;
 
-	dpi_config_lcd_manager(dssdev);
+	dpi_config_lcd_manager(out);
 
 	mdelay(2);
 
-	r = dss_mgr_enable(dssdev->manager);
+	r = dss_mgr_enable(out->manager);
 	if (r)
 		goto err_mgr_enable;
 
@@ -231,10 +231,10 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
 
 err_mgr_enable:
 err_set_mode:
-	if (dpi_use_dsi_pll(dssdev))
+	if (dpi_use_dsi_pll(out->device))
 		dsi_pll_uninit(dpi.dsidev, true);
 err_dsi_pll_init:
-	if (dpi_use_dsi_pll(dssdev))
+	if (dpi_use_dsi_pll(out->device))
 		dsi_runtime_put(dpi.dsidev);
 err_get_dsi:
 	dispc_runtime_put();
@@ -242,7 +242,7 @@ err_get_dispc:
 	if (cpu_is_omap34xx())
 		regulator_disable(dpi.vdds_dsi_reg);
 err_reg_enable:
-	omap_dss_stop_device(dssdev);
+	omap_dss_stop_device(out->device);
 err_start_dev:
 err_no_mgr:
 err_no_reg:
@@ -251,13 +251,13 @@ err_no_reg:
 }
 EXPORT_SYMBOL(omapdss_dpi_display_enable);
 
-void omapdss_dpi_display_disable(struct omap_dss_device *dssdev)
+void omapdss_dpi_display_disable(struct omap_dss_output *out)
 {
 	mutex_lock(&dpi.lock);
 
-	dss_mgr_disable(dssdev->manager);
+	dss_mgr_disable(out->manager);
 
-	if (dpi_use_dsi_pll(dssdev)) {
+	if (dpi_use_dsi_pll(out->device)) {
 		dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK);
 		dsi_pll_uninit(dpi.dsidev, true);
 		dsi_runtime_put(dpi.dsidev);
@@ -268,13 +268,13 @@ void omapdss_dpi_display_disable(struct omap_dss_device *dssdev)
 	if (cpu_is_omap34xx())
 		regulator_disable(dpi.vdds_dsi_reg);
 
-	omap_dss_stop_device(dssdev);
+	omap_dss_stop_device(out->device);
 
 	mutex_unlock(&dpi.lock);
 }
 EXPORT_SYMBOL(omapdss_dpi_display_disable);
 
-void omapdss_dpi_set_timings(struct omap_dss_device *dssdev,
+void omapdss_dpi_set_timings(struct omap_dss_output *out,
 		struct omap_video_timings *timings)
 {
 	int r;
@@ -285,23 +285,23 @@ void omapdss_dpi_set_timings(struct omap_dss_device *dssdev,
 
 	dpi.timings = *timings;
 
-	if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) {
+	if (out->device->state == OMAP_DSS_DISPLAY_ACTIVE) {
 		r = dispc_runtime_get();
 		if (r)
 			return;
 
-		dpi_set_mode(dssdev);
+		dpi_set_mode(out);
 
 		dispc_runtime_put();
 	} else {
-		dss_mgr_set_timings(dssdev->manager, timings);
+		dss_mgr_set_timings(out->manager, timings);
 	}
 
 	mutex_unlock(&dpi.lock);
 }
 EXPORT_SYMBOL(omapdss_dpi_set_timings);
 
-int dpi_check_timings(struct omap_dss_device *dssdev,
+int dpi_check_timings(struct omap_dss_output *out,
 			struct omap_video_timings *timings)
 {
 	int r;
@@ -310,13 +310,13 @@ int dpi_check_timings(struct omap_dss_device *dssdev,
 	unsigned long pck;
 	struct dispc_clock_info dispc_cinfo;
 
-	if (dss_mgr_check_timings(dssdev->manager, timings))
+	if (dss_mgr_check_timings(out->manager, timings))
 		return -EINVAL;
 
 	if (timings->pixel_clock == 0)
 		return -EINVAL;
 
-	if (dpi_use_dsi_pll(dssdev)) {
+	if (dpi_use_dsi_pll(out->device)) {
 		struct dsi_clock_info dsi_cinfo;
 		r = dsi_pll_calc_clock_div_pck(dpi.dsidev,
 				timings->pixel_clock * 1000,
@@ -348,7 +348,7 @@ int dpi_check_timings(struct omap_dss_device *dssdev,
 }
 EXPORT_SYMBOL(dpi_check_timings);
 
-void omapdss_dpi_set_data_lines(struct omap_dss_device *dssdev, int data_lines)
+void omapdss_dpi_set_data_lines(struct omap_dss_output *out, int data_lines)
 {
 	mutex_lock(&dpi.lock);
 
diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index 361d41e..da3f070 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -783,13 +783,13 @@ int omapdss_dsi_display_enable(struct omap_dss_device *dssdev);
 void omapdss_dsi_display_disable(struct omap_dss_device *dssdev,
 		bool disconnect_lanes, bool enter_ulps);
 
-int omapdss_dpi_display_enable(struct omap_dss_device *dssdev);
-void omapdss_dpi_display_disable(struct omap_dss_device *dssdev);
-void omapdss_dpi_set_timings(struct omap_dss_device *dssdev,
+int omapdss_dpi_display_enable(struct omap_dss_output *out);
+void omapdss_dpi_display_disable(struct omap_dss_output *out);
+void omapdss_dpi_set_timings(struct omap_dss_output *out,
 		struct omap_video_timings *timings);
-int dpi_check_timings(struct omap_dss_device *dssdev,
-			struct omap_video_timings *timings);
-void omapdss_dpi_set_data_lines(struct omap_dss_device *dssdev, int data_lines);
+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);
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [PATCH 11/23] OMAPDSS: DSI: Remove dsi_pdev_map global struct
  2012-08-21  6:10 ` Archit Taneja
@ 2012-08-21  6:10   ` Archit Taneja
  -1 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-08-21  5:58 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, rob, sumit.semwal, Archit Taneja

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	[flat|nested] 148+ messages in thread

* [PATCH 12/23] OMAPDSS: DSI: Pass outputs from panel driver to DSI interface driver
  2012-08-21  6:10 ` Archit Taneja
@ 2012-08-21  6:10   ` Archit Taneja
  -1 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-08-21  5:58 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, rob, sumit.semwal, Archit Taneja

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	[flat|nested] 148+ messages in thread

* [PATCH 13/23] OMAPDSS: SDI: Pass outputs from panel driver to SDI interface driver
  2012-08-21  6:10 ` Archit Taneja
@ 2012-08-21  6:10   ` Archit Taneja
  -1 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-08-21  5:58 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, rob, sumit.semwal, Archit Taneja

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	[flat|nested] 148+ messages in thread

* [PATCH 14/23] OMAPDSS: RFBI: Pass outputs from panel driver to RFBI interface driver
  2012-08-21  6:10 ` Archit Taneja
@ 2012-08-21  6:10   ` Archit Taneja
  -1 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-08-21  5:58 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, rob, sumit.semwal, Archit Taneja

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	[flat|nested] 148+ messages in thread

* [PATCH 15/23] OMAPDSS: RFBI: Add output pointers as arguments to all exported functions
  2012-08-21  6:10 ` Archit Taneja
@ 2012-08-21  6:10   ` Archit Taneja
  -1 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-08-21  5:58 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, rob, sumit.semwal, Archit Taneja

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	[flat|nested] 148+ messages in thread

* [PATCH 16/23] OMAPDSS: VENC: Pass outputs from panel driver to VENC interface driver
  2012-08-21  6:10 ` Archit Taneja
@ 2012-08-21  6:10   ` Archit Taneja
  -1 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-08-21  5:58 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, rob, sumit.semwal, Archit Taneja

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	[flat|nested] 148+ messages in thread

* [PATCH 17/23] OMAPDSS: HDMI: Pass outputs from panel driver to HDMI interface driver
  2012-08-21  6:10 ` Archit Taneja
@ 2012-08-21  6:10   ` Archit Taneja
  -1 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-08-21  5:58 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, rob, sumit.semwal, Archit Taneja

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	[flat|nested] 148+ messages in thread

* [PATCH 18/23] OMAPDSS: HDMI: Add output pointers as arguments to all functions used by hdmi panel driver
  2012-08-21  6:10 ` Archit Taneja
@ 2012-08-21  6:10   ` Archit Taneja
  -1 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-08-21  5:58 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, rob, sumit.semwal, Archit Taneja

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	[flat|nested] 148+ messages in thread

* [PATCH 19/23] OMAPDSS/OMAPFB: Change dssdev->manager references
  2012-08-21  6:10 ` Archit Taneja
@ 2012-08-21  6:10   ` Archit Taneja
  -1 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-08-21  5:58 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, rob, sumit.semwal, Archit Taneja

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	[flat|nested] 148+ messages in thread

* [PATCH 20/23] OMAPDSS: MANAGER: Update display sysfs store
  2012-08-21  6:10 ` Archit Taneja
@ 2012-08-21  6:10   ` Archit Taneja
  -1 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-08-21  5:58 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, rob, sumit.semwal, Archit Taneja

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	[flat|nested] 148+ messages in thread

* [PATCH 21/23] OMAPDSS: MANAGER: Get device via output
  2012-08-21  6:10 ` Archit Taneja
@ 2012-08-21  6:10   ` Archit Taneja
  -1 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-08-21  5:58 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, rob, sumit.semwal, Archit Taneja

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	[flat|nested] 148+ messages in thread

* [PATCH 22/23] OMAPDSS: APPLY: Remove omap_dss_device references from dss_ovl_enable/disable
  2012-08-21  6:10 ` Archit Taneja
@ 2012-08-21  6:10   ` Archit Taneja
  -1 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-08-21  5:58 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, rob, sumit.semwal, Archit Taneja

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	[flat|nested] 148+ messages in thread

* [PATCH 23/23] OMAPDSS: Remove old way of setting manager and device links
  2012-08-21  6:10 ` Archit Taneja
@ 2012-08-21  6:10   ` Archit Taneja
  -1 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-08-21  5:58 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, rob, sumit.semwal, Archit Taneja

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	[flat|nested] 148+ messages in thread

* [PATCH 00/23] OMAPDSS: Create output entities
@ 2012-08-21  6:10 ` Archit Taneja
  0 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-08-21  6:10 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, rob, sumit.semwal, Archit Taneja

Create a new entity in OMAPDSS called outputs. These represent the
interfaces/outputs like DSI, HDMI etc. that a panel connects to. An output
sits in between an overlay manager and a panel. More details about outputs
are explained in the first patch of the series.

This series adds omap_dss_output as an entity along with omap_overlay,
omap_overlay_manager and omap_dss_device. It changes the code to establish
links between managers and outputs, and outputs and devices. The rest of the
patches replace omap_dss_device with omap_dss_output as the argument exposed
by interface driver functions(DSI, HDMI etc) for panel drivers.

Reference tree:

git://gitorious.org/~boddob/linux-omap-dss2/archit-dss2-clone.git 2-add-outputs

Archit Taneja (23):
  OMAPDSS: outputs: Create a new entity called outputs
  OMAPDSS: outputs: Create and initialize output instances
  OMAPDSS: output: Add set/unset device ops for omap_dss_output
  OMAPDSS: APPLY: Add manager set/unset output ops for
    omap_overlay_manager
  OMAPDSS: Remove manager->device references
  OMAP_VOUT: Remove manager->device references
  OMAPFB: remove manager->device references
  OMAPDRM: Remove manager->device references
  OMAPDSS: Create links between managers, outputs and devices
  OMAPDSS: DPI: Pass outputs from panel driver to DPI interface driver
  OMAPDSS: DSI: Remove dsi_pdev_map global struct
  OMAPDSS: DSI: Pass outputs from panel driver to DSI interface driver
  OMAPDSS: SDI: Pass outputs from panel driver to SDI interface driver
  OMAPDSS: RFBI: Pass outputs from panel driver to RFBI interface
    driver
  OMAPDSS: RFBI: Add output pointers as arguments to all exported
    functions
  OMAPDSS: VENC: Pass outputs from panel driver to VENC interface
    driver
  OMAPDSS: HDMI: Pass outputs from panel driver to HDMI interface
    driver
  OMAPDSS: HDMI: Add output pointers as arguments to all functions used
    by hdmi panel driver
  OMAPDSS/OMAPFB: Change dssdev->manager references
  OMAPDSS: MANAGER: Update display sysfs store
  OMAPDSS: MANAGER: Get device via output
  OMAPDSS: APPLY: Remove omap_dss_device references from
    dss_ovl_enable/disable
  OMAPDSS: Remove old way of setting manager and device links

 drivers/media/video/omap/omap_vout.c               |   81 ++++--
 drivers/staging/omapdrm/omap_drv.c                 |    5 +-
 drivers/video/omap2/displays/panel-acx565akm.c     |   22 +-
 drivers/video/omap2/displays/panel-generic-dpi.c   |   27 +-
 .../omap2/displays/panel-lgphilips-lb035q02.c      |   16 +-
 drivers/video/omap2/displays/panel-n8x0.c          |  114 +++++---
 .../omap2/displays/panel-nec-nl8048hl11-01b.c      |   15 +-
 drivers/video/omap2/displays/panel-picodlp.c       |   15 +-
 .../video/omap2/displays/panel-sharp-ls037v7dw01.c |   16 +-
 drivers/video/omap2/displays/panel-taal.c          |  201 ++++++++-----
 drivers/video/omap2/displays/panel-tfp410.c        |   17 +-
 .../video/omap2/displays/panel-tpo-td043mtea1.c    |   29 +-
 drivers/video/omap2/dss/Makefile                   |    2 +-
 drivers/video/omap2/dss/apply.c                    |   52 ++--
 drivers/video/omap2/dss/core.c                     |    1 +
 drivers/video/omap2/dss/dispc.c                    |   10 +-
 drivers/video/omap2/dss/display.c                  |   11 +-
 drivers/video/omap2/dss/dpi.c                      |   84 ++++--
 drivers/video/omap2/dss/dsi.c                      |  307 +++++++++++---------
 drivers/video/omap2/dss/dss.h                      |   50 ++--
 drivers/video/omap2/dss/dss_features.c             |   52 ++++
 drivers/video/omap2/dss/dss_features.h             |    1 +
 drivers/video/omap2/dss/hdmi.c                     |   84 ++++--
 drivers/video/omap2/dss/hdmi_panel.c               |   85 ++++--
 drivers/video/omap2/dss/manager.c                  |   48 ++-
 drivers/video/omap2/dss/output.c                   |  125 ++++++++
 drivers/video/omap2/dss/overlay.c                  |   96 +++---
 drivers/video/omap2/dss/rfbi.c                     |   77 +++--
 drivers/video/omap2/dss/sdi.c                      |   54 ++--
 drivers/video/omap2/dss/venc.c                     |   78 +++--
 drivers/video/omap2/dss/venc_panel.c               |   53 +++-
 drivers/video/omap2/omapfb/omapfb-ioctl.c          |    4 +-
 drivers/video/omap2/omapfb/omapfb-main.c           |    7 +-
 drivers/video/omap2/omapfb/omapfb.h                |    5 +-
 include/video/omapdss.h                            |  172 ++++++-----
 35 files changed, 1350 insertions(+), 666 deletions(-)
 create mode 100644 drivers/video/omap2/dss/output.c

-- 
1.7.9.5


^ permalink raw reply	[flat|nested] 148+ messages in thread

* [PATCH 01/23] OMAPDSS: outputs: Create a new entity called outputs
@ 2012-08-21  6:10   ` Archit Taneja
  0 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-08-21  6:10 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, rob, sumit.semwal, Archit Taneja

The current OMAPDSS design contains 3 software entities: Overlays, Managers and
Devices. These map to pipelines, overlay managers and the panels respectively in
hardware. One or more overlays connect to a manager to represent a composition,
the manager connects to a device(generally a display) to display the content.

The part of DSS hardware which isn't represented by any of the above entities
are interfaces/outputs that connect to an overlay manager, i.e blocks like DSI,
HDMI, VENC and so on. Currently, an overlay manager directly connects to the
display, and the output to which it is actually connected is ignored. The panel
driver of the display is responsible of calling output specific functions to
configure the output.

Adding outputs as a new software entity gives us the following benefits:

- Have exact information on the possible connections between managers and
  outputs: A manager can't connect to each and every output, there only limited
  hardware links between a manager's video port and some of the outputs.

- Remove hacks related to connecting managers and devices: Currently, default
  links between managers and devices are set in a not so clean way. Matching is
  done via comparing the device type, and the display types supported by the
  manager. This isn't sufficient to establish all the possible links between
  managers, outputs and devices in hardware.

- Make panel drivers more generic: The DSS panel drivers currently call
  interface/output specific functions to configure the hardware IP. When making
  these calls, the driver isn't actually aware of the underlying output. The
  output driver extracts information from the panel's omap_dss_device pointer
  to figure out which interface it is connected to, and then configures the
  corresponding output block. An example of this is when a DSI panel calls
  dsi functions, the dsi driver figures out whether the panel is connected
  to DSI1 or DSI2. This isn't correct, and having output as entities will
  give the panel driver the exact information on which output to configure.
  Having outputs also gives the opportunity to make panel drivers generic
  across different platforms/SoCs, this is achieved as omap specific output
  calls can be replaced by ops of a particular output type.

- Have more complex connections between managers, outputs and devices: OMAPDSS
  currently doesn't support use cases like 2 outputs connect to a single
  device. This can be achieved by extending properties of outputs to connect to
  more managers or devices.

- Represent writeback as an output: The writeback pipeline fits well in OMAPDSS
  as compared to overlays, managers or devices.

Add a new struct to represent outputs. An output struct holds pointers to the
manager and device structs to which it is connected. Add functions which can
add an output, or look for one. Create an enum which represent each output
instance.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/dss/Makefile |    2 +-
 drivers/video/omap2/dss/core.c   |    1 +
 drivers/video/omap2/dss/dss.h    |    4 +++
 drivers/video/omap2/dss/output.c |   58 ++++++++++++++++++++++++++++++++++++++
 include/video/omapdss.h          |   30 ++++++++++++++++++++
 5 files changed, 94 insertions(+), 1 deletion(-)
 create mode 100644 drivers/video/omap2/dss/output.c

diff --git a/drivers/video/omap2/dss/Makefile b/drivers/video/omap2/dss/Makefile
index 30a48fb..645f8c3 100644
--- a/drivers/video/omap2/dss/Makefile
+++ b/drivers/video/omap2/dss/Makefile
@@ -1,6 +1,6 @@
 obj-$(CONFIG_OMAP2_DSS) += omapdss.o
 omapdss-y := core.o dss.o dss_features.o dispc.o dispc_coefs.o display.o \
-	manager.o overlay.o apply.o
+	manager.o overlay.o output.o apply.o
 omapdss-$(CONFIG_OMAP2_DSS_DPI) += dpi.o
 omapdss-$(CONFIG_OMAP2_DSS_RFBI) += rfbi.o
 omapdss-$(CONFIG_OMAP2_DSS_VENC) += venc.o venc_panel.o
diff --git a/drivers/video/omap2/dss/core.c b/drivers/video/omap2/dss/core.c
index c35a248..2eccd74 100644
--- a/drivers/video/omap2/dss/core.c
+++ b/drivers/video/omap2/dss/core.c
@@ -239,6 +239,7 @@ static int __init omap_dss_probe(struct platform_device *pdev)
 
 	dss_init_overlay_managers(pdev);
 	dss_init_overlays(pdev);
+	dss_init_outputs();
 
 	r = dss_initialize_debugfs();
 	if (r)
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index 41c00dc..8a7c94c 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -222,6 +222,10 @@ int dss_ovl_set_manager(struct omap_overlay *ovl,
 		struct omap_overlay_manager *mgr);
 int dss_ovl_unset_manager(struct omap_overlay *ovl);
 
+/* output */
+struct omap_dss_output *dss_create_output(struct platform_device *pdev);
+void dss_init_outputs(void);
+
 /* display */
 int dss_suspend_all_devices(void);
 int dss_resume_all_devices(void);
diff --git a/drivers/video/omap2/dss/output.c b/drivers/video/omap2/dss/output.c
new file mode 100644
index 0000000..034ebbe
--- /dev/null
+++ b/drivers/video/omap2/dss/output.c
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2012 Texas Instruments Ltd
+ * Author: Archit Taneja <archit@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#include <video/omapdss.h>
+
+#include "dss.h"
+
+static struct list_head output_list;
+
+struct omap_dss_output *dss_create_output(struct platform_device *pdev)
+{
+	struct omap_dss_output *out;
+
+	out = kzalloc(sizeof(struct omap_dss_output *), GFP_KERNEL);
+	if (!out)
+		return NULL;
+
+	out->pdev = pdev;
+
+	list_add_tail(&out->list, &output_list);
+
+	return out;
+}
+
+struct omap_dss_output *omap_dss_get_output(enum omap_dss_output_id id)
+{
+	struct omap_dss_output *out;
+
+	list_for_each_entry(out, &output_list, list) {
+		if (out->id = id)
+			return out;
+	}
+
+	return NULL;
+}
+
+void dss_init_outputs(void)
+{
+	INIT_LIST_HEAD(&output_list);
+}
diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index b868123..0ba613f 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -207,6 +207,16 @@ enum omap_hdmi_flags {
 	OMAP_HDMI_SDA_SCL_EXTERNAL_PULLUP = 1 << 0,
 };
 
+enum omap_dss_output_id {
+	OMAP_DSS_OUTPUT_DPI	= 1 << 0,
+	OMAP_DSS_OUTPUT_DBI	= 1 << 1,
+	OMAP_DSS_OUTPUT_SDI	= 1 << 2,
+	OMAP_DSS_OUTPUT_DSI1	= 1 << 3,
+	OMAP_DSS_OUTPUT_VENC	= 1 << 4,
+	OMAP_DSS_OUTPUT_DSI2	= 1 << 5,
+	OMAP_DSS_OUTPUT_HDMI	= 1 << 6,
+};
+
 /* RFBI */
 
 struct rfbi_timings {
@@ -492,6 +502,24 @@ struct omap_dsi_pin_config {
 	int pins[OMAP_DSS_MAX_DSI_PINS];
 };
 
+struct omap_dss_output {
+	struct list_head list;
+
+	/* display type supported by the output */
+	enum omap_display_type type;
+
+	/* output instance */
+	enum omap_dss_output_id id;
+
+	/* output's platform device pointer */
+	struct platform_device *pdev;
+
+	/* dynamic fields */
+	struct omap_overlay_manager *manager;
+
+	struct omap_dss_device *device;
+};
+
 struct omap_dss_device {
 	struct device dev;
 
@@ -699,6 +727,8 @@ struct omap_overlay_manager *omap_dss_get_overlay_manager(int num);
 int omap_dss_get_num_overlays(void);
 struct omap_overlay *omap_dss_get_overlay(int num);
 
+struct omap_dss_output *omap_dss_get_output(enum omap_dss_output_id id);
+
 void omapdss_default_get_resolution(struct omap_dss_device *dssdev,
 		u16 *xres, u16 *yres);
 int omapdss_default_get_recommended_bpp(struct omap_dss_device *dssdev);
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [PATCH 02/23] OMAPDSS: outputs: Create and initialize output instances
@ 2012-08-21  6:10   ` Archit Taneja
  0 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-08-21  6:10 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, rob, sumit.semwal, Archit Taneja

Create output instances by having an init function in the probes of the platform
device drivers for different interfaces. Create a small function for each
interface to initialize the output entity's fields type and id.

In the probe of each interface driver, the output entities are created before
the *_probe_pdata() functions intentionally. This is done to ensure that the
output entity is prepared before the panels connected to the output are
registered. We need the output entities to be ready because OMAPDSS will try
to make connections between overlays, managers, outputs and devices during the
panel's probe.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/dss/dpi.c  |   20 ++++++++++++++++++++
 drivers/video/omap2/dss/dsi.c  |   26 ++++++++++++++++++++++++--
 drivers/video/omap2/dss/hdmi.c |   18 ++++++++++++++++++
 drivers/video/omap2/dss/rfbi.c |   19 +++++++++++++++++++
 drivers/video/omap2/dss/sdi.c  |   20 ++++++++++++++++++++
 drivers/video/omap2/dss/venc.c |   20 ++++++++++++++++++++
 6 files changed, 121 insertions(+), 2 deletions(-)

diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c
index f260343..4eca2e7 100644
--- a/drivers/video/omap2/dss/dpi.c
+++ b/drivers/video/omap2/dss/dpi.c
@@ -408,10 +408,30 @@ static void __init dpi_probe_pdata(struct platform_device *pdev)
 	}
 }
 
+static int __init dpi_init_output(struct platform_device *pdev)
+{
+	struct omap_dss_output *out;
+
+	out = dss_create_output(pdev);
+	if (!out)
+		return -ENOMEM;
+
+	out->id = OMAP_DSS_OUTPUT_DPI;
+	out->type = OMAP_DISPLAY_TYPE_DPI;
+
+	return 0;
+}
+
 static int __init omap_dpi_probe(struct platform_device *pdev)
 {
+	int r;
+
 	mutex_init(&dpi.lock);
 
+	r = dpi_init_output(pdev);
+	if (r)
+		return r;
+
 	dpi_probe_pdata(pdev);
 
 	return 0;
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index 659b6cd..22e0873 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -4903,6 +4903,23 @@ static void __init dsi_probe_pdata(struct platform_device *dsidev)
 	}
 }
 
+static int __init dsi_init_output(struct platform_device *dsidev,
+		struct dsi_data *dsi)
+{
+	struct omap_dss_output *out;
+
+	out = dss_create_output(dsidev);
+	if (!out)
+		return -ENOMEM;
+
+	out->id = dsi->module_id = 0 ?
+			OMAP_DSS_OUTPUT_DSI1 : OMAP_DSS_OUTPUT_DSI2;
+
+	out->type = OMAP_DISPLAY_TYPE_DSI;
+
+	return 0;
+}
+
 /* DSI1 HW IP initialisation */
 static int __init omap_dsihw_probe(struct platform_device *dsidev)
 {
@@ -4997,10 +5014,14 @@ static int __init omap_dsihw_probe(struct platform_device *dsidev)
 	else
 		dsi->num_lanes_supported = 3;
 
-	dsi_probe_pdata(dsidev);
-
 	dsi_runtime_put(dsidev);
 
+	r = dsi_init_output(dsidev, dsi);
+	if (r)
+		goto err_init_output;
+
+	dsi_probe_pdata(dsidev);
+
 	if (dsi->module_id = 0)
 		dss_debugfs_create_file("dsi1_regs", dsi1_dump_regs);
 	else if (dsi->module_id = 1)
@@ -5014,6 +5035,7 @@ static int __init omap_dsihw_probe(struct platform_device *dsidev)
 #endif
 	return 0;
 
+err_init_output:
 err_runtime_get:
 	pm_runtime_disable(&dsidev->dev);
 	dsi_put_clocks(dsidev);
diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c
index 0cdf246..d32dbc3 100644
--- a/drivers/video/omap2/dss/hdmi.c
+++ b/drivers/video/omap2/dss/hdmi.c
@@ -890,6 +890,20 @@ static void __init hdmi_probe_pdata(struct platform_device *pdev)
 	}
 }
 
+static int __init hdmi_init_output(struct platform_device *pdev)
+{
+	struct omap_dss_output *out;
+
+	out = dss_create_output(pdev);
+	if (!out)
+		return -ENOMEM;
+
+	out->id = OMAP_DSS_OUTPUT_HDMI;
+	out->type = OMAP_DISPLAY_TYPE_HDMI;
+
+	return 0;
+}
+
 /* HDMI HW IP initialisation */
 static int __init omapdss_hdmihw_probe(struct platform_device *pdev)
 {
@@ -933,6 +947,10 @@ static int __init omapdss_hdmihw_probe(struct platform_device *pdev)
 
 	dss_debugfs_create_file("hdmi", hdmi_dump_regs);
 
+	r = hdmi_init_output(pdev);
+	if (r)
+		return r;
+
 	hdmi_probe_pdata(pdev);
 
 	return 0;
diff --git a/drivers/video/omap2/dss/rfbi.c b/drivers/video/omap2/dss/rfbi.c
index 5a9c0e9..9d9244c 100644
--- a/drivers/video/omap2/dss/rfbi.c
+++ b/drivers/video/omap2/dss/rfbi.c
@@ -967,6 +967,20 @@ static void __init rfbi_probe_pdata(struct platform_device *pdev)
 	}
 }
 
+static int __init rfbi_init_output(struct platform_device *pdev)
+{
+	struct omap_dss_output *out;
+
+	out = dss_create_output(pdev);
+	if (!out)
+		return -ENOMEM;
+
+	out->id = OMAP_DSS_OUTPUT_DBI;
+	out->type = OMAP_DISPLAY_TYPE_DBI;
+
+	return 0;
+}
+
 /* RFBI HW IP initialisation */
 static int __init omap_rfbihw_probe(struct platform_device *pdev)
 {
@@ -1018,10 +1032,15 @@ static int __init omap_rfbihw_probe(struct platform_device *pdev)
 
 	dss_debugfs_create_file("rfbi", rfbi_dump_regs);
 
+	r = rfbi_init_output(pdev);
+	if (r)
+		goto err_init_output;
+
 	rfbi_probe_pdata(pdev);
 
 	return 0;
 
+err_init_output:
 err_runtime_get:
 	pm_runtime_disable(&pdev->dev);
 	return r;
diff --git a/drivers/video/omap2/dss/sdi.c b/drivers/video/omap2/dss/sdi.c
index 3bf1bfe..a5632d0 100644
--- a/drivers/video/omap2/dss/sdi.c
+++ b/drivers/video/omap2/dss/sdi.c
@@ -216,8 +216,28 @@ static void __init sdi_probe_pdata(struct platform_device *pdev)
 	}
 }
 
+static int __init sdi_init_output(struct platform_device *pdev)
+{
+	struct omap_dss_output *out;
+
+	out = dss_create_output(pdev);
+	if (!out)
+		return -ENOMEM;
+
+	out->id = OMAP_DSS_OUTPUT_SDI;
+	out->type = OMAP_DISPLAY_TYPE_SDI;
+
+	return 0;
+}
+
 static int __init omap_sdi_probe(struct platform_device *pdev)
 {
+	int r;
+
+	r = sdi_init_output(pdev);
+	if (r)
+		return r;
+
 	sdi_probe_pdata(pdev);
 
 	return 0;
diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c
index 7d3eef8..264c5ec 100644
--- a/drivers/video/omap2/dss/venc.c
+++ b/drivers/video/omap2/dss/venc.c
@@ -778,6 +778,20 @@ static void __init venc_probe_pdata(struct platform_device *pdev)
 	}
 }
 
+static int __init venc_init_output(struct platform_device *pdev)
+{
+	struct omap_dss_output *out;
+
+	out = dss_create_output(pdev);
+	if (!out)
+		return -ENOMEM;
+
+	out->id = OMAP_DSS_OUTPUT_VENC;
+	out->type = OMAP_DISPLAY_TYPE_VENC;
+
+	return 0;
+}
+
 /* VENC HW IP initialisation */
 static int __init omap_venchw_probe(struct platform_device *pdev)
 {
@@ -825,10 +839,16 @@ static int __init omap_venchw_probe(struct platform_device *pdev)
 
 	dss_debugfs_create_file("venc", venc_dump_regs);
 
+	r = venc_init_output(pdev);
+	if (r)
+		goto err_init_output;
+
 	venc_probe_pdata(pdev);
 
 	return 0;
 
+err_init_output:
+	venc_panel_exit();
 err_panel_init:
 err_runtime_get:
 	pm_runtime_disable(&pdev->dev);
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [PATCH 03/23] OMAPDSS: output: Add set/unset device ops for omap_dss_output
@ 2012-08-21  6:10   ` Archit Taneja
  0 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-08-21  6:10 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, rob, sumit.semwal, Archit Taneja

An output entity represented by the struct omap_dss_output connects to a
omap_dss_device entity. Add functions to set or unset an output's device. This
is similar to how managers and devices were connected previously. An output can
connect to a device without being connected to a manager. However, the output
needs to eventually connect to a manager so that the connected panel can be
enabled.

Keep the omap_overlay_manager pointer in omap_dss_device for now to prevent
breaking things. This will be removed later when outputs are supported
completely.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/dss/output.c |   67 ++++++++++++++++++++++++++++++++++++++
 include/video/omapdss.h          |    5 +++
 2 files changed, 72 insertions(+)

diff --git a/drivers/video/omap2/dss/output.c b/drivers/video/omap2/dss/output.c
index 034ebbe..ac57b19 100644
--- a/drivers/video/omap2/dss/output.c
+++ b/drivers/video/omap2/dss/output.c
@@ -24,6 +24,70 @@
 #include "dss.h"
 
 static struct list_head output_list;
+static DEFINE_MUTEX(output_lock);
+
+static int dss_output_set_device(struct omap_dss_output *out,
+		struct omap_dss_device *dssdev)
+{
+	int r;
+
+	mutex_lock(&output_lock);
+
+	if (out->device) {
+		DSSERR("output already has device %s connected to it\n",
+			out->device->name);
+		r = -EINVAL;
+		goto err;
+	}
+
+	if (out->type != dssdev->type) {
+		DSSERR("output type and display type don't match\n");
+		r = -EINVAL;
+		goto err;
+	}
+
+	out->device = dssdev;
+	dssdev->output = out;
+
+	mutex_unlock(&output_lock);
+
+	return 0;
+err:
+	mutex_unlock(&output_lock);
+
+	return r;
+}
+
+static int dss_output_unset_device(struct omap_dss_output *out)
+{
+	int r;
+
+	mutex_lock(&output_lock);
+
+	if (!out->device) {
+		DSSERR("output doesn't have a device connected to it\n");
+		r = -EINVAL;
+		goto err;
+	}
+
+	if (out->device->state != OMAP_DSS_DISPLAY_DISABLED) {
+		DSSERR("device %s is not disabled, cannot unset device\n",
+				out->device->name);
+		r = -EINVAL;
+		goto err;
+	}
+
+	out->device->output = NULL;
+	out->device = NULL;
+
+	mutex_unlock(&output_lock);
+
+	return 0;
+err:
+	mutex_unlock(&output_lock);
+
+	return r;
+}
 
 struct omap_dss_output *dss_create_output(struct platform_device *pdev)
 {
@@ -35,6 +99,9 @@ struct omap_dss_output *dss_create_output(struct platform_device *pdev)
 
 	out->pdev = pdev;
 
+	out->set_device = &dss_output_set_device;
+	out->unset_device = &dss_output_unset_device;
+
 	list_add_tail(&out->list, &output_list);
 
 	return out;
diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index 0ba613f..2e40f27 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -518,6 +518,10 @@ struct omap_dss_output {
 	struct omap_overlay_manager *manager;
 
 	struct omap_dss_device *device;
+
+	int (*set_device) (struct omap_dss_output *out,
+		struct omap_dss_device *dssdev);
+	int (*unset_device) (struct omap_dss_output *out);
 };
 
 struct omap_dss_device {
@@ -619,6 +623,7 @@ 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	[flat|nested] 148+ messages in thread

* [PATCH 04/23] OMAPDSS: APPLY: Add manager set/unset output ops for omap_overlay_manager
@ 2012-08-21  6:10   ` Archit Taneja
  0 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-08-21  6:10 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, rob, sumit.semwal, Archit Taneja

Add set_output/unset_output ops for overlay managers, these form links between
managers and outputs. Create a function in dss features which tell all the
output instances that connect to a manager, use it when a manager tries to set
an output. Add a constraint of not unsetting an output when the manager is
enabled.

Keep the omap_dss_device pointer and set/unset_device ops in overlay_manager for
now to not break things. Keep the dss feature function get_supported_displays
as it's used in some places. These will be removed later.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/dss/apply.c        |   70 ++++++++++++++++++++++++++++++++
 drivers/video/omap2/dss/dss.h          |    3 ++
 drivers/video/omap2/dss/dss_features.c |   52 ++++++++++++++++++++++++
 drivers/video/omap2/dss/dss_features.h |    1 +
 drivers/video/omap2/dss/manager.c      |    4 ++
 include/video/omapdss.h                |    5 +++
 6 files changed, 135 insertions(+)

diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c
index 74f1a58..d241407 100644
--- a/drivers/video/omap2/dss/apply.c
+++ b/drivers/video/omap2/dss/apply.c
@@ -1311,6 +1311,76 @@ err:
 	return r;
 }
 
+int dss_mgr_set_output(struct omap_overlay_manager *mgr,
+		struct omap_dss_output *output)
+{
+	int r;
+
+	mutex_lock(&apply_lock);
+
+	if (mgr->output) {
+		DSSERR("manager %s is already connected to an output\n",
+			mgr->name);
+		r = -EINVAL;
+		goto err;
+	}
+
+	if ((mgr->supported_outputs & output->id) = 0) {
+		DSSERR("output does not support manager %s\n",
+			mgr->name);
+		r = -EINVAL;
+		goto err;
+	}
+
+	output->manager = mgr;
+	mgr->output = output;
+
+	mutex_unlock(&apply_lock);
+
+	return 0;
+err:
+	mutex_unlock(&apply_lock);
+	return r;
+}
+
+int dss_mgr_unset_output(struct omap_overlay_manager *mgr)
+{
+	int r;
+	struct mgr_priv_data *mp = get_mgr_priv(mgr);
+	unsigned long flags;
+
+	mutex_lock(&apply_lock);
+
+	if (!mgr->output) {
+		DSSERR("failed to unset output, output not set\n");
+		r = -EINVAL;
+		goto err;
+	}
+
+	spin_lock_irqsave(&data_lock, flags);
+
+	if (mp->enabled) {
+		DSSERR("output can't be unset when manager is enabled\n");
+		r = -EINVAL;
+		goto err1;
+	}
+
+	spin_unlock_irqrestore(&data_lock, flags);
+
+	mgr->output->manager = NULL;
+	mgr->output = NULL;
+
+	mutex_unlock(&apply_lock);
+
+	return 0;
+err1:
+	spin_unlock_irqrestore(&data_lock, flags);
+err:
+	mutex_unlock(&apply_lock);
+
+	return r;
+}
+
 static void dss_apply_mgr_timings(struct omap_overlay_manager *mgr,
 		const struct omap_video_timings *timings)
 {
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index 8a7c94c..a119506 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -205,6 +205,9 @@ void dss_mgr_get_info(struct omap_overlay_manager *mgr,
 int dss_mgr_set_device(struct omap_overlay_manager *mgr,
 		struct omap_dss_device *dssdev);
 int dss_mgr_unset_device(struct omap_overlay_manager *mgr);
+int dss_mgr_set_output(struct omap_overlay_manager *mgr,
+		struct omap_dss_output *output);
+int dss_mgr_unset_output(struct omap_overlay_manager *mgr);
 void dss_mgr_set_timings(struct omap_overlay_manager *mgr,
 		const struct omap_video_timings *timings);
 void dss_mgr_set_lcd_config(struct omap_overlay_manager *mgr,
diff --git a/drivers/video/omap2/dss/dss_features.c b/drivers/video/omap2/dss/dss_features.c
index 9387097..43f8491 100644
--- a/drivers/video/omap2/dss/dss_features.c
+++ b/drivers/video/omap2/dss/dss_features.c
@@ -47,6 +47,7 @@ struct omap_dss_features {
 	const int num_mgrs;
 	const int num_ovls;
 	const enum omap_display_type *supported_displays;
+	const enum omap_dss_output_id *supported_outputs;
 	const enum omap_color_mode *supported_color_modes;
 	const enum omap_overlay_caps *overlay_caps;
 	const char * const *clksrc_names;
@@ -144,6 +145,46 @@ static const enum omap_display_type omap4_dss_supported_displays[] = {
 	OMAP_DISPLAY_TYPE_DSI,
 };
 
+static const enum omap_dss_output_id omap2_dss_supported_outputs[] = {
+	/* OMAP_DSS_CHANNEL_LCD */
+	OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI,
+
+	/* OMAP_DSS_CHANNEL_DIGIT */
+	OMAP_DSS_OUTPUT_VENC,
+};
+
+static const enum omap_dss_output_id omap3430_dss_supported_outputs[] = {
+	/* OMAP_DSS_CHANNEL_LCD */
+	OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI |
+	OMAP_DSS_OUTPUT_SDI | OMAP_DSS_OUTPUT_DSI1,
+
+	/* OMAP_DSS_CHANNEL_DIGIT */
+	OMAP_DSS_OUTPUT_VENC,
+};
+
+static const enum omap_dss_output_id omap3630_dss_supported_outputs[] = {
+	/* OMAP_DSS_CHANNEL_LCD */
+	OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI |
+	OMAP_DSS_OUTPUT_DSI1,
+
+	/* OMAP_DSS_CHANNEL_DIGIT */
+	OMAP_DSS_OUTPUT_VENC,
+};
+
+static const enum omap_dss_output_id omap4_dss_supported_outputs[] = {
+	/* OMAP_DSS_CHANNEL_LCD */
+	OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI |
+	OMAP_DSS_OUTPUT_DSI1,
+
+	/* OMAP_DSS_CHANNEL_DIGIT */
+	OMAP_DSS_OUTPUT_VENC | OMAP_DSS_OUTPUT_HDMI |
+	OMAP_DSS_OUTPUT_DPI,
+
+	/* OMAP_DSS_CHANNEL_LCD2 */
+	OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI |
+	OMAP_DSS_OUTPUT_DSI2,
+};
+
 static const enum omap_color_mode omap2_dss_supported_color_modes[] = {
 	/* OMAP_DSS_GFX */
 	OMAP_DSS_COLOR_CLUT1 | OMAP_DSS_COLOR_CLUT2 |
@@ -458,6 +499,7 @@ static const struct omap_dss_features omap2_dss_features = {
 	.num_mgrs = 2,
 	.num_ovls = 3,
 	.supported_displays = omap2_dss_supported_displays,
+	.supported_outputs = omap2_dss_supported_outputs,
 	.supported_color_modes = omap2_dss_supported_color_modes,
 	.overlay_caps = omap2_dss_overlay_caps,
 	.clksrc_names = omap2_dss_clk_source_names,
@@ -478,6 +520,7 @@ static const struct omap_dss_features omap3430_dss_features = {
 	.num_mgrs = 2,
 	.num_ovls = 3,
 	.supported_displays = omap3430_dss_supported_displays,
+	.supported_outputs = omap3430_dss_supported_outputs,
 	.supported_color_modes = omap3_dss_supported_color_modes,
 	.overlay_caps = omap3430_dss_overlay_caps,
 	.clksrc_names = omap3_dss_clk_source_names,
@@ -497,6 +540,7 @@ static const struct omap_dss_features omap3630_dss_features = {
 	.num_mgrs = 2,
 	.num_ovls = 3,
 	.supported_displays = omap3630_dss_supported_displays,
+	.supported_outputs = omap3630_dss_supported_outputs,
 	.supported_color_modes = omap3_dss_supported_color_modes,
 	.overlay_caps = omap3630_dss_overlay_caps,
 	.clksrc_names = omap3_dss_clk_source_names,
@@ -518,6 +562,7 @@ static const struct omap_dss_features omap4430_es1_0_dss_features  = {
 	.num_mgrs = 3,
 	.num_ovls = 4,
 	.supported_displays = omap4_dss_supported_displays,
+	.supported_outputs = omap4_dss_supported_outputs,
 	.supported_color_modes = omap4_dss_supported_color_modes,
 	.overlay_caps = omap4_dss_overlay_caps,
 	.clksrc_names = omap4_dss_clk_source_names,
@@ -538,6 +583,7 @@ static const struct omap_dss_features omap4430_es2_0_1_2_dss_features = {
 	.num_mgrs = 3,
 	.num_ovls = 4,
 	.supported_displays = omap4_dss_supported_displays,
+	.supported_outputs = omap4_dss_supported_outputs,
 	.supported_color_modes = omap4_dss_supported_color_modes,
 	.overlay_caps = omap4_dss_overlay_caps,
 	.clksrc_names = omap4_dss_clk_source_names,
@@ -558,6 +604,7 @@ static const struct omap_dss_features omap4_dss_features = {
 	.num_mgrs = 3,
 	.num_ovls = 4,
 	.supported_displays = omap4_dss_supported_displays,
+	.supported_outputs = omap4_dss_supported_outputs,
 	.supported_color_modes = omap4_dss_supported_color_modes,
 	.overlay_caps = omap4_dss_overlay_caps,
 	.clksrc_names = omap4_dss_clk_source_names,
@@ -627,6 +674,11 @@ enum omap_display_type dss_feat_get_supported_displays(enum omap_channel channel
 	return omap_current_dss_features->supported_displays[channel];
 }
 
+enum omap_dss_output_id dss_feat_get_supported_outputs(enum omap_channel channel)
+{
+	return omap_current_dss_features->supported_outputs[channel];
+}
+
 enum omap_color_mode dss_feat_get_supported_color_modes(enum omap_plane plane)
 {
 	return omap_current_dss_features->supported_color_modes[plane];
diff --git a/drivers/video/omap2/dss/dss_features.h b/drivers/video/omap2/dss/dss_features.h
index 996ffcb..89a71d1 100644
--- a/drivers/video/omap2/dss/dss_features.h
+++ b/drivers/video/omap2/dss/dss_features.h
@@ -103,6 +103,7 @@ int dss_feat_get_num_ovls(void);
 unsigned long dss_feat_get_param_min(enum dss_range_param param);
 unsigned long dss_feat_get_param_max(enum dss_range_param param);
 enum omap_display_type dss_feat_get_supported_displays(enum omap_channel channel);
+enum omap_dss_output_id dss_feat_get_supported_outputs(enum omap_channel channel);
 enum omap_color_mode dss_feat_get_supported_color_modes(enum omap_plane plane);
 enum omap_overlay_caps dss_feat_get_overlay_caps(enum omap_plane plane);
 bool dss_feat_color_mode_supported(enum omap_plane plane,
diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c
index 53710fa..e15fa5f 100644
--- a/drivers/video/omap2/dss/manager.c
+++ b/drivers/video/omap2/dss/manager.c
@@ -549,6 +549,8 @@ int dss_init_overlay_managers(struct platform_device *pdev)
 
 		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;
 		mgr->set_manager_info = &dss_mgr_set_info;
 		mgr->get_manager_info = &dss_mgr_get_info;
@@ -558,6 +560,8 @@ int dss_init_overlay_managers(struct platform_device *pdev)
 		mgr->caps = 0;
 		mgr->supported_displays  			dss_feat_get_supported_displays(mgr->id);
+		mgr->supported_outputs +			dss_feat_get_supported_outputs(mgr->id);
 
 		INIT_LIST_HEAD(&mgr->overlays);
 
diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index 2e40f27..813672b 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -458,9 +458,11 @@ struct omap_overlay_manager {
 	enum omap_overlay_manager_caps caps;
 	struct list_head overlays;
 	enum omap_display_type supported_displays;
+	enum omap_dss_output_id supported_outputs;
 
 	/* dynamic fields */
 	struct omap_dss_device *device;
+	struct omap_dss_output *output;
 
 	/*
 	 * The following functions do not block:
@@ -476,6 +478,9 @@ struct omap_overlay_manager {
 	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);
 
 	int (*set_manager_info)(struct omap_overlay_manager *mgr,
 			struct omap_overlay_manager_info *info);
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [PATCH 05/23] OMAPDSS: Remove manager->device references
@ 2012-08-21  6:10   ` Archit Taneja
  0 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-08-21  6:10 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, rob, sumit.semwal, Archit Taneja

With the introduction of output entities, managers will now connect to outputs.
Create a helper op for managers named get_device. This will abstract away the
information on how to get the device from an overlay manager. The get_device
op currently retrieves the output via a manager->device reference. This will
be later replaced by a manager->output->device reference.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/dss/apply.c   |    6 ++++--
 drivers/video/omap2/dss/dispc.c   |   10 +++++++---
 drivers/video/omap2/dss/manager.c |   19 ++++++++++++++-----
 include/video/omapdss.h           |    2 ++
 4 files changed, 27 insertions(+), 10 deletions(-)

diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c
index d241407..8a05cbc 100644
--- a/drivers/video/omap2/dss/apply.c
+++ b/drivers/video/omap2/dss/apply.c
@@ -1607,7 +1607,8 @@ int dss_ovl_enable(struct omap_overlay *ovl)
 		goto err1;
 	}
 
-	if (ovl->manager = NULL || ovl->manager->device = NULL) {
+	if (ovl->manager = NULL ||
+			ovl->manager->get_device(ovl->manager) = NULL) {
 		r = -EINVAL;
 		goto err1;
 	}
@@ -1676,7 +1677,8 @@ int dss_ovl_disable(struct omap_overlay *ovl)
 		goto err;
 	}
 
-	if (ovl->manager = NULL || ovl->manager->device = NULL) {
+	if (ovl->manager = NULL ||
+			ovl->manager->get_device(ovl->manager) = NULL) {
 		r = -EINVAL;
 		goto err;
 	}
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index ff52702..33061f5 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -3503,7 +3503,7 @@ static void dispc_error_worker(struct work_struct *work)
 		bit = mgr_desc[i].sync_lost_irq;
 
 		if (bit & errors) {
-			struct omap_dss_device *dssdev = mgr->device;
+			struct omap_dss_device *dssdev = mgr->get_device(mgr);
 			bool enable;
 
 			DSSERR("SYNC_LOST on channel %s, restarting the output "
@@ -3534,9 +3534,13 @@ static void dispc_error_worker(struct work_struct *work)
 		DSSERR("OCP_ERR\n");
 		for (i = 0; i < omap_dss_get_num_overlay_managers(); ++i) {
 			struct omap_overlay_manager *mgr;
+			struct omap_dss_device *dssdev;
+
 			mgr = omap_dss_get_overlay_manager(i);
-			if (mgr->device && mgr->device->driver)
-				mgr->device->driver->disable(mgr->device);
+			dssdev = mgr->get_device(mgr);
+
+			if (dssdev && dssdev->driver)
+				dssdev->driver->disable(dssdev);
 		}
 	}
 
diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c
index e15fa5f..fd39f66 100644
--- a/drivers/video/omap2/dss/manager.c
+++ b/drivers/video/omap2/dss/manager.c
@@ -43,8 +43,10 @@ static ssize_t manager_name_show(struct omap_overlay_manager *mgr, char *buf)
 
 static ssize_t manager_display_show(struct omap_overlay_manager *mgr, char *buf)
 {
-	return snprintf(buf, PAGE_SIZE, "%s\n",
-			mgr->device ? mgr->device->name : "<none>");
+	struct omap_dss_device *dssdev = mgr->get_device(mgr);
+
+	return snprintf(buf, PAGE_SIZE, "%s\n", dssdev ?
+			dssdev->name : "<none>");
 }
 
 static ssize_t manager_display_store(struct omap_overlay_manager *mgr,
@@ -72,7 +74,7 @@ static ssize_t manager_display_store(struct omap_overlay_manager *mgr,
 	if (dssdev)
 		DSSDBG("display %s found\n", dssdev->name);
 
-	if (mgr->device) {
+	if (mgr->get_device(mgr)) {
 		r = mgr->unset_device(mgr);
 		if (r) {
 			DSSERR("failed to unset display\n");
@@ -490,9 +492,15 @@ static struct kobj_type manager_ktype = {
 	.default_attrs = manager_sysfs_attrs,
 };
 
+static inline struct omap_dss_device *dss_mgr_get_device(struct omap_overlay_manager *mgr)
+{
+	return mgr->device;
+}
+
 static int dss_mgr_wait_for_vsync(struct omap_overlay_manager *mgr)
 {
 	unsigned long timeout = msecs_to_jiffies(500);
+	struct omap_dss_device *dssdev = mgr->get_device(mgr);
 	u32 irq;
 	int r;
 
@@ -500,9 +508,9 @@ static int dss_mgr_wait_for_vsync(struct omap_overlay_manager *mgr)
 	if (r)
 		return r;
 
-	if (mgr->device->type = OMAP_DISPLAY_TYPE_VENC)
+	if (dssdev->type = OMAP_DISPLAY_TYPE_VENC)
 		irq = DISPC_IRQ_EVSYNC_ODD;
-	else if (mgr->device->type = OMAP_DISPLAY_TYPE_HDMI)
+	else if (dssdev->type = OMAP_DISPLAY_TYPE_HDMI)
 		irq = DISPC_IRQ_EVSYNC_EVEN;
 	else
 		irq = dispc_mgr_get_vsync_irq(mgr->id);
@@ -556,6 +564,7 @@ int dss_init_overlay_managers(struct platform_device *pdev)
 		mgr->get_manager_info = &dss_mgr_get_info;
 		mgr->wait_for_go = &dss_mgr_wait_for_go;
 		mgr->wait_for_vsync = &dss_mgr_wait_for_vsync;
+		mgr->get_device = &dss_mgr_get_device;
 
 		mgr->caps = 0;
 		mgr->supported_displays diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index 813672b..361d41e 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -490,6 +490,8 @@ struct omap_overlay_manager {
 	int (*apply)(struct omap_overlay_manager *mgr);
 	int (*wait_for_go)(struct omap_overlay_manager *mgr);
 	int (*wait_for_vsync)(struct omap_overlay_manager *mgr);
+
+	struct omap_dss_device *(*get_device)(struct omap_overlay_manager *mgr);
 };
 
 /* 22 pins means 1 clk lane and 10 data lanes */
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [PATCH 06/23] OMAP_VOUT: Remove manager->device references
@ 2012-08-21  6:10   ` Archit Taneja
  0 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-08-21  6:10 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, rob, sumit.semwal, Archit Taneja

With the introduction of output entities, managers will now connect to outputs.
Use the helper op for managers named get_device. This will abstract away the
information on how to get the device from an overlay manager.

Using the helper function will reduce the number of pointer dereferences a user
of OMAPDSS needs to do and reduce risk of a NULL dereference.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/media/video/omap/omap_vout.c |   81 ++++++++++++++++++++++++----------
 1 file changed, 57 insertions(+), 24 deletions(-)

diff --git a/drivers/media/video/omap/omap_vout.c b/drivers/media/video/omap/omap_vout.c
index 88cf9d9..0ebf87e 100644
--- a/drivers/media/video/omap/omap_vout.c
+++ b/drivers/media/video/omap/omap_vout.c
@@ -454,11 +454,16 @@ static int omapvid_init(struct omap_vout_device *vout, u32 addr)
 
 	win = &vout->win;
 	for (i = 0; i < ovid->num_overlays; i++) {
+		struct omap_dss_device *dssdev;
+
 		ovl = ovid->overlays[i];
-		if (!ovl->manager || !ovl->manager->device)
+		dssdev = ovl->manager ?
+			ovl->manager->get_device(ovl->manager) : NULL;
+
+		if (!dssdev)
 			return -EINVAL;
 
-		timing = &ovl->manager->device->panel.timings;
+		timing = &dssdev->panel.timings;
 
 		outw = win->w.width;
 		outh = win->w.height;
@@ -515,8 +520,12 @@ static int omapvid_apply_changes(struct omap_vout_device *vout)
 	struct omapvideo_info *ovid = &vout->vid_info;
 
 	for (i = 0; i < ovid->num_overlays; i++) {
+		struct omap_dss_device *dssdev;
+
 		ovl = ovid->overlays[i];
-		if (!ovl->manager || !ovl->manager->device)
+		dssdev = ovl->manager ?
+			ovl->manager->get_device(ovl->manager) : NULL;
+		if (!dssdev)
 			return -EINVAL;
 		ovl->manager->apply(ovl->manager);
 	}
@@ -579,12 +588,15 @@ static void omap_vout_isr(void *arg, unsigned int irqstatus)
 
 	ovid = &vout->vid_info;
 	ovl = ovid->overlays[0];
-	/* get the display device attached to the overlay */
-	if (!ovl->manager || !ovl->manager->device)
-		return;
 
 	mgr_id = ovl->manager->id;
-	cur_display = ovl->manager->device;
+
+	/* get the display device attached to the overlay */
+	cur_display = ovl->manager ?
+		ovl->manager->get_device(ovl->manager) : NULL;
+
+	if (!cur_display)
+		return;
 
 	spin_lock(&vout->vbq_lock);
 	do_gettimeofday(&timevalue);
@@ -948,7 +960,10 @@ static int omap_vout_release(struct file *file)
 	/* Disable all the overlay managers connected with this interface */
 	for (i = 0; i < ovid->num_overlays; i++) {
 		struct omap_overlay *ovl = ovid->overlays[i];
-		if (ovl->manager && ovl->manager->device)
+		struct omap_dss_device *dssdev = ovl->manager ?
+			ovl->manager->get_device(ovl->manager) : NULL;
+
+		if (dssdev)
 			ovl->disable(ovl);
 	}
 	/* Turn off the pipeline */
@@ -1081,14 +1096,17 @@ static int vidioc_try_fmt_vid_out(struct file *file, void *fh,
 	struct omapvideo_info *ovid;
 	struct omap_video_timings *timing;
 	struct omap_vout_device *vout = fh;
+	struct omap_dss_device *dssdev;
 
 	ovid = &vout->vid_info;
 	ovl = ovid->overlays[0];
+	/* get the display device attached to the overlay */
+	dssdev = ovl->manager ? ovl->manager->get_device(ovl->manager) : NULL;
 
-	if (!ovl->manager || !ovl->manager->device)
+	if (!dssdev)
 		return -EINVAL;
-	/* get the display device attached to the overlay */
-	timing = &ovl->manager->device->panel.timings;
+
+	timing = &dssdev->panel.timings;
 
 	vout->fbuf.fmt.height = timing->y_res;
 	vout->fbuf.fmt.width = timing->x_res;
@@ -1105,6 +1123,7 @@ static int vidioc_s_fmt_vid_out(struct file *file, void *fh,
 	struct omapvideo_info *ovid;
 	struct omap_video_timings *timing;
 	struct omap_vout_device *vout = fh;
+	struct omap_dss_device *dssdev;
 
 	if (vout->streaming)
 		return -EBUSY;
@@ -1113,13 +1132,14 @@ static int vidioc_s_fmt_vid_out(struct file *file, void *fh,
 
 	ovid = &vout->vid_info;
 	ovl = ovid->overlays[0];
+	dssdev = ovl->manager ? ovl->manager->get_device(ovl->manager) : NULL;
 
 	/* get the display device attached to the overlay */
-	if (!ovl->manager || !ovl->manager->device) {
+	if (!dssdev) {
 		ret = -EINVAL;
 		goto s_fmt_vid_out_exit;
 	}
-	timing = &ovl->manager->device->panel.timings;
+	timing = &dssdev->panel.timings;
 
 	/* We dont support RGB24-packed mode if vrfb rotation
 	 * is enabled*/
@@ -1298,6 +1318,7 @@ static int vidioc_s_crop(struct file *file, void *fh, struct v4l2_crop *crop)
 	struct omapvideo_info *ovid;
 	struct omap_overlay *ovl;
 	struct omap_video_timings *timing;
+	struct omap_dss_device *dssdev;
 
 	if (vout->streaming)
 		return -EBUSY;
@@ -1305,13 +1326,15 @@ static int vidioc_s_crop(struct file *file, void *fh, struct v4l2_crop *crop)
 	mutex_lock(&vout->lock);
 	ovid = &vout->vid_info;
 	ovl = ovid->overlays[0];
+	/* get the display device attached to the overlay */
+	dssdev = ovl->manager ? ovl->manager->get_device(ovl->manager) : NULL;
 
-	if (!ovl->manager || !ovl->manager->device) {
+	if (!dssdev) {
 		ret = -EINVAL;
 		goto s_crop_err;
 	}
-	/* get the display device attached to the overlay */
-	timing = &ovl->manager->device->panel.timings;
+
+	timing = &dssdev->panel.timings;
 
 	if (is_rotation_90_or_270(vout)) {
 		vout->fbuf.fmt.height = timing->x_res;
@@ -1666,8 +1689,9 @@ static int vidioc_streamon(struct file *file, void *fh, enum v4l2_buf_type i)
 
 	for (j = 0; j < ovid->num_overlays; j++) {
 		struct omap_overlay *ovl = ovid->overlays[j];
+		struct omap_overlay_manager *mgr = ovl->manager;
 
-		if (ovl->manager && ovl->manager->device) {
+		if (mgr && mgr->get_device(mgr)) {
 			struct omap_overlay_info info;
 			ovl->get_overlay_info(ovl, &info);
 			info.paddr = addr;
@@ -1690,8 +1714,10 @@ static int vidioc_streamon(struct file *file, void *fh, enum v4l2_buf_type i)
 
 	for (j = 0; j < ovid->num_overlays; j++) {
 		struct omap_overlay *ovl = ovid->overlays[j];
+		struct omap_dss_device *dssdev = ovl->manager ?
+			ovl->manager->get_device(ovl->manager) : NULL;
 
-		if (ovl->manager && ovl->manager->device) {
+		if (dssdev) {
 			ret = ovl->enable(ovl);
 			if (ret)
 				goto streamon_err1;
@@ -1726,8 +1752,10 @@ static int vidioc_streamoff(struct file *file, void *fh, enum v4l2_buf_type i)
 
 	for (j = 0; j < ovid->num_overlays; j++) {
 		struct omap_overlay *ovl = ovid->overlays[j];
+		struct omap_dss_device *dssdev = ovl->manager ?
+			ovl->manager->get_device(ovl->manager) : NULL;
 
-		if (ovl->manager && ovl->manager->device)
+		if (dssdev)
 			ovl->disable(ovl);
 	}
 
@@ -1890,8 +1918,9 @@ static int __init omap_vout_setup_video_data(struct omap_vout_device *vout)
 	struct video_device *vfd;
 	struct v4l2_pix_format *pix;
 	struct v4l2_control *control;
+	struct omap_overlay *ovl = vout->vid_info.overlays[0];
 	struct omap_dss_device *display -		vout->vid_info.overlays[0]->manager->device;
+		ovl->manager->get_device(ovl->manager);
 
 	/* set the default pix */
 	pix = &vout->pix;
@@ -2205,8 +2234,10 @@ static int __init omap_vout_probe(struct platform_device *pdev)
 	 */
 	for (i = 1; i < vid_dev->num_overlays; i++) {
 		ovl = omap_dss_get_overlay(i);
-		if (ovl->manager && ovl->manager->device) {
-			def_display = ovl->manager->device;
+		dssdev = ovl->manager ? ovl->manager->get_device(ovl->manager) :
+				NULL;
+		if (dssdev) {
+			def_display = dssdev;
 		} else {
 			dev_warn(&pdev->dev, "cannot find display\n");
 			def_display = NULL;
@@ -2253,8 +2284,10 @@ probe_err1:
 	for (i = 1; i < vid_dev->num_overlays; i++) {
 		def_display = NULL;
 		ovl = omap_dss_get_overlay(i);
-		if (ovl->manager && ovl->manager->device)
-			def_display = ovl->manager->device;
+		dssdev = ovl->manager ? ovl->manager->get_device(ovl->manager) :
+				NULL;
+		if (dssdev)
+			def_display = dssdev;
 
 		if (def_display && def_display->driver)
 			def_display->driver->disable(def_display);
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [PATCH 07/23] OMAPFB: remove manager->device references
@ 2012-08-21  6:10   ` Archit Taneja
  0 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-08-21  6:10 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, rob, sumit.semwal, Archit Taneja

With the introduction of output entities, managers will now connect to outputs.
Use the helper op for managers named get_device. This will abstract away the
information on how to get the device from an overlay manager.

Using the helper function will reduce the number of pointer dereferences a user
of OMAPDSS needs to do and reduce risk of a NULL dereference.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/omapfb/omapfb-main.c |    7 +++++--
 drivers/video/omap2/omapfb/omapfb.h      |    5 +++--
 2 files changed, 8 insertions(+), 4 deletions(-)

diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c
index fc671d3..c6992be 100644
--- a/drivers/video/omap2/omapfb/omapfb-main.c
+++ b/drivers/video/omap2/omapfb/omapfb-main.c
@@ -2353,6 +2353,7 @@ static int __init omapfb_probe(struct platform_device *pdev)
 	struct omap_overlay *ovl;
 	struct omap_dss_device *def_display;
 	struct omap_dss_device *dssdev;
+	struct omap_dss_device *mgr_device;
 
 	DBG("omapfb_probe\n");
 
@@ -2426,8 +2427,10 @@ static int __init omapfb_probe(struct platform_device *pdev)
 	/* gfx overlay should be the default one. find a display
 	 * connected to that, and use it as default display */
 	ovl = omap_dss_get_overlay(0);
-	if (ovl->manager && ovl->manager->device) {
-		def_display = ovl->manager->device;
+	mgr_device = ovl->manager ?
+		ovl->manager->get_device(ovl->manager) : NULL;
+	if (mgr_device) {
+		def_display = mgr_device;
 	} else {
 		dev_warn(&pdev->dev, "cannot find default display\n");
 		def_display = NULL;
diff --git a/drivers/video/omap2/omapfb/omapfb.h b/drivers/video/omap2/omapfb/omapfb.h
index 30361a0..2782b1f 100644
--- a/drivers/video/omap2/omapfb/omapfb.h
+++ b/drivers/video/omap2/omapfb/omapfb.h
@@ -148,8 +148,9 @@ static inline struct omap_dss_device *fb2display(struct fb_info *fbi)
 
 	/* XXX: returns the display connected to first attached overlay */
 	for (i = 0; i < ofbi->num_overlays; i++) {
-		if (ofbi->overlays[i]->manager)
-			return ofbi->overlays[i]->manager->device;
+		struct omap_overlay_manager *mgr = ofbi->overlays[i]->manager;
+		if (mgr)
+			return mgr->get_device(mgr);
 	}
 
 	return NULL;
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [PATCH 08/23] OMAPDRM: Remove manager->device references
@ 2012-08-21  6:10   ` Archit Taneja
  0 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-08-21  6:10 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, rob, sumit.semwal, Archit Taneja

With the introduction of output entities, managers will now connect to outputs.
Use the helper op for managers named get_device. This will abstract away the
information on how to get the device from an overlay manager.

Using the helper function will reduce the number of pointer dereferences a user
of OMAPDSS needs to do and reduce risk of a NULL dereference.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/staging/omapdrm/omap_drv.c |    5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/staging/omapdrm/omap_drv.c b/drivers/staging/omapdrm/omap_drv.c
index 4beab94..64a354a 100644
--- a/drivers/staging/omapdrm/omap_drv.c
+++ b/drivers/staging/omapdrm/omap_drv.c
@@ -106,7 +106,8 @@ static void dump_video_chains(void)
 	for (i = 0; i < omap_dss_get_num_overlays(); i++) {
 		struct omap_overlay *ovl = omap_dss_get_overlay(i);
 		struct omap_overlay_manager *mgr = ovl->manager;
-		struct omap_dss_device *dssdev = mgr ? mgr->device : NULL;
+		struct omap_dss_device *dssdev = mgr ?
+					mgr->get_device(mgr) : NULL;
 		if (dssdev) {
 			DBG("%d: %s -> %s -> %s", i, ovl->name, mgr->name,
 						dssdev->name);
@@ -185,7 +186,7 @@ static int create_connector(struct drm_device *dev,
 	for (j = 0; j < priv->num_encoders; j++) {
 		struct omap_overlay_manager *mgr  			omap_encoder_get_manager(priv->encoders[j]);
-		if (mgr->device = dssdev) {
+		if (mgr->get_device(mgr) = dssdev) {
 			drm_mode_connector_attach_encoder(connector,
 					priv->encoders[j]);
 		}
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [PATCH 09/23] OMAPDSS: Create links between managers, outputs and devices
@ 2012-08-21  6:10   ` Archit Taneja
  0 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-08-21  6:10 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, rob, sumit.semwal, Archit Taneja

Links between DSS entities are made in dss_recheck_connections when a new panel
is probed. Rewrite the code in dss_recheck_connections to link managers to
outputs, and outputs to devices.

The fields in omap_dss_device struct gives information on which output and
manager to connect to. The desired manager and output pointers are retrieved and
prepared(existing outputs/devices unset, if default display)) to form the
desired links. The output is linked to the device, and then the manager to the
output. If a probed device's required manager isn't free, the required output
is still connected to the device so that it's easier to use the panel in the
future.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/dss/overlay.c |   96 +++++++++++++++++++++----------------
 1 file changed, 56 insertions(+), 40 deletions(-)

diff --git a/drivers/video/omap2/dss/overlay.c b/drivers/video/omap2/dss/overlay.c
index 952c6fa..07605f1 100644
--- a/drivers/video/omap2/dss/overlay.c
+++ b/drivers/video/omap2/dss/overlay.c
@@ -525,51 +525,67 @@ void dss_init_overlays(struct platform_device *pdev)
 void dss_recheck_connections(struct omap_dss_device *dssdev, bool force)
 {
 	int i;
-	struct omap_overlay_manager *lcd_mgr;
-	struct omap_overlay_manager *tv_mgr;
-	struct omap_overlay_manager *lcd2_mgr = NULL;
-	struct omap_overlay_manager *lcd3_mgr = NULL;
 	struct omap_overlay_manager *mgr = NULL;
+	struct omap_dss_output *out = NULL;
+	enum omap_dss_output_id id;
+
+	switch (dssdev->type) {
+	case OMAP_DISPLAY_TYPE_DPI:
+		out = omap_dss_get_output(OMAP_DSS_OUTPUT_DPI);
+		break;
+	case OMAP_DISPLAY_TYPE_DBI:
+		out = omap_dss_get_output(OMAP_DSS_OUTPUT_DBI);
+		break;
+	case OMAP_DISPLAY_TYPE_SDI:
+		out = omap_dss_get_output(OMAP_DSS_OUTPUT_SDI);
+		break;
+	case OMAP_DISPLAY_TYPE_VENC:
+		out = omap_dss_get_output(OMAP_DSS_OUTPUT_VENC);
+		break;
+	case OMAP_DISPLAY_TYPE_HDMI:
+		out = omap_dss_get_output(OMAP_DSS_OUTPUT_HDMI);
+		break;
+	case OMAP_DISPLAY_TYPE_DSI:
+		id = dssdev->phy.dsi.module = 0 ? OMAP_DSS_OUTPUT_DSI1 :
+					OMAP_DSS_OUTPUT_DSI2;
+		out = omap_dss_get_output(id);
+		break;
+	default:
+		break;
+	}
 
-	lcd_mgr = omap_dss_get_overlay_manager(OMAP_DSS_CHANNEL_LCD);
-	tv_mgr = omap_dss_get_overlay_manager(OMAP_DSS_CHANNEL_DIGIT);
-	if (dss_has_feature(FEAT_MGR_LCD3))
-		lcd3_mgr = omap_dss_get_overlay_manager(OMAP_DSS_CHANNEL_LCD3);
-	if (dss_has_feature(FEAT_MGR_LCD2))
-		lcd2_mgr = omap_dss_get_overlay_manager(OMAP_DSS_CHANNEL_LCD2);
-
-	if (dssdev->channel = OMAP_DSS_CHANNEL_LCD3) {
-		if (!lcd3_mgr->device || force) {
-			if (lcd3_mgr->device)
-				lcd3_mgr->unset_device(lcd3_mgr);
-			lcd3_mgr->set_device(lcd3_mgr, dssdev);
-			mgr = lcd3_mgr;
-		}
-	} else if (dssdev->channel = OMAP_DSS_CHANNEL_LCD2) {
-		if (!lcd2_mgr->device || force) {
-			if (lcd2_mgr->device)
-				lcd2_mgr->unset_device(lcd2_mgr);
-			lcd2_mgr->set_device(lcd2_mgr, dssdev);
-			mgr = lcd2_mgr;
-		}
-	} else if (dssdev->type != OMAP_DISPLAY_TYPE_VENC
-			&& dssdev->type != OMAP_DISPLAY_TYPE_HDMI) {
-		if (!lcd_mgr->device || force) {
-			if (lcd_mgr->device)
-				lcd_mgr->unset_device(lcd_mgr);
-			lcd_mgr->set_device(lcd_mgr, dssdev);
-			mgr = lcd_mgr;
-		}
+	/*
+	 * We don't want to touch board files and mention channel for VENC
+	 * devices. Force the channel as DIGIT for HDMI and VENC devices
+	 */
+	if (dssdev->type = OMAP_DISPLAY_TYPE_VENC ||
+			dssdev->type = OMAP_DISPLAY_TYPE_HDMI)
+		dssdev->channel = OMAP_DSS_CHANNEL_DIGIT;
+
+	mgr = omap_dss_get_overlay_manager(dssdev->channel);
+
+	if (!mgr || !out) {
+		DSSERR("Incorrect manager or output\n");
+		return;
 	}
 
-	if (dssdev->type = OMAP_DISPLAY_TYPE_VENC
-			|| dssdev->type = OMAP_DISPLAY_TYPE_HDMI) {
-		if (!tv_mgr->device || force) {
-			if (tv_mgr->device)
-				tv_mgr->unset_device(tv_mgr);
-			tv_mgr->set_device(tv_mgr, dssdev);
-			mgr = tv_mgr;
+	if (!mgr->output || force) {
+		struct omap_dss_output *curr_out = mgr->output;
+
+		if (curr_out) {
+			if (curr_out->device)
+				curr_out->unset_device(curr_out);
+			mgr->unset_output(mgr);
 		}
+		out->set_device(out, dssdev);
+		mgr->set_output(mgr, out);
+	} else {
+		/*
+		 * connect a floating output to the device even if the desired
+		 * manager is in use
+		 */
+		if (!out->manager && !out->device)
+			out->set_device(out, dssdev);
 	}
 
 	if (mgr) {
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [PATCH 10/23] OMAPDSS: DPI: Pass outputs from panel driver to DPI interface driver
@ 2012-08-21  6:10   ` Archit Taneja
  0 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-08-21  6:10 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, rob, sumit.semwal, Archit Taneja

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 DPI 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-generic-dpi.c   |   27 ++++++---
 .../omap2/displays/panel-lgphilips-lb035q02.c      |   16 +++--
 .../omap2/displays/panel-nec-nl8048hl11-01b.c      |   15 +++--
 drivers/video/omap2/displays/panel-picodlp.c       |   15 +++--
 .../video/omap2/displays/panel-sharp-ls037v7dw01.c |   16 +++--
 drivers/video/omap2/displays/panel-tfp410.c        |   17 ++++--
 .../video/omap2/displays/panel-tpo-td043mtea1.c    |   29 ++++++---
 drivers/video/omap2/dss/dpi.c                      |   64 ++++++++++----------
 include/video/omapdss.h                            |   12 ++--
 9 files changed, 133 insertions(+), 78 deletions(-)

diff --git a/drivers/video/omap2/displays/panel-generic-dpi.c b/drivers/video/omap2/displays/panel-generic-dpi.c
index 88295c5..76ee8df 100644
--- a/drivers/video/omap2/displays/panel-generic-dpi.c
+++ b/drivers/video/omap2/displays/panel-generic-dpi.c
@@ -561,14 +561,18 @@ static int generic_dpi_panel_power_on(struct omap_dss_device *dssdev)
 	struct panel_generic_dpi_data *panel_data = get_panel_data(dssdev);
 	struct panel_drv_data *drv_data = dev_get_drvdata(&dssdev->dev);
 	struct panel_config *panel_config = drv_data->panel_config;
+	struct omap_dss_output *out = dssdev->output;
+
+	if (out = NULL)
+		return -ENODEV;
 
 	if (dssdev->state = OMAP_DSS_DISPLAY_ACTIVE)
 		return 0;
 
-	omapdss_dpi_set_timings(dssdev, &dssdev->panel.timings);
-	omapdss_dpi_set_data_lines(dssdev, dssdev->phy.dpi.data_lines);
+	omapdss_dpi_set_timings(out, &dssdev->panel.timings);
+	omapdss_dpi_set_data_lines(out, dssdev->phy.dpi.data_lines);
 
-	r = omapdss_dpi_display_enable(dssdev);
+	r = omapdss_dpi_display_enable(out);
 	if (r)
 		goto err0;
 
@@ -584,7 +588,7 @@ static int generic_dpi_panel_power_on(struct omap_dss_device *dssdev)
 
 	return 0;
 err1:
-	omapdss_dpi_display_disable(dssdev);
+	omapdss_dpi_display_disable(out);
 err0:
 	return r;
 }
@@ -594,6 +598,7 @@ static void generic_dpi_panel_power_off(struct omap_dss_device *dssdev)
 	struct panel_generic_dpi_data *panel_data = get_panel_data(dssdev);
 	struct panel_drv_data *drv_data = dev_get_drvdata(&dssdev->dev);
 	struct panel_config *panel_config = drv_data->panel_config;
+	struct omap_dss_output *out = dssdev->output;
 
 	if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
 		return;
@@ -605,7 +610,7 @@ static void generic_dpi_panel_power_off(struct omap_dss_device *dssdev)
 	if (panel_config->power_off_delay)
 		msleep(panel_config->power_off_delay);
 
-	omapdss_dpi_display_disable(dssdev);
+	omapdss_dpi_display_disable(out);
 }
 
 static int generic_dpi_panel_probe(struct omap_dss_device *dssdev)
@@ -726,10 +731,14 @@ static void generic_dpi_panel_set_timings(struct omap_dss_device *dssdev,
 		struct omap_video_timings *timings)
 {
 	struct panel_drv_data *drv_data = dev_get_drvdata(&dssdev->dev);
+	struct omap_dss_output *out = dssdev->output;
+
+	if (out = NULL)
+		return;
 
 	mutex_lock(&drv_data->lock);
 
-	omapdss_dpi_set_timings(dssdev, timings);
+	omapdss_dpi_set_timings(out, timings);
 
 	dssdev->panel.timings = *timings;
 
@@ -752,11 +761,15 @@ static int generic_dpi_panel_check_timings(struct omap_dss_device *dssdev,
 		struct omap_video_timings *timings)
 {
 	struct panel_drv_data *drv_data = dev_get_drvdata(&dssdev->dev);
+	struct omap_dss_output *out = dssdev->output;
 	int r;
 
+	if (out = NULL)
+		return -ENODEV;
+
 	mutex_lock(&drv_data->lock);
 
-	r = dpi_check_timings(dssdev, timings);
+	r = dpi_check_timings(out, timings);
 
 	mutex_unlock(&drv_data->lock);
 
diff --git a/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c b/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c
index 90c1cab..2764c32 100644
--- a/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c
+++ b/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c
@@ -50,15 +50,19 @@ static struct omap_video_timings lb035q02_timings = {
 
 static int lb035q02_panel_power_on(struct omap_dss_device *dssdev)
 {
+	struct omap_dss_output *out = dssdev->output;
 	int r;
 
+	if (out = NULL)
+		return -ENODEV;
+
 	if (dssdev->state = OMAP_DSS_DISPLAY_ACTIVE)
 		return 0;
 
-	omapdss_dpi_set_timings(dssdev, &dssdev->panel.timings);
-	omapdss_dpi_set_data_lines(dssdev, dssdev->phy.dpi.data_lines);
+	omapdss_dpi_set_timings(out, &dssdev->panel.timings);
+	omapdss_dpi_set_data_lines(out, dssdev->phy.dpi.data_lines);
 
-	r = omapdss_dpi_display_enable(dssdev);
+	r = omapdss_dpi_display_enable(out);
 	if (r)
 		goto err0;
 
@@ -70,20 +74,22 @@ static int lb035q02_panel_power_on(struct omap_dss_device *dssdev)
 
 	return 0;
 err1:
-	omapdss_dpi_display_disable(dssdev);
+	omapdss_dpi_display_disable(out);
 err0:
 	return r;
 }
 
 static void lb035q02_panel_power_off(struct omap_dss_device *dssdev)
 {
+	struct omap_dss_output *out = dssdev->output;
+
 	if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
 		return;
 
 	if (dssdev->platform_disable)
 		dssdev->platform_disable(dssdev);
 
-	omapdss_dpi_display_disable(dssdev);
+	omapdss_dpi_display_disable(out);
 }
 
 static int lb035q02_panel_probe(struct omap_dss_device *dssdev)
diff --git a/drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c b/drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c
index 908fd26..906bc48 100644
--- a/drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c
+++ b/drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c
@@ -171,14 +171,18 @@ static int nec_8048_panel_power_on(struct omap_dss_device *dssdev)
 	int r;
 	struct nec_8048_data *necd = dev_get_drvdata(&dssdev->dev);
 	struct backlight_device *bl = necd->bl;
+	struct omap_dss_output *out = dssdev->output;
+
+	if (out = NULL)
+		return -ENODEV;
 
 	if (dssdev->state = OMAP_DSS_DISPLAY_ACTIVE)
 		return 0;
 
-	omapdss_dpi_set_timings(dssdev, &dssdev->panel.timings);
-	omapdss_dpi_set_data_lines(dssdev, dssdev->phy.dpi.data_lines);
+	omapdss_dpi_set_timings(out, &dssdev->panel.timings);
+	omapdss_dpi_set_data_lines(out, dssdev->phy.dpi.data_lines);
 
-	r = omapdss_dpi_display_enable(dssdev);
+	r = omapdss_dpi_display_enable(out);
 	if (r)
 		goto err0;
 
@@ -194,7 +198,7 @@ static int nec_8048_panel_power_on(struct omap_dss_device *dssdev)
 
 	return 0;
 err1:
-	omapdss_dpi_display_disable(dssdev);
+	omapdss_dpi_display_disable(out);
 err0:
 	return r;
 }
@@ -203,6 +207,7 @@ static void nec_8048_panel_power_off(struct omap_dss_device *dssdev)
 {
 	struct nec_8048_data *necd = dev_get_drvdata(&dssdev->dev);
 	struct backlight_device *bl = necd->bl;
+	struct omap_dss_output *out = dssdev->output;
 
 	if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
 		return;
@@ -213,7 +218,7 @@ static void nec_8048_panel_power_off(struct omap_dss_device *dssdev)
 	if (dssdev->platform_disable)
 		dssdev->platform_disable(dssdev);
 
-	omapdss_dpi_display_disable(dssdev);
+	omapdss_dpi_display_disable(out);
 }
 
 static int nec_8048_panel_enable(struct omap_dss_device *dssdev)
diff --git a/drivers/video/omap2/displays/panel-picodlp.c b/drivers/video/omap2/displays/panel-picodlp.c
index 9df8764..2bd4f7b 100644
--- a/drivers/video/omap2/displays/panel-picodlp.c
+++ b/drivers/video/omap2/displays/panel-picodlp.c
@@ -352,6 +352,10 @@ static int picodlp_panel_power_on(struct omap_dss_device *dssdev)
 	int r, trial = 100;
 	struct picodlp_data *picod = dev_get_drvdata(&dssdev->dev);
 	struct picodlp_panel_data *picodlp_pdata = get_panel_data(dssdev);
+	struct omap_dss_output *out = dssdev->output;
+
+	if (out = NULL)
+		return -ENODEV;
 
 	if (dssdev->platform_enable) {
 		r = dssdev->platform_enable(dssdev);
@@ -378,10 +382,10 @@ static int picodlp_panel_power_on(struct omap_dss_device *dssdev)
 	 */
 	msleep(1000);
 
-	omapdss_dpi_set_timings(dssdev, &dssdev->panel.timings);
-	omapdss_dpi_set_data_lines(dssdev, dssdev->phy.dpi.data_lines);
+	omapdss_dpi_set_timings(out, &dssdev->panel.timings);
+	omapdss_dpi_set_data_lines(out, dssdev->phy.dpi.data_lines);
 
-	r = omapdss_dpi_display_enable(dssdev);
+	r = omapdss_dpi_display_enable(out);
 	if (r) {
 		dev_err(&dssdev->dev, "failed to enable DPI\n");
 		goto err1;
@@ -395,7 +399,7 @@ static int picodlp_panel_power_on(struct omap_dss_device *dssdev)
 
 	return r;
 err:
-	omapdss_dpi_display_disable(dssdev);
+	omapdss_dpi_display_disable(out);
 err1:
 	if (dssdev->platform_disable)
 		dssdev->platform_disable(dssdev);
@@ -406,8 +410,9 @@ err1:
 static void picodlp_panel_power_off(struct omap_dss_device *dssdev)
 {
 	struct picodlp_panel_data *picodlp_pdata = get_panel_data(dssdev);
+	struct omap_dss_output *out = dssdev->output;
 
-	omapdss_dpi_display_disable(dssdev);
+	omapdss_dpi_display_disable(out);
 
 	gpio_set_value(picodlp_pdata->emu_done_gpio, 0);
 	gpio_set_value(picodlp_pdata->pwrgood_gpio, 0);
diff --git a/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c b/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c
index 1ec3b27..dffd85a 100644
--- a/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c
+++ b/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c
@@ -137,15 +137,19 @@ static void __exit sharp_ls_panel_remove(struct omap_dss_device *dssdev)
 
 static int sharp_ls_power_on(struct omap_dss_device *dssdev)
 {
+	struct omap_dss_output *out = dssdev->output;
 	int r = 0;
 
+	if (out = NULL)
+		return -ENODEV;
+
 	if (dssdev->state = OMAP_DSS_DISPLAY_ACTIVE)
 		return 0;
 
-	omapdss_dpi_set_timings(dssdev, &dssdev->panel.timings);
-	omapdss_dpi_set_data_lines(dssdev, dssdev->phy.dpi.data_lines);
+	omapdss_dpi_set_timings(out, &dssdev->panel.timings);
+	omapdss_dpi_set_data_lines(out, dssdev->phy.dpi.data_lines);
 
-	r = omapdss_dpi_display_enable(dssdev);
+	r = omapdss_dpi_display_enable(out);
 	if (r)
 		goto err0;
 
@@ -160,13 +164,15 @@ static int sharp_ls_power_on(struct omap_dss_device *dssdev)
 
 	return 0;
 err1:
-	omapdss_dpi_display_disable(dssdev);
+	omapdss_dpi_display_disable(out);
 err0:
 	return r;
 }
 
 static void sharp_ls_power_off(struct omap_dss_device *dssdev)
 {
+	struct omap_dss_output *out = dssdev->output;
+
 	if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
 		return;
 
@@ -177,7 +183,7 @@ static void sharp_ls_power_off(struct omap_dss_device *dssdev)
 
 	msleep(100);
 
-	omapdss_dpi_display_disable(dssdev);
+	omapdss_dpi_display_disable(out);
 }
 
 static int sharp_ls_panel_enable(struct omap_dss_device *dssdev)
diff --git a/drivers/video/omap2/displays/panel-tfp410.c b/drivers/video/omap2/displays/panel-tfp410.c
index 4be9a59..88a1507 100644
--- a/drivers/video/omap2/displays/panel-tfp410.c
+++ b/drivers/video/omap2/displays/panel-tfp410.c
@@ -60,15 +60,19 @@ struct panel_drv_data {
 static int tfp410_power_on(struct omap_dss_device *dssdev)
 {
 	struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev);
+	struct omap_dss_output *out = dssdev->output;
 	int r;
 
+	if (out = NULL)
+		return -ENODEV;
+
 	if (dssdev->state = OMAP_DSS_DISPLAY_ACTIVE)
 		return 0;
 
-	omapdss_dpi_set_timings(dssdev, &dssdev->panel.timings);
-	omapdss_dpi_set_data_lines(dssdev, dssdev->phy.dpi.data_lines);
+	omapdss_dpi_set_timings(out, &dssdev->panel.timings);
+	omapdss_dpi_set_data_lines(out, dssdev->phy.dpi.data_lines);
 
-	r = omapdss_dpi_display_enable(dssdev);
+	r = omapdss_dpi_display_enable(out);
 	if (r)
 		goto err0;
 
@@ -83,6 +87,7 @@ err0:
 static void tfp410_power_off(struct omap_dss_device *dssdev)
 {
 	struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev);
+	struct omap_dss_output *out = dssdev->output;
 
 	if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
 		return;
@@ -90,7 +95,7 @@ static void tfp410_power_off(struct omap_dss_device *dssdev)
 	if (gpio_is_valid(ddata->pd_gpio))
 		gpio_set_value_cansleep(ddata->pd_gpio, 0);
 
-	omapdss_dpi_display_disable(dssdev);
+	omapdss_dpi_display_disable(out);
 }
 
 static int tfp410_probe(struct omap_dss_device *dssdev)
@@ -234,7 +239,7 @@ static void tfp410_set_timings(struct omap_dss_device *dssdev,
 	struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev);
 
 	mutex_lock(&ddata->lock);
-	omapdss_dpi_set_timings(dssdev, timings);
+	omapdss_dpi_set_timings(dssdev->output, timings);
 	dssdev->panel.timings = *timings;
 	mutex_unlock(&ddata->lock);
 }
@@ -256,7 +261,7 @@ static int tfp410_check_timings(struct omap_dss_device *dssdev,
 	int r;
 
 	mutex_lock(&ddata->lock);
-	r = dpi_check_timings(dssdev, timings);
+	r = dpi_check_timings(dssdev->output, timings);
 	mutex_unlock(&ddata->lock);
 
 	return r;
diff --git a/drivers/video/omap2/displays/panel-tpo-td043mtea1.c b/drivers/video/omap2/displays/panel-tpo-td043mtea1.c
index b5e6dbc..792e9ff 100644
--- a/drivers/video/omap2/displays/panel-tpo-td043mtea1.c
+++ b/drivers/video/omap2/displays/panel-tpo-td043mtea1.c
@@ -331,16 +331,20 @@ static void tpo_td043_power_off(struct tpo_td043_device *tpo_td043)
 
 static int tpo_td043_enable_dss(struct omap_dss_device *dssdev)
 {
+	struct omap_dss_output *out = dssdev->output;
 	struct tpo_td043_device *tpo_td043 = dev_get_drvdata(&dssdev->dev);
 	int r;
 
+	if (out = NULL)
+		return -ENODEV;
+
 	if (dssdev->state = OMAP_DSS_DISPLAY_ACTIVE)
 		return 0;
 
-	omapdss_dpi_set_timings(dssdev, &dssdev->panel.timings);
-	omapdss_dpi_set_data_lines(dssdev, dssdev->phy.dpi.data_lines);
+	omapdss_dpi_set_timings(out, &dssdev->panel.timings);
+	omapdss_dpi_set_data_lines(out, dssdev->phy.dpi.data_lines);
 
-	r = omapdss_dpi_display_enable(dssdev);
+	r = omapdss_dpi_display_enable(out);
 	if (r)
 		goto err0;
 
@@ -364,7 +368,7 @@ static int tpo_td043_enable_dss(struct omap_dss_device *dssdev)
 
 	return 0;
 err1:
-	omapdss_dpi_display_disable(dssdev);
+	omapdss_dpi_display_disable(out);
 err0:
 	return r;
 }
@@ -372,6 +376,7 @@ err0:
 static void tpo_td043_disable_dss(struct omap_dss_device *dssdev)
 {
 	struct tpo_td043_device *tpo_td043 = dev_get_drvdata(&dssdev->dev);
+	struct omap_dss_output *out = dssdev->output;
 
 	if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
 		return;
@@ -379,7 +384,7 @@ static void tpo_td043_disable_dss(struct omap_dss_device *dssdev)
 	if (dssdev->platform_disable)
 		dssdev->platform_disable(dssdev);
 
-	omapdss_dpi_display_disable(dssdev);
+	omapdss_dpi_display_disable(out);
 
 	if (!tpo_td043->spi_suspended)
 		tpo_td043_power_off(tpo_td043);
@@ -483,7 +488,12 @@ static void tpo_td043_remove(struct omap_dss_device *dssdev)
 static void tpo_td043_set_timings(struct omap_dss_device *dssdev,
 		struct omap_video_timings *timings)
 {
-	omapdss_dpi_set_timings(dssdev, timings);
+	struct omap_dss_output *out = dssdev->output;
+
+	if (out = NULL)
+		return;
+
+	omapdss_dpi_set_timings(out, timings);
 
 	dssdev->panel.timings = *timings;
 }
@@ -491,7 +501,12 @@ static void tpo_td043_set_timings(struct omap_dss_device *dssdev,
 static int tpo_td043_check_timings(struct omap_dss_device *dssdev,
 		struct omap_video_timings *timings)
 {
-	return dpi_check_timings(dssdev, timings);
+	struct omap_dss_output *out = dssdev->output;
+
+	if (out = NULL)
+		return -ENODEV;
+
+	return dpi_check_timings(out, timings);
 }
 
 static struct omap_dss_driver tpo_td043_driver = {
diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c
index 4eca2e7..6506e40 100644
--- a/drivers/video/omap2/dss/dpi.c
+++ b/drivers/video/omap2/dss/dpi.c
@@ -70,7 +70,7 @@ static bool dpi_use_dsi_pll(struct omap_dss_device *dssdev)
 		return false;
 }
 
-static int dpi_set_dsi_clk(struct omap_dss_device *dssdev,
+static int dpi_set_dsi_clk(struct omap_dss_output *out,
 		unsigned long pck_req, unsigned long *fck, int *lck_div,
 		int *pck_div)
 {
@@ -87,7 +87,7 @@ static int dpi_set_dsi_clk(struct omap_dss_device *dssdev,
 	if (r)
 		return r;
 
-	dss_select_dispc_clk_source(dssdev->clocks.dispc.dispc_fclk_src);
+	dss_select_dispc_clk_source(out->device->clocks.dispc.dispc_fclk_src);
 
 	dpi.mgr_config.clock_info = dispc_cinfo;
 
@@ -98,7 +98,7 @@ static int dpi_set_dsi_clk(struct omap_dss_device *dssdev,
 	return 0;
 }
 
-static int dpi_set_dispc_clk(struct omap_dss_device *dssdev,
+static int dpi_set_dispc_clk(struct omap_dss_output *out,
 		unsigned long pck_req, unsigned long *fck, int *lck_div,
 		int *pck_div)
 {
@@ -123,7 +123,7 @@ static int dpi_set_dispc_clk(struct omap_dss_device *dssdev,
 	return 0;
 }
 
-static int dpi_set_mode(struct omap_dss_device *dssdev)
+static int dpi_set_mode(struct omap_dss_output *out)
 {
 	struct omap_video_timings *t = &dpi.timings;
 	int lck_div = 0, pck_div = 0;
@@ -131,11 +131,11 @@ static int dpi_set_mode(struct omap_dss_device *dssdev)
 	unsigned long pck;
 	int r = 0;
 
-	if (dpi_use_dsi_pll(dssdev))
-		r = dpi_set_dsi_clk(dssdev, t->pixel_clock * 1000, &fck,
+	if (dpi_use_dsi_pll(out->device))
+		r = dpi_set_dsi_clk(out, t->pixel_clock * 1000, &fck,
 				&lck_div, &pck_div);
 	else
-		r = dpi_set_dispc_clk(dssdev, t->pixel_clock * 1000, &fck,
+		r = dpi_set_dispc_clk(out, t->pixel_clock * 1000, &fck,
 				&lck_div, &pck_div);
 	if (r)
 		return r;
@@ -150,12 +150,12 @@ static int dpi_set_mode(struct omap_dss_device *dssdev)
 		t->pixel_clock = pck;
 	}
 
-	dss_mgr_set_timings(dssdev->manager, t);
+	dss_mgr_set_timings(out->manager, t);
 
 	return 0;
 }
 
-static void dpi_config_lcd_manager(struct omap_dss_device *dssdev)
+static void dpi_config_lcd_manager(struct omap_dss_output *out)
 {
 	dpi.mgr_config.io_pad_mode = DSS_IO_PAD_MODE_BYPASS;
 
@@ -166,10 +166,10 @@ static void dpi_config_lcd_manager(struct omap_dss_device *dssdev)
 
 	dpi.mgr_config.lcden_sig_polarity = 0;
 
-	dss_mgr_set_lcd_config(dssdev->manager, &dpi.mgr_config);
+	dss_mgr_set_lcd_config(out->manager, &dpi.mgr_config);
 }
 
-int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
+int omapdss_dpi_display_enable(struct omap_dss_output *out)
 {
 	int r;
 
@@ -181,13 +181,13 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
 		goto err_no_reg;
 	}
 
-	if (dssdev->manager = NULL) {
+	if (out->manager = NULL) {
 		DSSERR("failed to enable display: no manager\n");
 		r = -ENODEV;
 		goto err_no_mgr;
 	}
 
-	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;
@@ -203,7 +203,7 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
 	if (r)
 		goto err_get_dispc;
 
-	if (dpi_use_dsi_pll(dssdev)) {
+	if (dpi_use_dsi_pll(out->device)) {
 		r = dsi_runtime_get(dpi.dsidev);
 		if (r)
 			goto err_get_dsi;
@@ -213,15 +213,15 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
 			goto err_dsi_pll_init;
 	}
 
-	r = dpi_set_mode(dssdev);
+	r = dpi_set_mode(out);
 	if (r)
 		goto err_set_mode;
 
-	dpi_config_lcd_manager(dssdev);
+	dpi_config_lcd_manager(out);
 
 	mdelay(2);
 
-	r = dss_mgr_enable(dssdev->manager);
+	r = dss_mgr_enable(out->manager);
 	if (r)
 		goto err_mgr_enable;
 
@@ -231,10 +231,10 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
 
 err_mgr_enable:
 err_set_mode:
-	if (dpi_use_dsi_pll(dssdev))
+	if (dpi_use_dsi_pll(out->device))
 		dsi_pll_uninit(dpi.dsidev, true);
 err_dsi_pll_init:
-	if (dpi_use_dsi_pll(dssdev))
+	if (dpi_use_dsi_pll(out->device))
 		dsi_runtime_put(dpi.dsidev);
 err_get_dsi:
 	dispc_runtime_put();
@@ -242,7 +242,7 @@ err_get_dispc:
 	if (cpu_is_omap34xx())
 		regulator_disable(dpi.vdds_dsi_reg);
 err_reg_enable:
-	omap_dss_stop_device(dssdev);
+	omap_dss_stop_device(out->device);
 err_start_dev:
 err_no_mgr:
 err_no_reg:
@@ -251,13 +251,13 @@ err_no_reg:
 }
 EXPORT_SYMBOL(omapdss_dpi_display_enable);
 
-void omapdss_dpi_display_disable(struct omap_dss_device *dssdev)
+void omapdss_dpi_display_disable(struct omap_dss_output *out)
 {
 	mutex_lock(&dpi.lock);
 
-	dss_mgr_disable(dssdev->manager);
+	dss_mgr_disable(out->manager);
 
-	if (dpi_use_dsi_pll(dssdev)) {
+	if (dpi_use_dsi_pll(out->device)) {
 		dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK);
 		dsi_pll_uninit(dpi.dsidev, true);
 		dsi_runtime_put(dpi.dsidev);
@@ -268,13 +268,13 @@ void omapdss_dpi_display_disable(struct omap_dss_device *dssdev)
 	if (cpu_is_omap34xx())
 		regulator_disable(dpi.vdds_dsi_reg);
 
-	omap_dss_stop_device(dssdev);
+	omap_dss_stop_device(out->device);
 
 	mutex_unlock(&dpi.lock);
 }
 EXPORT_SYMBOL(omapdss_dpi_display_disable);
 
-void omapdss_dpi_set_timings(struct omap_dss_device *dssdev,
+void omapdss_dpi_set_timings(struct omap_dss_output *out,
 		struct omap_video_timings *timings)
 {
 	int r;
@@ -285,23 +285,23 @@ void omapdss_dpi_set_timings(struct omap_dss_device *dssdev,
 
 	dpi.timings = *timings;
 
-	if (dssdev->state = OMAP_DSS_DISPLAY_ACTIVE) {
+	if (out->device->state = OMAP_DSS_DISPLAY_ACTIVE) {
 		r = dispc_runtime_get();
 		if (r)
 			return;
 
-		dpi_set_mode(dssdev);
+		dpi_set_mode(out);
 
 		dispc_runtime_put();
 	} else {
-		dss_mgr_set_timings(dssdev->manager, timings);
+		dss_mgr_set_timings(out->manager, timings);
 	}
 
 	mutex_unlock(&dpi.lock);
 }
 EXPORT_SYMBOL(omapdss_dpi_set_timings);
 
-int dpi_check_timings(struct omap_dss_device *dssdev,
+int dpi_check_timings(struct omap_dss_output *out,
 			struct omap_video_timings *timings)
 {
 	int r;
@@ -310,13 +310,13 @@ int dpi_check_timings(struct omap_dss_device *dssdev,
 	unsigned long pck;
 	struct dispc_clock_info dispc_cinfo;
 
-	if (dss_mgr_check_timings(dssdev->manager, timings))
+	if (dss_mgr_check_timings(out->manager, timings))
 		return -EINVAL;
 
 	if (timings->pixel_clock = 0)
 		return -EINVAL;
 
-	if (dpi_use_dsi_pll(dssdev)) {
+	if (dpi_use_dsi_pll(out->device)) {
 		struct dsi_clock_info dsi_cinfo;
 		r = dsi_pll_calc_clock_div_pck(dpi.dsidev,
 				timings->pixel_clock * 1000,
@@ -348,7 +348,7 @@ int dpi_check_timings(struct omap_dss_device *dssdev,
 }
 EXPORT_SYMBOL(dpi_check_timings);
 
-void omapdss_dpi_set_data_lines(struct omap_dss_device *dssdev, int data_lines)
+void omapdss_dpi_set_data_lines(struct omap_dss_output *out, int data_lines)
 {
 	mutex_lock(&dpi.lock);
 
diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index 361d41e..da3f070 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -783,13 +783,13 @@ int omapdss_dsi_display_enable(struct omap_dss_device *dssdev);
 void omapdss_dsi_display_disable(struct omap_dss_device *dssdev,
 		bool disconnect_lanes, bool enter_ulps);
 
-int omapdss_dpi_display_enable(struct omap_dss_device *dssdev);
-void omapdss_dpi_display_disable(struct omap_dss_device *dssdev);
-void omapdss_dpi_set_timings(struct omap_dss_device *dssdev,
+int omapdss_dpi_display_enable(struct omap_dss_output *out);
+void omapdss_dpi_display_disable(struct omap_dss_output *out);
+void omapdss_dpi_set_timings(struct omap_dss_output *out,
 		struct omap_video_timings *timings);
-int dpi_check_timings(struct omap_dss_device *dssdev,
-			struct omap_video_timings *timings);
-void omapdss_dpi_set_data_lines(struct omap_dss_device *dssdev, int data_lines);
+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);
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [PATCH 11/23] OMAPDSS: DSI: Remove dsi_pdev_map global struct
@ 2012-08-21  6:10   ` Archit Taneja
  0 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-08-21  6:10 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, rob, sumit.semwal, Archit Taneja

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	[flat|nested] 148+ messages in thread

* [PATCH 12/23] OMAPDSS: DSI: Pass outputs from panel driver to DSI interface driver
@ 2012-08-21  6:10   ` Archit Taneja
  0 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-08-21  6:10 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, rob, sumit.semwal, Archit Taneja

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	[flat|nested] 148+ messages in thread

* [PATCH 13/23] OMAPDSS: SDI: Pass outputs from panel driver to SDI interface driver
@ 2012-08-21  6:10   ` Archit Taneja
  0 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-08-21  6:10 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, rob, sumit.semwal, Archit Taneja

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	[flat|nested] 148+ messages in thread

* [PATCH 14/23] OMAPDSS: RFBI: Pass outputs from panel driver to RFBI interface driver
@ 2012-08-21  6:10   ` Archit Taneja
  0 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-08-21  6:10 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, rob, sumit.semwal, Archit Taneja

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	[flat|nested] 148+ messages in thread

* [PATCH 15/23] OMAPDSS: RFBI: Add output pointers as arguments to all exported functions
@ 2012-08-21  6:10   ` Archit Taneja
  0 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-08-21  6:10 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, rob, sumit.semwal, Archit Taneja

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	[flat|nested] 148+ messages in thread

* [PATCH 16/23] OMAPDSS: VENC: Pass outputs from panel driver to VENC interface driver
@ 2012-08-21  6:10   ` Archit Taneja
  0 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-08-21  6:10 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, rob, sumit.semwal, Archit Taneja

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	[flat|nested] 148+ messages in thread

* [PATCH 17/23] OMAPDSS: HDMI: Pass outputs from panel driver to HDMI interface driver
@ 2012-08-21  6:10   ` Archit Taneja
  0 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-08-21  6:10 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, rob, sumit.semwal, Archit Taneja

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	[flat|nested] 148+ messages in thread

* [PATCH 18/23] OMAPDSS: HDMI: Add output pointers as arguments to all functions used by hdmi panel dr
@ 2012-08-21  6:10   ` Archit Taneja
  0 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-08-21  6:10 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, rob, sumit.semwal, Archit Taneja

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	[flat|nested] 148+ messages in thread

* [PATCH 19/23] OMAPDSS/OMAPFB: Change dssdev->manager references
@ 2012-08-21  6:10   ` Archit Taneja
  0 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-08-21  6:10 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, rob, sumit.semwal, Archit Taneja

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	[flat|nested] 148+ messages in thread

* [PATCH 20/23] OMAPDSS: MANAGER: Update display sysfs store
@ 2012-08-21  6:10   ` Archit Taneja
  0 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-08-21  6:10 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, rob, sumit.semwal, Archit Taneja

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	[flat|nested] 148+ messages in thread

* [PATCH 21/23] OMAPDSS: MANAGER: Get device via output
@ 2012-08-21  6:10   ` Archit Taneja
  0 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-08-21  6:10 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, rob, sumit.semwal, Archit Taneja

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	[flat|nested] 148+ messages in thread

* [PATCH 22/23] OMAPDSS: APPLY: Remove omap_dss_device references from dss_ovl_enable/disable
@ 2012-08-21  6:10   ` Archit Taneja
  0 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-08-21  6:10 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, rob, sumit.semwal, Archit Taneja

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	[flat|nested] 148+ messages in thread

* [PATCH 23/23] OMAPDSS: Remove old way of setting manager and device links
@ 2012-08-21  6:10   ` Archit Taneja
  0 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-08-21  6:10 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, rob, sumit.semwal, Archit Taneja

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	[flat|nested] 148+ messages in thread

* Re: [PATCH 01/23] OMAPDSS: outputs: Create a new entity called outputs
  2012-08-21  6:10   ` Archit Taneja
@ 2012-08-24 12:41     ` Tomi Valkeinen
  -1 siblings, 0 replies; 148+ messages in thread
From: Tomi Valkeinen @ 2012-08-24 12:41 UTC (permalink / raw)
  To: Archit Taneja; +Cc: linux-omap, linux-fbdev, rob, sumit.semwal

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

On Tue, 2012-08-21 at 11:28 +0530, Archit Taneja wrote:

> diff --git a/drivers/video/omap2/dss/output.c b/drivers/video/omap2/dss/output.c
> new file mode 100644
> index 0000000..034ebbe
> --- /dev/null
> +++ b/drivers/video/omap2/dss/output.c
> @@ -0,0 +1,58 @@
> +/*
> + * Copyright (C) 2012 Texas Instruments Ltd
> + * Author: Archit Taneja <archit@ti.com>
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms of the GNU General Public License version 2 as published by
> + * the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful, but WITHOUT
> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
> + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
> + * more details.
> + *
> + * You should have received a copy of the GNU General Public License along with
> + * this program.  If not, see <http://www.gnu.org/licenses/>.
> + */
> +
> +#include <linux/kernel.h>
> +#include <linux/platform_device.h>
> +#include <linux/slab.h>
> +
> +#include <video/omapdss.h>
> +
> +#include "dss.h"
> +
> +static struct list_head output_list;

You can do:

static LIST_HEAD(output_list);

Then you don't need to initialize it separately.

> +
> +struct omap_dss_output *dss_create_output(struct platform_device *pdev)
> +{
> +	struct omap_dss_output *out;
> +
> +	out = kzalloc(sizeof(struct omap_dss_output *), GFP_KERNEL);
> +	if (!out)
> +		return NULL;

A patch that adds kzalloc but no free is always a bit suspicious =).

> +
> +	out->pdev = pdev;
> +
> +	list_add_tail(&out->list, &output_list);
> +
> +	return out;
> +}

Instead of allocating omap_dss_output here, you could let the caller do
it, and only initialize it here with default values (if that's even
needed). Then the caller can use kzalloc, or can just embed the stuct
into its own data-struct, which may be often a better choice.

> +struct omap_dss_output *omap_dss_get_output(enum omap_dss_output_id id)
> +{
> +	struct omap_dss_output *out;
> +
> +	list_for_each_entry(out, &output_list, list) {
> +		if (out->id == id)
> +			return out;
> +	}
> +
> +	return NULL;
> +}
> +
> +void dss_init_outputs(void)
> +{
> +	INIT_LIST_HEAD(&output_list);
> +}
> diff --git a/include/video/omapdss.h b/include/video/omapdss.h
> index b868123..0ba613f 100644
> --- a/include/video/omapdss.h
> +++ b/include/video/omapdss.h
> @@ -207,6 +207,16 @@ enum omap_hdmi_flags {
>  	OMAP_HDMI_SDA_SCL_EXTERNAL_PULLUP = 1 << 0,
>  };
>  
> +enum omap_dss_output_id {
> +	OMAP_DSS_OUTPUT_DPI	= 1 << 0,
> +	OMAP_DSS_OUTPUT_DBI	= 1 << 1,
> +	OMAP_DSS_OUTPUT_SDI	= 1 << 2,
> +	OMAP_DSS_OUTPUT_DSI1	= 1 << 3,
> +	OMAP_DSS_OUTPUT_VENC	= 1 << 4,
> +	OMAP_DSS_OUTPUT_DSI2	= 1 << 5,
> +	OMAP_DSS_OUTPUT_HDMI	= 1 << 6,
> +};

I'm not sure about this. We already have enum omap_display_type. If you
need the instance number, you could have that as a separate int field.

Where do you need the output_id?

> +
>  /* RFBI */
>  
>  struct rfbi_timings {
> @@ -492,6 +502,24 @@ struct omap_dsi_pin_config {
>  	int pins[OMAP_DSS_MAX_DSI_PINS];
>  };
>  
> +struct omap_dss_output {
> +	struct list_head list;
> +
> +	/* display type supported by the output */
> +	enum omap_display_type type;
> +
> +	/* output instance */
> +	enum omap_dss_output_id id;

So instead of omap_dss_output_id, you'd have omap_display_type type and
int id, which together tell the supported output and also the output
driver instance.

 Tomi


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

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [PATCH 01/23] OMAPDSS: outputs: Create a new entity called outputs
@ 2012-08-24 12:41     ` Tomi Valkeinen
  0 siblings, 0 replies; 148+ messages in thread
From: Tomi Valkeinen @ 2012-08-24 12:41 UTC (permalink / raw)
  To: Archit Taneja; +Cc: linux-omap, linux-fbdev, rob, sumit.semwal

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

On Tue, 2012-08-21 at 11:28 +0530, Archit Taneja wrote:

> diff --git a/drivers/video/omap2/dss/output.c b/drivers/video/omap2/dss/output.c
> new file mode 100644
> index 0000000..034ebbe
> --- /dev/null
> +++ b/drivers/video/omap2/dss/output.c
> @@ -0,0 +1,58 @@
> +/*
> + * Copyright (C) 2012 Texas Instruments Ltd
> + * Author: Archit Taneja <archit@ti.com>
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms of the GNU General Public License version 2 as published by
> + * the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful, but WITHOUT
> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
> + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
> + * more details.
> + *
> + * You should have received a copy of the GNU General Public License along with
> + * this program.  If not, see <http://www.gnu.org/licenses/>.
> + */
> +
> +#include <linux/kernel.h>
> +#include <linux/platform_device.h>
> +#include <linux/slab.h>
> +
> +#include <video/omapdss.h>
> +
> +#include "dss.h"
> +
> +static struct list_head output_list;

You can do:

static LIST_HEAD(output_list);

Then you don't need to initialize it separately.

> +
> +struct omap_dss_output *dss_create_output(struct platform_device *pdev)
> +{
> +	struct omap_dss_output *out;
> +
> +	out = kzalloc(sizeof(struct omap_dss_output *), GFP_KERNEL);
> +	if (!out)
> +		return NULL;

A patch that adds kzalloc but no free is always a bit suspicious =).

> +
> +	out->pdev = pdev;
> +
> +	list_add_tail(&out->list, &output_list);
> +
> +	return out;
> +}

Instead of allocating omap_dss_output here, you could let the caller do
it, and only initialize it here with default values (if that's even
needed). Then the caller can use kzalloc, or can just embed the stuct
into its own data-struct, which may be often a better choice.

> +struct omap_dss_output *omap_dss_get_output(enum omap_dss_output_id id)
> +{
> +	struct omap_dss_output *out;
> +
> +	list_for_each_entry(out, &output_list, list) {
> +		if (out->id == id)
> +			return out;
> +	}
> +
> +	return NULL;
> +}
> +
> +void dss_init_outputs(void)
> +{
> +	INIT_LIST_HEAD(&output_list);
> +}
> diff --git a/include/video/omapdss.h b/include/video/omapdss.h
> index b868123..0ba613f 100644
> --- a/include/video/omapdss.h
> +++ b/include/video/omapdss.h
> @@ -207,6 +207,16 @@ enum omap_hdmi_flags {
>  	OMAP_HDMI_SDA_SCL_EXTERNAL_PULLUP = 1 << 0,
>  };
>  
> +enum omap_dss_output_id {
> +	OMAP_DSS_OUTPUT_DPI	= 1 << 0,
> +	OMAP_DSS_OUTPUT_DBI	= 1 << 1,
> +	OMAP_DSS_OUTPUT_SDI	= 1 << 2,
> +	OMAP_DSS_OUTPUT_DSI1	= 1 << 3,
> +	OMAP_DSS_OUTPUT_VENC	= 1 << 4,
> +	OMAP_DSS_OUTPUT_DSI2	= 1 << 5,
> +	OMAP_DSS_OUTPUT_HDMI	= 1 << 6,
> +};

I'm not sure about this. We already have enum omap_display_type. If you
need the instance number, you could have that as a separate int field.

Where do you need the output_id?

> +
>  /* RFBI */
>  
>  struct rfbi_timings {
> @@ -492,6 +502,24 @@ struct omap_dsi_pin_config {
>  	int pins[OMAP_DSS_MAX_DSI_PINS];
>  };
>  
> +struct omap_dss_output {
> +	struct list_head list;
> +
> +	/* display type supported by the output */
> +	enum omap_display_type type;
> +
> +	/* output instance */
> +	enum omap_dss_output_id id;

So instead of omap_dss_output_id, you'd have omap_display_type type and
int id, which together tell the supported output and also the output
driver instance.

 Tomi


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

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [PATCH 01/23] OMAPDSS: outputs: Create a new entity called outputs
  2012-08-24 12:41     ` Tomi Valkeinen
@ 2012-08-24 12:53       ` Archit Taneja
  -1 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-08-24 12:51 UTC (permalink / raw)
  To: Tomi Valkeinen; +Cc: Archit Taneja, linux-omap, linux-fbdev, rob, sumit.semwal

On Friday 24 August 2012 06:11 PM, Tomi Valkeinen wrote:
> On Tue, 2012-08-21 at 11:28 +0530, Archit Taneja wrote:
>
>> diff --git a/drivers/video/omap2/dss/output.c b/drivers/video/omap2/dss/output.c
>> new file mode 100644
>> index 0000000..034ebbe
>> --- /dev/null
>> +++ b/drivers/video/omap2/dss/output.c
>> @@ -0,0 +1,58 @@
>> +/*
>> + * Copyright (C) 2012 Texas Instruments Ltd
>> + * Author: Archit Taneja <archit@ti.com>
>> + *
>> + * This program is free software; you can redistribute it and/or modify it
>> + * under the terms of the GNU General Public License version 2 as published by
>> + * the Free Software Foundation.
>> + *
>> + * This program is distributed in the hope that it will be useful, but WITHOUT
>> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
>> + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
>> + * more details.
>> + *
>> + * You should have received a copy of the GNU General Public License along with
>> + * this program.  If not, see <http://www.gnu.org/licenses/>.
>> + */
>> +
>> +#include <linux/kernel.h>
>> +#include <linux/platform_device.h>
>> +#include <linux/slab.h>
>> +
>> +#include <video/omapdss.h>
>> +
>> +#include "dss.h"
>> +
>> +static struct list_head output_list;
>
> You can do:
>
> static LIST_HEAD(output_list);
>
> Then you don't need to initialize it separately.

Oh ok. I'll fix this.

>
>> +
>> +struct omap_dss_output *dss_create_output(struct platform_device *pdev)
>> +{
>> +	struct omap_dss_output *out;
>> +
>> +	out = kzalloc(sizeof(struct omap_dss_output *), GFP_KERNEL);
>> +	if (!out)
>> +		return NULL;
>
> A patch that adds kzalloc but no free is always a bit suspicious =).
>
>> +
>> +	out->pdev = pdev;
>> +
>> +	list_add_tail(&out->list, &output_list);
>> +
>> +	return out;
>> +}
>
> Instead of allocating omap_dss_output here, you could let the caller do
> it, and only initialize it here with default values (if that's even
> needed). Then the caller can use kzalloc, or can just embed the stuct
> into its own data-struct, which may be often a better choice.

So output can be in each interface driver's private data, and we just 
add that to our list of outputs?

>
>> +struct omap_dss_output *omap_dss_get_output(enum omap_dss_output_id id)
>> +{
>> +	struct omap_dss_output *out;
>> +
>> +	list_for_each_entry(out, &output_list, list) {
>> +		if (out->id == id)
>> +			return out;
>> +	}
>> +
>> +	return NULL;
>> +}
>> +
>> +void dss_init_outputs(void)
>> +{
>> +	INIT_LIST_HEAD(&output_list);
>> +}
>> diff --git a/include/video/omapdss.h b/include/video/omapdss.h
>> index b868123..0ba613f 100644
>> --- a/include/video/omapdss.h
>> +++ b/include/video/omapdss.h
>> @@ -207,6 +207,16 @@ enum omap_hdmi_flags {
>>   	OMAP_HDMI_SDA_SCL_EXTERNAL_PULLUP = 1 << 0,
>>   };
>>
>> +enum omap_dss_output_id {
>> +	OMAP_DSS_OUTPUT_DPI	= 1 << 0,
>> +	OMAP_DSS_OUTPUT_DBI	= 1 << 1,
>> +	OMAP_DSS_OUTPUT_SDI	= 1 << 2,
>> +	OMAP_DSS_OUTPUT_DSI1	= 1 << 3,
>> +	OMAP_DSS_OUTPUT_VENC	= 1 << 4,
>> +	OMAP_DSS_OUTPUT_DSI2	= 1 << 5,
>> +	OMAP_DSS_OUTPUT_HDMI	= 1 << 6,
>> +};
>
> I'm not sure about this. We already have enum omap_display_type. If you
> need the instance number, you could have that as a separate int field.
>
> Where do you need the output_id?

output_id is used to take care of situations where there our multiple 
outputs of the same type, like DSI1 and DSI2. An enum helps when we 
check if an overlay manager supports that output instance or not. For 
ex, on OMAP4, LCD1 connects to DSI1 and not DSI2.

I add a func called dss_feat_get_supported_outputs(channel) later to 
check for this. When setting a new output for a manager, we just do an 
'&' to see if the output in question is in the mask of the manager's set 
of supported outputs.

>
>> +
>>   /* RFBI */
>>
>>   struct rfbi_timings {
>> @@ -492,6 +502,24 @@ struct omap_dsi_pin_config {
>>   	int pins[OMAP_DSS_MAX_DSI_PINS];
>>   };
>>
>> +struct omap_dss_output {
>> +	struct list_head list;
>> +
>> +	/* display type supported by the output */
>> +	enum omap_display_type type;
>> +
>> +	/* output instance */
>> +	enum omap_dss_output_id id;
>
> So instead of omap_dss_output_id, you'd have omap_display_type type and
> int id, which together tell the supported output and also the output
> driver instance.
>
>   Tomi
>


^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [PATCH 01/23] OMAPDSS: outputs: Create a new entity called outputs
@ 2012-08-24 12:53       ` Archit Taneja
  0 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-08-24 12:53 UTC (permalink / raw)
  To: Tomi Valkeinen; +Cc: Archit Taneja, linux-omap, linux-fbdev, rob, sumit.semwal

On Friday 24 August 2012 06:11 PM, Tomi Valkeinen wrote:
> On Tue, 2012-08-21 at 11:28 +0530, Archit Taneja wrote:
>
>> diff --git a/drivers/video/omap2/dss/output.c b/drivers/video/omap2/dss/output.c
>> new file mode 100644
>> index 0000000..034ebbe
>> --- /dev/null
>> +++ b/drivers/video/omap2/dss/output.c
>> @@ -0,0 +1,58 @@
>> +/*
>> + * Copyright (C) 2012 Texas Instruments Ltd
>> + * Author: Archit Taneja <archit@ti.com>
>> + *
>> + * This program is free software; you can redistribute it and/or modify it
>> + * under the terms of the GNU General Public License version 2 as published by
>> + * the Free Software Foundation.
>> + *
>> + * This program is distributed in the hope that it will be useful, but WITHOUT
>> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
>> + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
>> + * more details.
>> + *
>> + * You should have received a copy of the GNU General Public License along with
>> + * this program.  If not, see <http://www.gnu.org/licenses/>.
>> + */
>> +
>> +#include <linux/kernel.h>
>> +#include <linux/platform_device.h>
>> +#include <linux/slab.h>
>> +
>> +#include <video/omapdss.h>
>> +
>> +#include "dss.h"
>> +
>> +static struct list_head output_list;
>
> You can do:
>
> static LIST_HEAD(output_list);
>
> Then you don't need to initialize it separately.

Oh ok. I'll fix this.

>
>> +
>> +struct omap_dss_output *dss_create_output(struct platform_device *pdev)
>> +{
>> +	struct omap_dss_output *out;
>> +
>> +	out = kzalloc(sizeof(struct omap_dss_output *), GFP_KERNEL);
>> +	if (!out)
>> +		return NULL;
>
> A patch that adds kzalloc but no free is always a bit suspicious =).
>
>> +
>> +	out->pdev = pdev;
>> +
>> +	list_add_tail(&out->list, &output_list);
>> +
>> +	return out;
>> +}
>
> Instead of allocating omap_dss_output here, you could let the caller do
> it, and only initialize it here with default values (if that's even
> needed). Then the caller can use kzalloc, or can just embed the stuct
> into its own data-struct, which may be often a better choice.

So output can be in each interface driver's private data, and we just 
add that to our list of outputs?

>
>> +struct omap_dss_output *omap_dss_get_output(enum omap_dss_output_id id)
>> +{
>> +	struct omap_dss_output *out;
>> +
>> +	list_for_each_entry(out, &output_list, list) {
>> +		if (out->id = id)
>> +			return out;
>> +	}
>> +
>> +	return NULL;
>> +}
>> +
>> +void dss_init_outputs(void)
>> +{
>> +	INIT_LIST_HEAD(&output_list);
>> +}
>> diff --git a/include/video/omapdss.h b/include/video/omapdss.h
>> index b868123..0ba613f 100644
>> --- a/include/video/omapdss.h
>> +++ b/include/video/omapdss.h
>> @@ -207,6 +207,16 @@ enum omap_hdmi_flags {
>>   	OMAP_HDMI_SDA_SCL_EXTERNAL_PULLUP = 1 << 0,
>>   };
>>
>> +enum omap_dss_output_id {
>> +	OMAP_DSS_OUTPUT_DPI	= 1 << 0,
>> +	OMAP_DSS_OUTPUT_DBI	= 1 << 1,
>> +	OMAP_DSS_OUTPUT_SDI	= 1 << 2,
>> +	OMAP_DSS_OUTPUT_DSI1	= 1 << 3,
>> +	OMAP_DSS_OUTPUT_VENC	= 1 << 4,
>> +	OMAP_DSS_OUTPUT_DSI2	= 1 << 5,
>> +	OMAP_DSS_OUTPUT_HDMI	= 1 << 6,
>> +};
>
> I'm not sure about this. We already have enum omap_display_type. If you
> need the instance number, you could have that as a separate int field.
>
> Where do you need the output_id?

output_id is used to take care of situations where there our multiple 
outputs of the same type, like DSI1 and DSI2. An enum helps when we 
check if an overlay manager supports that output instance or not. For 
ex, on OMAP4, LCD1 connects to DSI1 and not DSI2.

I add a func called dss_feat_get_supported_outputs(channel) later to 
check for this. When setting a new output for a manager, we just do an 
'&' to see if the output in question is in the mask of the manager's set 
of supported outputs.

>
>> +
>>   /* RFBI */
>>
>>   struct rfbi_timings {
>> @@ -492,6 +502,24 @@ struct omap_dsi_pin_config {
>>   	int pins[OMAP_DSS_MAX_DSI_PINS];
>>   };
>>
>> +struct omap_dss_output {
>> +	struct list_head list;
>> +
>> +	/* display type supported by the output */
>> +	enum omap_display_type type;
>> +
>> +	/* output instance */
>> +	enum omap_dss_output_id id;
>
> So instead of omap_dss_output_id, you'd have omap_display_type type and
> int id, which together tell the supported output and also the output
> driver instance.
>
>   Tomi
>


^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [PATCH 02/23] OMAPDSS: outputs: Create and initialize output instances
  2012-08-21  6:10   ` Archit Taneja
@ 2012-08-24 13:14     ` Tomi Valkeinen
  -1 siblings, 0 replies; 148+ messages in thread
From: Tomi Valkeinen @ 2012-08-24 13:14 UTC (permalink / raw)
  To: Archit Taneja; +Cc: linux-omap, linux-fbdev, rob, sumit.semwal

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

On Tue, 2012-08-21 at 11:28 +0530, Archit Taneja wrote:
> Create output instances by having an init function in the probes of the platform
> device drivers for different interfaces. Create a small function for each
> interface to initialize the output entity's fields type and id.
> 
> In the probe of each interface driver, the output entities are created before
> the *_probe_pdata() functions intentionally. This is done to ensure that the
> output entity is prepared before the panels connected to the output are
> registered. We need the output entities to be ready because OMAPDSS will try
> to make connections between overlays, managers, outputs and devices during the
> panel's probe.

You're referring to the recheck_connections stuff? I have a patch that
moves that to omapfb side. But of course it doesn't hurt to initialize
the output early.

We should generally do the initialization in output driver's probe more
or less so that we first setup everything related to the output driver,
and after that we register the dssdevs. But I think that's what is
already done.

So, no complaints =).

> Signed-off-by: Archit Taneja <archit@ti.com>
> ---
>  drivers/video/omap2/dss/dpi.c  |   20 ++++++++++++++++++++
>  drivers/video/omap2/dss/dsi.c  |   26 ++++++++++++++++++++++++--
>  drivers/video/omap2/dss/hdmi.c |   18 ++++++++++++++++++
>  drivers/video/omap2/dss/rfbi.c |   19 +++++++++++++++++++
>  drivers/video/omap2/dss/sdi.c  |   20 ++++++++++++++++++++
>  drivers/video/omap2/dss/venc.c |   20 ++++++++++++++++++++
>  6 files changed, 121 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c
> index f260343..4eca2e7 100644
> --- a/drivers/video/omap2/dss/dpi.c
> +++ b/drivers/video/omap2/dss/dpi.c
> @@ -408,10 +408,30 @@ static void __init dpi_probe_pdata(struct platform_device *pdev)
>  	}
>  }
>  
> +static int __init dpi_init_output(struct platform_device *pdev)
> +{
> +	struct omap_dss_output *out;
> +
> +	out = dss_create_output(pdev);
> +	if (!out)
> +		return -ENOMEM;
> +
> +	out->id = OMAP_DSS_OUTPUT_DPI;
> +	out->type = OMAP_DISPLAY_TYPE_DPI;
> +
> +	return 0;
> +}
> +
>  static int __init omap_dpi_probe(struct platform_device *pdev)
>  {
> +	int r;
> +
>  	mutex_init(&dpi.lock);
>  
> +	r = dpi_init_output(pdev);
> +	if (r)
> +		return r;
> +
>  	dpi_probe_pdata(pdev);
>  
>  	return 0;
> diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
> index 659b6cd..22e0873 100644
> --- a/drivers/video/omap2/dss/dsi.c
> +++ b/drivers/video/omap2/dss/dsi.c
> @@ -4903,6 +4903,23 @@ static void __init dsi_probe_pdata(struct platform_device *dsidev)
>  	}
>  }
>  
> +static int __init dsi_init_output(struct platform_device *dsidev,
> +		struct dsi_data *dsi)
> +{
> +	struct omap_dss_output *out;
> +
> +	out = dss_create_output(dsidev);
> +	if (!out)
> +		return -ENOMEM;
> +
> +	out->id = dsi->module_id == 0 ?
> +			OMAP_DSS_OUTPUT_DSI1 : OMAP_DSS_OUTPUT_DSI2;
> +
> +	out->type = OMAP_DISPLAY_TYPE_DSI;
> +
> +	return 0;

As I mentioned in the last email, I think this could be something like:

struct omap_dss_output *out = &dsi->output;

out->pdev = dsidev;
out->id = xxx;
out->type = yyy;
dss_register_output(out);


> +}
> +
>  /* DSI1 HW IP initialisation */
>  static int __init omap_dsihw_probe(struct platform_device *dsidev)
>  {
> @@ -4997,10 +5014,14 @@ static int __init omap_dsihw_probe(struct platform_device *dsidev)
>  	else
>  		dsi->num_lanes_supported = 3;
>  
> -	dsi_probe_pdata(dsidev);
> -
>  	dsi_runtime_put(dsidev);
>  
> +	r = dsi_init_output(dsidev, dsi);
> +	if (r)
> +		goto err_init_output;
> +
> +	dsi_probe_pdata(dsidev);
> +

Why do you change the sequence here? Isn't it enough to just add the
init_output before probe_pdata?

 Tomi


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

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [PATCH 02/23] OMAPDSS: outputs: Create and initialize output instances
@ 2012-08-24 13:14     ` Tomi Valkeinen
  0 siblings, 0 replies; 148+ messages in thread
From: Tomi Valkeinen @ 2012-08-24 13:14 UTC (permalink / raw)
  To: Archit Taneja; +Cc: linux-omap, linux-fbdev, rob, sumit.semwal

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

On Tue, 2012-08-21 at 11:28 +0530, Archit Taneja wrote:
> Create output instances by having an init function in the probes of the platform
> device drivers for different interfaces. Create a small function for each
> interface to initialize the output entity's fields type and id.
> 
> In the probe of each interface driver, the output entities are created before
> the *_probe_pdata() functions intentionally. This is done to ensure that the
> output entity is prepared before the panels connected to the output are
> registered. We need the output entities to be ready because OMAPDSS will try
> to make connections between overlays, managers, outputs and devices during the
> panel's probe.

You're referring to the recheck_connections stuff? I have a patch that
moves that to omapfb side. But of course it doesn't hurt to initialize
the output early.

We should generally do the initialization in output driver's probe more
or less so that we first setup everything related to the output driver,
and after that we register the dssdevs. But I think that's what is
already done.

So, no complaints =).

> Signed-off-by: Archit Taneja <archit@ti.com>
> ---
>  drivers/video/omap2/dss/dpi.c  |   20 ++++++++++++++++++++
>  drivers/video/omap2/dss/dsi.c  |   26 ++++++++++++++++++++++++--
>  drivers/video/omap2/dss/hdmi.c |   18 ++++++++++++++++++
>  drivers/video/omap2/dss/rfbi.c |   19 +++++++++++++++++++
>  drivers/video/omap2/dss/sdi.c  |   20 ++++++++++++++++++++
>  drivers/video/omap2/dss/venc.c |   20 ++++++++++++++++++++
>  6 files changed, 121 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c
> index f260343..4eca2e7 100644
> --- a/drivers/video/omap2/dss/dpi.c
> +++ b/drivers/video/omap2/dss/dpi.c
> @@ -408,10 +408,30 @@ static void __init dpi_probe_pdata(struct platform_device *pdev)
>  	}
>  }
>  
> +static int __init dpi_init_output(struct platform_device *pdev)
> +{
> +	struct omap_dss_output *out;
> +
> +	out = dss_create_output(pdev);
> +	if (!out)
> +		return -ENOMEM;
> +
> +	out->id = OMAP_DSS_OUTPUT_DPI;
> +	out->type = OMAP_DISPLAY_TYPE_DPI;
> +
> +	return 0;
> +}
> +
>  static int __init omap_dpi_probe(struct platform_device *pdev)
>  {
> +	int r;
> +
>  	mutex_init(&dpi.lock);
>  
> +	r = dpi_init_output(pdev);
> +	if (r)
> +		return r;
> +
>  	dpi_probe_pdata(pdev);
>  
>  	return 0;
> diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
> index 659b6cd..22e0873 100644
> --- a/drivers/video/omap2/dss/dsi.c
> +++ b/drivers/video/omap2/dss/dsi.c
> @@ -4903,6 +4903,23 @@ static void __init dsi_probe_pdata(struct platform_device *dsidev)
>  	}
>  }
>  
> +static int __init dsi_init_output(struct platform_device *dsidev,
> +		struct dsi_data *dsi)
> +{
> +	struct omap_dss_output *out;
> +
> +	out = dss_create_output(dsidev);
> +	if (!out)
> +		return -ENOMEM;
> +
> +	out->id = dsi->module_id == 0 ?
> +			OMAP_DSS_OUTPUT_DSI1 : OMAP_DSS_OUTPUT_DSI2;
> +
> +	out->type = OMAP_DISPLAY_TYPE_DSI;
> +
> +	return 0;

As I mentioned in the last email, I think this could be something like:

struct omap_dss_output *out = &dsi->output;

out->pdev = dsidev;
out->id = xxx;
out->type = yyy;
dss_register_output(out);


> +}
> +
>  /* DSI1 HW IP initialisation */
>  static int __init omap_dsihw_probe(struct platform_device *dsidev)
>  {
> @@ -4997,10 +5014,14 @@ static int __init omap_dsihw_probe(struct platform_device *dsidev)
>  	else
>  		dsi->num_lanes_supported = 3;
>  
> -	dsi_probe_pdata(dsidev);
> -
>  	dsi_runtime_put(dsidev);
>  
> +	r = dsi_init_output(dsidev, dsi);
> +	if (r)
> +		goto err_init_output;
> +
> +	dsi_probe_pdata(dsidev);
> +

Why do you change the sequence here? Isn't it enough to just add the
init_output before probe_pdata?

 Tomi


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

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [PATCH 02/23] OMAPDSS: outputs: Create and initialize output instances
  2012-08-24 13:14     ` Tomi Valkeinen
@ 2012-08-27  6:31       ` Archit Taneja
  -1 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-08-27  6:19 UTC (permalink / raw)
  To: Tomi Valkeinen; +Cc: linux-omap, linux-fbdev, rob, sumit.semwal

On Friday 24 August 2012 06:44 PM, Tomi Valkeinen wrote:
> On Tue, 2012-08-21 at 11:28 +0530, Archit Taneja wrote:
>> Create output instances by having an init function in the probes of the platform
>> device drivers for different interfaces. Create a small function for each
>> interface to initialize the output entity's fields type and id.
>>
>> In the probe of each interface driver, the output entities are created before
>> the *_probe_pdata() functions intentionally. This is done to ensure that the
>> output entity is prepared before the panels connected to the output are
>> registered. We need the output entities to be ready because OMAPDSS will try
>> to make connections between overlays, managers, outputs and devices during the
>> panel's probe.
>
> You're referring to the recheck_connections stuff? I have a patch that
> moves that to omapfb side. But of course it doesn't hurt to initialize
> the output early.

I've seen that patch. omapfb would need to take care of connecting 
outputs to displays, and managers to outputs. This is added in 
recheck_connections done in a patch #9 of the series.

The question is whether we want some initial connections made between 
outputs and displays by DSS, or should that be left completely to 
omapfb/omapdrm?

>
> We should generally do the initialization in output driver's probe more
> or less so that we first setup everything related to the output driver,
> and after that we register the dssdevs. But I think that's what is
> already done.
>
> So, no complaints =).

Another thing that comes up with delaying the recheck_connections stuff 
is that we can't assume that at the point of panel driver's probe, there 
is an output connected to the display. That makes it a bit tricky to 
call an output function in the panel's probe, since it isn't connected 
to any output at all. An example is when we request for a VC in 
taal_probe. Since the panel isn't connected to any output yet, we can't 
really call a dsi function to request for the VC. This particular case 
can be solved by requesting VCs only when we enable the panel(probably 
makes more sense this way), but there might be other situations which 
could get tricky to tackle.

>
>> Signed-off-by: Archit Taneja <archit@ti.com>
>> ---
>>   drivers/video/omap2/dss/dpi.c  |   20 ++++++++++++++++++++
>>   drivers/video/omap2/dss/dsi.c  |   26 ++++++++++++++++++++++++--
>>   drivers/video/omap2/dss/hdmi.c |   18 ++++++++++++++++++
>>   drivers/video/omap2/dss/rfbi.c |   19 +++++++++++++++++++
>>   drivers/video/omap2/dss/sdi.c  |   20 ++++++++++++++++++++
>>   drivers/video/omap2/dss/venc.c |   20 ++++++++++++++++++++
>>   6 files changed, 121 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c
>> index f260343..4eca2e7 100644
>> --- a/drivers/video/omap2/dss/dpi.c
>> +++ b/drivers/video/omap2/dss/dpi.c
>> @@ -408,10 +408,30 @@ static void __init dpi_probe_pdata(struct platform_device *pdev)
>>   	}
>>   }
>>
>> +static int __init dpi_init_output(struct platform_device *pdev)
>> +{
>> +	struct omap_dss_output *out;
>> +
>> +	out = dss_create_output(pdev);
>> +	if (!out)
>> +		return -ENOMEM;
>> +
>> +	out->id = OMAP_DSS_OUTPUT_DPI;
>> +	out->type = OMAP_DISPLAY_TYPE_DPI;
>> +
>> +	return 0;
>> +}
>> +
>>   static int __init omap_dpi_probe(struct platform_device *pdev)
>>   {
>> +	int r;
>> +
>>   	mutex_init(&dpi.lock);
>>
>> +	r = dpi_init_output(pdev);
>> +	if (r)
>> +		return r;
>> +
>>   	dpi_probe_pdata(pdev);
>>
>>   	return 0;
>> diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
>> index 659b6cd..22e0873 100644
>> --- a/drivers/video/omap2/dss/dsi.c
>> +++ b/drivers/video/omap2/dss/dsi.c
>> @@ -4903,6 +4903,23 @@ static void __init dsi_probe_pdata(struct platform_device *dsidev)
>>   	}
>>   }
>>
>> +static int __init dsi_init_output(struct platform_device *dsidev,
>> +		struct dsi_data *dsi)
>> +{
>> +	struct omap_dss_output *out;
>> +
>> +	out = dss_create_output(dsidev);
>> +	if (!out)
>> +		return -ENOMEM;
>> +
>> +	out->id = dsi->module_id == 0 ?
>> +			OMAP_DSS_OUTPUT_DSI1 : OMAP_DSS_OUTPUT_DSI2;
>> +
>> +	out->type = OMAP_DISPLAY_TYPE_DSI;
>> +
>> +	return 0;
>
> As I mentioned in the last email, I think this could be something like:
>
> struct omap_dss_output *out = &dsi->output;
>
> out->pdev = dsidev;
> out->id = xxx;
> out->type = yyy;
> dss_register_output(out);
>

Right, this is much better, will do it this way.

>
>> +}
>> +
>>   /* DSI1 HW IP initialisation */
>>   static int __init omap_dsihw_probe(struct platform_device *dsidev)
>>   {
>> @@ -4997,10 +5014,14 @@ static int __init omap_dsihw_probe(struct platform_device *dsidev)
>>   	else
>>   		dsi->num_lanes_supported = 3;
>>
>> -	dsi_probe_pdata(dsidev);
>> -
>>   	dsi_runtime_put(dsidev);
>>
>> +	r = dsi_init_output(dsidev, dsi);
>> +	if (r)
>> +		goto err_init_output;
>> +
>> +	dsi_probe_pdata(dsidev);
>> +
>
> Why do you change the sequence here? Isn't it enough to just add the
> init_output before probe_pdata?

Yes, I think I didn't see the point in keeping the clocks on for 
dsi_init_output() and dsi_probe_pdata(), so tried to incorporate that in 
this patch too :), I'll change this back to the old way, it doesn't make 
sense in moving around pm runtime calls in this series.

Archit


^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [PATCH 02/23] OMAPDSS: outputs: Create and initialize output instances
@ 2012-08-27  6:31       ` Archit Taneja
  0 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-08-27  6:31 UTC (permalink / raw)
  To: Tomi Valkeinen; +Cc: linux-omap, linux-fbdev, rob, sumit.semwal

On Friday 24 August 2012 06:44 PM, Tomi Valkeinen wrote:
> On Tue, 2012-08-21 at 11:28 +0530, Archit Taneja wrote:
>> Create output instances by having an init function in the probes of the platform
>> device drivers for different interfaces. Create a small function for each
>> interface to initialize the output entity's fields type and id.
>>
>> In the probe of each interface driver, the output entities are created before
>> the *_probe_pdata() functions intentionally. This is done to ensure that the
>> output entity is prepared before the panels connected to the output are
>> registered. We need the output entities to be ready because OMAPDSS will try
>> to make connections between overlays, managers, outputs and devices during the
>> panel's probe.
>
> You're referring to the recheck_connections stuff? I have a patch that
> moves that to omapfb side. But of course it doesn't hurt to initialize
> the output early.

I've seen that patch. omapfb would need to take care of connecting 
outputs to displays, and managers to outputs. This is added in 
recheck_connections done in a patch #9 of the series.

The question is whether we want some initial connections made between 
outputs and displays by DSS, or should that be left completely to 
omapfb/omapdrm?

>
> We should generally do the initialization in output driver's probe more
> or less so that we first setup everything related to the output driver,
> and after that we register the dssdevs. But I think that's what is
> already done.
>
> So, no complaints =).

Another thing that comes up with delaying the recheck_connections stuff 
is that we can't assume that at the point of panel driver's probe, there 
is an output connected to the display. That makes it a bit tricky to 
call an output function in the panel's probe, since it isn't connected 
to any output at all. An example is when we request for a VC in 
taal_probe. Since the panel isn't connected to any output yet, we can't 
really call a dsi function to request for the VC. This particular case 
can be solved by requesting VCs only when we enable the panel(probably 
makes more sense this way), but there might be other situations which 
could get tricky to tackle.

>
>> Signed-off-by: Archit Taneja <archit@ti.com>
>> ---
>>   drivers/video/omap2/dss/dpi.c  |   20 ++++++++++++++++++++
>>   drivers/video/omap2/dss/dsi.c  |   26 ++++++++++++++++++++++++--
>>   drivers/video/omap2/dss/hdmi.c |   18 ++++++++++++++++++
>>   drivers/video/omap2/dss/rfbi.c |   19 +++++++++++++++++++
>>   drivers/video/omap2/dss/sdi.c  |   20 ++++++++++++++++++++
>>   drivers/video/omap2/dss/venc.c |   20 ++++++++++++++++++++
>>   6 files changed, 121 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c
>> index f260343..4eca2e7 100644
>> --- a/drivers/video/omap2/dss/dpi.c
>> +++ b/drivers/video/omap2/dss/dpi.c
>> @@ -408,10 +408,30 @@ static void __init dpi_probe_pdata(struct platform_device *pdev)
>>   	}
>>   }
>>
>> +static int __init dpi_init_output(struct platform_device *pdev)
>> +{
>> +	struct omap_dss_output *out;
>> +
>> +	out = dss_create_output(pdev);
>> +	if (!out)
>> +		return -ENOMEM;
>> +
>> +	out->id = OMAP_DSS_OUTPUT_DPI;
>> +	out->type = OMAP_DISPLAY_TYPE_DPI;
>> +
>> +	return 0;
>> +}
>> +
>>   static int __init omap_dpi_probe(struct platform_device *pdev)
>>   {
>> +	int r;
>> +
>>   	mutex_init(&dpi.lock);
>>
>> +	r = dpi_init_output(pdev);
>> +	if (r)
>> +		return r;
>> +
>>   	dpi_probe_pdata(pdev);
>>
>>   	return 0;
>> diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
>> index 659b6cd..22e0873 100644
>> --- a/drivers/video/omap2/dss/dsi.c
>> +++ b/drivers/video/omap2/dss/dsi.c
>> @@ -4903,6 +4903,23 @@ static void __init dsi_probe_pdata(struct platform_device *dsidev)
>>   	}
>>   }
>>
>> +static int __init dsi_init_output(struct platform_device *dsidev,
>> +		struct dsi_data *dsi)
>> +{
>> +	struct omap_dss_output *out;
>> +
>> +	out = dss_create_output(dsidev);
>> +	if (!out)
>> +		return -ENOMEM;
>> +
>> +	out->id = dsi->module_id = 0 ?
>> +			OMAP_DSS_OUTPUT_DSI1 : OMAP_DSS_OUTPUT_DSI2;
>> +
>> +	out->type = OMAP_DISPLAY_TYPE_DSI;
>> +
>> +	return 0;
>
> As I mentioned in the last email, I think this could be something like:
>
> struct omap_dss_output *out = &dsi->output;
>
> out->pdev = dsidev;
> out->id = xxx;
> out->type = yyy;
> dss_register_output(out);
>

Right, this is much better, will do it this way.

>
>> +}
>> +
>>   /* DSI1 HW IP initialisation */
>>   static int __init omap_dsihw_probe(struct platform_device *dsidev)
>>   {
>> @@ -4997,10 +5014,14 @@ static int __init omap_dsihw_probe(struct platform_device *dsidev)
>>   	else
>>   		dsi->num_lanes_supported = 3;
>>
>> -	dsi_probe_pdata(dsidev);
>> -
>>   	dsi_runtime_put(dsidev);
>>
>> +	r = dsi_init_output(dsidev, dsi);
>> +	if (r)
>> +		goto err_init_output;
>> +
>> +	dsi_probe_pdata(dsidev);
>> +
>
> Why do you change the sequence here? Isn't it enough to just add the
> init_output before probe_pdata?

Yes, I think I didn't see the point in keeping the clocks on for 
dsi_init_output() and dsi_probe_pdata(), so tried to incorporate that in 
this patch too :), I'll change this back to the old way, it doesn't make 
sense in moving around pm runtime calls in this series.

Archit


^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [PATCH 02/23] OMAPDSS: outputs: Create and initialize output instances
  2012-08-27  6:31       ` Archit Taneja
@ 2012-08-27  6:44         ` Tomi Valkeinen
  -1 siblings, 0 replies; 148+ messages in thread
From: Tomi Valkeinen @ 2012-08-27  6:44 UTC (permalink / raw)
  To: Archit Taneja; +Cc: linux-omap, linux-fbdev, rob, sumit.semwal

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

On Mon, 2012-08-27 at 11:49 +0530, Archit Taneja wrote:
> On Friday 24 August 2012 06:44 PM, Tomi Valkeinen wrote:
> > On Tue, 2012-08-21 at 11:28 +0530, Archit Taneja wrote:
> >> Create output instances by having an init function in the probes of the platform
> >> device drivers for different interfaces. Create a small function for each
> >> interface to initialize the output entity's fields type and id.
> >>
> >> In the probe of each interface driver, the output entities are created before
> >> the *_probe_pdata() functions intentionally. This is done to ensure that the
> >> output entity is prepared before the panels connected to the output are
> >> registered. We need the output entities to be ready because OMAPDSS will try
> >> to make connections between overlays, managers, outputs and devices during the
> >> panel's probe.
> >
> > You're referring to the recheck_connections stuff? I have a patch that
> > moves that to omapfb side. But of course it doesn't hurt to initialize
> > the output early.
> 
> I've seen that patch. omapfb would need to take care of connecting 
> outputs to displays, and managers to outputs. This is added in 
> recheck_connections done in a patch #9 of the series.
> 
> The question is whether we want some initial connections made between 
> outputs and displays by DSS, or should that be left completely to 
> omapfb/omapdrm?

Good question. I don't know. Perhaps we should set initial connections
there, as the cases where we have multiple displays per output are quite
rare.

> > We should generally do the initialization in output driver's probe more
> > or less so that we first setup everything related to the output driver,
> > and after that we register the dssdevs. But I think that's what is
> > already done.
> >
> > So, no complaints =).
> 
> Another thing that comes up with delaying the recheck_connections stuff 
> is that we can't assume that at the point of panel driver's probe, there 
> is an output connected to the display. That makes it a bit tricky to 
> call an output function in the panel's probe, since it isn't connected 
> to any output at all. An example is when we request for a VC in 
> taal_probe. Since the panel isn't connected to any output yet, we can't 
> really call a dsi function to request for the VC. This particular case 
> can be solved by requesting VCs only when we enable the panel(probably 
> makes more sense this way), but there might be other situations which 
> could get tricky to tackle.

Right. Well, as you said, we can easily move the stuff from taal's probe
to enable. There shouldn't be any problems to that.

However, this problem is part of the bigger problem that I haven't been
able to solve properly: how to manage the probe/enable stuff for panels.
Everything would be simple and easy if we had just one panel per output,
and we could just get and configure everything at probe. But we can have
multiple panels per output, of which only one can be used at a time...

That's why we currently acquire most of the display resources at enable,
instead of probe.

 Tomi


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

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [PATCH 02/23] OMAPDSS: outputs: Create and initialize output instances
@ 2012-08-27  6:44         ` Tomi Valkeinen
  0 siblings, 0 replies; 148+ messages in thread
From: Tomi Valkeinen @ 2012-08-27  6:44 UTC (permalink / raw)
  To: Archit Taneja; +Cc: linux-omap, linux-fbdev, rob, sumit.semwal

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

On Mon, 2012-08-27 at 11:49 +0530, Archit Taneja wrote:
> On Friday 24 August 2012 06:44 PM, Tomi Valkeinen wrote:
> > On Tue, 2012-08-21 at 11:28 +0530, Archit Taneja wrote:
> >> Create output instances by having an init function in the probes of the platform
> >> device drivers for different interfaces. Create a small function for each
> >> interface to initialize the output entity's fields type and id.
> >>
> >> In the probe of each interface driver, the output entities are created before
> >> the *_probe_pdata() functions intentionally. This is done to ensure that the
> >> output entity is prepared before the panels connected to the output are
> >> registered. We need the output entities to be ready because OMAPDSS will try
> >> to make connections between overlays, managers, outputs and devices during the
> >> panel's probe.
> >
> > You're referring to the recheck_connections stuff? I have a patch that
> > moves that to omapfb side. But of course it doesn't hurt to initialize
> > the output early.
> 
> I've seen that patch. omapfb would need to take care of connecting 
> outputs to displays, and managers to outputs. This is added in 
> recheck_connections done in a patch #9 of the series.
> 
> The question is whether we want some initial connections made between 
> outputs and displays by DSS, or should that be left completely to 
> omapfb/omapdrm?

Good question. I don't know. Perhaps we should set initial connections
there, as the cases where we have multiple displays per output are quite
rare.

> > We should generally do the initialization in output driver's probe more
> > or less so that we first setup everything related to the output driver,
> > and after that we register the dssdevs. But I think that's what is
> > already done.
> >
> > So, no complaints =).
> 
> Another thing that comes up with delaying the recheck_connections stuff 
> is that we can't assume that at the point of panel driver's probe, there 
> is an output connected to the display. That makes it a bit tricky to 
> call an output function in the panel's probe, since it isn't connected 
> to any output at all. An example is when we request for a VC in 
> taal_probe. Since the panel isn't connected to any output yet, we can't 
> really call a dsi function to request for the VC. This particular case 
> can be solved by requesting VCs only when we enable the panel(probably 
> makes more sense this way), but there might be other situations which 
> could get tricky to tackle.

Right. Well, as you said, we can easily move the stuff from taal's probe
to enable. There shouldn't be any problems to that.

However, this problem is part of the bigger problem that I haven't been
able to solve properly: how to manage the probe/enable stuff for panels.
Everything would be simple and easy if we had just one panel per output,
and we could just get and configure everything at probe. But we can have
multiple panels per output, of which only one can be used at a time...

That's why we currently acquire most of the display resources at enable,
instead of probe.

 Tomi


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

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [PATCH 01/23] OMAPDSS: outputs: Create a new entity called outputs
  2012-08-24 12:53       ` Archit Taneja
@ 2012-08-29 10:32         ` Tomi Valkeinen
  -1 siblings, 0 replies; 148+ messages in thread
From: Tomi Valkeinen @ 2012-08-29 10:32 UTC (permalink / raw)
  To: Archit Taneja; +Cc: Archit Taneja, linux-omap, linux-fbdev, rob, sumit.semwal

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

On Fri, 2012-08-24 at 18:21 +0530, Archit Taneja wrote:

> >> +enum omap_dss_output_id {
> >> +	OMAP_DSS_OUTPUT_DPI	= 1 << 0,
> >> +	OMAP_DSS_OUTPUT_DBI	= 1 << 1,
> >> +	OMAP_DSS_OUTPUT_SDI	= 1 << 2,
> >> +	OMAP_DSS_OUTPUT_DSI1	= 1 << 3,
> >> +	OMAP_DSS_OUTPUT_VENC	= 1 << 4,
> >> +	OMAP_DSS_OUTPUT_DSI2	= 1 << 5,
> >> +	OMAP_DSS_OUTPUT_HDMI	= 1 << 6,
> >> +};
> >
> > I'm not sure about this. We already have enum omap_display_type. If you
> > need the instance number, you could have that as a separate int field.
> >
> > Where do you need the output_id?
> 
> output_id is used to take care of situations where there our multiple 
> outputs of the same type, like DSI1 and DSI2. An enum helps when we 
> check if an overlay manager supports that output instance or not. For 
> ex, on OMAP4, LCD1 connects to DSI1 and not DSI2.
> 
> I add a func called dss_feat_get_supported_outputs(channel) later to 
> check for this. When setting a new output for a manager, we just do an 
> '&' to see if the output in question is in the mask of the manager's set 
> of supported outputs.

After thinking about this, I think we should remove the
omap_display_type and the supported_displays stuff. It doesn't really
work anymore, as we have more complex connections with omap4+. With a
quick glance to the code, I think it should be quite easy to remove it.

And we need something like your omap_dss_output_id. I'm just not sure
about the enum. But perhaps it's the easiest option for now, as some
kind of array of similar would be more complex to implement, and I'm not
sure if it really gives anything. You could move the VENC away from
between DSI1 and DSI2, though. I'm not sure why you put VENC in between
=).

 Tomi


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

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [PATCH 01/23] OMAPDSS: outputs: Create a new entity called outputs
@ 2012-08-29 10:32         ` Tomi Valkeinen
  0 siblings, 0 replies; 148+ messages in thread
From: Tomi Valkeinen @ 2012-08-29 10:32 UTC (permalink / raw)
  To: Archit Taneja; +Cc: Archit Taneja, linux-omap, linux-fbdev, rob, sumit.semwal

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

On Fri, 2012-08-24 at 18:21 +0530, Archit Taneja wrote:

> >> +enum omap_dss_output_id {
> >> +	OMAP_DSS_OUTPUT_DPI	= 1 << 0,
> >> +	OMAP_DSS_OUTPUT_DBI	= 1 << 1,
> >> +	OMAP_DSS_OUTPUT_SDI	= 1 << 2,
> >> +	OMAP_DSS_OUTPUT_DSI1	= 1 << 3,
> >> +	OMAP_DSS_OUTPUT_VENC	= 1 << 4,
> >> +	OMAP_DSS_OUTPUT_DSI2	= 1 << 5,
> >> +	OMAP_DSS_OUTPUT_HDMI	= 1 << 6,
> >> +};
> >
> > I'm not sure about this. We already have enum omap_display_type. If you
> > need the instance number, you could have that as a separate int field.
> >
> > Where do you need the output_id?
> 
> output_id is used to take care of situations where there our multiple 
> outputs of the same type, like DSI1 and DSI2. An enum helps when we 
> check if an overlay manager supports that output instance or not. For 
> ex, on OMAP4, LCD1 connects to DSI1 and not DSI2.
> 
> I add a func called dss_feat_get_supported_outputs(channel) later to 
> check for this. When setting a new output for a manager, we just do an 
> '&' to see if the output in question is in the mask of the manager's set 
> of supported outputs.

After thinking about this, I think we should remove the
omap_display_type and the supported_displays stuff. It doesn't really
work anymore, as we have more complex connections with omap4+. With a
quick glance to the code, I think it should be quite easy to remove it.

And we need something like your omap_dss_output_id. I'm just not sure
about the enum. But perhaps it's the easiest option for now, as some
kind of array of similar would be more complex to implement, and I'm not
sure if it really gives anything. You could move the VENC away from
between DSI1 and DSI2, though. I'm not sure why you put VENC in between
=).

 Tomi


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

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [PATCH 01/23] OMAPDSS: outputs: Create a new entity called outputs
  2012-08-29 10:32         ` Tomi Valkeinen
@ 2012-08-29 10:58           ` Archit Taneja
  -1 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-08-29 10:57 UTC (permalink / raw)
  To: Tomi Valkeinen; +Cc: linux-omap, linux-fbdev, rob, sumit.semwal

On Wednesday 29 August 2012 04:02 PM, Tomi Valkeinen wrote:
> On Fri, 2012-08-24 at 18:21 +0530, Archit Taneja wrote:
>
>>>> +enum omap_dss_output_id {
>>>> +	OMAP_DSS_OUTPUT_DPI	= 1 << 0,
>>>> +	OMAP_DSS_OUTPUT_DBI	= 1 << 1,
>>>> +	OMAP_DSS_OUTPUT_SDI	= 1 << 2,
>>>> +	OMAP_DSS_OUTPUT_DSI1	= 1 << 3,
>>>> +	OMAP_DSS_OUTPUT_VENC	= 1 << 4,
>>>> +	OMAP_DSS_OUTPUT_DSI2	= 1 << 5,
>>>> +	OMAP_DSS_OUTPUT_HDMI	= 1 << 6,
>>>> +};
>>>
>>> I'm not sure about this. We already have enum omap_display_type. If you
>>> need the instance number, you could have that as a separate int field.
>>>
>>> Where do you need the output_id?
>>
>> output_id is used to take care of situations where there our multiple
>> outputs of the same type, like DSI1 and DSI2. An enum helps when we
>> check if an overlay manager supports that output instance or not. For
>> ex, on OMAP4, LCD1 connects to DSI1 and not DSI2.
>>
>> I add a func called dss_feat_get_supported_outputs(channel) later to
>> check for this. When setting a new output for a manager, we just do an
>> '&' to see if the output in question is in the mask of the manager's set
>> of supported outputs.
>
> After thinking about this, I think we should remove the
> omap_display_type and the supported_displays stuff. It doesn't really
> work anymore, as we have more complex connections with omap4+. With a
> quick glance to the code, I think it should be quite easy to remove it.
>
> And we need something like your omap_dss_output_id. I'm just not sure
> about the enum. But perhaps it's the easiest option for now, as some
> kind of array of similar would be more complex to implement, and I'm not
> sure if it really gives anything. You could move the VENC away from
> between DSI1 and DSI2, though. I'm not sure why you put VENC in between
> =).

I put the outputs in the order in which they were introduced in OMAPs, 
I'm not sure why I did that, maybe I copied that approach after looking 
at some other enum. I'll change it.

Archit

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [PATCH 01/23] OMAPDSS: outputs: Create a new entity called outputs
@ 2012-08-29 10:58           ` Archit Taneja
  0 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-08-29 10:58 UTC (permalink / raw)
  To: Tomi Valkeinen; +Cc: linux-omap, linux-fbdev, rob, sumit.semwal

On Wednesday 29 August 2012 04:02 PM, Tomi Valkeinen wrote:
> On Fri, 2012-08-24 at 18:21 +0530, Archit Taneja wrote:
>
>>>> +enum omap_dss_output_id {
>>>> +	OMAP_DSS_OUTPUT_DPI	= 1 << 0,
>>>> +	OMAP_DSS_OUTPUT_DBI	= 1 << 1,
>>>> +	OMAP_DSS_OUTPUT_SDI	= 1 << 2,
>>>> +	OMAP_DSS_OUTPUT_DSI1	= 1 << 3,
>>>> +	OMAP_DSS_OUTPUT_VENC	= 1 << 4,
>>>> +	OMAP_DSS_OUTPUT_DSI2	= 1 << 5,
>>>> +	OMAP_DSS_OUTPUT_HDMI	= 1 << 6,
>>>> +};
>>>
>>> I'm not sure about this. We already have enum omap_display_type. If you
>>> need the instance number, you could have that as a separate int field.
>>>
>>> Where do you need the output_id?
>>
>> output_id is used to take care of situations where there our multiple
>> outputs of the same type, like DSI1 and DSI2. An enum helps when we
>> check if an overlay manager supports that output instance or not. For
>> ex, on OMAP4, LCD1 connects to DSI1 and not DSI2.
>>
>> I add a func called dss_feat_get_supported_outputs(channel) later to
>> check for this. When setting a new output for a manager, we just do an
>> '&' to see if the output in question is in the mask of the manager's set
>> of supported outputs.
>
> After thinking about this, I think we should remove the
> omap_display_type and the supported_displays stuff. It doesn't really
> work anymore, as we have more complex connections with omap4+. With a
> quick glance to the code, I think it should be quite easy to remove it.
>
> And we need something like your omap_dss_output_id. I'm just not sure
> about the enum. But perhaps it's the easiest option for now, as some
> kind of array of similar would be more complex to implement, and I'm not
> sure if it really gives anything. You could move the VENC away from
> between DSI1 and DSI2, though. I'm not sure why you put VENC in between
> =).

I put the outputs in the order in which they were introduced in OMAPs, 
I'm not sure why I did that, maybe I copied that approach after looking 
at some other enum. I'll change it.

Archit

^ permalink raw reply	[flat|nested] 148+ messages in thread

* [PATCH v2 00/23] OMAPDSS: Create output entities
  2012-08-21  6:10 ` Archit Taneja
@ 2012-08-30 11:52   ` Archit Taneja
  -1 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-08-30 11:40 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: rob, linux-omap, linux-fbdev, Archit Taneja

Create a new entity in OMAPDSS called outputs. These represent the
interfaces/outputs like DSI, HDMI etc. that a panel connects to. An output
sits in between an overlay manager and a panel. More details about outputs
are explained in the first patch of the series.

This series adds omap_dss_output as an entity along with omap_overlay,
omap_overlay_manager and omap_dss_device. It changes the code to establish
links between managers and outputs, and outputs and devices.

Changes since v1:
- Output drivers private data structs hold the output struct rather than
  output.c allocating it. This struct is added to a list when
  dss_register_output()is called.
- Outputs are not passed from panel driver to output driver anymore. We are
  sticking to passing omap_dss_device for now till we get a clearer picture on
  how common panel framework turns out. Outputs are still used within the output
  driver, rather than passing dssdev everywhere.

Reference tree:

git://gitorious.org/~boddob/linux-omap-dss2/archit-dss2-clone.git 2-add-outputs

Archit Taneja (23):
  OMAPDSS: outputs: Create a new entity called outputs
  OMAPDSS: outputs: Create and register output instances
  OMAPDSS: output: Add set/unset device ops for omap_dss_output
  OMAPDSS: APPLY: Add manager set/unset output ops for
    omap_overlay_manager
  OMAPDSS: Remove manager->device references
  OMAP_VOUT: Remove manager->device references
  OMAPFB: remove manager->device references
  OMAPDRM: Remove manager->device references
  OMAPDSS: Create links between managers, outputs and devices
  OMAPDSS: DPI: Pass omap_dss_output within the driver
  OMAPDSS: DSI: Remove dsi_pdev_map global struct
  OMAPDSS: DSI: Pass omap_dss_output within the driver
  OMAPDSS: SDI: Pass omap_dss_output within the driver
  OMAPDSS: RFBI: Pass omap_dss_output within the driver
  OMAPDSS: RFBI: Add dssdev pointers as arguments to all exported
    functions
  OMAPDSS: VENC: Pass omap_dss_output within the driver
  OMAPDSS: HDMI: Pass omap_dss_output within the driver
  OMAPDSS: HDMI: Add dssdev pointer as an argument to all functions
    used by hdmi panel driver
  OMAPDSS/OMAPFB: Change dssdev->manager references
  OMAPDSS: MANAGER: Update display sysfs store
  OMAPDSS: MANAGER: Get device via output
  OMAPDSS: APPLY: Remove omap_dss_device references from
    dss_ovl_enable/disable
  OMAPDSS: Remove old way of setting manager and device links

 drivers/media/video/omap/omap_vout.c      |   81 +++++++---
 drivers/staging/omapdrm/omap_drv.c        |    5 +-
 drivers/video/omap2/displays/panel-n8x0.c |   55 ++++---
 drivers/video/omap2/dss/Makefile          |    2 +-
 drivers/video/omap2/dss/apply.c           |   52 +++---
 drivers/video/omap2/dss/dispc.c           |   10 +-
 drivers/video/omap2/dss/display.c         |   11 +-
 drivers/video/omap2/dss/dpi.c             |   70 +++++---
 drivers/video/omap2/dss/dsi.c             |  249 ++++++++++++++++++-----------
 drivers/video/omap2/dss/dss.h             |   23 ++-
 drivers/video/omap2/dss/dss_features.c    |   52 ++++++
 drivers/video/omap2/dss/dss_features.h    |    1 +
 drivers/video/omap2/dss/hdmi.c            |   72 ++++++---
 drivers/video/omap2/dss/hdmi_panel.c      |   20 +--
 drivers/video/omap2/dss/manager.c         |   48 ++++--
 drivers/video/omap2/dss/output.c          |  110 +++++++++++++
 drivers/video/omap2/dss/overlay.c         |   96 ++++++-----
 drivers/video/omap2/dss/rfbi.c            |   66 +++++---
 drivers/video/omap2/dss/sdi.c             |   35 ++--
 drivers/video/omap2/dss/venc.c            |   47 ++++--
 drivers/video/omap2/omapfb/omapfb-ioctl.c |    7 +-
 drivers/video/omap2/omapfb/omapfb-main.c  |    7 +-
 drivers/video/omap2/omapfb/omapfb.h       |    5 +-
 include/video/omapdss.h                   |   72 +++++++--
 24 files changed, 848 insertions(+), 348 deletions(-)
 create mode 100644 drivers/video/omap2/dss/output.c

-- 
1.7.9.5


^ permalink raw reply	[flat|nested] 148+ messages in thread

* [PATCH v2 01/23] OMAPDSS: outputs: Create a new entity called outputs
  2012-08-30 11:52   ` Archit Taneja
@ 2012-08-30 11:52     ` Archit Taneja
  -1 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-08-30 11:40 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: rob, linux-omap, linux-fbdev, Archit Taneja

The current OMAPDSS design contains 3 software entities: Overlays, Managers and
Devices. These map to pipelines, overlay managers and the panels respectively in
hardware. One or more overlays connect to a manager to represent a composition,
the manager connects to a device(generally a display) to display the content.

The part of DSS hardware which isn't represented by any of the above entities
are interfaces/outputs that connect to an overlay manager, i.e blocks like DSI,
HDMI, VENC and so on. Currently, an overlay manager directly connects to the
display, and the output to which it is actually connected is ignored. The panel
driver of the display is responsible of calling output specific functions to
configure the output.

Adding outputs as a new software entity gives us the following benefits:

- Have exact information on the possible connections between managers and
  outputs: A manager can't connect to each and every output, there only limited
  hardware links between a manager's video port and some of the outputs.

- Remove hacks related to connecting managers and devices: Currently, default
  links between managers and devices are set in a not so clean way. Matching is
  done via comparing the device type, and the display types supported by the
  manager. This isn't sufficient to establish all the possible links between
  managers, outputs and devices in hardware.

- Make panel drivers more generic: The DSS panel drivers currently call
  interface/output specific functions to configure the hardware IP. When making
  these calls, the driver isn't actually aware of the underlying output. The
  output driver extracts information from the panel's omap_dss_device pointer
  to figure out which interface it is connected to, and then configures the
  corresponding output block. An example of this is when a DSI panel calls
  dsi functions, the dsi driver figures out whether the panel is connected
  to DSI1 or DSI2. This isn't correct, and having output as entities will
  give the panel driver the exact information on which output to configure.
  Having outputs also gives the opportunity to make panel drivers generic
  across different platforms/SoCs, this is achieved as omap specific output
  calls can be replaced by ops of a particular output type.

- Have more complex connections between managers, outputs and devices: OMAPDSS
  currently doesn't support use cases like 2 outputs connect to a single
  device. This can be achieved by extending properties of outputs to connect to
  more managers or devices.

- Represent writeback as an output: The writeback pipeline fits well in OMAPDSS
  as compared to overlays, managers or devices.

Add a new struct to represent outputs. An output struct holds pointers to the
manager and device structs to which it is connected. Add functions which can
register an output, or look for one. Create an enum which represent each output
instance.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/dss/Makefile |    2 +-
 drivers/video/omap2/dss/dss.h    |    3 +++
 drivers/video/omap2/dss/output.c |   43 ++++++++++++++++++++++++++++++++++++++
 include/video/omapdss.h          |   30 ++++++++++++++++++++++++++
 4 files changed, 77 insertions(+), 1 deletion(-)
 create mode 100644 drivers/video/omap2/dss/output.c

diff --git a/drivers/video/omap2/dss/Makefile b/drivers/video/omap2/dss/Makefile
index 30a48fb..645f8c3 100644
--- a/drivers/video/omap2/dss/Makefile
+++ b/drivers/video/omap2/dss/Makefile
@@ -1,6 +1,6 @@
 obj-$(CONFIG_OMAP2_DSS) += omapdss.o
 omapdss-y := core.o dss.o dss_features.o dispc.o dispc_coefs.o display.o \
-	manager.o overlay.o apply.o
+	manager.o overlay.o output.o apply.o
 omapdss-$(CONFIG_OMAP2_DSS_DPI) += dpi.o
 omapdss-$(CONFIG_OMAP2_DSS_RFBI) += rfbi.o
 omapdss-$(CONFIG_OMAP2_DSS_VENC) += venc.o venc_panel.o
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index d6cca82..e77d8d2 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -222,6 +222,9 @@ int dss_ovl_set_manager(struct omap_overlay *ovl,
 		struct omap_overlay_manager *mgr);
 int dss_ovl_unset_manager(struct omap_overlay *ovl);
 
+/* output */
+void dss_register_output(struct omap_dss_output *out);
+
 /* display */
 int dss_suspend_all_devices(void);
 int dss_resume_all_devices(void);
diff --git a/drivers/video/omap2/dss/output.c b/drivers/video/omap2/dss/output.c
new file mode 100644
index 0000000..7d81be5
--- /dev/null
+++ b/drivers/video/omap2/dss/output.c
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2012 Texas Instruments Ltd
+ * Author: Archit Taneja <archit@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#include <video/omapdss.h>
+
+#include "dss.h"
+
+static LIST_HEAD(output_list);
+
+void dss_register_output(struct omap_dss_output *out)
+{
+	list_add_tail(&out->list, &output_list);
+}
+
+struct omap_dss_output *omap_dss_get_output(enum omap_dss_output_id id)
+{
+	struct omap_dss_output *out;
+
+	list_for_each_entry(out, &output_list, list) {
+		if (out->id == id)
+			return out;
+	}
+
+	return NULL;
+}
diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index b868123..2926a04 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -207,6 +207,16 @@ enum omap_hdmi_flags {
 	OMAP_HDMI_SDA_SCL_EXTERNAL_PULLUP = 1 << 0,
 };
 
+enum omap_dss_output_id {
+	OMAP_DSS_OUTPUT_DPI	= 1 << 0,
+	OMAP_DSS_OUTPUT_DBI	= 1 << 1,
+	OMAP_DSS_OUTPUT_SDI	= 1 << 2,
+	OMAP_DSS_OUTPUT_DSI1	= 1 << 3,
+	OMAP_DSS_OUTPUT_DSI2	= 1 << 4,
+	OMAP_DSS_OUTPUT_VENC	= 1 << 5,
+	OMAP_DSS_OUTPUT_HDMI	= 1 << 6,
+};
+
 /* RFBI */
 
 struct rfbi_timings {
@@ -492,6 +502,24 @@ struct omap_dsi_pin_config {
 	int pins[OMAP_DSS_MAX_DSI_PINS];
 };
 
+struct omap_dss_output {
+	struct list_head list;
+
+	/* display type supported by the output */
+	enum omap_display_type type;
+
+	/* output instance */
+	enum omap_dss_output_id id;
+
+	/* output's platform device pointer */
+	struct platform_device *pdev;
+
+	/* dynamic fields */
+	struct omap_overlay_manager *manager;
+
+	struct omap_dss_device *device;
+};
+
 struct omap_dss_device {
 	struct device dev;
 
@@ -699,6 +727,8 @@ struct omap_overlay_manager *omap_dss_get_overlay_manager(int num);
 int omap_dss_get_num_overlays(void);
 struct omap_overlay *omap_dss_get_overlay(int num);
 
+struct omap_dss_output *omap_dss_get_output(enum omap_dss_output_id id);
+
 void omapdss_default_get_resolution(struct omap_dss_device *dssdev,
 		u16 *xres, u16 *yres);
 int omapdss_default_get_recommended_bpp(struct omap_dss_device *dssdev);
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [PATCH v2 02/23] OMAPDSS: outputs: Create and register output instances
  2012-08-30 11:52   ` Archit Taneja
@ 2012-08-30 11:52     ` Archit Taneja
  -1 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-08-30 11:40 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: rob, linux-omap, linux-fbdev, Archit Taneja

Add output structs to output driver's private data. Register output instances by
having an init function in the probes of the platform device drivers for
different outputs. The *_init_output for each output registers the output and
fill up the output's plaform device, type and id fields.

In the probe of each interface driver, the output entities are initialized
before the *_probe_pdata() functions intentionally. This is done to ensure that
the output entity is prepared before the panels connected to the output are
registered. We need the output entities to be ready because OMAPDSS will try
to make connections between overlays, managers, outputs and devices during the
panel's probe.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/dss/dpi.c  |   15 +++++++++++++++
 drivers/video/omap2/dss/dsi.c  |   18 ++++++++++++++++++
 drivers/video/omap2/dss/hdmi.c |   15 +++++++++++++++
 drivers/video/omap2/dss/rfbi.c |   17 +++++++++++++++++
 drivers/video/omap2/dss/sdi.c  |   15 +++++++++++++++
 drivers/video/omap2/dss/venc.c |   15 +++++++++++++++
 6 files changed, 95 insertions(+)

diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c
index 25fb895..9a7aee5 100644
--- a/drivers/video/omap2/dss/dpi.c
+++ b/drivers/video/omap2/dss/dpi.c
@@ -45,6 +45,8 @@ static struct {
 	struct omap_video_timings timings;
 	struct dss_lcd_mgr_config mgr_config;
 	int data_lines;
+
+	struct omap_dss_output output;
 } dpi;
 
 static struct platform_device *dpi_get_dsidev(enum omap_dss_clk_source clk)
@@ -410,10 +412,23 @@ static void __init dpi_probe_pdata(struct platform_device *pdev)
 	}
 }
 
+static void __init dpi_init_output(struct platform_device *pdev)
+{
+	struct omap_dss_output *out = &dpi.output;
+
+	dss_register_output(out);
+
+	out->pdev = pdev;
+	out->id = OMAP_DSS_OUTPUT_DPI;
+	out->type = OMAP_DISPLAY_TYPE_DPI;
+}
+
 static int __init omap_dpi_probe(struct platform_device *pdev)
 {
 	mutex_init(&dpi.lock);
 
+	dpi_init_output(pdev);
+
 	dpi_probe_pdata(pdev);
 
 	return 0;
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index 659b6cd..6a83ab7 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -337,6 +337,8 @@ struct dsi_data {
 	enum omap_dss_dsi_pixel_format pix_fmt;
 	enum omap_dss_dsi_mode mode;
 	struct omap_dss_dsi_videomode_timings vm_timings;
+
+	struct omap_dss_output output;
 };
 
 struct dsi_packet_sent_handler_data {
@@ -4903,6 +4905,20 @@ static void __init dsi_probe_pdata(struct platform_device *dsidev)
 	}
 }
 
+static void __init dsi_init_output(struct platform_device *dsidev,
+		struct dsi_data *dsi)
+{
+	struct omap_dss_output *out = &dsi->output;
+
+	dss_register_output(out);
+
+	out->pdev = dsidev;
+	out->id = dsi->module_id == 0 ?
+			OMAP_DSS_OUTPUT_DSI1 : OMAP_DSS_OUTPUT_DSI2;
+
+	out->type = OMAP_DISPLAY_TYPE_DSI;
+}
+
 /* DSI1 HW IP initialisation */
 static int __init omap_dsihw_probe(struct platform_device *dsidev)
 {
@@ -4997,6 +5013,8 @@ static int __init omap_dsihw_probe(struct platform_device *dsidev)
 	else
 		dsi->num_lanes_supported = 3;
 
+	dsi_init_output(dsidev, dsi);
+
 	dsi_probe_pdata(dsidev);
 
 	dsi_runtime_put(dsidev);
diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c
index 0cdf246..d93954d 100644
--- a/drivers/video/omap2/dss/hdmi.c
+++ b/drivers/video/omap2/dss/hdmi.c
@@ -61,6 +61,8 @@ static struct {
 	struct hdmi_ip_data ip_data;
 
 	struct clk *sys_clk;
+
+	struct omap_dss_output output;
 } hdmi;
 
 /*
@@ -890,6 +892,17 @@ static void __init hdmi_probe_pdata(struct platform_device *pdev)
 	}
 }
 
+static void __init hdmi_init_output(struct platform_device *pdev)
+{
+	struct omap_dss_output *out = &hdmi.output;
+
+	dss_register_output(out);
+
+	out->pdev = pdev;
+	out->id = OMAP_DSS_OUTPUT_HDMI;
+	out->type = OMAP_DISPLAY_TYPE_HDMI;
+}
+
 /* HDMI HW IP initialisation */
 static int __init omapdss_hdmihw_probe(struct platform_device *pdev)
 {
@@ -933,6 +946,8 @@ static int __init omapdss_hdmihw_probe(struct platform_device *pdev)
 
 	dss_debugfs_create_file("hdmi", hdmi_dump_regs);
 
+	hdmi_init_output(pdev);
+
 	hdmi_probe_pdata(pdev);
 
 	return 0;
diff --git a/drivers/video/omap2/dss/rfbi.c b/drivers/video/omap2/dss/rfbi.c
index 5a9c0e9..3450f51 100644
--- a/drivers/video/omap2/dss/rfbi.c
+++ b/drivers/video/omap2/dss/rfbi.c
@@ -116,6 +116,8 @@ static struct {
 	int pixel_size;
 	int data_lines;
 	struct rfbi_timings intf_timings;
+
+	struct omap_dss_output output;
 } rfbi;
 
 static inline void rfbi_write_reg(const struct rfbi_reg idx, u32 val)
@@ -967,6 +969,19 @@ static void __init rfbi_probe_pdata(struct platform_device *pdev)
 	}
 }
 
+static void __init rfbi_init_output(struct platform_device *pdev)
+{
+	struct omap_dss_output *out = &rfbi.output;
+
+	dss_register_output(out);
+
+	out->pdev = pdev;
+	out->id = OMAP_DSS_OUTPUT_DBI;
+	out->type = OMAP_DISPLAY_TYPE_DBI;
+
+	return 0;
+}
+
 /* RFBI HW IP initialisation */
 static int __init omap_rfbihw_probe(struct platform_device *pdev)
 {
@@ -1018,6 +1033,8 @@ static int __init omap_rfbihw_probe(struct platform_device *pdev)
 
 	dss_debugfs_create_file("rfbi", rfbi_dump_regs);
 
+	rfbi_init_output(pdev);
+
 	rfbi_probe_pdata(pdev);
 
 	return 0;
diff --git a/drivers/video/omap2/dss/sdi.c b/drivers/video/omap2/dss/sdi.c
index 3bf1bfe..d8879f3 100644
--- a/drivers/video/omap2/dss/sdi.c
+++ b/drivers/video/omap2/dss/sdi.c
@@ -36,6 +36,8 @@ static struct {
 	struct dss_lcd_mgr_config mgr_config;
 	struct omap_video_timings timings;
 	int datapairs;
+
+	struct omap_dss_output output;
 } sdi;
 
 static void sdi_config_lcd_manager(struct omap_dss_device *dssdev)
@@ -216,8 +218,21 @@ static void __init sdi_probe_pdata(struct platform_device *pdev)
 	}
 }
 
+static void __init sdi_init_output(struct platform_device *pdev)
+{
+	struct omap_dss_output *out = &sdi.output;
+
+	dss_register_output(out);
+
+	out->pdev = pdev;
+	out->id = OMAP_DSS_OUTPUT_SDI;
+	out->type = OMAP_DISPLAY_TYPE_SDI;
+}
+
 static int __init omap_sdi_probe(struct platform_device *pdev)
 {
+	sdi_init_output(pdev);
+
 	sdi_probe_pdata(pdev);
 
 	return 0;
diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c
index 4a6caf9..942a378 100644
--- a/drivers/video/omap2/dss/venc.c
+++ b/drivers/video/omap2/dss/venc.c
@@ -304,6 +304,8 @@ static struct {
 	struct omap_video_timings timings;
 	enum omap_dss_venc_type type;
 	bool invert_polarity;
+
+	struct omap_dss_output output;
 } venc;
 
 static inline void venc_write_reg(int idx, u32 val)
@@ -773,6 +775,17 @@ static void __init venc_probe_pdata(struct platform_device *pdev)
 	}
 }
 
+static void __init venc_init_output(struct platform_device *pdev)
+{
+	struct omap_dss_output *out = &venc.output;
+
+	dss_register_output(out);
+
+	out->pdev = pdev;
+	out->id = OMAP_DSS_OUTPUT_VENC;
+	out->type = OMAP_DISPLAY_TYPE_VENC;
+}
+
 /* VENC HW IP initialisation */
 static int __init omap_venchw_probe(struct platform_device *pdev)
 {
@@ -820,6 +833,8 @@ static int __init omap_venchw_probe(struct platform_device *pdev)
 
 	dss_debugfs_create_file("venc", venc_dump_regs);
 
+	venc_init_output(pdev);
+
 	venc_probe_pdata(pdev);
 
 	return 0;
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [PATCH v2 03/23] OMAPDSS: output: Add set/unset device ops for omap_dss_output
  2012-08-30 11:52   ` Archit Taneja
@ 2012-08-30 11:52     ` Archit Taneja
  -1 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-08-30 11:40 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: rob, linux-omap, linux-fbdev, Archit Taneja

An output entity represented by the struct omap_dss_output connects to a
omap_dss_device entity. Add functions to set or unset an output's device. This
is similar to how managers and devices were connected previously. An output can
connect to a device without being connected to a manager. However, the output
needs to eventually connect to a manager so that the connected panel can be
enabled.

Keep the omap_overlay_manager pointer in omap_dss_device for now to prevent
breaking things. This will be removed later when outputs are supported
completely.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/dss/output.c |   67 ++++++++++++++++++++++++++++++++++++++
 include/video/omapdss.h          |    5 +++
 2 files changed, 72 insertions(+)

diff --git a/drivers/video/omap2/dss/output.c b/drivers/video/omap2/dss/output.c
index 7d81be5..abc3aa2 100644
--- a/drivers/video/omap2/dss/output.c
+++ b/drivers/video/omap2/dss/output.c
@@ -24,9 +24,76 @@
 #include "dss.h"
 
 static LIST_HEAD(output_list);
+static DEFINE_MUTEX(output_lock);
+
+static int dss_output_set_device(struct omap_dss_output *out,
+		struct omap_dss_device *dssdev)
+{
+	int r;
+
+	mutex_lock(&output_lock);
+
+	if (out->device) {
+		DSSERR("output already has device %s connected to it\n",
+			out->device->name);
+		r = -EINVAL;
+		goto err;
+	}
+
+	if (out->type != dssdev->type) {
+		DSSERR("output type and display type don't match\n");
+		r = -EINVAL;
+		goto err;
+	}
+
+	out->device = dssdev;
+	dssdev->output = out;
+
+	mutex_unlock(&output_lock);
+
+	return 0;
+err:
+	mutex_unlock(&output_lock);
+
+	return r;
+}
+
+static int dss_output_unset_device(struct omap_dss_output *out)
+{
+	int r;
+
+	mutex_lock(&output_lock);
+
+	if (!out->device) {
+		DSSERR("output doesn't have a device connected to it\n");
+		r = -EINVAL;
+		goto err;
+	}
+
+	if (out->device->state != OMAP_DSS_DISPLAY_DISABLED) {
+		DSSERR("device %s is not disabled, cannot unset device\n",
+				out->device->name);
+		r = -EINVAL;
+		goto err;
+	}
+
+	out->device->output = NULL;
+	out->device = NULL;
+
+	mutex_unlock(&output_lock);
+
+	return 0;
+err:
+	mutex_unlock(&output_lock);
+
+	return r;
+}
 
 void dss_register_output(struct omap_dss_output *out)
 {
+	out->set_device = &dss_output_set_device;
+	out->unset_device = &dss_output_unset_device;
+
 	list_add_tail(&out->list, &output_list);
 }
 
diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index 2926a04..b3fba19 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -518,6 +518,10 @@ struct omap_dss_output {
 	struct omap_overlay_manager *manager;
 
 	struct omap_dss_device *device;
+
+	int (*set_device) (struct omap_dss_output *out,
+		struct omap_dss_device *dssdev);
+	int (*unset_device) (struct omap_dss_output *out);
 };
 
 struct omap_dss_device {
@@ -619,6 +623,7 @@ 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	[flat|nested] 148+ messages in thread

* [PATCH v2 04/23] OMAPDSS: APPLY: Add manager set/unset output ops for omap_overlay_manager
  2012-08-30 11:52   ` Archit Taneja
@ 2012-08-30 11:52     ` Archit Taneja
  -1 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-08-30 11:40 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: rob, linux-omap, linux-fbdev, Archit Taneja

Add set_output/unset_output ops for overlay managers, these form links between
managers and outputs. Create a function in dss features which tell all the
output instances that connect to a manager, use it when a manager tries to set
an output. Add a constraint of not unsetting an output when the manager is
enabled.

Keep the omap_dss_device pointer and set/unset_device ops in overlay_manager for
now to not break things. Keep the dss feature function get_supported_displays
as it's used in some places. These will be removed later.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/dss/apply.c        |   70 ++++++++++++++++++++++++++++++++
 drivers/video/omap2/dss/dss.h          |    3 ++
 drivers/video/omap2/dss/dss_features.c |   52 ++++++++++++++++++++++++
 drivers/video/omap2/dss/dss_features.h |    1 +
 drivers/video/omap2/dss/manager.c      |    4 ++
 include/video/omapdss.h                |    5 +++
 6 files changed, 135 insertions(+)

diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c
index 74f1a58..d241407 100644
--- a/drivers/video/omap2/dss/apply.c
+++ b/drivers/video/omap2/dss/apply.c
@@ -1311,6 +1311,76 @@ err:
 	return r;
 }
 
+int dss_mgr_set_output(struct omap_overlay_manager *mgr,
+		struct omap_dss_output *output)
+{
+	int r;
+
+	mutex_lock(&apply_lock);
+
+	if (mgr->output) {
+		DSSERR("manager %s is already connected to an output\n",
+			mgr->name);
+		r = -EINVAL;
+		goto err;
+	}
+
+	if ((mgr->supported_outputs & output->id) == 0) {
+		DSSERR("output does not support manager %s\n",
+			mgr->name);
+		r = -EINVAL;
+		goto err;
+	}
+
+	output->manager = mgr;
+	mgr->output = output;
+
+	mutex_unlock(&apply_lock);
+
+	return 0;
+err:
+	mutex_unlock(&apply_lock);
+	return r;
+}
+
+int dss_mgr_unset_output(struct omap_overlay_manager *mgr)
+{
+	int r;
+	struct mgr_priv_data *mp = get_mgr_priv(mgr);
+	unsigned long flags;
+
+	mutex_lock(&apply_lock);
+
+	if (!mgr->output) {
+		DSSERR("failed to unset output, output not set\n");
+		r = -EINVAL;
+		goto err;
+	}
+
+	spin_lock_irqsave(&data_lock, flags);
+
+	if (mp->enabled) {
+		DSSERR("output can't be unset when manager is enabled\n");
+		r = -EINVAL;
+		goto err1;
+	}
+
+	spin_unlock_irqrestore(&data_lock, flags);
+
+	mgr->output->manager = NULL;
+	mgr->output = NULL;
+
+	mutex_unlock(&apply_lock);
+
+	return 0;
+err1:
+	spin_unlock_irqrestore(&data_lock, flags);
+err:
+	mutex_unlock(&apply_lock);
+
+	return r;
+}
+
 static void dss_apply_mgr_timings(struct omap_overlay_manager *mgr,
 		const struct omap_video_timings *timings)
 {
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index e77d8d2..de2fb9d 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -205,6 +205,9 @@ void dss_mgr_get_info(struct omap_overlay_manager *mgr,
 int dss_mgr_set_device(struct omap_overlay_manager *mgr,
 		struct omap_dss_device *dssdev);
 int dss_mgr_unset_device(struct omap_overlay_manager *mgr);
+int dss_mgr_set_output(struct omap_overlay_manager *mgr,
+		struct omap_dss_output *output);
+int dss_mgr_unset_output(struct omap_overlay_manager *mgr);
 void dss_mgr_set_timings(struct omap_overlay_manager *mgr,
 		const struct omap_video_timings *timings);
 void dss_mgr_set_lcd_config(struct omap_overlay_manager *mgr,
diff --git a/drivers/video/omap2/dss/dss_features.c b/drivers/video/omap2/dss/dss_features.c
index 2fe39d6..2872329 100644
--- a/drivers/video/omap2/dss/dss_features.c
+++ b/drivers/video/omap2/dss/dss_features.c
@@ -47,6 +47,7 @@ struct omap_dss_features {
 	const int num_mgrs;
 	const int num_ovls;
 	const enum omap_display_type *supported_displays;
+	const enum omap_dss_output_id *supported_outputs;
 	const enum omap_color_mode *supported_color_modes;
 	const enum omap_overlay_caps *overlay_caps;
 	const char * const *clksrc_names;
@@ -144,6 +145,46 @@ static const enum omap_display_type omap4_dss_supported_displays[] = {
 	OMAP_DISPLAY_TYPE_DSI,
 };
 
+static const enum omap_dss_output_id omap2_dss_supported_outputs[] = {
+	/* OMAP_DSS_CHANNEL_LCD */
+	OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI,
+
+	/* OMAP_DSS_CHANNEL_DIGIT */
+	OMAP_DSS_OUTPUT_VENC,
+};
+
+static const enum omap_dss_output_id omap3430_dss_supported_outputs[] = {
+	/* OMAP_DSS_CHANNEL_LCD */
+	OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI |
+	OMAP_DSS_OUTPUT_SDI | OMAP_DSS_OUTPUT_DSI1,
+
+	/* OMAP_DSS_CHANNEL_DIGIT */
+	OMAP_DSS_OUTPUT_VENC,
+};
+
+static const enum omap_dss_output_id omap3630_dss_supported_outputs[] = {
+	/* OMAP_DSS_CHANNEL_LCD */
+	OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI |
+	OMAP_DSS_OUTPUT_DSI1,
+
+	/* OMAP_DSS_CHANNEL_DIGIT */
+	OMAP_DSS_OUTPUT_VENC,
+};
+
+static const enum omap_dss_output_id omap4_dss_supported_outputs[] = {
+	/* OMAP_DSS_CHANNEL_LCD */
+	OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI |
+	OMAP_DSS_OUTPUT_DSI1,
+
+	/* OMAP_DSS_CHANNEL_DIGIT */
+	OMAP_DSS_OUTPUT_VENC | OMAP_DSS_OUTPUT_HDMI |
+	OMAP_DSS_OUTPUT_DPI,
+
+	/* OMAP_DSS_CHANNEL_LCD2 */
+	OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI |
+	OMAP_DSS_OUTPUT_DSI2,
+};
+
 static const enum omap_color_mode omap2_dss_supported_color_modes[] = {
 	/* OMAP_DSS_GFX */
 	OMAP_DSS_COLOR_CLUT1 | OMAP_DSS_COLOR_CLUT2 |
@@ -459,6 +500,7 @@ static const struct omap_dss_features omap2_dss_features = {
 	.num_mgrs = 2,
 	.num_ovls = 3,
 	.supported_displays = omap2_dss_supported_displays,
+	.supported_outputs = omap2_dss_supported_outputs,
 	.supported_color_modes = omap2_dss_supported_color_modes,
 	.overlay_caps = omap2_dss_overlay_caps,
 	.clksrc_names = omap2_dss_clk_source_names,
@@ -479,6 +521,7 @@ static const struct omap_dss_features omap3430_dss_features = {
 	.num_mgrs = 2,
 	.num_ovls = 3,
 	.supported_displays = omap3430_dss_supported_displays,
+	.supported_outputs = omap3430_dss_supported_outputs,
 	.supported_color_modes = omap3_dss_supported_color_modes,
 	.overlay_caps = omap3430_dss_overlay_caps,
 	.clksrc_names = omap3_dss_clk_source_names,
@@ -498,6 +541,7 @@ static const struct omap_dss_features omap3630_dss_features = {
 	.num_mgrs = 2,
 	.num_ovls = 3,
 	.supported_displays = omap3630_dss_supported_displays,
+	.supported_outputs = omap3630_dss_supported_outputs,
 	.supported_color_modes = omap3_dss_supported_color_modes,
 	.overlay_caps = omap3630_dss_overlay_caps,
 	.clksrc_names = omap3_dss_clk_source_names,
@@ -519,6 +563,7 @@ static const struct omap_dss_features omap4430_es1_0_dss_features  = {
 	.num_mgrs = 3,
 	.num_ovls = 4,
 	.supported_displays = omap4_dss_supported_displays,
+	.supported_outputs = omap4_dss_supported_outputs,
 	.supported_color_modes = omap4_dss_supported_color_modes,
 	.overlay_caps = omap4_dss_overlay_caps,
 	.clksrc_names = omap4_dss_clk_source_names,
@@ -539,6 +584,7 @@ static const struct omap_dss_features omap4430_es2_0_1_2_dss_features = {
 	.num_mgrs = 3,
 	.num_ovls = 4,
 	.supported_displays = omap4_dss_supported_displays,
+	.supported_outputs = omap4_dss_supported_outputs,
 	.supported_color_modes = omap4_dss_supported_color_modes,
 	.overlay_caps = omap4_dss_overlay_caps,
 	.clksrc_names = omap4_dss_clk_source_names,
@@ -559,6 +605,7 @@ static const struct omap_dss_features omap4_dss_features = {
 	.num_mgrs = 3,
 	.num_ovls = 4,
 	.supported_displays = omap4_dss_supported_displays,
+	.supported_outputs = omap4_dss_supported_outputs,
 	.supported_color_modes = omap4_dss_supported_color_modes,
 	.overlay_caps = omap4_dss_overlay_caps,
 	.clksrc_names = omap4_dss_clk_source_names,
@@ -628,6 +675,11 @@ enum omap_display_type dss_feat_get_supported_displays(enum omap_channel channel
 	return omap_current_dss_features->supported_displays[channel];
 }
 
+enum omap_dss_output_id dss_feat_get_supported_outputs(enum omap_channel channel)
+{
+	return omap_current_dss_features->supported_outputs[channel];
+}
+
 enum omap_color_mode dss_feat_get_supported_color_modes(enum omap_plane plane)
 {
 	return omap_current_dss_features->supported_color_modes[plane];
diff --git a/drivers/video/omap2/dss/dss_features.h b/drivers/video/omap2/dss/dss_features.h
index 26d43a4..5fe62a8 100644
--- a/drivers/video/omap2/dss/dss_features.h
+++ b/drivers/video/omap2/dss/dss_features.h
@@ -104,6 +104,7 @@ int dss_feat_get_num_ovls(void);
 unsigned long dss_feat_get_param_min(enum dss_range_param param);
 unsigned long dss_feat_get_param_max(enum dss_range_param param);
 enum omap_display_type dss_feat_get_supported_displays(enum omap_channel channel);
+enum omap_dss_output_id dss_feat_get_supported_outputs(enum omap_channel channel);
 enum omap_color_mode dss_feat_get_supported_color_modes(enum omap_plane plane);
 enum omap_overlay_caps dss_feat_get_overlay_caps(enum omap_plane plane);
 bool dss_feat_color_mode_supported(enum omap_plane plane,
diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c
index 53710fa..e15fa5f 100644
--- a/drivers/video/omap2/dss/manager.c
+++ b/drivers/video/omap2/dss/manager.c
@@ -549,6 +549,8 @@ int dss_init_overlay_managers(struct platform_device *pdev)
 
 		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;
 		mgr->set_manager_info = &dss_mgr_set_info;
 		mgr->get_manager_info = &dss_mgr_get_info;
@@ -558,6 +560,8 @@ int dss_init_overlay_managers(struct platform_device *pdev)
 		mgr->caps = 0;
 		mgr->supported_displays =
 			dss_feat_get_supported_displays(mgr->id);
+		mgr->supported_outputs =
+			dss_feat_get_supported_outputs(mgr->id);
 
 		INIT_LIST_HEAD(&mgr->overlays);
 
diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index b3fba19..a3b35f9 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -458,9 +458,11 @@ struct omap_overlay_manager {
 	enum omap_overlay_manager_caps caps;
 	struct list_head overlays;
 	enum omap_display_type supported_displays;
+	enum omap_dss_output_id supported_outputs;
 
 	/* dynamic fields */
 	struct omap_dss_device *device;
+	struct omap_dss_output *output;
 
 	/*
 	 * The following functions do not block:
@@ -476,6 +478,9 @@ struct omap_overlay_manager {
 	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);
 
 	int (*set_manager_info)(struct omap_overlay_manager *mgr,
 			struct omap_overlay_manager_info *info);
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [PATCH v2 05/23] OMAPDSS: Remove manager->device references
  2012-08-30 11:52   ` Archit Taneja
@ 2012-08-30 11:52     ` Archit Taneja
  -1 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-08-30 11:40 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: rob, linux-omap, linux-fbdev, Archit Taneja

With the introduction of output entities, managers will now connect to outputs.
Create a helper op for managers named get_device. This will abstract away the
information on how to get the device from an overlay manager. The get_device
op currently retrieves the output via a manager->device reference. This will
be later replaced by a manager->output->device reference.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/dss/apply.c   |    6 ++++--
 drivers/video/omap2/dss/dispc.c   |   10 +++++++---
 drivers/video/omap2/dss/manager.c |   19 ++++++++++++++-----
 include/video/omapdss.h           |    2 ++
 4 files changed, 27 insertions(+), 10 deletions(-)

diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c
index d241407..8a05cbc 100644
--- a/drivers/video/omap2/dss/apply.c
+++ b/drivers/video/omap2/dss/apply.c
@@ -1607,7 +1607,8 @@ int dss_ovl_enable(struct omap_overlay *ovl)
 		goto err1;
 	}
 
-	if (ovl->manager == NULL || ovl->manager->device == NULL) {
+	if (ovl->manager == NULL ||
+			ovl->manager->get_device(ovl->manager) == NULL) {
 		r = -EINVAL;
 		goto err1;
 	}
@@ -1676,7 +1677,8 @@ int dss_ovl_disable(struct omap_overlay *ovl)
 		goto err;
 	}
 
-	if (ovl->manager == NULL || ovl->manager->device == NULL) {
+	if (ovl->manager == NULL ||
+			ovl->manager->get_device(ovl->manager) == NULL) {
 		r = -EINVAL;
 		goto err;
 	}
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index 0de9a7e..bfd73f5 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -3549,7 +3549,7 @@ static void dispc_error_worker(struct work_struct *work)
 		bit = mgr_desc[i].sync_lost_irq;
 
 		if (bit & errors) {
-			struct omap_dss_device *dssdev = mgr->device;
+			struct omap_dss_device *dssdev = mgr->get_device(mgr);
 			bool enable;
 
 			DSSERR("SYNC_LOST on channel %s, restarting the output "
@@ -3580,9 +3580,13 @@ static void dispc_error_worker(struct work_struct *work)
 		DSSERR("OCP_ERR\n");
 		for (i = 0; i < omap_dss_get_num_overlay_managers(); ++i) {
 			struct omap_overlay_manager *mgr;
+			struct omap_dss_device *dssdev;
+
 			mgr = omap_dss_get_overlay_manager(i);
-			if (mgr->device && mgr->device->driver)
-				mgr->device->driver->disable(mgr->device);
+			dssdev = mgr->get_device(mgr);
+
+			if (dssdev && dssdev->driver)
+				dssdev->driver->disable(dssdev);
 		}
 	}
 
diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c
index e15fa5f..fd39f66 100644
--- a/drivers/video/omap2/dss/manager.c
+++ b/drivers/video/omap2/dss/manager.c
@@ -43,8 +43,10 @@ static ssize_t manager_name_show(struct omap_overlay_manager *mgr, char *buf)
 
 static ssize_t manager_display_show(struct omap_overlay_manager *mgr, char *buf)
 {
-	return snprintf(buf, PAGE_SIZE, "%s\n",
-			mgr->device ? mgr->device->name : "<none>");
+	struct omap_dss_device *dssdev = mgr->get_device(mgr);
+
+	return snprintf(buf, PAGE_SIZE, "%s\n", dssdev ?
+			dssdev->name : "<none>");
 }
 
 static ssize_t manager_display_store(struct omap_overlay_manager *mgr,
@@ -72,7 +74,7 @@ static ssize_t manager_display_store(struct omap_overlay_manager *mgr,
 	if (dssdev)
 		DSSDBG("display %s found\n", dssdev->name);
 
-	if (mgr->device) {
+	if (mgr->get_device(mgr)) {
 		r = mgr->unset_device(mgr);
 		if (r) {
 			DSSERR("failed to unset display\n");
@@ -490,9 +492,15 @@ static struct kobj_type manager_ktype = {
 	.default_attrs = manager_sysfs_attrs,
 };
 
+static inline struct omap_dss_device *dss_mgr_get_device(struct omap_overlay_manager *mgr)
+{
+	return mgr->device;
+}
+
 static int dss_mgr_wait_for_vsync(struct omap_overlay_manager *mgr)
 {
 	unsigned long timeout = msecs_to_jiffies(500);
+	struct omap_dss_device *dssdev = mgr->get_device(mgr);
 	u32 irq;
 	int r;
 
@@ -500,9 +508,9 @@ static int dss_mgr_wait_for_vsync(struct omap_overlay_manager *mgr)
 	if (r)
 		return r;
 
-	if (mgr->device->type == OMAP_DISPLAY_TYPE_VENC)
+	if (dssdev->type == OMAP_DISPLAY_TYPE_VENC)
 		irq = DISPC_IRQ_EVSYNC_ODD;
-	else if (mgr->device->type == OMAP_DISPLAY_TYPE_HDMI)
+	else if (dssdev->type == OMAP_DISPLAY_TYPE_HDMI)
 		irq = DISPC_IRQ_EVSYNC_EVEN;
 	else
 		irq = dispc_mgr_get_vsync_irq(mgr->id);
@@ -556,6 +564,7 @@ int dss_init_overlay_managers(struct platform_device *pdev)
 		mgr->get_manager_info = &dss_mgr_get_info;
 		mgr->wait_for_go = &dss_mgr_wait_for_go;
 		mgr->wait_for_vsync = &dss_mgr_wait_for_vsync;
+		mgr->get_device = &dss_mgr_get_device;
 
 		mgr->caps = 0;
 		mgr->supported_displays =
diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index a3b35f9..29c1440 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -490,6 +490,8 @@ struct omap_overlay_manager {
 	int (*apply)(struct omap_overlay_manager *mgr);
 	int (*wait_for_go)(struct omap_overlay_manager *mgr);
 	int (*wait_for_vsync)(struct omap_overlay_manager *mgr);
+
+	struct omap_dss_device *(*get_device)(struct omap_overlay_manager *mgr);
 };
 
 /* 22 pins means 1 clk lane and 10 data lanes */
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [PATCH v2 06/23] OMAP_VOUT: Remove manager->device references
  2012-08-30 11:52   ` Archit Taneja
@ 2012-08-30 11:52     ` Archit Taneja
  -1 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-08-30 11:40 UTC (permalink / raw)
  To: tomi.valkeinen
  Cc: rob, linux-omap, linux-fbdev, Archit Taneja, Vaibhav Hiremath

With the introduction of output entities, managers will now connect to outputs.
Use the helper op for managers named get_device. This will abstract away the
information on how to get the device from an overlay manager.

Using the helper function will reduce the number of pointer dereferences a user
of OMAPDSS needs to do and reduce risk of a NULL dereference.

Cc: Vaibhav Hiremath <hvaibhav@ti.com>
Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/media/video/omap/omap_vout.c |   81 ++++++++++++++++++++++++----------
 1 file changed, 57 insertions(+), 24 deletions(-)

diff --git a/drivers/media/video/omap/omap_vout.c b/drivers/media/video/omap/omap_vout.c
index 88cf9d9..0ebf87e 100644
--- a/drivers/media/video/omap/omap_vout.c
+++ b/drivers/media/video/omap/omap_vout.c
@@ -454,11 +454,16 @@ static int omapvid_init(struct omap_vout_device *vout, u32 addr)
 
 	win = &vout->win;
 	for (i = 0; i < ovid->num_overlays; i++) {
+		struct omap_dss_device *dssdev;
+
 		ovl = ovid->overlays[i];
-		if (!ovl->manager || !ovl->manager->device)
+		dssdev = ovl->manager ?
+			ovl->manager->get_device(ovl->manager) : NULL;
+
+		if (!dssdev)
 			return -EINVAL;
 
-		timing = &ovl->manager->device->panel.timings;
+		timing = &dssdev->panel.timings;
 
 		outw = win->w.width;
 		outh = win->w.height;
@@ -515,8 +520,12 @@ static int omapvid_apply_changes(struct omap_vout_device *vout)
 	struct omapvideo_info *ovid = &vout->vid_info;
 
 	for (i = 0; i < ovid->num_overlays; i++) {
+		struct omap_dss_device *dssdev;
+
 		ovl = ovid->overlays[i];
-		if (!ovl->manager || !ovl->manager->device)
+		dssdev = ovl->manager ?
+			ovl->manager->get_device(ovl->manager) : NULL;
+		if (!dssdev)
 			return -EINVAL;
 		ovl->manager->apply(ovl->manager);
 	}
@@ -579,12 +588,15 @@ static void omap_vout_isr(void *arg, unsigned int irqstatus)
 
 	ovid = &vout->vid_info;
 	ovl = ovid->overlays[0];
-	/* get the display device attached to the overlay */
-	if (!ovl->manager || !ovl->manager->device)
-		return;
 
 	mgr_id = ovl->manager->id;
-	cur_display = ovl->manager->device;
+
+	/* get the display device attached to the overlay */
+	cur_display = ovl->manager ?
+		ovl->manager->get_device(ovl->manager) : NULL;
+
+	if (!cur_display)
+		return;
 
 	spin_lock(&vout->vbq_lock);
 	do_gettimeofday(&timevalue);
@@ -948,7 +960,10 @@ static int omap_vout_release(struct file *file)
 	/* Disable all the overlay managers connected with this interface */
 	for (i = 0; i < ovid->num_overlays; i++) {
 		struct omap_overlay *ovl = ovid->overlays[i];
-		if (ovl->manager && ovl->manager->device)
+		struct omap_dss_device *dssdev = ovl->manager ?
+			ovl->manager->get_device(ovl->manager) : NULL;
+
+		if (dssdev)
 			ovl->disable(ovl);
 	}
 	/* Turn off the pipeline */
@@ -1081,14 +1096,17 @@ static int vidioc_try_fmt_vid_out(struct file *file, void *fh,
 	struct omapvideo_info *ovid;
 	struct omap_video_timings *timing;
 	struct omap_vout_device *vout = fh;
+	struct omap_dss_device *dssdev;
 
 	ovid = &vout->vid_info;
 	ovl = ovid->overlays[0];
+	/* get the display device attached to the overlay */
+	dssdev = ovl->manager ? ovl->manager->get_device(ovl->manager) : NULL;
 
-	if (!ovl->manager || !ovl->manager->device)
+	if (!dssdev)
 		return -EINVAL;
-	/* get the display device attached to the overlay */
-	timing = &ovl->manager->device->panel.timings;
+
+	timing = &dssdev->panel.timings;
 
 	vout->fbuf.fmt.height = timing->y_res;
 	vout->fbuf.fmt.width = timing->x_res;
@@ -1105,6 +1123,7 @@ static int vidioc_s_fmt_vid_out(struct file *file, void *fh,
 	struct omapvideo_info *ovid;
 	struct omap_video_timings *timing;
 	struct omap_vout_device *vout = fh;
+	struct omap_dss_device *dssdev;
 
 	if (vout->streaming)
 		return -EBUSY;
@@ -1113,13 +1132,14 @@ static int vidioc_s_fmt_vid_out(struct file *file, void *fh,
 
 	ovid = &vout->vid_info;
 	ovl = ovid->overlays[0];
+	dssdev = ovl->manager ? ovl->manager->get_device(ovl->manager) : NULL;
 
 	/* get the display device attached to the overlay */
-	if (!ovl->manager || !ovl->manager->device) {
+	if (!dssdev) {
 		ret = -EINVAL;
 		goto s_fmt_vid_out_exit;
 	}
-	timing = &ovl->manager->device->panel.timings;
+	timing = &dssdev->panel.timings;
 
 	/* We dont support RGB24-packed mode if vrfb rotation
 	 * is enabled*/
@@ -1298,6 +1318,7 @@ static int vidioc_s_crop(struct file *file, void *fh, struct v4l2_crop *crop)
 	struct omapvideo_info *ovid;
 	struct omap_overlay *ovl;
 	struct omap_video_timings *timing;
+	struct omap_dss_device *dssdev;
 
 	if (vout->streaming)
 		return -EBUSY;
@@ -1305,13 +1326,15 @@ static int vidioc_s_crop(struct file *file, void *fh, struct v4l2_crop *crop)
 	mutex_lock(&vout->lock);
 	ovid = &vout->vid_info;
 	ovl = ovid->overlays[0];
+	/* get the display device attached to the overlay */
+	dssdev = ovl->manager ? ovl->manager->get_device(ovl->manager) : NULL;
 
-	if (!ovl->manager || !ovl->manager->device) {
+	if (!dssdev) {
 		ret = -EINVAL;
 		goto s_crop_err;
 	}
-	/* get the display device attached to the overlay */
-	timing = &ovl->manager->device->panel.timings;
+
+	timing = &dssdev->panel.timings;
 
 	if (is_rotation_90_or_270(vout)) {
 		vout->fbuf.fmt.height = timing->x_res;
@@ -1666,8 +1689,9 @@ static int vidioc_streamon(struct file *file, void *fh, enum v4l2_buf_type i)
 
 	for (j = 0; j < ovid->num_overlays; j++) {
 		struct omap_overlay *ovl = ovid->overlays[j];
+		struct omap_overlay_manager *mgr = ovl->manager;
 
-		if (ovl->manager && ovl->manager->device) {
+		if (mgr && mgr->get_device(mgr)) {
 			struct omap_overlay_info info;
 			ovl->get_overlay_info(ovl, &info);
 			info.paddr = addr;
@@ -1690,8 +1714,10 @@ static int vidioc_streamon(struct file *file, void *fh, enum v4l2_buf_type i)
 
 	for (j = 0; j < ovid->num_overlays; j++) {
 		struct omap_overlay *ovl = ovid->overlays[j];
+		struct omap_dss_device *dssdev = ovl->manager ?
+			ovl->manager->get_device(ovl->manager) : NULL;
 
-		if (ovl->manager && ovl->manager->device) {
+		if (dssdev) {
 			ret = ovl->enable(ovl);
 			if (ret)
 				goto streamon_err1;
@@ -1726,8 +1752,10 @@ static int vidioc_streamoff(struct file *file, void *fh, enum v4l2_buf_type i)
 
 	for (j = 0; j < ovid->num_overlays; j++) {
 		struct omap_overlay *ovl = ovid->overlays[j];
+		struct omap_dss_device *dssdev = ovl->manager ?
+			ovl->manager->get_device(ovl->manager) : NULL;
 
-		if (ovl->manager && ovl->manager->device)
+		if (dssdev)
 			ovl->disable(ovl);
 	}
 
@@ -1890,8 +1918,9 @@ static int __init omap_vout_setup_video_data(struct omap_vout_device *vout)
 	struct video_device *vfd;
 	struct v4l2_pix_format *pix;
 	struct v4l2_control *control;
+	struct omap_overlay *ovl = vout->vid_info.overlays[0];
 	struct omap_dss_device *display =
-		vout->vid_info.overlays[0]->manager->device;
+		ovl->manager->get_device(ovl->manager);
 
 	/* set the default pix */
 	pix = &vout->pix;
@@ -2205,8 +2234,10 @@ static int __init omap_vout_probe(struct platform_device *pdev)
 	 */
 	for (i = 1; i < vid_dev->num_overlays; i++) {
 		ovl = omap_dss_get_overlay(i);
-		if (ovl->manager && ovl->manager->device) {
-			def_display = ovl->manager->device;
+		dssdev = ovl->manager ? ovl->manager->get_device(ovl->manager) :
+				NULL;
+		if (dssdev) {
+			def_display = dssdev;
 		} else {
 			dev_warn(&pdev->dev, "cannot find display\n");
 			def_display = NULL;
@@ -2253,8 +2284,10 @@ probe_err1:
 	for (i = 1; i < vid_dev->num_overlays; i++) {
 		def_display = NULL;
 		ovl = omap_dss_get_overlay(i);
-		if (ovl->manager && ovl->manager->device)
-			def_display = ovl->manager->device;
+		dssdev = ovl->manager ? ovl->manager->get_device(ovl->manager) :
+				NULL;
+		if (dssdev)
+			def_display = dssdev;
 
 		if (def_display && def_display->driver)
 			def_display->driver->disable(def_display);
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [PATCH v2 07/23] OMAPFB: remove manager->device references
  2012-08-30 11:52   ` Archit Taneja
@ 2012-08-30 11:52     ` Archit Taneja
  -1 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-08-30 11:40 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: rob, linux-omap, linux-fbdev, Archit Taneja

With the introduction of output entities, managers will now connect to outputs.
Use the helper op for managers named get_device. This will abstract away the
information on how to get the device from an overlay manager.

Using the helper function will reduce the number of pointer dereferences a user
of OMAPDSS needs to do and reduce risk of a NULL dereference.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/omapfb/omapfb-main.c |    7 +++++--
 drivers/video/omap2/omapfb/omapfb.h      |    5 +++--
 2 files changed, 8 insertions(+), 4 deletions(-)

diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c
index fc671d3..c6992be 100644
--- a/drivers/video/omap2/omapfb/omapfb-main.c
+++ b/drivers/video/omap2/omapfb/omapfb-main.c
@@ -2353,6 +2353,7 @@ static int __init omapfb_probe(struct platform_device *pdev)
 	struct omap_overlay *ovl;
 	struct omap_dss_device *def_display;
 	struct omap_dss_device *dssdev;
+	struct omap_dss_device *mgr_device;
 
 	DBG("omapfb_probe\n");
 
@@ -2426,8 +2427,10 @@ static int __init omapfb_probe(struct platform_device *pdev)
 	/* gfx overlay should be the default one. find a display
 	 * connected to that, and use it as default display */
 	ovl = omap_dss_get_overlay(0);
-	if (ovl->manager && ovl->manager->device) {
-		def_display = ovl->manager->device;
+	mgr_device = ovl->manager ?
+		ovl->manager->get_device(ovl->manager) : NULL;
+	if (mgr_device) {
+		def_display = mgr_device;
 	} else {
 		dev_warn(&pdev->dev, "cannot find default display\n");
 		def_display = NULL;
diff --git a/drivers/video/omap2/omapfb/omapfb.h b/drivers/video/omap2/omapfb/omapfb.h
index 30361a0..2782b1f 100644
--- a/drivers/video/omap2/omapfb/omapfb.h
+++ b/drivers/video/omap2/omapfb/omapfb.h
@@ -148,8 +148,9 @@ static inline struct omap_dss_device *fb2display(struct fb_info *fbi)
 
 	/* XXX: returns the display connected to first attached overlay */
 	for (i = 0; i < ofbi->num_overlays; i++) {
-		if (ofbi->overlays[i]->manager)
-			return ofbi->overlays[i]->manager->device;
+		struct omap_overlay_manager *mgr = ofbi->overlays[i]->manager;
+		if (mgr)
+			return mgr->get_device(mgr);
 	}
 
 	return NULL;
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [PATCH v2 08/23] OMAPDRM: Remove manager->device references
  2012-08-30 11:52   ` Archit Taneja
@ 2012-08-30 11:52     ` Archit Taneja
  -1 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-08-30 11:40 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: rob, linux-omap, linux-fbdev, Archit Taneja

With the introduction of output entities, managers will now connect to outputs.
Use the helper op for managers named get_device. This will abstract away the
information on how to get the device from an overlay manager.

Using the helper function will reduce the number of pointer dereferences a user
of OMAPDSS needs to do and reduce risk of a NULL dereference.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/staging/omapdrm/omap_drv.c |    5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/staging/omapdrm/omap_drv.c b/drivers/staging/omapdrm/omap_drv.c
index 4beab94..64a354a 100644
--- a/drivers/staging/omapdrm/omap_drv.c
+++ b/drivers/staging/omapdrm/omap_drv.c
@@ -106,7 +106,8 @@ static void dump_video_chains(void)
 	for (i = 0; i < omap_dss_get_num_overlays(); i++) {
 		struct omap_overlay *ovl = omap_dss_get_overlay(i);
 		struct omap_overlay_manager *mgr = ovl->manager;
-		struct omap_dss_device *dssdev = mgr ? mgr->device : NULL;
+		struct omap_dss_device *dssdev = mgr ?
+					mgr->get_device(mgr) : NULL;
 		if (dssdev) {
 			DBG("%d: %s -> %s -> %s", i, ovl->name, mgr->name,
 						dssdev->name);
@@ -185,7 +186,7 @@ static int create_connector(struct drm_device *dev,
 	for (j = 0; j < priv->num_encoders; j++) {
 		struct omap_overlay_manager *mgr =
 			omap_encoder_get_manager(priv->encoders[j]);
-		if (mgr->device == dssdev) {
+		if (mgr->get_device(mgr) == dssdev) {
 			drm_mode_connector_attach_encoder(connector,
 					priv->encoders[j]);
 		}
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [PATCH v2 09/23] OMAPDSS: Create links between managers, outputs and devices
  2012-08-30 11:52   ` Archit Taneja
@ 2012-08-30 11:52     ` Archit Taneja
  -1 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-08-30 11:40 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: rob, linux-omap, linux-fbdev, Archit Taneja

Links between DSS entities are made in dss_recheck_connections when a new panel
is probed. Rewrite the code in dss_recheck_connections to link managers to
outputs, and outputs to devices.

The fields in omap_dss_device struct gives information on which output and
manager to connect to. The desired manager and output pointers are retrieved and
prepared(existing outputs/devices unset, if default display)) to form the
desired links. The output is linked to the device, and then the manager to the
output. If a probed device's required manager isn't free, the required output
is still connected to the device so that it's easier to use the panel in the
future.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/dss/overlay.c |   96 +++++++++++++++++++++----------------
 1 file changed, 56 insertions(+), 40 deletions(-)

diff --git a/drivers/video/omap2/dss/overlay.c b/drivers/video/omap2/dss/overlay.c
index 952c6fa..07605f1 100644
--- a/drivers/video/omap2/dss/overlay.c
+++ b/drivers/video/omap2/dss/overlay.c
@@ -525,51 +525,67 @@ void dss_init_overlays(struct platform_device *pdev)
 void dss_recheck_connections(struct omap_dss_device *dssdev, bool force)
 {
 	int i;
-	struct omap_overlay_manager *lcd_mgr;
-	struct omap_overlay_manager *tv_mgr;
-	struct omap_overlay_manager *lcd2_mgr = NULL;
-	struct omap_overlay_manager *lcd3_mgr = NULL;
 	struct omap_overlay_manager *mgr = NULL;
+	struct omap_dss_output *out = NULL;
+	enum omap_dss_output_id id;
+
+	switch (dssdev->type) {
+	case OMAP_DISPLAY_TYPE_DPI:
+		out = omap_dss_get_output(OMAP_DSS_OUTPUT_DPI);
+		break;
+	case OMAP_DISPLAY_TYPE_DBI:
+		out = omap_dss_get_output(OMAP_DSS_OUTPUT_DBI);
+		break;
+	case OMAP_DISPLAY_TYPE_SDI:
+		out = omap_dss_get_output(OMAP_DSS_OUTPUT_SDI);
+		break;
+	case OMAP_DISPLAY_TYPE_VENC:
+		out = omap_dss_get_output(OMAP_DSS_OUTPUT_VENC);
+		break;
+	case OMAP_DISPLAY_TYPE_HDMI:
+		out = omap_dss_get_output(OMAP_DSS_OUTPUT_HDMI);
+		break;
+	case OMAP_DISPLAY_TYPE_DSI:
+		id = dssdev->phy.dsi.module == 0 ? OMAP_DSS_OUTPUT_DSI1 :
+					OMAP_DSS_OUTPUT_DSI2;
+		out = omap_dss_get_output(id);
+		break;
+	default:
+		break;
+	}
 
-	lcd_mgr = omap_dss_get_overlay_manager(OMAP_DSS_CHANNEL_LCD);
-	tv_mgr = omap_dss_get_overlay_manager(OMAP_DSS_CHANNEL_DIGIT);
-	if (dss_has_feature(FEAT_MGR_LCD3))
-		lcd3_mgr = omap_dss_get_overlay_manager(OMAP_DSS_CHANNEL_LCD3);
-	if (dss_has_feature(FEAT_MGR_LCD2))
-		lcd2_mgr = omap_dss_get_overlay_manager(OMAP_DSS_CHANNEL_LCD2);
-
-	if (dssdev->channel == OMAP_DSS_CHANNEL_LCD3) {
-		if (!lcd3_mgr->device || force) {
-			if (lcd3_mgr->device)
-				lcd3_mgr->unset_device(lcd3_mgr);
-			lcd3_mgr->set_device(lcd3_mgr, dssdev);
-			mgr = lcd3_mgr;
-		}
-	} else if (dssdev->channel == OMAP_DSS_CHANNEL_LCD2) {
-		if (!lcd2_mgr->device || force) {
-			if (lcd2_mgr->device)
-				lcd2_mgr->unset_device(lcd2_mgr);
-			lcd2_mgr->set_device(lcd2_mgr, dssdev);
-			mgr = lcd2_mgr;
-		}
-	} else if (dssdev->type != OMAP_DISPLAY_TYPE_VENC
-			&& dssdev->type != OMAP_DISPLAY_TYPE_HDMI) {
-		if (!lcd_mgr->device || force) {
-			if (lcd_mgr->device)
-				lcd_mgr->unset_device(lcd_mgr);
-			lcd_mgr->set_device(lcd_mgr, dssdev);
-			mgr = lcd_mgr;
-		}
+	/*
+	 * We don't want to touch board files and mention channel for VENC
+	 * devices. Force the channel as DIGIT for HDMI and VENC devices
+	 */
+	if (dssdev->type == OMAP_DISPLAY_TYPE_VENC ||
+			dssdev->type == OMAP_DISPLAY_TYPE_HDMI)
+		dssdev->channel = OMAP_DSS_CHANNEL_DIGIT;
+
+	mgr = omap_dss_get_overlay_manager(dssdev->channel);
+
+	if (!mgr || !out) {
+		DSSERR("Incorrect manager or output\n");
+		return;
 	}
 
-	if (dssdev->type == OMAP_DISPLAY_TYPE_VENC
-			|| dssdev->type == OMAP_DISPLAY_TYPE_HDMI) {
-		if (!tv_mgr->device || force) {
-			if (tv_mgr->device)
-				tv_mgr->unset_device(tv_mgr);
-			tv_mgr->set_device(tv_mgr, dssdev);
-			mgr = tv_mgr;
+	if (!mgr->output || force) {
+		struct omap_dss_output *curr_out = mgr->output;
+
+		if (curr_out) {
+			if (curr_out->device)
+				curr_out->unset_device(curr_out);
+			mgr->unset_output(mgr);
 		}
+		out->set_device(out, dssdev);
+		mgr->set_output(mgr, out);
+	} else {
+		/*
+		 * connect a floating output to the device even if the desired
+		 * manager is in use
+		 */
+		if (!out->manager && !out->device)
+			out->set_device(out, dssdev);
 	}
 
 	if (mgr) {
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [PATCH v2 10/23] OMAPDSS: DPI: Pass omap_dss_output within the driver
  2012-08-30 11:52   ` Archit Taneja
@ 2012-08-30 11:52     ` Archit Taneja
  -1 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-08-30 11:40 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: rob, linux-omap, linux-fbdev, Archit Taneja

When a panel driver calls a DPI function, it passes the omap_dss_device
pointer, this pointer currently propagates within the DPI driver to configure
the interface.

Extract the omap_dss_output pointer from omap_dss_device received from the panel
driver, pass the output pointer to DPI functions local to the driver to
configure the interface, these functions no longer need omap_dss_device since
the driver now maintains a copy of output parameters.

Replace dssdev->manager references with out->manager references as only these
will be valid later.

With the addition of outputs. There is a possibility that an omap_dss_device
isn't connected to an output, or a manager isn't connected to an output yet.
Ensure that the DPI interface functions proceed only if the output is non NULL.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/dss/dpi.c |   55 +++++++++++++++++++++++++----------------
 1 file changed, 34 insertions(+), 21 deletions(-)

diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c
index 9a7aee5..cb17adb 100644
--- a/drivers/video/omap2/dss/dpi.c
+++ b/drivers/video/omap2/dss/dpi.c
@@ -73,7 +73,7 @@ static bool dpi_use_dsi_pll(struct omap_dss_device *dssdev)
 		return false;
 }
 
-static int dpi_set_dsi_clk(struct omap_dss_device *dssdev,
+static int dpi_set_dsi_clk(struct omap_dss_output *out,
 		unsigned long pck_req, unsigned long *fck, int *lck_div,
 		int *pck_div)
 {
@@ -90,7 +90,7 @@ static int dpi_set_dsi_clk(struct omap_dss_device *dssdev,
 	if (r)
 		return r;
 
-	dss_select_dispc_clk_source(dssdev->clocks.dispc.dispc_fclk_src);
+	dss_select_dispc_clk_source(out->device->clocks.dispc.dispc_fclk_src);
 
 	dpi.mgr_config.clock_info = dispc_cinfo;
 
@@ -101,7 +101,7 @@ static int dpi_set_dsi_clk(struct omap_dss_device *dssdev,
 	return 0;
 }
 
-static int dpi_set_dispc_clk(struct omap_dss_device *dssdev,
+static int dpi_set_dispc_clk(struct omap_dss_output *out,
 		unsigned long pck_req, unsigned long *fck, int *lck_div,
 		int *pck_div)
 {
@@ -126,7 +126,7 @@ static int dpi_set_dispc_clk(struct omap_dss_device *dssdev,
 	return 0;
 }
 
-static int dpi_set_mode(struct omap_dss_device *dssdev)
+static int dpi_set_mode(struct omap_dss_output *out)
 {
 	struct omap_video_timings *t = &dpi.timings;
 	int lck_div = 0, pck_div = 0;
@@ -134,11 +134,11 @@ static int dpi_set_mode(struct omap_dss_device *dssdev)
 	unsigned long pck;
 	int r = 0;
 
-	if (dpi_use_dsi_pll(dssdev))
-		r = dpi_set_dsi_clk(dssdev, t->pixel_clock * 1000, &fck,
+	if (dpi_use_dsi_pll(out->device))
+		r = dpi_set_dsi_clk(out, t->pixel_clock * 1000, &fck,
 				&lck_div, &pck_div);
 	else
-		r = dpi_set_dispc_clk(dssdev, t->pixel_clock * 1000, &fck,
+		r = dpi_set_dispc_clk(out, t->pixel_clock * 1000, &fck,
 				&lck_div, &pck_div);
 	if (r)
 		return r;
@@ -153,12 +153,12 @@ static int dpi_set_mode(struct omap_dss_device *dssdev)
 		t->pixel_clock = pck;
 	}
 
-	dss_mgr_set_timings(dssdev->manager, t);
+	dss_mgr_set_timings(out->manager, t);
 
 	return 0;
 }
 
-static void dpi_config_lcd_manager(struct omap_dss_device *dssdev)
+static void dpi_config_lcd_manager(struct omap_dss_output *out)
 {
 	dpi.mgr_config.io_pad_mode = DSS_IO_PAD_MODE_BYPASS;
 
@@ -169,11 +169,12 @@ static void dpi_config_lcd_manager(struct omap_dss_device *dssdev)
 
 	dpi.mgr_config.lcden_sig_polarity = 0;
 
-	dss_mgr_set_lcd_config(dssdev->manager, &dpi.mgr_config);
+	dss_mgr_set_lcd_config(out->manager, &dpi.mgr_config);
 }
 
 int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
 {
+	struct omap_dss_output *out = dssdev->output;
 	int r;
 
 	mutex_lock(&dpi.lock);
@@ -184,10 +185,10 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
 		goto err_no_reg;
 	}
 
-	if (dssdev->manager == NULL) {
-		DSSERR("failed to enable display: no manager\n");
+	if (out == NULL || out->manager == NULL) {
+		DSSERR("failed to enable display: no output/manager\n");
 		r = -ENODEV;
-		goto err_no_mgr;
+		goto err_no_out_mgr;
 	}
 
 	r = omap_dss_start_device(dssdev);
@@ -216,15 +217,15 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
 			goto err_dsi_pll_init;
 	}
 
-	r = dpi_set_mode(dssdev);
+	r = dpi_set_mode(out);
 	if (r)
 		goto err_set_mode;
 
-	dpi_config_lcd_manager(dssdev);
+	dpi_config_lcd_manager(out);
 
 	mdelay(2);
 
-	r = dss_mgr_enable(dssdev->manager);
+	r = dss_mgr_enable(out->manager);
 	if (r)
 		goto err_mgr_enable;
 
@@ -247,7 +248,7 @@ err_get_dispc:
 err_reg_enable:
 	omap_dss_stop_device(dssdev);
 err_start_dev:
-err_no_mgr:
+err_no_out_mgr:
 err_no_reg:
 	mutex_unlock(&dpi.lock);
 	return r;
@@ -256,9 +257,11 @@ EXPORT_SYMBOL(omapdss_dpi_display_enable);
 
 void omapdss_dpi_display_disable(struct omap_dss_device *dssdev)
 {
+	struct omap_dss_output *out = dssdev->output;
+
 	mutex_lock(&dpi.lock);
 
-	dss_mgr_disable(dssdev->manager);
+	dss_mgr_disable(out->manager);
 
 	if (dpi_use_dsi_pll(dssdev)) {
 		dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK);
@@ -280,10 +283,16 @@ EXPORT_SYMBOL(omapdss_dpi_display_disable);
 void omapdss_dpi_set_timings(struct omap_dss_device *dssdev,
 		struct omap_video_timings *timings)
 {
+	struct omap_dss_output *out = dssdev->output;
 	int r;
 
 	DSSDBG("dpi_set_timings\n");
 
+	if (out == NULL) {
+		DSSERR("No output connected to %s\n", dssdev->name);
+		return;
+	}
+
 	mutex_lock(&dpi.lock);
 
 	dpi.timings = *timings;
@@ -293,11 +302,11 @@ void omapdss_dpi_set_timings(struct omap_dss_device *dssdev,
 		if (r)
 			return;
 
-		dpi_set_mode(dssdev);
+		dpi_set_mode(out);
 
 		dispc_runtime_put();
 	} else {
-		dss_mgr_set_timings(dssdev->manager, timings);
+		dss_mgr_set_timings(out->manager, timings);
 	}
 
 	mutex_unlock(&dpi.lock);
@@ -312,8 +321,12 @@ int dpi_check_timings(struct omap_dss_device *dssdev,
 	unsigned long fck;
 	unsigned long pck;
 	struct dispc_clock_info dispc_cinfo;
+	struct omap_dss_output *out = dssdev->output;
+
+	if (out == NULL)
+		return -ENODEV;
 
-	if (dss_mgr_check_timings(dssdev->manager, timings))
+	if (dss_mgr_check_timings(out->manager, timings))
 		return -EINVAL;
 
 	if (timings->pixel_clock == 0)
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [PATCH v2 11/23] OMAPDSS: DSI: Remove dsi_pdev_map global struct
  2012-08-30 11:52   ` Archit Taneja
@ 2012-08-30 11:52     ` Archit Taneja
  -1 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-08-30 11:40 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: rob, linux-omap, linux-fbdev, Archit Taneja

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 6a83ab7..78212c4 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -346,8 +346,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);
@@ -360,12 +358,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,
@@ -4933,7 +4938,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	[flat|nested] 148+ messages in thread

* [PATCH v2 12/23] OMAPDSS: DSI: Pass omap_dss_output within the driver
  2012-08-30 11:52   ` Archit Taneja
@ 2012-08-30 11:52     ` Archit Taneja
  -1 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-08-30 11:40 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: rob, linux-omap, linux-fbdev, Archit Taneja

When a panel driver calls a DSI function, it passes the omap_dss_device
pointer, this pointer currently propagates within the DSI driver to configure
the interface.

Extract the omap_dss_output pointer from omap_dss_device received from the panel
driver, pass the output pointer to DSI functions local to the driver to
configure the interface, these functions no longer need omap_dss_device since
the driver now maintains a copy of output parameters.

Replace dssdev->manager references with out->manager references as only these
will be valid later.

With the addition of outputs. There is a possibility that an omap_dss_device
isn't connected to an output, or a manager isn't connected to an output yet.
Ensure that the DSI interface functions proceed only if the output is non NULL.

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

diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index 78212c4..228510f 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -356,9 +356,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)
@@ -391,7 +391,8 @@ static inline u32 dsi_read_reg(struct platform_device *dsidev,
 
 void dsi_bus_lock(struct omap_dss_device *dssdev)
 {
-	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+	struct omap_dss_output *out = dssdev->output;
+	struct platform_device *dsidev = dsi_get_dsidev_from_output(out);
 	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
 
 	down(&dsi->bus_lock);
@@ -400,7 +401,8 @@ EXPORT_SYMBOL(dsi_bus_lock);
 
 void dsi_bus_unlock(struct omap_dss_device *dssdev)
 {
-	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+	struct omap_dss_output *out = dssdev->output;
+	struct platform_device *dsidev = dsi_get_dsidev_from_output(out);
 	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
 
 	up(&dsi->bus_lock);
@@ -1205,15 +1207,15 @@ 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);
 	unsigned long dsi_fclk;
 	unsigned lp_clk_div;
 	unsigned long lp_clk;
 
-	lp_clk_div = dssdev->clocks.dsi.lp_clk_div;
+	lp_clk_div = out->device->clocks.dsi.lp_clk_div;
 
 	if (lp_clk_div == 0 || lp_clk_div > dsi->lpdiv_max)
 		return -EINVAL;
@@ -2689,7 +2691,8 @@ static int dsi_vc_config_source(struct platform_device *dsidev, int channel,
 void omapdss_dsi_vc_enable_hs(struct omap_dss_device *dssdev, int channel,
 		bool enable)
 {
-	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+	struct omap_dss_output *out = dssdev->output;
+	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);
@@ -2817,7 +2820,8 @@ static int dsi_vc_send_bta(struct platform_device *dsidev, int channel)
 
 int dsi_vc_send_bta_sync(struct omap_dss_device *dssdev, int channel)
 {
-	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+	struct omap_dss_output *out = dssdev->output;
+	struct platform_device *dsidev = dsi_get_dsidev_from_output(out);
 	DECLARE_COMPLETION_ONSTACK(completion);
 	int r = 0;
 	u32 err;
@@ -2986,7 +2990,8 @@ static int dsi_vc_send_short(struct platform_device *dsidev, int channel,
 
 int dsi_vc_send_null(struct omap_dss_device *dssdev, int channel)
 {
-	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+	struct omap_dss_output *out = dssdev->output;
+	struct platform_device *dsidev = dsi_get_dsidev_from_output(out);
 
 	return dsi_vc_send_long(dsidev, channel, MIPI_DSI_NULL_PACKET, NULL,
 		0, 0);
@@ -3026,7 +3031,8 @@ static int dsi_vc_write_nosync_common(struct platform_device *dsidev,
 int dsi_vc_dcs_write_nosync(struct omap_dss_device *dssdev, int channel,
 		u8 *data, int len)
 {
-	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+	struct omap_dss_output *out = dssdev->output;
+	struct platform_device *dsidev = dsi_get_dsidev_from_output(out);
 
 	return dsi_vc_write_nosync_common(dsidev, channel, data, len,
 			DSS_DSI_CONTENT_DCS);
@@ -3036,24 +3042,25 @@ EXPORT_SYMBOL(dsi_vc_dcs_write_nosync);
 int dsi_vc_generic_write_nosync(struct omap_dss_device *dssdev, int channel,
 		u8 *data, int len)
 {
-	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+	struct omap_dss_output *out = dssdev->output;
+	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->device, channel);
 	if (r)
 		goto err;
 
@@ -3075,7 +3082,9 @@ err:
 int dsi_vc_dcs_write(struct omap_dss_device *dssdev, int channel, u8 *data,
 		int len)
 {
-	return dsi_vc_write_common(dssdev, channel, data, len,
+	struct omap_dss_output *out = dssdev->output;
+
+	return dsi_vc_write_common(out, channel, data, len,
 			DSS_DSI_CONTENT_DCS);
 }
 EXPORT_SYMBOL(dsi_vc_dcs_write);
@@ -3083,7 +3092,9 @@ EXPORT_SYMBOL(dsi_vc_dcs_write);
 int dsi_vc_generic_write(struct omap_dss_device *dssdev, int channel, u8 *data,
 		int len)
 {
-	return dsi_vc_write_common(dssdev, channel, data, len,
+	struct omap_dss_output *out = dssdev->output;
+
+	return dsi_vc_write_common(out, channel, data, len,
 			DSS_DSI_CONTENT_GENERIC);
 }
 EXPORT_SYMBOL(dsi_vc_generic_write);
@@ -3295,7 +3306,8 @@ err:
 int dsi_vc_dcs_read(struct omap_dss_device *dssdev, int channel, u8 dcs_cmd,
 		u8 *buf, int buflen)
 {
-	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+	struct omap_dss_output *out = dssdev->output;
+	struct platform_device *dsidev = dsi_get_dsidev_from_output(out);
 	int r;
 
 	r = dsi_vc_dcs_send_read_request(dsidev, channel, dcs_cmd);
@@ -3323,17 +3335,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->device, channel);
 	if (r)
 		return r;
 
@@ -3353,9 +3365,10 @@ static int dsi_vc_generic_read(struct omap_dss_device *dssdev, int channel,
 int dsi_vc_generic_read_0(struct omap_dss_device *dssdev, int channel, u8 *buf,
 		int buflen)
 {
+	struct omap_dss_output *out = dssdev->output;
 	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;
@@ -3368,9 +3381,10 @@ EXPORT_SYMBOL(dsi_vc_generic_read_0);
 int dsi_vc_generic_read_1(struct omap_dss_device *dssdev, int channel, u8 param,
 		u8 *buf, int buflen)
 {
+	struct omap_dss_output *out = dssdev->output;
 	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;
@@ -3383,13 +3397,14 @@ EXPORT_SYMBOL(dsi_vc_generic_read_1);
 int dsi_vc_generic_read_2(struct omap_dss_device *dssdev, int channel,
 		u8 param1, u8 param2, u8 *buf, int buflen)
 {
+	struct omap_dss_output *out = dssdev->output;
 	int r;
 	u8 reqdata[2];
 
 	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;
@@ -3402,7 +3417,8 @@ EXPORT_SYMBOL(dsi_vc_generic_read_2);
 int dsi_vc_set_max_rx_packet_size(struct omap_dss_device *dssdev, int channel,
 		u16 len)
 {
-	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+	struct omap_dss_output *out = dssdev->output;
+	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);
@@ -3738,10 +3754,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;
@@ -3856,9 +3873,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;
@@ -3916,7 +3933,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);
@@ -4042,7 +4059,8 @@ static void dsi_proto_timings(struct platform_device *dsidev)
 int omapdss_dsi_configure_pins(struct omap_dss_device *dssdev,
 		const struct omap_dsi_pin_config *pin_cfg)
 {
-	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+	struct omap_dss_output *out = dssdev->output;
+	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;
@@ -4109,7 +4127,8 @@ EXPORT_SYMBOL(omapdss_dsi_configure_pins);
 
 int dsi_enable_video_output(struct omap_dss_device *dssdev, int channel)
 {
-	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+	struct omap_dss_output *out = dssdev->output;
+	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;
@@ -4150,7 +4169,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);
@@ -4166,7 +4185,8 @@ EXPORT_SYMBOL(dsi_enable_video_output);
 
 void dsi_disable_video_output(struct omap_dss_device *dssdev, int channel)
 {
-	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+	struct omap_dss_output *out = dssdev->output;
+	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) {
@@ -4180,13 +4200,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;
@@ -4249,9 +4269,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
@@ -4325,7 +4345,8 @@ static void dsi_framedone_irq_callback(void *data, u32 mask)
 int omap_dsi_update(struct omap_dss_device *dssdev, int channel,
 		void (*callback)(int, void *), void *data)
 {
-	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+	struct omap_dss_output *out = dssdev->output;
+	struct platform_device *dsidev = dsi_get_dsidev_from_output(out);
 	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
 	u16 dw, dh;
 
@@ -4343,7 +4364,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;
 }
@@ -4351,10 +4372,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;
@@ -4375,10 +4397,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;
 
@@ -4390,7 +4413,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);
@@ -4417,9 +4440,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;
 
@@ -4428,7 +4451,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:
@@ -4439,24 +4462,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;
 
@@ -4479,23 +4503,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");
@@ -4507,12 +4533,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;
 
@@ -4530,7 +4556,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);
@@ -4538,11 +4564,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);
@@ -4556,29 +4583,33 @@ 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)
 {
-	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
-	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
+	struct omap_dss_output *out = dssdev->output;
+	struct platform_device *dsidev;
+	struct dsi_data *dsi;
 	int r = 0;
 
 	DSSDBG("dsi_display_enable\n");
 
+	if (out == NULL || out->manager == NULL) {
+		DSSERR("failed to enable display: no output/manager\n");
+		r = -ENODEV;
+		goto err_no_out_mgr;
+	}
+
+	dsidev = dsi_get_dsidev_from_output(out);
+	dsi = dsi_get_dsidrv_data(dsidev);
+
 	WARN_ON(!dsi_bus_is_locked(dsidev));
 
 	mutex_lock(&dsi->lock);
 
-	if (dssdev->manager == NULL) {
-		DSSERR("failed to enable display: no manager\n");
-		r = -ENODEV;
-		goto err_start_dev;
-	}
-
 	r = omap_dss_start_device(dssdev);
 	if (r) {
 		DSSERR("failed to start device\n");
@@ -4593,11 +4624,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;
 
@@ -4606,7 +4637,7 @@ 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);
@@ -4614,6 +4645,7 @@ err_get_dsi:
 	omap_dss_stop_device(dssdev);
 err_start_dev:
 	mutex_unlock(&dsi->lock);
+err_no_out_mgr:
 	DSSDBG("dsi_display_enable FAILED\n");
 	return r;
 }
@@ -4622,7 +4654,8 @@ EXPORT_SYMBOL(omapdss_dsi_display_enable);
 void omapdss_dsi_display_disable(struct omap_dss_device *dssdev,
 		bool disconnect_lanes, bool enter_ulps)
 {
-	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+	struct omap_dss_output *out = dssdev->output;
+	struct platform_device *dsidev = dsi_get_dsidev_from_output(out);
 	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
 
 	DSSDBG("dsi_display_disable\n");
@@ -4636,9 +4669,9 @@ 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);
@@ -4651,7 +4684,8 @@ EXPORT_SYMBOL(omapdss_dsi_display_disable);
 
 int omapdss_dsi_enable_te(struct omap_dss_device *dssdev, bool enable)
 {
-	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+	struct omap_dss_output *out = dssdev->output;
+	struct platform_device *dsidev = dsi_get_dsidev_from_output(out);
 	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
 
 	dsi->te_enabled = enable;
@@ -4662,7 +4696,8 @@ EXPORT_SYMBOL(omapdss_dsi_enable_te);
 void omapdss_dsi_set_timings(struct omap_dss_device *dssdev,
 		struct omap_video_timings *timings)
 {
-	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+	struct omap_dss_output *out = dssdev->output;
+	struct platform_device *dsidev = dsi_get_dsidev_from_output(out);
 	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
 
 	mutex_lock(&dsi->lock);
@@ -4675,7 +4710,8 @@ EXPORT_SYMBOL(omapdss_dsi_set_timings);
 
 void omapdss_dsi_set_size(struct omap_dss_device *dssdev, u16 w, u16 h)
 {
-	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+	struct omap_dss_output *out = dssdev->output;
+	struct platform_device *dsidev = dsi_get_dsidev_from_output(out);
 	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
 
 	mutex_lock(&dsi->lock);
@@ -4690,7 +4726,8 @@ EXPORT_SYMBOL(omapdss_dsi_set_size);
 void omapdss_dsi_set_pixel_format(struct omap_dss_device *dssdev,
 		enum omap_dss_dsi_pixel_format fmt)
 {
-	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+	struct omap_dss_output *out = dssdev->output;
+	struct platform_device *dsidev = dsi_get_dsidev_from_output(out);
 	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
 
 	mutex_lock(&dsi->lock);
@@ -4704,7 +4741,8 @@ EXPORT_SYMBOL(omapdss_dsi_set_pixel_format);
 void omapdss_dsi_set_operation_mode(struct omap_dss_device *dssdev,
 		enum omap_dss_dsi_mode mode)
 {
-	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+	struct omap_dss_output *out = dssdev->output;
+	struct platform_device *dsidev = dsi_get_dsidev_from_output(out);
 	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
 
 	mutex_lock(&dsi->lock);
@@ -4718,7 +4756,8 @@ EXPORT_SYMBOL(omapdss_dsi_set_operation_mode);
 void omapdss_dsi_set_videomode_timings(struct omap_dss_device *dssdev,
 		struct omap_dss_dsi_videomode_timings *timings)
 {
-	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+	struct omap_dss_output *out = dssdev->output;
+	struct platform_device *dsidev = dsi_get_dsidev_from_output(out);
 	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
 
 	mutex_lock(&dsi->lock);
@@ -4731,7 +4770,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");
@@ -4759,7 +4799,8 @@ static int __init dsi_init_display(struct omap_dss_device *dssdev)
 
 int omap_dsi_request_vc(struct omap_dss_device *dssdev, int *channel)
 {
-	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+	struct omap_dss_output *out = dssdev->output;
+	struct platform_device *dsidev = dsi_get_dsidev_from_output(out);
 	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
 	int i;
 
@@ -4778,7 +4819,8 @@ EXPORT_SYMBOL(omap_dsi_request_vc);
 
 int omap_dsi_set_vc_id(struct omap_dss_device *dssdev, int channel, int vc_id)
 {
-	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+	struct omap_dss_output *out = dssdev->output;
+	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) {
@@ -4805,7 +4847,8 @@ EXPORT_SYMBOL(omap_dsi_set_vc_id);
 
 void omap_dsi_release_vc(struct omap_dss_device *dssdev, int channel)
 {
-	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+	struct omap_dss_output *out = dssdev->output;
+	struct platform_device *dsidev = dsi_get_dsidev_from_output(out);
 	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
 
 	if ((channel >= 0 && channel <= 3) &&
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [PATCH v2 13/23] OMAPDSS: SDI: Pass omap_dss_output within the driver
  2012-08-30 11:52   ` Archit Taneja
@ 2012-08-30 11:52     ` Archit Taneja
  -1 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-08-30 11:40 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: rob, linux-omap, linux-fbdev, Archit Taneja

When a panel driver calls a SDI function, it passes the omap_dss_device
pointer, this pointer currently propagates within the SDI driver to configure
the interface.

Extract the omap_dss_output pointer from omap_dss_device received from the panel
driver, pass the output pointer to SDI functions local to the driver to
configure the interface, these functions no longer need omap_dss_device since
the driver now maintains a copy of output parameters.

Replace dssdev->manager references with out->manager references as only these
will be valid later.

With the addition of outputs. There is a possibility that an omap_dss_device
isn't connected to an output, or a manager isn't connected to an output yet.
Ensure that the SDI interface functions proceed only if the output is non NULL.

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

diff --git a/drivers/video/omap2/dss/sdi.c b/drivers/video/omap2/dss/sdi.c
index d8879f3..24f9ba0 100644
--- a/drivers/video/omap2/dss/sdi.c
+++ b/drivers/video/omap2/dss/sdi.c
@@ -40,7 +40,7 @@ static struct {
 	struct omap_dss_output output;
 } 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;
 
@@ -50,19 +50,20 @@ 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)
 {
+	struct omap_dss_output *out = dssdev->output;
 	struct omap_video_timings *t = &sdi.timings;
 	struct dss_clock_info dss_cinfo;
 	struct dispc_clock_info dispc_cinfo;
 	unsigned long pck;
 	int r;
 
-	if (dssdev->manager == NULL) {
-		DSSERR("failed to enable display: no manager\n");
+	if (out == NULL || out->manager == NULL) {
+		DSSERR("failed to enable display: no output/manager\n");
 		return -ENODEV;
 	}
 
@@ -100,14 +101,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);
 
@@ -116,7 +116,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;
 
@@ -139,7 +139,9 @@ EXPORT_SYMBOL(omapdss_sdi_display_enable);
 
 void omapdss_sdi_display_disable(struct omap_dss_device *dssdev)
 {
-	dss_mgr_disable(dssdev->manager);
+	struct omap_dss_output *out = dssdev->output;
+
+	dss_mgr_disable(out->manager);
 
 	dss_sdi_disable();
 
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [PATCH v2 14/23] OMAPDSS: RFBI: Pass omap_dss_output within the driver
  2012-08-30 11:52   ` Archit Taneja
@ 2012-08-30 11:52     ` Archit Taneja
  -1 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-08-30 11:40 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: rob, linux-omap, linux-fbdev, Archit Taneja

When a panel driver calls a RFBI function, it passes the omap_dss_device
pointer, this pointer currently propagates within the RFBI driver to configure
the interface.

Extract the omap_dss_output pointer from omap_dss_device received from the panel
driver, pass the output pointer to RFBI functions local to the driver to
configure the interface, these functions no longer need omap_dss_device since
the driver now maintains a copy of output parameters.

Replace dssdev->manager references with out->manager references as only these
will be valid later.

With the addition of outputs. There is a possibility that an omap_dss_device
isn't connected to an output, or a manager isn't connected to an output yet.
Ensure that the RFBI interface functions proceed only if the output is non NULL.

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

diff --git a/drivers/video/omap2/dss/rfbi.c b/drivers/video/omap2/dss/rfbi.c
index 3450f51..545e14f 100644
--- a/drivers/video/omap2/dss/rfbi.c
+++ b/drivers/video/omap2/dss/rfbi.c
@@ -307,11 +307,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;
 
@@ -320,9 +321,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;
 
@@ -779,7 +780,9 @@ EXPORT_SYMBOL(omap_rfbi_configure);
 int omap_rfbi_update(struct omap_dss_device *dssdev, void (*callback)(void *),
 		void *data)
 {
-	return rfbi_transfer_area(dssdev, callback, data);
+	struct omap_dss_output *out = dssdev->output;
+
+	return rfbi_transfer_area(out, callback, data);
 }
 EXPORT_SYMBOL(omap_rfbi_update);
 
@@ -849,7 +852,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;
 
@@ -862,7 +865,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
@@ -883,15 +886,16 @@ 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)
 {
+	struct omap_dss_output *out = dssdev->output;
 	int r;
 
-	if (dssdev->manager == NULL) {
-		DSSERR("failed to enable display: no manager\n");
+	if (out == NULL || out->manager == NULL) {
+		DSSERR("failed to enable display: no output/manager\n");
 		return -ENODEV;
 	}
 
@@ -912,7 +916,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);
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [PATCH v2 15/23] OMAPDSS: RFBI: Add dssdev pointers as arguments to all exported functions
  2012-08-30 11:52   ` Archit Taneja
@ 2012-08-30 11:52     ` Archit Taneja
  -1 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-08-30 11:40 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: rob, linux-omap, linux-fbdev, Archit Taneja

All functions of an interface driver used by a panel driver should have an
omap_dss_device 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 dssdev 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 |   55 ++++++++++++++++-------------
 drivers/video/omap2/dss/rfbi.c            |   25 +++++++------
 include/video/omapdss.h                   |   25 +++++++------
 3 files changed, 60 insertions(+), 45 deletions(-)

diff --git a/drivers/video/omap2/displays/panel-n8x0.c b/drivers/video/omap2/displays/panel-n8x0.c
index 17ae85e..e3a8c44 100644
--- a/drivers/video/omap2/displays/panel-n8x0.c
+++ b/drivers/video/omap2/displays/panel-n8x0.c
@@ -88,27 +88,30 @@ 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, &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);
+	omap_rfbi_write_command(dssdev, &cmd, 1);
+	omap_rfbi_write_data(dssdev, 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);
+	omap_rfbi_write_command(dssdev, &cmd, 1);
+	omap_rfbi_read_data(dssdev, 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;
 }
 
@@ -155,7 +158,7 @@ static void blizzard_ctrl_setup_update(struct omap_dss_device *dssdev,
 
 	omap_rfbi_configure(dssdev);
 
-	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(dssdev, 16);
 	omapdss_rfbi_set_data_lines(dssdev, 16);
@@ -313,8 +316,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,11 +539,11 @@ static int n8x0_panel_enable(struct omap_dss_device *dssdev)
 
 	mutex_lock(&ddata->lock);
 
-	rfbi_bus_lock();
+	rfbi_bus_lock(dssdev);
 
 	r = n8x0_panel_power_on(dssdev);
 
-	rfbi_bus_unlock();
+	rfbi_bus_unlock(dssdev);
 
 	if (r) {
 		mutex_unlock(&ddata->lock);
@@ -562,11 +565,11 @@ static void n8x0_panel_disable(struct omap_dss_device *dssdev)
 
 	mutex_lock(&ddata->lock);
 
-	rfbi_bus_lock();
+	rfbi_bus_lock(dssdev);
 
 	n8x0_panel_power_off(dssdev);
 
-	rfbi_bus_unlock();
+	rfbi_bus_unlock(dssdev);
 
 	dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
 
@@ -581,11 +584,11 @@ static int n8x0_panel_suspend(struct omap_dss_device *dssdev)
 
 	mutex_lock(&ddata->lock);
 
-	rfbi_bus_lock();
+	rfbi_bus_lock(dssdev);
 
 	n8x0_panel_power_off(dssdev);
 
-	rfbi_bus_unlock();
+	rfbi_bus_unlock(dssdev);
 
 	dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
 
@@ -603,11 +606,11 @@ static int n8x0_panel_resume(struct omap_dss_device *dssdev)
 
 	mutex_lock(&ddata->lock);
 
-	rfbi_bus_lock();
+	rfbi_bus_lock(dssdev);
 
 	r = n8x0_panel_power_on(dssdev);
 
-	rfbi_bus_unlock();
+	rfbi_bus_unlock(dssdev);
 
 	if (r) {
 		mutex_unlock(&ddata->lock);
@@ -630,7 +633,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);
 }
 
 static int n8x0_panel_update(struct omap_dss_device *dssdev,
@@ -651,7 +656,7 @@ static int n8x0_panel_update(struct omap_dss_device *dssdev,
 	}
 
 	mutex_lock(&ddata->lock);
-	rfbi_bus_lock();
+	rfbi_bus_lock(dssdev);
 
 	blizzard_ctrl_setup_update(dssdev, x, y, w, h);
 
@@ -669,8 +674,8 @@ static int n8x0_panel_sync(struct omap_dss_device *dssdev)
 	dev_dbg(&dssdev->dev, "sync\n");
 
 	mutex_lock(&ddata->lock);
-	rfbi_bus_lock();
-	rfbi_bus_unlock();
+	rfbi_bus_lock(dssdev);
+	rfbi_bus_unlock(dssdev);
 	mutex_unlock(&ddata->lock);
 
 	return 0;
diff --git a/drivers/video/omap2/dss/rfbi.c b/drivers/video/omap2/dss/rfbi.c
index 545e14f..b9d5b96 100644
--- a/drivers/video/omap2/dss/rfbi.c
+++ b/drivers/video/omap2/dss/rfbi.c
@@ -151,19 +151,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_device *dssdev)
 {
 	down(&rfbi.bus_lock);
 }
 EXPORT_SYMBOL(rfbi_bus_lock);
 
-void rfbi_bus_unlock(void)
+void rfbi_bus_unlock(struct omap_dss_device *dssdev)
 {
 	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_device *dssdev, const void *buf,
+		u32 len)
 {
 	switch (rfbi.parallelmode) {
 	case OMAP_DSS_RFBI_PARALLELMODE_8:
@@ -191,7 +192,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_device *dssdev, void *buf, u32 len)
 {
 	switch (rfbi.parallelmode) {
 	case OMAP_DSS_RFBI_PARALLELMODE_8:
@@ -223,7 +224,8 @@ 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_device *dssdev, const void *buf,
+		u32 len)
 {
 	switch (rfbi.parallelmode) {
 	case OMAP_DSS_RFBI_PARALLELMODE_8:
@@ -252,7 +254,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_device *dssdev,
+		const void __iomem *buf, int scr_width,
 		u16 x, u16 y,
 		u16 w, u16 h)
 {
@@ -574,9 +577,10 @@ 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,
-			     unsigned hs_pulse_time, unsigned vs_pulse_time,
-			     int hs_pol_inv, int vs_pol_inv, int extif_div)
+int omap_rfbi_setup_te(struct omap_dss_device *dssdev,
+			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)
 {
 	int hs, vs;
 	int min;
@@ -616,7 +620,8 @@ 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_device *dssdev, bool enable,
+		unsigned line)
 {
 	u32 l;
 
diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index 29c1440..0e73ef8 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -238,18 +238,23 @@ 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_device *dssdev, const void *buf,
+		u32 len);
+void omap_rfbi_read_data(struct omap_dss_device *dssdev, void *buf, u32 len);
+void omap_rfbi_write_data(struct omap_dss_device *dssdev, const void *buf,
+		u32 len);
+void omap_rfbi_write_pixels(struct omap_dss_device *dssdev,
+		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,
-			     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);
+int omap_rfbi_enable_te(struct omap_dss_device *dssdev, bool enable,
+		unsigned line);
+int omap_rfbi_setup_te(struct omap_dss_device *dssdev,
+			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(struct omap_dss_device *dssdev);
+void rfbi_bus_unlock(struct omap_dss_device *dssdev);
 
 /* DSI */
 
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [PATCH v2 16/23] OMAPDSS: VENC: Pass omap_dss_output within the driver
  2012-08-30 11:52   ` Archit Taneja
@ 2012-08-30 11:52     ` Archit Taneja
  -1 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-08-30 11:40 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: rob, linux-omap, linux-fbdev, Archit Taneja

When a panel driver calls a VENC function, it passes the omap_dss_device
pointer, this pointer currently propagates within the VENC driver to configure
the interface.

Extract the omap_dss_output pointer from omap_dss_device received from the panel
driver, pass the output pointer to VENC functions local to the driver to
configure the interface, these functions no longer need omap_dss_device since
the driver now maintains a copy of output parameters.

Replace dssdev->manager references with out->manager references as only these
will be valid later.

With the addition of outputs. There is a possibility that an omap_dss_device
isn't connected to an output, or a manager isn't connected to an output yet.
Ensure that the VENC interface functions proceed only if the output is non NULL.

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

diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c
index 942a378..3fe974f 100644
--- a/drivers/video/omap2/dss/venc.c
+++ b/drivers/video/omap2/dss/venc.c
@@ -428,7 +428,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;
@@ -455,13 +455,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;
 
@@ -478,12 +478,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);
 
@@ -498,14 +498,15 @@ unsigned long venc_get_pixel_clock(void)
 
 int omapdss_venc_display_enable(struct omap_dss_device *dssdev)
 {
+	struct omap_dss_output *out = dssdev->output;
 	int r;
 
 	DSSDBG("venc_display_enable\n");
 
 	mutex_lock(&venc.venc_lock);
 
-	if (dssdev->manager == NULL) {
-		DSSERR("Failed to enable display: no manager\n");
+	if (out == NULL || out->manager == NULL) {
+		DSSERR("Failed to enable display: no output/manager\n");
 		r = -ENODEV;
 		goto err0;
 	}
@@ -520,7 +521,7 @@ int omapdss_venc_display_enable(struct omap_dss_device *dssdev)
 		dssdev->platform_enable(dssdev);
 
 
-	r = venc_power_on(dssdev);
+	r = venc_power_on(out);
 	if (r)
 		goto err1;
 
@@ -540,11 +541,13 @@ err0:
 
 void omapdss_venc_display_disable(struct omap_dss_device *dssdev)
 {
+	struct omap_dss_output *out = dssdev->output;
+
 	DSSDBG("venc_display_disable\n");
 
 	mutex_lock(&venc.venc_lock);
 
-	venc_power_off(dssdev);
+	venc_power_off(out);
 
 	omap_dss_stop_device(dssdev);
 
@@ -557,8 +560,13 @@ void omapdss_venc_display_disable(struct omap_dss_device *dssdev)
 void omapdss_venc_set_timings(struct omap_dss_device *dssdev,
 		struct omap_video_timings *timings)
 {
+	struct omap_dss_output *out = dssdev->output;
+
 	DSSDBG("venc_set_timings\n");
 
+	if (out == NULL)
+		return;
+
 	mutex_lock(&venc.venc_lock);
 
 	/* Reset WSS data when the TV standard changes. */
@@ -571,13 +579,13 @@ void omapdss_venc_set_timings(struct omap_dss_device *dssdev,
 		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);
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [PATCH v2 17/23] OMAPDSS: HDMI: Pass omap_dss_output within the driver
  2012-08-30 11:52   ` Archit Taneja
@ 2012-08-30 11:52     ` Archit Taneja
  -1 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-08-30 11:40 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: rob, linux-omap, linux-fbdev, Archit Taneja

When a panel driver calls a HDMI function, it passes the omap_dss_device
pointer, this pointer currently propagates within the HDMI driver to configure
the interface.

Extract the omap_dss_output pointer from omap_dss_device received from the panel
driver, pass the output pointer to HDMI functions local to the driver to
configure the interface, these functions no longer need omap_dss_device since
the driver now maintains a copy of output parameters.

Replace dssdev->manager references with out->manager references as only these
will be valid later.

With the addition of outputs. There is a possibility that an omap_dss_device
isn't connected to an output, or a manager isn't connected to an output yet.
Ensure that the HDMI interface functions proceed only if the output is non NULL.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/dss/hdmi.c |   40 ++++++++++++++++++++++++----------------
 1 file changed, 24 insertions(+), 16 deletions(-)

diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c
index d93954d..3c89904 100644
--- a/drivers/video/omap2/dss/hdmi.c
+++ b/drivers/video/omap2/dss/hdmi.c
@@ -407,9 +407,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;
 
@@ -458,7 +459,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;
@@ -468,7 +469,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;
 
@@ -476,7 +477,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);
 
@@ -504,19 +505,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;
 
@@ -533,9 +534,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);
@@ -560,9 +561,13 @@ int omapdss_hdmi_display_check_timing(struct omap_dss_device *dssdev,
 void omapdss_hdmi_display_set_timing(struct omap_dss_device *dssdev,
 		struct omap_video_timings *timings)
 {
+	struct omap_dss_output *out = dssdev->output;
 	struct hdmi_cm cm;
 	const struct hdmi_config *t;
 
+	if (out == NULL)
+		return;
+
 	mutex_lock(&hdmi.lock);
 
 	cm = hdmi_get_code(timings);
@@ -575,13 +580,13 @@ void omapdss_hdmi_display_set_timing(struct omap_dss_device *dssdev,
 	if (dssdev->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);
@@ -640,14 +645,15 @@ bool omapdss_hdmi_detect(void)
 int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev)
 {
 	struct omap_dss_hdmi_data *priv = dssdev->data;
+	struct omap_dss_output *out = dssdev->output;
 	int r = 0;
 
 	DSSDBG("ENTER hdmi_display_enable\n");
 
 	mutex_lock(&hdmi.lock);
 
-	if (dssdev->manager == NULL) {
-		DSSERR("failed to enable display: no manager\n");
+	if (out == NULL || out->manager == NULL) {
+		DSSERR("failed to enable display: no output/manager\n");
 		r = -ENODEV;
 		goto err0;
 	}
@@ -668,7 +674,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;
@@ -689,11 +695,13 @@ err0:
 
 void omapdss_hdmi_display_disable(struct omap_dss_device *dssdev)
 {
+	struct omap_dss_output *out = dssdev->output;
+
 	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);
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [PATCH v2 18/23] OMAPDSS: HDMI: Add dssdev pointer as an argument to all functions used by hdmi panel driver
  2012-08-30 11:52   ` Archit Taneja
@ 2012-08-30 11:52     ` Archit Taneja
  -1 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-08-30 11:40 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: rob, linux-omap, linux-fbdev, Archit Taneja

All functions of an output driver used by a panel driver should have an
omap_dss_device 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 dssdev arguments to 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       |   17 +++++++++--------
 drivers/video/omap2/dss/hdmi_panel.c |   20 ++++++++++----------
 3 files changed, 28 insertions(+), 26 deletions(-)

diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index de2fb9d..11c245d 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -506,17 +506,18 @@ void omapdss_hdmi_display_set_timing(struct omap_dss_device *dssdev,
 		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 omapdss_hdmi_read_edid(struct omap_dss_device *dssdev, u8 *buf, int len);
+bool omapdss_hdmi_detect(struct omap_dss_device *dssdev);
 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_device *dssdev);
+void hdmi_audio_disable(struct omap_dss_device *dssdev);
+int hdmi_audio_start(struct omap_dss_device *dssdev);
+void hdmi_audio_stop(struct omap_dss_device *dssdev);
+bool hdmi_mode_has_audio(struct omap_dss_device *dssdev);
+int hdmi_audio_config(struct omap_dss_device *dssdev,
+		struct omap_dss_audio *audio);
 #endif
 
 /* RFBI */
diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c
index 3c89904..2d3b959 100644
--- a/drivers/video/omap2/dss/hdmi.c
+++ b/drivers/video/omap2/dss/hdmi.c
@@ -608,7 +608,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_device *dssdev, u8 *buf, int len)
 {
 	int r;
 
@@ -625,7 +625,7 @@ int omapdss_hdmi_read_edid(u8 *buf, int len)
 	return r;
 }
 
-bool omapdss_hdmi_detect(void)
+bool omapdss_hdmi_detect(struct omap_dss_device *dssdev)
 {
 	int r;
 
@@ -833,35 +833,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_device *dssdev)
 {
 	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_device *dssdev)
 {
 	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_device *dssdev)
 {
 	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_device *dssdev)
 {
 	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_device *dssdev)
 {
 	if (hdmi.ip_data.cfg.cm.mode == HDMI_HDMI)
 		return true;
@@ -869,7 +869,8 @@ bool hdmi_mode_has_audio(void)
 		return false;
 }
 
-int hdmi_audio_config(struct omap_dss_audio *audio)
+int hdmi_audio_config(struct omap_dss_device *dssdev,
+		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 69fb115..ef3fc86 100644
--- a/drivers/video/omap2/dss/hdmi_panel.c
+++ b/drivers/video/omap2/dss/hdmi_panel.c
@@ -88,13 +88,13 @@ static int hdmi_panel_audio_enable(struct omap_dss_device *dssdev)
 
 	/* 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(dssdev)) {
 		DSSERR("audio not supported or display is off\n");
 		r = -EPERM;
 		goto err;
 	}
 
-	r = hdmi_audio_enable();
+	r = hdmi_audio_enable(dssdev);
 
 	if (!r)
 		dssdev->audio_state = OMAP_DSS_AUDIO_ENABLED;
@@ -111,7 +111,7 @@ static void hdmi_panel_audio_disable(struct omap_dss_device *dssdev)
 
 	spin_lock_irqsave(&hdmi.audio_lock, flags);
 
-	hdmi_audio_disable();
+	hdmi_audio_disable(dssdev);
 
 	dssdev->audio_state = OMAP_DSS_AUDIO_DISABLED;
 
@@ -134,7 +134,7 @@ static int hdmi_panel_audio_start(struct omap_dss_device *dssdev)
 		goto err;
 	}
 
-	r = hdmi_audio_start();
+	r = hdmi_audio_start(dssdev);
 
 	if (!r)
 		dssdev->audio_state = OMAP_DSS_AUDIO_PLAYING;
@@ -150,7 +150,7 @@ static void hdmi_panel_audio_stop(struct omap_dss_device *dssdev)
 
 	spin_lock_irqsave(&hdmi.audio_lock, flags);
 
-	hdmi_audio_stop();
+	hdmi_audio_stop(dssdev);
 	dssdev->audio_state = OMAP_DSS_AUDIO_ENABLED;
 
 	spin_unlock_irqrestore(&hdmi.audio_lock, flags);
@@ -165,7 +165,7 @@ static bool hdmi_panel_audio_supported(struct omap_dss_device *dssdev)
 	if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
 		goto err;
 
-	if (!hdmi_mode_has_audio())
+	if (!hdmi_mode_has_audio(dssdev))
 		goto err;
 
 	r = true;
@@ -185,13 +185,13 @@ static int hdmi_panel_audio_config(struct omap_dss_device *dssdev,
 
 	/* 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(dssdev)) {
 		DSSERR("audio not supported or display is off\n");
 		r = -EPERM;
 		goto err;
 	}
 
-	r = hdmi_audio_config(audio);
+	r = hdmi_audio_config(dssdev, audio);
 
 	if (!r)
 		dssdev->audio_state = OMAP_DSS_AUDIO_CONFIGURED;
@@ -388,7 +388,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(dssdev, buf, len);
 
 	if (dssdev->state == OMAP_DSS_DISPLAY_DISABLED ||
 			dssdev->state == OMAP_DSS_DISPLAY_SUSPENDED)
@@ -411,7 +411,7 @@ static bool hdmi_detect(struct omap_dss_device *dssdev)
 			goto err;
 	}
 
-	r = omapdss_hdmi_detect();
+	r = omapdss_hdmi_detect(dssdev);
 
 	if (dssdev->state == OMAP_DSS_DISPLAY_DISABLED ||
 			dssdev->state == OMAP_DSS_DISPLAY_SUSPENDED)
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [PATCH v2 19/23] OMAPDSS/OMAPFB: Change dssdev->manager references
  2012-08-30 11:52   ` Archit Taneja
@ 2012-08-30 11:52     ` Archit Taneja
  -1 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-08-30 11:40 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: rob, linux-omap, linux-fbdev, Archit Taneja

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 |    7 +++++--
 2 files changed, 14 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..606b89f 100644
--- a/drivers/video/omap2/omapfb/omapfb-ioctl.c
+++ b/drivers/video/omap2/omapfb/omapfb-ioctl.c
@@ -599,6 +599,7 @@ int omapfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg)
 	struct omapfb_info *ofbi = FB2OFB(fbi);
 	struct omapfb2_device *fbdev = ofbi->fbdev;
 	struct omap_dss_device *display = fb2display(fbi);
+	struct omap_overlay_manager *mgr;
 
 	union {
 		struct omapfb_update_window_old	uwnd_o;
@@ -786,12 +787,14 @@ 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);
+		mgr = display->output->manager;
+
+		r = mgr->wait_for_vsync(mgr);
 		break;
 
 	case OMAPFB_WAITFORGO:
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [PATCH v2 20/23] OMAPDSS: MANAGER: Update display sysfs store
  2012-08-30 11:52   ` Archit Taneja
@ 2012-08-30 11:52     ` Archit Taneja
  -1 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-08-30 11:40 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: rob, linux-omap, linux-fbdev, Archit Taneja

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	[flat|nested] 148+ messages in thread

* [PATCH v2 21/23] OMAPDSS: MANAGER: Get device via output
  2012-08-30 11:52   ` Archit Taneja
@ 2012-08-30 11:52     ` Archit Taneja
  -1 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-08-30 11:40 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: rob, linux-omap, linux-fbdev, Archit Taneja

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	[flat|nested] 148+ messages in thread

* [PATCH v2 22/23] OMAPDSS: APPLY: Remove omap_dss_device references from dss_ovl_enable/disable
  2012-08-30 11:52   ` Archit Taneja
@ 2012-08-30 11:52     ` Archit Taneja
  -1 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-08-30 11:40 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: rob, linux-omap, linux-fbdev, Archit Taneja

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	[flat|nested] 148+ messages in thread

* [PATCH v2 23/23] OMAPDSS: Remove old way of setting manager and device links
  2012-08-30 11:52   ` Archit Taneja
@ 2012-08-30 11:52     ` Archit Taneja
  -1 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-08-30 11:40 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: rob, linux-omap, linux-fbdev, Archit Taneja

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 0e73ef8..4ff43e6 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	[flat|nested] 148+ messages in thread

* [PATCH v2 00/23] OMAPDSS: Create output entities
@ 2012-08-30 11:52   ` Archit Taneja
  0 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-08-30 11:52 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: rob, linux-omap, linux-fbdev, Archit Taneja

Create a new entity in OMAPDSS called outputs. These represent the
interfaces/outputs like DSI, HDMI etc. that a panel connects to. An output
sits in between an overlay manager and a panel. More details about outputs
are explained in the first patch of the series.

This series adds omap_dss_output as an entity along with omap_overlay,
omap_overlay_manager and omap_dss_device. It changes the code to establish
links between managers and outputs, and outputs and devices.

Changes since v1:
- Output drivers private data structs hold the output struct rather than
  output.c allocating it. This struct is added to a list when
  dss_register_output()is called.
- Outputs are not passed from panel driver to output driver anymore. We are
  sticking to passing omap_dss_device for now till we get a clearer picture on
  how common panel framework turns out. Outputs are still used within the output
  driver, rather than passing dssdev everywhere.

Reference tree:

git://gitorious.org/~boddob/linux-omap-dss2/archit-dss2-clone.git 2-add-outputs

Archit Taneja (23):
  OMAPDSS: outputs: Create a new entity called outputs
  OMAPDSS: outputs: Create and register output instances
  OMAPDSS: output: Add set/unset device ops for omap_dss_output
  OMAPDSS: APPLY: Add manager set/unset output ops for
    omap_overlay_manager
  OMAPDSS: Remove manager->device references
  OMAP_VOUT: Remove manager->device references
  OMAPFB: remove manager->device references
  OMAPDRM: Remove manager->device references
  OMAPDSS: Create links between managers, outputs and devices
  OMAPDSS: DPI: Pass omap_dss_output within the driver
  OMAPDSS: DSI: Remove dsi_pdev_map global struct
  OMAPDSS: DSI: Pass omap_dss_output within the driver
  OMAPDSS: SDI: Pass omap_dss_output within the driver
  OMAPDSS: RFBI: Pass omap_dss_output within the driver
  OMAPDSS: RFBI: Add dssdev pointers as arguments to all exported
    functions
  OMAPDSS: VENC: Pass omap_dss_output within the driver
  OMAPDSS: HDMI: Pass omap_dss_output within the driver
  OMAPDSS: HDMI: Add dssdev pointer as an argument to all functions
    used by hdmi panel driver
  OMAPDSS/OMAPFB: Change dssdev->manager references
  OMAPDSS: MANAGER: Update display sysfs store
  OMAPDSS: MANAGER: Get device via output
  OMAPDSS: APPLY: Remove omap_dss_device references from
    dss_ovl_enable/disable
  OMAPDSS: Remove old way of setting manager and device links

 drivers/media/video/omap/omap_vout.c      |   81 +++++++---
 drivers/staging/omapdrm/omap_drv.c        |    5 +-
 drivers/video/omap2/displays/panel-n8x0.c |   55 ++++---
 drivers/video/omap2/dss/Makefile          |    2 +-
 drivers/video/omap2/dss/apply.c           |   52 +++---
 drivers/video/omap2/dss/dispc.c           |   10 +-
 drivers/video/omap2/dss/display.c         |   11 +-
 drivers/video/omap2/dss/dpi.c             |   70 +++++---
 drivers/video/omap2/dss/dsi.c             |  249 ++++++++++++++++++-----------
 drivers/video/omap2/dss/dss.h             |   23 ++-
 drivers/video/omap2/dss/dss_features.c    |   52 ++++++
 drivers/video/omap2/dss/dss_features.h    |    1 +
 drivers/video/omap2/dss/hdmi.c            |   72 ++++++---
 drivers/video/omap2/dss/hdmi_panel.c      |   20 +--
 drivers/video/omap2/dss/manager.c         |   48 ++++--
 drivers/video/omap2/dss/output.c          |  110 +++++++++++++
 drivers/video/omap2/dss/overlay.c         |   96 ++++++-----
 drivers/video/omap2/dss/rfbi.c            |   66 +++++---
 drivers/video/omap2/dss/sdi.c             |   35 ++--
 drivers/video/omap2/dss/venc.c            |   47 ++++--
 drivers/video/omap2/omapfb/omapfb-ioctl.c |    7 +-
 drivers/video/omap2/omapfb/omapfb-main.c  |    7 +-
 drivers/video/omap2/omapfb/omapfb.h       |    5 +-
 include/video/omapdss.h                   |   72 +++++++--
 24 files changed, 848 insertions(+), 348 deletions(-)
 create mode 100644 drivers/video/omap2/dss/output.c

-- 
1.7.9.5


^ permalink raw reply	[flat|nested] 148+ messages in thread

* [PATCH v2 01/23] OMAPDSS: outputs: Create a new entity called outputs
@ 2012-08-30 11:52     ` Archit Taneja
  0 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-08-30 11:52 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: rob, linux-omap, linux-fbdev, Archit Taneja

The current OMAPDSS design contains 3 software entities: Overlays, Managers and
Devices. These map to pipelines, overlay managers and the panels respectively in
hardware. One or more overlays connect to a manager to represent a composition,
the manager connects to a device(generally a display) to display the content.

The part of DSS hardware which isn't represented by any of the above entities
are interfaces/outputs that connect to an overlay manager, i.e blocks like DSI,
HDMI, VENC and so on. Currently, an overlay manager directly connects to the
display, and the output to which it is actually connected is ignored. The panel
driver of the display is responsible of calling output specific functions to
configure the output.

Adding outputs as a new software entity gives us the following benefits:

- Have exact information on the possible connections between managers and
  outputs: A manager can't connect to each and every output, there only limited
  hardware links between a manager's video port and some of the outputs.

- Remove hacks related to connecting managers and devices: Currently, default
  links between managers and devices are set in a not so clean way. Matching is
  done via comparing the device type, and the display types supported by the
  manager. This isn't sufficient to establish all the possible links between
  managers, outputs and devices in hardware.

- Make panel drivers more generic: The DSS panel drivers currently call
  interface/output specific functions to configure the hardware IP. When making
  these calls, the driver isn't actually aware of the underlying output. The
  output driver extracts information from the panel's omap_dss_device pointer
  to figure out which interface it is connected to, and then configures the
  corresponding output block. An example of this is when a DSI panel calls
  dsi functions, the dsi driver figures out whether the panel is connected
  to DSI1 or DSI2. This isn't correct, and having output as entities will
  give the panel driver the exact information on which output to configure.
  Having outputs also gives the opportunity to make panel drivers generic
  across different platforms/SoCs, this is achieved as omap specific output
  calls can be replaced by ops of a particular output type.

- Have more complex connections between managers, outputs and devices: OMAPDSS
  currently doesn't support use cases like 2 outputs connect to a single
  device. This can be achieved by extending properties of outputs to connect to
  more managers or devices.

- Represent writeback as an output: The writeback pipeline fits well in OMAPDSS
  as compared to overlays, managers or devices.

Add a new struct to represent outputs. An output struct holds pointers to the
manager and device structs to which it is connected. Add functions which can
register an output, or look for one. Create an enum which represent each output
instance.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/dss/Makefile |    2 +-
 drivers/video/omap2/dss/dss.h    |    3 +++
 drivers/video/omap2/dss/output.c |   43 ++++++++++++++++++++++++++++++++++++++
 include/video/omapdss.h          |   30 ++++++++++++++++++++++++++
 4 files changed, 77 insertions(+), 1 deletion(-)
 create mode 100644 drivers/video/omap2/dss/output.c

diff --git a/drivers/video/omap2/dss/Makefile b/drivers/video/omap2/dss/Makefile
index 30a48fb..645f8c3 100644
--- a/drivers/video/omap2/dss/Makefile
+++ b/drivers/video/omap2/dss/Makefile
@@ -1,6 +1,6 @@
 obj-$(CONFIG_OMAP2_DSS) += omapdss.o
 omapdss-y := core.o dss.o dss_features.o dispc.o dispc_coefs.o display.o \
-	manager.o overlay.o apply.o
+	manager.o overlay.o output.o apply.o
 omapdss-$(CONFIG_OMAP2_DSS_DPI) += dpi.o
 omapdss-$(CONFIG_OMAP2_DSS_RFBI) += rfbi.o
 omapdss-$(CONFIG_OMAP2_DSS_VENC) += venc.o venc_panel.o
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index d6cca82..e77d8d2 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -222,6 +222,9 @@ int dss_ovl_set_manager(struct omap_overlay *ovl,
 		struct omap_overlay_manager *mgr);
 int dss_ovl_unset_manager(struct omap_overlay *ovl);
 
+/* output */
+void dss_register_output(struct omap_dss_output *out);
+
 /* display */
 int dss_suspend_all_devices(void);
 int dss_resume_all_devices(void);
diff --git a/drivers/video/omap2/dss/output.c b/drivers/video/omap2/dss/output.c
new file mode 100644
index 0000000..7d81be5
--- /dev/null
+++ b/drivers/video/omap2/dss/output.c
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2012 Texas Instruments Ltd
+ * Author: Archit Taneja <archit@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#include <video/omapdss.h>
+
+#include "dss.h"
+
+static LIST_HEAD(output_list);
+
+void dss_register_output(struct omap_dss_output *out)
+{
+	list_add_tail(&out->list, &output_list);
+}
+
+struct omap_dss_output *omap_dss_get_output(enum omap_dss_output_id id)
+{
+	struct omap_dss_output *out;
+
+	list_for_each_entry(out, &output_list, list) {
+		if (out->id = id)
+			return out;
+	}
+
+	return NULL;
+}
diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index b868123..2926a04 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -207,6 +207,16 @@ enum omap_hdmi_flags {
 	OMAP_HDMI_SDA_SCL_EXTERNAL_PULLUP = 1 << 0,
 };
 
+enum omap_dss_output_id {
+	OMAP_DSS_OUTPUT_DPI	= 1 << 0,
+	OMAP_DSS_OUTPUT_DBI	= 1 << 1,
+	OMAP_DSS_OUTPUT_SDI	= 1 << 2,
+	OMAP_DSS_OUTPUT_DSI1	= 1 << 3,
+	OMAP_DSS_OUTPUT_DSI2	= 1 << 4,
+	OMAP_DSS_OUTPUT_VENC	= 1 << 5,
+	OMAP_DSS_OUTPUT_HDMI	= 1 << 6,
+};
+
 /* RFBI */
 
 struct rfbi_timings {
@@ -492,6 +502,24 @@ struct omap_dsi_pin_config {
 	int pins[OMAP_DSS_MAX_DSI_PINS];
 };
 
+struct omap_dss_output {
+	struct list_head list;
+
+	/* display type supported by the output */
+	enum omap_display_type type;
+
+	/* output instance */
+	enum omap_dss_output_id id;
+
+	/* output's platform device pointer */
+	struct platform_device *pdev;
+
+	/* dynamic fields */
+	struct omap_overlay_manager *manager;
+
+	struct omap_dss_device *device;
+};
+
 struct omap_dss_device {
 	struct device dev;
 
@@ -699,6 +727,8 @@ struct omap_overlay_manager *omap_dss_get_overlay_manager(int num);
 int omap_dss_get_num_overlays(void);
 struct omap_overlay *omap_dss_get_overlay(int num);
 
+struct omap_dss_output *omap_dss_get_output(enum omap_dss_output_id id);
+
 void omapdss_default_get_resolution(struct omap_dss_device *dssdev,
 		u16 *xres, u16 *yres);
 int omapdss_default_get_recommended_bpp(struct omap_dss_device *dssdev);
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [PATCH v2 02/23] OMAPDSS: outputs: Create and register output instances
@ 2012-08-30 11:52     ` Archit Taneja
  0 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-08-30 11:52 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: rob, linux-omap, linux-fbdev, Archit Taneja

Add output structs to output driver's private data. Register output instances by
having an init function in the probes of the platform device drivers for
different outputs. The *_init_output for each output registers the output and
fill up the output's plaform device, type and id fields.

In the probe of each interface driver, the output entities are initialized
before the *_probe_pdata() functions intentionally. This is done to ensure that
the output entity is prepared before the panels connected to the output are
registered. We need the output entities to be ready because OMAPDSS will try
to make connections between overlays, managers, outputs and devices during the
panel's probe.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/dss/dpi.c  |   15 +++++++++++++++
 drivers/video/omap2/dss/dsi.c  |   18 ++++++++++++++++++
 drivers/video/omap2/dss/hdmi.c |   15 +++++++++++++++
 drivers/video/omap2/dss/rfbi.c |   17 +++++++++++++++++
 drivers/video/omap2/dss/sdi.c  |   15 +++++++++++++++
 drivers/video/omap2/dss/venc.c |   15 +++++++++++++++
 6 files changed, 95 insertions(+)

diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c
index 25fb895..9a7aee5 100644
--- a/drivers/video/omap2/dss/dpi.c
+++ b/drivers/video/omap2/dss/dpi.c
@@ -45,6 +45,8 @@ static struct {
 	struct omap_video_timings timings;
 	struct dss_lcd_mgr_config mgr_config;
 	int data_lines;
+
+	struct omap_dss_output output;
 } dpi;
 
 static struct platform_device *dpi_get_dsidev(enum omap_dss_clk_source clk)
@@ -410,10 +412,23 @@ static void __init dpi_probe_pdata(struct platform_device *pdev)
 	}
 }
 
+static void __init dpi_init_output(struct platform_device *pdev)
+{
+	struct omap_dss_output *out = &dpi.output;
+
+	dss_register_output(out);
+
+	out->pdev = pdev;
+	out->id = OMAP_DSS_OUTPUT_DPI;
+	out->type = OMAP_DISPLAY_TYPE_DPI;
+}
+
 static int __init omap_dpi_probe(struct platform_device *pdev)
 {
 	mutex_init(&dpi.lock);
 
+	dpi_init_output(pdev);
+
 	dpi_probe_pdata(pdev);
 
 	return 0;
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index 659b6cd..6a83ab7 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -337,6 +337,8 @@ struct dsi_data {
 	enum omap_dss_dsi_pixel_format pix_fmt;
 	enum omap_dss_dsi_mode mode;
 	struct omap_dss_dsi_videomode_timings vm_timings;
+
+	struct omap_dss_output output;
 };
 
 struct dsi_packet_sent_handler_data {
@@ -4903,6 +4905,20 @@ static void __init dsi_probe_pdata(struct platform_device *dsidev)
 	}
 }
 
+static void __init dsi_init_output(struct platform_device *dsidev,
+		struct dsi_data *dsi)
+{
+	struct omap_dss_output *out = &dsi->output;
+
+	dss_register_output(out);
+
+	out->pdev = dsidev;
+	out->id = dsi->module_id = 0 ?
+			OMAP_DSS_OUTPUT_DSI1 : OMAP_DSS_OUTPUT_DSI2;
+
+	out->type = OMAP_DISPLAY_TYPE_DSI;
+}
+
 /* DSI1 HW IP initialisation */
 static int __init omap_dsihw_probe(struct platform_device *dsidev)
 {
@@ -4997,6 +5013,8 @@ static int __init omap_dsihw_probe(struct platform_device *dsidev)
 	else
 		dsi->num_lanes_supported = 3;
 
+	dsi_init_output(dsidev, dsi);
+
 	dsi_probe_pdata(dsidev);
 
 	dsi_runtime_put(dsidev);
diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c
index 0cdf246..d93954d 100644
--- a/drivers/video/omap2/dss/hdmi.c
+++ b/drivers/video/omap2/dss/hdmi.c
@@ -61,6 +61,8 @@ static struct {
 	struct hdmi_ip_data ip_data;
 
 	struct clk *sys_clk;
+
+	struct omap_dss_output output;
 } hdmi;
 
 /*
@@ -890,6 +892,17 @@ static void __init hdmi_probe_pdata(struct platform_device *pdev)
 	}
 }
 
+static void __init hdmi_init_output(struct platform_device *pdev)
+{
+	struct omap_dss_output *out = &hdmi.output;
+
+	dss_register_output(out);
+
+	out->pdev = pdev;
+	out->id = OMAP_DSS_OUTPUT_HDMI;
+	out->type = OMAP_DISPLAY_TYPE_HDMI;
+}
+
 /* HDMI HW IP initialisation */
 static int __init omapdss_hdmihw_probe(struct platform_device *pdev)
 {
@@ -933,6 +946,8 @@ static int __init omapdss_hdmihw_probe(struct platform_device *pdev)
 
 	dss_debugfs_create_file("hdmi", hdmi_dump_regs);
 
+	hdmi_init_output(pdev);
+
 	hdmi_probe_pdata(pdev);
 
 	return 0;
diff --git a/drivers/video/omap2/dss/rfbi.c b/drivers/video/omap2/dss/rfbi.c
index 5a9c0e9..3450f51 100644
--- a/drivers/video/omap2/dss/rfbi.c
+++ b/drivers/video/omap2/dss/rfbi.c
@@ -116,6 +116,8 @@ static struct {
 	int pixel_size;
 	int data_lines;
 	struct rfbi_timings intf_timings;
+
+	struct omap_dss_output output;
 } rfbi;
 
 static inline void rfbi_write_reg(const struct rfbi_reg idx, u32 val)
@@ -967,6 +969,19 @@ static void __init rfbi_probe_pdata(struct platform_device *pdev)
 	}
 }
 
+static void __init rfbi_init_output(struct platform_device *pdev)
+{
+	struct omap_dss_output *out = &rfbi.output;
+
+	dss_register_output(out);
+
+	out->pdev = pdev;
+	out->id = OMAP_DSS_OUTPUT_DBI;
+	out->type = OMAP_DISPLAY_TYPE_DBI;
+
+	return 0;
+}
+
 /* RFBI HW IP initialisation */
 static int __init omap_rfbihw_probe(struct platform_device *pdev)
 {
@@ -1018,6 +1033,8 @@ static int __init omap_rfbihw_probe(struct platform_device *pdev)
 
 	dss_debugfs_create_file("rfbi", rfbi_dump_regs);
 
+	rfbi_init_output(pdev);
+
 	rfbi_probe_pdata(pdev);
 
 	return 0;
diff --git a/drivers/video/omap2/dss/sdi.c b/drivers/video/omap2/dss/sdi.c
index 3bf1bfe..d8879f3 100644
--- a/drivers/video/omap2/dss/sdi.c
+++ b/drivers/video/omap2/dss/sdi.c
@@ -36,6 +36,8 @@ static struct {
 	struct dss_lcd_mgr_config mgr_config;
 	struct omap_video_timings timings;
 	int datapairs;
+
+	struct omap_dss_output output;
 } sdi;
 
 static void sdi_config_lcd_manager(struct omap_dss_device *dssdev)
@@ -216,8 +218,21 @@ static void __init sdi_probe_pdata(struct platform_device *pdev)
 	}
 }
 
+static void __init sdi_init_output(struct platform_device *pdev)
+{
+	struct omap_dss_output *out = &sdi.output;
+
+	dss_register_output(out);
+
+	out->pdev = pdev;
+	out->id = OMAP_DSS_OUTPUT_SDI;
+	out->type = OMAP_DISPLAY_TYPE_SDI;
+}
+
 static int __init omap_sdi_probe(struct platform_device *pdev)
 {
+	sdi_init_output(pdev);
+
 	sdi_probe_pdata(pdev);
 
 	return 0;
diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c
index 4a6caf9..942a378 100644
--- a/drivers/video/omap2/dss/venc.c
+++ b/drivers/video/omap2/dss/venc.c
@@ -304,6 +304,8 @@ static struct {
 	struct omap_video_timings timings;
 	enum omap_dss_venc_type type;
 	bool invert_polarity;
+
+	struct omap_dss_output output;
 } venc;
 
 static inline void venc_write_reg(int idx, u32 val)
@@ -773,6 +775,17 @@ static void __init venc_probe_pdata(struct platform_device *pdev)
 	}
 }
 
+static void __init venc_init_output(struct platform_device *pdev)
+{
+	struct omap_dss_output *out = &venc.output;
+
+	dss_register_output(out);
+
+	out->pdev = pdev;
+	out->id = OMAP_DSS_OUTPUT_VENC;
+	out->type = OMAP_DISPLAY_TYPE_VENC;
+}
+
 /* VENC HW IP initialisation */
 static int __init omap_venchw_probe(struct platform_device *pdev)
 {
@@ -820,6 +833,8 @@ static int __init omap_venchw_probe(struct platform_device *pdev)
 
 	dss_debugfs_create_file("venc", venc_dump_regs);
 
+	venc_init_output(pdev);
+
 	venc_probe_pdata(pdev);
 
 	return 0;
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [PATCH v2 03/23] OMAPDSS: output: Add set/unset device ops for omap_dss_output
@ 2012-08-30 11:52     ` Archit Taneja
  0 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-08-30 11:52 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: rob, linux-omap, linux-fbdev, Archit Taneja

An output entity represented by the struct omap_dss_output connects to a
omap_dss_device entity. Add functions to set or unset an output's device. This
is similar to how managers and devices were connected previously. An output can
connect to a device without being connected to a manager. However, the output
needs to eventually connect to a manager so that the connected panel can be
enabled.

Keep the omap_overlay_manager pointer in omap_dss_device for now to prevent
breaking things. This will be removed later when outputs are supported
completely.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/dss/output.c |   67 ++++++++++++++++++++++++++++++++++++++
 include/video/omapdss.h          |    5 +++
 2 files changed, 72 insertions(+)

diff --git a/drivers/video/omap2/dss/output.c b/drivers/video/omap2/dss/output.c
index 7d81be5..abc3aa2 100644
--- a/drivers/video/omap2/dss/output.c
+++ b/drivers/video/omap2/dss/output.c
@@ -24,9 +24,76 @@
 #include "dss.h"
 
 static LIST_HEAD(output_list);
+static DEFINE_MUTEX(output_lock);
+
+static int dss_output_set_device(struct omap_dss_output *out,
+		struct omap_dss_device *dssdev)
+{
+	int r;
+
+	mutex_lock(&output_lock);
+
+	if (out->device) {
+		DSSERR("output already has device %s connected to it\n",
+			out->device->name);
+		r = -EINVAL;
+		goto err;
+	}
+
+	if (out->type != dssdev->type) {
+		DSSERR("output type and display type don't match\n");
+		r = -EINVAL;
+		goto err;
+	}
+
+	out->device = dssdev;
+	dssdev->output = out;
+
+	mutex_unlock(&output_lock);
+
+	return 0;
+err:
+	mutex_unlock(&output_lock);
+
+	return r;
+}
+
+static int dss_output_unset_device(struct omap_dss_output *out)
+{
+	int r;
+
+	mutex_lock(&output_lock);
+
+	if (!out->device) {
+		DSSERR("output doesn't have a device connected to it\n");
+		r = -EINVAL;
+		goto err;
+	}
+
+	if (out->device->state != OMAP_DSS_DISPLAY_DISABLED) {
+		DSSERR("device %s is not disabled, cannot unset device\n",
+				out->device->name);
+		r = -EINVAL;
+		goto err;
+	}
+
+	out->device->output = NULL;
+	out->device = NULL;
+
+	mutex_unlock(&output_lock);
+
+	return 0;
+err:
+	mutex_unlock(&output_lock);
+
+	return r;
+}
 
 void dss_register_output(struct omap_dss_output *out)
 {
+	out->set_device = &dss_output_set_device;
+	out->unset_device = &dss_output_unset_device;
+
 	list_add_tail(&out->list, &output_list);
 }
 
diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index 2926a04..b3fba19 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -518,6 +518,10 @@ struct omap_dss_output {
 	struct omap_overlay_manager *manager;
 
 	struct omap_dss_device *device;
+
+	int (*set_device) (struct omap_dss_output *out,
+		struct omap_dss_device *dssdev);
+	int (*unset_device) (struct omap_dss_output *out);
 };
 
 struct omap_dss_device {
@@ -619,6 +623,7 @@ 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	[flat|nested] 148+ messages in thread

* [PATCH v2 04/23] OMAPDSS: APPLY: Add manager set/unset output ops for omap_overlay_manager
@ 2012-08-30 11:52     ` Archit Taneja
  0 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-08-30 11:52 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: rob, linux-omap, linux-fbdev, Archit Taneja

Add set_output/unset_output ops for overlay managers, these form links between
managers and outputs. Create a function in dss features which tell all the
output instances that connect to a manager, use it when a manager tries to set
an output. Add a constraint of not unsetting an output when the manager is
enabled.

Keep the omap_dss_device pointer and set/unset_device ops in overlay_manager for
now to not break things. Keep the dss feature function get_supported_displays
as it's used in some places. These will be removed later.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/dss/apply.c        |   70 ++++++++++++++++++++++++++++++++
 drivers/video/omap2/dss/dss.h          |    3 ++
 drivers/video/omap2/dss/dss_features.c |   52 ++++++++++++++++++++++++
 drivers/video/omap2/dss/dss_features.h |    1 +
 drivers/video/omap2/dss/manager.c      |    4 ++
 include/video/omapdss.h                |    5 +++
 6 files changed, 135 insertions(+)

diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c
index 74f1a58..d241407 100644
--- a/drivers/video/omap2/dss/apply.c
+++ b/drivers/video/omap2/dss/apply.c
@@ -1311,6 +1311,76 @@ err:
 	return r;
 }
 
+int dss_mgr_set_output(struct omap_overlay_manager *mgr,
+		struct omap_dss_output *output)
+{
+	int r;
+
+	mutex_lock(&apply_lock);
+
+	if (mgr->output) {
+		DSSERR("manager %s is already connected to an output\n",
+			mgr->name);
+		r = -EINVAL;
+		goto err;
+	}
+
+	if ((mgr->supported_outputs & output->id) = 0) {
+		DSSERR("output does not support manager %s\n",
+			mgr->name);
+		r = -EINVAL;
+		goto err;
+	}
+
+	output->manager = mgr;
+	mgr->output = output;
+
+	mutex_unlock(&apply_lock);
+
+	return 0;
+err:
+	mutex_unlock(&apply_lock);
+	return r;
+}
+
+int dss_mgr_unset_output(struct omap_overlay_manager *mgr)
+{
+	int r;
+	struct mgr_priv_data *mp = get_mgr_priv(mgr);
+	unsigned long flags;
+
+	mutex_lock(&apply_lock);
+
+	if (!mgr->output) {
+		DSSERR("failed to unset output, output not set\n");
+		r = -EINVAL;
+		goto err;
+	}
+
+	spin_lock_irqsave(&data_lock, flags);
+
+	if (mp->enabled) {
+		DSSERR("output can't be unset when manager is enabled\n");
+		r = -EINVAL;
+		goto err1;
+	}
+
+	spin_unlock_irqrestore(&data_lock, flags);
+
+	mgr->output->manager = NULL;
+	mgr->output = NULL;
+
+	mutex_unlock(&apply_lock);
+
+	return 0;
+err1:
+	spin_unlock_irqrestore(&data_lock, flags);
+err:
+	mutex_unlock(&apply_lock);
+
+	return r;
+}
+
 static void dss_apply_mgr_timings(struct omap_overlay_manager *mgr,
 		const struct omap_video_timings *timings)
 {
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index e77d8d2..de2fb9d 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -205,6 +205,9 @@ void dss_mgr_get_info(struct omap_overlay_manager *mgr,
 int dss_mgr_set_device(struct omap_overlay_manager *mgr,
 		struct omap_dss_device *dssdev);
 int dss_mgr_unset_device(struct omap_overlay_manager *mgr);
+int dss_mgr_set_output(struct omap_overlay_manager *mgr,
+		struct omap_dss_output *output);
+int dss_mgr_unset_output(struct omap_overlay_manager *mgr);
 void dss_mgr_set_timings(struct omap_overlay_manager *mgr,
 		const struct omap_video_timings *timings);
 void dss_mgr_set_lcd_config(struct omap_overlay_manager *mgr,
diff --git a/drivers/video/omap2/dss/dss_features.c b/drivers/video/omap2/dss/dss_features.c
index 2fe39d6..2872329 100644
--- a/drivers/video/omap2/dss/dss_features.c
+++ b/drivers/video/omap2/dss/dss_features.c
@@ -47,6 +47,7 @@ struct omap_dss_features {
 	const int num_mgrs;
 	const int num_ovls;
 	const enum omap_display_type *supported_displays;
+	const enum omap_dss_output_id *supported_outputs;
 	const enum omap_color_mode *supported_color_modes;
 	const enum omap_overlay_caps *overlay_caps;
 	const char * const *clksrc_names;
@@ -144,6 +145,46 @@ static const enum omap_display_type omap4_dss_supported_displays[] = {
 	OMAP_DISPLAY_TYPE_DSI,
 };
 
+static const enum omap_dss_output_id omap2_dss_supported_outputs[] = {
+	/* OMAP_DSS_CHANNEL_LCD */
+	OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI,
+
+	/* OMAP_DSS_CHANNEL_DIGIT */
+	OMAP_DSS_OUTPUT_VENC,
+};
+
+static const enum omap_dss_output_id omap3430_dss_supported_outputs[] = {
+	/* OMAP_DSS_CHANNEL_LCD */
+	OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI |
+	OMAP_DSS_OUTPUT_SDI | OMAP_DSS_OUTPUT_DSI1,
+
+	/* OMAP_DSS_CHANNEL_DIGIT */
+	OMAP_DSS_OUTPUT_VENC,
+};
+
+static const enum omap_dss_output_id omap3630_dss_supported_outputs[] = {
+	/* OMAP_DSS_CHANNEL_LCD */
+	OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI |
+	OMAP_DSS_OUTPUT_DSI1,
+
+	/* OMAP_DSS_CHANNEL_DIGIT */
+	OMAP_DSS_OUTPUT_VENC,
+};
+
+static const enum omap_dss_output_id omap4_dss_supported_outputs[] = {
+	/* OMAP_DSS_CHANNEL_LCD */
+	OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI |
+	OMAP_DSS_OUTPUT_DSI1,
+
+	/* OMAP_DSS_CHANNEL_DIGIT */
+	OMAP_DSS_OUTPUT_VENC | OMAP_DSS_OUTPUT_HDMI |
+	OMAP_DSS_OUTPUT_DPI,
+
+	/* OMAP_DSS_CHANNEL_LCD2 */
+	OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI |
+	OMAP_DSS_OUTPUT_DSI2,
+};
+
 static const enum omap_color_mode omap2_dss_supported_color_modes[] = {
 	/* OMAP_DSS_GFX */
 	OMAP_DSS_COLOR_CLUT1 | OMAP_DSS_COLOR_CLUT2 |
@@ -459,6 +500,7 @@ static const struct omap_dss_features omap2_dss_features = {
 	.num_mgrs = 2,
 	.num_ovls = 3,
 	.supported_displays = omap2_dss_supported_displays,
+	.supported_outputs = omap2_dss_supported_outputs,
 	.supported_color_modes = omap2_dss_supported_color_modes,
 	.overlay_caps = omap2_dss_overlay_caps,
 	.clksrc_names = omap2_dss_clk_source_names,
@@ -479,6 +521,7 @@ static const struct omap_dss_features omap3430_dss_features = {
 	.num_mgrs = 2,
 	.num_ovls = 3,
 	.supported_displays = omap3430_dss_supported_displays,
+	.supported_outputs = omap3430_dss_supported_outputs,
 	.supported_color_modes = omap3_dss_supported_color_modes,
 	.overlay_caps = omap3430_dss_overlay_caps,
 	.clksrc_names = omap3_dss_clk_source_names,
@@ -498,6 +541,7 @@ static const struct omap_dss_features omap3630_dss_features = {
 	.num_mgrs = 2,
 	.num_ovls = 3,
 	.supported_displays = omap3630_dss_supported_displays,
+	.supported_outputs = omap3630_dss_supported_outputs,
 	.supported_color_modes = omap3_dss_supported_color_modes,
 	.overlay_caps = omap3630_dss_overlay_caps,
 	.clksrc_names = omap3_dss_clk_source_names,
@@ -519,6 +563,7 @@ static const struct omap_dss_features omap4430_es1_0_dss_features  = {
 	.num_mgrs = 3,
 	.num_ovls = 4,
 	.supported_displays = omap4_dss_supported_displays,
+	.supported_outputs = omap4_dss_supported_outputs,
 	.supported_color_modes = omap4_dss_supported_color_modes,
 	.overlay_caps = omap4_dss_overlay_caps,
 	.clksrc_names = omap4_dss_clk_source_names,
@@ -539,6 +584,7 @@ static const struct omap_dss_features omap4430_es2_0_1_2_dss_features = {
 	.num_mgrs = 3,
 	.num_ovls = 4,
 	.supported_displays = omap4_dss_supported_displays,
+	.supported_outputs = omap4_dss_supported_outputs,
 	.supported_color_modes = omap4_dss_supported_color_modes,
 	.overlay_caps = omap4_dss_overlay_caps,
 	.clksrc_names = omap4_dss_clk_source_names,
@@ -559,6 +605,7 @@ static const struct omap_dss_features omap4_dss_features = {
 	.num_mgrs = 3,
 	.num_ovls = 4,
 	.supported_displays = omap4_dss_supported_displays,
+	.supported_outputs = omap4_dss_supported_outputs,
 	.supported_color_modes = omap4_dss_supported_color_modes,
 	.overlay_caps = omap4_dss_overlay_caps,
 	.clksrc_names = omap4_dss_clk_source_names,
@@ -628,6 +675,11 @@ enum omap_display_type dss_feat_get_supported_displays(enum omap_channel channel
 	return omap_current_dss_features->supported_displays[channel];
 }
 
+enum omap_dss_output_id dss_feat_get_supported_outputs(enum omap_channel channel)
+{
+	return omap_current_dss_features->supported_outputs[channel];
+}
+
 enum omap_color_mode dss_feat_get_supported_color_modes(enum omap_plane plane)
 {
 	return omap_current_dss_features->supported_color_modes[plane];
diff --git a/drivers/video/omap2/dss/dss_features.h b/drivers/video/omap2/dss/dss_features.h
index 26d43a4..5fe62a8 100644
--- a/drivers/video/omap2/dss/dss_features.h
+++ b/drivers/video/omap2/dss/dss_features.h
@@ -104,6 +104,7 @@ int dss_feat_get_num_ovls(void);
 unsigned long dss_feat_get_param_min(enum dss_range_param param);
 unsigned long dss_feat_get_param_max(enum dss_range_param param);
 enum omap_display_type dss_feat_get_supported_displays(enum omap_channel channel);
+enum omap_dss_output_id dss_feat_get_supported_outputs(enum omap_channel channel);
 enum omap_color_mode dss_feat_get_supported_color_modes(enum omap_plane plane);
 enum omap_overlay_caps dss_feat_get_overlay_caps(enum omap_plane plane);
 bool dss_feat_color_mode_supported(enum omap_plane plane,
diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c
index 53710fa..e15fa5f 100644
--- a/drivers/video/omap2/dss/manager.c
+++ b/drivers/video/omap2/dss/manager.c
@@ -549,6 +549,8 @@ int dss_init_overlay_managers(struct platform_device *pdev)
 
 		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;
 		mgr->set_manager_info = &dss_mgr_set_info;
 		mgr->get_manager_info = &dss_mgr_get_info;
@@ -558,6 +560,8 @@ int dss_init_overlay_managers(struct platform_device *pdev)
 		mgr->caps = 0;
 		mgr->supported_displays  			dss_feat_get_supported_displays(mgr->id);
+		mgr->supported_outputs +			dss_feat_get_supported_outputs(mgr->id);
 
 		INIT_LIST_HEAD(&mgr->overlays);
 
diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index b3fba19..a3b35f9 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -458,9 +458,11 @@ struct omap_overlay_manager {
 	enum omap_overlay_manager_caps caps;
 	struct list_head overlays;
 	enum omap_display_type supported_displays;
+	enum omap_dss_output_id supported_outputs;
 
 	/* dynamic fields */
 	struct omap_dss_device *device;
+	struct omap_dss_output *output;
 
 	/*
 	 * The following functions do not block:
@@ -476,6 +478,9 @@ struct omap_overlay_manager {
 	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);
 
 	int (*set_manager_info)(struct omap_overlay_manager *mgr,
 			struct omap_overlay_manager_info *info);
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [PATCH v2 05/23] OMAPDSS: Remove manager->device references
@ 2012-08-30 11:52     ` Archit Taneja
  0 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-08-30 11:52 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: rob, linux-omap, linux-fbdev, Archit Taneja

With the introduction of output entities, managers will now connect to outputs.
Create a helper op for managers named get_device. This will abstract away the
information on how to get the device from an overlay manager. The get_device
op currently retrieves the output via a manager->device reference. This will
be later replaced by a manager->output->device reference.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/dss/apply.c   |    6 ++++--
 drivers/video/omap2/dss/dispc.c   |   10 +++++++---
 drivers/video/omap2/dss/manager.c |   19 ++++++++++++++-----
 include/video/omapdss.h           |    2 ++
 4 files changed, 27 insertions(+), 10 deletions(-)

diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c
index d241407..8a05cbc 100644
--- a/drivers/video/omap2/dss/apply.c
+++ b/drivers/video/omap2/dss/apply.c
@@ -1607,7 +1607,8 @@ int dss_ovl_enable(struct omap_overlay *ovl)
 		goto err1;
 	}
 
-	if (ovl->manager = NULL || ovl->manager->device = NULL) {
+	if (ovl->manager = NULL ||
+			ovl->manager->get_device(ovl->manager) = NULL) {
 		r = -EINVAL;
 		goto err1;
 	}
@@ -1676,7 +1677,8 @@ int dss_ovl_disable(struct omap_overlay *ovl)
 		goto err;
 	}
 
-	if (ovl->manager = NULL || ovl->manager->device = NULL) {
+	if (ovl->manager = NULL ||
+			ovl->manager->get_device(ovl->manager) = NULL) {
 		r = -EINVAL;
 		goto err;
 	}
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index 0de9a7e..bfd73f5 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -3549,7 +3549,7 @@ static void dispc_error_worker(struct work_struct *work)
 		bit = mgr_desc[i].sync_lost_irq;
 
 		if (bit & errors) {
-			struct omap_dss_device *dssdev = mgr->device;
+			struct omap_dss_device *dssdev = mgr->get_device(mgr);
 			bool enable;
 
 			DSSERR("SYNC_LOST on channel %s, restarting the output "
@@ -3580,9 +3580,13 @@ static void dispc_error_worker(struct work_struct *work)
 		DSSERR("OCP_ERR\n");
 		for (i = 0; i < omap_dss_get_num_overlay_managers(); ++i) {
 			struct omap_overlay_manager *mgr;
+			struct omap_dss_device *dssdev;
+
 			mgr = omap_dss_get_overlay_manager(i);
-			if (mgr->device && mgr->device->driver)
-				mgr->device->driver->disable(mgr->device);
+			dssdev = mgr->get_device(mgr);
+
+			if (dssdev && dssdev->driver)
+				dssdev->driver->disable(dssdev);
 		}
 	}
 
diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c
index e15fa5f..fd39f66 100644
--- a/drivers/video/omap2/dss/manager.c
+++ b/drivers/video/omap2/dss/manager.c
@@ -43,8 +43,10 @@ static ssize_t manager_name_show(struct omap_overlay_manager *mgr, char *buf)
 
 static ssize_t manager_display_show(struct omap_overlay_manager *mgr, char *buf)
 {
-	return snprintf(buf, PAGE_SIZE, "%s\n",
-			mgr->device ? mgr->device->name : "<none>");
+	struct omap_dss_device *dssdev = mgr->get_device(mgr);
+
+	return snprintf(buf, PAGE_SIZE, "%s\n", dssdev ?
+			dssdev->name : "<none>");
 }
 
 static ssize_t manager_display_store(struct omap_overlay_manager *mgr,
@@ -72,7 +74,7 @@ static ssize_t manager_display_store(struct omap_overlay_manager *mgr,
 	if (dssdev)
 		DSSDBG("display %s found\n", dssdev->name);
 
-	if (mgr->device) {
+	if (mgr->get_device(mgr)) {
 		r = mgr->unset_device(mgr);
 		if (r) {
 			DSSERR("failed to unset display\n");
@@ -490,9 +492,15 @@ static struct kobj_type manager_ktype = {
 	.default_attrs = manager_sysfs_attrs,
 };
 
+static inline struct omap_dss_device *dss_mgr_get_device(struct omap_overlay_manager *mgr)
+{
+	return mgr->device;
+}
+
 static int dss_mgr_wait_for_vsync(struct omap_overlay_manager *mgr)
 {
 	unsigned long timeout = msecs_to_jiffies(500);
+	struct omap_dss_device *dssdev = mgr->get_device(mgr);
 	u32 irq;
 	int r;
 
@@ -500,9 +508,9 @@ static int dss_mgr_wait_for_vsync(struct omap_overlay_manager *mgr)
 	if (r)
 		return r;
 
-	if (mgr->device->type = OMAP_DISPLAY_TYPE_VENC)
+	if (dssdev->type = OMAP_DISPLAY_TYPE_VENC)
 		irq = DISPC_IRQ_EVSYNC_ODD;
-	else if (mgr->device->type = OMAP_DISPLAY_TYPE_HDMI)
+	else if (dssdev->type = OMAP_DISPLAY_TYPE_HDMI)
 		irq = DISPC_IRQ_EVSYNC_EVEN;
 	else
 		irq = dispc_mgr_get_vsync_irq(mgr->id);
@@ -556,6 +564,7 @@ int dss_init_overlay_managers(struct platform_device *pdev)
 		mgr->get_manager_info = &dss_mgr_get_info;
 		mgr->wait_for_go = &dss_mgr_wait_for_go;
 		mgr->wait_for_vsync = &dss_mgr_wait_for_vsync;
+		mgr->get_device = &dss_mgr_get_device;
 
 		mgr->caps = 0;
 		mgr->supported_displays diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index a3b35f9..29c1440 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -490,6 +490,8 @@ struct omap_overlay_manager {
 	int (*apply)(struct omap_overlay_manager *mgr);
 	int (*wait_for_go)(struct omap_overlay_manager *mgr);
 	int (*wait_for_vsync)(struct omap_overlay_manager *mgr);
+
+	struct omap_dss_device *(*get_device)(struct omap_overlay_manager *mgr);
 };
 
 /* 22 pins means 1 clk lane and 10 data lanes */
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [PATCH v2 06/23] OMAP_VOUT: Remove manager->device references
@ 2012-08-30 11:52     ` Archit Taneja
  0 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-08-30 11:52 UTC (permalink / raw)
  To: tomi.valkeinen
  Cc: rob, linux-omap, linux-fbdev, Archit Taneja, Vaibhav Hiremath

With the introduction of output entities, managers will now connect to outputs.
Use the helper op for managers named get_device. This will abstract away the
information on how to get the device from an overlay manager.

Using the helper function will reduce the number of pointer dereferences a user
of OMAPDSS needs to do and reduce risk of a NULL dereference.

Cc: Vaibhav Hiremath <hvaibhav@ti.com>
Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/media/video/omap/omap_vout.c |   81 ++++++++++++++++++++++++----------
 1 file changed, 57 insertions(+), 24 deletions(-)

diff --git a/drivers/media/video/omap/omap_vout.c b/drivers/media/video/omap/omap_vout.c
index 88cf9d9..0ebf87e 100644
--- a/drivers/media/video/omap/omap_vout.c
+++ b/drivers/media/video/omap/omap_vout.c
@@ -454,11 +454,16 @@ static int omapvid_init(struct omap_vout_device *vout, u32 addr)
 
 	win = &vout->win;
 	for (i = 0; i < ovid->num_overlays; i++) {
+		struct omap_dss_device *dssdev;
+
 		ovl = ovid->overlays[i];
-		if (!ovl->manager || !ovl->manager->device)
+		dssdev = ovl->manager ?
+			ovl->manager->get_device(ovl->manager) : NULL;
+
+		if (!dssdev)
 			return -EINVAL;
 
-		timing = &ovl->manager->device->panel.timings;
+		timing = &dssdev->panel.timings;
 
 		outw = win->w.width;
 		outh = win->w.height;
@@ -515,8 +520,12 @@ static int omapvid_apply_changes(struct omap_vout_device *vout)
 	struct omapvideo_info *ovid = &vout->vid_info;
 
 	for (i = 0; i < ovid->num_overlays; i++) {
+		struct omap_dss_device *dssdev;
+
 		ovl = ovid->overlays[i];
-		if (!ovl->manager || !ovl->manager->device)
+		dssdev = ovl->manager ?
+			ovl->manager->get_device(ovl->manager) : NULL;
+		if (!dssdev)
 			return -EINVAL;
 		ovl->manager->apply(ovl->manager);
 	}
@@ -579,12 +588,15 @@ static void omap_vout_isr(void *arg, unsigned int irqstatus)
 
 	ovid = &vout->vid_info;
 	ovl = ovid->overlays[0];
-	/* get the display device attached to the overlay */
-	if (!ovl->manager || !ovl->manager->device)
-		return;
 
 	mgr_id = ovl->manager->id;
-	cur_display = ovl->manager->device;
+
+	/* get the display device attached to the overlay */
+	cur_display = ovl->manager ?
+		ovl->manager->get_device(ovl->manager) : NULL;
+
+	if (!cur_display)
+		return;
 
 	spin_lock(&vout->vbq_lock);
 	do_gettimeofday(&timevalue);
@@ -948,7 +960,10 @@ static int omap_vout_release(struct file *file)
 	/* Disable all the overlay managers connected with this interface */
 	for (i = 0; i < ovid->num_overlays; i++) {
 		struct omap_overlay *ovl = ovid->overlays[i];
-		if (ovl->manager && ovl->manager->device)
+		struct omap_dss_device *dssdev = ovl->manager ?
+			ovl->manager->get_device(ovl->manager) : NULL;
+
+		if (dssdev)
 			ovl->disable(ovl);
 	}
 	/* Turn off the pipeline */
@@ -1081,14 +1096,17 @@ static int vidioc_try_fmt_vid_out(struct file *file, void *fh,
 	struct omapvideo_info *ovid;
 	struct omap_video_timings *timing;
 	struct omap_vout_device *vout = fh;
+	struct omap_dss_device *dssdev;
 
 	ovid = &vout->vid_info;
 	ovl = ovid->overlays[0];
+	/* get the display device attached to the overlay */
+	dssdev = ovl->manager ? ovl->manager->get_device(ovl->manager) : NULL;
 
-	if (!ovl->manager || !ovl->manager->device)
+	if (!dssdev)
 		return -EINVAL;
-	/* get the display device attached to the overlay */
-	timing = &ovl->manager->device->panel.timings;
+
+	timing = &dssdev->panel.timings;
 
 	vout->fbuf.fmt.height = timing->y_res;
 	vout->fbuf.fmt.width = timing->x_res;
@@ -1105,6 +1123,7 @@ static int vidioc_s_fmt_vid_out(struct file *file, void *fh,
 	struct omapvideo_info *ovid;
 	struct omap_video_timings *timing;
 	struct omap_vout_device *vout = fh;
+	struct omap_dss_device *dssdev;
 
 	if (vout->streaming)
 		return -EBUSY;
@@ -1113,13 +1132,14 @@ static int vidioc_s_fmt_vid_out(struct file *file, void *fh,
 
 	ovid = &vout->vid_info;
 	ovl = ovid->overlays[0];
+	dssdev = ovl->manager ? ovl->manager->get_device(ovl->manager) : NULL;
 
 	/* get the display device attached to the overlay */
-	if (!ovl->manager || !ovl->manager->device) {
+	if (!dssdev) {
 		ret = -EINVAL;
 		goto s_fmt_vid_out_exit;
 	}
-	timing = &ovl->manager->device->panel.timings;
+	timing = &dssdev->panel.timings;
 
 	/* We dont support RGB24-packed mode if vrfb rotation
 	 * is enabled*/
@@ -1298,6 +1318,7 @@ static int vidioc_s_crop(struct file *file, void *fh, struct v4l2_crop *crop)
 	struct omapvideo_info *ovid;
 	struct omap_overlay *ovl;
 	struct omap_video_timings *timing;
+	struct omap_dss_device *dssdev;
 
 	if (vout->streaming)
 		return -EBUSY;
@@ -1305,13 +1326,15 @@ static int vidioc_s_crop(struct file *file, void *fh, struct v4l2_crop *crop)
 	mutex_lock(&vout->lock);
 	ovid = &vout->vid_info;
 	ovl = ovid->overlays[0];
+	/* get the display device attached to the overlay */
+	dssdev = ovl->manager ? ovl->manager->get_device(ovl->manager) : NULL;
 
-	if (!ovl->manager || !ovl->manager->device) {
+	if (!dssdev) {
 		ret = -EINVAL;
 		goto s_crop_err;
 	}
-	/* get the display device attached to the overlay */
-	timing = &ovl->manager->device->panel.timings;
+
+	timing = &dssdev->panel.timings;
 
 	if (is_rotation_90_or_270(vout)) {
 		vout->fbuf.fmt.height = timing->x_res;
@@ -1666,8 +1689,9 @@ static int vidioc_streamon(struct file *file, void *fh, enum v4l2_buf_type i)
 
 	for (j = 0; j < ovid->num_overlays; j++) {
 		struct omap_overlay *ovl = ovid->overlays[j];
+		struct omap_overlay_manager *mgr = ovl->manager;
 
-		if (ovl->manager && ovl->manager->device) {
+		if (mgr && mgr->get_device(mgr)) {
 			struct omap_overlay_info info;
 			ovl->get_overlay_info(ovl, &info);
 			info.paddr = addr;
@@ -1690,8 +1714,10 @@ static int vidioc_streamon(struct file *file, void *fh, enum v4l2_buf_type i)
 
 	for (j = 0; j < ovid->num_overlays; j++) {
 		struct omap_overlay *ovl = ovid->overlays[j];
+		struct omap_dss_device *dssdev = ovl->manager ?
+			ovl->manager->get_device(ovl->manager) : NULL;
 
-		if (ovl->manager && ovl->manager->device) {
+		if (dssdev) {
 			ret = ovl->enable(ovl);
 			if (ret)
 				goto streamon_err1;
@@ -1726,8 +1752,10 @@ static int vidioc_streamoff(struct file *file, void *fh, enum v4l2_buf_type i)
 
 	for (j = 0; j < ovid->num_overlays; j++) {
 		struct omap_overlay *ovl = ovid->overlays[j];
+		struct omap_dss_device *dssdev = ovl->manager ?
+			ovl->manager->get_device(ovl->manager) : NULL;
 
-		if (ovl->manager && ovl->manager->device)
+		if (dssdev)
 			ovl->disable(ovl);
 	}
 
@@ -1890,8 +1918,9 @@ static int __init omap_vout_setup_video_data(struct omap_vout_device *vout)
 	struct video_device *vfd;
 	struct v4l2_pix_format *pix;
 	struct v4l2_control *control;
+	struct omap_overlay *ovl = vout->vid_info.overlays[0];
 	struct omap_dss_device *display -		vout->vid_info.overlays[0]->manager->device;
+		ovl->manager->get_device(ovl->manager);
 
 	/* set the default pix */
 	pix = &vout->pix;
@@ -2205,8 +2234,10 @@ static int __init omap_vout_probe(struct platform_device *pdev)
 	 */
 	for (i = 1; i < vid_dev->num_overlays; i++) {
 		ovl = omap_dss_get_overlay(i);
-		if (ovl->manager && ovl->manager->device) {
-			def_display = ovl->manager->device;
+		dssdev = ovl->manager ? ovl->manager->get_device(ovl->manager) :
+				NULL;
+		if (dssdev) {
+			def_display = dssdev;
 		} else {
 			dev_warn(&pdev->dev, "cannot find display\n");
 			def_display = NULL;
@@ -2253,8 +2284,10 @@ probe_err1:
 	for (i = 1; i < vid_dev->num_overlays; i++) {
 		def_display = NULL;
 		ovl = omap_dss_get_overlay(i);
-		if (ovl->manager && ovl->manager->device)
-			def_display = ovl->manager->device;
+		dssdev = ovl->manager ? ovl->manager->get_device(ovl->manager) :
+				NULL;
+		if (dssdev)
+			def_display = dssdev;
 
 		if (def_display && def_display->driver)
 			def_display->driver->disable(def_display);
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [PATCH v2 07/23] OMAPFB: remove manager->device references
@ 2012-08-30 11:52     ` Archit Taneja
  0 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-08-30 11:52 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: rob, linux-omap, linux-fbdev, Archit Taneja

With the introduction of output entities, managers will now connect to outputs.
Use the helper op for managers named get_device. This will abstract away the
information on how to get the device from an overlay manager.

Using the helper function will reduce the number of pointer dereferences a user
of OMAPDSS needs to do and reduce risk of a NULL dereference.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/omapfb/omapfb-main.c |    7 +++++--
 drivers/video/omap2/omapfb/omapfb.h      |    5 +++--
 2 files changed, 8 insertions(+), 4 deletions(-)

diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c
index fc671d3..c6992be 100644
--- a/drivers/video/omap2/omapfb/omapfb-main.c
+++ b/drivers/video/omap2/omapfb/omapfb-main.c
@@ -2353,6 +2353,7 @@ static int __init omapfb_probe(struct platform_device *pdev)
 	struct omap_overlay *ovl;
 	struct omap_dss_device *def_display;
 	struct omap_dss_device *dssdev;
+	struct omap_dss_device *mgr_device;
 
 	DBG("omapfb_probe\n");
 
@@ -2426,8 +2427,10 @@ static int __init omapfb_probe(struct platform_device *pdev)
 	/* gfx overlay should be the default one. find a display
 	 * connected to that, and use it as default display */
 	ovl = omap_dss_get_overlay(0);
-	if (ovl->manager && ovl->manager->device) {
-		def_display = ovl->manager->device;
+	mgr_device = ovl->manager ?
+		ovl->manager->get_device(ovl->manager) : NULL;
+	if (mgr_device) {
+		def_display = mgr_device;
 	} else {
 		dev_warn(&pdev->dev, "cannot find default display\n");
 		def_display = NULL;
diff --git a/drivers/video/omap2/omapfb/omapfb.h b/drivers/video/omap2/omapfb/omapfb.h
index 30361a0..2782b1f 100644
--- a/drivers/video/omap2/omapfb/omapfb.h
+++ b/drivers/video/omap2/omapfb/omapfb.h
@@ -148,8 +148,9 @@ static inline struct omap_dss_device *fb2display(struct fb_info *fbi)
 
 	/* XXX: returns the display connected to first attached overlay */
 	for (i = 0; i < ofbi->num_overlays; i++) {
-		if (ofbi->overlays[i]->manager)
-			return ofbi->overlays[i]->manager->device;
+		struct omap_overlay_manager *mgr = ofbi->overlays[i]->manager;
+		if (mgr)
+			return mgr->get_device(mgr);
 	}
 
 	return NULL;
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [PATCH v2 08/23] OMAPDRM: Remove manager->device references
@ 2012-08-30 11:52     ` Archit Taneja
  0 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-08-30 11:52 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: rob, linux-omap, linux-fbdev, Archit Taneja

With the introduction of output entities, managers will now connect to outputs.
Use the helper op for managers named get_device. This will abstract away the
information on how to get the device from an overlay manager.

Using the helper function will reduce the number of pointer dereferences a user
of OMAPDSS needs to do and reduce risk of a NULL dereference.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/staging/omapdrm/omap_drv.c |    5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/staging/omapdrm/omap_drv.c b/drivers/staging/omapdrm/omap_drv.c
index 4beab94..64a354a 100644
--- a/drivers/staging/omapdrm/omap_drv.c
+++ b/drivers/staging/omapdrm/omap_drv.c
@@ -106,7 +106,8 @@ static void dump_video_chains(void)
 	for (i = 0; i < omap_dss_get_num_overlays(); i++) {
 		struct omap_overlay *ovl = omap_dss_get_overlay(i);
 		struct omap_overlay_manager *mgr = ovl->manager;
-		struct omap_dss_device *dssdev = mgr ? mgr->device : NULL;
+		struct omap_dss_device *dssdev = mgr ?
+					mgr->get_device(mgr) : NULL;
 		if (dssdev) {
 			DBG("%d: %s -> %s -> %s", i, ovl->name, mgr->name,
 						dssdev->name);
@@ -185,7 +186,7 @@ static int create_connector(struct drm_device *dev,
 	for (j = 0; j < priv->num_encoders; j++) {
 		struct omap_overlay_manager *mgr  			omap_encoder_get_manager(priv->encoders[j]);
-		if (mgr->device = dssdev) {
+		if (mgr->get_device(mgr) = dssdev) {
 			drm_mode_connector_attach_encoder(connector,
 					priv->encoders[j]);
 		}
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [PATCH v2 09/23] OMAPDSS: Create links between managers, outputs and devices
@ 2012-08-30 11:52     ` Archit Taneja
  0 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-08-30 11:52 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: rob, linux-omap, linux-fbdev, Archit Taneja

Links between DSS entities are made in dss_recheck_connections when a new panel
is probed. Rewrite the code in dss_recheck_connections to link managers to
outputs, and outputs to devices.

The fields in omap_dss_device struct gives information on which output and
manager to connect to. The desired manager and output pointers are retrieved and
prepared(existing outputs/devices unset, if default display)) to form the
desired links. The output is linked to the device, and then the manager to the
output. If a probed device's required manager isn't free, the required output
is still connected to the device so that it's easier to use the panel in the
future.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/dss/overlay.c |   96 +++++++++++++++++++++----------------
 1 file changed, 56 insertions(+), 40 deletions(-)

diff --git a/drivers/video/omap2/dss/overlay.c b/drivers/video/omap2/dss/overlay.c
index 952c6fa..07605f1 100644
--- a/drivers/video/omap2/dss/overlay.c
+++ b/drivers/video/omap2/dss/overlay.c
@@ -525,51 +525,67 @@ void dss_init_overlays(struct platform_device *pdev)
 void dss_recheck_connections(struct omap_dss_device *dssdev, bool force)
 {
 	int i;
-	struct omap_overlay_manager *lcd_mgr;
-	struct omap_overlay_manager *tv_mgr;
-	struct omap_overlay_manager *lcd2_mgr = NULL;
-	struct omap_overlay_manager *lcd3_mgr = NULL;
 	struct omap_overlay_manager *mgr = NULL;
+	struct omap_dss_output *out = NULL;
+	enum omap_dss_output_id id;
+
+	switch (dssdev->type) {
+	case OMAP_DISPLAY_TYPE_DPI:
+		out = omap_dss_get_output(OMAP_DSS_OUTPUT_DPI);
+		break;
+	case OMAP_DISPLAY_TYPE_DBI:
+		out = omap_dss_get_output(OMAP_DSS_OUTPUT_DBI);
+		break;
+	case OMAP_DISPLAY_TYPE_SDI:
+		out = omap_dss_get_output(OMAP_DSS_OUTPUT_SDI);
+		break;
+	case OMAP_DISPLAY_TYPE_VENC:
+		out = omap_dss_get_output(OMAP_DSS_OUTPUT_VENC);
+		break;
+	case OMAP_DISPLAY_TYPE_HDMI:
+		out = omap_dss_get_output(OMAP_DSS_OUTPUT_HDMI);
+		break;
+	case OMAP_DISPLAY_TYPE_DSI:
+		id = dssdev->phy.dsi.module = 0 ? OMAP_DSS_OUTPUT_DSI1 :
+					OMAP_DSS_OUTPUT_DSI2;
+		out = omap_dss_get_output(id);
+		break;
+	default:
+		break;
+	}
 
-	lcd_mgr = omap_dss_get_overlay_manager(OMAP_DSS_CHANNEL_LCD);
-	tv_mgr = omap_dss_get_overlay_manager(OMAP_DSS_CHANNEL_DIGIT);
-	if (dss_has_feature(FEAT_MGR_LCD3))
-		lcd3_mgr = omap_dss_get_overlay_manager(OMAP_DSS_CHANNEL_LCD3);
-	if (dss_has_feature(FEAT_MGR_LCD2))
-		lcd2_mgr = omap_dss_get_overlay_manager(OMAP_DSS_CHANNEL_LCD2);
-
-	if (dssdev->channel = OMAP_DSS_CHANNEL_LCD3) {
-		if (!lcd3_mgr->device || force) {
-			if (lcd3_mgr->device)
-				lcd3_mgr->unset_device(lcd3_mgr);
-			lcd3_mgr->set_device(lcd3_mgr, dssdev);
-			mgr = lcd3_mgr;
-		}
-	} else if (dssdev->channel = OMAP_DSS_CHANNEL_LCD2) {
-		if (!lcd2_mgr->device || force) {
-			if (lcd2_mgr->device)
-				lcd2_mgr->unset_device(lcd2_mgr);
-			lcd2_mgr->set_device(lcd2_mgr, dssdev);
-			mgr = lcd2_mgr;
-		}
-	} else if (dssdev->type != OMAP_DISPLAY_TYPE_VENC
-			&& dssdev->type != OMAP_DISPLAY_TYPE_HDMI) {
-		if (!lcd_mgr->device || force) {
-			if (lcd_mgr->device)
-				lcd_mgr->unset_device(lcd_mgr);
-			lcd_mgr->set_device(lcd_mgr, dssdev);
-			mgr = lcd_mgr;
-		}
+	/*
+	 * We don't want to touch board files and mention channel for VENC
+	 * devices. Force the channel as DIGIT for HDMI and VENC devices
+	 */
+	if (dssdev->type = OMAP_DISPLAY_TYPE_VENC ||
+			dssdev->type = OMAP_DISPLAY_TYPE_HDMI)
+		dssdev->channel = OMAP_DSS_CHANNEL_DIGIT;
+
+	mgr = omap_dss_get_overlay_manager(dssdev->channel);
+
+	if (!mgr || !out) {
+		DSSERR("Incorrect manager or output\n");
+		return;
 	}
 
-	if (dssdev->type = OMAP_DISPLAY_TYPE_VENC
-			|| dssdev->type = OMAP_DISPLAY_TYPE_HDMI) {
-		if (!tv_mgr->device || force) {
-			if (tv_mgr->device)
-				tv_mgr->unset_device(tv_mgr);
-			tv_mgr->set_device(tv_mgr, dssdev);
-			mgr = tv_mgr;
+	if (!mgr->output || force) {
+		struct omap_dss_output *curr_out = mgr->output;
+
+		if (curr_out) {
+			if (curr_out->device)
+				curr_out->unset_device(curr_out);
+			mgr->unset_output(mgr);
 		}
+		out->set_device(out, dssdev);
+		mgr->set_output(mgr, out);
+	} else {
+		/*
+		 * connect a floating output to the device even if the desired
+		 * manager is in use
+		 */
+		if (!out->manager && !out->device)
+			out->set_device(out, dssdev);
 	}
 
 	if (mgr) {
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [PATCH v2 10/23] OMAPDSS: DPI: Pass omap_dss_output within the driver
@ 2012-08-30 11:52     ` Archit Taneja
  0 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-08-30 11:52 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: rob, linux-omap, linux-fbdev, Archit Taneja

When a panel driver calls a DPI function, it passes the omap_dss_device
pointer, this pointer currently propagates within the DPI driver to configure
the interface.

Extract the omap_dss_output pointer from omap_dss_device received from the panel
driver, pass the output pointer to DPI functions local to the driver to
configure the interface, these functions no longer need omap_dss_device since
the driver now maintains a copy of output parameters.

Replace dssdev->manager references with out->manager references as only these
will be valid later.

With the addition of outputs. There is a possibility that an omap_dss_device
isn't connected to an output, or a manager isn't connected to an output yet.
Ensure that the DPI interface functions proceed only if the output is non NULL.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/dss/dpi.c |   55 +++++++++++++++++++++++++----------------
 1 file changed, 34 insertions(+), 21 deletions(-)

diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c
index 9a7aee5..cb17adb 100644
--- a/drivers/video/omap2/dss/dpi.c
+++ b/drivers/video/omap2/dss/dpi.c
@@ -73,7 +73,7 @@ static bool dpi_use_dsi_pll(struct omap_dss_device *dssdev)
 		return false;
 }
 
-static int dpi_set_dsi_clk(struct omap_dss_device *dssdev,
+static int dpi_set_dsi_clk(struct omap_dss_output *out,
 		unsigned long pck_req, unsigned long *fck, int *lck_div,
 		int *pck_div)
 {
@@ -90,7 +90,7 @@ static int dpi_set_dsi_clk(struct omap_dss_device *dssdev,
 	if (r)
 		return r;
 
-	dss_select_dispc_clk_source(dssdev->clocks.dispc.dispc_fclk_src);
+	dss_select_dispc_clk_source(out->device->clocks.dispc.dispc_fclk_src);
 
 	dpi.mgr_config.clock_info = dispc_cinfo;
 
@@ -101,7 +101,7 @@ static int dpi_set_dsi_clk(struct omap_dss_device *dssdev,
 	return 0;
 }
 
-static int dpi_set_dispc_clk(struct omap_dss_device *dssdev,
+static int dpi_set_dispc_clk(struct omap_dss_output *out,
 		unsigned long pck_req, unsigned long *fck, int *lck_div,
 		int *pck_div)
 {
@@ -126,7 +126,7 @@ static int dpi_set_dispc_clk(struct omap_dss_device *dssdev,
 	return 0;
 }
 
-static int dpi_set_mode(struct omap_dss_device *dssdev)
+static int dpi_set_mode(struct omap_dss_output *out)
 {
 	struct omap_video_timings *t = &dpi.timings;
 	int lck_div = 0, pck_div = 0;
@@ -134,11 +134,11 @@ static int dpi_set_mode(struct omap_dss_device *dssdev)
 	unsigned long pck;
 	int r = 0;
 
-	if (dpi_use_dsi_pll(dssdev))
-		r = dpi_set_dsi_clk(dssdev, t->pixel_clock * 1000, &fck,
+	if (dpi_use_dsi_pll(out->device))
+		r = dpi_set_dsi_clk(out, t->pixel_clock * 1000, &fck,
 				&lck_div, &pck_div);
 	else
-		r = dpi_set_dispc_clk(dssdev, t->pixel_clock * 1000, &fck,
+		r = dpi_set_dispc_clk(out, t->pixel_clock * 1000, &fck,
 				&lck_div, &pck_div);
 	if (r)
 		return r;
@@ -153,12 +153,12 @@ static int dpi_set_mode(struct omap_dss_device *dssdev)
 		t->pixel_clock = pck;
 	}
 
-	dss_mgr_set_timings(dssdev->manager, t);
+	dss_mgr_set_timings(out->manager, t);
 
 	return 0;
 }
 
-static void dpi_config_lcd_manager(struct omap_dss_device *dssdev)
+static void dpi_config_lcd_manager(struct omap_dss_output *out)
 {
 	dpi.mgr_config.io_pad_mode = DSS_IO_PAD_MODE_BYPASS;
 
@@ -169,11 +169,12 @@ static void dpi_config_lcd_manager(struct omap_dss_device *dssdev)
 
 	dpi.mgr_config.lcden_sig_polarity = 0;
 
-	dss_mgr_set_lcd_config(dssdev->manager, &dpi.mgr_config);
+	dss_mgr_set_lcd_config(out->manager, &dpi.mgr_config);
 }
 
 int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
 {
+	struct omap_dss_output *out = dssdev->output;
 	int r;
 
 	mutex_lock(&dpi.lock);
@@ -184,10 +185,10 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
 		goto err_no_reg;
 	}
 
-	if (dssdev->manager = NULL) {
-		DSSERR("failed to enable display: no manager\n");
+	if (out = NULL || out->manager = NULL) {
+		DSSERR("failed to enable display: no output/manager\n");
 		r = -ENODEV;
-		goto err_no_mgr;
+		goto err_no_out_mgr;
 	}
 
 	r = omap_dss_start_device(dssdev);
@@ -216,15 +217,15 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
 			goto err_dsi_pll_init;
 	}
 
-	r = dpi_set_mode(dssdev);
+	r = dpi_set_mode(out);
 	if (r)
 		goto err_set_mode;
 
-	dpi_config_lcd_manager(dssdev);
+	dpi_config_lcd_manager(out);
 
 	mdelay(2);
 
-	r = dss_mgr_enable(dssdev->manager);
+	r = dss_mgr_enable(out->manager);
 	if (r)
 		goto err_mgr_enable;
 
@@ -247,7 +248,7 @@ err_get_dispc:
 err_reg_enable:
 	omap_dss_stop_device(dssdev);
 err_start_dev:
-err_no_mgr:
+err_no_out_mgr:
 err_no_reg:
 	mutex_unlock(&dpi.lock);
 	return r;
@@ -256,9 +257,11 @@ EXPORT_SYMBOL(omapdss_dpi_display_enable);
 
 void omapdss_dpi_display_disable(struct omap_dss_device *dssdev)
 {
+	struct omap_dss_output *out = dssdev->output;
+
 	mutex_lock(&dpi.lock);
 
-	dss_mgr_disable(dssdev->manager);
+	dss_mgr_disable(out->manager);
 
 	if (dpi_use_dsi_pll(dssdev)) {
 		dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK);
@@ -280,10 +283,16 @@ EXPORT_SYMBOL(omapdss_dpi_display_disable);
 void omapdss_dpi_set_timings(struct omap_dss_device *dssdev,
 		struct omap_video_timings *timings)
 {
+	struct omap_dss_output *out = dssdev->output;
 	int r;
 
 	DSSDBG("dpi_set_timings\n");
 
+	if (out = NULL) {
+		DSSERR("No output connected to %s\n", dssdev->name);
+		return;
+	}
+
 	mutex_lock(&dpi.lock);
 
 	dpi.timings = *timings;
@@ -293,11 +302,11 @@ void omapdss_dpi_set_timings(struct omap_dss_device *dssdev,
 		if (r)
 			return;
 
-		dpi_set_mode(dssdev);
+		dpi_set_mode(out);
 
 		dispc_runtime_put();
 	} else {
-		dss_mgr_set_timings(dssdev->manager, timings);
+		dss_mgr_set_timings(out->manager, timings);
 	}
 
 	mutex_unlock(&dpi.lock);
@@ -312,8 +321,12 @@ int dpi_check_timings(struct omap_dss_device *dssdev,
 	unsigned long fck;
 	unsigned long pck;
 	struct dispc_clock_info dispc_cinfo;
+	struct omap_dss_output *out = dssdev->output;
+
+	if (out = NULL)
+		return -ENODEV;
 
-	if (dss_mgr_check_timings(dssdev->manager, timings))
+	if (dss_mgr_check_timings(out->manager, timings))
 		return -EINVAL;
 
 	if (timings->pixel_clock = 0)
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [PATCH v2 11/23] OMAPDSS: DSI: Remove dsi_pdev_map global struct
@ 2012-08-30 11:52     ` Archit Taneja
  0 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-08-30 11:52 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: rob, linux-omap, linux-fbdev, Archit Taneja

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 6a83ab7..78212c4 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -346,8 +346,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);
@@ -360,12 +358,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,
@@ -4933,7 +4938,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	[flat|nested] 148+ messages in thread

* [PATCH v2 12/23] OMAPDSS: DSI: Pass omap_dss_output within the driver
@ 2012-08-30 11:52     ` Archit Taneja
  0 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-08-30 11:52 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: rob, linux-omap, linux-fbdev, Archit Taneja

When a panel driver calls a DSI function, it passes the omap_dss_device
pointer, this pointer currently propagates within the DSI driver to configure
the interface.

Extract the omap_dss_output pointer from omap_dss_device received from the panel
driver, pass the output pointer to DSI functions local to the driver to
configure the interface, these functions no longer need omap_dss_device since
the driver now maintains a copy of output parameters.

Replace dssdev->manager references with out->manager references as only these
will be valid later.

With the addition of outputs. There is a possibility that an omap_dss_device
isn't connected to an output, or a manager isn't connected to an output yet.
Ensure that the DSI interface functions proceed only if the output is non NULL.

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

diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index 78212c4..228510f 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -356,9 +356,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)
@@ -391,7 +391,8 @@ static inline u32 dsi_read_reg(struct platform_device *dsidev,
 
 void dsi_bus_lock(struct omap_dss_device *dssdev)
 {
-	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+	struct omap_dss_output *out = dssdev->output;
+	struct platform_device *dsidev = dsi_get_dsidev_from_output(out);
 	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
 
 	down(&dsi->bus_lock);
@@ -400,7 +401,8 @@ EXPORT_SYMBOL(dsi_bus_lock);
 
 void dsi_bus_unlock(struct omap_dss_device *dssdev)
 {
-	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+	struct omap_dss_output *out = dssdev->output;
+	struct platform_device *dsidev = dsi_get_dsidev_from_output(out);
 	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
 
 	up(&dsi->bus_lock);
@@ -1205,15 +1207,15 @@ 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);
 	unsigned long dsi_fclk;
 	unsigned lp_clk_div;
 	unsigned long lp_clk;
 
-	lp_clk_div = dssdev->clocks.dsi.lp_clk_div;
+	lp_clk_div = out->device->clocks.dsi.lp_clk_div;
 
 	if (lp_clk_div = 0 || lp_clk_div > dsi->lpdiv_max)
 		return -EINVAL;
@@ -2689,7 +2691,8 @@ static int dsi_vc_config_source(struct platform_device *dsidev, int channel,
 void omapdss_dsi_vc_enable_hs(struct omap_dss_device *dssdev, int channel,
 		bool enable)
 {
-	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+	struct omap_dss_output *out = dssdev->output;
+	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);
@@ -2817,7 +2820,8 @@ static int dsi_vc_send_bta(struct platform_device *dsidev, int channel)
 
 int dsi_vc_send_bta_sync(struct omap_dss_device *dssdev, int channel)
 {
-	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+	struct omap_dss_output *out = dssdev->output;
+	struct platform_device *dsidev = dsi_get_dsidev_from_output(out);
 	DECLARE_COMPLETION_ONSTACK(completion);
 	int r = 0;
 	u32 err;
@@ -2986,7 +2990,8 @@ static int dsi_vc_send_short(struct platform_device *dsidev, int channel,
 
 int dsi_vc_send_null(struct omap_dss_device *dssdev, int channel)
 {
-	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+	struct omap_dss_output *out = dssdev->output;
+	struct platform_device *dsidev = dsi_get_dsidev_from_output(out);
 
 	return dsi_vc_send_long(dsidev, channel, MIPI_DSI_NULL_PACKET, NULL,
 		0, 0);
@@ -3026,7 +3031,8 @@ static int dsi_vc_write_nosync_common(struct platform_device *dsidev,
 int dsi_vc_dcs_write_nosync(struct omap_dss_device *dssdev, int channel,
 		u8 *data, int len)
 {
-	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+	struct omap_dss_output *out = dssdev->output;
+	struct platform_device *dsidev = dsi_get_dsidev_from_output(out);
 
 	return dsi_vc_write_nosync_common(dsidev, channel, data, len,
 			DSS_DSI_CONTENT_DCS);
@@ -3036,24 +3042,25 @@ EXPORT_SYMBOL(dsi_vc_dcs_write_nosync);
 int dsi_vc_generic_write_nosync(struct omap_dss_device *dssdev, int channel,
 		u8 *data, int len)
 {
-	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+	struct omap_dss_output *out = dssdev->output;
+	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->device, channel);
 	if (r)
 		goto err;
 
@@ -3075,7 +3082,9 @@ err:
 int dsi_vc_dcs_write(struct omap_dss_device *dssdev, int channel, u8 *data,
 		int len)
 {
-	return dsi_vc_write_common(dssdev, channel, data, len,
+	struct omap_dss_output *out = dssdev->output;
+
+	return dsi_vc_write_common(out, channel, data, len,
 			DSS_DSI_CONTENT_DCS);
 }
 EXPORT_SYMBOL(dsi_vc_dcs_write);
@@ -3083,7 +3092,9 @@ EXPORT_SYMBOL(dsi_vc_dcs_write);
 int dsi_vc_generic_write(struct omap_dss_device *dssdev, int channel, u8 *data,
 		int len)
 {
-	return dsi_vc_write_common(dssdev, channel, data, len,
+	struct omap_dss_output *out = dssdev->output;
+
+	return dsi_vc_write_common(out, channel, data, len,
 			DSS_DSI_CONTENT_GENERIC);
 }
 EXPORT_SYMBOL(dsi_vc_generic_write);
@@ -3295,7 +3306,8 @@ err:
 int dsi_vc_dcs_read(struct omap_dss_device *dssdev, int channel, u8 dcs_cmd,
 		u8 *buf, int buflen)
 {
-	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+	struct omap_dss_output *out = dssdev->output;
+	struct platform_device *dsidev = dsi_get_dsidev_from_output(out);
 	int r;
 
 	r = dsi_vc_dcs_send_read_request(dsidev, channel, dcs_cmd);
@@ -3323,17 +3335,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->device, channel);
 	if (r)
 		return r;
 
@@ -3353,9 +3365,10 @@ static int dsi_vc_generic_read(struct omap_dss_device *dssdev, int channel,
 int dsi_vc_generic_read_0(struct omap_dss_device *dssdev, int channel, u8 *buf,
 		int buflen)
 {
+	struct omap_dss_output *out = dssdev->output;
 	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;
@@ -3368,9 +3381,10 @@ EXPORT_SYMBOL(dsi_vc_generic_read_0);
 int dsi_vc_generic_read_1(struct omap_dss_device *dssdev, int channel, u8 param,
 		u8 *buf, int buflen)
 {
+	struct omap_dss_output *out = dssdev->output;
 	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;
@@ -3383,13 +3397,14 @@ EXPORT_SYMBOL(dsi_vc_generic_read_1);
 int dsi_vc_generic_read_2(struct omap_dss_device *dssdev, int channel,
 		u8 param1, u8 param2, u8 *buf, int buflen)
 {
+	struct omap_dss_output *out = dssdev->output;
 	int r;
 	u8 reqdata[2];
 
 	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;
@@ -3402,7 +3417,8 @@ EXPORT_SYMBOL(dsi_vc_generic_read_2);
 int dsi_vc_set_max_rx_packet_size(struct omap_dss_device *dssdev, int channel,
 		u16 len)
 {
-	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+	struct omap_dss_output *out = dssdev->output;
+	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);
@@ -3738,10 +3754,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;
@@ -3856,9 +3873,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;
@@ -3916,7 +3933,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);
@@ -4042,7 +4059,8 @@ static void dsi_proto_timings(struct platform_device *dsidev)
 int omapdss_dsi_configure_pins(struct omap_dss_device *dssdev,
 		const struct omap_dsi_pin_config *pin_cfg)
 {
-	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+	struct omap_dss_output *out = dssdev->output;
+	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;
@@ -4109,7 +4127,8 @@ EXPORT_SYMBOL(omapdss_dsi_configure_pins);
 
 int dsi_enable_video_output(struct omap_dss_device *dssdev, int channel)
 {
-	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+	struct omap_dss_output *out = dssdev->output;
+	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;
@@ -4150,7 +4169,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);
@@ -4166,7 +4185,8 @@ EXPORT_SYMBOL(dsi_enable_video_output);
 
 void dsi_disable_video_output(struct omap_dss_device *dssdev, int channel)
 {
-	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+	struct omap_dss_output *out = dssdev->output;
+	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) {
@@ -4180,13 +4200,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;
@@ -4249,9 +4269,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
@@ -4325,7 +4345,8 @@ static void dsi_framedone_irq_callback(void *data, u32 mask)
 int omap_dsi_update(struct omap_dss_device *dssdev, int channel,
 		void (*callback)(int, void *), void *data)
 {
-	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+	struct omap_dss_output *out = dssdev->output;
+	struct platform_device *dsidev = dsi_get_dsidev_from_output(out);
 	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
 	u16 dw, dh;
 
@@ -4343,7 +4364,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;
 }
@@ -4351,10 +4372,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;
@@ -4375,10 +4397,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;
 
@@ -4390,7 +4413,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);
@@ -4417,9 +4440,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;
 
@@ -4428,7 +4451,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:
@@ -4439,24 +4462,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;
 
@@ -4479,23 +4503,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");
@@ -4507,12 +4533,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;
 
@@ -4530,7 +4556,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);
@@ -4538,11 +4564,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);
@@ -4556,29 +4583,33 @@ 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)
 {
-	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
-	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
+	struct omap_dss_output *out = dssdev->output;
+	struct platform_device *dsidev;
+	struct dsi_data *dsi;
 	int r = 0;
 
 	DSSDBG("dsi_display_enable\n");
 
+	if (out = NULL || out->manager = NULL) {
+		DSSERR("failed to enable display: no output/manager\n");
+		r = -ENODEV;
+		goto err_no_out_mgr;
+	}
+
+	dsidev = dsi_get_dsidev_from_output(out);
+	dsi = dsi_get_dsidrv_data(dsidev);
+
 	WARN_ON(!dsi_bus_is_locked(dsidev));
 
 	mutex_lock(&dsi->lock);
 
-	if (dssdev->manager = NULL) {
-		DSSERR("failed to enable display: no manager\n");
-		r = -ENODEV;
-		goto err_start_dev;
-	}
-
 	r = omap_dss_start_device(dssdev);
 	if (r) {
 		DSSERR("failed to start device\n");
@@ -4593,11 +4624,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;
 
@@ -4606,7 +4637,7 @@ 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);
@@ -4614,6 +4645,7 @@ err_get_dsi:
 	omap_dss_stop_device(dssdev);
 err_start_dev:
 	mutex_unlock(&dsi->lock);
+err_no_out_mgr:
 	DSSDBG("dsi_display_enable FAILED\n");
 	return r;
 }
@@ -4622,7 +4654,8 @@ EXPORT_SYMBOL(omapdss_dsi_display_enable);
 void omapdss_dsi_display_disable(struct omap_dss_device *dssdev,
 		bool disconnect_lanes, bool enter_ulps)
 {
-	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+	struct omap_dss_output *out = dssdev->output;
+	struct platform_device *dsidev = dsi_get_dsidev_from_output(out);
 	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
 
 	DSSDBG("dsi_display_disable\n");
@@ -4636,9 +4669,9 @@ 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);
@@ -4651,7 +4684,8 @@ EXPORT_SYMBOL(omapdss_dsi_display_disable);
 
 int omapdss_dsi_enable_te(struct omap_dss_device *dssdev, bool enable)
 {
-	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+	struct omap_dss_output *out = dssdev->output;
+	struct platform_device *dsidev = dsi_get_dsidev_from_output(out);
 	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
 
 	dsi->te_enabled = enable;
@@ -4662,7 +4696,8 @@ EXPORT_SYMBOL(omapdss_dsi_enable_te);
 void omapdss_dsi_set_timings(struct omap_dss_device *dssdev,
 		struct omap_video_timings *timings)
 {
-	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+	struct omap_dss_output *out = dssdev->output;
+	struct platform_device *dsidev = dsi_get_dsidev_from_output(out);
 	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
 
 	mutex_lock(&dsi->lock);
@@ -4675,7 +4710,8 @@ EXPORT_SYMBOL(omapdss_dsi_set_timings);
 
 void omapdss_dsi_set_size(struct omap_dss_device *dssdev, u16 w, u16 h)
 {
-	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+	struct omap_dss_output *out = dssdev->output;
+	struct platform_device *dsidev = dsi_get_dsidev_from_output(out);
 	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
 
 	mutex_lock(&dsi->lock);
@@ -4690,7 +4726,8 @@ EXPORT_SYMBOL(omapdss_dsi_set_size);
 void omapdss_dsi_set_pixel_format(struct omap_dss_device *dssdev,
 		enum omap_dss_dsi_pixel_format fmt)
 {
-	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+	struct omap_dss_output *out = dssdev->output;
+	struct platform_device *dsidev = dsi_get_dsidev_from_output(out);
 	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
 
 	mutex_lock(&dsi->lock);
@@ -4704,7 +4741,8 @@ EXPORT_SYMBOL(omapdss_dsi_set_pixel_format);
 void omapdss_dsi_set_operation_mode(struct omap_dss_device *dssdev,
 		enum omap_dss_dsi_mode mode)
 {
-	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+	struct omap_dss_output *out = dssdev->output;
+	struct platform_device *dsidev = dsi_get_dsidev_from_output(out);
 	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
 
 	mutex_lock(&dsi->lock);
@@ -4718,7 +4756,8 @@ EXPORT_SYMBOL(omapdss_dsi_set_operation_mode);
 void omapdss_dsi_set_videomode_timings(struct omap_dss_device *dssdev,
 		struct omap_dss_dsi_videomode_timings *timings)
 {
-	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+	struct omap_dss_output *out = dssdev->output;
+	struct platform_device *dsidev = dsi_get_dsidev_from_output(out);
 	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
 
 	mutex_lock(&dsi->lock);
@@ -4731,7 +4770,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");
@@ -4759,7 +4799,8 @@ static int __init dsi_init_display(struct omap_dss_device *dssdev)
 
 int omap_dsi_request_vc(struct omap_dss_device *dssdev, int *channel)
 {
-	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+	struct omap_dss_output *out = dssdev->output;
+	struct platform_device *dsidev = dsi_get_dsidev_from_output(out);
 	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
 	int i;
 
@@ -4778,7 +4819,8 @@ EXPORT_SYMBOL(omap_dsi_request_vc);
 
 int omap_dsi_set_vc_id(struct omap_dss_device *dssdev, int channel, int vc_id)
 {
-	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+	struct omap_dss_output *out = dssdev->output;
+	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) {
@@ -4805,7 +4847,8 @@ EXPORT_SYMBOL(omap_dsi_set_vc_id);
 
 void omap_dsi_release_vc(struct omap_dss_device *dssdev, int channel)
 {
-	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+	struct omap_dss_output *out = dssdev->output;
+	struct platform_device *dsidev = dsi_get_dsidev_from_output(out);
 	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
 
 	if ((channel >= 0 && channel <= 3) &&
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [PATCH v2 13/23] OMAPDSS: SDI: Pass omap_dss_output within the driver
@ 2012-08-30 11:52     ` Archit Taneja
  0 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-08-30 11:52 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: rob, linux-omap, linux-fbdev, Archit Taneja

When a panel driver calls a SDI function, it passes the omap_dss_device
pointer, this pointer currently propagates within the SDI driver to configure
the interface.

Extract the omap_dss_output pointer from omap_dss_device received from the panel
driver, pass the output pointer to SDI functions local to the driver to
configure the interface, these functions no longer need omap_dss_device since
the driver now maintains a copy of output parameters.

Replace dssdev->manager references with out->manager references as only these
will be valid later.

With the addition of outputs. There is a possibility that an omap_dss_device
isn't connected to an output, or a manager isn't connected to an output yet.
Ensure that the SDI interface functions proceed only if the output is non NULL.

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

diff --git a/drivers/video/omap2/dss/sdi.c b/drivers/video/omap2/dss/sdi.c
index d8879f3..24f9ba0 100644
--- a/drivers/video/omap2/dss/sdi.c
+++ b/drivers/video/omap2/dss/sdi.c
@@ -40,7 +40,7 @@ static struct {
 	struct omap_dss_output output;
 } 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;
 
@@ -50,19 +50,20 @@ 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)
 {
+	struct omap_dss_output *out = dssdev->output;
 	struct omap_video_timings *t = &sdi.timings;
 	struct dss_clock_info dss_cinfo;
 	struct dispc_clock_info dispc_cinfo;
 	unsigned long pck;
 	int r;
 
-	if (dssdev->manager = NULL) {
-		DSSERR("failed to enable display: no manager\n");
+	if (out = NULL || out->manager = NULL) {
+		DSSERR("failed to enable display: no output/manager\n");
 		return -ENODEV;
 	}
 
@@ -100,14 +101,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);
 
@@ -116,7 +116,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;
 
@@ -139,7 +139,9 @@ EXPORT_SYMBOL(omapdss_sdi_display_enable);
 
 void omapdss_sdi_display_disable(struct omap_dss_device *dssdev)
 {
-	dss_mgr_disable(dssdev->manager);
+	struct omap_dss_output *out = dssdev->output;
+
+	dss_mgr_disable(out->manager);
 
 	dss_sdi_disable();
 
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [PATCH v2 14/23] OMAPDSS: RFBI: Pass omap_dss_output within the driver
@ 2012-08-30 11:52     ` Archit Taneja
  0 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-08-30 11:52 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: rob, linux-omap, linux-fbdev, Archit Taneja

When a panel driver calls a RFBI function, it passes the omap_dss_device
pointer, this pointer currently propagates within the RFBI driver to configure
the interface.

Extract the omap_dss_output pointer from omap_dss_device received from the panel
driver, pass the output pointer to RFBI functions local to the driver to
configure the interface, these functions no longer need omap_dss_device since
the driver now maintains a copy of output parameters.

Replace dssdev->manager references with out->manager references as only these
will be valid later.

With the addition of outputs. There is a possibility that an omap_dss_device
isn't connected to an output, or a manager isn't connected to an output yet.
Ensure that the RFBI interface functions proceed only if the output is non NULL.

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

diff --git a/drivers/video/omap2/dss/rfbi.c b/drivers/video/omap2/dss/rfbi.c
index 3450f51..545e14f 100644
--- a/drivers/video/omap2/dss/rfbi.c
+++ b/drivers/video/omap2/dss/rfbi.c
@@ -307,11 +307,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;
 
@@ -320,9 +321,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;
 
@@ -779,7 +780,9 @@ EXPORT_SYMBOL(omap_rfbi_configure);
 int omap_rfbi_update(struct omap_dss_device *dssdev, void (*callback)(void *),
 		void *data)
 {
-	return rfbi_transfer_area(dssdev, callback, data);
+	struct omap_dss_output *out = dssdev->output;
+
+	return rfbi_transfer_area(out, callback, data);
 }
 EXPORT_SYMBOL(omap_rfbi_update);
 
@@ -849,7 +852,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;
 
@@ -862,7 +865,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
@@ -883,15 +886,16 @@ 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)
 {
+	struct omap_dss_output *out = dssdev->output;
 	int r;
 
-	if (dssdev->manager = NULL) {
-		DSSERR("failed to enable display: no manager\n");
+	if (out = NULL || out->manager = NULL) {
+		DSSERR("failed to enable display: no output/manager\n");
 		return -ENODEV;
 	}
 
@@ -912,7 +916,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);
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [PATCH v2 15/23] OMAPDSS: RFBI: Add dssdev pointers as arguments to all exported functions
@ 2012-08-30 11:52     ` Archit Taneja
  0 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-08-30 11:52 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: rob, linux-omap, linux-fbdev, Archit Taneja

All functions of an interface driver used by a panel driver should have an
omap_dss_device 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 dssdev 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 |   55 ++++++++++++++++-------------
 drivers/video/omap2/dss/rfbi.c            |   25 +++++++------
 include/video/omapdss.h                   |   25 +++++++------
 3 files changed, 60 insertions(+), 45 deletions(-)

diff --git a/drivers/video/omap2/displays/panel-n8x0.c b/drivers/video/omap2/displays/panel-n8x0.c
index 17ae85e..e3a8c44 100644
--- a/drivers/video/omap2/displays/panel-n8x0.c
+++ b/drivers/video/omap2/displays/panel-n8x0.c
@@ -88,27 +88,30 @@ 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, &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);
+	omap_rfbi_write_command(dssdev, &cmd, 1);
+	omap_rfbi_write_data(dssdev, 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);
+	omap_rfbi_write_command(dssdev, &cmd, 1);
+	omap_rfbi_read_data(dssdev, 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;
 }
 
@@ -155,7 +158,7 @@ static void blizzard_ctrl_setup_update(struct omap_dss_device *dssdev,
 
 	omap_rfbi_configure(dssdev);
 
-	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(dssdev, 16);
 	omapdss_rfbi_set_data_lines(dssdev, 16);
@@ -313,8 +316,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,11 +539,11 @@ static int n8x0_panel_enable(struct omap_dss_device *dssdev)
 
 	mutex_lock(&ddata->lock);
 
-	rfbi_bus_lock();
+	rfbi_bus_lock(dssdev);
 
 	r = n8x0_panel_power_on(dssdev);
 
-	rfbi_bus_unlock();
+	rfbi_bus_unlock(dssdev);
 
 	if (r) {
 		mutex_unlock(&ddata->lock);
@@ -562,11 +565,11 @@ static void n8x0_panel_disable(struct omap_dss_device *dssdev)
 
 	mutex_lock(&ddata->lock);
 
-	rfbi_bus_lock();
+	rfbi_bus_lock(dssdev);
 
 	n8x0_panel_power_off(dssdev);
 
-	rfbi_bus_unlock();
+	rfbi_bus_unlock(dssdev);
 
 	dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
 
@@ -581,11 +584,11 @@ static int n8x0_panel_suspend(struct omap_dss_device *dssdev)
 
 	mutex_lock(&ddata->lock);
 
-	rfbi_bus_lock();
+	rfbi_bus_lock(dssdev);
 
 	n8x0_panel_power_off(dssdev);
 
-	rfbi_bus_unlock();
+	rfbi_bus_unlock(dssdev);
 
 	dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
 
@@ -603,11 +606,11 @@ static int n8x0_panel_resume(struct omap_dss_device *dssdev)
 
 	mutex_lock(&ddata->lock);
 
-	rfbi_bus_lock();
+	rfbi_bus_lock(dssdev);
 
 	r = n8x0_panel_power_on(dssdev);
 
-	rfbi_bus_unlock();
+	rfbi_bus_unlock(dssdev);
 
 	if (r) {
 		mutex_unlock(&ddata->lock);
@@ -630,7 +633,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);
 }
 
 static int n8x0_panel_update(struct omap_dss_device *dssdev,
@@ -651,7 +656,7 @@ static int n8x0_panel_update(struct omap_dss_device *dssdev,
 	}
 
 	mutex_lock(&ddata->lock);
-	rfbi_bus_lock();
+	rfbi_bus_lock(dssdev);
 
 	blizzard_ctrl_setup_update(dssdev, x, y, w, h);
 
@@ -669,8 +674,8 @@ static int n8x0_panel_sync(struct omap_dss_device *dssdev)
 	dev_dbg(&dssdev->dev, "sync\n");
 
 	mutex_lock(&ddata->lock);
-	rfbi_bus_lock();
-	rfbi_bus_unlock();
+	rfbi_bus_lock(dssdev);
+	rfbi_bus_unlock(dssdev);
 	mutex_unlock(&ddata->lock);
 
 	return 0;
diff --git a/drivers/video/omap2/dss/rfbi.c b/drivers/video/omap2/dss/rfbi.c
index 545e14f..b9d5b96 100644
--- a/drivers/video/omap2/dss/rfbi.c
+++ b/drivers/video/omap2/dss/rfbi.c
@@ -151,19 +151,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_device *dssdev)
 {
 	down(&rfbi.bus_lock);
 }
 EXPORT_SYMBOL(rfbi_bus_lock);
 
-void rfbi_bus_unlock(void)
+void rfbi_bus_unlock(struct omap_dss_device *dssdev)
 {
 	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_device *dssdev, const void *buf,
+		u32 len)
 {
 	switch (rfbi.parallelmode) {
 	case OMAP_DSS_RFBI_PARALLELMODE_8:
@@ -191,7 +192,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_device *dssdev, void *buf, u32 len)
 {
 	switch (rfbi.parallelmode) {
 	case OMAP_DSS_RFBI_PARALLELMODE_8:
@@ -223,7 +224,8 @@ 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_device *dssdev, const void *buf,
+		u32 len)
 {
 	switch (rfbi.parallelmode) {
 	case OMAP_DSS_RFBI_PARALLELMODE_8:
@@ -252,7 +254,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_device *dssdev,
+		const void __iomem *buf, int scr_width,
 		u16 x, u16 y,
 		u16 w, u16 h)
 {
@@ -574,9 +577,10 @@ 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,
-			     unsigned hs_pulse_time, unsigned vs_pulse_time,
-			     int hs_pol_inv, int vs_pol_inv, int extif_div)
+int omap_rfbi_setup_te(struct omap_dss_device *dssdev,
+			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)
 {
 	int hs, vs;
 	int min;
@@ -616,7 +620,8 @@ 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_device *dssdev, bool enable,
+		unsigned line)
 {
 	u32 l;
 
diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index 29c1440..0e73ef8 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -238,18 +238,23 @@ 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_device *dssdev, const void *buf,
+		u32 len);
+void omap_rfbi_read_data(struct omap_dss_device *dssdev, void *buf, u32 len);
+void omap_rfbi_write_data(struct omap_dss_device *dssdev, const void *buf,
+		u32 len);
+void omap_rfbi_write_pixels(struct omap_dss_device *dssdev,
+		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,
-			     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);
+int omap_rfbi_enable_te(struct omap_dss_device *dssdev, bool enable,
+		unsigned line);
+int omap_rfbi_setup_te(struct omap_dss_device *dssdev,
+			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(struct omap_dss_device *dssdev);
+void rfbi_bus_unlock(struct omap_dss_device *dssdev);
 
 /* DSI */
 
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [PATCH v2 16/23] OMAPDSS: VENC: Pass omap_dss_output within the driver
@ 2012-08-30 11:52     ` Archit Taneja
  0 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-08-30 11:52 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: rob, linux-omap, linux-fbdev, Archit Taneja

When a panel driver calls a VENC function, it passes the omap_dss_device
pointer, this pointer currently propagates within the VENC driver to configure
the interface.

Extract the omap_dss_output pointer from omap_dss_device received from the panel
driver, pass the output pointer to VENC functions local to the driver to
configure the interface, these functions no longer need omap_dss_device since
the driver now maintains a copy of output parameters.

Replace dssdev->manager references with out->manager references as only these
will be valid later.

With the addition of outputs. There is a possibility that an omap_dss_device
isn't connected to an output, or a manager isn't connected to an output yet.
Ensure that the VENC interface functions proceed only if the output is non NULL.

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

diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c
index 942a378..3fe974f 100644
--- a/drivers/video/omap2/dss/venc.c
+++ b/drivers/video/omap2/dss/venc.c
@@ -428,7 +428,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;
@@ -455,13 +455,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;
 
@@ -478,12 +478,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);
 
@@ -498,14 +498,15 @@ unsigned long venc_get_pixel_clock(void)
 
 int omapdss_venc_display_enable(struct omap_dss_device *dssdev)
 {
+	struct omap_dss_output *out = dssdev->output;
 	int r;
 
 	DSSDBG("venc_display_enable\n");
 
 	mutex_lock(&venc.venc_lock);
 
-	if (dssdev->manager = NULL) {
-		DSSERR("Failed to enable display: no manager\n");
+	if (out = NULL || out->manager = NULL) {
+		DSSERR("Failed to enable display: no output/manager\n");
 		r = -ENODEV;
 		goto err0;
 	}
@@ -520,7 +521,7 @@ int omapdss_venc_display_enable(struct omap_dss_device *dssdev)
 		dssdev->platform_enable(dssdev);
 
 
-	r = venc_power_on(dssdev);
+	r = venc_power_on(out);
 	if (r)
 		goto err1;
 
@@ -540,11 +541,13 @@ err0:
 
 void omapdss_venc_display_disable(struct omap_dss_device *dssdev)
 {
+	struct omap_dss_output *out = dssdev->output;
+
 	DSSDBG("venc_display_disable\n");
 
 	mutex_lock(&venc.venc_lock);
 
-	venc_power_off(dssdev);
+	venc_power_off(out);
 
 	omap_dss_stop_device(dssdev);
 
@@ -557,8 +560,13 @@ void omapdss_venc_display_disable(struct omap_dss_device *dssdev)
 void omapdss_venc_set_timings(struct omap_dss_device *dssdev,
 		struct omap_video_timings *timings)
 {
+	struct omap_dss_output *out = dssdev->output;
+
 	DSSDBG("venc_set_timings\n");
 
+	if (out = NULL)
+		return;
+
 	mutex_lock(&venc.venc_lock);
 
 	/* Reset WSS data when the TV standard changes. */
@@ -571,13 +579,13 @@ void omapdss_venc_set_timings(struct omap_dss_device *dssdev,
 		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);
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [PATCH v2 17/23] OMAPDSS: HDMI: Pass omap_dss_output within the driver
@ 2012-08-30 11:52     ` Archit Taneja
  0 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-08-30 11:52 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: rob, linux-omap, linux-fbdev, Archit Taneja

When a panel driver calls a HDMI function, it passes the omap_dss_device
pointer, this pointer currently propagates within the HDMI driver to configure
the interface.

Extract the omap_dss_output pointer from omap_dss_device received from the panel
driver, pass the output pointer to HDMI functions local to the driver to
configure the interface, these functions no longer need omap_dss_device since
the driver now maintains a copy of output parameters.

Replace dssdev->manager references with out->manager references as only these
will be valid later.

With the addition of outputs. There is a possibility that an omap_dss_device
isn't connected to an output, or a manager isn't connected to an output yet.
Ensure that the HDMI interface functions proceed only if the output is non NULL.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/dss/hdmi.c |   40 ++++++++++++++++++++++++----------------
 1 file changed, 24 insertions(+), 16 deletions(-)

diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c
index d93954d..3c89904 100644
--- a/drivers/video/omap2/dss/hdmi.c
+++ b/drivers/video/omap2/dss/hdmi.c
@@ -407,9 +407,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;
 
@@ -458,7 +459,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;
@@ -468,7 +469,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;
 
@@ -476,7 +477,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);
 
@@ -504,19 +505,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;
 
@@ -533,9 +534,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);
@@ -560,9 +561,13 @@ int omapdss_hdmi_display_check_timing(struct omap_dss_device *dssdev,
 void omapdss_hdmi_display_set_timing(struct omap_dss_device *dssdev,
 		struct omap_video_timings *timings)
 {
+	struct omap_dss_output *out = dssdev->output;
 	struct hdmi_cm cm;
 	const struct hdmi_config *t;
 
+	if (out = NULL)
+		return;
+
 	mutex_lock(&hdmi.lock);
 
 	cm = hdmi_get_code(timings);
@@ -575,13 +580,13 @@ void omapdss_hdmi_display_set_timing(struct omap_dss_device *dssdev,
 	if (dssdev->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);
@@ -640,14 +645,15 @@ bool omapdss_hdmi_detect(void)
 int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev)
 {
 	struct omap_dss_hdmi_data *priv = dssdev->data;
+	struct omap_dss_output *out = dssdev->output;
 	int r = 0;
 
 	DSSDBG("ENTER hdmi_display_enable\n");
 
 	mutex_lock(&hdmi.lock);
 
-	if (dssdev->manager = NULL) {
-		DSSERR("failed to enable display: no manager\n");
+	if (out = NULL || out->manager = NULL) {
+		DSSERR("failed to enable display: no output/manager\n");
 		r = -ENODEV;
 		goto err0;
 	}
@@ -668,7 +674,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;
@@ -689,11 +695,13 @@ err0:
 
 void omapdss_hdmi_display_disable(struct omap_dss_device *dssdev)
 {
+	struct omap_dss_output *out = dssdev->output;
+
 	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);
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [PATCH v2 18/23] OMAPDSS: HDMI: Add dssdev pointer as an argument to all functions used by hdmi pane
@ 2012-08-30 11:52     ` Archit Taneja
  0 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-08-30 11:52 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: rob, linux-omap, linux-fbdev, Archit Taneja

All functions of an output driver used by a panel driver should have an
omap_dss_device 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 dssdev arguments to 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       |   17 +++++++++--------
 drivers/video/omap2/dss/hdmi_panel.c |   20 ++++++++++----------
 3 files changed, 28 insertions(+), 26 deletions(-)

diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index de2fb9d..11c245d 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -506,17 +506,18 @@ void omapdss_hdmi_display_set_timing(struct omap_dss_device *dssdev,
 		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 omapdss_hdmi_read_edid(struct omap_dss_device *dssdev, u8 *buf, int len);
+bool omapdss_hdmi_detect(struct omap_dss_device *dssdev);
 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_device *dssdev);
+void hdmi_audio_disable(struct omap_dss_device *dssdev);
+int hdmi_audio_start(struct omap_dss_device *dssdev);
+void hdmi_audio_stop(struct omap_dss_device *dssdev);
+bool hdmi_mode_has_audio(struct omap_dss_device *dssdev);
+int hdmi_audio_config(struct omap_dss_device *dssdev,
+		struct omap_dss_audio *audio);
 #endif
 
 /* RFBI */
diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c
index 3c89904..2d3b959 100644
--- a/drivers/video/omap2/dss/hdmi.c
+++ b/drivers/video/omap2/dss/hdmi.c
@@ -608,7 +608,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_device *dssdev, u8 *buf, int len)
 {
 	int r;
 
@@ -625,7 +625,7 @@ int omapdss_hdmi_read_edid(u8 *buf, int len)
 	return r;
 }
 
-bool omapdss_hdmi_detect(void)
+bool omapdss_hdmi_detect(struct omap_dss_device *dssdev)
 {
 	int r;
 
@@ -833,35 +833,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_device *dssdev)
 {
 	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_device *dssdev)
 {
 	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_device *dssdev)
 {
 	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_device *dssdev)
 {
 	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_device *dssdev)
 {
 	if (hdmi.ip_data.cfg.cm.mode = HDMI_HDMI)
 		return true;
@@ -869,7 +869,8 @@ bool hdmi_mode_has_audio(void)
 		return false;
 }
 
-int hdmi_audio_config(struct omap_dss_audio *audio)
+int hdmi_audio_config(struct omap_dss_device *dssdev,
+		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 69fb115..ef3fc86 100644
--- a/drivers/video/omap2/dss/hdmi_panel.c
+++ b/drivers/video/omap2/dss/hdmi_panel.c
@@ -88,13 +88,13 @@ static int hdmi_panel_audio_enable(struct omap_dss_device *dssdev)
 
 	/* 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(dssdev)) {
 		DSSERR("audio not supported or display is off\n");
 		r = -EPERM;
 		goto err;
 	}
 
-	r = hdmi_audio_enable();
+	r = hdmi_audio_enable(dssdev);
 
 	if (!r)
 		dssdev->audio_state = OMAP_DSS_AUDIO_ENABLED;
@@ -111,7 +111,7 @@ static void hdmi_panel_audio_disable(struct omap_dss_device *dssdev)
 
 	spin_lock_irqsave(&hdmi.audio_lock, flags);
 
-	hdmi_audio_disable();
+	hdmi_audio_disable(dssdev);
 
 	dssdev->audio_state = OMAP_DSS_AUDIO_DISABLED;
 
@@ -134,7 +134,7 @@ static int hdmi_panel_audio_start(struct omap_dss_device *dssdev)
 		goto err;
 	}
 
-	r = hdmi_audio_start();
+	r = hdmi_audio_start(dssdev);
 
 	if (!r)
 		dssdev->audio_state = OMAP_DSS_AUDIO_PLAYING;
@@ -150,7 +150,7 @@ static void hdmi_panel_audio_stop(struct omap_dss_device *dssdev)
 
 	spin_lock_irqsave(&hdmi.audio_lock, flags);
 
-	hdmi_audio_stop();
+	hdmi_audio_stop(dssdev);
 	dssdev->audio_state = OMAP_DSS_AUDIO_ENABLED;
 
 	spin_unlock_irqrestore(&hdmi.audio_lock, flags);
@@ -165,7 +165,7 @@ static bool hdmi_panel_audio_supported(struct omap_dss_device *dssdev)
 	if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
 		goto err;
 
-	if (!hdmi_mode_has_audio())
+	if (!hdmi_mode_has_audio(dssdev))
 		goto err;
 
 	r = true;
@@ -185,13 +185,13 @@ static int hdmi_panel_audio_config(struct omap_dss_device *dssdev,
 
 	/* 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(dssdev)) {
 		DSSERR("audio not supported or display is off\n");
 		r = -EPERM;
 		goto err;
 	}
 
-	r = hdmi_audio_config(audio);
+	r = hdmi_audio_config(dssdev, audio);
 
 	if (!r)
 		dssdev->audio_state = OMAP_DSS_AUDIO_CONFIGURED;
@@ -388,7 +388,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(dssdev, buf, len);
 
 	if (dssdev->state = OMAP_DSS_DISPLAY_DISABLED ||
 			dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED)
@@ -411,7 +411,7 @@ static bool hdmi_detect(struct omap_dss_device *dssdev)
 			goto err;
 	}
 
-	r = omapdss_hdmi_detect();
+	r = omapdss_hdmi_detect(dssdev);
 
 	if (dssdev->state = OMAP_DSS_DISPLAY_DISABLED ||
 			dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED)
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [PATCH v2 19/23] OMAPDSS/OMAPFB: Change dssdev->manager references
@ 2012-08-30 11:52     ` Archit Taneja
  0 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-08-30 11:52 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: rob, linux-omap, linux-fbdev, Archit Taneja

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 |    7 +++++--
 2 files changed, 14 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..606b89f 100644
--- a/drivers/video/omap2/omapfb/omapfb-ioctl.c
+++ b/drivers/video/omap2/omapfb/omapfb-ioctl.c
@@ -599,6 +599,7 @@ int omapfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg)
 	struct omapfb_info *ofbi = FB2OFB(fbi);
 	struct omapfb2_device *fbdev = ofbi->fbdev;
 	struct omap_dss_device *display = fb2display(fbi);
+	struct omap_overlay_manager *mgr;
 
 	union {
 		struct omapfb_update_window_old	uwnd_o;
@@ -786,12 +787,14 @@ 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);
+		mgr = display->output->manager;
+
+		r = mgr->wait_for_vsync(mgr);
 		break;
 
 	case OMAPFB_WAITFORGO:
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [PATCH v2 20/23] OMAPDSS: MANAGER: Update display sysfs store
@ 2012-08-30 11:52     ` Archit Taneja
  0 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-08-30 11:52 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: rob, linux-omap, linux-fbdev, Archit Taneja

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	[flat|nested] 148+ messages in thread

* [PATCH v2 21/23] OMAPDSS: MANAGER: Get device via output
@ 2012-08-30 11:52     ` Archit Taneja
  0 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-08-30 11:52 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: rob, linux-omap, linux-fbdev, Archit Taneja

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	[flat|nested] 148+ messages in thread

* [PATCH v2 22/23] OMAPDSS: APPLY: Remove omap_dss_device references from dss_ovl_enable/disable
@ 2012-08-30 11:52     ` Archit Taneja
  0 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-08-30 11:52 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: rob, linux-omap, linux-fbdev, Archit Taneja

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	[flat|nested] 148+ messages in thread

* [PATCH v2 23/23] OMAPDSS: Remove old way of setting manager and device links
@ 2012-08-30 11:52     ` Archit Taneja
  0 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-08-30 11:52 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: rob, linux-omap, linux-fbdev, Archit Taneja

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 0e73ef8..4ff43e6 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	[flat|nested] 148+ messages in thread

* Re: [PATCH v2 02/23] OMAPDSS: outputs: Create and register output instances
  2012-08-30 11:52     ` Archit Taneja
@ 2012-08-31 11:57       ` Tomi Valkeinen
  -1 siblings, 0 replies; 148+ messages in thread
From: Tomi Valkeinen @ 2012-08-31 11:57 UTC (permalink / raw)
  To: Archit Taneja; +Cc: rob, linux-omap, linux-fbdev

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

On Thu, 2012-08-30 at 17:10 +0530, Archit Taneja wrote:
> Add output structs to output driver's private data. Register output instances by
> having an init function in the probes of the platform device drivers for
> different outputs. The *_init_output for each output registers the output and
> fill up the output's plaform device, type and id fields.
> 
> In the probe of each interface driver, the output entities are initialized
> before the *_probe_pdata() functions intentionally. This is done to ensure that
> the output entity is prepared before the panels connected to the output are
> registered. We need the output entities to be ready because OMAPDSS will try
> to make connections between overlays, managers, outputs and devices during the
> panel's probe.
> 
> Signed-off-by: Archit Taneja <archit@ti.com>
> ---
>  drivers/video/omap2/dss/dpi.c  |   15 +++++++++++++++
>  drivers/video/omap2/dss/dsi.c  |   18 ++++++++++++++++++
>  drivers/video/omap2/dss/hdmi.c |   15 +++++++++++++++
>  drivers/video/omap2/dss/rfbi.c |   17 +++++++++++++++++
>  drivers/video/omap2/dss/sdi.c  |   15 +++++++++++++++
>  drivers/video/omap2/dss/venc.c |   15 +++++++++++++++
>  6 files changed, 95 insertions(+)
> 
> diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c
> index 25fb895..9a7aee5 100644
> --- a/drivers/video/omap2/dss/dpi.c
> +++ b/drivers/video/omap2/dss/dpi.c
> @@ -45,6 +45,8 @@ static struct {
>  	struct omap_video_timings timings;
>  	struct dss_lcd_mgr_config mgr_config;
>  	int data_lines;
> +
> +	struct omap_dss_output output;
>  } dpi;
>  
>  static struct platform_device *dpi_get_dsidev(enum omap_dss_clk_source clk)
> @@ -410,10 +412,23 @@ static void __init dpi_probe_pdata(struct platform_device *pdev)
>  	}
>  }
>  
> +static void __init dpi_init_output(struct platform_device *pdev)
> +{
> +	struct omap_dss_output *out = &dpi.output;
> +
> +	dss_register_output(out);
> +
> +	out->pdev = pdev;
> +	out->id = OMAP_DSS_OUTPUT_DPI;
> +	out->type = OMAP_DISPLAY_TYPE_DPI;
> +}

I think you should first initialize the output, and then register it.
Not the other way around.

I believe you need to implement unregister also. Normally unregister
won't be done, but the probe of an output driver can fail after the
output has been registered, and thus the output needs to be unregistered
at cleanup.

And it doesn't harm to unregister at the driver's remove.

 Tomi


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

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [PATCH v2 02/23] OMAPDSS: outputs: Create and register output instances
@ 2012-08-31 11:57       ` Tomi Valkeinen
  0 siblings, 0 replies; 148+ messages in thread
From: Tomi Valkeinen @ 2012-08-31 11:57 UTC (permalink / raw)
  To: Archit Taneja; +Cc: rob, linux-omap, linux-fbdev

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

On Thu, 2012-08-30 at 17:10 +0530, Archit Taneja wrote:
> Add output structs to output driver's private data. Register output instances by
> having an init function in the probes of the platform device drivers for
> different outputs. The *_init_output for each output registers the output and
> fill up the output's plaform device, type and id fields.
> 
> In the probe of each interface driver, the output entities are initialized
> before the *_probe_pdata() functions intentionally. This is done to ensure that
> the output entity is prepared before the panels connected to the output are
> registered. We need the output entities to be ready because OMAPDSS will try
> to make connections between overlays, managers, outputs and devices during the
> panel's probe.
> 
> Signed-off-by: Archit Taneja <archit@ti.com>
> ---
>  drivers/video/omap2/dss/dpi.c  |   15 +++++++++++++++
>  drivers/video/omap2/dss/dsi.c  |   18 ++++++++++++++++++
>  drivers/video/omap2/dss/hdmi.c |   15 +++++++++++++++
>  drivers/video/omap2/dss/rfbi.c |   17 +++++++++++++++++
>  drivers/video/omap2/dss/sdi.c  |   15 +++++++++++++++
>  drivers/video/omap2/dss/venc.c |   15 +++++++++++++++
>  6 files changed, 95 insertions(+)
> 
> diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c
> index 25fb895..9a7aee5 100644
> --- a/drivers/video/omap2/dss/dpi.c
> +++ b/drivers/video/omap2/dss/dpi.c
> @@ -45,6 +45,8 @@ static struct {
>  	struct omap_video_timings timings;
>  	struct dss_lcd_mgr_config mgr_config;
>  	int data_lines;
> +
> +	struct omap_dss_output output;
>  } dpi;
>  
>  static struct platform_device *dpi_get_dsidev(enum omap_dss_clk_source clk)
> @@ -410,10 +412,23 @@ static void __init dpi_probe_pdata(struct platform_device *pdev)
>  	}
>  }
>  
> +static void __init dpi_init_output(struct platform_device *pdev)
> +{
> +	struct omap_dss_output *out = &dpi.output;
> +
> +	dss_register_output(out);
> +
> +	out->pdev = pdev;
> +	out->id = OMAP_DSS_OUTPUT_DPI;
> +	out->type = OMAP_DISPLAY_TYPE_DPI;
> +}

I think you should first initialize the output, and then register it.
Not the other way around.

I believe you need to implement unregister also. Normally unregister
won't be done, but the probe of an output driver can fail after the
output has been registered, and thus the output needs to be unregistered
at cleanup.

And it doesn't harm to unregister at the driver's remove.

 Tomi


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

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [PATCH v2 03/23] OMAPDSS: output: Add set/unset device ops for omap_dss_output
  2012-08-30 11:52     ` Archit Taneja
@ 2012-08-31 12:03       ` Tomi Valkeinen
  -1 siblings, 0 replies; 148+ messages in thread
From: Tomi Valkeinen @ 2012-08-31 12:03 UTC (permalink / raw)
  To: Archit Taneja; +Cc: rob, linux-omap, linux-fbdev

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

On Thu, 2012-08-30 at 17:10 +0530, Archit Taneja wrote:
> An output entity represented by the struct omap_dss_output connects to a
> omap_dss_device entity. Add functions to set or unset an output's device. This
> is similar to how managers and devices were connected previously. An output can
> connect to a device without being connected to a manager. However, the output
> needs to eventually connect to a manager so that the connected panel can be
> enabled.
> 
> Keep the omap_overlay_manager pointer in omap_dss_device for now to prevent
> breaking things. This will be removed later when outputs are supported
> completely.
> 
> Signed-off-by: Archit Taneja <archit@ti.com>
> ---
>  drivers/video/omap2/dss/output.c |   67 ++++++++++++++++++++++++++++++++++++++
>  include/video/omapdss.h          |    5 +++
>  2 files changed, 72 insertions(+)
> 
> diff --git a/drivers/video/omap2/dss/output.c b/drivers/video/omap2/dss/output.c
> index 7d81be5..abc3aa2 100644
> --- a/drivers/video/omap2/dss/output.c
> +++ b/drivers/video/omap2/dss/output.c
> @@ -24,9 +24,76 @@
>  #include "dss.h"
>  
>  static LIST_HEAD(output_list);
> +static DEFINE_MUTEX(output_lock);
> +
> +static int dss_output_set_device(struct omap_dss_output *out,
> +		struct omap_dss_device *dssdev)
> +{
> +	int r;
> +
> +	mutex_lock(&output_lock);
> +
> +	if (out->device) {
> +		DSSERR("output already has device %s connected to it\n",
> +			out->device->name);
> +		r = -EINVAL;
> +		goto err;
> +	}
> +
> +	if (out->type != dssdev->type) {
> +		DSSERR("output type and display type don't match\n");
> +		r = -EINVAL;
> +		goto err;
> +	}
> +
> +	out->device = dssdev;
> +	dssdev->output = out;
> +
> +	mutex_unlock(&output_lock);
> +
> +	return 0;
> +err:
> +	mutex_unlock(&output_lock);
> +
> +	return r;
> +}
> +
> +static int dss_output_unset_device(struct omap_dss_output *out)
> +{
> +	int r;
> +
> +	mutex_lock(&output_lock);
> +
> +	if (!out->device) {
> +		DSSERR("output doesn't have a device connected to it\n");
> +		r = -EINVAL;
> +		goto err;
> +	}
> +
> +	if (out->device->state != OMAP_DSS_DISPLAY_DISABLED) {
> +		DSSERR("device %s is not disabled, cannot unset device\n",
> +				out->device->name);
> +		r = -EINVAL;
> +		goto err;
> +	}
> +
> +	out->device->output = NULL;
> +	out->device = NULL;
> +
> +	mutex_unlock(&output_lock);
> +
> +	return 0;
> +err:
> +	mutex_unlock(&output_lock);
> +
> +	return r;
> +}
>  
>  void dss_register_output(struct omap_dss_output *out)
>  {
> +	out->set_device = &dss_output_set_device;
> +	out->unset_device = &dss_output_unset_device;
> +
>  	list_add_tail(&out->list, &output_list);
>  }

I don't think there's need for this indirection. We should use function
pointers only when the func pointer may lead to different functions.
Here we'll always have just one function, dss_output_set_device. We can
as well call the function directly.

I know we have similar func pointers for ovls/mgrs currently, but I
don't think they are good either. They are a relic from the time we
supported "virtual" overlays and managers, and thus could have different
implementations for the operations.

 Tomi


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

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [PATCH v2 03/23] OMAPDSS: output: Add set/unset device ops for omap_dss_output
@ 2012-08-31 12:03       ` Tomi Valkeinen
  0 siblings, 0 replies; 148+ messages in thread
From: Tomi Valkeinen @ 2012-08-31 12:03 UTC (permalink / raw)
  To: Archit Taneja; +Cc: rob, linux-omap, linux-fbdev

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

On Thu, 2012-08-30 at 17:10 +0530, Archit Taneja wrote:
> An output entity represented by the struct omap_dss_output connects to a
> omap_dss_device entity. Add functions to set or unset an output's device. This
> is similar to how managers and devices were connected previously. An output can
> connect to a device without being connected to a manager. However, the output
> needs to eventually connect to a manager so that the connected panel can be
> enabled.
> 
> Keep the omap_overlay_manager pointer in omap_dss_device for now to prevent
> breaking things. This will be removed later when outputs are supported
> completely.
> 
> Signed-off-by: Archit Taneja <archit@ti.com>
> ---
>  drivers/video/omap2/dss/output.c |   67 ++++++++++++++++++++++++++++++++++++++
>  include/video/omapdss.h          |    5 +++
>  2 files changed, 72 insertions(+)
> 
> diff --git a/drivers/video/omap2/dss/output.c b/drivers/video/omap2/dss/output.c
> index 7d81be5..abc3aa2 100644
> --- a/drivers/video/omap2/dss/output.c
> +++ b/drivers/video/omap2/dss/output.c
> @@ -24,9 +24,76 @@
>  #include "dss.h"
>  
>  static LIST_HEAD(output_list);
> +static DEFINE_MUTEX(output_lock);
> +
> +static int dss_output_set_device(struct omap_dss_output *out,
> +		struct omap_dss_device *dssdev)
> +{
> +	int r;
> +
> +	mutex_lock(&output_lock);
> +
> +	if (out->device) {
> +		DSSERR("output already has device %s connected to it\n",
> +			out->device->name);
> +		r = -EINVAL;
> +		goto err;
> +	}
> +
> +	if (out->type != dssdev->type) {
> +		DSSERR("output type and display type don't match\n");
> +		r = -EINVAL;
> +		goto err;
> +	}
> +
> +	out->device = dssdev;
> +	dssdev->output = out;
> +
> +	mutex_unlock(&output_lock);
> +
> +	return 0;
> +err:
> +	mutex_unlock(&output_lock);
> +
> +	return r;
> +}
> +
> +static int dss_output_unset_device(struct omap_dss_output *out)
> +{
> +	int r;
> +
> +	mutex_lock(&output_lock);
> +
> +	if (!out->device) {
> +		DSSERR("output doesn't have a device connected to it\n");
> +		r = -EINVAL;
> +		goto err;
> +	}
> +
> +	if (out->device->state != OMAP_DSS_DISPLAY_DISABLED) {
> +		DSSERR("device %s is not disabled, cannot unset device\n",
> +				out->device->name);
> +		r = -EINVAL;
> +		goto err;
> +	}
> +
> +	out->device->output = NULL;
> +	out->device = NULL;
> +
> +	mutex_unlock(&output_lock);
> +
> +	return 0;
> +err:
> +	mutex_unlock(&output_lock);
> +
> +	return r;
> +}
>  
>  void dss_register_output(struct omap_dss_output *out)
>  {
> +	out->set_device = &dss_output_set_device;
> +	out->unset_device = &dss_output_unset_device;
> +
>  	list_add_tail(&out->list, &output_list);
>  }

I don't think there's need for this indirection. We should use function
pointers only when the func pointer may lead to different functions.
Here we'll always have just one function, dss_output_set_device. We can
as well call the function directly.

I know we have similar func pointers for ovls/mgrs currently, but I
don't think they are good either. They are a relic from the time we
supported "virtual" overlays and managers, and thus could have different
implementations for the operations.

 Tomi


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

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [PATCH v2 02/23] OMAPDSS: outputs: Create and register output instances
  2012-08-31 11:57       ` Tomi Valkeinen
@ 2012-08-31 12:15         ` Archit Taneja
  -1 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-08-31 12:03 UTC (permalink / raw)
  To: Tomi Valkeinen; +Cc: Archit Taneja, rob, linux-omap, linux-fbdev

On Friday 31 August 2012 05:27 PM, Tomi Valkeinen wrote:
> On Thu, 2012-08-30 at 17:10 +0530, Archit Taneja wrote:
>> Add output structs to output driver's private data. Register output instances by
>> having an init function in the probes of the platform device drivers for
>> different outputs. The *_init_output for each output registers the output and
>> fill up the output's plaform device, type and id fields.
>>
>> In the probe of each interface driver, the output entities are initialized
>> before the *_probe_pdata() functions intentionally. This is done to ensure that
>> the output entity is prepared before the panels connected to the output are
>> registered. We need the output entities to be ready because OMAPDSS will try
>> to make connections between overlays, managers, outputs and devices during the
>> panel's probe.
>>
>> Signed-off-by: Archit Taneja <archit@ti.com>
>> ---
>>   drivers/video/omap2/dss/dpi.c  |   15 +++++++++++++++
>>   drivers/video/omap2/dss/dsi.c  |   18 ++++++++++++++++++
>>   drivers/video/omap2/dss/hdmi.c |   15 +++++++++++++++
>>   drivers/video/omap2/dss/rfbi.c |   17 +++++++++++++++++
>>   drivers/video/omap2/dss/sdi.c  |   15 +++++++++++++++
>>   drivers/video/omap2/dss/venc.c |   15 +++++++++++++++
>>   6 files changed, 95 insertions(+)
>>
>> diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c
>> index 25fb895..9a7aee5 100644
>> --- a/drivers/video/omap2/dss/dpi.c
>> +++ b/drivers/video/omap2/dss/dpi.c
>> @@ -45,6 +45,8 @@ static struct {
>>   	struct omap_video_timings timings;
>>   	struct dss_lcd_mgr_config mgr_config;
>>   	int data_lines;
>> +
>> +	struct omap_dss_output output;
>>   } dpi;
>>
>>   static struct platform_device *dpi_get_dsidev(enum omap_dss_clk_source clk)
>> @@ -410,10 +412,23 @@ static void __init dpi_probe_pdata(struct platform_device *pdev)
>>   	}
>>   }
>>
>> +static void __init dpi_init_output(struct platform_device *pdev)
>> +{
>> +	struct omap_dss_output *out = &dpi.output;
>> +
>> +	dss_register_output(out);
>> +
>> +	out->pdev = pdev;
>> +	out->id = OMAP_DSS_OUTPUT_DPI;
>> +	out->type = OMAP_DISPLAY_TYPE_DPI;
>> +}
>
> I think you should first initialize the output, and then register it.
> Not the other way around.

Ok.

>
> I believe you need to implement unregister also. Normally unregister
> won't be done, but the probe of an output driver can fail after the
> output has been registered, and thus the output needs to be unregistered
> at cleanup.

Ah, right.

>
> And it doesn't harm to unregister at the driver's remove.

I'll fix these, thanks.

Archit


^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [PATCH v2 06/23] OMAP_VOUT: Remove manager->device references
  2012-08-30 11:52     ` Archit Taneja
@ 2012-08-31 12:11       ` Tomi Valkeinen
  -1 siblings, 0 replies; 148+ messages in thread
From: Tomi Valkeinen @ 2012-08-31 12:11 UTC (permalink / raw)
  To: Archit Taneja; +Cc: rob, linux-omap, linux-fbdev, Vaibhav Hiremath

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

On Thu, 2012-08-30 at 17:10 +0530, Archit Taneja wrote:
> With the introduction of output entities, managers will now connect to outputs.
> Use the helper op for managers named get_device. This will abstract away the
> information on how to get the device from an overlay manager.
> 
> Using the helper function will reduce the number of pointer dereferences a user
> of OMAPDSS needs to do and reduce risk of a NULL dereference.

Almost all the uses here seem to be getting the dssdev from an overlay.
Would it make sense to implement get_device for an ovl? That would
reduce all the ovl->manager ? ovl->manager->get_device(ovl->manager) :
NULL; code to ovl->get_device(ovl).

 Tomi


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

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [PATCH v2 06/23] OMAP_VOUT: Remove manager->device references
@ 2012-08-31 12:11       ` Tomi Valkeinen
  0 siblings, 0 replies; 148+ messages in thread
From: Tomi Valkeinen @ 2012-08-31 12:11 UTC (permalink / raw)
  To: Archit Taneja; +Cc: rob, linux-omap, linux-fbdev, Vaibhav Hiremath

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

On Thu, 2012-08-30 at 17:10 +0530, Archit Taneja wrote:
> With the introduction of output entities, managers will now connect to outputs.
> Use the helper op for managers named get_device. This will abstract away the
> information on how to get the device from an overlay manager.
> 
> Using the helper function will reduce the number of pointer dereferences a user
> of OMAPDSS needs to do and reduce risk of a NULL dereference.

Almost all the uses here seem to be getting the dssdev from an overlay.
Would it make sense to implement get_device for an ovl? That would
reduce all the ovl->manager ? ovl->manager->get_device(ovl->manager) :
NULL; code to ovl->get_device(ovl).

 Tomi


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

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [PATCH v2 02/23] OMAPDSS: outputs: Create and register output instances
@ 2012-08-31 12:15         ` Archit Taneja
  0 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-08-31 12:15 UTC (permalink / raw)
  To: Tomi Valkeinen; +Cc: Archit Taneja, rob, linux-omap, linux-fbdev

On Friday 31 August 2012 05:27 PM, Tomi Valkeinen wrote:
> On Thu, 2012-08-30 at 17:10 +0530, Archit Taneja wrote:
>> Add output structs to output driver's private data. Register output instances by
>> having an init function in the probes of the platform device drivers for
>> different outputs. The *_init_output for each output registers the output and
>> fill up the output's plaform device, type and id fields.
>>
>> In the probe of each interface driver, the output entities are initialized
>> before the *_probe_pdata() functions intentionally. This is done to ensure that
>> the output entity is prepared before the panels connected to the output are
>> registered. We need the output entities to be ready because OMAPDSS will try
>> to make connections between overlays, managers, outputs and devices during the
>> panel's probe.
>>
>> Signed-off-by: Archit Taneja <archit@ti.com>
>> ---
>>   drivers/video/omap2/dss/dpi.c  |   15 +++++++++++++++
>>   drivers/video/omap2/dss/dsi.c  |   18 ++++++++++++++++++
>>   drivers/video/omap2/dss/hdmi.c |   15 +++++++++++++++
>>   drivers/video/omap2/dss/rfbi.c |   17 +++++++++++++++++
>>   drivers/video/omap2/dss/sdi.c  |   15 +++++++++++++++
>>   drivers/video/omap2/dss/venc.c |   15 +++++++++++++++
>>   6 files changed, 95 insertions(+)
>>
>> diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c
>> index 25fb895..9a7aee5 100644
>> --- a/drivers/video/omap2/dss/dpi.c
>> +++ b/drivers/video/omap2/dss/dpi.c
>> @@ -45,6 +45,8 @@ static struct {
>>   	struct omap_video_timings timings;
>>   	struct dss_lcd_mgr_config mgr_config;
>>   	int data_lines;
>> +
>> +	struct omap_dss_output output;
>>   } dpi;
>>
>>   static struct platform_device *dpi_get_dsidev(enum omap_dss_clk_source clk)
>> @@ -410,10 +412,23 @@ static void __init dpi_probe_pdata(struct platform_device *pdev)
>>   	}
>>   }
>>
>> +static void __init dpi_init_output(struct platform_device *pdev)
>> +{
>> +	struct omap_dss_output *out = &dpi.output;
>> +
>> +	dss_register_output(out);
>> +
>> +	out->pdev = pdev;
>> +	out->id = OMAP_DSS_OUTPUT_DPI;
>> +	out->type = OMAP_DISPLAY_TYPE_DPI;
>> +}
>
> I think you should first initialize the output, and then register it.
> Not the other way around.

Ok.

>
> I believe you need to implement unregister also. Normally unregister
> won't be done, but the probe of an output driver can fail after the
> output has been registered, and thus the output needs to be unregistered
> at cleanup.

Ah, right.

>
> And it doesn't harm to unregister at the driver's remove.

I'll fix these, thanks.

Archit


^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [PATCH v2 03/23] OMAPDSS: output: Add set/unset device ops for omap_dss_output
  2012-08-31 12:03       ` Tomi Valkeinen
@ 2012-08-31 12:36         ` Archit Taneja
  -1 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-08-31 12:24 UTC (permalink / raw)
  To: Tomi Valkeinen; +Cc: rob, linux-omap, linux-fbdev

On Friday 31 August 2012 05:33 PM, Tomi Valkeinen wrote:
> On Thu, 2012-08-30 at 17:10 +0530, Archit Taneja wrote:
>> An output entity represented by the struct omap_dss_output connects to a
>> omap_dss_device entity. Add functions to set or unset an output's device. This
>> is similar to how managers and devices were connected previously. An output can
>> connect to a device without being connected to a manager. However, the output
>> needs to eventually connect to a manager so that the connected panel can be
>> enabled.
>>
>> Keep the omap_overlay_manager pointer in omap_dss_device for now to prevent
>> breaking things. This will be removed later when outputs are supported
>> completely.
>>
>> Signed-off-by: Archit Taneja <archit@ti.com>
>> ---
>>   drivers/video/omap2/dss/output.c |   67 ++++++++++++++++++++++++++++++++++++++
>>   include/video/omapdss.h          |    5 +++
>>   2 files changed, 72 insertions(+)
>>
>> diff --git a/drivers/video/omap2/dss/output.c b/drivers/video/omap2/dss/output.c
>> index 7d81be5..abc3aa2 100644
>> --- a/drivers/video/omap2/dss/output.c
>> +++ b/drivers/video/omap2/dss/output.c
>> @@ -24,9 +24,76 @@
>>   #include "dss.h"
>>
>>   static LIST_HEAD(output_list);
>> +static DEFINE_MUTEX(output_lock);
>> +
>> +static int dss_output_set_device(struct omap_dss_output *out,
>> +		struct omap_dss_device *dssdev)
>> +{
>> +	int r;
>> +
>> +	mutex_lock(&output_lock);
>> +
>> +	if (out->device) {
>> +		DSSERR("output already has device %s connected to it\n",
>> +			out->device->name);
>> +		r = -EINVAL;
>> +		goto err;
>> +	}
>> +
>> +	if (out->type != dssdev->type) {
>> +		DSSERR("output type and display type don't match\n");
>> +		r = -EINVAL;
>> +		goto err;
>> +	}
>> +
>> +	out->device = dssdev;
>> +	dssdev->output = out;
>> +
>> +	mutex_unlock(&output_lock);
>> +
>> +	return 0;
>> +err:
>> +	mutex_unlock(&output_lock);
>> +
>> +	return r;
>> +}
>> +
>> +static int dss_output_unset_device(struct omap_dss_output *out)
>> +{
>> +	int r;
>> +
>> +	mutex_lock(&output_lock);
>> +
>> +	if (!out->device) {
>> +		DSSERR("output doesn't have a device connected to it\n");
>> +		r = -EINVAL;
>> +		goto err;
>> +	}
>> +
>> +	if (out->device->state != OMAP_DSS_DISPLAY_DISABLED) {
>> +		DSSERR("device %s is not disabled, cannot unset device\n",
>> +				out->device->name);
>> +		r = -EINVAL;
>> +		goto err;
>> +	}
>> +
>> +	out->device->output = NULL;
>> +	out->device = NULL;
>> +
>> +	mutex_unlock(&output_lock);
>> +
>> +	return 0;
>> +err:
>> +	mutex_unlock(&output_lock);
>> +
>> +	return r;
>> +}
>>
>>   void dss_register_output(struct omap_dss_output *out)
>>   {
>> +	out->set_device = &dss_output_set_device;
>> +	out->unset_device = &dss_output_unset_device;
>> +
>>   	list_add_tail(&out->list, &output_list);
>>   }
>
> I don't think there's need for this indirection. We should use function
> pointers only when the func pointer may lead to different functions.
> Here we'll always have just one function, dss_output_set_device. We can
> as well call the function directly.

Okay. I understand that. But in general, don't func pointers prevent us 
from exporting more symbols?

>
> I know we have similar func pointers for ovls/mgrs currently, but I
> don't think they are good either. They are a relic from the time we
> supported "virtual" overlays and managers, and thus could have different
> implementations for the operations.

Oh okay, I guess you mean the L4/sDMA updates for DSI command mode.

Archit


^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [PATCH v2 03/23] OMAPDSS: output: Add set/unset device ops for omap_dss_output
  2012-08-31 12:36         ` Archit Taneja
@ 2012-08-31 12:28           ` Tomi Valkeinen
  -1 siblings, 0 replies; 148+ messages in thread
From: Tomi Valkeinen @ 2012-08-31 12:28 UTC (permalink / raw)
  To: Archit Taneja; +Cc: rob, linux-omap, linux-fbdev

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

On Fri, 2012-08-31 at 17:54 +0530, Archit Taneja wrote:
> On Friday 31 August 2012 05:33 PM, Tomi Valkeinen wrote:

> > I don't think there's need for this indirection. We should use function
> > pointers only when the func pointer may lead to different functions.
> > Here we'll always have just one function, dss_output_set_device. We can
> > as well call the function directly.
> 
> Okay. I understand that. But in general, don't func pointers prevent us 
> from exporting more symbols?

Yes. But I'm not sure if there's any real downside to exporting, as long
as the names are prefixed properly so that there are no name clashes.

> > I know we have similar func pointers for ovls/mgrs currently, but I
> > don't think they are good either. They are a relic from the time we
> > supported "virtual" overlays and managers, and thus could have different
> > implementations for the operations.
> 
> Oh okay, I guess you mean the L4/sDMA updates for DSI command mode.

Yep.

 Tomi


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

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [PATCH v2 03/23] OMAPDSS: output: Add set/unset device ops for omap_dss_output
@ 2012-08-31 12:28           ` Tomi Valkeinen
  0 siblings, 0 replies; 148+ messages in thread
From: Tomi Valkeinen @ 2012-08-31 12:28 UTC (permalink / raw)
  To: Archit Taneja; +Cc: rob, linux-omap, linux-fbdev

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

On Fri, 2012-08-31 at 17:54 +0530, Archit Taneja wrote:
> On Friday 31 August 2012 05:33 PM, Tomi Valkeinen wrote:

> > I don't think there's need for this indirection. We should use function
> > pointers only when the func pointer may lead to different functions.
> > Here we'll always have just one function, dss_output_set_device. We can
> > as well call the function directly.
> 
> Okay. I understand that. But in general, don't func pointers prevent us 
> from exporting more symbols?

Yes. But I'm not sure if there's any real downside to exporting, as long
as the names are prefixed properly so that there are no name clashes.

> > I know we have similar func pointers for ovls/mgrs currently, but I
> > don't think they are good either. They are a relic from the time we
> > supported "virtual" overlays and managers, and thus could have different
> > implementations for the operations.
> 
> Oh okay, I guess you mean the L4/sDMA updates for DSI command mode.

Yep.

 Tomi


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

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [PATCH v2 06/23] OMAP_VOUT: Remove manager->device references
  2012-08-31 12:11       ` Tomi Valkeinen
@ 2012-08-31 12:46         ` Archit Taneja
  -1 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-08-31 12:34 UTC (permalink / raw)
  To: Tomi Valkeinen; +Cc: rob, linux-omap, linux-fbdev, Vaibhav Hiremath

On Friday 31 August 2012 05:41 PM, Tomi Valkeinen wrote:
> On Thu, 2012-08-30 at 17:10 +0530, Archit Taneja wrote:
>> With the introduction of output entities, managers will now connect to outputs.
>> Use the helper op for managers named get_device. This will abstract away the
>> information on how to get the device from an overlay manager.
>>
>> Using the helper function will reduce the number of pointer dereferences a user
>> of OMAPDSS needs to do and reduce risk of a NULL dereference.
>
> Almost all the uses here seem to be getting the dssdev from an overlay.
> Would it make sense to implement get_device for an ovl? That would
> reduce all the ovl->manager ? ovl->manager->get_device(ovl->manager) :
> NULL; code to ovl->get_device(ovl).

That make sense.

We would still need mgr->get_device() though, as in some places, dss and 
drm try to get the display from the manager.

Archit


^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [PATCH v2 03/23] OMAPDSS: output: Add set/unset device ops for omap_dss_output
@ 2012-08-31 12:36         ` Archit Taneja
  0 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-08-31 12:36 UTC (permalink / raw)
  To: Tomi Valkeinen; +Cc: rob, linux-omap, linux-fbdev

On Friday 31 August 2012 05:33 PM, Tomi Valkeinen wrote:
> On Thu, 2012-08-30 at 17:10 +0530, Archit Taneja wrote:
>> An output entity represented by the struct omap_dss_output connects to a
>> omap_dss_device entity. Add functions to set or unset an output's device. This
>> is similar to how managers and devices were connected previously. An output can
>> connect to a device without being connected to a manager. However, the output
>> needs to eventually connect to a manager so that the connected panel can be
>> enabled.
>>
>> Keep the omap_overlay_manager pointer in omap_dss_device for now to prevent
>> breaking things. This will be removed later when outputs are supported
>> completely.
>>
>> Signed-off-by: Archit Taneja <archit@ti.com>
>> ---
>>   drivers/video/omap2/dss/output.c |   67 ++++++++++++++++++++++++++++++++++++++
>>   include/video/omapdss.h          |    5 +++
>>   2 files changed, 72 insertions(+)
>>
>> diff --git a/drivers/video/omap2/dss/output.c b/drivers/video/omap2/dss/output.c
>> index 7d81be5..abc3aa2 100644
>> --- a/drivers/video/omap2/dss/output.c
>> +++ b/drivers/video/omap2/dss/output.c
>> @@ -24,9 +24,76 @@
>>   #include "dss.h"
>>
>>   static LIST_HEAD(output_list);
>> +static DEFINE_MUTEX(output_lock);
>> +
>> +static int dss_output_set_device(struct omap_dss_output *out,
>> +		struct omap_dss_device *dssdev)
>> +{
>> +	int r;
>> +
>> +	mutex_lock(&output_lock);
>> +
>> +	if (out->device) {
>> +		DSSERR("output already has device %s connected to it\n",
>> +			out->device->name);
>> +		r = -EINVAL;
>> +		goto err;
>> +	}
>> +
>> +	if (out->type != dssdev->type) {
>> +		DSSERR("output type and display type don't match\n");
>> +		r = -EINVAL;
>> +		goto err;
>> +	}
>> +
>> +	out->device = dssdev;
>> +	dssdev->output = out;
>> +
>> +	mutex_unlock(&output_lock);
>> +
>> +	return 0;
>> +err:
>> +	mutex_unlock(&output_lock);
>> +
>> +	return r;
>> +}
>> +
>> +static int dss_output_unset_device(struct omap_dss_output *out)
>> +{
>> +	int r;
>> +
>> +	mutex_lock(&output_lock);
>> +
>> +	if (!out->device) {
>> +		DSSERR("output doesn't have a device connected to it\n");
>> +		r = -EINVAL;
>> +		goto err;
>> +	}
>> +
>> +	if (out->device->state != OMAP_DSS_DISPLAY_DISABLED) {
>> +		DSSERR("device %s is not disabled, cannot unset device\n",
>> +				out->device->name);
>> +		r = -EINVAL;
>> +		goto err;
>> +	}
>> +
>> +	out->device->output = NULL;
>> +	out->device = NULL;
>> +
>> +	mutex_unlock(&output_lock);
>> +
>> +	return 0;
>> +err:
>> +	mutex_unlock(&output_lock);
>> +
>> +	return r;
>> +}
>>
>>   void dss_register_output(struct omap_dss_output *out)
>>   {
>> +	out->set_device = &dss_output_set_device;
>> +	out->unset_device = &dss_output_unset_device;
>> +
>>   	list_add_tail(&out->list, &output_list);
>>   }
>
> I don't think there's need for this indirection. We should use function
> pointers only when the func pointer may lead to different functions.
> Here we'll always have just one function, dss_output_set_device. We can
> as well call the function directly.

Okay. I understand that. But in general, don't func pointers prevent us 
from exporting more symbols?

>
> I know we have similar func pointers for ovls/mgrs currently, but I
> don't think they are good either. They are a relic from the time we
> supported "virtual" overlays and managers, and thus could have different
> implementations for the operations.

Oh okay, I guess you mean the L4/sDMA updates for DSI command mode.

Archit


^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [PATCH v2 06/23] OMAP_VOUT: Remove manager->device references
@ 2012-08-31 12:46         ` Archit Taneja
  0 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-08-31 12:46 UTC (permalink / raw)
  To: Tomi Valkeinen; +Cc: rob, linux-omap, linux-fbdev, Vaibhav Hiremath

On Friday 31 August 2012 05:41 PM, Tomi Valkeinen wrote:
> On Thu, 2012-08-30 at 17:10 +0530, Archit Taneja wrote:
>> With the introduction of output entities, managers will now connect to outputs.
>> Use the helper op for managers named get_device. This will abstract away the
>> information on how to get the device from an overlay manager.
>>
>> Using the helper function will reduce the number of pointer dereferences a user
>> of OMAPDSS needs to do and reduce risk of a NULL dereference.
>
> Almost all the uses here seem to be getting the dssdev from an overlay.
> Would it make sense to implement get_device for an ovl? That would
> reduce all the ovl->manager ? ovl->manager->get_device(ovl->manager) :
> NULL; code to ovl->get_device(ovl).

That make sense.

We would still need mgr->get_device() though, as in some places, dss and 
drm try to get the display from the manager.

Archit


^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [PATCH v2 10/23] OMAPDSS: DPI: Pass omap_dss_output within the driver
  2012-08-30 11:52     ` Archit Taneja
@ 2012-08-31 13:48       ` Tomi Valkeinen
  -1 siblings, 0 replies; 148+ messages in thread
From: Tomi Valkeinen @ 2012-08-31 13:48 UTC (permalink / raw)
  To: Archit Taneja; +Cc: rob, linux-omap, linux-fbdev

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

On Thu, 2012-08-30 at 17:10 +0530, Archit Taneja wrote:
> When a panel driver calls a DPI function, it passes the omap_dss_device
> pointer, this pointer currently propagates within the DPI driver to configure
> the interface.
> 
> Extract the omap_dss_output pointer from omap_dss_device received from the panel
> driver, pass the output pointer to DPI functions local to the driver to
> configure the interface, these functions no longer need omap_dss_device since
> the driver now maintains a copy of output parameters.
> 
> Replace dssdev->manager references with out->manager references as only these
> will be valid later.
> 
> With the addition of outputs. There is a possibility that an omap_dss_device
> isn't connected to an output, or a manager isn't connected to an output yet.
> Ensure that the DPI interface functions proceed only if the output is non NULL.

I agree with the direction of this and the similar patches for other
outputs, but I think we should leave these out for now, at least most of
the code here.

So ultimately we'll have the output drivers taking the omap_dss_output
as an argument, and we don't need dssdev anymore. But we can't do that
yet, and now that you mix both approaches I think the end result makes
the code a bit more confusing, and it would be changed again later when
dssdev can be removed.

What I mean is that, for example, display_enable takes dssdev as an
argument. Then you extract output from that, and pass output to some
other functions. Then these functions again extract dssdev from the
output.

This feels like extra churn that doesn't really help anything, and will
be changed later when the functions get output as an argument. So I
propose to keep passing dssdev around until we've removed the
dependencies to dssdev, and we (probably) get the output directly as an
argument to the functions. Then we can clean them up properly at one go.

The dssdev->manager parts still need to be changed to out->manager, of
course, but I think those are minority of the changes here and the
following patches.

 Tomi


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

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [PATCH v2 10/23] OMAPDSS: DPI: Pass omap_dss_output within the driver
@ 2012-08-31 13:48       ` Tomi Valkeinen
  0 siblings, 0 replies; 148+ messages in thread
From: Tomi Valkeinen @ 2012-08-31 13:48 UTC (permalink / raw)
  To: Archit Taneja; +Cc: rob, linux-omap, linux-fbdev

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

On Thu, 2012-08-30 at 17:10 +0530, Archit Taneja wrote:
> When a panel driver calls a DPI function, it passes the omap_dss_device
> pointer, this pointer currently propagates within the DPI driver to configure
> the interface.
> 
> Extract the omap_dss_output pointer from omap_dss_device received from the panel
> driver, pass the output pointer to DPI functions local to the driver to
> configure the interface, these functions no longer need omap_dss_device since
> the driver now maintains a copy of output parameters.
> 
> Replace dssdev->manager references with out->manager references as only these
> will be valid later.
> 
> With the addition of outputs. There is a possibility that an omap_dss_device
> isn't connected to an output, or a manager isn't connected to an output yet.
> Ensure that the DPI interface functions proceed only if the output is non NULL.

I agree with the direction of this and the similar patches for other
outputs, but I think we should leave these out for now, at least most of
the code here.

So ultimately we'll have the output drivers taking the omap_dss_output
as an argument, and we don't need dssdev anymore. But we can't do that
yet, and now that you mix both approaches I think the end result makes
the code a bit more confusing, and it would be changed again later when
dssdev can be removed.

What I mean is that, for example, display_enable takes dssdev as an
argument. Then you extract output from that, and pass output to some
other functions. Then these functions again extract dssdev from the
output.

This feels like extra churn that doesn't really help anything, and will
be changed later when the functions get output as an argument. So I
propose to keep passing dssdev around until we've removed the
dependencies to dssdev, and we (probably) get the output directly as an
argument to the functions. Then we can clean them up properly at one go.

The dssdev->manager parts still need to be changed to out->manager, of
course, but I think those are minority of the changes here and the
following patches.

 Tomi


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

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [PATCH v2 10/23] OMAPDSS: DPI: Pass omap_dss_output within the driver
  2012-08-31 13:48       ` Tomi Valkeinen
@ 2012-08-31 14:00         ` Archit Taneja
  -1 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-08-31 13:59 UTC (permalink / raw)
  To: Tomi Valkeinen; +Cc: rob, linux-omap, linux-fbdev

On Friday 31 August 2012 07:18 PM, Tomi Valkeinen wrote:
> On Thu, 2012-08-30 at 17:10 +0530, Archit Taneja wrote:
>> When a panel driver calls a DPI function, it passes the omap_dss_device
>> pointer, this pointer currently propagates within the DPI driver to configure
>> the interface.
>>
>> Extract the omap_dss_output pointer from omap_dss_device received from the panel
>> driver, pass the output pointer to DPI functions local to the driver to
>> configure the interface, these functions no longer need omap_dss_device since
>> the driver now maintains a copy of output parameters.
>>
>> Replace dssdev->manager references with out->manager references as only these
>> will be valid later.
>>
>> With the addition of outputs. There is a possibility that an omap_dss_device
>> isn't connected to an output, or a manager isn't connected to an output yet.
>> Ensure that the DPI interface functions proceed only if the output is non NULL.
>
> I agree with the direction of this and the similar patches for other
> outputs, but I think we should leave these out for now, at least most of
> the code here.
>
> So ultimately we'll have the output drivers taking the omap_dss_output
> as an argument, and we don't need dssdev anymore. But we can't do that
> yet, and now that you mix both approaches I think the end result makes
> the code a bit more confusing, and it would be changed again later when
> dssdev can be removed.
>
> What I mean is that, for example, display_enable takes dssdev as an
> argument. Then you extract output from that, and pass output to some
> other functions. Then these functions again extract dssdev from the
> output.
>
> This feels like extra churn that doesn't really help anything, and will
> be changed later when the functions get output as an argument. So I
> propose to keep passing dssdev around until we've removed the
> dependencies to dssdev, and we (probably) get the output directly as an
> argument to the functions. Then we can clean them up properly at one go.
>
> The dssdev->manager parts still need to be changed to out->manager, of
> course, but I think those are minority of the changes here and the
> following patches.

Ok. Yes, I guess if we start from here, we would need to do unnecessary 
changes once we completely switch to outputs.

I'll change these output patches such that, only the dssdev->manager 
references are fixed to dssdev->output->manager.

Archit


^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [PATCH v2 10/23] OMAPDSS: DPI: Pass omap_dss_output within the driver
@ 2012-08-31 14:00         ` Archit Taneja
  0 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-08-31 14:00 UTC (permalink / raw)
  To: Tomi Valkeinen; +Cc: rob, linux-omap, linux-fbdev

On Friday 31 August 2012 07:18 PM, Tomi Valkeinen wrote:
> On Thu, 2012-08-30 at 17:10 +0530, Archit Taneja wrote:
>> When a panel driver calls a DPI function, it passes the omap_dss_device
>> pointer, this pointer currently propagates within the DPI driver to configure
>> the interface.
>>
>> Extract the omap_dss_output pointer from omap_dss_device received from the panel
>> driver, pass the output pointer to DPI functions local to the driver to
>> configure the interface, these functions no longer need omap_dss_device since
>> the driver now maintains a copy of output parameters.
>>
>> Replace dssdev->manager references with out->manager references as only these
>> will be valid later.
>>
>> With the addition of outputs. There is a possibility that an omap_dss_device
>> isn't connected to an output, or a manager isn't connected to an output yet.
>> Ensure that the DPI interface functions proceed only if the output is non NULL.
>
> I agree with the direction of this and the similar patches for other
> outputs, but I think we should leave these out for now, at least most of
> the code here.
>
> So ultimately we'll have the output drivers taking the omap_dss_output
> as an argument, and we don't need dssdev anymore. But we can't do that
> yet, and now that you mix both approaches I think the end result makes
> the code a bit more confusing, and it would be changed again later when
> dssdev can be removed.
>
> What I mean is that, for example, display_enable takes dssdev as an
> argument. Then you extract output from that, and pass output to some
> other functions. Then these functions again extract dssdev from the
> output.
>
> This feels like extra churn that doesn't really help anything, and will
> be changed later when the functions get output as an argument. So I
> propose to keep passing dssdev around until we've removed the
> dependencies to dssdev, and we (probably) get the output directly as an
> argument to the functions. Then we can clean them up properly at one go.
>
> The dssdev->manager parts still need to be changed to out->manager, of
> course, but I think those are minority of the changes here and the
> following patches.

Ok. Yes, I guess if we start from here, we would need to do unnecessary 
changes once we completely switch to outputs.

I'll change these output patches such that, only the dssdev->manager 
references are fixed to dssdev->output->manager.

Archit


^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [PATCH v2 09/23] OMAPDSS: Create links between managers, outputs and devices
  2012-08-30 11:52     ` Archit Taneja
@ 2012-08-31 14:10       ` Tomi Valkeinen
  -1 siblings, 0 replies; 148+ messages in thread
From: Tomi Valkeinen @ 2012-08-31 14:10 UTC (permalink / raw)
  To: Archit Taneja; +Cc: rob, linux-omap, linux-fbdev

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

On Thu, 2012-08-30 at 17:10 +0530, Archit Taneja wrote:
> Links between DSS entities are made in dss_recheck_connections when a new panel
> is probed. Rewrite the code in dss_recheck_connections to link managers to
> outputs, and outputs to devices.
> 
> The fields in omap_dss_device struct gives information on which output and
> manager to connect to. The desired manager and output pointers are retrieved and
> prepared(existing outputs/devices unset, if default display)) to form the
> desired links. The output is linked to the device, and then the manager to the
> output. If a probed device's required manager isn't free, the required output
> is still connected to the device so that it's easier to use the panel in the
> future.

I've been pondering this one, and I can't come to a conclusion. The
recheck_connections is just so ugly that I'd like to get rid of it =). I
guess this patch doesn't make it any more ugly, so we can include it in
the patch series.

And as I mentioned earlier, I think we should get rid of the
OMAP_DISPLAY_TYPE_* enum, as it's kinda extra now. But doing that would
require changing all board files. That's not out of the question, but I
think we should first make sure we know what we are doing with the board
files so we don't go back and forth there.

Just gathering my thoughts:

When we define a panel in DT/board file, we should also define the
output instance, because that's part of the hardware design. But there
are no hardcoded links between mgrs and outputs, so that doesn't belong
to the DT/board file. For example, omap4460's DSI1 can take input from
LCD1 or LCD2.

So who could/should make the decision which mgr to use... Well, I don't
know on what basis the decision can be made, but I still think omapdss
can't make good decisions on that, so probably the whole "chain" should
be configured in the omapfb/omapdrm level.

 Tomi


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

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [PATCH v2 09/23] OMAPDSS: Create links between managers, outputs and devices
@ 2012-08-31 14:10       ` Tomi Valkeinen
  0 siblings, 0 replies; 148+ messages in thread
From: Tomi Valkeinen @ 2012-08-31 14:10 UTC (permalink / raw)
  To: Archit Taneja; +Cc: rob, linux-omap, linux-fbdev

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

On Thu, 2012-08-30 at 17:10 +0530, Archit Taneja wrote:
> Links between DSS entities are made in dss_recheck_connections when a new panel
> is probed. Rewrite the code in dss_recheck_connections to link managers to
> outputs, and outputs to devices.
> 
> The fields in omap_dss_device struct gives information on which output and
> manager to connect to. The desired manager and output pointers are retrieved and
> prepared(existing outputs/devices unset, if default display)) to form the
> desired links. The output is linked to the device, and then the manager to the
> output. If a probed device's required manager isn't free, the required output
> is still connected to the device so that it's easier to use the panel in the
> future.

I've been pondering this one, and I can't come to a conclusion. The
recheck_connections is just so ugly that I'd like to get rid of it =). I
guess this patch doesn't make it any more ugly, so we can include it in
the patch series.

And as I mentioned earlier, I think we should get rid of the
OMAP_DISPLAY_TYPE_* enum, as it's kinda extra now. But doing that would
require changing all board files. That's not out of the question, but I
think we should first make sure we know what we are doing with the board
files so we don't go back and forth there.

Just gathering my thoughts:

When we define a panel in DT/board file, we should also define the
output instance, because that's part of the hardware design. But there
are no hardcoded links between mgrs and outputs, so that doesn't belong
to the DT/board file. For example, omap4460's DSI1 can take input from
LCD1 or LCD2.

So who could/should make the decision which mgr to use... Well, I don't
know on what basis the decision can be made, but I still think omapdss
can't make good decisions on that, so probably the whole "chain" should
be configured in the omapfb/omapdrm level.

 Tomi


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

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [PATCH v2 15/23] OMAPDSS: RFBI: Add dssdev pointers as arguments to all exported functions
  2012-08-30 11:52     ` Archit Taneja
@ 2012-08-31 14:20       ` Tomi Valkeinen
  -1 siblings, 0 replies; 148+ messages in thread
From: Tomi Valkeinen @ 2012-08-31 14:20 UTC (permalink / raw)
  To: Archit Taneja; +Cc: rob, linux-omap, linux-fbdev

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

On Thu, 2012-08-30 at 17:10 +0530, Archit Taneja wrote:
> All functions of an interface driver used by a panel driver should have an
> omap_dss_device 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 dssdev 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.

This and the similar patch for HDMI could probably also be left out for
now. Again I agree that this is correct direction, but this is not
really needed (right?) for output work or writeback. And we'll
eventually just change these parameters again.

The motivation for this patch was probably to have common format for the
output driver's functions, so that you can use func pointers in an ops
struct?

Let's delay that work until the common panel framework gets a bit more
solid.

Sorry if I'm saying "leave this patch out" for most of the patches =). I
just want to avoid extra churn, going back and forth with the code. The
most important things now are to get the output work in a state that WB
can be used, and on the other hand to remove the dssdev dependencies so
that at some point we can remove dssdev totally.

 Tomi


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

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [PATCH v2 15/23] OMAPDSS: RFBI: Add dssdev pointers as arguments to all exported functions
@ 2012-08-31 14:20       ` Tomi Valkeinen
  0 siblings, 0 replies; 148+ messages in thread
From: Tomi Valkeinen @ 2012-08-31 14:20 UTC (permalink / raw)
  To: Archit Taneja; +Cc: rob, linux-omap, linux-fbdev

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

On Thu, 2012-08-30 at 17:10 +0530, Archit Taneja wrote:
> All functions of an interface driver used by a panel driver should have an
> omap_dss_device 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 dssdev 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.

This and the similar patch for HDMI could probably also be left out for
now. Again I agree that this is correct direction, but this is not
really needed (right?) for output work or writeback. And we'll
eventually just change these parameters again.

The motivation for this patch was probably to have common format for the
output driver's functions, so that you can use func pointers in an ops
struct?

Let's delay that work until the common panel framework gets a bit more
solid.

Sorry if I'm saying "leave this patch out" for most of the patches =). I
just want to avoid extra churn, going back and forth with the code. The
most important things now are to get the output work in a state that WB
can be used, and on the other hand to remove the dssdev dependencies so
that at some point we can remove dssdev totally.

 Tomi


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

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [PATCH v2 09/23] OMAPDSS: Create links between managers, outputs and devices
  2012-08-31 14:10       ` Tomi Valkeinen
@ 2012-08-31 14:36         ` Archit Taneja
  -1 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-08-31 14:24 UTC (permalink / raw)
  To: Tomi Valkeinen; +Cc: rob, linux-omap, linux-fbdev

On Friday 31 August 2012 07:40 PM, Tomi Valkeinen wrote:
> On Thu, 2012-08-30 at 17:10 +0530, Archit Taneja wrote:
>> Links between DSS entities are made in dss_recheck_connections when a new panel
>> is probed. Rewrite the code in dss_recheck_connections to link managers to
>> outputs, and outputs to devices.
>>
>> The fields in omap_dss_device struct gives information on which output and
>> manager to connect to. The desired manager and output pointers are retrieved and
>> prepared(existing outputs/devices unset, if default display)) to form the
>> desired links. The output is linked to the device, and then the manager to the
>> output. If a probed device's required manager isn't free, the required output
>> is still connected to the device so that it's easier to use the panel in the
>> future.
>
> I've been pondering this one, and I can't come to a conclusion. The
> recheck_connections is just so ugly that I'd like to get rid of it =). I
> guess this patch doesn't make it any more ugly, so we can include it in
> the patch series.
>
> And as I mentioned earlier, I think we should get rid of the
> OMAP_DISPLAY_TYPE_* enum, as it's kinda extra now. But doing that would
> require changing all board files. That's not out of the question, but I
> think we should first make sure we know what we are doing with the board
> files so we don't go back and forth there.

Yes, I didn't remove it for the same reason.

>
> Just gathering my thoughts:
>
> When we define a panel in DT/board file, we should also define the
> output instance, because that's part of the hardware design. But there

It's a part of hardware design if the panel can't be detached. But yes, 
even for detachable panels, we can assume that the panel would 
eventually connect to that output.

> are no hardcoded links between mgrs and outputs, so that doesn't belong
> to the DT/board file. For example, omap4460's DSI1 can take input from
> LCD1 or LCD2.

Right, so we don't need an equivalent of the dssdev->channel field in DT 
info. As you said, we need the output instance, is that why you were 
sceptical about it being defined as an enum in previous patches? 
Probably we could define output instances in DT as a pair of instance 
number and instance type {number, type}. It would be sort of hard to 
play around with those within OMAPDSS though.

>
> So who could/should make the decision which mgr to use... Well, I don't
> know on what basis the decision can be made, but I still think omapdss
> can't make good decisions on that, so probably the whole "chain" should
> be configured in the omapfb/omapdrm level.

Which manager to chose could be simply picking up the next free manager 
which can connect to that output. omapfb/drm can take care of that.

Archit


^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [PATCH v2 15/23] OMAPDSS: RFBI: Add dssdev pointers as arguments to all exported functions
  2012-08-31 14:20       ` Tomi Valkeinen
@ 2012-08-31 14:42         ` Archit Taneja
  -1 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-08-31 14:30 UTC (permalink / raw)
  To: Tomi Valkeinen; +Cc: rob, linux-omap, linux-fbdev

On Friday 31 August 2012 07:50 PM, Tomi Valkeinen wrote:
> On Thu, 2012-08-30 at 17:10 +0530, Archit Taneja wrote:
>> All functions of an interface driver used by a panel driver should have an
>> omap_dss_device 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 dssdev 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.
>
> This and the similar patch for HDMI could probably also be left out for
> now. Again I agree that this is correct direction, but this is not
> really needed (right?) for output work or writeback. And we'll
> eventually just change these parameters again.
>
> The motivation for this patch was probably to have common format for the
> output driver's functions, so that you can use func pointers in an ops
> struct?

Yes, or the fact that we need the function to pass something related to 
the output to configure it. Things work now since we just have one 
instance of hdmi/rfbi, and that we have a global struct from which we 
can get the required info. We definitely need to pass something to these 
functions, whether we should pass the panel, or the output itself isn't 
clear yet.

>
> Let's delay that work until the common panel framework gets a bit more
> solid.

I get your point. We might need to replace the dssdevs with outputs (or 
something similar) in the future. Hence it would lead to churn.

>
> Sorry if I'm saying "leave this patch out" for most of the patches =). I
> just want to avoid extra churn, going back and forth with the code. The
> most important things now are to get the output work in a state that WB
> can be used, and on the other hand to remove the dssdev dependencies so
> that at some point we can remove dssdev totally.

That's okay. If we keep this stuff, it'll be us who have to change it 
later :)

Archit

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [PATCH v2 20/23] OMAPDSS: MANAGER: Update display sysfs store
  2012-08-30 11:52     ` Archit Taneja
@ 2012-08-31 14:30       ` Tomi Valkeinen
  -1 siblings, 0 replies; 148+ messages in thread
From: Tomi Valkeinen @ 2012-08-31 14:30 UTC (permalink / raw)
  To: Archit Taneja; +Cc: rob, linux-omap, linux-fbdev

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

On Thu, 2012-08-30 at 17:10 +0530, Archit Taneja wrote:
> 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;
>  		}
>  

Hmm, I think this is a bit broken. If I read this right, the unlinking
removes both mgr-output link and the output-dssdev link. But the linking
part only sets up the mgr-output link.

So if there's a very simple configuration with one display, if you
unlink it via sysfs you can't link it back again.

The store function gets the mgr and the dssdev as arguments. I think
this could be changed so that the function would "guess" the needed
output. Well, not so much a guess, because a dssdev can only be
connected to one output, defined by the HW design. That is basically
what the recheck_connections does, we could use the same method here.

Then this sysfs file should work just like before.

 Tomi


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

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [PATCH v2 20/23] OMAPDSS: MANAGER: Update display sysfs store
@ 2012-08-31 14:30       ` Tomi Valkeinen
  0 siblings, 0 replies; 148+ messages in thread
From: Tomi Valkeinen @ 2012-08-31 14:30 UTC (permalink / raw)
  To: Archit Taneja; +Cc: rob, linux-omap, linux-fbdev

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

On Thu, 2012-08-30 at 17:10 +0530, Archit Taneja wrote:
> 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;
>  		}
>  

Hmm, I think this is a bit broken. If I read this right, the unlinking
removes both mgr-output link and the output-dssdev link. But the linking
part only sets up the mgr-output link.

So if there's a very simple configuration with one display, if you
unlink it via sysfs you can't link it back again.

The store function gets the mgr and the dssdev as arguments. I think
this could be changed so that the function would "guess" the needed
output. Well, not so much a guess, because a dssdev can only be
connected to one output, defined by the HW design. That is basically
what the recheck_connections does, we could use the same method here.

Then this sysfs file should work just like before.

 Tomi


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

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [PATCH v2 09/23] OMAPDSS: Create links between managers, outputs and devices
@ 2012-08-31 14:36         ` Archit Taneja
  0 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-08-31 14:36 UTC (permalink / raw)
  To: Tomi Valkeinen; +Cc: rob, linux-omap, linux-fbdev

On Friday 31 August 2012 07:40 PM, Tomi Valkeinen wrote:
> On Thu, 2012-08-30 at 17:10 +0530, Archit Taneja wrote:
>> Links between DSS entities are made in dss_recheck_connections when a new panel
>> is probed. Rewrite the code in dss_recheck_connections to link managers to
>> outputs, and outputs to devices.
>>
>> The fields in omap_dss_device struct gives information on which output and
>> manager to connect to. The desired manager and output pointers are retrieved and
>> prepared(existing outputs/devices unset, if default display)) to form the
>> desired links. The output is linked to the device, and then the manager to the
>> output. If a probed device's required manager isn't free, the required output
>> is still connected to the device so that it's easier to use the panel in the
>> future.
>
> I've been pondering this one, and I can't come to a conclusion. The
> recheck_connections is just so ugly that I'd like to get rid of it =). I
> guess this patch doesn't make it any more ugly, so we can include it in
> the patch series.
>
> And as I mentioned earlier, I think we should get rid of the
> OMAP_DISPLAY_TYPE_* enum, as it's kinda extra now. But doing that would
> require changing all board files. That's not out of the question, but I
> think we should first make sure we know what we are doing with the board
> files so we don't go back and forth there.

Yes, I didn't remove it for the same reason.

>
> Just gathering my thoughts:
>
> When we define a panel in DT/board file, we should also define the
> output instance, because that's part of the hardware design. But there

It's a part of hardware design if the panel can't be detached. But yes, 
even for detachable panels, we can assume that the panel would 
eventually connect to that output.

> are no hardcoded links between mgrs and outputs, so that doesn't belong
> to the DT/board file. For example, omap4460's DSI1 can take input from
> LCD1 or LCD2.

Right, so we don't need an equivalent of the dssdev->channel field in DT 
info. As you said, we need the output instance, is that why you were 
sceptical about it being defined as an enum in previous patches? 
Probably we could define output instances in DT as a pair of instance 
number and instance type {number, type}. It would be sort of hard to 
play around with those within OMAPDSS though.

>
> So who could/should make the decision which mgr to use... Well, I don't
> know on what basis the decision can be made, but I still think omapdss
> can't make good decisions on that, so probably the whole "chain" should
> be configured in the omapfb/omapdrm level.

Which manager to chose could be simply picking up the next free manager 
which can connect to that output. omapfb/drm can take care of that.

Archit


^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [PATCH v2 20/23] OMAPDSS: MANAGER: Update display sysfs store
  2012-08-31 14:30       ` Tomi Valkeinen
@ 2012-08-31 14:53         ` Archit Taneja
  -1 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-08-31 14:41 UTC (permalink / raw)
  To: Tomi Valkeinen; +Cc: rob, linux-omap, linux-fbdev

On Friday 31 August 2012 08:00 PM, Tomi Valkeinen wrote:
> On Thu, 2012-08-30 at 17:10 +0530, Archit Taneja wrote:
>> 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;
>>   		}
>>
>
> Hmm, I think this is a bit broken. If I read this right, the unlinking
> removes both mgr-output link and the output-dssdev link. But the linking
> part only sets up the mgr-output link.
>
> So if there's a very simple configuration with one display, if you
> unlink it via sysfs you can't link it back again.

Ah, right. You might need to reinsert the display module again to get 
the output-display link again. Which is bad. Or have a sysfs file for 
setting manager output. Which is something we want to stay away from anyway.

>
> The store function gets the mgr and the dssdev as arguments. I think
> this could be changed so that the function would "guess" the needed
> output. Well, not so much a guess, because a dssdev can only be
> connected to one output, defined by the HW design. That is basically
> what the recheck_connections does, we could use the same method here.
>
> Then this sysfs file should work just like before.

That's a good idea, we could reuse the code in recheck_connections a 
bit. I wanted to stay away from the guessing. But I think we need to do 
it if a simple unlink-link of a display itself fails.

Archit


^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [PATCH v2 15/23] OMAPDSS: RFBI: Add dssdev pointers as arguments to all exported functions
@ 2012-08-31 14:42         ` Archit Taneja
  0 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-08-31 14:42 UTC (permalink / raw)
  To: Tomi Valkeinen; +Cc: rob, linux-omap, linux-fbdev

On Friday 31 August 2012 07:50 PM, Tomi Valkeinen wrote:
> On Thu, 2012-08-30 at 17:10 +0530, Archit Taneja wrote:
>> All functions of an interface driver used by a panel driver should have an
>> omap_dss_device 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 dssdev 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.
>
> This and the similar patch for HDMI could probably also be left out for
> now. Again I agree that this is correct direction, but this is not
> really needed (right?) for output work or writeback. And we'll
> eventually just change these parameters again.
>
> The motivation for this patch was probably to have common format for the
> output driver's functions, so that you can use func pointers in an ops
> struct?

Yes, or the fact that we need the function to pass something related to 
the output to configure it. Things work now since we just have one 
instance of hdmi/rfbi, and that we have a global struct from which we 
can get the required info. We definitely need to pass something to these 
functions, whether we should pass the panel, or the output itself isn't 
clear yet.

>
> Let's delay that work until the common panel framework gets a bit more
> solid.

I get your point. We might need to replace the dssdevs with outputs (or 
something similar) in the future. Hence it would lead to churn.

>
> Sorry if I'm saying "leave this patch out" for most of the patches =). I
> just want to avoid extra churn, going back and forth with the code. The
> most important things now are to get the output work in a state that WB
> can be used, and on the other hand to remove the dssdev dependencies so
> that at some point we can remove dssdev totally.

That's okay. If we keep this stuff, it'll be us who have to change it 
later :)

Archit

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [PATCH v2 09/23] OMAPDSS: Create links between managers, outputs and devices
  2012-08-31 14:36         ` Archit Taneja
@ 2012-08-31 14:45           ` Tomi Valkeinen
  -1 siblings, 0 replies; 148+ messages in thread
From: Tomi Valkeinen @ 2012-08-31 14:45 UTC (permalink / raw)
  To: Archit Taneja; +Cc: rob, linux-omap, linux-fbdev

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

On Fri, 2012-08-31 at 19:54 +0530, Archit Taneja wrote:
> On Friday 31 August 2012 07:40 PM, Tomi Valkeinen wrote:
> > On Thu, 2012-08-30 at 17:10 +0530, Archit Taneja wrote:
> >> Links between DSS entities are made in dss_recheck_connections when a new panel
> >> is probed. Rewrite the code in dss_recheck_connections to link managers to
> >> outputs, and outputs to devices.
> >>
> >> The fields in omap_dss_device struct gives information on which output and
> >> manager to connect to. The desired manager and output pointers are retrieved and
> >> prepared(existing outputs/devices unset, if default display)) to form the
> >> desired links. The output is linked to the device, and then the manager to the
> >> output. If a probed device's required manager isn't free, the required output
> >> is still connected to the device so that it's easier to use the panel in the
> >> future.
> >
> > I've been pondering this one, and I can't come to a conclusion. The
> > recheck_connections is just so ugly that I'd like to get rid of it =). I
> > guess this patch doesn't make it any more ugly, so we can include it in
> > the patch series.
> >
> > And as I mentioned earlier, I think we should get rid of the
> > OMAP_DISPLAY_TYPE_* enum, as it's kinda extra now. But doing that would
> > require changing all board files. That's not out of the question, but I
> > think we should first make sure we know what we are doing with the board
> > files so we don't go back and forth there.
> 
> Yes, I didn't remove it for the same reason.
> 
> >
> > Just gathering my thoughts:
> >
> > When we define a panel in DT/board file, we should also define the
> > output instance, because that's part of the hardware design. But there
> 
> It's a part of hardware design if the panel can't be detached. But yes, 
> even for detachable panels, we can assume that the panel would 
> eventually connect to that output.
> 
> > are no hardcoded links between mgrs and outputs, so that doesn't belong
> > to the DT/board file. For example, omap4460's DSI1 can take input from
> > LCD1 or LCD2.
> 
> Right, so we don't need an equivalent of the dssdev->channel field in DT 
> info. As you said, we need the output instance, is that why you were 

What I'm planning for DT is a direct link to the output instance.
Something like this (not correct, just to give the idea):

dss {
	dpi {
	};
};

i2c {
	/* an i2c controlled panel */
	my-panel {
		video-bus = <&dpi>;
	};
};

Then my-panel can get the handle from video-bus, and it'll get the
output device directly, without need for any IDs or such.

> sceptical about it being defined as an enum in previous patches? 
> Probably we could define output instances in DT as a pair of instance 
> number and instance type {number, type}. It would be sort of hard to 
> play around with those within OMAPDSS though.

Well, optimally we wouldn't need to know about display types or output
instances, at least in most of the cases. We'd just have a bunch of
managers, and a bunch of outputs, and rules how these can be connected.
And the panel devices would have a link to the output it's connect in HW
level.

There are probably some cases where we need some kind of ID, so that we
can handle the DSI PLL's and such. And we need to setup the rules above
somewhere, and perhaps that code needs IDs to set it up. I'm not sure.

And, well, if we don't have IDs, the rules above need to be some kind of
lists of pointers. Perhaps having a bit mask is just simpler, as we'll
never have too many output instances.

So I'm not really against having the enum. It just would've been neat to
have the output type and instance number encoded into this enum, so that
it'd be easy to extract either one. But that kinda ruins the possibility
to use it in a bit mask.

> > So who could/should make the decision which mgr to use... Well, I don't
> > know on what basis the decision can be made, but I still think omapdss
> > can't make good decisions on that, so probably the whole "chain" should
> > be configured in the omapfb/omapdrm level.
> 
> Which manager to chose could be simply picking up the next free manager 
> which can connect to that output. omapfb/drm can take care of that.

That's a good default implementation, but not quite perfect. If there
are two displays, often the other display (well, output) can only be
connected to one particular manager, whereas the other one could use two
managers. And if both try to use the same manager, especially if the one
with two options is selected first, the other one is left without a mgr.

 Tomi


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

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [PATCH v2 09/23] OMAPDSS: Create links between managers, outputs and devices
@ 2012-08-31 14:45           ` Tomi Valkeinen
  0 siblings, 0 replies; 148+ messages in thread
From: Tomi Valkeinen @ 2012-08-31 14:45 UTC (permalink / raw)
  To: Archit Taneja; +Cc: rob, linux-omap, linux-fbdev

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

On Fri, 2012-08-31 at 19:54 +0530, Archit Taneja wrote:
> On Friday 31 August 2012 07:40 PM, Tomi Valkeinen wrote:
> > On Thu, 2012-08-30 at 17:10 +0530, Archit Taneja wrote:
> >> Links between DSS entities are made in dss_recheck_connections when a new panel
> >> is probed. Rewrite the code in dss_recheck_connections to link managers to
> >> outputs, and outputs to devices.
> >>
> >> The fields in omap_dss_device struct gives information on which output and
> >> manager to connect to. The desired manager and output pointers are retrieved and
> >> prepared(existing outputs/devices unset, if default display)) to form the
> >> desired links. The output is linked to the device, and then the manager to the
> >> output. If a probed device's required manager isn't free, the required output
> >> is still connected to the device so that it's easier to use the panel in the
> >> future.
> >
> > I've been pondering this one, and I can't come to a conclusion. The
> > recheck_connections is just so ugly that I'd like to get rid of it =). I
> > guess this patch doesn't make it any more ugly, so we can include it in
> > the patch series.
> >
> > And as I mentioned earlier, I think we should get rid of the
> > OMAP_DISPLAY_TYPE_* enum, as it's kinda extra now. But doing that would
> > require changing all board files. That's not out of the question, but I
> > think we should first make sure we know what we are doing with the board
> > files so we don't go back and forth there.
> 
> Yes, I didn't remove it for the same reason.
> 
> >
> > Just gathering my thoughts:
> >
> > When we define a panel in DT/board file, we should also define the
> > output instance, because that's part of the hardware design. But there
> 
> It's a part of hardware design if the panel can't be detached. But yes, 
> even for detachable panels, we can assume that the panel would 
> eventually connect to that output.
> 
> > are no hardcoded links between mgrs and outputs, so that doesn't belong
> > to the DT/board file. For example, omap4460's DSI1 can take input from
> > LCD1 or LCD2.
> 
> Right, so we don't need an equivalent of the dssdev->channel field in DT 
> info. As you said, we need the output instance, is that why you were 

What I'm planning for DT is a direct link to the output instance.
Something like this (not correct, just to give the idea):

dss {
	dpi {
	};
};

i2c {
	/* an i2c controlled panel */
	my-panel {
		video-bus = <&dpi>;
	};
};

Then my-panel can get the handle from video-bus, and it'll get the
output device directly, without need for any IDs or such.

> sceptical about it being defined as an enum in previous patches? 
> Probably we could define output instances in DT as a pair of instance 
> number and instance type {number, type}. It would be sort of hard to 
> play around with those within OMAPDSS though.

Well, optimally we wouldn't need to know about display types or output
instances, at least in most of the cases. We'd just have a bunch of
managers, and a bunch of outputs, and rules how these can be connected.
And the panel devices would have a link to the output it's connect in HW
level.

There are probably some cases where we need some kind of ID, so that we
can handle the DSI PLL's and such. And we need to setup the rules above
somewhere, and perhaps that code needs IDs to set it up. I'm not sure.

And, well, if we don't have IDs, the rules above need to be some kind of
lists of pointers. Perhaps having a bit mask is just simpler, as we'll
never have too many output instances.

So I'm not really against having the enum. It just would've been neat to
have the output type and instance number encoded into this enum, so that
it'd be easy to extract either one. But that kinda ruins the possibility
to use it in a bit mask.

> > So who could/should make the decision which mgr to use... Well, I don't
> > know on what basis the decision can be made, but I still think omapdss
> > can't make good decisions on that, so probably the whole "chain" should
> > be configured in the omapfb/omapdrm level.
> 
> Which manager to chose could be simply picking up the next free manager 
> which can connect to that output. omapfb/drm can take care of that.

That's a good default implementation, but not quite perfect. If there
are two displays, often the other display (well, output) can only be
connected to one particular manager, whereas the other one could use two
managers. And if both try to use the same manager, especially if the one
with two options is selected first, the other one is left without a mgr.

 Tomi


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

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [PATCH v2 20/23] OMAPDSS: MANAGER: Update display sysfs store
@ 2012-08-31 14:53         ` Archit Taneja
  0 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-08-31 14:53 UTC (permalink / raw)
  To: Tomi Valkeinen; +Cc: rob, linux-omap, linux-fbdev

On Friday 31 August 2012 08:00 PM, Tomi Valkeinen wrote:
> On Thu, 2012-08-30 at 17:10 +0530, Archit Taneja wrote:
>> 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;
>>   		}
>>
>
> Hmm, I think this is a bit broken. If I read this right, the unlinking
> removes both mgr-output link and the output-dssdev link. But the linking
> part only sets up the mgr-output link.
>
> So if there's a very simple configuration with one display, if you
> unlink it via sysfs you can't link it back again.

Ah, right. You might need to reinsert the display module again to get 
the output-display link again. Which is bad. Or have a sysfs file for 
setting manager output. Which is something we want to stay away from anyway.

>
> The store function gets the mgr and the dssdev as arguments. I think
> this could be changed so that the function would "guess" the needed
> output. Well, not so much a guess, because a dssdev can only be
> connected to one output, defined by the HW design. That is basically
> what the recheck_connections does, we could use the same method here.
>
> Then this sysfs file should work just like before.

That's a good idea, we could reuse the code in recheck_connections a 
bit. I wanted to stay away from the guessing. But I think we need to do 
it if a simple unlink-link of a display itself fails.

Archit


^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [PATCH v2 09/23] OMAPDSS: Create links between managers, outputs and devices
  2012-08-31 14:45           ` Tomi Valkeinen
@ 2012-08-31 15:08             ` Tomi Valkeinen
  -1 siblings, 0 replies; 148+ messages in thread
From: Tomi Valkeinen @ 2012-08-31 15:08 UTC (permalink / raw)
  To: Archit Taneja; +Cc: rob, linux-omap, linux-fbdev

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

On Fri, 2012-08-31 at 17:45 +0300, Tomi Valkeinen wrote:

> So I'm not really against having the enum. It just would've been neat to
> have the output type and instance number encoded into this enum, so that
> it'd be easy to extract either one. But that kinda ruins the possibility
> to use it in a bit mask.

Hmm, this is just a non-finished idea (and it's late Friday... =) that
came to my mind:

I had a brief look at TRMs for different OMAPs (omap4/5/6), and it looks
like the maximum output options for one manager is 4 (LCD2 on omap4460).
Usually there are just 2 or 3.

So, we could trust that the above holds and do this so that we use a u32
field to hold four 8 bit output options. In 8 bits we can combine two
values from 0 to 15. 15 should be more than enough for output display
types and output instances.

Then with helpers like these:

/* second DSI instance */
#define DSI1 ((1 << 4) | DISPLAY_TYPE_DSI)
/* first DPI instance */
#define DPI0 ((0 << 4) | DISPLAY_TYPE_DPI)

an example output options for a manager that can be connected to DSI1
and DPI0 could be:

(DSI1 << 8) | (DPI0)

This could be parsed with a for loop, going though the 4 bytes of the
u32 value. This would allow us to avoid managing a real list, and we
could extract the instance and the type from the value. Of course we
could also extend the field to u64 to hold 8 outputs if need be.

Whether this would be worth it compared to simple bitmask, I'm not sure
=). Depends how much we need to extract the ID and type.

 Tomi


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

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [PATCH v2 09/23] OMAPDSS: Create links between managers, outputs and devices
@ 2012-08-31 15:08             ` Tomi Valkeinen
  0 siblings, 0 replies; 148+ messages in thread
From: Tomi Valkeinen @ 2012-08-31 15:08 UTC (permalink / raw)
  To: Archit Taneja; +Cc: rob, linux-omap, linux-fbdev

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

On Fri, 2012-08-31 at 17:45 +0300, Tomi Valkeinen wrote:

> So I'm not really against having the enum. It just would've been neat to
> have the output type and instance number encoded into this enum, so that
> it'd be easy to extract either one. But that kinda ruins the possibility
> to use it in a bit mask.

Hmm, this is just a non-finished idea (and it's late Friday... =) that
came to my mind:

I had a brief look at TRMs for different OMAPs (omap4/5/6), and it looks
like the maximum output options for one manager is 4 (LCD2 on omap4460).
Usually there are just 2 or 3.

So, we could trust that the above holds and do this so that we use a u32
field to hold four 8 bit output options. In 8 bits we can combine two
values from 0 to 15. 15 should be more than enough for output display
types and output instances.

Then with helpers like these:

/* second DSI instance */
#define DSI1 ((1 << 4) | DISPLAY_TYPE_DSI)
/* first DPI instance */
#define DPI0 ((0 << 4) | DISPLAY_TYPE_DPI)

an example output options for a manager that can be connected to DSI1
and DPI0 could be:

(DSI1 << 8) | (DPI0)

This could be parsed with a for loop, going though the 4 bytes of the
u32 value. This would allow us to avoid managing a real list, and we
could extract the instance and the type from the value. Of course we
could also extend the field to u64 to hold 8 outputs if need be.

Whether this would be worth it compared to simple bitmask, I'm not sure
=). Depends how much we need to extract the ID and type.

 Tomi


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

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [PATCH v2 09/23] OMAPDSS: Create links between managers, outputs and devices
  2012-08-31 15:08             ` Tomi Valkeinen
@ 2012-09-03  9:38               ` Archit Taneja
  -1 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-09-03  9:26 UTC (permalink / raw)
  To: Tomi Valkeinen; +Cc: rob, linux-omap, linux-fbdev

On Friday 31 August 2012 08:38 PM, Tomi Valkeinen wrote:
> On Fri, 2012-08-31 at 17:45 +0300, Tomi Valkeinen wrote:
>
>> So I'm not really against having the enum. It just would've been neat to
>> have the output type and instance number encoded into this enum, so that
>> it'd be easy to extract either one. But that kinda ruins the possibility
>> to use it in a bit mask.
>
> Hmm, this is just a non-finished idea (and it's late Friday... =) that
> came to my mind:
>
> I had a brief look at TRMs for different OMAPs (omap4/5/6), and it looks
> like the maximum output options for one manager is 4 (LCD2 on omap4460).
> Usually there are just 2 or 3.
>
> So, we could trust that the above holds and do this so that we use a u32
> field to hold four 8 bit output options. In 8 bits we can combine two
> values from 0 to 15. 15 should be more than enough for output display
> types and output instances.
>
> Then with helpers like these:
>
> /* second DSI instance */
> #define DSI1 ((1 << 4) | DISPLAY_TYPE_DSI)
> /* first DPI instance */
> #define DPI0 ((0 << 4) | DISPLAY_TYPE_DPI)

Okay, so DISPLAY_TYPE_DSI / DPI can't be a number left shifted any 
more(that would limit us to have only 4 types of output display types), 
like we have right now, they would need to be 0, 1, 2, 3 and so on. So 
with this approach, we could extract the instance number quickly, but we 
may not be able to check if the manager supports the output display type 
in constant time.

>
> an example output options for a manager that can be connected to DSI1
> and DPI0 could be:
>
> (DSI1 << 8) | (DPI0)
>
> This could be parsed with a for loop, going though the 4 bytes of the
> u32 value. This would allow us to avoid managing a real list, and we
> could extract the instance and the type from the value. Of course we
> could also extend the field to u64 to hold 8 outputs if need be.

Probably we could have a u64, and 2 bytes for each output, and a bit 
mask for both output instance and output display type. We could have 
display type enums as:

DISPLAY_TYPE_DPI	1 << 5
DISPLAY_TYPE_DSI	1 << 6
DISPLAY_TYPE_VENC	1 << 7
DISPLAY_TYPE_HDMI	1 << 8
DISPLAY_TYPE_SDI	1 << 9
DISPLAY_TYPE_RFBI	1 << 10
...

>
> Whether this would be worth it compared to simple bitmask, I'm not sure
> =). Depends how much we need to extract the ID and type.

Anyway, I don't think I'll try to implement this in this series. I'll 
stick to the output instance enums for now.

Archit


^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [PATCH v2 09/23] OMAPDSS: Create links between managers, outputs and devices
  2012-09-03  9:38               ` Archit Taneja
@ 2012-09-03  9:35                 ` Tomi Valkeinen
  -1 siblings, 0 replies; 148+ messages in thread
From: Tomi Valkeinen @ 2012-09-03  9:35 UTC (permalink / raw)
  To: Archit Taneja; +Cc: rob, linux-omap, linux-fbdev

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

On Mon, 2012-09-03 at 14:56 +0530, Archit Taneja wrote:
> On Friday 31 August 2012 08:38 PM, Tomi Valkeinen wrote:
> > On Fri, 2012-08-31 at 17:45 +0300, Tomi Valkeinen wrote:
> >
> >> So I'm not really against having the enum. It just would've been neat to
> >> have the output type and instance number encoded into this enum, so that
> >> it'd be easy to extract either one. But that kinda ruins the possibility
> >> to use it in a bit mask.
> >
> > Hmm, this is just a non-finished idea (and it's late Friday... =) that
> > came to my mind:
> >
> > I had a brief look at TRMs for different OMAPs (omap4/5/6), and it looks
> > like the maximum output options for one manager is 4 (LCD2 on omap4460).
> > Usually there are just 2 or 3.
> >
> > So, we could trust that the above holds and do this so that we use a u32
> > field to hold four 8 bit output options. In 8 bits we can combine two
> > values from 0 to 15. 15 should be more than enough for output display
> > types and output instances.
> >
> > Then with helpers like these:
> >
> > /* second DSI instance */
> > #define DSI1 ((1 << 4) | DISPLAY_TYPE_DSI)
> > /* first DPI instance */
> > #define DPI0 ((0 << 4) | DISPLAY_TYPE_DPI)
> 
> Okay, so DISPLAY_TYPE_DSI / DPI can't be a number left shifted any 
> more(that would limit us to have only 4 types of output display types), 
> like we have right now, they would need to be 0, 1, 2, 3 and so on. So 
> with this approach, we could extract the instance number quickly, but we 
> may not be able to check if the manager supports the output display type 
> in constant time.

True, it wouldn't be constant. But it'd be checking between one to four
bytes, so I think it's quite fast =).

> > an example output options for a manager that can be connected to DSI1
> > and DPI0 could be:
> >
> > (DSI1 << 8) | (DPI0)
> >
> > This could be parsed with a for loop, going though the 4 bytes of the
> > u32 value. This would allow us to avoid managing a real list, and we
> > could extract the instance and the type from the value. Of course we
> > could also extend the field to u64 to hold 8 outputs if need be.
> 
> Probably we could have a u64, and 2 bytes for each output, and a bit 
> mask for both output instance and output display type. We could have 
> display type enums as:
> 
> DISPLAY_TYPE_DPI	1 << 5
> DISPLAY_TYPE_DSI	1 << 6
> DISPLAY_TYPE_VENC	1 << 7
> DISPLAY_TYPE_HDMI	1 << 8
> DISPLAY_TYPE_SDI	1 << 9
> DISPLAY_TYPE_RFBI	1 << 10
> ...
> 
> >
> > Whether this would be worth it compared to simple bitmask, I'm not sure
> > =). Depends how much we need to extract the ID and type.
> 
> Anyway, I don't think I'll try to implement this in this series. I'll 
> stick to the output instance enums for now.

Sure. And as I said, I'm not sure if it's worth it. We currently have
multiple instances only for DSI, and only two instances there. And I
think we need to handle the instance number only in a few places. It's
not too much to do:

if (type == DSI1) ... else if (type == DSI2) ...

 Tomi


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

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [PATCH v2 09/23] OMAPDSS: Create links between managers, outputs and devices
@ 2012-09-03  9:35                 ` Tomi Valkeinen
  0 siblings, 0 replies; 148+ messages in thread
From: Tomi Valkeinen @ 2012-09-03  9:35 UTC (permalink / raw)
  To: Archit Taneja; +Cc: rob, linux-omap, linux-fbdev

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

On Mon, 2012-09-03 at 14:56 +0530, Archit Taneja wrote:
> On Friday 31 August 2012 08:38 PM, Tomi Valkeinen wrote:
> > On Fri, 2012-08-31 at 17:45 +0300, Tomi Valkeinen wrote:
> >
> >> So I'm not really against having the enum. It just would've been neat to
> >> have the output type and instance number encoded into this enum, so that
> >> it'd be easy to extract either one. But that kinda ruins the possibility
> >> to use it in a bit mask.
> >
> > Hmm, this is just a non-finished idea (and it's late Friday... =) that
> > came to my mind:
> >
> > I had a brief look at TRMs for different OMAPs (omap4/5/6), and it looks
> > like the maximum output options for one manager is 4 (LCD2 on omap4460).
> > Usually there are just 2 or 3.
> >
> > So, we could trust that the above holds and do this so that we use a u32
> > field to hold four 8 bit output options. In 8 bits we can combine two
> > values from 0 to 15. 15 should be more than enough for output display
> > types and output instances.
> >
> > Then with helpers like these:
> >
> > /* second DSI instance */
> > #define DSI1 ((1 << 4) | DISPLAY_TYPE_DSI)
> > /* first DPI instance */
> > #define DPI0 ((0 << 4) | DISPLAY_TYPE_DPI)
> 
> Okay, so DISPLAY_TYPE_DSI / DPI can't be a number left shifted any 
> more(that would limit us to have only 4 types of output display types), 
> like we have right now, they would need to be 0, 1, 2, 3 and so on. So 
> with this approach, we could extract the instance number quickly, but we 
> may not be able to check if the manager supports the output display type 
> in constant time.

True, it wouldn't be constant. But it'd be checking between one to four
bytes, so I think it's quite fast =).

> > an example output options for a manager that can be connected to DSI1
> > and DPI0 could be:
> >
> > (DSI1 << 8) | (DPI0)
> >
> > This could be parsed with a for loop, going though the 4 bytes of the
> > u32 value. This would allow us to avoid managing a real list, and we
> > could extract the instance and the type from the value. Of course we
> > could also extend the field to u64 to hold 8 outputs if need be.
> 
> Probably we could have a u64, and 2 bytes for each output, and a bit 
> mask for both output instance and output display type. We could have 
> display type enums as:
> 
> DISPLAY_TYPE_DPI	1 << 5
> DISPLAY_TYPE_DSI	1 << 6
> DISPLAY_TYPE_VENC	1 << 7
> DISPLAY_TYPE_HDMI	1 << 8
> DISPLAY_TYPE_SDI	1 << 9
> DISPLAY_TYPE_RFBI	1 << 10
> ...
> 
> >
> > Whether this would be worth it compared to simple bitmask, I'm not sure
> > =). Depends how much we need to extract the ID and type.
> 
> Anyway, I don't think I'll try to implement this in this series. I'll 
> stick to the output instance enums for now.

Sure. And as I said, I'm not sure if it's worth it. We currently have
multiple instances only for DSI, and only two instances there. And I
think we need to handle the instance number only in a few places. It's
not too much to do:

if (type == DSI1) ... else if (type == DSI2) ...

 Tomi


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

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [PATCH v2 09/23] OMAPDSS: Create links between managers, outputs and devices
@ 2012-09-03  9:38               ` Archit Taneja
  0 siblings, 0 replies; 148+ messages in thread
From: Archit Taneja @ 2012-09-03  9:38 UTC (permalink / raw)
  To: Tomi Valkeinen; +Cc: rob, linux-omap, linux-fbdev

On Friday 31 August 2012 08:38 PM, Tomi Valkeinen wrote:
> On Fri, 2012-08-31 at 17:45 +0300, Tomi Valkeinen wrote:
>
>> So I'm not really against having the enum. It just would've been neat to
>> have the output type and instance number encoded into this enum, so that
>> it'd be easy to extract either one. But that kinda ruins the possibility
>> to use it in a bit mask.
>
> Hmm, this is just a non-finished idea (and it's late Friday... =) that
> came to my mind:
>
> I had a brief look at TRMs for different OMAPs (omap4/5/6), and it looks
> like the maximum output options for one manager is 4 (LCD2 on omap4460).
> Usually there are just 2 or 3.
>
> So, we could trust that the above holds and do this so that we use a u32
> field to hold four 8 bit output options. In 8 bits we can combine two
> values from 0 to 15. 15 should be more than enough for output display
> types and output instances.
>
> Then with helpers like these:
>
> /* second DSI instance */
> #define DSI1 ((1 << 4) | DISPLAY_TYPE_DSI)
> /* first DPI instance */
> #define DPI0 ((0 << 4) | DISPLAY_TYPE_DPI)

Okay, so DISPLAY_TYPE_DSI / DPI can't be a number left shifted any 
more(that would limit us to have only 4 types of output display types), 
like we have right now, they would need to be 0, 1, 2, 3 and so on. So 
with this approach, we could extract the instance number quickly, but we 
may not be able to check if the manager supports the output display type 
in constant time.

>
> an example output options for a manager that can be connected to DSI1
> and DPI0 could be:
>
> (DSI1 << 8) | (DPI0)
>
> This could be parsed with a for loop, going though the 4 bytes of the
> u32 value. This would allow us to avoid managing a real list, and we
> could extract the instance and the type from the value. Of course we
> could also extend the field to u64 to hold 8 outputs if need be.

Probably we could have a u64, and 2 bytes for each output, and a bit 
mask for both output instance and output display type. We could have 
display type enums as:

DISPLAY_TYPE_DPI	1 << 5
DISPLAY_TYPE_DSI	1 << 6
DISPLAY_TYPE_VENC	1 << 7
DISPLAY_TYPE_HDMI	1 << 8
DISPLAY_TYPE_SDI	1 << 9
DISPLAY_TYPE_RFBI	1 << 10
...

>
> Whether this would be worth it compared to simple bitmask, I'm not sure
> =). Depends how much we need to extract the ID and type.

Anyway, I don't think I'll try to implement this in this series. I'll 
stick to the output instance enums for now.

Archit


^ permalink raw reply	[flat|nested] 148+ messages in thread

end of thread, other threads:[~2012-09-03  9:38 UTC | newest]

Thread overview: 148+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-08-21  5:58 [PATCH 00/23] OMAPDSS: Create output entities Archit Taneja
2012-08-21  6:10 ` Archit Taneja
2012-08-21  5:58 ` [PATCH 01/23] OMAPDSS: outputs: Create a new entity called outputs Archit Taneja
2012-08-21  6:10   ` Archit Taneja
2012-08-24 12:41   ` Tomi Valkeinen
2012-08-24 12:41     ` Tomi Valkeinen
2012-08-24 12:51     ` Archit Taneja
2012-08-24 12:53       ` Archit Taneja
2012-08-29 10:32       ` Tomi Valkeinen
2012-08-29 10:32         ` Tomi Valkeinen
2012-08-29 10:57         ` Archit Taneja
2012-08-29 10:58           ` Archit Taneja
2012-08-21  5:58 ` [PATCH 02/23] OMAPDSS: outputs: Create and initialize output instances Archit Taneja
2012-08-21  6:10   ` Archit Taneja
2012-08-24 13:14   ` Tomi Valkeinen
2012-08-24 13:14     ` Tomi Valkeinen
2012-08-27  6:19     ` Archit Taneja
2012-08-27  6:31       ` Archit Taneja
2012-08-27  6:44       ` Tomi Valkeinen
2012-08-27  6:44         ` Tomi Valkeinen
2012-08-21  5:58 ` [PATCH 03/23] OMAPDSS: output: Add set/unset device ops for omap_dss_output Archit Taneja
2012-08-21  6:10   ` Archit Taneja
2012-08-21  5:58 ` [PATCH 04/23] OMAPDSS: APPLY: Add manager set/unset output ops for omap_overlay_manager Archit Taneja
2012-08-21  6:10   ` Archit Taneja
2012-08-21  5:58 ` [PATCH 05/23] OMAPDSS: Remove manager->device references Archit Taneja
2012-08-21  6:10   ` Archit Taneja
2012-08-21  5:58 ` [PATCH 06/23] OMAP_VOUT: " Archit Taneja
2012-08-21  6:10   ` Archit Taneja
2012-08-21  5:58 ` [PATCH 07/23] OMAPFB: remove " Archit Taneja
2012-08-21  6:10   ` Archit Taneja
2012-08-21  5:58 ` [PATCH 08/23] OMAPDRM: Remove " Archit Taneja
2012-08-21  6:10   ` Archit Taneja
2012-08-21  5:58 ` [PATCH 09/23] OMAPDSS: Create links between managers, outputs and devices Archit Taneja
2012-08-21  6:10   ` Archit Taneja
2012-08-21  5:58 ` [PATCH 10/23] OMAPDSS: DPI: Pass outputs from panel driver to DPI interface driver Archit Taneja
2012-08-21  6:10   ` Archit Taneja
2012-08-21  5:58 ` [PATCH 11/23] OMAPDSS: DSI: Remove dsi_pdev_map global struct Archit Taneja
2012-08-21  6:10   ` Archit Taneja
2012-08-21  5:58 ` [PATCH 12/23] OMAPDSS: DSI: Pass outputs from panel driver to DSI interface driver Archit Taneja
2012-08-21  6:10   ` Archit Taneja
2012-08-21  5:58 ` [PATCH 13/23] OMAPDSS: SDI: Pass outputs from panel driver to SDI " Archit Taneja
2012-08-21  6:10   ` Archit Taneja
2012-08-21  5:58 ` [PATCH 14/23] OMAPDSS: RFBI: Pass outputs from panel driver to RFBI " Archit Taneja
2012-08-21  6:10   ` Archit Taneja
2012-08-21  5:58 ` [PATCH 15/23] OMAPDSS: RFBI: Add output pointers as arguments to all exported functions Archit Taneja
2012-08-21  6:10   ` Archit Taneja
2012-08-21  5:58 ` [PATCH 16/23] OMAPDSS: VENC: Pass outputs from panel driver to VENC interface driver Archit Taneja
2012-08-21  6:10   ` Archit Taneja
2012-08-21  5:58 ` [PATCH 17/23] OMAPDSS: HDMI: Pass outputs from panel driver to HDMI " Archit Taneja
2012-08-21  6:10   ` Archit Taneja
2012-08-21  5:58 ` [PATCH 18/23] OMAPDSS: HDMI: Add output pointers as arguments to all functions used by hdmi panel driver Archit Taneja
2012-08-21  6:10   ` [PATCH 18/23] OMAPDSS: HDMI: Add output pointers as arguments to all functions used by hdmi panel dr Archit Taneja
2012-08-21  5:58 ` [PATCH 19/23] OMAPDSS/OMAPFB: Change dssdev->manager references Archit Taneja
2012-08-21  6:10   ` Archit Taneja
2012-08-21  5:58 ` [PATCH 20/23] OMAPDSS: MANAGER: Update display sysfs store Archit Taneja
2012-08-21  6:10   ` Archit Taneja
2012-08-21  5:58 ` [PATCH 21/23] OMAPDSS: MANAGER: Get device via output Archit Taneja
2012-08-21  6:10   ` Archit Taneja
2012-08-21  5:58 ` [PATCH 22/23] OMAPDSS: APPLY: Remove omap_dss_device references from dss_ovl_enable/disable Archit Taneja
2012-08-21  6:10   ` Archit Taneja
2012-08-21  5:58 ` [PATCH 23/23] OMAPDSS: Remove old way of setting manager and device links Archit Taneja
2012-08-21  6:10   ` Archit Taneja
2012-08-30 11:40 ` [PATCH v2 00/23] OMAPDSS: Create output entities Archit Taneja
2012-08-30 11:52   ` Archit Taneja
2012-08-30 11:40   ` [PATCH v2 01/23] OMAPDSS: outputs: Create a new entity called outputs Archit Taneja
2012-08-30 11:52     ` Archit Taneja
2012-08-30 11:40   ` [PATCH v2 02/23] OMAPDSS: outputs: Create and register output instances Archit Taneja
2012-08-30 11:52     ` Archit Taneja
2012-08-31 11:57     ` Tomi Valkeinen
2012-08-31 11:57       ` Tomi Valkeinen
2012-08-31 12:03       ` Archit Taneja
2012-08-31 12:15         ` Archit Taneja
2012-08-30 11:40   ` [PATCH v2 03/23] OMAPDSS: output: Add set/unset device ops for omap_dss_output Archit Taneja
2012-08-30 11:52     ` Archit Taneja
2012-08-31 12:03     ` Tomi Valkeinen
2012-08-31 12:03       ` Tomi Valkeinen
2012-08-31 12:24       ` Archit Taneja
2012-08-31 12:36         ` Archit Taneja
2012-08-31 12:28         ` Tomi Valkeinen
2012-08-31 12:28           ` Tomi Valkeinen
2012-08-30 11:40   ` [PATCH v2 04/23] OMAPDSS: APPLY: Add manager set/unset output ops for omap_overlay_manager Archit Taneja
2012-08-30 11:52     ` Archit Taneja
2012-08-30 11:40   ` [PATCH v2 05/23] OMAPDSS: Remove manager->device references Archit Taneja
2012-08-30 11:52     ` Archit Taneja
2012-08-30 11:40   ` [PATCH v2 06/23] OMAP_VOUT: " Archit Taneja
2012-08-30 11:52     ` Archit Taneja
2012-08-31 12:11     ` Tomi Valkeinen
2012-08-31 12:11       ` Tomi Valkeinen
2012-08-31 12:34       ` Archit Taneja
2012-08-31 12:46         ` Archit Taneja
2012-08-30 11:40   ` [PATCH v2 07/23] OMAPFB: remove " Archit Taneja
2012-08-30 11:52     ` Archit Taneja
2012-08-30 11:40   ` [PATCH v2 08/23] OMAPDRM: Remove " Archit Taneja
2012-08-30 11:52     ` Archit Taneja
2012-08-30 11:40   ` [PATCH v2 09/23] OMAPDSS: Create links between managers, outputs and devices Archit Taneja
2012-08-30 11:52     ` Archit Taneja
2012-08-31 14:10     ` Tomi Valkeinen
2012-08-31 14:10       ` Tomi Valkeinen
2012-08-31 14:24       ` Archit Taneja
2012-08-31 14:36         ` Archit Taneja
2012-08-31 14:45         ` Tomi Valkeinen
2012-08-31 14:45           ` Tomi Valkeinen
2012-08-31 15:08           ` Tomi Valkeinen
2012-08-31 15:08             ` Tomi Valkeinen
2012-09-03  9:26             ` Archit Taneja
2012-09-03  9:38               ` Archit Taneja
2012-09-03  9:35               ` Tomi Valkeinen
2012-09-03  9:35                 ` Tomi Valkeinen
2012-08-30 11:40   ` [PATCH v2 10/23] OMAPDSS: DPI: Pass omap_dss_output within the driver Archit Taneja
2012-08-30 11:52     ` Archit Taneja
2012-08-31 13:48     ` Tomi Valkeinen
2012-08-31 13:48       ` Tomi Valkeinen
2012-08-31 13:59       ` Archit Taneja
2012-08-31 14:00         ` Archit Taneja
2012-08-30 11:40   ` [PATCH v2 11/23] OMAPDSS: DSI: Remove dsi_pdev_map global struct Archit Taneja
2012-08-30 11:52     ` Archit Taneja
2012-08-30 11:40   ` [PATCH v2 12/23] OMAPDSS: DSI: Pass omap_dss_output within the driver Archit Taneja
2012-08-30 11:52     ` Archit Taneja
2012-08-30 11:40   ` [PATCH v2 13/23] OMAPDSS: SDI: " Archit Taneja
2012-08-30 11:52     ` Archit Taneja
2012-08-30 11:40   ` [PATCH v2 14/23] OMAPDSS: RFBI: " Archit Taneja
2012-08-30 11:52     ` Archit Taneja
2012-08-30 11:40   ` [PATCH v2 15/23] OMAPDSS: RFBI: Add dssdev pointers as arguments to all exported functions Archit Taneja
2012-08-30 11:52     ` Archit Taneja
2012-08-31 14:20     ` Tomi Valkeinen
2012-08-31 14:20       ` Tomi Valkeinen
2012-08-31 14:30       ` Archit Taneja
2012-08-31 14:42         ` Archit Taneja
2012-08-30 11:40   ` [PATCH v2 16/23] OMAPDSS: VENC: Pass omap_dss_output within the driver Archit Taneja
2012-08-30 11:52     ` Archit Taneja
2012-08-30 11:40   ` [PATCH v2 17/23] OMAPDSS: HDMI: " Archit Taneja
2012-08-30 11:52     ` Archit Taneja
2012-08-30 11:40   ` [PATCH v2 18/23] OMAPDSS: HDMI: Add dssdev pointer as an argument to all functions used by hdmi panel driver Archit Taneja
2012-08-30 11:52     ` [PATCH v2 18/23] OMAPDSS: HDMI: Add dssdev pointer as an argument to all functions used by hdmi pane Archit Taneja
2012-08-30 11:40   ` [PATCH v2 19/23] OMAPDSS/OMAPFB: Change dssdev->manager references Archit Taneja
2012-08-30 11:52     ` Archit Taneja
2012-08-30 11:40   ` [PATCH v2 20/23] OMAPDSS: MANAGER: Update display sysfs store Archit Taneja
2012-08-30 11:52     ` Archit Taneja
2012-08-31 14:30     ` Tomi Valkeinen
2012-08-31 14:30       ` Tomi Valkeinen
2012-08-31 14:41       ` Archit Taneja
2012-08-31 14:53         ` Archit Taneja
2012-08-30 11:40   ` [PATCH v2 21/23] OMAPDSS: MANAGER: Get device via output Archit Taneja
2012-08-30 11:52     ` Archit Taneja
2012-08-30 11:40   ` [PATCH v2 22/23] OMAPDSS: APPLY: Remove omap_dss_device references from dss_ovl_enable/disable Archit Taneja
2012-08-30 11:52     ` Archit Taneja
2012-08-30 11:40   ` [PATCH v2 23/23] OMAPDSS: Remove old way of setting manager and device links Archit Taneja
2012-08-30 11:52     ` Archit Taneja

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.