All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC 00/17] OMAPDSS: Change way of passing timings from panel driver to interface
@ 2012-08-01 10:43 ` Archit Taneja
  0 siblings, 0 replies; 122+ messages in thread
From: Archit Taneja @ 2012-08-01 10:31 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-fbdev, linux-omap, sumit.semwal, rob, Archit Taneja

This series tries to make interface drivers less dependent on omap_dss_device
which represents a panel/device connected to that interface. The current way of
configuring an interface is to populate the panel's omap_dss_device instance
with parameters common to the panel and the interface, they are either populated
in the board file, or in the panel driver. Panel timings, number of lanes
connected to interface, and pixel format are examples of such parameters, these
are then extracted by the interface driver to configure itself.

This approach has some disadvantages:

- The omap_dss_device contains fields which could be handled independently by
  the panel driver. For example, we have an enum field in omap_dss_device to
  tell what mode the panel operates in. This information could be handled by the
  panel driver itself. But it's a part of omap_dss_device since we need to pass
  this down to the interface driver.

- An interface can't exist by itself. That is, it needs a panel to be connected
  to it to configure itself. It's not practical to configure an interface
  without a panel, but it's theoretically possible, and we may need it if we
  expose the interface as an entity to a user of OMAPDSS. It's also useful if we
  represent writeback as an interface, writeback isn't connected to a panel.

- There is a lack of clarity in how the interface configures itself. Since the
  interface driver extracts info from omap_dss_device, it's unclear from a panel
  driver point of view about what information in omap_dss_device the interface
  is using and what it's not using.

- There are issues with checking the correctness of the parameters in
  omap_dss_device. We currently fill up the omap_dss_device completely, and then
  try to enable the interface, this results in catching a wrong parameter at a
  much later point, rather than catching it immediately.

The alternative approach is for the interface drivers to expose functions/api to
the panel drivers to configure such parameters. This way, the panel driver can
pass the parameters to the interface itself, rather than filling up
omap_dss_device. This would need the panel driver to keep a copy of the
parameters so that it can use to configure it later. This resolves all the
issues mentioned above, and also gives us a chance to make a generic set of
function ops for interfaces, this can make a panel driver independent of
the underlying platform.

The current series starts of this work by creating a set_timings function for
all interfaces passing omap_video_timings, this prevents dssdev->panel.timings
references. The first few patches are some minor cleanups which are useful for
the patches which come later.

There are some points on which I need suggestions/clarifications:
- How do we make sure that these functions are called by the panel driver at the
  right time? For example, when setting timings for DSI video mode, we would
  need to call omapdss_dsi_set_timings() before we call
  omapdss_dsi_display_enable(), otherwise the copy of timings contained in DSI
  driver data would be invalid. Also, what should the behaviour of such a
  set_timings operation if the interface is already enabled. It is clear for
  DPI and HDMI, but I'm not clear about what to do about other interfaces. Do we
  add checks for the state of the interface/panel?

- A specific issue about DSI/RFBI getting the resolution via
  device->driver->get_resolution(), does this provide a result based on panel
  rotation? Can this somehow be replaced by timings?

- For SDI, the set_timings operation is simplified, instead of disabling and
  then enabling the panel with a new set of timings, only the new timings are
  configured. This is similar to what is done in DPI. I am not clear if this
  will work for SDI or not.

- There is no set_timings() function for RFBI yet, this needs to be though of
  and fixed. 

The reference tree and branch:

This is based on Tomi's for-florian-merged branch, and has 2 of his patches which
got missed the last merge window.

This hasn't been tested thoroughly with all interfaces yet. I was interested in
getting some comments.

Archit Taneja (17):
  OMAPDSS: APPLY: Constify timings argument in dss_mgr_set_timings
  OMAPDSS: DPI: Remove omap_dss_device arguments in
    dpi_set_dsi_clk/dpi_set_dispc_clk
  OMAPDSS: HDMI: Remove omap_dss_device argument from hdmi_compute_pll
  OMAPDSS: DPI: Add locking for DPI interface
  OMAPDSS: DPI: Maintain our own timings field in driver data
  OMAPDSS: DPI displays: Take care of panel timings in the driver
    itself
  OMAPDSS: Displays: Add locking in generic DPI panel driver
  OMAPDSS: DSI: Maintain own copy of timings in driver data
  OMAPDSS: HDMI: Use our own omap_video_timings field when setting
    interface timings
  OMAPDSS: HDMI: Add a get_timing function for HDMI interface
  OMAPDSS: HDMI: Add locking for hdmi interface get/set timing
    functions
  OMAPDSS: SDI: Create a separate function for timing/clock
    configurations
  OMAPDSS: SDI: Create a function to set timings
  OMAPDSS: SDI: Maintain our own timings field in driver data
  OMAPDSS: VENC: Split VENC into interface and panel driver
  OMAPDSS: VENC: Maintain our own timings field in driver data
  OMAPDSS: VENC: Add a get_timing function for VENC interface

 drivers/video/omap2/displays/panel-acx565akm.c     |   13 +-
 drivers/video/omap2/displays/panel-generic-dpi.c   |   75 ++++++-
 .../omap2/displays/panel-lgphilips-lb035q02.c      |    2 +
 .../omap2/displays/panel-nec-nl8048hl11-01b.c      |    2 +
 drivers/video/omap2/displays/panel-picodlp.c       |    3 +
 .../video/omap2/displays/panel-sharp-ls037v7dw01.c |    2 +
 drivers/video/omap2/displays/panel-taal.c          |    2 +
 drivers/video/omap2/displays/panel-tfp410.c        |    5 +-
 .../video/omap2/displays/panel-tpo-td043mtea1.c    |    6 +-
 drivers/video/omap2/dss/Makefile                   |    2 +-
 drivers/video/omap2/dss/apply.c                    |    4 +-
 drivers/video/omap2/dss/dpi.c                      |   52 +++--
 drivers/video/omap2/dss/dsi.c                      |   27 ++-
 drivers/video/omap2/dss/dss.h                      |   19 +-
 drivers/video/omap2/dss/hdmi.c                     |   60 +++--
 drivers/video/omap2/dss/hdmi_panel.c               |   12 +-
 drivers/video/omap2/dss/sdi.c                      |   87 +++++---
 drivers/video/omap2/dss/venc.c                     |  233 ++++++--------------
 drivers/video/omap2/dss/venc_panel.c               |  231 +++++++++++++++++++
 include/video/omapdss.h                            |    8 +-
 20 files changed, 579 insertions(+), 266 deletions(-)
 create mode 100644 drivers/video/omap2/dss/venc_panel.c

-- 
1.7.9.5


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

* [RFC 01/17] OMAPDSS: APPLY: Constify timings argument in dss_mgr_set_timings
  2012-08-01 10:43 ` Archit Taneja
@ 2012-08-01 10:43   ` Archit Taneja
  -1 siblings, 0 replies; 122+ messages in thread
From: Archit Taneja @ 2012-08-01 10:31 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-fbdev, linux-omap, sumit.semwal, rob, Archit Taneja

The function dss_mgr_set_timings is supposed to apply timings passed by an
interface driver. It is not supposed to change the timings. Add const qualifier
to the omap_video_timings pointer argument in dss_mgr_set_timings().

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

diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c
index 0fefc68..52a5940 100644
--- a/drivers/video/omap2/dss/apply.c
+++ b/drivers/video/omap2/dss/apply.c
@@ -1302,7 +1302,7 @@ err:
 }
 
 static void dss_apply_mgr_timings(struct omap_overlay_manager *mgr,
-		struct omap_video_timings *timings)
+		const struct omap_video_timings *timings)
 {
 	struct mgr_priv_data *mp = get_mgr_priv(mgr);
 
@@ -1311,7 +1311,7 @@ static void dss_apply_mgr_timings(struct omap_overlay_manager *mgr,
 }
 
 void dss_mgr_set_timings(struct omap_overlay_manager *mgr,
-		struct omap_video_timings *timings)
+		const struct omap_video_timings *timings)
 {
 	unsigned long flags;
 
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index 335ee93..8a9630b 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -207,7 +207,7 @@ 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);
 void dss_mgr_set_timings(struct omap_overlay_manager *mgr,
-		struct omap_video_timings *timings);
+		const struct omap_video_timings *timings);
 void dss_mgr_set_lcd_config(struct omap_overlay_manager *mgr,
 		const struct dss_lcd_mgr_config *config);
 const struct omap_video_timings *dss_mgr_get_timings(struct omap_overlay_manager *mgr);
-- 
1.7.9.5


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

* [RFC 02/17] OMAPDSS: DPI: Remove omap_dss_device arguments in dpi_set_dsi_clk/dpi_set_dispc_clk
  2012-08-01 10:43 ` Archit Taneja
@ 2012-08-01 10:43   ` Archit Taneja
  -1 siblings, 0 replies; 122+ messages in thread
From: Archit Taneja @ 2012-08-01 10:31 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-fbdev, linux-omap, sumit.semwal, rob, Archit Taneja

The clock related info for DSS modules is not tied anymore to a panel's
omap_dss_device struct. It's now passed via platform data. The functions
dpi_set_dsi_clk() and dpi_set_dispc_clk() do not need the omap_dss_device
argument to retieve these clocks. They use the api dss_get_platform_clock_config
to get the clocks. Remove the omap_dss_device arguments from these functions.

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

diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c
index 5fec180..c20fe23 100644
--- a/drivers/video/omap2/dss/dpi.c
+++ b/drivers/video/omap2/dss/dpi.c
@@ -80,9 +80,8 @@ static bool dpi_use_dsi_pll(struct omap_dss_device *dssdev)
 		lcd_src == OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC;
 }
 
-static int dpi_set_dsi_clk(struct omap_dss_device *dssdev,
-		unsigned long pck_req, unsigned long *fck, int *lck_div,
-		int *pck_div)
+static int dpi_set_dsi_clk(unsigned long pck_req, unsigned long *fck,
+		int *lck_div, int *pck_div)
 {
 	const struct omapdss_clock_config *clks;
 	struct dsi_clock_info dsi_cinfo;
@@ -111,9 +110,8 @@ static int dpi_set_dsi_clk(struct omap_dss_device *dssdev,
 	return 0;
 }
 
-static int dpi_set_dispc_clk(struct omap_dss_device *dssdev,
-		unsigned long pck_req, unsigned long *fck, int *lck_div,
-		int *pck_div)
+static int dpi_set_dispc_clk(unsigned long pck_req, unsigned long *fck,
+		int *lck_div, int *pck_div)
 {
 	struct dss_clock_info dss_cinfo;
 	struct dispc_clock_info dispc_cinfo;
@@ -145,10 +143,10 @@ static int dpi_set_mode(struct omap_dss_device *dssdev)
 	int r = 0;
 
 	if (dpi_use_dsi_pll(dssdev))
-		r = dpi_set_dsi_clk(dssdev, t->pixel_clock * 1000, &fck,
+		r = dpi_set_dsi_clk(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(t->pixel_clock * 1000, &fck,
 				&lck_div, &pck_div);
 	if (r)
 		return r;
-- 
1.7.9.5


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

* [RFC 03/17] OMAPDSS: HDMI: Remove omap_dss_device argument from hdmi_compute_pll
  2012-08-01 10:43 ` Archit Taneja
@ 2012-08-01 10:43   ` Archit Taneja
  -1 siblings, 0 replies; 122+ messages in thread
From: Archit Taneja @ 2012-08-01 10:31 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-fbdev, linux-omap, sumit.semwal, rob, Archit Taneja

The clock related info for DSS modules is not tied anymore to a panel's
omap_dss_device struct. It's now passed via platform data. The function
hdmi_compute_pll() do not need the omap_dss_device argument to retieve these
clocks. They use the api dss_get_platform_clock_config() get the clocks. Remove
the omap_dss_device argument from hdmi_compute_pll()

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

diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c
index 16b2386..6635b09 100644
--- a/drivers/video/omap2/dss/hdmi.c
+++ b/drivers/video/omap2/dss/hdmi.c
@@ -405,8 +405,7 @@ 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,
-		struct hdmi_pll_info *pi)
+static void hdmi_compute_pll(int phy, struct hdmi_pll_info *pi)
 {
 	const struct omapdss_clock_config *clks;
 	unsigned long clkin, refclk;
@@ -491,7 +490,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(phy, &hdmi.ip_data.pll_data);
 
 	hdmi.ip_data.ops->video_disable(&hdmi.ip_data);
 
-- 
1.7.9.5


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

* [RFC 04/17] OMAPDSS: DPI: Add locking for DPI interface
  2012-08-01 10:43 ` Archit Taneja
@ 2012-08-01 10:43   ` Archit Taneja
  -1 siblings, 0 replies; 122+ messages in thread
From: Archit Taneja @ 2012-08-01 10:31 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-fbdev, linux-omap, sumit.semwal, rob, Archit Taneja

The DPI interface driver currently relies on the panel driver to ensure calls
like omapdss_dpi_display_enable() and omapdss_dpi_display_disable() are executed
sequentially. Also, currently, there is no way to protect the DPI driver data.

All DPI panel drivers don't ensure this, and in general, a DPI panel driver
should use it's lock to that ensure it's own driver data and omap_dss_device
states are taken care of, and not worry about the DPI interface.

Add mutex locking in the DPI enable/disable/set_timings ops.

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

diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c
index c20fe23..add47fe 100644
--- a/drivers/video/omap2/dss/dpi.c
+++ b/drivers/video/omap2/dss/dpi.c
@@ -39,6 +39,8 @@ static struct {
 	struct regulator *vdds_dsi_reg;
 	struct platform_device *dsidev;
 
+	struct mutex lock;
+
 	struct dss_lcd_mgr_config mgr_config;
 } dpi;
 
@@ -184,14 +186,18 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
 {
 	int r;
 
+	mutex_lock(&dpi.lock);
+
 	if (cpu_is_omap34xx() && !dpi.vdds_dsi_reg) {
 		DSSERR("no VDSS_DSI regulator\n");
-		return -ENODEV;
+		r = -ENODEV;
+		goto err_no_reg;
 	}
 
 	if (dssdev->manager == NULL) {
 		DSSERR("failed to enable display: no manager\n");
-		return -ENODEV;
+		r = -ENODEV;
+		goto err_no_mgr;
 	}
 
 	if (dpi_use_dsi_pll(dssdev)) {
@@ -238,6 +244,8 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
 	if (r)
 		goto err_mgr_enable;
 
+	mutex_unlock(&dpi.lock);
+
 	return 0;
 
 err_mgr_enable:
@@ -255,12 +263,17 @@ err_get_dispc:
 err_reg_enable:
 	omap_dss_stop_device(dssdev);
 err_start_dev:
+err_no_mgr:
+err_no_reg:
+	mutex_unlock(&dpi.lock);
 	return r;
 }
 EXPORT_SYMBOL(omapdss_dpi_display_enable);
 
 void omapdss_dpi_display_disable(struct omap_dss_device *dssdev)
 {
+	mutex_lock(&dpi.lock);
+
 	dss_mgr_disable(dssdev->manager);
 
 	if (dpi_use_dsi_pll(dssdev)) {
@@ -275,6 +288,8 @@ void omapdss_dpi_display_disable(struct omap_dss_device *dssdev)
 		regulator_disable(dpi.vdds_dsi_reg);
 
 	omap_dss_stop_device(dssdev);
+
+	mutex_unlock(&dpi.lock);
 }
 EXPORT_SYMBOL(omapdss_dpi_display_disable);
 
@@ -284,6 +299,9 @@ void dpi_set_timings(struct omap_dss_device *dssdev,
 	int r;
 
 	DSSDBG("dpi_set_timings\n");
+
+	mutex_lock(&dpi.lock);
+
 	dssdev->panel.timings = *timings;
 	if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) {
 		r = dispc_runtime_get();
@@ -296,6 +314,8 @@ void dpi_set_timings(struct omap_dss_device *dssdev,
 	} else {
 		dss_mgr_set_timings(dssdev->manager, timings);
 	}
+
+	mutex_unlock(&dpi.lock);
 }
 EXPORT_SYMBOL(dpi_set_timings);
 
@@ -392,6 +412,8 @@ static void __init dpi_probe_pdata(struct platform_device *pdev)
 
 static int __init omap_dpi_probe(struct platform_device *pdev)
 {
+	mutex_init(&dpi.lock);
+
 	dpi_probe_pdata(pdev);
 
 	return 0;
-- 
1.7.9.5


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

* [RFC 05/17] OMAPDSS: DPI: Maintain our own timings field in driver data
  2012-08-01 10:43 ` Archit Taneja
@ 2012-08-01 10:43   ` Archit Taneja
  -1 siblings, 0 replies; 122+ messages in thread
From: Archit Taneja @ 2012-08-01 10:31 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-fbdev, linux-omap, sumit.semwal, rob, Archit Taneja

The DPI driver currently relies on the timings in omap_dss_device struct to
configure the DISPC accordingly. This makes the DPI interface driver dependent
on the omap_dss_device struct.

Make the DPI driver data maintain it's own timings field. The panel driver is
expected to call dpi_set_timings()(renamed to omapdss_dpi_set_timings) to set
these timings before the panel is enabled.

In the set_timings() op, we still ensure that the omap_dss_device timings
(dssdev->panel.timings) are configured. This will later be configured only by
the DPI panel drivers.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/displays/panel-generic-dpi.c   |    4 +++-
 .../omap2/displays/panel-lgphilips-lb035q02.c      |    2 ++
 .../omap2/displays/panel-nec-nl8048hl11-01b.c      |    2 ++
 drivers/video/omap2/displays/panel-picodlp.c       |    3 +++
 .../video/omap2/displays/panel-sharp-ls037v7dw01.c |    2 ++
 drivers/video/omap2/displays/panel-tfp410.c        |    4 +++-
 .../video/omap2/displays/panel-tpo-td043mtea1.c    |    4 +++-
 drivers/video/omap2/dss/dpi.c                      |   11 +++++++----
 include/video/omapdss.h                            |    4 ++--
 9 files changed, 27 insertions(+), 9 deletions(-)

diff --git a/drivers/video/omap2/displays/panel-generic-dpi.c b/drivers/video/omap2/displays/panel-generic-dpi.c
index bc5af25..5e70313 100644
--- a/drivers/video/omap2/displays/panel-generic-dpi.c
+++ b/drivers/video/omap2/displays/panel-generic-dpi.c
@@ -563,6 +563,8 @@ static int generic_dpi_panel_power_on(struct omap_dss_device *dssdev)
 	if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
 		return 0;
 
+	omapdss_dpi_set_timings(dssdev, &dssdev->panel.timings);
+
 	r = omapdss_dpi_display_enable(dssdev);
 	if (r)
 		goto err0;
@@ -695,7 +697,7 @@ static int generic_dpi_panel_resume(struct omap_dss_device *dssdev)
 static void generic_dpi_panel_set_timings(struct omap_dss_device *dssdev,
 		struct omap_video_timings *timings)
 {
-	dpi_set_timings(dssdev, timings);
+	omapdss_dpi_set_timings(dssdev, timings);
 }
 
 static int generic_dpi_panel_check_timings(struct omap_dss_device *dssdev,
diff --git a/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c b/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c
index 8028077..7e52aee 100644
--- a/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c
+++ b/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c
@@ -55,6 +55,8 @@ static int lb035q02_panel_power_on(struct omap_dss_device *dssdev)
 	if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
 		return 0;
 
+	omapdss_dpi_set_timings(dssdev, &dssdev->panel.timings);
+
 	r = omapdss_dpi_display_enable(dssdev);
 	if (r)
 		goto err0;
diff --git a/drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c b/drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c
index b122b0f..e501c40 100644
--- a/drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c
+++ b/drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c
@@ -175,6 +175,8 @@ static int nec_8048_panel_power_on(struct omap_dss_device *dssdev)
 	if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
 		return 0;
 
+	omapdss_dpi_set_timings(dssdev, &dssdev->panel.timings);
+
 	r = omapdss_dpi_display_enable(dssdev);
 	if (r)
 		goto err0;
diff --git a/drivers/video/omap2/displays/panel-picodlp.c b/drivers/video/omap2/displays/panel-picodlp.c
index 2d35bd3..0d7a8ff 100644
--- a/drivers/video/omap2/displays/panel-picodlp.c
+++ b/drivers/video/omap2/displays/panel-picodlp.c
@@ -377,6 +377,9 @@ static int picodlp_panel_power_on(struct omap_dss_device *dssdev)
 	 * then only i2c commands can be successfully sent to dpp2600
 	 */
 	msleep(1000);
+
+	omapdss_dpi_set_timings(dssdev, &dssdev->panel.timings);
+
 	r = omapdss_dpi_display_enable(dssdev);
 	if (r) {
 		dev_err(&dssdev->dev, "failed to enable DPI\n");
diff --git a/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c b/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c
index bd86ba9..1486a81 100644
--- a/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c
+++ b/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c
@@ -142,6 +142,8 @@ static int sharp_ls_power_on(struct omap_dss_device *dssdev)
 	if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
 		return 0;
 
+	omapdss_dpi_set_timings(dssdev, &dssdev->panel.timings);
+
 	r = omapdss_dpi_display_enable(dssdev);
 	if (r)
 		goto err0;
diff --git a/drivers/video/omap2/displays/panel-tfp410.c b/drivers/video/omap2/displays/panel-tfp410.c
index 40cc0cfa..c6f9503 100644
--- a/drivers/video/omap2/displays/panel-tfp410.c
+++ b/drivers/video/omap2/displays/panel-tfp410.c
@@ -65,6 +65,8 @@ static int tfp410_power_on(struct omap_dss_device *dssdev)
 	if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
 		return 0;
 
+	omapdss_dpi_set_timings(dssdev, &dssdev->panel.timings);
+
 	r = omapdss_dpi_display_enable(dssdev);
 	if (r)
 		goto err0;
@@ -231,7 +233,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);
-	dpi_set_timings(dssdev, timings);
+	omapdss_dpi_set_timings(dssdev, timings);
 	mutex_unlock(&ddata->lock);
 }
 
diff --git a/drivers/video/omap2/displays/panel-tpo-td043mtea1.c b/drivers/video/omap2/displays/panel-tpo-td043mtea1.c
index fa7baa6..ecb163e 100644
--- a/drivers/video/omap2/displays/panel-tpo-td043mtea1.c
+++ b/drivers/video/omap2/displays/panel-tpo-td043mtea1.c
@@ -337,6 +337,8 @@ static int tpo_td043_enable_dss(struct omap_dss_device *dssdev)
 	if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
 		return 0;
 
+	omapdss_dpi_set_timings(dssdev, &dssdev->panel.timings);
+
 	r = omapdss_dpi_display_enable(dssdev);
 	if (r)
 		goto err0;
@@ -480,7 +482,7 @@ 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)
 {
-	dpi_set_timings(dssdev, timings);
+	omapdss_dpi_set_timings(dssdev, timings);
 }
 
 static int tpo_td043_check_timings(struct omap_dss_device *dssdev,
diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c
index add47fe..96dd1a4 100644
--- a/drivers/video/omap2/dss/dpi.c
+++ b/drivers/video/omap2/dss/dpi.c
@@ -41,6 +41,7 @@ static struct {
 
 	struct mutex lock;
 
+	struct omap_video_timings timings;
 	struct dss_lcd_mgr_config mgr_config;
 } dpi;
 
@@ -138,7 +139,7 @@ static int dpi_set_dispc_clk(unsigned long pck_req, unsigned long *fck,
 
 static int dpi_set_mode(struct omap_dss_device *dssdev)
 {
-	struct omap_video_timings *t = &dssdev->panel.timings;
+	struct omap_video_timings *t = &dpi.timings;
 	int lck_div = 0, pck_div = 0;
 	unsigned long fck = 0;
 	unsigned long pck;
@@ -293,8 +294,8 @@ void omapdss_dpi_display_disable(struct omap_dss_device *dssdev)
 }
 EXPORT_SYMBOL(omapdss_dpi_display_disable);
 
-void dpi_set_timings(struct omap_dss_device *dssdev,
-			struct omap_video_timings *timings)
+void omapdss_dpi_set_timings(struct omap_dss_device *dssdev,
+		struct omap_video_timings *timings)
 {
 	int r;
 
@@ -302,7 +303,9 @@ void dpi_set_timings(struct omap_dss_device *dssdev,
 
 	mutex_lock(&dpi.lock);
 
+	dpi.timings = *timings;
 	dssdev->panel.timings = *timings;
+
 	if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) {
 		r = dispc_runtime_get();
 		if (r)
@@ -317,7 +320,7 @@ void dpi_set_timings(struct omap_dss_device *dssdev,
 
 	mutex_unlock(&dpi.lock);
 }
-EXPORT_SYMBOL(dpi_set_timings);
+EXPORT_SYMBOL(omapdss_dpi_set_timings);
 
 int dpi_check_timings(struct omap_dss_device *dssdev,
 			struct omap_video_timings *timings)
diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index 6f7581b..ebf2ebd 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -751,8 +751,8 @@ void omapdss_dsi_display_disable(struct omap_dss_device *dssdev,
 
 int omapdss_dpi_display_enable(struct omap_dss_device *dssdev);
 void omapdss_dpi_display_disable(struct omap_dss_device *dssdev);
-void dpi_set_timings(struct omap_dss_device *dssdev,
-			struct omap_video_timings *timings);
+void omapdss_dpi_set_timings(struct omap_dss_device *dssdev,
+		struct omap_video_timings *timings);
 int dpi_check_timings(struct omap_dss_device *dssdev,
 			struct omap_video_timings *timings);
 
-- 
1.7.9.5


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

* [RFC 06/17] OMAPDSS: DPI displays: Take care of panel timings in the driver itself
  2012-08-01 10:43 ` Archit Taneja
@ 2012-08-01 10:43   ` Archit Taneja
  -1 siblings, 0 replies; 122+ messages in thread
From: Archit Taneja @ 2012-08-01 10:31 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-fbdev, linux-omap, sumit.semwal, rob, Archit Taneja

The timings maintained in omap_dss_device(dssdev->panel.timings) should be
maintained by the panel driver itself. It's the panel drivers responsibility
to update it if a new set of timings is to be configured. The DPI interface
driver shouldn't be responsible of updating the panel timings, it's responsible
of maintianing it's own copy of timings.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/displays/panel-generic-dpi.c   |    2 ++
 drivers/video/omap2/displays/panel-tfp410.c        |    1 +
 .../video/omap2/displays/panel-tpo-td043mtea1.c    |    2 ++
 drivers/video/omap2/dss/dpi.c                      |    1 -
 4 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/video/omap2/displays/panel-generic-dpi.c b/drivers/video/omap2/displays/panel-generic-dpi.c
index 5e70313..e773594 100644
--- a/drivers/video/omap2/displays/panel-generic-dpi.c
+++ b/drivers/video/omap2/displays/panel-generic-dpi.c
@@ -698,6 +698,8 @@ static void generic_dpi_panel_set_timings(struct omap_dss_device *dssdev,
 		struct omap_video_timings *timings)
 {
 	omapdss_dpi_set_timings(dssdev, timings);
+
+	dssdev->panel.timings = *timings;
 }
 
 static int generic_dpi_panel_check_timings(struct omap_dss_device *dssdev,
diff --git a/drivers/video/omap2/displays/panel-tfp410.c b/drivers/video/omap2/displays/panel-tfp410.c
index c6f9503..9397236 100644
--- a/drivers/video/omap2/displays/panel-tfp410.c
+++ b/drivers/video/omap2/displays/panel-tfp410.c
@@ -234,6 +234,7 @@ static void tfp410_set_timings(struct omap_dss_device *dssdev,
 
 	mutex_lock(&ddata->lock);
 	omapdss_dpi_set_timings(dssdev, timings);
+	dssdev->panel.timings = *timings;
 	mutex_unlock(&ddata->lock);
 }
 
diff --git a/drivers/video/omap2/displays/panel-tpo-td043mtea1.c b/drivers/video/omap2/displays/panel-tpo-td043mtea1.c
index ecb163e..3f47f5f 100644
--- a/drivers/video/omap2/displays/panel-tpo-td043mtea1.c
+++ b/drivers/video/omap2/displays/panel-tpo-td043mtea1.c
@@ -483,6 +483,8 @@ static void tpo_td043_set_timings(struct omap_dss_device *dssdev,
 		struct omap_video_timings *timings)
 {
 	omapdss_dpi_set_timings(dssdev, timings);
+
+	dssdev->panel.timings = *timings;
 }
 
 static int tpo_td043_check_timings(struct omap_dss_device *dssdev,
diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c
index 96dd1a4..6c43d80 100644
--- a/drivers/video/omap2/dss/dpi.c
+++ b/drivers/video/omap2/dss/dpi.c
@@ -304,7 +304,6 @@ void omapdss_dpi_set_timings(struct omap_dss_device *dssdev,
 	mutex_lock(&dpi.lock);
 
 	dpi.timings = *timings;
-	dssdev->panel.timings = *timings;
 
 	if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) {
 		r = dispc_runtime_get();
-- 
1.7.9.5


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

* [RFC 07/17] OMAPDSS: Displays: Add locking in generic DPI panel driver
  2012-08-01 10:43 ` Archit Taneja
@ 2012-08-01 10:43   ` Archit Taneja
  -1 siblings, 0 replies; 122+ messages in thread
From: Archit Taneja @ 2012-08-01 10:31 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-fbdev, linux-omap, sumit.semwal, rob, Archit Taneja

The generic DPI panel driver doesn't currently have locking to ensure that
the display states and the driver data is maintained correctly. Add mutex
locking to take care of this. Add a new get_timings driver op to override the
default get_timings op. The new driver op contains locking to ensure the correct
panel timings are seen when a DSS2 user calls device->driver->get_timings.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/displays/panel-generic-dpi.c |   69 +++++++++++++++++++---
 1 file changed, 62 insertions(+), 7 deletions(-)

diff --git a/drivers/video/omap2/displays/panel-generic-dpi.c b/drivers/video/omap2/displays/panel-generic-dpi.c
index e773594..a07e18c 100644
--- a/drivers/video/omap2/displays/panel-generic-dpi.c
+++ b/drivers/video/omap2/displays/panel-generic-dpi.c
@@ -545,6 +545,8 @@ struct panel_drv_data {
 	struct omap_dss_device *dssdev;
 
 	struct panel_config *panel_config;
+
+	struct mutex lock;
 };
 
 static inline struct panel_generic_dpi_data
@@ -636,6 +638,8 @@ static int generic_dpi_panel_probe(struct omap_dss_device *dssdev)
 	drv_data->dssdev = dssdev;
 	drv_data->panel_config = panel_config;
 
+	mutex_init(&drv_data->lock);
+
 	dev_set_drvdata(&dssdev->dev, drv_data);
 
 	return 0;
@@ -654,58 +658,108 @@ static void __exit generic_dpi_panel_remove(struct omap_dss_device *dssdev)
 
 static int generic_dpi_panel_enable(struct omap_dss_device *dssdev)
 {
-	int r = 0;
+	struct panel_drv_data *drv_data = dev_get_drvdata(&dssdev->dev);
+	int r;
+
+	mutex_lock(&drv_data->lock);
 
 	r = generic_dpi_panel_power_on(dssdev);
 	if (r)
-		return r;
+		goto err;
 
 	dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
+err:
+	mutex_unlock(&drv_data->lock);
 
-	return 0;
+	return r;
 }
 
 static void generic_dpi_panel_disable(struct omap_dss_device *dssdev)
 {
+	struct panel_drv_data *drv_data = dev_get_drvdata(&dssdev->dev);
+
+	mutex_lock(&drv_data->lock);
+
 	generic_dpi_panel_power_off(dssdev);
 
 	dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
+
+	mutex_unlock(&drv_data->lock);
 }
 
 static int generic_dpi_panel_suspend(struct omap_dss_device *dssdev)
 {
+	struct panel_drv_data *drv_data = dev_get_drvdata(&dssdev->dev);
+
+	mutex_lock(&drv_data->lock);
+
 	generic_dpi_panel_power_off(dssdev);
 
 	dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
 
+	mutex_unlock(&drv_data->lock);
+
 	return 0;
 }
 
 static int generic_dpi_panel_resume(struct omap_dss_device *dssdev)
 {
-	int r = 0;
+	struct panel_drv_data *drv_data = dev_get_drvdata(&dssdev->dev);
+	int r;
+
+	mutex_lock(&drv_data->lock);
 
 	r = generic_dpi_panel_power_on(dssdev);
 	if (r)
-		return r;
+		goto err;
 
 	dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
 
-	return 0;
+err:
+	mutex_unlock(&drv_data->lock);
+
+	return r;
 }
 
 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);
+
+	mutex_lock(&drv_data->lock);
+
 	omapdss_dpi_set_timings(dssdev, timings);
 
 	dssdev->panel.timings = *timings;
+
+	mutex_unlock(&drv_data->lock);
+}
+
+static void generic_dpi_panel_get_timings(struct omap_dss_device *dssdev,
+		struct omap_video_timings *timings)
+{
+	struct panel_drv_data *drv_data = dev_get_drvdata(&dssdev->dev);
+
+	mutex_lock(&drv_data->lock);
+
+	*timings = dssdev->panel.timings;
+
+	mutex_unlock(&drv_data->lock);
 }
 
 static int generic_dpi_panel_check_timings(struct omap_dss_device *dssdev,
 		struct omap_video_timings *timings)
 {
-	return dpi_check_timings(dssdev, timings);
+	struct panel_drv_data *drv_data = dev_get_drvdata(&dssdev->dev);
+	int r;
+
+	mutex_lock(&drv_data->lock);
+
+	r = dpi_check_timings(dssdev, timings);
+
+	mutex_unlock(&drv_data->lock);
+
+	return r;
 }
 
 static struct omap_dss_driver dpi_driver = {
@@ -718,6 +772,7 @@ static struct omap_dss_driver dpi_driver = {
 	.resume		= generic_dpi_panel_resume,
 
 	.set_timings	= generic_dpi_panel_set_timings,
+	.get_timings	= generic_dpi_panel_get_timings,
 	.check_timings	= generic_dpi_panel_check_timings,
 
 	.driver         = {
-- 
1.7.9.5


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

* [RFC 08/17] OMAPDSS: DSI: Maintain own copy of timings in driver data
  2012-08-01 10:43 ` Archit Taneja
@ 2012-08-01 10:43   ` Archit Taneja
  -1 siblings, 0 replies; 122+ messages in thread
From: Archit Taneja @ 2012-08-01 10:31 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-fbdev, linux-omap, sumit.semwal, rob, Archit Taneja

The DSI driver currently relies on the timings in omap_dss_device struct to
configure the DISPC and DSI blocks accordingly. This makes the DSI interface
driver dependent on the omap_dss_device struct.

Make the DPI driver data maintain it's own timings field. The panel driver is
expected to call omapdss_dsi_set_timings() to set these timings before the panel
is enabled.

Signed-off-by: Archit Taneja <archit@ti.com>d
---
 drivers/video/omap2/displays/panel-taal.c |    2 ++
 drivers/video/omap2/dss/dsi.c             |   27 ++++++++++++++++++++++-----
 include/video/omapdss.h                   |    2 ++
 3 files changed, 26 insertions(+), 5 deletions(-)

diff --git a/drivers/video/omap2/displays/panel-taal.c b/drivers/video/omap2/displays/panel-taal.c
index 3f5acc7..4775580 100644
--- a/drivers/video/omap2/displays/panel-taal.c
+++ b/drivers/video/omap2/displays/panel-taal.c
@@ -1060,6 +1060,8 @@ static int taal_power_on(struct omap_dss_device *dssdev)
 		goto err0;
 	};
 
+	omapdss_dsi_set_timings(dssdev, &td->panel_config->timings);
+
 	r = omapdss_dsi_display_enable(dssdev);
 	if (r) {
 		dev_err(&dssdev->dev, "failed to enable DSI\n");
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index 27c27c4..598d965 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -333,6 +333,7 @@ struct dsi_data {
 	unsigned scp_clk_refcount;
 
 	struct dss_lcd_mgr_config mgr_config;
+	struct omap_video_timings timings;
 };
 
 struct dsi_packet_sent_handler_data {
@@ -3607,9 +3608,10 @@ static void dsi_config_vp_num_line_buffers(struct omap_dss_device *dssdev)
 	int num_line_buffers;
 
 	if (dssdev->panel.dsi_mode == OMAP_DSS_DSI_VIDEO_MODE) {
+		struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
 		int bpp = dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt);
 		unsigned line_buf_size = dsi_get_line_buf_size(dsidev);
-		struct omap_video_timings *timings = &dssdev->panel.timings;
+		struct omap_video_timings *timings = &dsi->timings;
 		/*
 		 * Don't use line buffers if width is greater than the video
 		 * port's line buffer size
@@ -3738,7 +3740,7 @@ static void dsi_config_cmd_mode_interleaving(struct omap_dss_device *dssdev)
 	int ddr_clk_pre, ddr_clk_post, enter_hs_mode_lat, exit_hs_mode_lat;
 	int tclk_trail, ths_exit, exiths_clk;
 	bool ddr_alwon;
-	struct omap_video_timings *timings = &dssdev->panel.timings;
+	struct omap_video_timings *timings = &dsi->timings;
 	int bpp = dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt);
 	int ndl = dsi->num_lanes_used - 1;
 	const struct omapdss_clock_config *clks;
@@ -3996,7 +3998,7 @@ static void dsi_proto_timings(struct omap_dss_device *dssdev)
 		int vbp = dssdev->panel.dsi_vm_data.vbp;
 		int window_sync = dssdev->panel.dsi_vm_data.window_sync;
 		bool hsync_end = dssdev->panel.dsi_vm_data.vp_hsync_end;
-		struct omap_video_timings *timings = &dssdev->panel.timings;
+		struct omap_video_timings *timings = &dsi->timings;
 		int bpp = dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt);
 		int tl, t_he, width_bytes;
 
@@ -4105,6 +4107,7 @@ 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 dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
 	int bpp = dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt);
 	u8 data_type;
 	u16 word_count;
@@ -4135,7 +4138,7 @@ int dsi_enable_video_output(struct omap_dss_device *dssdev, int channel)
 		/* MODE, 1 = video mode */
 		REG_FLD_MOD(dsidev, DSI_VC_CTRL(channel), 1, 4, 4);
 
-		word_count = DIV_ROUND_UP(dssdev->panel.timings.x_res * bpp, 8);
+		word_count = DIV_ROUND_UP(dsi->timings.x_res * bpp, 8);
 
 		dsi_vc_write_long_header(dsidev, channel, data_type,
 				word_count, 0);
@@ -4401,7 +4404,7 @@ static int dsi_display_init_dispc(struct omap_dss_device *dssdev)
 		dsi->mgr_config.stallmode = true;
 		dsi->mgr_config.fifohandcheck = true;
 	} else {
-		timings = dssdev->panel.timings;
+		timings = dsi->timings;
 
 		dsi->mgr_config.stallmode = false;
 		dsi->mgr_config.fifohandcheck = false;
@@ -4688,6 +4691,20 @@ 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,
+		struct omap_video_timings *timings)
+{
+	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
+
+	mutex_lock(&dsi->lock);
+
+	dsi->timings = *timings;
+
+	mutex_unlock(&dsi->lock);
+}
+EXPORT_SYMBOL(omapdss_dsi_set_timings);
+
 static int __init dsi_init_display(struct omap_dss_device *dssdev)
 {
 	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index ebf2ebd..a2cd133 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -736,6 +736,8 @@ int omap_dispc_wait_for_irq_interruptible_timeout(u32 irqmask,
 void omapdss_dsi_vc_enable_hs(struct omap_dss_device *dssdev, 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,
+		struct omap_video_timings *timings);
 
 int omap_dsi_update(struct omap_dss_device *dssdev, int channel,
 		void (*callback)(int, void *), void *data);
-- 
1.7.9.5


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

* [RFC 09/17] OMAPDSS: HDMI: Use our own omap_video_timings field when setting interface timings
  2012-08-01 10:43 ` Archit Taneja
@ 2012-08-01 10:43   ` Archit Taneja
  -1 siblings, 0 replies; 122+ messages in thread
From: Archit Taneja @ 2012-08-01 10:31 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-fbdev, linux-omap, sumit.semwal, rob, Archit Taneja

The hdmi driver currently updates only the 'code' member of hdmi_config when
the op omapdss_hdmi_display_set_timing() is called by the hdmi panel driver.
The 'timing' field of hdmi_config is updated only when hdmi_power_on is called.
It makes more sense to configure the whole hdmi_config field in the set_timing
op called by the panel driver. This way, we don't need to call both functions
to ensure that our hdmi_config is configured correctly. Also, we don't need to
calculate hdmi_config during hdmi_power_on, or rely on the omap_video_timings
in the panel's omap_dss_device struct.

A default timing is now configured in hdmi's probe if the panel driver doesn't
set any timing, or doesn't set a valid timing before enabling the panel. Also,
when setting manager timings, use the omap_video_timing calculated by
hdmi_get_timings(), this returns the timings as specified in the CEA/VESA
tables, don't use the one provided by the panel driver directly.

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

diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index 8a9630b..7e38ffd 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -485,7 +485,8 @@ static inline unsigned long hdmi_get_pixel_clock(void)
 #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);
+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);
diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c
index 6635b09..01665fa 100644
--- a/drivers/video/omap2/dss/hdmi.c
+++ b/drivers/video/omap2/dss/hdmi.c
@@ -462,7 +462,6 @@ static int hdmi_power_on(struct omap_dss_device *dssdev)
 {
 	const struct omapdss_clock_config *clks;
 	int r;
-	const struct hdmi_config *timing;
 	struct omap_video_timings *p;
 	unsigned long phy;
 
@@ -472,22 +471,10 @@ static int hdmi_power_on(struct omap_dss_device *dssdev)
 
 	dss_mgr_disable(dssdev->manager);
 
-	p = &dssdev->panel.timings;
+	p = &hdmi.ip_data.cfg.timings;
 
-	DSSDBG("hdmi_power_on x_res= %d y_res = %d\n",
-		dssdev->panel.timings.x_res,
-		dssdev->panel.timings.y_res);
+	DSSDBG("hdmi_power_on x_res= %d y_res = %d\n", p->x_res, p->y_res);
 
-	timing = hdmi_get_timings();
-	if (timing == NULL) {
-		/* HDMI code 4 corresponds to 640 * 480 VGA */
-		hdmi.ip_data.cfg.cm.code = 4;
-		/* DVI mode 1 corresponds to HDMI 0 to DVI */
-		hdmi.ip_data.cfg.cm.mode = HDMI_DVI;
-		hdmi.ip_data.cfg = vesa_timings[0];
-	} else {
-		hdmi.ip_data.cfg = *timing;
-	}
 	phy = p->pixel_clock;
 
 	hdmi_compute_pll(phy, &hdmi.ip_data.pll_data);
@@ -525,7 +512,7 @@ static int hdmi_power_on(struct omap_dss_device *dssdev)
 	dispc_enable_gamma_table(0);
 
 	/* tv size */
-	dss_mgr_set_timings(dssdev->manager, &dssdev->panel.timings);
+	dss_mgr_set_timings(dssdev->manager, p);
 
 	r = hdmi.ip_data.ops->video_enable(&hdmi.ip_data);
 	if (r)
@@ -571,13 +558,18 @@ 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_device *dssdev,
+		struct omap_video_timings *timings)
 {
 	struct hdmi_cm cm;
+	const struct hdmi_config *timing;
+
+	cm = hdmi_get_code(timings);
+	hdmi.ip_data.cfg.cm = cm;
 
-	cm = hdmi_get_code(&dssdev->panel.timings);
-	hdmi.ip_data.cfg.cm.code = cm.code;
-	hdmi.ip_data.cfg.cm.mode = cm.mode;
+	timing = hdmi_get_timings();
+	if (timing != NULL)
+		hdmi.ip_data.cfg = *timing;
 
 	if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) {
 		int r;
@@ -588,7 +580,7 @@ void omapdss_hdmi_display_set_timing(struct omap_dss_device *dssdev)
 		if (r)
 			DSSERR("failed to power on device\n");
 	} else {
-		dss_mgr_set_timings(dssdev->manager, &dssdev->panel.timings);
+		dss_mgr_set_timings(dssdev->manager, &timing->timings);
 	}
 }
 
@@ -933,6 +925,13 @@ static int __init omapdss_hdmihw_probe(struct platform_device *pdev)
 	hdmi.ip_data.core_av_offset = HDMI_CORE_AV;
 	hdmi.ip_data.pll_offset = HDMI_PLLCTRL;
 	hdmi.ip_data.phy_offset = HDMI_PHY;
+
+	/*
+	 * initialize hdmi timings to default value:
+	 * HDMI code 4(VGA) and HDMI mode 1(DVI)
+	 */
+	hdmi.ip_data.cfg = vesa_timings[0];
+
 	mutex_init(&hdmi.ip_data.lock);
 
 	hdmi_panel_init();
diff --git a/drivers/video/omap2/dss/hdmi_panel.c b/drivers/video/omap2/dss/hdmi_panel.c
index e10844f..8dce206 100644
--- a/drivers/video/omap2/dss/hdmi_panel.c
+++ b/drivers/video/omap2/dss/hdmi_panel.c
@@ -336,8 +336,8 @@ static void hdmi_set_timings(struct omap_dss_device *dssdev,
 	 */
 	hdmi_panel_audio_disable(dssdev);
 
+	omapdss_hdmi_display_set_timing(dssdev, timings);
 	dssdev->panel.timings = *timings;
-	omapdss_hdmi_display_set_timing(dssdev);
 
 	mutex_unlock(&hdmi.lock);
 }
-- 
1.7.9.5


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

* [RFC 10/17] OMAPDSS: HDMI: Add a get_timing function for HDMI interface
  2012-08-01 10:43 ` Archit Taneja
@ 2012-08-01 10:43   ` Archit Taneja
  -1 siblings, 0 replies; 122+ messages in thread
From: Archit Taneja @ 2012-08-01 10:31 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-fbdev, linux-omap, sumit.semwal, rob, Archit Taneja

Add function omapdss_hdmi_display_get_timing() which returns the timings
maintained by the HDMI interface driver in it's hdmi_config field. This
prevents the need for the panel driver to configure default timings in it's
probe.

This function is just intended to be used once during the panel driver's probe.
It makes sense for those interfaces which can be configured to a default timing.

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

diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index 7e38ffd..df49c5d 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -485,6 +485,8 @@ static inline unsigned long hdmi_get_pixel_clock(void)
 #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_get_timing(struct omap_dss_device *dssdev,
+		struct omap_video_timings *timings);
 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,
diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c
index 01665fa..2de1f91 100644
--- a/drivers/video/omap2/dss/hdmi.c
+++ b/drivers/video/omap2/dss/hdmi.c
@@ -544,6 +544,12 @@ static void hdmi_power_off(struct omap_dss_device *dssdev)
 	hdmi_runtime_put();
 }
 
+void omapdss_hdmi_display_get_timing(struct omap_dss_device *dssdev,
+		struct omap_video_timings *timings)
+{
+	*timings = hdmi.ip_data.cfg.timings;
+}
+
 int omapdss_hdmi_display_check_timing(struct omap_dss_device *dssdev,
 					struct omap_video_timings *timings)
 {
diff --git a/drivers/video/omap2/dss/hdmi_panel.c b/drivers/video/omap2/dss/hdmi_panel.c
index 8dce206..8473193 100644
--- a/drivers/video/omap2/dss/hdmi_panel.c
+++ b/drivers/video/omap2/dss/hdmi_panel.c
@@ -41,13 +41,13 @@ static struct {
 
 static int hdmi_panel_probe(struct omap_dss_device *dssdev)
 {
+	struct omap_video_timings timings;
+
 	DSSDBG("ENTER hdmi_panel_probe\n");
 
-	dssdev->panel.timings = (struct omap_video_timings)
-			{ 640, 480, 25175, 96, 16, 48, 2, 11, 31,
-				OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
-				false,
-			};
+	omapdss_hdmi_display_get_timing(dssdev, &timings);
+
+	dssdev->panel.timings = timings;
 
 	DSSDBG("hdmi_panel_probe x_res= %d y_res = %d\n",
 		dssdev->panel.timings.x_res,
-- 
1.7.9.5


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

* [RFC 11/17] OMAPDSS: HDMI: Add locking for hdmi interface get/set timing functions
  2012-08-01 10:43 ` Archit Taneja
@ 2012-08-01 10:43   ` Archit Taneja
  -1 siblings, 0 replies; 122+ messages in thread
From: Archit Taneja @ 2012-08-01 10:31 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-fbdev, linux-omap, sumit.semwal, rob, Archit Taneja

The hdmi interface driver exposes functions to the hdmi panel driver to
get and configure the interface timings maintained by the hdmi driver.

These timings(stored in hdmi.ip_data.cfg) should be protected by the hdmi lock
to ensure they are called sequentially, this is similar to how hdmi enable and
disable functions need locking.

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

diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c
index 2de1f91..dfd582e 100644
--- a/drivers/video/omap2/dss/hdmi.c
+++ b/drivers/video/omap2/dss/hdmi.c
@@ -547,7 +547,11 @@ static void hdmi_power_off(struct omap_dss_device *dssdev)
 void omapdss_hdmi_display_get_timing(struct omap_dss_device *dssdev,
 		struct omap_video_timings *timings)
 {
+	mutex_lock(&hdmi.lock);
+
 	*timings = hdmi.ip_data.cfg.timings;
+
+	mutex_unlock(&hdmi.lock);
 }
 
 int omapdss_hdmi_display_check_timing(struct omap_dss_device *dssdev,
@@ -570,6 +574,8 @@ void omapdss_hdmi_display_set_timing(struct omap_dss_device *dssdev,
 	struct hdmi_cm cm;
 	const struct hdmi_config *timing;
 
+	mutex_lock(&hdmi.lock);
+
 	cm = hdmi_get_code(timings);
 	hdmi.ip_data.cfg.cm = cm;
 
@@ -588,6 +594,8 @@ void omapdss_hdmi_display_set_timing(struct omap_dss_device *dssdev,
 	} else {
 		dss_mgr_set_timings(dssdev->manager, &timing->timings);
 	}
+
+	mutex_unlock(&hdmi.lock);
 }
 
 static void hdmi_dump_regs(struct seq_file *s)
-- 
1.7.9.5


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

* [RFC 12/17] OMAPDSS: SDI: Create a separate function for timing/clock configurations
  2012-08-01 10:43 ` Archit Taneja
@ 2012-08-01 10:43   ` Archit Taneja
  -1 siblings, 0 replies; 122+ messages in thread
From: Archit Taneja @ 2012-08-01 10:31 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-fbdev, linux-omap, sumit.semwal, rob, Archit Taneja

Create a function sdi_set_mode() which configures the DISPC and DSS(PRCM)
clocks to get the required pixel clock, and configure the manager timings.
This is similar to what's done in the DPI driver in dpi_set_mode().

This makes the code a bit cleaner to read, and makes it easier to reconfigure
timings instead of switching off the whole interface, and then enabling the
interface with the new timings.

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

diff --git a/drivers/video/omap2/dss/sdi.c b/drivers/video/omap2/dss/sdi.c
index 5d31699..f2d3f45 100644
--- a/drivers/video/omap2/dss/sdi.c
+++ b/drivers/video/omap2/dss/sdi.c
@@ -49,40 +49,21 @@ static void sdi_config_lcd_manager(struct omap_dss_device *dssdev)
 	dss_mgr_set_lcd_config(dssdev->manager, &sdi.mgr_config);
 }
 
-int omapdss_sdi_display_enable(struct omap_dss_device *dssdev)
+static int sdi_set_mode(struct omap_dss_device *dssdev)
 {
+	int r;
 	struct omap_video_timings *t = &dssdev->panel.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");
-		return -ENODEV;
-	}
-
-	r = omap_dss_start_device(dssdev);
-	if (r) {
-		DSSERR("failed to start device\n");
-		goto err_start_dev;
-	}
-
-	r = regulator_enable(sdi.vdds_sdi_reg);
-	if (r)
-		goto err_reg_enable;
-
-	r = dispc_runtime_get();
-	if (r)
-		goto err_get_dispc;
 
 	/* 15.5.9.1.2 */
-	dssdev->panel.timings.data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE;
-	dssdev->panel.timings.sync_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE;
+	t->data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE;
+	t->sync_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE;
 
 	r = dss_calc_clock_div(t->pixel_clock * 1000, &dss_cinfo, &dispc_cinfo);
 	if (r)
-		goto err_calc_clock_div;
+		return r;
 
 	sdi.mgr_config.clock_info = dispc_cinfo;
 
@@ -96,12 +77,41 @@ int omapdss_sdi_display_enable(struct omap_dss_device *dssdev)
 		t->pixel_clock = pck;
 	}
 
-
 	dss_mgr_set_timings(dssdev->manager, t);
 
 	r = dss_set_clock_div(&dss_cinfo);
 	if (r)
-		goto err_set_dss_clock_div;
+		return r;
+
+	return 0;
+}
+
+int omapdss_sdi_display_enable(struct omap_dss_device *dssdev)
+{
+	int r;
+
+	if (dssdev->manager == NULL) {
+		DSSERR("failed to enable display: no manager\n");
+		return -ENODEV;
+	}
+
+	r = omap_dss_start_device(dssdev);
+	if (r) {
+		DSSERR("failed to start device\n");
+		goto err_start_dev;
+	}
+
+	r = regulator_enable(sdi.vdds_sdi_reg);
+	if (r)
+		goto err_reg_enable;
+
+	r = dispc_runtime_get();
+	if (r)
+		goto err_get_dispc;
+
+	r = sdi_set_mode(dssdev);
+	if (r)
+		goto err_set_mode;
 
 	sdi_config_lcd_manager(dssdev);
 
@@ -120,8 +130,7 @@ int omapdss_sdi_display_enable(struct omap_dss_device *dssdev)
 err_mgr_enable:
 	dss_sdi_disable();
 err_sdi_enable:
-err_set_dss_clock_div:
-err_calc_clock_div:
+err_set_mode:
 	dispc_runtime_put();
 err_get_dispc:
 	regulator_disable(sdi.vdds_sdi_reg);
-- 
1.7.9.5


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

* [RFC 13/17] OMAPDSS: SDI: Create a function to set timings
  2012-08-01 10:43 ` Archit Taneja
@ 2012-08-01 10:43   ` Archit Taneja
  -1 siblings, 0 replies; 122+ messages in thread
From: Archit Taneja @ 2012-08-01 10:31 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-fbdev, linux-omap, sumit.semwal, rob, Archit Taneja

Create function omapdss_sdi_set_timings(), this can be used by a SDI panel
driver without disabling/enabling the SDI interface. This is similar to the
set_timings op of the DPI interface driver. It calls sdi_set_mode() which only
configures the DISPC timings and DSS/DISPC clock dividers.

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

diff --git a/drivers/video/omap2/displays/panel-acx565akm.c b/drivers/video/omap2/displays/panel-acx565akm.c
index eaeed43..11bdc88 100644
--- a/drivers/video/omap2/displays/panel-acx565akm.c
+++ b/drivers/video/omap2/displays/panel-acx565akm.c
@@ -731,18 +731,7 @@ 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)
 {
-	int r;
-
-	if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
-		omapdss_sdi_display_disable(dssdev);
-
-	dssdev->panel.timings = *timings;
-
-	if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) {
-		r = omapdss_sdi_display_enable(dssdev);
-		if (r)
-			dev_err(&dssdev->dev, "%s enable failed\n", __func__);
-	}
+	omapdss_sdi_set_timings(dssdev, timings);
 }
 
 static int acx_panel_check_timings(struct omap_dss_device *dssdev,
diff --git a/drivers/video/omap2/dss/sdi.c b/drivers/video/omap2/dss/sdi.c
index f2d3f45..d88243f 100644
--- a/drivers/video/omap2/dss/sdi.c
+++ b/drivers/video/omap2/dss/sdi.c
@@ -155,6 +155,25 @@ void omapdss_sdi_display_disable(struct omap_dss_device *dssdev)
 }
 EXPORT_SYMBOL(omapdss_sdi_display_disable);
 
+void omapdss_sdi_set_timings(struct omap_dss_device *dssdev,
+		struct omap_video_timings *timings)
+{
+	int r;
+
+	dssdev->panel.timings = *timings;
+
+	if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) {
+		r = dispc_runtime_get();
+		if (r)
+			return;
+
+		sdi_set_mode(dssdev);
+
+		dispc_runtime_put();
+	}
+}
+EXPORT_SYMBOL(omapdss_sdi_set_timings);
+
 static int __init sdi_init_display(struct omap_dss_device *dssdev)
 {
 	DSSDBG("SDI init\n");
diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index a2cd133..54ba639 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -760,6 +760,8 @@ int dpi_check_timings(struct omap_dss_device *dssdev,
 
 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,
+		struct omap_video_timings *timings);
 
 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] 122+ messages in thread

* [RFC 14/17] OMAPDSS: SDI: Maintain our own timings field in driver data
  2012-08-01 10:43 ` Archit Taneja
@ 2012-08-01 10:43   ` Archit Taneja
  -1 siblings, 0 replies; 122+ messages in thread
From: Archit Taneja @ 2012-08-01 10:31 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-fbdev, linux-omap, sumit.semwal, rob, Archit Taneja

The SDI driver currently relies on the timings in omap_dss_device struct to
configure the DISPC accordingly. This makes the SDI interface driver dependent
on the omap_dss_device struct.

Make the SDI driver data maintain it's own timings field. The panel driver is
expected to call omapdss_sdi_set_timings() to set these timings before the panel
is enabled.

Make the SDI panel driver configure the new timings is the omap_dss_device
struct(dssdev->panel.timings). The SDI driver is responsible for maintaining
only it's own copy of timings.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/displays/panel-acx565akm.c |    4 ++++
 drivers/video/omap2/dss/sdi.c                  |    5 +++--
 2 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/video/omap2/displays/panel-acx565akm.c b/drivers/video/omap2/displays/panel-acx565akm.c
index 11bdc88..77fe59f 100644
--- a/drivers/video/omap2/displays/panel-acx565akm.c
+++ b/drivers/video/omap2/displays/panel-acx565akm.c
@@ -600,6 +600,8 @@ static int acx_panel_power_on(struct omap_dss_device *dssdev)
 
 	mutex_lock(&md->mutex);
 
+	omapdss_sdi_set_timings(dssdev, &dssdev->panel.timings);
+
 	r = omapdss_sdi_display_enable(dssdev);
 	if (r) {
 		pr_err("%s sdi enable failed\n", __func__);
@@ -732,6 +734,8 @@ static void acx_panel_set_timings(struct omap_dss_device *dssdev,
 		struct omap_video_timings *timings)
 {
 	omapdss_sdi_set_timings(dssdev, timings);
+
+	dssdev->panel.timings = *timings;
 }
 
 static int acx_panel_check_timings(struct omap_dss_device *dssdev,
diff --git a/drivers/video/omap2/dss/sdi.c b/drivers/video/omap2/dss/sdi.c
index d88243f..917816d 100644
--- a/drivers/video/omap2/dss/sdi.c
+++ b/drivers/video/omap2/dss/sdi.c
@@ -34,6 +34,7 @@ static struct {
 	struct regulator *vdds_sdi_reg;
 
 	struct dss_lcd_mgr_config mgr_config;
+	struct omap_video_timings timings;
 } sdi;
 
 static void sdi_config_lcd_manager(struct omap_dss_device *dssdev)
@@ -52,7 +53,7 @@ static void sdi_config_lcd_manager(struct omap_dss_device *dssdev)
 static int sdi_set_mode(struct omap_dss_device *dssdev)
 {
 	int r;
-	struct omap_video_timings *t = &dssdev->panel.timings;
+	struct omap_video_timings *t = &sdi.timings;
 	struct dss_clock_info dss_cinfo;
 	struct dispc_clock_info dispc_cinfo;
 	unsigned long pck;
@@ -160,7 +161,7 @@ void omapdss_sdi_set_timings(struct omap_dss_device *dssdev,
 {
 	int r;
 
-	dssdev->panel.timings = *timings;
+	sdi.timings = *timings;
 
 	if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) {
 		r = dispc_runtime_get();
-- 
1.7.9.5


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

* [RFC 15/17] OMAPDSS: VENC: Split VENC into interface and panel driver
  2012-08-01 10:43 ` Archit Taneja
@ 2012-08-01 10:43   ` Archit Taneja
  -1 siblings, 0 replies; 122+ messages in thread
From: Archit Taneja @ 2012-08-01 10:31 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-fbdev, linux-omap, sumit.semwal, rob, Archit Taneja

The current venc.c driver contains both the interface and panel driver code.
This makes the driver hard to read, and difficult to understand the work split
between the interface and panel driver and the how the locking works.

This also makes it easier to clearly define the VENC interface ops called by the
panel driver.

Split venc.c into venc.c and venc_panel.c representing the interface and panel
driver respectively. This split is done along the lines of the HDMI interface
and panel drivers.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/dss/Makefile     |    2 +-
 drivers/video/omap2/dss/dss.h        |   10 ++
 drivers/video/omap2/dss/venc.c       |  208 ++++++++----------------------
 drivers/video/omap2/dss/venc_panel.c |  231 ++++++++++++++++++++++++++++++++++
 4 files changed, 295 insertions(+), 156 deletions(-)
 create mode 100644 drivers/video/omap2/dss/venc_panel.c

diff --git a/drivers/video/omap2/dss/Makefile b/drivers/video/omap2/dss/Makefile
index 5c450b0..30a48fb 100644
--- a/drivers/video/omap2/dss/Makefile
+++ b/drivers/video/omap2/dss/Makefile
@@ -3,7 +3,7 @@ omapdss-y := core.o dss.o dss_features.o dispc.o dispc_coefs.o display.o \
 	manager.o overlay.o apply.o
 omapdss-$(CONFIG_OMAP2_DSS_DPI) += dpi.o
 omapdss-$(CONFIG_OMAP2_DSS_RFBI) += rfbi.o
-omapdss-$(CONFIG_OMAP2_DSS_VENC) += venc.o
+omapdss-$(CONFIG_OMAP2_DSS_VENC) += venc.o venc_panel.o
 omapdss-$(CONFIG_OMAP2_DSS_SDI) += sdi.o
 omapdss-$(CONFIG_OMAP2_DSS_DSI) += dsi.o
 omapdss-$(CONFIG_OMAP4_DSS_HDMI) += hdmi.o \
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index df49c5d..69b6ab9 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -470,6 +470,16 @@ 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,
+		struct omap_video_timings *timings);
+int omapdss_venc_check_timings(struct omap_dss_device *dssdev,
+		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);
+int venc_panel_init(void);
+void venc_panel_exit(void);
 
 /* HDMI */
 #ifdef CONFIG_OMAP4_DSS_HDMI
diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c
index 3a22087..ffca542 100644
--- a/drivers/video/omap2/dss/venc.c
+++ b/drivers/video/omap2/dss/venc.c
@@ -427,6 +427,10 @@ static int venc_power_on(struct omap_dss_device *dssdev)
 	u32 l;
 	int r;
 
+	r = venc_runtime_get();
+	if (r)
+		goto err0;
+
 	venc_reset();
 	venc_write_config(venc_timings_to_config(&dssdev->panel.timings));
 
@@ -449,26 +453,22 @@ static int venc_power_on(struct omap_dss_device *dssdev)
 
 	r = regulator_enable(venc.vdda_dac_reg);
 	if (r)
-		goto err;
-
-	if (dssdev->platform_enable)
-		dssdev->platform_enable(dssdev);
+		goto err1;
 
 	r = dss_mgr_enable(dssdev->manager);
 	if (r)
-		goto err;
+		goto err2;
 
 	return 0;
 
-err:
+err2:
+	regulator_disable(venc.vdda_dac_reg);
+err1:
 	venc_write_reg(VENC_OUTPUT_CONTROL, 0);
 	dss_set_dac_pwrdn_bgz(0);
 
-	if (dssdev->platform_disable)
-		dssdev->platform_disable(dssdev);
-
-	regulator_disable(venc.vdda_dac_reg);
-
+	venc_runtime_put();
+err0:
 	return r;
 }
 
@@ -479,10 +479,9 @@ static void venc_power_off(struct omap_dss_device *dssdev)
 
 	dss_mgr_disable(dssdev->manager);
 
-	if (dssdev->platform_disable)
-		dssdev->platform_disable(dssdev);
-
 	regulator_disable(venc.vdda_dac_reg);
+
+	venc_runtime_put();
 }
 
 unsigned long venc_get_pixel_clock(void)
@@ -491,171 +490,95 @@ unsigned long venc_get_pixel_clock(void)
 	return 13500000;
 }
 
-static ssize_t display_output_type_show(struct device *dev,
-		struct device_attribute *attr, char *buf)
+int omapdss_venc_display_enable(struct omap_dss_device *dssdev)
 {
-	struct omap_dss_device *dssdev = to_dss_device(dev);
-	const char *ret;
-
-	switch (dssdev->phy.venc.type) {
-	case OMAP_DSS_VENC_TYPE_COMPOSITE:
-		ret = "composite";
-		break;
-	case OMAP_DSS_VENC_TYPE_SVIDEO:
-		ret = "svideo";
-		break;
-	default:
-		return -EINVAL;
-	}
+	int r;
 
-	return snprintf(buf, PAGE_SIZE, "%s\n", ret);
-}
-
-static ssize_t display_output_type_store(struct device *dev,
-		struct device_attribute *attr, const char *buf, size_t size)
-{
-	struct omap_dss_device *dssdev = to_dss_device(dev);
-	enum omap_dss_venc_type new_type;
-
-	if (sysfs_streq("composite", buf))
-		new_type = OMAP_DSS_VENC_TYPE_COMPOSITE;
-	else if (sysfs_streq("svideo", buf))
-		new_type = OMAP_DSS_VENC_TYPE_SVIDEO;
-	else
-		return -EINVAL;
+	DSSDBG("venc_display_enable\n");
 
 	mutex_lock(&venc.venc_lock);
 
-	if (dssdev->phy.venc.type != new_type) {
-		dssdev->phy.venc.type = new_type;
-		if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) {
-			venc_power_off(dssdev);
-			venc_power_on(dssdev);
-		}
+	if (dssdev->manager == NULL) {
+		DSSERR("Failed to enable display: no manager\n");
+		r = -ENODEV;
+		goto err0;
 	}
 
-	mutex_unlock(&venc.venc_lock);
-
-	return size;
-}
-
-static DEVICE_ATTR(output_type, S_IRUGO | S_IWUSR,
-		display_output_type_show, display_output_type_store);
-
-/* driver */
-static int venc_panel_probe(struct omap_dss_device *dssdev)
-{
-	dssdev->panel.timings = omap_dss_pal_timings;
-
-	return device_create_file(&dssdev->dev, &dev_attr_output_type);
-}
-
-static void venc_panel_remove(struct omap_dss_device *dssdev)
-{
-	device_remove_file(&dssdev->dev, &dev_attr_output_type);
-}
-
-static int venc_panel_enable(struct omap_dss_device *dssdev)
-{
-	int r = 0;
-
-	DSSDBG("venc_enable_display\n");
-
-	mutex_lock(&venc.venc_lock);
-
 	r = omap_dss_start_device(dssdev);
 	if (r) {
 		DSSERR("failed to start device\n");
 		goto err0;
 	}
 
-	if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) {
-		r = -EINVAL;
-		goto err1;
-	}
+	if (dssdev->platform_enable)
+		dssdev->platform_enable(dssdev);
 
-	r = venc_runtime_get();
-	if (r)
-		goto err1;
 
 	r = venc_power_on(dssdev);
 	if (r)
-		goto err2;
+		goto err1;
 
 	venc.wss_data = 0;
 
-	dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
-
 	mutex_unlock(&venc.venc_lock);
+
 	return 0;
-err2:
-	venc_runtime_put();
 err1:
+	if (dssdev->platform_disable)
+		dssdev->platform_disable(dssdev);
 	omap_dss_stop_device(dssdev);
 err0:
 	mutex_unlock(&venc.venc_lock);
-
 	return r;
 }
 
-static void venc_panel_disable(struct omap_dss_device *dssdev)
+void omapdss_venc_display_disable(struct omap_dss_device *dssdev)
 {
-	DSSDBG("venc_disable_display\n");
+	DSSDBG("venc_display_disable\n");
 
 	mutex_lock(&venc.venc_lock);
 
-	if (dssdev->state == OMAP_DSS_DISPLAY_DISABLED)
-		goto end;
-
-	if (dssdev->state == OMAP_DSS_DISPLAY_SUSPENDED) {
-		/* suspended is the same as disabled with venc */
-		dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
-		goto end;
-	}
-
 	venc_power_off(dssdev);
 
-	venc_runtime_put();
-
-	dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
-
 	omap_dss_stop_device(dssdev);
-end:
-	mutex_unlock(&venc.venc_lock);
-}
 
-static int venc_panel_suspend(struct omap_dss_device *dssdev)
-{
-	venc_panel_disable(dssdev);
-	return 0;
-}
+	if (dssdev->platform_disable)
+		dssdev->platform_disable(dssdev);
 
-static int venc_panel_resume(struct omap_dss_device *dssdev)
-{
-	return venc_panel_enable(dssdev);
+	mutex_unlock(&venc.venc_lock);
 }
 
-static void venc_set_timings(struct omap_dss_device *dssdev,
-			struct omap_video_timings *timings)
+void omapdss_venc_set_timings(struct omap_dss_device *dssdev,
+		struct omap_video_timings *timings)
 {
 	DSSDBG("venc_set_timings\n");
 
+	mutex_lock(&venc.venc_lock);
+
 	/* Reset WSS data when the TV standard changes. */
 	if (memcmp(&dssdev->panel.timings, timings, sizeof(*timings)))
 		venc.wss_data = 0;
 
 	dssdev->panel.timings = *timings;
+
 	if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) {
+		int r;
+
 		/* turn the venc off and on to get new timings to use */
-		venc_panel_disable(dssdev);
-		venc_panel_enable(dssdev);
+		venc_power_off(dssdev);
+
+		r = venc_power_on(dssdev);
+		if (r)
+			DSSERR("failed to power on VENC\n");
 	} else {
 		dss_mgr_set_timings(dssdev->manager, timings);
 	}
+
+	mutex_unlock(&venc.venc_lock);
 }
 
-static int venc_check_timings(struct omap_dss_device *dssdev,
-			struct omap_video_timings *timings)
+int omapdss_venc_check_timings(struct omap_dss_device *dssdev,
+		struct omap_video_timings *timings)
 {
 	DSSDBG("venc_check_timings\n");
 
@@ -668,13 +591,13 @@ static int venc_check_timings(struct omap_dss_device *dssdev,
 	return -EINVAL;
 }
 
-static u32 venc_get_wss(struct omap_dss_device *dssdev)
+u32 omapdss_venc_get_wss(struct omap_dss_device *dssdev)
 {
 	/* Invert due to VENC_L21_WC_CTL:INV=1 */
 	return (venc.wss_data >> 8) ^ 0xfffff;
 }
 
-static int venc_set_wss(struct omap_dss_device *dssdev,	u32 wss)
+int omapdss_venc_set_wss(struct omap_dss_device *dssdev, u32 wss)
 {
 	const struct venc_config *config;
 	int r;
@@ -703,31 +626,6 @@ err:
 	return r;
 }
 
-static struct omap_dss_driver venc_driver = {
-	.probe		= venc_panel_probe,
-	.remove		= venc_panel_remove,
-
-	.enable		= venc_panel_enable,
-	.disable	= venc_panel_disable,
-	.suspend	= venc_panel_suspend,
-	.resume		= venc_panel_resume,
-
-	.get_resolution	= omapdss_default_get_resolution,
-	.get_recommended_bpp = omapdss_default_get_recommended_bpp,
-
-	.set_timings	= venc_set_timings,
-	.check_timings	= venc_check_timings,
-
-	.get_wss	= venc_get_wss,
-	.set_wss	= venc_set_wss,
-
-	.driver         = {
-		.name   = "venc",
-		.owner  = THIS_MODULE,
-	},
-};
-/* driver end */
-
 static int __init venc_init_display(struct omap_dss_device *dssdev)
 {
 	DSSDBG("init_display\n");
@@ -897,9 +795,9 @@ static int __init omap_venchw_probe(struct platform_device *pdev)
 
 	venc_runtime_put();
 
-	r = omap_dss_register_driver(&venc_driver);
+	r = venc_panel_init();
 	if (r)
-		goto err_reg_panel_driver;
+		goto err_panel_init;
 
 	dss_debugfs_create_file("venc", venc_dump_regs);
 
@@ -907,7 +805,7 @@ static int __init omap_venchw_probe(struct platform_device *pdev)
 
 	return 0;
 
-err_reg_panel_driver:
+err_panel_init:
 err_runtime_get:
 	pm_runtime_disable(&pdev->dev);
 	venc_put_clocks();
@@ -923,7 +821,7 @@ static int __exit omap_venchw_remove(struct platform_device *pdev)
 		venc.vdda_dac_reg = NULL;
 	}
 
-	omap_dss_unregister_driver(&venc_driver);
+	venc_panel_exit();
 
 	pm_runtime_disable(&pdev->dev);
 	venc_put_clocks();
diff --git a/drivers/video/omap2/dss/venc_panel.c b/drivers/video/omap2/dss/venc_panel.c
new file mode 100644
index 0000000..6b31298
--- /dev/null
+++ b/drivers/video/omap2/dss/venc_panel.c
@@ -0,0 +1,231 @@
+/*
+ * Copyright (C) 2009 Nokia Corporation
+ * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
+ *
+ * VENC panel driver
+ *
+ * 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/err.h>
+#include <linux/io.h>
+#include <linux/mutex.h>
+#include <linux/module.h>
+
+#include <video/omapdss.h>
+
+#include "dss.h"
+
+static struct {
+	struct mutex lock;
+} venc_panel;
+
+static ssize_t display_output_type_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct omap_dss_device *dssdev = to_dss_device(dev);
+	const char *ret;
+
+	switch (dssdev->phy.venc.type) {
+	case OMAP_DSS_VENC_TYPE_COMPOSITE:
+		ret = "composite";
+		break;
+	case OMAP_DSS_VENC_TYPE_SVIDEO:
+		ret = "svideo";
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return snprintf(buf, PAGE_SIZE, "%s\n", ret);
+}
+
+static ssize_t display_output_type_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t size)
+{
+	struct omap_dss_device *dssdev = to_dss_device(dev);
+	enum omap_dss_venc_type new_type;
+
+	if (sysfs_streq("composite", buf))
+		new_type = OMAP_DSS_VENC_TYPE_COMPOSITE;
+	else if (sysfs_streq("svideo", buf))
+		new_type = OMAP_DSS_VENC_TYPE_SVIDEO;
+	else
+		return -EINVAL;
+
+	mutex_lock(&venc_panel.lock);
+
+	if (dssdev->phy.venc.type != new_type) {
+		dssdev->phy.venc.type = new_type;
+		if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) {
+			omapdss_venc_display_disable(dssdev);
+			omapdss_venc_display_enable(dssdev);
+		}
+	}
+
+	mutex_unlock(&venc_panel.lock);
+
+	return size;
+}
+
+static DEVICE_ATTR(output_type, S_IRUGO | S_IWUSR,
+		display_output_type_show, display_output_type_store);
+
+static int venc_panel_probe(struct omap_dss_device *dssdev)
+{
+	mutex_init(&venc_panel.lock);
+
+	/* set initial timings to PAL */
+	dssdev->panel.timings = (struct omap_video_timings)
+		{ 720, 574, 13500, 64, 12, 68, 5, 5, 41,
+			OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
+			true,
+		};
+
+	return device_create_file(&dssdev->dev, &dev_attr_output_type);
+}
+
+static void venc_panel_remove(struct omap_dss_device *dssdev)
+{
+	device_remove_file(&dssdev->dev, &dev_attr_output_type);
+}
+
+static int venc_panel_enable(struct omap_dss_device *dssdev)
+{
+	int r;
+
+	dev_dbg(&dssdev->dev, "venc_panel_enable\n");
+
+	mutex_lock(&venc_panel.lock);
+
+	if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) {
+		r = -EINVAL;
+		goto err;
+	}
+
+	r = omapdss_venc_display_enable(dssdev);
+	if (r)
+		goto err;
+
+	dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
+
+	mutex_unlock(&venc_panel.lock);
+
+	return 0;
+err:
+	mutex_unlock(&venc_panel.lock);
+
+	return r;
+}
+
+static void venc_panel_disable(struct omap_dss_device *dssdev)
+{
+	dev_dbg(&dssdev->dev, "venc_panel_disable\n");
+
+	mutex_lock(&venc_panel.lock);
+
+	if (dssdev->state == OMAP_DSS_DISPLAY_DISABLED)
+		goto end;
+
+	if (dssdev->state == OMAP_DSS_DISPLAY_SUSPENDED) {
+		/* suspended is the same as disabled with venc */
+		dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
+		goto end;
+	}
+
+	omapdss_venc_display_disable(dssdev);
+
+	dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
+end:
+	mutex_unlock(&venc_panel.lock);
+}
+
+static int venc_panel_suspend(struct omap_dss_device *dssdev)
+{
+	venc_panel_disable(dssdev);
+	return 0;
+}
+
+static int venc_panel_resume(struct omap_dss_device *dssdev)
+{
+	return venc_panel_enable(dssdev);
+}
+
+static void venc_panel_set_timings(struct omap_dss_device *dssdev,
+		struct omap_video_timings *timings)
+{
+	dev_dbg(&dssdev->dev, "venc_panel_set_timings\n");
+
+	mutex_lock(&venc_panel.lock);
+
+	omapdss_venc_set_timings(dssdev, timings);
+
+	mutex_unlock(&venc_panel.lock);
+}
+
+static int venc_panel_check_timings(struct omap_dss_device *dssdev,
+		struct omap_video_timings *timings)
+{
+	dev_dbg(&dssdev->dev, "venc_panel_check_timings\n");
+
+	return omapdss_venc_check_timings(dssdev, timings);
+}
+
+static u32 venc_panel_get_wss(struct omap_dss_device *dssdev)
+{
+	dev_dbg(&dssdev->dev, "venc_panel_get_wss\n");
+
+	return omapdss_venc_get_wss(dssdev);
+}
+
+static int venc_panel_set_wss(struct omap_dss_device *dssdev, u32 wss)
+{
+	dev_dbg(&dssdev->dev, "venc_panel_set_wss\n");
+
+	return omapdss_venc_set_wss(dssdev, wss);
+}
+
+static struct omap_dss_driver venc_driver = {
+	.probe		= venc_panel_probe,
+	.remove		= venc_panel_remove,
+
+	.enable		= venc_panel_enable,
+	.disable	= venc_panel_disable,
+	.suspend	= venc_panel_suspend,
+	.resume		= venc_panel_resume,
+
+	.get_resolution	= omapdss_default_get_resolution,
+	.get_recommended_bpp = omapdss_default_get_recommended_bpp,
+
+	.set_timings	= venc_panel_set_timings,
+	.check_timings	= venc_panel_check_timings,
+
+	.get_wss	= venc_panel_get_wss,
+	.set_wss	= venc_panel_set_wss,
+
+	.driver         = {
+		.name   = "venc",
+		.owner  = THIS_MODULE,
+	},
+};
+
+int venc_panel_init(void)
+{
+	return omap_dss_register_driver(&venc_driver);
+}
+
+void venc_panel_exit(void)
+{
+	omap_dss_unregister_driver(&venc_driver);
+}
-- 
1.7.9.5


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

* [RFC 16/17] OMAPDSS: VENC: Maintain our own timings field in driver data
  2012-08-01 10:43 ` Archit Taneja
@ 2012-08-01 10:43   ` Archit Taneja
  -1 siblings, 0 replies; 122+ messages in thread
From: Archit Taneja @ 2012-08-01 10:31 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-fbdev, linux-omap, sumit.semwal, rob, Archit Taneja

The VENC driver currently relies on the timings in omap_dss_device struct to
configure the DISPC and VENC blocks accordingly. This makes the VENC interface
driver dependent on the omap_dss_device struct.

Make the VENC driver data maintain it's own timings field. The panel driver is
expected to call omapdss_venc_set_timings() to set these timings before the
panel is enabled.

Make the VENC panel driver configure the new timings is the omap_dss_device
struct(dssdev->panel.timings). The VENC driver is responsible for maintaining
only it's own copy of timings.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/dss/venc.c       |   12 +++++++-----
 drivers/video/omap2/dss/venc_panel.c |    1 +
 2 files changed, 8 insertions(+), 5 deletions(-)

diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c
index ffca542..d96025e 100644
--- a/drivers/video/omap2/dss/venc.c
+++ b/drivers/video/omap2/dss/venc.c
@@ -300,6 +300,8 @@ static struct {
 	struct regulator *vdda_dac_reg;
 
 	struct clk	*tv_dac_clk;
+
+	struct omap_video_timings timings;
 } venc;
 
 static inline void venc_write_reg(int idx, u32 val)
@@ -432,7 +434,7 @@ static int venc_power_on(struct omap_dss_device *dssdev)
 		goto err0;
 
 	venc_reset();
-	venc_write_config(venc_timings_to_config(&dssdev->panel.timings));
+	venc_write_config(venc_timings_to_config(&venc.timings));
 
 	dss_set_venc_output(dssdev->phy.venc.type);
 	dss_set_dac_pwrdn_bgz(1);
@@ -449,7 +451,7 @@ static int venc_power_on(struct omap_dss_device *dssdev)
 
 	venc_write_reg(VENC_OUTPUT_CONTROL, l);
 
-	dss_mgr_set_timings(dssdev->manager, &dssdev->panel.timings);
+	dss_mgr_set_timings(dssdev->manager, &venc.timings);
 
 	r = regulator_enable(venc.vdda_dac_reg);
 	if (r)
@@ -556,10 +558,10 @@ void omapdss_venc_set_timings(struct omap_dss_device *dssdev,
 	mutex_lock(&venc.venc_lock);
 
 	/* Reset WSS data when the TV standard changes. */
-	if (memcmp(&dssdev->panel.timings, timings, sizeof(*timings)))
+	if (memcmp(&venc.timings, timings, sizeof(*timings)))
 		venc.wss_data = 0;
 
-	dssdev->panel.timings = *timings;
+	venc.timings = *timings;
 
 	if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) {
 		int r;
@@ -606,7 +608,7 @@ int omapdss_venc_set_wss(struct omap_dss_device *dssdev, u32 wss)
 
 	mutex_lock(&venc.venc_lock);
 
-	config = venc_timings_to_config(&dssdev->panel.timings);
+	config = venc_timings_to_config(&venc.timings);
 
 	/* Invert due to VENC_L21_WC_CTL:INV=1 */
 	venc.wss_data = (wss ^ 0xfffff) << 8;
diff --git a/drivers/video/omap2/dss/venc_panel.c b/drivers/video/omap2/dss/venc_panel.c
index 6b31298..350b0d9 100644
--- a/drivers/video/omap2/dss/venc_panel.c
+++ b/drivers/video/omap2/dss/venc_panel.c
@@ -170,6 +170,7 @@ static void venc_panel_set_timings(struct omap_dss_device *dssdev,
 	mutex_lock(&venc_panel.lock);
 
 	omapdss_venc_set_timings(dssdev, timings);
+	dssdev->panel.timings = *timings;
 
 	mutex_unlock(&venc_panel.lock);
 }
-- 
1.7.9.5


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

* [RFC 17/17] OMAPDSS: VENC: Add a get_timing function for VENC interface
  2012-08-01 10:43 ` Archit Taneja
@ 2012-08-01 10:43   ` Archit Taneja
  -1 siblings, 0 replies; 122+ messages in thread
From: Archit Taneja @ 2012-08-01 10:31 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-fbdev, linux-omap, sumit.semwal, rob, Archit Taneja

Add function omapdss_venc_get_timing() which returns the timings
maintained by the VENC interface driver in it's driver data. This is just used
once by the driver during it's probe. This prevents the need for the panel
driver to configure default timings in it's probe.

Int the VENC interface's probe, the timings field is set to PAL as a default
value. The get_timing op makes more sense for interfaces which can be configured
to a default timing.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/dss/dss.h        |    2 ++
 drivers/video/omap2/dss/venc.c       |   13 +++++++++++++
 drivers/video/omap2/dss/venc_panel.c |   11 +++++------
 3 files changed, 20 insertions(+), 6 deletions(-)

diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index 69b6ab9..3fe76c0 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -474,6 +474,8 @@ 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,
 		struct omap_video_timings *timings);
+void omapdss_venc_get_timings(struct omap_dss_device *dssdev,
+		struct omap_video_timings *timings);
 int omapdss_venc_check_timings(struct omap_dss_device *dssdev,
 		struct omap_video_timings *timings);
 u32 omapdss_venc_get_wss(struct omap_dss_device *dssdev);
diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c
index d96025e..42f97ac 100644
--- a/drivers/video/omap2/dss/venc.c
+++ b/drivers/video/omap2/dss/venc.c
@@ -579,6 +579,18 @@ void omapdss_venc_set_timings(struct omap_dss_device *dssdev,
 	mutex_unlock(&venc.venc_lock);
 }
 
+void omapdss_venc_get_timings(struct omap_dss_device *dssdev,
+		struct omap_video_timings *timings)
+{
+	DSSDBG("venc_set_timings\n");
+
+	mutex_lock(&venc.venc_lock);
+
+	*timings = venc.timings;
+
+	mutex_unlock(&venc.venc_lock);
+}
+
 int omapdss_venc_check_timings(struct omap_dss_device *dssdev,
 		struct omap_video_timings *timings)
 {
@@ -768,6 +780,7 @@ static int __init omap_venchw_probe(struct platform_device *pdev)
 	mutex_init(&venc.venc_lock);
 
 	venc.wss_data = 0;
+	venc.timings = omap_dss_pal_timings;
 
 	venc_mem = platform_get_resource(venc.pdev, IORESOURCE_MEM, 0);
 	if (!venc_mem) {
diff --git a/drivers/video/omap2/dss/venc_panel.c b/drivers/video/omap2/dss/venc_panel.c
index 350b0d9..fe9958d 100644
--- a/drivers/video/omap2/dss/venc_panel.c
+++ b/drivers/video/omap2/dss/venc_panel.c
@@ -84,14 +84,13 @@ static DEVICE_ATTR(output_type, S_IRUGO | S_IWUSR,
 
 static int venc_panel_probe(struct omap_dss_device *dssdev)
 {
+	struct omap_video_timings timings;
+
 	mutex_init(&venc_panel.lock);
 
-	/* set initial timings to PAL */
-	dssdev->panel.timings = (struct omap_video_timings)
-		{ 720, 574, 13500, 64, 12, 68, 5, 5, 41,
-			OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
-			true,
-		};
+	omapdss_venc_get_timings(dssdev, &timings);
+
+	dssdev->panel.timings = timings;
 
 	return device_create_file(&dssdev->dev, &dev_attr_output_type);
 }
-- 
1.7.9.5


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

* Re: [RFC 00/17] OMAPDSS: Change way of passing timings from panel driver to interface
  2012-08-01 10:43 ` Archit Taneja
@ 2012-08-01 10:47   ` Archit Taneja
  -1 siblings, 0 replies; 122+ messages in thread
From: Archit Taneja @ 2012-08-01 10:35 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-fbdev, linux-omap, sumit.semwal, rob

On Wednesday 01 August 2012 04:01 PM, Archit Taneja wrote:
> This series tries to make interface drivers less dependent on omap_dss_device
> which represents a panel/device connected to that interface. The current way of
> configuring an interface is to populate the panel's omap_dss_device instance
> with parameters common to the panel and the interface, they are either populated
> in the board file, or in the panel driver. Panel timings, number of lanes
> connected to interface, and pixel format are examples of such parameters, these
> are then extracted by the interface driver to configure itself.
>
> This approach has some disadvantages:
>
> - The omap_dss_device contains fields which could be handled independently by
>    the panel driver. For example, we have an enum field in omap_dss_device to
>    tell what mode the panel operates in. This information could be handled by the
>    panel driver itself. But it's a part of omap_dss_device since we need to pass
>    this down to the interface driver.
>
> - An interface can't exist by itself. That is, it needs a panel to be connected
>    to it to configure itself. It's not practical to configure an interface
>    without a panel, but it's theoretically possible, and we may need it if we
>    expose the interface as an entity to a user of OMAPDSS. It's also useful if we
>    represent writeback as an interface, writeback isn't connected to a panel.
>
> - There is a lack of clarity in how the interface configures itself. Since the
>    interface driver extracts info from omap_dss_device, it's unclear from a panel
>    driver point of view about what information in omap_dss_device the interface
>    is using and what it's not using.
>
> - There are issues with checking the correctness of the parameters in
>    omap_dss_device. We currently fill up the omap_dss_device completely, and then
>    try to enable the interface, this results in catching a wrong parameter at a
>    much later point, rather than catching it immediately.
>
> The alternative approach is for the interface drivers to expose functions/api to
> the panel drivers to configure such parameters. This way, the panel driver can
> pass the parameters to the interface itself, rather than filling up
> omap_dss_device. This would need the panel driver to keep a copy of the
> parameters so that it can use to configure it later. This resolves all the
> issues mentioned above, and also gives us a chance to make a generic set of
> function ops for interfaces, this can make a panel driver independent of
> the underlying platform.
>
> The current series starts of this work by creating a set_timings function for
> all interfaces passing omap_video_timings, this prevents dssdev->panel.timings
> references. The first few patches are some minor cleanups which are useful for
> the patches which come later.
>
> There are some points on which I need suggestions/clarifications:
> - How do we make sure that these functions are called by the panel driver at the
>    right time? For example, when setting timings for DSI video mode, we would
>    need to call omapdss_dsi_set_timings() before we call
>    omapdss_dsi_display_enable(), otherwise the copy of timings contained in DSI
>    driver data would be invalid. Also, what should the behaviour of such a
>    set_timings operation if the interface is already enabled. It is clear for
>    DPI and HDMI, but I'm not clear about what to do about other interfaces. Do we
>    add checks for the state of the interface/panel?
>
> - A specific issue about DSI/RFBI getting the resolution via
>    device->driver->get_resolution(), does this provide a result based on panel
>    rotation? Can this somehow be replaced by timings?
>
> - For SDI, the set_timings operation is simplified, instead of disabling and
>    then enabling the panel with a new set of timings, only the new timings are
>    configured. This is similar to what is done in DPI. I am not clear if this
>    will work for SDI or not.
>
> - There is no set_timings() function for RFBI yet, this needs to be though of
>    and fixed.
>
> The reference tree and branch:

forgot to add the link here:

git://gitorious.org/~boddob/linux-omap-dss2/archit-dss2-clone.git 
pass_timings_interface

Archit
>
> This is based on Tomi's for-florian-merged branch, and has 2 of his patches which
> got missed the last merge window.
>
> This hasn't been tested thoroughly with all interfaces yet. I was interested in
> getting some comments.
>
> Archit Taneja (17):
>    OMAPDSS: APPLY: Constify timings argument in dss_mgr_set_timings
>    OMAPDSS: DPI: Remove omap_dss_device arguments in
>      dpi_set_dsi_clk/dpi_set_dispc_clk
>    OMAPDSS: HDMI: Remove omap_dss_device argument from hdmi_compute_pll
>    OMAPDSS: DPI: Add locking for DPI interface
>    OMAPDSS: DPI: Maintain our own timings field in driver data
>    OMAPDSS: DPI displays: Take care of panel timings in the driver
>      itself
>    OMAPDSS: Displays: Add locking in generic DPI panel driver
>    OMAPDSS: DSI: Maintain own copy of timings in driver data
>    OMAPDSS: HDMI: Use our own omap_video_timings field when setting
>      interface timings
>    OMAPDSS: HDMI: Add a get_timing function for HDMI interface
>    OMAPDSS: HDMI: Add locking for hdmi interface get/set timing
>      functions
>    OMAPDSS: SDI: Create a separate function for timing/clock
>      configurations
>    OMAPDSS: SDI: Create a function to set timings
>    OMAPDSS: SDI: Maintain our own timings field in driver data
>    OMAPDSS: VENC: Split VENC into interface and panel driver
>    OMAPDSS: VENC: Maintain our own timings field in driver data
>    OMAPDSS: VENC: Add a get_timing function for VENC interface
>
>   drivers/video/omap2/displays/panel-acx565akm.c     |   13 +-
>   drivers/video/omap2/displays/panel-generic-dpi.c   |   75 ++++++-
>   .../omap2/displays/panel-lgphilips-lb035q02.c      |    2 +
>   .../omap2/displays/panel-nec-nl8048hl11-01b.c      |    2 +
>   drivers/video/omap2/displays/panel-picodlp.c       |    3 +
>   .../video/omap2/displays/panel-sharp-ls037v7dw01.c |    2 +
>   drivers/video/omap2/displays/panel-taal.c          |    2 +
>   drivers/video/omap2/displays/panel-tfp410.c        |    5 +-
>   .../video/omap2/displays/panel-tpo-td043mtea1.c    |    6 +-
>   drivers/video/omap2/dss/Makefile                   |    2 +-
>   drivers/video/omap2/dss/apply.c                    |    4 +-
>   drivers/video/omap2/dss/dpi.c                      |   52 +++--
>   drivers/video/omap2/dss/dsi.c                      |   27 ++-
>   drivers/video/omap2/dss/dss.h                      |   19 +-
>   drivers/video/omap2/dss/hdmi.c                     |   60 +++--
>   drivers/video/omap2/dss/hdmi_panel.c               |   12 +-
>   drivers/video/omap2/dss/sdi.c                      |   87 +++++---
>   drivers/video/omap2/dss/venc.c                     |  233 ++++++--------------
>   drivers/video/omap2/dss/venc_panel.c               |  231 +++++++++++++++++++
>   include/video/omapdss.h                            |    8 +-
>   20 files changed, 579 insertions(+), 266 deletions(-)
>   create mode 100644 drivers/video/omap2/dss/venc_panel.c
>


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

* [RFC 00/17] OMAPDSS: Change way of passing timings from panel driver to interface
@ 2012-08-01 10:43 ` Archit Taneja
  0 siblings, 0 replies; 122+ messages in thread
From: Archit Taneja @ 2012-08-01 10:43 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-fbdev, linux-omap, sumit.semwal, rob, Archit Taneja

This series tries to make interface drivers less dependent on omap_dss_device
which represents a panel/device connected to that interface. The current way of
configuring an interface is to populate the panel's omap_dss_device instance
with parameters common to the panel and the interface, they are either populated
in the board file, or in the panel driver. Panel timings, number of lanes
connected to interface, and pixel format are examples of such parameters, these
are then extracted by the interface driver to configure itself.

This approach has some disadvantages:

- The omap_dss_device contains fields which could be handled independently by
  the panel driver. For example, we have an enum field in omap_dss_device to
  tell what mode the panel operates in. This information could be handled by the
  panel driver itself. But it's a part of omap_dss_device since we need to pass
  this down to the interface driver.

- An interface can't exist by itself. That is, it needs a panel to be connected
  to it to configure itself. It's not practical to configure an interface
  without a panel, but it's theoretically possible, and we may need it if we
  expose the interface as an entity to a user of OMAPDSS. It's also useful if we
  represent writeback as an interface, writeback isn't connected to a panel.

- There is a lack of clarity in how the interface configures itself. Since the
  interface driver extracts info from omap_dss_device, it's unclear from a panel
  driver point of view about what information in omap_dss_device the interface
  is using and what it's not using.

- There are issues with checking the correctness of the parameters in
  omap_dss_device. We currently fill up the omap_dss_device completely, and then
  try to enable the interface, this results in catching a wrong parameter at a
  much later point, rather than catching it immediately.

The alternative approach is for the interface drivers to expose functions/api to
the panel drivers to configure such parameters. This way, the panel driver can
pass the parameters to the interface itself, rather than filling up
omap_dss_device. This would need the panel driver to keep a copy of the
parameters so that it can use to configure it later. This resolves all the
issues mentioned above, and also gives us a chance to make a generic set of
function ops for interfaces, this can make a panel driver independent of
the underlying platform.

The current series starts of this work by creating a set_timings function for
all interfaces passing omap_video_timings, this prevents dssdev->panel.timings
references. The first few patches are some minor cleanups which are useful for
the patches which come later.

There are some points on which I need suggestions/clarifications:
- How do we make sure that these functions are called by the panel driver at the
  right time? For example, when setting timings for DSI video mode, we would
  need to call omapdss_dsi_set_timings() before we call
  omapdss_dsi_display_enable(), otherwise the copy of timings contained in DSI
  driver data would be invalid. Also, what should the behaviour of such a
  set_timings operation if the interface is already enabled. It is clear for
  DPI and HDMI, but I'm not clear about what to do about other interfaces. Do we
  add checks for the state of the interface/panel?

- A specific issue about DSI/RFBI getting the resolution via
  device->driver->get_resolution(), does this provide a result based on panel
  rotation? Can this somehow be replaced by timings?

- For SDI, the set_timings operation is simplified, instead of disabling and
  then enabling the panel with a new set of timings, only the new timings are
  configured. This is similar to what is done in DPI. I am not clear if this
  will work for SDI or not.

- There is no set_timings() function for RFBI yet, this needs to be though of
  and fixed. 

The reference tree and branch:

This is based on Tomi's for-florian-merged branch, and has 2 of his patches which
got missed the last merge window.

This hasn't been tested thoroughly with all interfaces yet. I was interested in
getting some comments.

Archit Taneja (17):
  OMAPDSS: APPLY: Constify timings argument in dss_mgr_set_timings
  OMAPDSS: DPI: Remove omap_dss_device arguments in
    dpi_set_dsi_clk/dpi_set_dispc_clk
  OMAPDSS: HDMI: Remove omap_dss_device argument from hdmi_compute_pll
  OMAPDSS: DPI: Add locking for DPI interface
  OMAPDSS: DPI: Maintain our own timings field in driver data
  OMAPDSS: DPI displays: Take care of panel timings in the driver
    itself
  OMAPDSS: Displays: Add locking in generic DPI panel driver
  OMAPDSS: DSI: Maintain own copy of timings in driver data
  OMAPDSS: HDMI: Use our own omap_video_timings field when setting
    interface timings
  OMAPDSS: HDMI: Add a get_timing function for HDMI interface
  OMAPDSS: HDMI: Add locking for hdmi interface get/set timing
    functions
  OMAPDSS: SDI: Create a separate function for timing/clock
    configurations
  OMAPDSS: SDI: Create a function to set timings
  OMAPDSS: SDI: Maintain our own timings field in driver data
  OMAPDSS: VENC: Split VENC into interface and panel driver
  OMAPDSS: VENC: Maintain our own timings field in driver data
  OMAPDSS: VENC: Add a get_timing function for VENC interface

 drivers/video/omap2/displays/panel-acx565akm.c     |   13 +-
 drivers/video/omap2/displays/panel-generic-dpi.c   |   75 ++++++-
 .../omap2/displays/panel-lgphilips-lb035q02.c      |    2 +
 .../omap2/displays/panel-nec-nl8048hl11-01b.c      |    2 +
 drivers/video/omap2/displays/panel-picodlp.c       |    3 +
 .../video/omap2/displays/panel-sharp-ls037v7dw01.c |    2 +
 drivers/video/omap2/displays/panel-taal.c          |    2 +
 drivers/video/omap2/displays/panel-tfp410.c        |    5 +-
 .../video/omap2/displays/panel-tpo-td043mtea1.c    |    6 +-
 drivers/video/omap2/dss/Makefile                   |    2 +-
 drivers/video/omap2/dss/apply.c                    |    4 +-
 drivers/video/omap2/dss/dpi.c                      |   52 +++--
 drivers/video/omap2/dss/dsi.c                      |   27 ++-
 drivers/video/omap2/dss/dss.h                      |   19 +-
 drivers/video/omap2/dss/hdmi.c                     |   60 +++--
 drivers/video/omap2/dss/hdmi_panel.c               |   12 +-
 drivers/video/omap2/dss/sdi.c                      |   87 +++++---
 drivers/video/omap2/dss/venc.c                     |  233 ++++++--------------
 drivers/video/omap2/dss/venc_panel.c               |  231 +++++++++++++++++++
 include/video/omapdss.h                            |    8 +-
 20 files changed, 579 insertions(+), 266 deletions(-)
 create mode 100644 drivers/video/omap2/dss/venc_panel.c

-- 
1.7.9.5


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

* [RFC 01/17] OMAPDSS: APPLY: Constify timings argument in dss_mgr_set_timings
@ 2012-08-01 10:43   ` Archit Taneja
  0 siblings, 0 replies; 122+ messages in thread
From: Archit Taneja @ 2012-08-01 10:43 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-fbdev, linux-omap, sumit.semwal, rob, Archit Taneja

The function dss_mgr_set_timings is supposed to apply timings passed by an
interface driver. It is not supposed to change the timings. Add const qualifier
to the omap_video_timings pointer argument in dss_mgr_set_timings().

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

diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c
index 0fefc68..52a5940 100644
--- a/drivers/video/omap2/dss/apply.c
+++ b/drivers/video/omap2/dss/apply.c
@@ -1302,7 +1302,7 @@ err:
 }
 
 static void dss_apply_mgr_timings(struct omap_overlay_manager *mgr,
-		struct omap_video_timings *timings)
+		const struct omap_video_timings *timings)
 {
 	struct mgr_priv_data *mp = get_mgr_priv(mgr);
 
@@ -1311,7 +1311,7 @@ static void dss_apply_mgr_timings(struct omap_overlay_manager *mgr,
 }
 
 void dss_mgr_set_timings(struct omap_overlay_manager *mgr,
-		struct omap_video_timings *timings)
+		const struct omap_video_timings *timings)
 {
 	unsigned long flags;
 
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index 335ee93..8a9630b 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -207,7 +207,7 @@ 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);
 void dss_mgr_set_timings(struct omap_overlay_manager *mgr,
-		struct omap_video_timings *timings);
+		const struct omap_video_timings *timings);
 void dss_mgr_set_lcd_config(struct omap_overlay_manager *mgr,
 		const struct dss_lcd_mgr_config *config);
 const struct omap_video_timings *dss_mgr_get_timings(struct omap_overlay_manager *mgr);
-- 
1.7.9.5


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

* [RFC 02/17] OMAPDSS: DPI: Remove omap_dss_device arguments in dpi_set_dsi_clk/dpi_set_dispc_clk
@ 2012-08-01 10:43   ` Archit Taneja
  0 siblings, 0 replies; 122+ messages in thread
From: Archit Taneja @ 2012-08-01 10:43 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-fbdev, linux-omap, sumit.semwal, rob, Archit Taneja

The clock related info for DSS modules is not tied anymore to a panel's
omap_dss_device struct. It's now passed via platform data. The functions
dpi_set_dsi_clk() and dpi_set_dispc_clk() do not need the omap_dss_device
argument to retieve these clocks. They use the api dss_get_platform_clock_config
to get the clocks. Remove the omap_dss_device arguments from these functions.

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

diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c
index 5fec180..c20fe23 100644
--- a/drivers/video/omap2/dss/dpi.c
+++ b/drivers/video/omap2/dss/dpi.c
@@ -80,9 +80,8 @@ static bool dpi_use_dsi_pll(struct omap_dss_device *dssdev)
 		lcd_src = OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC;
 }
 
-static int dpi_set_dsi_clk(struct omap_dss_device *dssdev,
-		unsigned long pck_req, unsigned long *fck, int *lck_div,
-		int *pck_div)
+static int dpi_set_dsi_clk(unsigned long pck_req, unsigned long *fck,
+		int *lck_div, int *pck_div)
 {
 	const struct omapdss_clock_config *clks;
 	struct dsi_clock_info dsi_cinfo;
@@ -111,9 +110,8 @@ static int dpi_set_dsi_clk(struct omap_dss_device *dssdev,
 	return 0;
 }
 
-static int dpi_set_dispc_clk(struct omap_dss_device *dssdev,
-		unsigned long pck_req, unsigned long *fck, int *lck_div,
-		int *pck_div)
+static int dpi_set_dispc_clk(unsigned long pck_req, unsigned long *fck,
+		int *lck_div, int *pck_div)
 {
 	struct dss_clock_info dss_cinfo;
 	struct dispc_clock_info dispc_cinfo;
@@ -145,10 +143,10 @@ static int dpi_set_mode(struct omap_dss_device *dssdev)
 	int r = 0;
 
 	if (dpi_use_dsi_pll(dssdev))
-		r = dpi_set_dsi_clk(dssdev, t->pixel_clock * 1000, &fck,
+		r = dpi_set_dsi_clk(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(t->pixel_clock * 1000, &fck,
 				&lck_div, &pck_div);
 	if (r)
 		return r;
-- 
1.7.9.5


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

* [RFC 03/17] OMAPDSS: HDMI: Remove omap_dss_device argument from hdmi_compute_pll
@ 2012-08-01 10:43   ` Archit Taneja
  0 siblings, 0 replies; 122+ messages in thread
From: Archit Taneja @ 2012-08-01 10:43 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-fbdev, linux-omap, sumit.semwal, rob, Archit Taneja

The clock related info for DSS modules is not tied anymore to a panel's
omap_dss_device struct. It's now passed via platform data. The function
hdmi_compute_pll() do not need the omap_dss_device argument to retieve these
clocks. They use the api dss_get_platform_clock_config() get the clocks. Remove
the omap_dss_device argument from hdmi_compute_pll()

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

diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c
index 16b2386..6635b09 100644
--- a/drivers/video/omap2/dss/hdmi.c
+++ b/drivers/video/omap2/dss/hdmi.c
@@ -405,8 +405,7 @@ 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,
-		struct hdmi_pll_info *pi)
+static void hdmi_compute_pll(int phy, struct hdmi_pll_info *pi)
 {
 	const struct omapdss_clock_config *clks;
 	unsigned long clkin, refclk;
@@ -491,7 +490,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(phy, &hdmi.ip_data.pll_data);
 
 	hdmi.ip_data.ops->video_disable(&hdmi.ip_data);
 
-- 
1.7.9.5


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

* [RFC 04/17] OMAPDSS: DPI: Add locking for DPI interface
@ 2012-08-01 10:43   ` Archit Taneja
  0 siblings, 0 replies; 122+ messages in thread
From: Archit Taneja @ 2012-08-01 10:43 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-fbdev, linux-omap, sumit.semwal, rob, Archit Taneja

The DPI interface driver currently relies on the panel driver to ensure calls
like omapdss_dpi_display_enable() and omapdss_dpi_display_disable() are executed
sequentially. Also, currently, there is no way to protect the DPI driver data.

All DPI panel drivers don't ensure this, and in general, a DPI panel driver
should use it's lock to that ensure it's own driver data and omap_dss_device
states are taken care of, and not worry about the DPI interface.

Add mutex locking in the DPI enable/disable/set_timings ops.

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

diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c
index c20fe23..add47fe 100644
--- a/drivers/video/omap2/dss/dpi.c
+++ b/drivers/video/omap2/dss/dpi.c
@@ -39,6 +39,8 @@ static struct {
 	struct regulator *vdds_dsi_reg;
 	struct platform_device *dsidev;
 
+	struct mutex lock;
+
 	struct dss_lcd_mgr_config mgr_config;
 } dpi;
 
@@ -184,14 +186,18 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
 {
 	int r;
 
+	mutex_lock(&dpi.lock);
+
 	if (cpu_is_omap34xx() && !dpi.vdds_dsi_reg) {
 		DSSERR("no VDSS_DSI regulator\n");
-		return -ENODEV;
+		r = -ENODEV;
+		goto err_no_reg;
 	}
 
 	if (dssdev->manager = NULL) {
 		DSSERR("failed to enable display: no manager\n");
-		return -ENODEV;
+		r = -ENODEV;
+		goto err_no_mgr;
 	}
 
 	if (dpi_use_dsi_pll(dssdev)) {
@@ -238,6 +244,8 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
 	if (r)
 		goto err_mgr_enable;
 
+	mutex_unlock(&dpi.lock);
+
 	return 0;
 
 err_mgr_enable:
@@ -255,12 +263,17 @@ err_get_dispc:
 err_reg_enable:
 	omap_dss_stop_device(dssdev);
 err_start_dev:
+err_no_mgr:
+err_no_reg:
+	mutex_unlock(&dpi.lock);
 	return r;
 }
 EXPORT_SYMBOL(omapdss_dpi_display_enable);
 
 void omapdss_dpi_display_disable(struct omap_dss_device *dssdev)
 {
+	mutex_lock(&dpi.lock);
+
 	dss_mgr_disable(dssdev->manager);
 
 	if (dpi_use_dsi_pll(dssdev)) {
@@ -275,6 +288,8 @@ void omapdss_dpi_display_disable(struct omap_dss_device *dssdev)
 		regulator_disable(dpi.vdds_dsi_reg);
 
 	omap_dss_stop_device(dssdev);
+
+	mutex_unlock(&dpi.lock);
 }
 EXPORT_SYMBOL(omapdss_dpi_display_disable);
 
@@ -284,6 +299,9 @@ void dpi_set_timings(struct omap_dss_device *dssdev,
 	int r;
 
 	DSSDBG("dpi_set_timings\n");
+
+	mutex_lock(&dpi.lock);
+
 	dssdev->panel.timings = *timings;
 	if (dssdev->state = OMAP_DSS_DISPLAY_ACTIVE) {
 		r = dispc_runtime_get();
@@ -296,6 +314,8 @@ void dpi_set_timings(struct omap_dss_device *dssdev,
 	} else {
 		dss_mgr_set_timings(dssdev->manager, timings);
 	}
+
+	mutex_unlock(&dpi.lock);
 }
 EXPORT_SYMBOL(dpi_set_timings);
 
@@ -392,6 +412,8 @@ static void __init dpi_probe_pdata(struct platform_device *pdev)
 
 static int __init omap_dpi_probe(struct platform_device *pdev)
 {
+	mutex_init(&dpi.lock);
+
 	dpi_probe_pdata(pdev);
 
 	return 0;
-- 
1.7.9.5


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

* [RFC 05/17] OMAPDSS: DPI: Maintain our own timings field in driver data
@ 2012-08-01 10:43   ` Archit Taneja
  0 siblings, 0 replies; 122+ messages in thread
From: Archit Taneja @ 2012-08-01 10:43 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-fbdev, linux-omap, sumit.semwal, rob, Archit Taneja

The DPI driver currently relies on the timings in omap_dss_device struct to
configure the DISPC accordingly. This makes the DPI interface driver dependent
on the omap_dss_device struct.

Make the DPI driver data maintain it's own timings field. The panel driver is
expected to call dpi_set_timings()(renamed to omapdss_dpi_set_timings) to set
these timings before the panel is enabled.

In the set_timings() op, we still ensure that the omap_dss_device timings
(dssdev->panel.timings) are configured. This will later be configured only by
the DPI panel drivers.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/displays/panel-generic-dpi.c   |    4 +++-
 .../omap2/displays/panel-lgphilips-lb035q02.c      |    2 ++
 .../omap2/displays/panel-nec-nl8048hl11-01b.c      |    2 ++
 drivers/video/omap2/displays/panel-picodlp.c       |    3 +++
 .../video/omap2/displays/panel-sharp-ls037v7dw01.c |    2 ++
 drivers/video/omap2/displays/panel-tfp410.c        |    4 +++-
 .../video/omap2/displays/panel-tpo-td043mtea1.c    |    4 +++-
 drivers/video/omap2/dss/dpi.c                      |   11 +++++++----
 include/video/omapdss.h                            |    4 ++--
 9 files changed, 27 insertions(+), 9 deletions(-)

diff --git a/drivers/video/omap2/displays/panel-generic-dpi.c b/drivers/video/omap2/displays/panel-generic-dpi.c
index bc5af25..5e70313 100644
--- a/drivers/video/omap2/displays/panel-generic-dpi.c
+++ b/drivers/video/omap2/displays/panel-generic-dpi.c
@@ -563,6 +563,8 @@ static int generic_dpi_panel_power_on(struct omap_dss_device *dssdev)
 	if (dssdev->state = OMAP_DSS_DISPLAY_ACTIVE)
 		return 0;
 
+	omapdss_dpi_set_timings(dssdev, &dssdev->panel.timings);
+
 	r = omapdss_dpi_display_enable(dssdev);
 	if (r)
 		goto err0;
@@ -695,7 +697,7 @@ static int generic_dpi_panel_resume(struct omap_dss_device *dssdev)
 static void generic_dpi_panel_set_timings(struct omap_dss_device *dssdev,
 		struct omap_video_timings *timings)
 {
-	dpi_set_timings(dssdev, timings);
+	omapdss_dpi_set_timings(dssdev, timings);
 }
 
 static int generic_dpi_panel_check_timings(struct omap_dss_device *dssdev,
diff --git a/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c b/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c
index 8028077..7e52aee 100644
--- a/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c
+++ b/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c
@@ -55,6 +55,8 @@ static int lb035q02_panel_power_on(struct omap_dss_device *dssdev)
 	if (dssdev->state = OMAP_DSS_DISPLAY_ACTIVE)
 		return 0;
 
+	omapdss_dpi_set_timings(dssdev, &dssdev->panel.timings);
+
 	r = omapdss_dpi_display_enable(dssdev);
 	if (r)
 		goto err0;
diff --git a/drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c b/drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c
index b122b0f..e501c40 100644
--- a/drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c
+++ b/drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c
@@ -175,6 +175,8 @@ static int nec_8048_panel_power_on(struct omap_dss_device *dssdev)
 	if (dssdev->state = OMAP_DSS_DISPLAY_ACTIVE)
 		return 0;
 
+	omapdss_dpi_set_timings(dssdev, &dssdev->panel.timings);
+
 	r = omapdss_dpi_display_enable(dssdev);
 	if (r)
 		goto err0;
diff --git a/drivers/video/omap2/displays/panel-picodlp.c b/drivers/video/omap2/displays/panel-picodlp.c
index 2d35bd3..0d7a8ff 100644
--- a/drivers/video/omap2/displays/panel-picodlp.c
+++ b/drivers/video/omap2/displays/panel-picodlp.c
@@ -377,6 +377,9 @@ static int picodlp_panel_power_on(struct omap_dss_device *dssdev)
 	 * then only i2c commands can be successfully sent to dpp2600
 	 */
 	msleep(1000);
+
+	omapdss_dpi_set_timings(dssdev, &dssdev->panel.timings);
+
 	r = omapdss_dpi_display_enable(dssdev);
 	if (r) {
 		dev_err(&dssdev->dev, "failed to enable DPI\n");
diff --git a/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c b/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c
index bd86ba9..1486a81 100644
--- a/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c
+++ b/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c
@@ -142,6 +142,8 @@ static int sharp_ls_power_on(struct omap_dss_device *dssdev)
 	if (dssdev->state = OMAP_DSS_DISPLAY_ACTIVE)
 		return 0;
 
+	omapdss_dpi_set_timings(dssdev, &dssdev->panel.timings);
+
 	r = omapdss_dpi_display_enable(dssdev);
 	if (r)
 		goto err0;
diff --git a/drivers/video/omap2/displays/panel-tfp410.c b/drivers/video/omap2/displays/panel-tfp410.c
index 40cc0cfa..c6f9503 100644
--- a/drivers/video/omap2/displays/panel-tfp410.c
+++ b/drivers/video/omap2/displays/panel-tfp410.c
@@ -65,6 +65,8 @@ static int tfp410_power_on(struct omap_dss_device *dssdev)
 	if (dssdev->state = OMAP_DSS_DISPLAY_ACTIVE)
 		return 0;
 
+	omapdss_dpi_set_timings(dssdev, &dssdev->panel.timings);
+
 	r = omapdss_dpi_display_enable(dssdev);
 	if (r)
 		goto err0;
@@ -231,7 +233,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);
-	dpi_set_timings(dssdev, timings);
+	omapdss_dpi_set_timings(dssdev, timings);
 	mutex_unlock(&ddata->lock);
 }
 
diff --git a/drivers/video/omap2/displays/panel-tpo-td043mtea1.c b/drivers/video/omap2/displays/panel-tpo-td043mtea1.c
index fa7baa6..ecb163e 100644
--- a/drivers/video/omap2/displays/panel-tpo-td043mtea1.c
+++ b/drivers/video/omap2/displays/panel-tpo-td043mtea1.c
@@ -337,6 +337,8 @@ static int tpo_td043_enable_dss(struct omap_dss_device *dssdev)
 	if (dssdev->state = OMAP_DSS_DISPLAY_ACTIVE)
 		return 0;
 
+	omapdss_dpi_set_timings(dssdev, &dssdev->panel.timings);
+
 	r = omapdss_dpi_display_enable(dssdev);
 	if (r)
 		goto err0;
@@ -480,7 +482,7 @@ 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)
 {
-	dpi_set_timings(dssdev, timings);
+	omapdss_dpi_set_timings(dssdev, timings);
 }
 
 static int tpo_td043_check_timings(struct omap_dss_device *dssdev,
diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c
index add47fe..96dd1a4 100644
--- a/drivers/video/omap2/dss/dpi.c
+++ b/drivers/video/omap2/dss/dpi.c
@@ -41,6 +41,7 @@ static struct {
 
 	struct mutex lock;
 
+	struct omap_video_timings timings;
 	struct dss_lcd_mgr_config mgr_config;
 } dpi;
 
@@ -138,7 +139,7 @@ static int dpi_set_dispc_clk(unsigned long pck_req, unsigned long *fck,
 
 static int dpi_set_mode(struct omap_dss_device *dssdev)
 {
-	struct omap_video_timings *t = &dssdev->panel.timings;
+	struct omap_video_timings *t = &dpi.timings;
 	int lck_div = 0, pck_div = 0;
 	unsigned long fck = 0;
 	unsigned long pck;
@@ -293,8 +294,8 @@ void omapdss_dpi_display_disable(struct omap_dss_device *dssdev)
 }
 EXPORT_SYMBOL(omapdss_dpi_display_disable);
 
-void dpi_set_timings(struct omap_dss_device *dssdev,
-			struct omap_video_timings *timings)
+void omapdss_dpi_set_timings(struct omap_dss_device *dssdev,
+		struct omap_video_timings *timings)
 {
 	int r;
 
@@ -302,7 +303,9 @@ void dpi_set_timings(struct omap_dss_device *dssdev,
 
 	mutex_lock(&dpi.lock);
 
+	dpi.timings = *timings;
 	dssdev->panel.timings = *timings;
+
 	if (dssdev->state = OMAP_DSS_DISPLAY_ACTIVE) {
 		r = dispc_runtime_get();
 		if (r)
@@ -317,7 +320,7 @@ void dpi_set_timings(struct omap_dss_device *dssdev,
 
 	mutex_unlock(&dpi.lock);
 }
-EXPORT_SYMBOL(dpi_set_timings);
+EXPORT_SYMBOL(omapdss_dpi_set_timings);
 
 int dpi_check_timings(struct omap_dss_device *dssdev,
 			struct omap_video_timings *timings)
diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index 6f7581b..ebf2ebd 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -751,8 +751,8 @@ void omapdss_dsi_display_disable(struct omap_dss_device *dssdev,
 
 int omapdss_dpi_display_enable(struct omap_dss_device *dssdev);
 void omapdss_dpi_display_disable(struct omap_dss_device *dssdev);
-void dpi_set_timings(struct omap_dss_device *dssdev,
-			struct omap_video_timings *timings);
+void omapdss_dpi_set_timings(struct omap_dss_device *dssdev,
+		struct omap_video_timings *timings);
 int dpi_check_timings(struct omap_dss_device *dssdev,
 			struct omap_video_timings *timings);
 
-- 
1.7.9.5


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

* [RFC 06/17] OMAPDSS: DPI displays: Take care of panel timings in the driver itself
@ 2012-08-01 10:43   ` Archit Taneja
  0 siblings, 0 replies; 122+ messages in thread
From: Archit Taneja @ 2012-08-01 10:43 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-fbdev, linux-omap, sumit.semwal, rob, Archit Taneja

The timings maintained in omap_dss_device(dssdev->panel.timings) should be
maintained by the panel driver itself. It's the panel drivers responsibility
to update it if a new set of timings is to be configured. The DPI interface
driver shouldn't be responsible of updating the panel timings, it's responsible
of maintianing it's own copy of timings.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/displays/panel-generic-dpi.c   |    2 ++
 drivers/video/omap2/displays/panel-tfp410.c        |    1 +
 .../video/omap2/displays/panel-tpo-td043mtea1.c    |    2 ++
 drivers/video/omap2/dss/dpi.c                      |    1 -
 4 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/video/omap2/displays/panel-generic-dpi.c b/drivers/video/omap2/displays/panel-generic-dpi.c
index 5e70313..e773594 100644
--- a/drivers/video/omap2/displays/panel-generic-dpi.c
+++ b/drivers/video/omap2/displays/panel-generic-dpi.c
@@ -698,6 +698,8 @@ static void generic_dpi_panel_set_timings(struct omap_dss_device *dssdev,
 		struct omap_video_timings *timings)
 {
 	omapdss_dpi_set_timings(dssdev, timings);
+
+	dssdev->panel.timings = *timings;
 }
 
 static int generic_dpi_panel_check_timings(struct omap_dss_device *dssdev,
diff --git a/drivers/video/omap2/displays/panel-tfp410.c b/drivers/video/omap2/displays/panel-tfp410.c
index c6f9503..9397236 100644
--- a/drivers/video/omap2/displays/panel-tfp410.c
+++ b/drivers/video/omap2/displays/panel-tfp410.c
@@ -234,6 +234,7 @@ static void tfp410_set_timings(struct omap_dss_device *dssdev,
 
 	mutex_lock(&ddata->lock);
 	omapdss_dpi_set_timings(dssdev, timings);
+	dssdev->panel.timings = *timings;
 	mutex_unlock(&ddata->lock);
 }
 
diff --git a/drivers/video/omap2/displays/panel-tpo-td043mtea1.c b/drivers/video/omap2/displays/panel-tpo-td043mtea1.c
index ecb163e..3f47f5f 100644
--- a/drivers/video/omap2/displays/panel-tpo-td043mtea1.c
+++ b/drivers/video/omap2/displays/panel-tpo-td043mtea1.c
@@ -483,6 +483,8 @@ static void tpo_td043_set_timings(struct omap_dss_device *dssdev,
 		struct omap_video_timings *timings)
 {
 	omapdss_dpi_set_timings(dssdev, timings);
+
+	dssdev->panel.timings = *timings;
 }
 
 static int tpo_td043_check_timings(struct omap_dss_device *dssdev,
diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c
index 96dd1a4..6c43d80 100644
--- a/drivers/video/omap2/dss/dpi.c
+++ b/drivers/video/omap2/dss/dpi.c
@@ -304,7 +304,6 @@ void omapdss_dpi_set_timings(struct omap_dss_device *dssdev,
 	mutex_lock(&dpi.lock);
 
 	dpi.timings = *timings;
-	dssdev->panel.timings = *timings;
 
 	if (dssdev->state = OMAP_DSS_DISPLAY_ACTIVE) {
 		r = dispc_runtime_get();
-- 
1.7.9.5


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

* [RFC 07/17] OMAPDSS: Displays: Add locking in generic DPI panel driver
@ 2012-08-01 10:43   ` Archit Taneja
  0 siblings, 0 replies; 122+ messages in thread
From: Archit Taneja @ 2012-08-01 10:43 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-fbdev, linux-omap, sumit.semwal, rob, Archit Taneja

The generic DPI panel driver doesn't currently have locking to ensure that
the display states and the driver data is maintained correctly. Add mutex
locking to take care of this. Add a new get_timings driver op to override the
default get_timings op. The new driver op contains locking to ensure the correct
panel timings are seen when a DSS2 user calls device->driver->get_timings.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/displays/panel-generic-dpi.c |   69 +++++++++++++++++++---
 1 file changed, 62 insertions(+), 7 deletions(-)

diff --git a/drivers/video/omap2/displays/panel-generic-dpi.c b/drivers/video/omap2/displays/panel-generic-dpi.c
index e773594..a07e18c 100644
--- a/drivers/video/omap2/displays/panel-generic-dpi.c
+++ b/drivers/video/omap2/displays/panel-generic-dpi.c
@@ -545,6 +545,8 @@ struct panel_drv_data {
 	struct omap_dss_device *dssdev;
 
 	struct panel_config *panel_config;
+
+	struct mutex lock;
 };
 
 static inline struct panel_generic_dpi_data
@@ -636,6 +638,8 @@ static int generic_dpi_panel_probe(struct omap_dss_device *dssdev)
 	drv_data->dssdev = dssdev;
 	drv_data->panel_config = panel_config;
 
+	mutex_init(&drv_data->lock);
+
 	dev_set_drvdata(&dssdev->dev, drv_data);
 
 	return 0;
@@ -654,58 +658,108 @@ static void __exit generic_dpi_panel_remove(struct omap_dss_device *dssdev)
 
 static int generic_dpi_panel_enable(struct omap_dss_device *dssdev)
 {
-	int r = 0;
+	struct panel_drv_data *drv_data = dev_get_drvdata(&dssdev->dev);
+	int r;
+
+	mutex_lock(&drv_data->lock);
 
 	r = generic_dpi_panel_power_on(dssdev);
 	if (r)
-		return r;
+		goto err;
 
 	dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
+err:
+	mutex_unlock(&drv_data->lock);
 
-	return 0;
+	return r;
 }
 
 static void generic_dpi_panel_disable(struct omap_dss_device *dssdev)
 {
+	struct panel_drv_data *drv_data = dev_get_drvdata(&dssdev->dev);
+
+	mutex_lock(&drv_data->lock);
+
 	generic_dpi_panel_power_off(dssdev);
 
 	dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
+
+	mutex_unlock(&drv_data->lock);
 }
 
 static int generic_dpi_panel_suspend(struct omap_dss_device *dssdev)
 {
+	struct panel_drv_data *drv_data = dev_get_drvdata(&dssdev->dev);
+
+	mutex_lock(&drv_data->lock);
+
 	generic_dpi_panel_power_off(dssdev);
 
 	dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
 
+	mutex_unlock(&drv_data->lock);
+
 	return 0;
 }
 
 static int generic_dpi_panel_resume(struct omap_dss_device *dssdev)
 {
-	int r = 0;
+	struct panel_drv_data *drv_data = dev_get_drvdata(&dssdev->dev);
+	int r;
+
+	mutex_lock(&drv_data->lock);
 
 	r = generic_dpi_panel_power_on(dssdev);
 	if (r)
-		return r;
+		goto err;
 
 	dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
 
-	return 0;
+err:
+	mutex_unlock(&drv_data->lock);
+
+	return r;
 }
 
 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);
+
+	mutex_lock(&drv_data->lock);
+
 	omapdss_dpi_set_timings(dssdev, timings);
 
 	dssdev->panel.timings = *timings;
+
+	mutex_unlock(&drv_data->lock);
+}
+
+static void generic_dpi_panel_get_timings(struct omap_dss_device *dssdev,
+		struct omap_video_timings *timings)
+{
+	struct panel_drv_data *drv_data = dev_get_drvdata(&dssdev->dev);
+
+	mutex_lock(&drv_data->lock);
+
+	*timings = dssdev->panel.timings;
+
+	mutex_unlock(&drv_data->lock);
 }
 
 static int generic_dpi_panel_check_timings(struct omap_dss_device *dssdev,
 		struct omap_video_timings *timings)
 {
-	return dpi_check_timings(dssdev, timings);
+	struct panel_drv_data *drv_data = dev_get_drvdata(&dssdev->dev);
+	int r;
+
+	mutex_lock(&drv_data->lock);
+
+	r = dpi_check_timings(dssdev, timings);
+
+	mutex_unlock(&drv_data->lock);
+
+	return r;
 }
 
 static struct omap_dss_driver dpi_driver = {
@@ -718,6 +772,7 @@ static struct omap_dss_driver dpi_driver = {
 	.resume		= generic_dpi_panel_resume,
 
 	.set_timings	= generic_dpi_panel_set_timings,
+	.get_timings	= generic_dpi_panel_get_timings,
 	.check_timings	= generic_dpi_panel_check_timings,
 
 	.driver         = {
-- 
1.7.9.5


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

* [RFC 08/17] OMAPDSS: DSI: Maintain own copy of timings in driver data
@ 2012-08-01 10:43   ` Archit Taneja
  0 siblings, 0 replies; 122+ messages in thread
From: Archit Taneja @ 2012-08-01 10:43 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-fbdev, linux-omap, sumit.semwal, rob, Archit Taneja

The DSI driver currently relies on the timings in omap_dss_device struct to
configure the DISPC and DSI blocks accordingly. This makes the DSI interface
driver dependent on the omap_dss_device struct.

Make the DPI driver data maintain it's own timings field. The panel driver is
expected to call omapdss_dsi_set_timings() to set these timings before the panel
is enabled.

Signed-off-by: Archit Taneja <archit@ti.com>d
---
 drivers/video/omap2/displays/panel-taal.c |    2 ++
 drivers/video/omap2/dss/dsi.c             |   27 ++++++++++++++++++++++-----
 include/video/omapdss.h                   |    2 ++
 3 files changed, 26 insertions(+), 5 deletions(-)

diff --git a/drivers/video/omap2/displays/panel-taal.c b/drivers/video/omap2/displays/panel-taal.c
index 3f5acc7..4775580 100644
--- a/drivers/video/omap2/displays/panel-taal.c
+++ b/drivers/video/omap2/displays/panel-taal.c
@@ -1060,6 +1060,8 @@ static int taal_power_on(struct omap_dss_device *dssdev)
 		goto err0;
 	};
 
+	omapdss_dsi_set_timings(dssdev, &td->panel_config->timings);
+
 	r = omapdss_dsi_display_enable(dssdev);
 	if (r) {
 		dev_err(&dssdev->dev, "failed to enable DSI\n");
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index 27c27c4..598d965 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -333,6 +333,7 @@ struct dsi_data {
 	unsigned scp_clk_refcount;
 
 	struct dss_lcd_mgr_config mgr_config;
+	struct omap_video_timings timings;
 };
 
 struct dsi_packet_sent_handler_data {
@@ -3607,9 +3608,10 @@ static void dsi_config_vp_num_line_buffers(struct omap_dss_device *dssdev)
 	int num_line_buffers;
 
 	if (dssdev->panel.dsi_mode = OMAP_DSS_DSI_VIDEO_MODE) {
+		struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
 		int bpp = dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt);
 		unsigned line_buf_size = dsi_get_line_buf_size(dsidev);
-		struct omap_video_timings *timings = &dssdev->panel.timings;
+		struct omap_video_timings *timings = &dsi->timings;
 		/*
 		 * Don't use line buffers if width is greater than the video
 		 * port's line buffer size
@@ -3738,7 +3740,7 @@ static void dsi_config_cmd_mode_interleaving(struct omap_dss_device *dssdev)
 	int ddr_clk_pre, ddr_clk_post, enter_hs_mode_lat, exit_hs_mode_lat;
 	int tclk_trail, ths_exit, exiths_clk;
 	bool ddr_alwon;
-	struct omap_video_timings *timings = &dssdev->panel.timings;
+	struct omap_video_timings *timings = &dsi->timings;
 	int bpp = dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt);
 	int ndl = dsi->num_lanes_used - 1;
 	const struct omapdss_clock_config *clks;
@@ -3996,7 +3998,7 @@ static void dsi_proto_timings(struct omap_dss_device *dssdev)
 		int vbp = dssdev->panel.dsi_vm_data.vbp;
 		int window_sync = dssdev->panel.dsi_vm_data.window_sync;
 		bool hsync_end = dssdev->panel.dsi_vm_data.vp_hsync_end;
-		struct omap_video_timings *timings = &dssdev->panel.timings;
+		struct omap_video_timings *timings = &dsi->timings;
 		int bpp = dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt);
 		int tl, t_he, width_bytes;
 
@@ -4105,6 +4107,7 @@ 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 dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
 	int bpp = dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt);
 	u8 data_type;
 	u16 word_count;
@@ -4135,7 +4138,7 @@ int dsi_enable_video_output(struct omap_dss_device *dssdev, int channel)
 		/* MODE, 1 = video mode */
 		REG_FLD_MOD(dsidev, DSI_VC_CTRL(channel), 1, 4, 4);
 
-		word_count = DIV_ROUND_UP(dssdev->panel.timings.x_res * bpp, 8);
+		word_count = DIV_ROUND_UP(dsi->timings.x_res * bpp, 8);
 
 		dsi_vc_write_long_header(dsidev, channel, data_type,
 				word_count, 0);
@@ -4401,7 +4404,7 @@ static int dsi_display_init_dispc(struct omap_dss_device *dssdev)
 		dsi->mgr_config.stallmode = true;
 		dsi->mgr_config.fifohandcheck = true;
 	} else {
-		timings = dssdev->panel.timings;
+		timings = dsi->timings;
 
 		dsi->mgr_config.stallmode = false;
 		dsi->mgr_config.fifohandcheck = false;
@@ -4688,6 +4691,20 @@ 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,
+		struct omap_video_timings *timings)
+{
+	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
+
+	mutex_lock(&dsi->lock);
+
+	dsi->timings = *timings;
+
+	mutex_unlock(&dsi->lock);
+}
+EXPORT_SYMBOL(omapdss_dsi_set_timings);
+
 static int __init dsi_init_display(struct omap_dss_device *dssdev)
 {
 	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index ebf2ebd..a2cd133 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -736,6 +736,8 @@ int omap_dispc_wait_for_irq_interruptible_timeout(u32 irqmask,
 void omapdss_dsi_vc_enable_hs(struct omap_dss_device *dssdev, 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,
+		struct omap_video_timings *timings);
 
 int omap_dsi_update(struct omap_dss_device *dssdev, int channel,
 		void (*callback)(int, void *), void *data);
-- 
1.7.9.5


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

* [RFC 09/17] OMAPDSS: HDMI: Use our own omap_video_timings field when setting interface timings
@ 2012-08-01 10:43   ` Archit Taneja
  0 siblings, 0 replies; 122+ messages in thread
From: Archit Taneja @ 2012-08-01 10:43 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-fbdev, linux-omap, sumit.semwal, rob, Archit Taneja

The hdmi driver currently updates only the 'code' member of hdmi_config when
the op omapdss_hdmi_display_set_timing() is called by the hdmi panel driver.
The 'timing' field of hdmi_config is updated only when hdmi_power_on is called.
It makes more sense to configure the whole hdmi_config field in the set_timing
op called by the panel driver. This way, we don't need to call both functions
to ensure that our hdmi_config is configured correctly. Also, we don't need to
calculate hdmi_config during hdmi_power_on, or rely on the omap_video_timings
in the panel's omap_dss_device struct.

A default timing is now configured in hdmi's probe if the panel driver doesn't
set any timing, or doesn't set a valid timing before enabling the panel. Also,
when setting manager timings, use the omap_video_timing calculated by
hdmi_get_timings(), this returns the timings as specified in the CEA/VESA
tables, don't use the one provided by the panel driver directly.

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

diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index 8a9630b..7e38ffd 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -485,7 +485,8 @@ static inline unsigned long hdmi_get_pixel_clock(void)
 #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);
+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);
diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c
index 6635b09..01665fa 100644
--- a/drivers/video/omap2/dss/hdmi.c
+++ b/drivers/video/omap2/dss/hdmi.c
@@ -462,7 +462,6 @@ static int hdmi_power_on(struct omap_dss_device *dssdev)
 {
 	const struct omapdss_clock_config *clks;
 	int r;
-	const struct hdmi_config *timing;
 	struct omap_video_timings *p;
 	unsigned long phy;
 
@@ -472,22 +471,10 @@ static int hdmi_power_on(struct omap_dss_device *dssdev)
 
 	dss_mgr_disable(dssdev->manager);
 
-	p = &dssdev->panel.timings;
+	p = &hdmi.ip_data.cfg.timings;
 
-	DSSDBG("hdmi_power_on x_res= %d y_res = %d\n",
-		dssdev->panel.timings.x_res,
-		dssdev->panel.timings.y_res);
+	DSSDBG("hdmi_power_on x_res= %d y_res = %d\n", p->x_res, p->y_res);
 
-	timing = hdmi_get_timings();
-	if (timing = NULL) {
-		/* HDMI code 4 corresponds to 640 * 480 VGA */
-		hdmi.ip_data.cfg.cm.code = 4;
-		/* DVI mode 1 corresponds to HDMI 0 to DVI */
-		hdmi.ip_data.cfg.cm.mode = HDMI_DVI;
-		hdmi.ip_data.cfg = vesa_timings[0];
-	} else {
-		hdmi.ip_data.cfg = *timing;
-	}
 	phy = p->pixel_clock;
 
 	hdmi_compute_pll(phy, &hdmi.ip_data.pll_data);
@@ -525,7 +512,7 @@ static int hdmi_power_on(struct omap_dss_device *dssdev)
 	dispc_enable_gamma_table(0);
 
 	/* tv size */
-	dss_mgr_set_timings(dssdev->manager, &dssdev->panel.timings);
+	dss_mgr_set_timings(dssdev->manager, p);
 
 	r = hdmi.ip_data.ops->video_enable(&hdmi.ip_data);
 	if (r)
@@ -571,13 +558,18 @@ 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_device *dssdev,
+		struct omap_video_timings *timings)
 {
 	struct hdmi_cm cm;
+	const struct hdmi_config *timing;
+
+	cm = hdmi_get_code(timings);
+	hdmi.ip_data.cfg.cm = cm;
 
-	cm = hdmi_get_code(&dssdev->panel.timings);
-	hdmi.ip_data.cfg.cm.code = cm.code;
-	hdmi.ip_data.cfg.cm.mode = cm.mode;
+	timing = hdmi_get_timings();
+	if (timing != NULL)
+		hdmi.ip_data.cfg = *timing;
 
 	if (dssdev->state = OMAP_DSS_DISPLAY_ACTIVE) {
 		int r;
@@ -588,7 +580,7 @@ void omapdss_hdmi_display_set_timing(struct omap_dss_device *dssdev)
 		if (r)
 			DSSERR("failed to power on device\n");
 	} else {
-		dss_mgr_set_timings(dssdev->manager, &dssdev->panel.timings);
+		dss_mgr_set_timings(dssdev->manager, &timing->timings);
 	}
 }
 
@@ -933,6 +925,13 @@ static int __init omapdss_hdmihw_probe(struct platform_device *pdev)
 	hdmi.ip_data.core_av_offset = HDMI_CORE_AV;
 	hdmi.ip_data.pll_offset = HDMI_PLLCTRL;
 	hdmi.ip_data.phy_offset = HDMI_PHY;
+
+	/*
+	 * initialize hdmi timings to default value:
+	 * HDMI code 4(VGA) and HDMI mode 1(DVI)
+	 */
+	hdmi.ip_data.cfg = vesa_timings[0];
+
 	mutex_init(&hdmi.ip_data.lock);
 
 	hdmi_panel_init();
diff --git a/drivers/video/omap2/dss/hdmi_panel.c b/drivers/video/omap2/dss/hdmi_panel.c
index e10844f..8dce206 100644
--- a/drivers/video/omap2/dss/hdmi_panel.c
+++ b/drivers/video/omap2/dss/hdmi_panel.c
@@ -336,8 +336,8 @@ static void hdmi_set_timings(struct omap_dss_device *dssdev,
 	 */
 	hdmi_panel_audio_disable(dssdev);
 
+	omapdss_hdmi_display_set_timing(dssdev, timings);
 	dssdev->panel.timings = *timings;
-	omapdss_hdmi_display_set_timing(dssdev);
 
 	mutex_unlock(&hdmi.lock);
 }
-- 
1.7.9.5


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

* [RFC 10/17] OMAPDSS: HDMI: Add a get_timing function for HDMI interface
@ 2012-08-01 10:43   ` Archit Taneja
  0 siblings, 0 replies; 122+ messages in thread
From: Archit Taneja @ 2012-08-01 10:43 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-fbdev, linux-omap, sumit.semwal, rob, Archit Taneja

Add function omapdss_hdmi_display_get_timing() which returns the timings
maintained by the HDMI interface driver in it's hdmi_config field. This
prevents the need for the panel driver to configure default timings in it's
probe.

This function is just intended to be used once during the panel driver's probe.
It makes sense for those interfaces which can be configured to a default timing.

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

diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index 7e38ffd..df49c5d 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -485,6 +485,8 @@ static inline unsigned long hdmi_get_pixel_clock(void)
 #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_get_timing(struct omap_dss_device *dssdev,
+		struct omap_video_timings *timings);
 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,
diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c
index 01665fa..2de1f91 100644
--- a/drivers/video/omap2/dss/hdmi.c
+++ b/drivers/video/omap2/dss/hdmi.c
@@ -544,6 +544,12 @@ static void hdmi_power_off(struct omap_dss_device *dssdev)
 	hdmi_runtime_put();
 }
 
+void omapdss_hdmi_display_get_timing(struct omap_dss_device *dssdev,
+		struct omap_video_timings *timings)
+{
+	*timings = hdmi.ip_data.cfg.timings;
+}
+
 int omapdss_hdmi_display_check_timing(struct omap_dss_device *dssdev,
 					struct omap_video_timings *timings)
 {
diff --git a/drivers/video/omap2/dss/hdmi_panel.c b/drivers/video/omap2/dss/hdmi_panel.c
index 8dce206..8473193 100644
--- a/drivers/video/omap2/dss/hdmi_panel.c
+++ b/drivers/video/omap2/dss/hdmi_panel.c
@@ -41,13 +41,13 @@ static struct {
 
 static int hdmi_panel_probe(struct omap_dss_device *dssdev)
 {
+	struct omap_video_timings timings;
+
 	DSSDBG("ENTER hdmi_panel_probe\n");
 
-	dssdev->panel.timings = (struct omap_video_timings)
-			{ 640, 480, 25175, 96, 16, 48, 2, 11, 31,
-				OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
-				false,
-			};
+	omapdss_hdmi_display_get_timing(dssdev, &timings);
+
+	dssdev->panel.timings = timings;
 
 	DSSDBG("hdmi_panel_probe x_res= %d y_res = %d\n",
 		dssdev->panel.timings.x_res,
-- 
1.7.9.5


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

* [RFC 11/17] OMAPDSS: HDMI: Add locking for hdmi interface get/set timing functions
@ 2012-08-01 10:43   ` Archit Taneja
  0 siblings, 0 replies; 122+ messages in thread
From: Archit Taneja @ 2012-08-01 10:43 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-fbdev, linux-omap, sumit.semwal, rob, Archit Taneja

The hdmi interface driver exposes functions to the hdmi panel driver to
get and configure the interface timings maintained by the hdmi driver.

These timings(stored in hdmi.ip_data.cfg) should be protected by the hdmi lock
to ensure they are called sequentially, this is similar to how hdmi enable and
disable functions need locking.

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

diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c
index 2de1f91..dfd582e 100644
--- a/drivers/video/omap2/dss/hdmi.c
+++ b/drivers/video/omap2/dss/hdmi.c
@@ -547,7 +547,11 @@ static void hdmi_power_off(struct omap_dss_device *dssdev)
 void omapdss_hdmi_display_get_timing(struct omap_dss_device *dssdev,
 		struct omap_video_timings *timings)
 {
+	mutex_lock(&hdmi.lock);
+
 	*timings = hdmi.ip_data.cfg.timings;
+
+	mutex_unlock(&hdmi.lock);
 }
 
 int omapdss_hdmi_display_check_timing(struct omap_dss_device *dssdev,
@@ -570,6 +574,8 @@ void omapdss_hdmi_display_set_timing(struct omap_dss_device *dssdev,
 	struct hdmi_cm cm;
 	const struct hdmi_config *timing;
 
+	mutex_lock(&hdmi.lock);
+
 	cm = hdmi_get_code(timings);
 	hdmi.ip_data.cfg.cm = cm;
 
@@ -588,6 +594,8 @@ void omapdss_hdmi_display_set_timing(struct omap_dss_device *dssdev,
 	} else {
 		dss_mgr_set_timings(dssdev->manager, &timing->timings);
 	}
+
+	mutex_unlock(&hdmi.lock);
 }
 
 static void hdmi_dump_regs(struct seq_file *s)
-- 
1.7.9.5


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

* [RFC 12/17] OMAPDSS: SDI: Create a separate function for timing/clock configurations
@ 2012-08-01 10:43   ` Archit Taneja
  0 siblings, 0 replies; 122+ messages in thread
From: Archit Taneja @ 2012-08-01 10:43 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-fbdev, linux-omap, sumit.semwal, rob, Archit Taneja

Create a function sdi_set_mode() which configures the DISPC and DSS(PRCM)
clocks to get the required pixel clock, and configure the manager timings.
This is similar to what's done in the DPI driver in dpi_set_mode().

This makes the code a bit cleaner to read, and makes it easier to reconfigure
timings instead of switching off the whole interface, and then enabling the
interface with the new timings.

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

diff --git a/drivers/video/omap2/dss/sdi.c b/drivers/video/omap2/dss/sdi.c
index 5d31699..f2d3f45 100644
--- a/drivers/video/omap2/dss/sdi.c
+++ b/drivers/video/omap2/dss/sdi.c
@@ -49,40 +49,21 @@ static void sdi_config_lcd_manager(struct omap_dss_device *dssdev)
 	dss_mgr_set_lcd_config(dssdev->manager, &sdi.mgr_config);
 }
 
-int omapdss_sdi_display_enable(struct omap_dss_device *dssdev)
+static int sdi_set_mode(struct omap_dss_device *dssdev)
 {
+	int r;
 	struct omap_video_timings *t = &dssdev->panel.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");
-		return -ENODEV;
-	}
-
-	r = omap_dss_start_device(dssdev);
-	if (r) {
-		DSSERR("failed to start device\n");
-		goto err_start_dev;
-	}
-
-	r = regulator_enable(sdi.vdds_sdi_reg);
-	if (r)
-		goto err_reg_enable;
-
-	r = dispc_runtime_get();
-	if (r)
-		goto err_get_dispc;
 
 	/* 15.5.9.1.2 */
-	dssdev->panel.timings.data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE;
-	dssdev->panel.timings.sync_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE;
+	t->data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE;
+	t->sync_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE;
 
 	r = dss_calc_clock_div(t->pixel_clock * 1000, &dss_cinfo, &dispc_cinfo);
 	if (r)
-		goto err_calc_clock_div;
+		return r;
 
 	sdi.mgr_config.clock_info = dispc_cinfo;
 
@@ -96,12 +77,41 @@ int omapdss_sdi_display_enable(struct omap_dss_device *dssdev)
 		t->pixel_clock = pck;
 	}
 
-
 	dss_mgr_set_timings(dssdev->manager, t);
 
 	r = dss_set_clock_div(&dss_cinfo);
 	if (r)
-		goto err_set_dss_clock_div;
+		return r;
+
+	return 0;
+}
+
+int omapdss_sdi_display_enable(struct omap_dss_device *dssdev)
+{
+	int r;
+
+	if (dssdev->manager = NULL) {
+		DSSERR("failed to enable display: no manager\n");
+		return -ENODEV;
+	}
+
+	r = omap_dss_start_device(dssdev);
+	if (r) {
+		DSSERR("failed to start device\n");
+		goto err_start_dev;
+	}
+
+	r = regulator_enable(sdi.vdds_sdi_reg);
+	if (r)
+		goto err_reg_enable;
+
+	r = dispc_runtime_get();
+	if (r)
+		goto err_get_dispc;
+
+	r = sdi_set_mode(dssdev);
+	if (r)
+		goto err_set_mode;
 
 	sdi_config_lcd_manager(dssdev);
 
@@ -120,8 +130,7 @@ int omapdss_sdi_display_enable(struct omap_dss_device *dssdev)
 err_mgr_enable:
 	dss_sdi_disable();
 err_sdi_enable:
-err_set_dss_clock_div:
-err_calc_clock_div:
+err_set_mode:
 	dispc_runtime_put();
 err_get_dispc:
 	regulator_disable(sdi.vdds_sdi_reg);
-- 
1.7.9.5


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

* [RFC 13/17] OMAPDSS: SDI: Create a function to set timings
@ 2012-08-01 10:43   ` Archit Taneja
  0 siblings, 0 replies; 122+ messages in thread
From: Archit Taneja @ 2012-08-01 10:43 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-fbdev, linux-omap, sumit.semwal, rob, Archit Taneja

Create function omapdss_sdi_set_timings(), this can be used by a SDI panel
driver without disabling/enabling the SDI interface. This is similar to the
set_timings op of the DPI interface driver. It calls sdi_set_mode() which only
configures the DISPC timings and DSS/DISPC clock dividers.

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

diff --git a/drivers/video/omap2/displays/panel-acx565akm.c b/drivers/video/omap2/displays/panel-acx565akm.c
index eaeed43..11bdc88 100644
--- a/drivers/video/omap2/displays/panel-acx565akm.c
+++ b/drivers/video/omap2/displays/panel-acx565akm.c
@@ -731,18 +731,7 @@ 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)
 {
-	int r;
-
-	if (dssdev->state = OMAP_DSS_DISPLAY_ACTIVE)
-		omapdss_sdi_display_disable(dssdev);
-
-	dssdev->panel.timings = *timings;
-
-	if (dssdev->state = OMAP_DSS_DISPLAY_ACTIVE) {
-		r = omapdss_sdi_display_enable(dssdev);
-		if (r)
-			dev_err(&dssdev->dev, "%s enable failed\n", __func__);
-	}
+	omapdss_sdi_set_timings(dssdev, timings);
 }
 
 static int acx_panel_check_timings(struct omap_dss_device *dssdev,
diff --git a/drivers/video/omap2/dss/sdi.c b/drivers/video/omap2/dss/sdi.c
index f2d3f45..d88243f 100644
--- a/drivers/video/omap2/dss/sdi.c
+++ b/drivers/video/omap2/dss/sdi.c
@@ -155,6 +155,25 @@ void omapdss_sdi_display_disable(struct omap_dss_device *dssdev)
 }
 EXPORT_SYMBOL(omapdss_sdi_display_disable);
 
+void omapdss_sdi_set_timings(struct omap_dss_device *dssdev,
+		struct omap_video_timings *timings)
+{
+	int r;
+
+	dssdev->panel.timings = *timings;
+
+	if (dssdev->state = OMAP_DSS_DISPLAY_ACTIVE) {
+		r = dispc_runtime_get();
+		if (r)
+			return;
+
+		sdi_set_mode(dssdev);
+
+		dispc_runtime_put();
+	}
+}
+EXPORT_SYMBOL(omapdss_sdi_set_timings);
+
 static int __init sdi_init_display(struct omap_dss_device *dssdev)
 {
 	DSSDBG("SDI init\n");
diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index a2cd133..54ba639 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -760,6 +760,8 @@ int dpi_check_timings(struct omap_dss_device *dssdev,
 
 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,
+		struct omap_video_timings *timings);
 
 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] 122+ messages in thread

* [RFC 14/17] OMAPDSS: SDI: Maintain our own timings field in driver data
@ 2012-08-01 10:43   ` Archit Taneja
  0 siblings, 0 replies; 122+ messages in thread
From: Archit Taneja @ 2012-08-01 10:43 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-fbdev, linux-omap, sumit.semwal, rob, Archit Taneja

The SDI driver currently relies on the timings in omap_dss_device struct to
configure the DISPC accordingly. This makes the SDI interface driver dependent
on the omap_dss_device struct.

Make the SDI driver data maintain it's own timings field. The panel driver is
expected to call omapdss_sdi_set_timings() to set these timings before the panel
is enabled.

Make the SDI panel driver configure the new timings is the omap_dss_device
struct(dssdev->panel.timings). The SDI driver is responsible for maintaining
only it's own copy of timings.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/displays/panel-acx565akm.c |    4 ++++
 drivers/video/omap2/dss/sdi.c                  |    5 +++--
 2 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/video/omap2/displays/panel-acx565akm.c b/drivers/video/omap2/displays/panel-acx565akm.c
index 11bdc88..77fe59f 100644
--- a/drivers/video/omap2/displays/panel-acx565akm.c
+++ b/drivers/video/omap2/displays/panel-acx565akm.c
@@ -600,6 +600,8 @@ static int acx_panel_power_on(struct omap_dss_device *dssdev)
 
 	mutex_lock(&md->mutex);
 
+	omapdss_sdi_set_timings(dssdev, &dssdev->panel.timings);
+
 	r = omapdss_sdi_display_enable(dssdev);
 	if (r) {
 		pr_err("%s sdi enable failed\n", __func__);
@@ -732,6 +734,8 @@ static void acx_panel_set_timings(struct omap_dss_device *dssdev,
 		struct omap_video_timings *timings)
 {
 	omapdss_sdi_set_timings(dssdev, timings);
+
+	dssdev->panel.timings = *timings;
 }
 
 static int acx_panel_check_timings(struct omap_dss_device *dssdev,
diff --git a/drivers/video/omap2/dss/sdi.c b/drivers/video/omap2/dss/sdi.c
index d88243f..917816d 100644
--- a/drivers/video/omap2/dss/sdi.c
+++ b/drivers/video/omap2/dss/sdi.c
@@ -34,6 +34,7 @@ static struct {
 	struct regulator *vdds_sdi_reg;
 
 	struct dss_lcd_mgr_config mgr_config;
+	struct omap_video_timings timings;
 } sdi;
 
 static void sdi_config_lcd_manager(struct omap_dss_device *dssdev)
@@ -52,7 +53,7 @@ static void sdi_config_lcd_manager(struct omap_dss_device *dssdev)
 static int sdi_set_mode(struct omap_dss_device *dssdev)
 {
 	int r;
-	struct omap_video_timings *t = &dssdev->panel.timings;
+	struct omap_video_timings *t = &sdi.timings;
 	struct dss_clock_info dss_cinfo;
 	struct dispc_clock_info dispc_cinfo;
 	unsigned long pck;
@@ -160,7 +161,7 @@ void omapdss_sdi_set_timings(struct omap_dss_device *dssdev,
 {
 	int r;
 
-	dssdev->panel.timings = *timings;
+	sdi.timings = *timings;
 
 	if (dssdev->state = OMAP_DSS_DISPLAY_ACTIVE) {
 		r = dispc_runtime_get();
-- 
1.7.9.5


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

* [RFC 15/17] OMAPDSS: VENC: Split VENC into interface and panel driver
@ 2012-08-01 10:43   ` Archit Taneja
  0 siblings, 0 replies; 122+ messages in thread
From: Archit Taneja @ 2012-08-01 10:43 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-fbdev, linux-omap, sumit.semwal, rob, Archit Taneja

The current venc.c driver contains both the interface and panel driver code.
This makes the driver hard to read, and difficult to understand the work split
between the interface and panel driver and the how the locking works.

This also makes it easier to clearly define the VENC interface ops called by the
panel driver.

Split venc.c into venc.c and venc_panel.c representing the interface and panel
driver respectively. This split is done along the lines of the HDMI interface
and panel drivers.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/dss/Makefile     |    2 +-
 drivers/video/omap2/dss/dss.h        |   10 ++
 drivers/video/omap2/dss/venc.c       |  208 ++++++++----------------------
 drivers/video/omap2/dss/venc_panel.c |  231 ++++++++++++++++++++++++++++++++++
 4 files changed, 295 insertions(+), 156 deletions(-)
 create mode 100644 drivers/video/omap2/dss/venc_panel.c

diff --git a/drivers/video/omap2/dss/Makefile b/drivers/video/omap2/dss/Makefile
index 5c450b0..30a48fb 100644
--- a/drivers/video/omap2/dss/Makefile
+++ b/drivers/video/omap2/dss/Makefile
@@ -3,7 +3,7 @@ omapdss-y := core.o dss.o dss_features.o dispc.o dispc_coefs.o display.o \
 	manager.o overlay.o apply.o
 omapdss-$(CONFIG_OMAP2_DSS_DPI) += dpi.o
 omapdss-$(CONFIG_OMAP2_DSS_RFBI) += rfbi.o
-omapdss-$(CONFIG_OMAP2_DSS_VENC) += venc.o
+omapdss-$(CONFIG_OMAP2_DSS_VENC) += venc.o venc_panel.o
 omapdss-$(CONFIG_OMAP2_DSS_SDI) += sdi.o
 omapdss-$(CONFIG_OMAP2_DSS_DSI) += dsi.o
 omapdss-$(CONFIG_OMAP4_DSS_HDMI) += hdmi.o \
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index df49c5d..69b6ab9 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -470,6 +470,16 @@ 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,
+		struct omap_video_timings *timings);
+int omapdss_venc_check_timings(struct omap_dss_device *dssdev,
+		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);
+int venc_panel_init(void);
+void venc_panel_exit(void);
 
 /* HDMI */
 #ifdef CONFIG_OMAP4_DSS_HDMI
diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c
index 3a22087..ffca542 100644
--- a/drivers/video/omap2/dss/venc.c
+++ b/drivers/video/omap2/dss/venc.c
@@ -427,6 +427,10 @@ static int venc_power_on(struct omap_dss_device *dssdev)
 	u32 l;
 	int r;
 
+	r = venc_runtime_get();
+	if (r)
+		goto err0;
+
 	venc_reset();
 	venc_write_config(venc_timings_to_config(&dssdev->panel.timings));
 
@@ -449,26 +453,22 @@ static int venc_power_on(struct omap_dss_device *dssdev)
 
 	r = regulator_enable(venc.vdda_dac_reg);
 	if (r)
-		goto err;
-
-	if (dssdev->platform_enable)
-		dssdev->platform_enable(dssdev);
+		goto err1;
 
 	r = dss_mgr_enable(dssdev->manager);
 	if (r)
-		goto err;
+		goto err2;
 
 	return 0;
 
-err:
+err2:
+	regulator_disable(venc.vdda_dac_reg);
+err1:
 	venc_write_reg(VENC_OUTPUT_CONTROL, 0);
 	dss_set_dac_pwrdn_bgz(0);
 
-	if (dssdev->platform_disable)
-		dssdev->platform_disable(dssdev);
-
-	regulator_disable(venc.vdda_dac_reg);
-
+	venc_runtime_put();
+err0:
 	return r;
 }
 
@@ -479,10 +479,9 @@ static void venc_power_off(struct omap_dss_device *dssdev)
 
 	dss_mgr_disable(dssdev->manager);
 
-	if (dssdev->platform_disable)
-		dssdev->platform_disable(dssdev);
-
 	regulator_disable(venc.vdda_dac_reg);
+
+	venc_runtime_put();
 }
 
 unsigned long venc_get_pixel_clock(void)
@@ -491,171 +490,95 @@ unsigned long venc_get_pixel_clock(void)
 	return 13500000;
 }
 
-static ssize_t display_output_type_show(struct device *dev,
-		struct device_attribute *attr, char *buf)
+int omapdss_venc_display_enable(struct omap_dss_device *dssdev)
 {
-	struct omap_dss_device *dssdev = to_dss_device(dev);
-	const char *ret;
-
-	switch (dssdev->phy.venc.type) {
-	case OMAP_DSS_VENC_TYPE_COMPOSITE:
-		ret = "composite";
-		break;
-	case OMAP_DSS_VENC_TYPE_SVIDEO:
-		ret = "svideo";
-		break;
-	default:
-		return -EINVAL;
-	}
+	int r;
 
-	return snprintf(buf, PAGE_SIZE, "%s\n", ret);
-}
-
-static ssize_t display_output_type_store(struct device *dev,
-		struct device_attribute *attr, const char *buf, size_t size)
-{
-	struct omap_dss_device *dssdev = to_dss_device(dev);
-	enum omap_dss_venc_type new_type;
-
-	if (sysfs_streq("composite", buf))
-		new_type = OMAP_DSS_VENC_TYPE_COMPOSITE;
-	else if (sysfs_streq("svideo", buf))
-		new_type = OMAP_DSS_VENC_TYPE_SVIDEO;
-	else
-		return -EINVAL;
+	DSSDBG("venc_display_enable\n");
 
 	mutex_lock(&venc.venc_lock);
 
-	if (dssdev->phy.venc.type != new_type) {
-		dssdev->phy.venc.type = new_type;
-		if (dssdev->state = OMAP_DSS_DISPLAY_ACTIVE) {
-			venc_power_off(dssdev);
-			venc_power_on(dssdev);
-		}
+	if (dssdev->manager = NULL) {
+		DSSERR("Failed to enable display: no manager\n");
+		r = -ENODEV;
+		goto err0;
 	}
 
-	mutex_unlock(&venc.venc_lock);
-
-	return size;
-}
-
-static DEVICE_ATTR(output_type, S_IRUGO | S_IWUSR,
-		display_output_type_show, display_output_type_store);
-
-/* driver */
-static int venc_panel_probe(struct omap_dss_device *dssdev)
-{
-	dssdev->panel.timings = omap_dss_pal_timings;
-
-	return device_create_file(&dssdev->dev, &dev_attr_output_type);
-}
-
-static void venc_panel_remove(struct omap_dss_device *dssdev)
-{
-	device_remove_file(&dssdev->dev, &dev_attr_output_type);
-}
-
-static int venc_panel_enable(struct omap_dss_device *dssdev)
-{
-	int r = 0;
-
-	DSSDBG("venc_enable_display\n");
-
-	mutex_lock(&venc.venc_lock);
-
 	r = omap_dss_start_device(dssdev);
 	if (r) {
 		DSSERR("failed to start device\n");
 		goto err0;
 	}
 
-	if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) {
-		r = -EINVAL;
-		goto err1;
-	}
+	if (dssdev->platform_enable)
+		dssdev->platform_enable(dssdev);
 
-	r = venc_runtime_get();
-	if (r)
-		goto err1;
 
 	r = venc_power_on(dssdev);
 	if (r)
-		goto err2;
+		goto err1;
 
 	venc.wss_data = 0;
 
-	dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
-
 	mutex_unlock(&venc.venc_lock);
+
 	return 0;
-err2:
-	venc_runtime_put();
 err1:
+	if (dssdev->platform_disable)
+		dssdev->platform_disable(dssdev);
 	omap_dss_stop_device(dssdev);
 err0:
 	mutex_unlock(&venc.venc_lock);
-
 	return r;
 }
 
-static void venc_panel_disable(struct omap_dss_device *dssdev)
+void omapdss_venc_display_disable(struct omap_dss_device *dssdev)
 {
-	DSSDBG("venc_disable_display\n");
+	DSSDBG("venc_display_disable\n");
 
 	mutex_lock(&venc.venc_lock);
 
-	if (dssdev->state = OMAP_DSS_DISPLAY_DISABLED)
-		goto end;
-
-	if (dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED) {
-		/* suspended is the same as disabled with venc */
-		dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
-		goto end;
-	}
-
 	venc_power_off(dssdev);
 
-	venc_runtime_put();
-
-	dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
-
 	omap_dss_stop_device(dssdev);
-end:
-	mutex_unlock(&venc.venc_lock);
-}
 
-static int venc_panel_suspend(struct omap_dss_device *dssdev)
-{
-	venc_panel_disable(dssdev);
-	return 0;
-}
+	if (dssdev->platform_disable)
+		dssdev->platform_disable(dssdev);
 
-static int venc_panel_resume(struct omap_dss_device *dssdev)
-{
-	return venc_panel_enable(dssdev);
+	mutex_unlock(&venc.venc_lock);
 }
 
-static void venc_set_timings(struct omap_dss_device *dssdev,
-			struct omap_video_timings *timings)
+void omapdss_venc_set_timings(struct omap_dss_device *dssdev,
+		struct omap_video_timings *timings)
 {
 	DSSDBG("venc_set_timings\n");
 
+	mutex_lock(&venc.venc_lock);
+
 	/* Reset WSS data when the TV standard changes. */
 	if (memcmp(&dssdev->panel.timings, timings, sizeof(*timings)))
 		venc.wss_data = 0;
 
 	dssdev->panel.timings = *timings;
+
 	if (dssdev->state = OMAP_DSS_DISPLAY_ACTIVE) {
+		int r;
+
 		/* turn the venc off and on to get new timings to use */
-		venc_panel_disable(dssdev);
-		venc_panel_enable(dssdev);
+		venc_power_off(dssdev);
+
+		r = venc_power_on(dssdev);
+		if (r)
+			DSSERR("failed to power on VENC\n");
 	} else {
 		dss_mgr_set_timings(dssdev->manager, timings);
 	}
+
+	mutex_unlock(&venc.venc_lock);
 }
 
-static int venc_check_timings(struct omap_dss_device *dssdev,
-			struct omap_video_timings *timings)
+int omapdss_venc_check_timings(struct omap_dss_device *dssdev,
+		struct omap_video_timings *timings)
 {
 	DSSDBG("venc_check_timings\n");
 
@@ -668,13 +591,13 @@ static int venc_check_timings(struct omap_dss_device *dssdev,
 	return -EINVAL;
 }
 
-static u32 venc_get_wss(struct omap_dss_device *dssdev)
+u32 omapdss_venc_get_wss(struct omap_dss_device *dssdev)
 {
 	/* Invert due to VENC_L21_WC_CTL:INV=1 */
 	return (venc.wss_data >> 8) ^ 0xfffff;
 }
 
-static int venc_set_wss(struct omap_dss_device *dssdev,	u32 wss)
+int omapdss_venc_set_wss(struct omap_dss_device *dssdev, u32 wss)
 {
 	const struct venc_config *config;
 	int r;
@@ -703,31 +626,6 @@ err:
 	return r;
 }
 
-static struct omap_dss_driver venc_driver = {
-	.probe		= venc_panel_probe,
-	.remove		= venc_panel_remove,
-
-	.enable		= venc_panel_enable,
-	.disable	= venc_panel_disable,
-	.suspend	= venc_panel_suspend,
-	.resume		= venc_panel_resume,
-
-	.get_resolution	= omapdss_default_get_resolution,
-	.get_recommended_bpp = omapdss_default_get_recommended_bpp,
-
-	.set_timings	= venc_set_timings,
-	.check_timings	= venc_check_timings,
-
-	.get_wss	= venc_get_wss,
-	.set_wss	= venc_set_wss,
-
-	.driver         = {
-		.name   = "venc",
-		.owner  = THIS_MODULE,
-	},
-};
-/* driver end */
-
 static int __init venc_init_display(struct omap_dss_device *dssdev)
 {
 	DSSDBG("init_display\n");
@@ -897,9 +795,9 @@ static int __init omap_venchw_probe(struct platform_device *pdev)
 
 	venc_runtime_put();
 
-	r = omap_dss_register_driver(&venc_driver);
+	r = venc_panel_init();
 	if (r)
-		goto err_reg_panel_driver;
+		goto err_panel_init;
 
 	dss_debugfs_create_file("venc", venc_dump_regs);
 
@@ -907,7 +805,7 @@ static int __init omap_venchw_probe(struct platform_device *pdev)
 
 	return 0;
 
-err_reg_panel_driver:
+err_panel_init:
 err_runtime_get:
 	pm_runtime_disable(&pdev->dev);
 	venc_put_clocks();
@@ -923,7 +821,7 @@ static int __exit omap_venchw_remove(struct platform_device *pdev)
 		venc.vdda_dac_reg = NULL;
 	}
 
-	omap_dss_unregister_driver(&venc_driver);
+	venc_panel_exit();
 
 	pm_runtime_disable(&pdev->dev);
 	venc_put_clocks();
diff --git a/drivers/video/omap2/dss/venc_panel.c b/drivers/video/omap2/dss/venc_panel.c
new file mode 100644
index 0000000..6b31298
--- /dev/null
+++ b/drivers/video/omap2/dss/venc_panel.c
@@ -0,0 +1,231 @@
+/*
+ * Copyright (C) 2009 Nokia Corporation
+ * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
+ *
+ * VENC panel driver
+ *
+ * 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/err.h>
+#include <linux/io.h>
+#include <linux/mutex.h>
+#include <linux/module.h>
+
+#include <video/omapdss.h>
+
+#include "dss.h"
+
+static struct {
+	struct mutex lock;
+} venc_panel;
+
+static ssize_t display_output_type_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct omap_dss_device *dssdev = to_dss_device(dev);
+	const char *ret;
+
+	switch (dssdev->phy.venc.type) {
+	case OMAP_DSS_VENC_TYPE_COMPOSITE:
+		ret = "composite";
+		break;
+	case OMAP_DSS_VENC_TYPE_SVIDEO:
+		ret = "svideo";
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return snprintf(buf, PAGE_SIZE, "%s\n", ret);
+}
+
+static ssize_t display_output_type_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t size)
+{
+	struct omap_dss_device *dssdev = to_dss_device(dev);
+	enum omap_dss_venc_type new_type;
+
+	if (sysfs_streq("composite", buf))
+		new_type = OMAP_DSS_VENC_TYPE_COMPOSITE;
+	else if (sysfs_streq("svideo", buf))
+		new_type = OMAP_DSS_VENC_TYPE_SVIDEO;
+	else
+		return -EINVAL;
+
+	mutex_lock(&venc_panel.lock);
+
+	if (dssdev->phy.venc.type != new_type) {
+		dssdev->phy.venc.type = new_type;
+		if (dssdev->state = OMAP_DSS_DISPLAY_ACTIVE) {
+			omapdss_venc_display_disable(dssdev);
+			omapdss_venc_display_enable(dssdev);
+		}
+	}
+
+	mutex_unlock(&venc_panel.lock);
+
+	return size;
+}
+
+static DEVICE_ATTR(output_type, S_IRUGO | S_IWUSR,
+		display_output_type_show, display_output_type_store);
+
+static int venc_panel_probe(struct omap_dss_device *dssdev)
+{
+	mutex_init(&venc_panel.lock);
+
+	/* set initial timings to PAL */
+	dssdev->panel.timings = (struct omap_video_timings)
+		{ 720, 574, 13500, 64, 12, 68, 5, 5, 41,
+			OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
+			true,
+		};
+
+	return device_create_file(&dssdev->dev, &dev_attr_output_type);
+}
+
+static void venc_panel_remove(struct omap_dss_device *dssdev)
+{
+	device_remove_file(&dssdev->dev, &dev_attr_output_type);
+}
+
+static int venc_panel_enable(struct omap_dss_device *dssdev)
+{
+	int r;
+
+	dev_dbg(&dssdev->dev, "venc_panel_enable\n");
+
+	mutex_lock(&venc_panel.lock);
+
+	if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) {
+		r = -EINVAL;
+		goto err;
+	}
+
+	r = omapdss_venc_display_enable(dssdev);
+	if (r)
+		goto err;
+
+	dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
+
+	mutex_unlock(&venc_panel.lock);
+
+	return 0;
+err:
+	mutex_unlock(&venc_panel.lock);
+
+	return r;
+}
+
+static void venc_panel_disable(struct omap_dss_device *dssdev)
+{
+	dev_dbg(&dssdev->dev, "venc_panel_disable\n");
+
+	mutex_lock(&venc_panel.lock);
+
+	if (dssdev->state = OMAP_DSS_DISPLAY_DISABLED)
+		goto end;
+
+	if (dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED) {
+		/* suspended is the same as disabled with venc */
+		dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
+		goto end;
+	}
+
+	omapdss_venc_display_disable(dssdev);
+
+	dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
+end:
+	mutex_unlock(&venc_panel.lock);
+}
+
+static int venc_panel_suspend(struct omap_dss_device *dssdev)
+{
+	venc_panel_disable(dssdev);
+	return 0;
+}
+
+static int venc_panel_resume(struct omap_dss_device *dssdev)
+{
+	return venc_panel_enable(dssdev);
+}
+
+static void venc_panel_set_timings(struct omap_dss_device *dssdev,
+		struct omap_video_timings *timings)
+{
+	dev_dbg(&dssdev->dev, "venc_panel_set_timings\n");
+
+	mutex_lock(&venc_panel.lock);
+
+	omapdss_venc_set_timings(dssdev, timings);
+
+	mutex_unlock(&venc_panel.lock);
+}
+
+static int venc_panel_check_timings(struct omap_dss_device *dssdev,
+		struct omap_video_timings *timings)
+{
+	dev_dbg(&dssdev->dev, "venc_panel_check_timings\n");
+
+	return omapdss_venc_check_timings(dssdev, timings);
+}
+
+static u32 venc_panel_get_wss(struct omap_dss_device *dssdev)
+{
+	dev_dbg(&dssdev->dev, "venc_panel_get_wss\n");
+
+	return omapdss_venc_get_wss(dssdev);
+}
+
+static int venc_panel_set_wss(struct omap_dss_device *dssdev, u32 wss)
+{
+	dev_dbg(&dssdev->dev, "venc_panel_set_wss\n");
+
+	return omapdss_venc_set_wss(dssdev, wss);
+}
+
+static struct omap_dss_driver venc_driver = {
+	.probe		= venc_panel_probe,
+	.remove		= venc_panel_remove,
+
+	.enable		= venc_panel_enable,
+	.disable	= venc_panel_disable,
+	.suspend	= venc_panel_suspend,
+	.resume		= venc_panel_resume,
+
+	.get_resolution	= omapdss_default_get_resolution,
+	.get_recommended_bpp = omapdss_default_get_recommended_bpp,
+
+	.set_timings	= venc_panel_set_timings,
+	.check_timings	= venc_panel_check_timings,
+
+	.get_wss	= venc_panel_get_wss,
+	.set_wss	= venc_panel_set_wss,
+
+	.driver         = {
+		.name   = "venc",
+		.owner  = THIS_MODULE,
+	},
+};
+
+int venc_panel_init(void)
+{
+	return omap_dss_register_driver(&venc_driver);
+}
+
+void venc_panel_exit(void)
+{
+	omap_dss_unregister_driver(&venc_driver);
+}
-- 
1.7.9.5


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

* [RFC 16/17] OMAPDSS: VENC: Maintain our own timings field in driver data
@ 2012-08-01 10:43   ` Archit Taneja
  0 siblings, 0 replies; 122+ messages in thread
From: Archit Taneja @ 2012-08-01 10:43 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-fbdev, linux-omap, sumit.semwal, rob, Archit Taneja

The VENC driver currently relies on the timings in omap_dss_device struct to
configure the DISPC and VENC blocks accordingly. This makes the VENC interface
driver dependent on the omap_dss_device struct.

Make the VENC driver data maintain it's own timings field. The panel driver is
expected to call omapdss_venc_set_timings() to set these timings before the
panel is enabled.

Make the VENC panel driver configure the new timings is the omap_dss_device
struct(dssdev->panel.timings). The VENC driver is responsible for maintaining
only it's own copy of timings.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/dss/venc.c       |   12 +++++++-----
 drivers/video/omap2/dss/venc_panel.c |    1 +
 2 files changed, 8 insertions(+), 5 deletions(-)

diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c
index ffca542..d96025e 100644
--- a/drivers/video/omap2/dss/venc.c
+++ b/drivers/video/omap2/dss/venc.c
@@ -300,6 +300,8 @@ static struct {
 	struct regulator *vdda_dac_reg;
 
 	struct clk	*tv_dac_clk;
+
+	struct omap_video_timings timings;
 } venc;
 
 static inline void venc_write_reg(int idx, u32 val)
@@ -432,7 +434,7 @@ static int venc_power_on(struct omap_dss_device *dssdev)
 		goto err0;
 
 	venc_reset();
-	venc_write_config(venc_timings_to_config(&dssdev->panel.timings));
+	venc_write_config(venc_timings_to_config(&venc.timings));
 
 	dss_set_venc_output(dssdev->phy.venc.type);
 	dss_set_dac_pwrdn_bgz(1);
@@ -449,7 +451,7 @@ static int venc_power_on(struct omap_dss_device *dssdev)
 
 	venc_write_reg(VENC_OUTPUT_CONTROL, l);
 
-	dss_mgr_set_timings(dssdev->manager, &dssdev->panel.timings);
+	dss_mgr_set_timings(dssdev->manager, &venc.timings);
 
 	r = regulator_enable(venc.vdda_dac_reg);
 	if (r)
@@ -556,10 +558,10 @@ void omapdss_venc_set_timings(struct omap_dss_device *dssdev,
 	mutex_lock(&venc.venc_lock);
 
 	/* Reset WSS data when the TV standard changes. */
-	if (memcmp(&dssdev->panel.timings, timings, sizeof(*timings)))
+	if (memcmp(&venc.timings, timings, sizeof(*timings)))
 		venc.wss_data = 0;
 
-	dssdev->panel.timings = *timings;
+	venc.timings = *timings;
 
 	if (dssdev->state = OMAP_DSS_DISPLAY_ACTIVE) {
 		int r;
@@ -606,7 +608,7 @@ int omapdss_venc_set_wss(struct omap_dss_device *dssdev, u32 wss)
 
 	mutex_lock(&venc.venc_lock);
 
-	config = venc_timings_to_config(&dssdev->panel.timings);
+	config = venc_timings_to_config(&venc.timings);
 
 	/* Invert due to VENC_L21_WC_CTL:INV=1 */
 	venc.wss_data = (wss ^ 0xfffff) << 8;
diff --git a/drivers/video/omap2/dss/venc_panel.c b/drivers/video/omap2/dss/venc_panel.c
index 6b31298..350b0d9 100644
--- a/drivers/video/omap2/dss/venc_panel.c
+++ b/drivers/video/omap2/dss/venc_panel.c
@@ -170,6 +170,7 @@ static void venc_panel_set_timings(struct omap_dss_device *dssdev,
 	mutex_lock(&venc_panel.lock);
 
 	omapdss_venc_set_timings(dssdev, timings);
+	dssdev->panel.timings = *timings;
 
 	mutex_unlock(&venc_panel.lock);
 }
-- 
1.7.9.5


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

* [RFC 17/17] OMAPDSS: VENC: Add a get_timing function for VENC interface
@ 2012-08-01 10:43   ` Archit Taneja
  0 siblings, 0 replies; 122+ messages in thread
From: Archit Taneja @ 2012-08-01 10:43 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-fbdev, linux-omap, sumit.semwal, rob, Archit Taneja

Add function omapdss_venc_get_timing() which returns the timings
maintained by the VENC interface driver in it's driver data. This is just used
once by the driver during it's probe. This prevents the need for the panel
driver to configure default timings in it's probe.

Int the VENC interface's probe, the timings field is set to PAL as a default
value. The get_timing op makes more sense for interfaces which can be configured
to a default timing.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/dss/dss.h        |    2 ++
 drivers/video/omap2/dss/venc.c       |   13 +++++++++++++
 drivers/video/omap2/dss/venc_panel.c |   11 +++++------
 3 files changed, 20 insertions(+), 6 deletions(-)

diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index 69b6ab9..3fe76c0 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -474,6 +474,8 @@ 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,
 		struct omap_video_timings *timings);
+void omapdss_venc_get_timings(struct omap_dss_device *dssdev,
+		struct omap_video_timings *timings);
 int omapdss_venc_check_timings(struct omap_dss_device *dssdev,
 		struct omap_video_timings *timings);
 u32 omapdss_venc_get_wss(struct omap_dss_device *dssdev);
diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c
index d96025e..42f97ac 100644
--- a/drivers/video/omap2/dss/venc.c
+++ b/drivers/video/omap2/dss/venc.c
@@ -579,6 +579,18 @@ void omapdss_venc_set_timings(struct omap_dss_device *dssdev,
 	mutex_unlock(&venc.venc_lock);
 }
 
+void omapdss_venc_get_timings(struct omap_dss_device *dssdev,
+		struct omap_video_timings *timings)
+{
+	DSSDBG("venc_set_timings\n");
+
+	mutex_lock(&venc.venc_lock);
+
+	*timings = venc.timings;
+
+	mutex_unlock(&venc.venc_lock);
+}
+
 int omapdss_venc_check_timings(struct omap_dss_device *dssdev,
 		struct omap_video_timings *timings)
 {
@@ -768,6 +780,7 @@ static int __init omap_venchw_probe(struct platform_device *pdev)
 	mutex_init(&venc.venc_lock);
 
 	venc.wss_data = 0;
+	venc.timings = omap_dss_pal_timings;
 
 	venc_mem = platform_get_resource(venc.pdev, IORESOURCE_MEM, 0);
 	if (!venc_mem) {
diff --git a/drivers/video/omap2/dss/venc_panel.c b/drivers/video/omap2/dss/venc_panel.c
index 350b0d9..fe9958d 100644
--- a/drivers/video/omap2/dss/venc_panel.c
+++ b/drivers/video/omap2/dss/venc_panel.c
@@ -84,14 +84,13 @@ static DEVICE_ATTR(output_type, S_IRUGO | S_IWUSR,
 
 static int venc_panel_probe(struct omap_dss_device *dssdev)
 {
+	struct omap_video_timings timings;
+
 	mutex_init(&venc_panel.lock);
 
-	/* set initial timings to PAL */
-	dssdev->panel.timings = (struct omap_video_timings)
-		{ 720, 574, 13500, 64, 12, 68, 5, 5, 41,
-			OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
-			true,
-		};
+	omapdss_venc_get_timings(dssdev, &timings);
+
+	dssdev->panel.timings = timings;
 
 	return device_create_file(&dssdev->dev, &dev_attr_output_type);
 }
-- 
1.7.9.5


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

* Re: [RFC 00/17] OMAPDSS: Change way of passing timings from panel driver to interface
@ 2012-08-01 10:47   ` Archit Taneja
  0 siblings, 0 replies; 122+ messages in thread
From: Archit Taneja @ 2012-08-01 10:47 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-fbdev, linux-omap, sumit.semwal, rob

On Wednesday 01 August 2012 04:01 PM, Archit Taneja wrote:
> This series tries to make interface drivers less dependent on omap_dss_device
> which represents a panel/device connected to that interface. The current way of
> configuring an interface is to populate the panel's omap_dss_device instance
> with parameters common to the panel and the interface, they are either populated
> in the board file, or in the panel driver. Panel timings, number of lanes
> connected to interface, and pixel format are examples of such parameters, these
> are then extracted by the interface driver to configure itself.
>
> This approach has some disadvantages:
>
> - The omap_dss_device contains fields which could be handled independently by
>    the panel driver. For example, we have an enum field in omap_dss_device to
>    tell what mode the panel operates in. This information could be handled by the
>    panel driver itself. But it's a part of omap_dss_device since we need to pass
>    this down to the interface driver.
>
> - An interface can't exist by itself. That is, it needs a panel to be connected
>    to it to configure itself. It's not practical to configure an interface
>    without a panel, but it's theoretically possible, and we may need it if we
>    expose the interface as an entity to a user of OMAPDSS. It's also useful if we
>    represent writeback as an interface, writeback isn't connected to a panel.
>
> - There is a lack of clarity in how the interface configures itself. Since the
>    interface driver extracts info from omap_dss_device, it's unclear from a panel
>    driver point of view about what information in omap_dss_device the interface
>    is using and what it's not using.
>
> - There are issues with checking the correctness of the parameters in
>    omap_dss_device. We currently fill up the omap_dss_device completely, and then
>    try to enable the interface, this results in catching a wrong parameter at a
>    much later point, rather than catching it immediately.
>
> The alternative approach is for the interface drivers to expose functions/api to
> the panel drivers to configure such parameters. This way, the panel driver can
> pass the parameters to the interface itself, rather than filling up
> omap_dss_device. This would need the panel driver to keep a copy of the
> parameters so that it can use to configure it later. This resolves all the
> issues mentioned above, and also gives us a chance to make a generic set of
> function ops for interfaces, this can make a panel driver independent of
> the underlying platform.
>
> The current series starts of this work by creating a set_timings function for
> all interfaces passing omap_video_timings, this prevents dssdev->panel.timings
> references. The first few patches are some minor cleanups which are useful for
> the patches which come later.
>
> There are some points on which I need suggestions/clarifications:
> - How do we make sure that these functions are called by the panel driver at the
>    right time? For example, when setting timings for DSI video mode, we would
>    need to call omapdss_dsi_set_timings() before we call
>    omapdss_dsi_display_enable(), otherwise the copy of timings contained in DSI
>    driver data would be invalid. Also, what should the behaviour of such a
>    set_timings operation if the interface is already enabled. It is clear for
>    DPI and HDMI, but I'm not clear about what to do about other interfaces. Do we
>    add checks for the state of the interface/panel?
>
> - A specific issue about DSI/RFBI getting the resolution via
>    device->driver->get_resolution(), does this provide a result based on panel
>    rotation? Can this somehow be replaced by timings?
>
> - For SDI, the set_timings operation is simplified, instead of disabling and
>    then enabling the panel with a new set of timings, only the new timings are
>    configured. This is similar to what is done in DPI. I am not clear if this
>    will work for SDI or not.
>
> - There is no set_timings() function for RFBI yet, this needs to be though of
>    and fixed.
>
> The reference tree and branch:

forgot to add the link here:

git://gitorious.org/~boddob/linux-omap-dss2/archit-dss2-clone.git 
pass_timings_interface

Archit
>
> This is based on Tomi's for-florian-merged branch, and has 2 of his patches which
> got missed the last merge window.
>
> This hasn't been tested thoroughly with all interfaces yet. I was interested in
> getting some comments.
>
> Archit Taneja (17):
>    OMAPDSS: APPLY: Constify timings argument in dss_mgr_set_timings
>    OMAPDSS: DPI: Remove omap_dss_device arguments in
>      dpi_set_dsi_clk/dpi_set_dispc_clk
>    OMAPDSS: HDMI: Remove omap_dss_device argument from hdmi_compute_pll
>    OMAPDSS: DPI: Add locking for DPI interface
>    OMAPDSS: DPI: Maintain our own timings field in driver data
>    OMAPDSS: DPI displays: Take care of panel timings in the driver
>      itself
>    OMAPDSS: Displays: Add locking in generic DPI panel driver
>    OMAPDSS: DSI: Maintain own copy of timings in driver data
>    OMAPDSS: HDMI: Use our own omap_video_timings field when setting
>      interface timings
>    OMAPDSS: HDMI: Add a get_timing function for HDMI interface
>    OMAPDSS: HDMI: Add locking for hdmi interface get/set timing
>      functions
>    OMAPDSS: SDI: Create a separate function for timing/clock
>      configurations
>    OMAPDSS: SDI: Create a function to set timings
>    OMAPDSS: SDI: Maintain our own timings field in driver data
>    OMAPDSS: VENC: Split VENC into interface and panel driver
>    OMAPDSS: VENC: Maintain our own timings field in driver data
>    OMAPDSS: VENC: Add a get_timing function for VENC interface
>
>   drivers/video/omap2/displays/panel-acx565akm.c     |   13 +-
>   drivers/video/omap2/displays/panel-generic-dpi.c   |   75 ++++++-
>   .../omap2/displays/panel-lgphilips-lb035q02.c      |    2 +
>   .../omap2/displays/panel-nec-nl8048hl11-01b.c      |    2 +
>   drivers/video/omap2/displays/panel-picodlp.c       |    3 +
>   .../video/omap2/displays/panel-sharp-ls037v7dw01.c |    2 +
>   drivers/video/omap2/displays/panel-taal.c          |    2 +
>   drivers/video/omap2/displays/panel-tfp410.c        |    5 +-
>   .../video/omap2/displays/panel-tpo-td043mtea1.c    |    6 +-
>   drivers/video/omap2/dss/Makefile                   |    2 +-
>   drivers/video/omap2/dss/apply.c                    |    4 +-
>   drivers/video/omap2/dss/dpi.c                      |   52 +++--
>   drivers/video/omap2/dss/dsi.c                      |   27 ++-
>   drivers/video/omap2/dss/dss.h                      |   19 +-
>   drivers/video/omap2/dss/hdmi.c                     |   60 +++--
>   drivers/video/omap2/dss/hdmi_panel.c               |   12 +-
>   drivers/video/omap2/dss/sdi.c                      |   87 +++++---
>   drivers/video/omap2/dss/venc.c                     |  233 ++++++--------------
>   drivers/video/omap2/dss/venc_panel.c               |  231 +++++++++++++++++++
>   include/video/omapdss.h                            |    8 +-
>   20 files changed, 579 insertions(+), 266 deletions(-)
>   create mode 100644 drivers/video/omap2/dss/venc_panel.c
>


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

* Re: [RFC 08/17] OMAPDSS: DSI: Maintain own copy of timings in driver data
  2012-08-01 10:43   ` Archit Taneja
@ 2012-08-07 14:07     ` Tomi Valkeinen
  -1 siblings, 0 replies; 122+ messages in thread
From: Tomi Valkeinen @ 2012-08-07 14:07 UTC (permalink / raw)
  To: Archit Taneja; +Cc: linux-fbdev, linux-omap, sumit.semwal, rob

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

On Wed, 2012-08-01 at 16:01 +0530, Archit Taneja wrote:
> The DSI driver currently relies on the timings in omap_dss_device struct to
> configure the DISPC and DSI blocks accordingly. This makes the DSI interface
> driver dependent on the omap_dss_device struct.
> 
> Make the DPI driver data maintain it's own timings field. The panel driver is
          ^^^
DSI

> expected to call omapdss_dsi_set_timings() to set these timings before the panel
> is enabled.
> 
> Signed-off-by: Archit Taneja <archit@ti.com>d
> ---
>  drivers/video/omap2/displays/panel-taal.c |    2 ++
>  drivers/video/omap2/dss/dsi.c             |   27 ++++++++++++++++++++++-----
>  include/video/omapdss.h                   |    2 ++
>  3 files changed, 26 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/video/omap2/displays/panel-taal.c b/drivers/video/omap2/displays/panel-taal.c
> index 3f5acc7..4775580 100644
> --- a/drivers/video/omap2/displays/panel-taal.c
> +++ b/drivers/video/omap2/displays/panel-taal.c
> @@ -1060,6 +1060,8 @@ static int taal_power_on(struct omap_dss_device *dssdev)
>  		goto err0;
>  	};
>  
> +	omapdss_dsi_set_timings(dssdev, &td->panel_config->timings);
> +
>  	r = omapdss_dsi_display_enable(dssdev);
>  	if (r) {
>  		dev_err(&dssdev->dev, "failed to enable DSI\n");

Video timings for command mode panel are meaningless. If we need to pass
the resolution of the panel, perhaps we should have a separate function
for that.

However, with a quick glance at dsi.c, we don't even use the
dssdev->panel.timings for cmd mode panel. But we do use
dssdev->get_resolution() in a few places. Those calls could be replaced
by storing the panel size in dsi.c, given with omapdss_dsi_set_size() or
such. We could use the timings field in dsi.c to store them, though.

 Tomi


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

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

* Re: [RFC 08/17] OMAPDSS: DSI: Maintain own copy of timings in driver data
@ 2012-08-07 14:07     ` Tomi Valkeinen
  0 siblings, 0 replies; 122+ messages in thread
From: Tomi Valkeinen @ 2012-08-07 14:07 UTC (permalink / raw)
  To: Archit Taneja; +Cc: linux-fbdev, linux-omap, sumit.semwal, rob

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

On Wed, 2012-08-01 at 16:01 +0530, Archit Taneja wrote:
> The DSI driver currently relies on the timings in omap_dss_device struct to
> configure the DISPC and DSI blocks accordingly. This makes the DSI interface
> driver dependent on the omap_dss_device struct.
> 
> Make the DPI driver data maintain it's own timings field. The panel driver is
          ^^^
DSI

> expected to call omapdss_dsi_set_timings() to set these timings before the panel
> is enabled.
> 
> Signed-off-by: Archit Taneja <archit@ti.com>d
> ---
>  drivers/video/omap2/displays/panel-taal.c |    2 ++
>  drivers/video/omap2/dss/dsi.c             |   27 ++++++++++++++++++++++-----
>  include/video/omapdss.h                   |    2 ++
>  3 files changed, 26 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/video/omap2/displays/panel-taal.c b/drivers/video/omap2/displays/panel-taal.c
> index 3f5acc7..4775580 100644
> --- a/drivers/video/omap2/displays/panel-taal.c
> +++ b/drivers/video/omap2/displays/panel-taal.c
> @@ -1060,6 +1060,8 @@ static int taal_power_on(struct omap_dss_device *dssdev)
>  		goto err0;
>  	};
>  
> +	omapdss_dsi_set_timings(dssdev, &td->panel_config->timings);
> +
>  	r = omapdss_dsi_display_enable(dssdev);
>  	if (r) {
>  		dev_err(&dssdev->dev, "failed to enable DSI\n");

Video timings for command mode panel are meaningless. If we need to pass
the resolution of the panel, perhaps we should have a separate function
for that.

However, with a quick glance at dsi.c, we don't even use the
dssdev->panel.timings for cmd mode panel. But we do use
dssdev->get_resolution() in a few places. Those calls could be replaced
by storing the panel size in dsi.c, given with omapdss_dsi_set_size() or
such. We could use the timings field in dsi.c to store them, though.

 Tomi


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

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

* Re: [RFC 13/17] OMAPDSS: SDI: Create a function to set timings
  2012-08-01 10:43   ` Archit Taneja
@ 2012-08-07 14:20     ` Tomi Valkeinen
  -1 siblings, 0 replies; 122+ messages in thread
From: Tomi Valkeinen @ 2012-08-07 14:20 UTC (permalink / raw)
  To: Archit Taneja; +Cc: linux-fbdev, linux-omap, sumit.semwal, rob

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

On Wed, 2012-08-01 at 16:01 +0530, Archit Taneja wrote:
> Create function omapdss_sdi_set_timings(), this can be used by a SDI panel
> driver without disabling/enabling the SDI interface. This is similar to the
> set_timings op of the DPI interface driver. It calls sdi_set_mode() which only
> configures the DISPC timings and DSS/DISPC clock dividers.

I don't think this works, as the SDI PLL uses pclk-free, and if pclk
changes, PLL lock probably breaks.

OMAP3430 TRM explains the sequence how to configure settings on the fly,
but that's not very simple. Just turning the output off and on is much
easier.

 Tomi


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

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

* Re: [RFC 13/17] OMAPDSS: SDI: Create a function to set timings
@ 2012-08-07 14:20     ` Tomi Valkeinen
  0 siblings, 0 replies; 122+ messages in thread
From: Tomi Valkeinen @ 2012-08-07 14:20 UTC (permalink / raw)
  To: Archit Taneja; +Cc: linux-fbdev, linux-omap, sumit.semwal, rob

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

On Wed, 2012-08-01 at 16:01 +0530, Archit Taneja wrote:
> Create function omapdss_sdi_set_timings(), this can be used by a SDI panel
> driver without disabling/enabling the SDI interface. This is similar to the
> set_timings op of the DPI interface driver. It calls sdi_set_mode() which only
> configures the DISPC timings and DSS/DISPC clock dividers.

I don't think this works, as the SDI PLL uses pclk-free, and if pclk
changes, PLL lock probably breaks.

OMAP3430 TRM explains the sequence how to configure settings on the fly,
but that's not very simple. Just turning the output off and on is much
easier.

 Tomi


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

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

* Re: [RFC 00/17] OMAPDSS: Change way of passing timings from panel driver to interface
  2012-08-01 10:43 ` Archit Taneja
@ 2012-08-07 14:32   ` Tomi Valkeinen
  -1 siblings, 0 replies; 122+ messages in thread
From: Tomi Valkeinen @ 2012-08-07 14:32 UTC (permalink / raw)
  To: Archit Taneja; +Cc: linux-fbdev, linux-omap, sumit.semwal, rob

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

On Wed, 2012-08-01 at 16:01 +0530, Archit Taneja wrote:
> This series tries to make interface drivers less dependent on omap_dss_device
> which represents a panel/device connected to that interface. The current way of
> configuring an interface is to populate the panel's omap_dss_device instance
> with parameters common to the panel and the interface, they are either populated
> in the board file, or in the panel driver. Panel timings, number of lanes
> connected to interface, and pixel format are examples of such parameters, these
> are then extracted by the interface driver to configure itself.

The series looks good. I had only a few comments to make, but obviously
this needs quite a bit of testing. I'll try it out.

 Tomi


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

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

* Re: [RFC 00/17] OMAPDSS: Change way of passing timings from panel driver to interface
@ 2012-08-07 14:32   ` Tomi Valkeinen
  0 siblings, 0 replies; 122+ messages in thread
From: Tomi Valkeinen @ 2012-08-07 14:32 UTC (permalink / raw)
  To: Archit Taneja; +Cc: linux-fbdev, linux-omap, sumit.semwal, rob

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

On Wed, 2012-08-01 at 16:01 +0530, Archit Taneja wrote:
> This series tries to make interface drivers less dependent on omap_dss_device
> which represents a panel/device connected to that interface. The current way of
> configuring an interface is to populate the panel's omap_dss_device instance
> with parameters common to the panel and the interface, they are either populated
> in the board file, or in the panel driver. Panel timings, number of lanes
> connected to interface, and pixel format are examples of such parameters, these
> are then extracted by the interface driver to configure itself.

The series looks good. I had only a few comments to make, but obviously
this needs quite a bit of testing. I'll try it out.

 Tomi


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

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

* Re: [RFC 08/17] OMAPDSS: DSI: Maintain own copy of timings in driver data
  2012-08-07 14:07     ` Tomi Valkeinen
@ 2012-08-08  6:09       ` Archit Taneja
  -1 siblings, 0 replies; 122+ messages in thread
From: Archit Taneja @ 2012-08-08  5:57 UTC (permalink / raw)
  To: Tomi Valkeinen; +Cc: linux-fbdev, linux-omap, sumit.semwal, rob

On Tuesday 07 August 2012 07:37 PM, Tomi Valkeinen wrote:
> On Wed, 2012-08-01 at 16:01 +0530, Archit Taneja wrote:
>> The DSI driver currently relies on the timings in omap_dss_device struct to
>> configure the DISPC and DSI blocks accordingly. This makes the DSI interface
>> driver dependent on the omap_dss_device struct.
>>
>> Make the DPI driver data maintain it's own timings field. The panel driver is
>            ^^^
> DSI
>
>> expected to call omapdss_dsi_set_timings() to set these timings before the panel
>> is enabled.
>>
>> Signed-off-by: Archit Taneja <archit@ti.com>d
>> ---
>>   drivers/video/omap2/displays/panel-taal.c |    2 ++
>>   drivers/video/omap2/dss/dsi.c             |   27 ++++++++++++++++++++++-----
>>   include/video/omapdss.h                   |    2 ++
>>   3 files changed, 26 insertions(+), 5 deletions(-)
>>
>> diff --git a/drivers/video/omap2/displays/panel-taal.c b/drivers/video/omap2/displays/panel-taal.c
>> index 3f5acc7..4775580 100644
>> --- a/drivers/video/omap2/displays/panel-taal.c
>> +++ b/drivers/video/omap2/displays/panel-taal.c
>> @@ -1060,6 +1060,8 @@ static int taal_power_on(struct omap_dss_device *dssdev)
>>   		goto err0;
>>   	};
>>
>> +	omapdss_dsi_set_timings(dssdev, &td->panel_config->timings);
>> +
>>   	r = omapdss_dsi_display_enable(dssdev);
>>   	if (r) {
>>   		dev_err(&dssdev->dev, "failed to enable DSI\n");
>
> Video timings for command mode panel are meaningless. If we need to pass
> the resolution of the panel, perhaps we should have a separate function
> for that.
>
> However, with a quick glance at dsi.c, we don't even use the
> dssdev->panel.timings for cmd mode panel. But we do use
> dssdev->get_resolution() in a few places. Those calls could be replaced
> by storing the panel size in dsi.c, given with omapdss_dsi_set_size() or
> such. We could use the timings field in dsi.c to store them, though.

I am a bit unclear about resolution when it comes to command mode panels.

For command mode panels, we can perform rotation at the panel side. That 
is, the panel refreshes itself by fetching pixels from it's buffer in a 
rotated way. Is that right?

If the original resolution is 864x480, and we set rotation at panel side 
to make the rotation 480x864, the DISPC manager size should also be 
configured at 480x864 right?

We seem to be setting the manager timings only once when DSI is enabled. 
After that, setting rotation doesn't impact manager size.

I am asking this to understand if we need to keep resolution as a 
separate parameter than timings. That is, timings represents the initial 
width and height of the panel, and resolution represents the current 
width and height of the panel.

Archit


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

* Re: [RFC 13/17] OMAPDSS: SDI: Create a function to set timings
  2012-08-07 14:20     ` Tomi Valkeinen
@ 2012-08-08  6:10       ` Archit Taneja
  -1 siblings, 0 replies; 122+ messages in thread
From: Archit Taneja @ 2012-08-08  5:58 UTC (permalink / raw)
  To: Tomi Valkeinen; +Cc: linux-fbdev, linux-omap, sumit.semwal, rob

On Tuesday 07 August 2012 07:50 PM, Tomi Valkeinen wrote:
> On Wed, 2012-08-01 at 16:01 +0530, Archit Taneja wrote:
>> Create function omapdss_sdi_set_timings(), this can be used by a SDI panel
>> driver without disabling/enabling the SDI interface. This is similar to the
>> set_timings op of the DPI interface driver. It calls sdi_set_mode() which only
>> configures the DISPC timings and DSS/DISPC clock dividers.
>
> I don't think this works, as the SDI PLL uses pclk-free, and if pclk
> changes, PLL lock probably breaks.
>
> OMAP3430 TRM explains the sequence how to configure settings on the fly,
> but that's not very simple. Just turning the output off and on is much
> easier.

Right, I'll make set_timings() just disable and enable SDI like before.

Archit


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

* Re: [RFC 00/17] OMAPDSS: Change way of passing timings from panel driver to interface
  2012-08-07 14:32   ` Tomi Valkeinen
@ 2012-08-08  6:17     ` Archit Taneja
  -1 siblings, 0 replies; 122+ messages in thread
From: Archit Taneja @ 2012-08-08  6:05 UTC (permalink / raw)
  To: Tomi Valkeinen; +Cc: linux-fbdev, linux-omap, sumit.semwal, rob

On Tuesday 07 August 2012 08:02 PM, Tomi Valkeinen wrote:
> On Wed, 2012-08-01 at 16:01 +0530, Archit Taneja wrote:
>> This series tries to make interface drivers less dependent on omap_dss_device
>> which represents a panel/device connected to that interface. The current way of
>> configuring an interface is to populate the panel's omap_dss_device instance
>> with parameters common to the panel and the interface, they are either populated
>> in the board file, or in the panel driver. Panel timings, number of lanes
>> connected to interface, and pixel format are examples of such parameters, these
>> are then extracted by the interface driver to configure itself.
>
> The series looks good. I had only a few comments to make, but obviously
> this needs quite a bit of testing. I'll try it out.

One thing I'm not sure about is whether these new functions should be 
aware of the state of the output. For example, if we call set_timings() 
with DSI video mode which is already enabled, the timings won't really 
take any impact.

Similar issues would occur when we try to make other ops like 
set_data_lines() or set_pixel_format(). These need to be called before 
the output is enabled. I was wondering if we would need to add 
intelligence here to make panel drivers less likely to make mistakes.

Archit

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

* Re: [RFC 08/17] OMAPDSS: DSI: Maintain own copy of timings in driver data
@ 2012-08-08  6:09       ` Archit Taneja
  0 siblings, 0 replies; 122+ messages in thread
From: Archit Taneja @ 2012-08-08  6:09 UTC (permalink / raw)
  To: Tomi Valkeinen; +Cc: linux-fbdev, linux-omap, sumit.semwal, rob

On Tuesday 07 August 2012 07:37 PM, Tomi Valkeinen wrote:
> On Wed, 2012-08-01 at 16:01 +0530, Archit Taneja wrote:
>> The DSI driver currently relies on the timings in omap_dss_device struct to
>> configure the DISPC and DSI blocks accordingly. This makes the DSI interface
>> driver dependent on the omap_dss_device struct.
>>
>> Make the DPI driver data maintain it's own timings field. The panel driver is
>            ^^^
> DSI
>
>> expected to call omapdss_dsi_set_timings() to set these timings before the panel
>> is enabled.
>>
>> Signed-off-by: Archit Taneja <archit@ti.com>d
>> ---
>>   drivers/video/omap2/displays/panel-taal.c |    2 ++
>>   drivers/video/omap2/dss/dsi.c             |   27 ++++++++++++++++++++++-----
>>   include/video/omapdss.h                   |    2 ++
>>   3 files changed, 26 insertions(+), 5 deletions(-)
>>
>> diff --git a/drivers/video/omap2/displays/panel-taal.c b/drivers/video/omap2/displays/panel-taal.c
>> index 3f5acc7..4775580 100644
>> --- a/drivers/video/omap2/displays/panel-taal.c
>> +++ b/drivers/video/omap2/displays/panel-taal.c
>> @@ -1060,6 +1060,8 @@ static int taal_power_on(struct omap_dss_device *dssdev)
>>   		goto err0;
>>   	};
>>
>> +	omapdss_dsi_set_timings(dssdev, &td->panel_config->timings);
>> +
>>   	r = omapdss_dsi_display_enable(dssdev);
>>   	if (r) {
>>   		dev_err(&dssdev->dev, "failed to enable DSI\n");
>
> Video timings for command mode panel are meaningless. If we need to pass
> the resolution of the panel, perhaps we should have a separate function
> for that.
>
> However, with a quick glance at dsi.c, we don't even use the
> dssdev->panel.timings for cmd mode panel. But we do use
> dssdev->get_resolution() in a few places. Those calls could be replaced
> by storing the panel size in dsi.c, given with omapdss_dsi_set_size() or
> such. We could use the timings field in dsi.c to store them, though.

I am a bit unclear about resolution when it comes to command mode panels.

For command mode panels, we can perform rotation at the panel side. That 
is, the panel refreshes itself by fetching pixels from it's buffer in a 
rotated way. Is that right?

If the original resolution is 864x480, and we set rotation at panel side 
to make the rotation 480x864, the DISPC manager size should also be 
configured at 480x864 right?

We seem to be setting the manager timings only once when DSI is enabled. 
After that, setting rotation doesn't impact manager size.

I am asking this to understand if we need to keep resolution as a 
separate parameter than timings. That is, timings represents the initial 
width and height of the panel, and resolution represents the current 
width and height of the panel.

Archit


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

* Re: [RFC 13/17] OMAPDSS: SDI: Create a function to set timings
@ 2012-08-08  6:10       ` Archit Taneja
  0 siblings, 0 replies; 122+ messages in thread
From: Archit Taneja @ 2012-08-08  6:10 UTC (permalink / raw)
  To: Tomi Valkeinen; +Cc: linux-fbdev, linux-omap, sumit.semwal, rob

On Tuesday 07 August 2012 07:50 PM, Tomi Valkeinen wrote:
> On Wed, 2012-08-01 at 16:01 +0530, Archit Taneja wrote:
>> Create function omapdss_sdi_set_timings(), this can be used by a SDI panel
>> driver without disabling/enabling the SDI interface. This is similar to the
>> set_timings op of the DPI interface driver. It calls sdi_set_mode() which only
>> configures the DISPC timings and DSS/DISPC clock dividers.
>
> I don't think this works, as the SDI PLL uses pclk-free, and if pclk
> changes, PLL lock probably breaks.
>
> OMAP3430 TRM explains the sequence how to configure settings on the fly,
> but that's not very simple. Just turning the output off and on is much
> easier.

Right, I'll make set_timings() just disable and enable SDI like before.

Archit


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

* Re: [RFC 08/17] OMAPDSS: DSI: Maintain own copy of timings in driver data
  2012-08-08  6:09       ` Archit Taneja
@ 2012-08-08  6:15         ` Tomi Valkeinen
  -1 siblings, 0 replies; 122+ messages in thread
From: Tomi Valkeinen @ 2012-08-08  6:15 UTC (permalink / raw)
  To: Archit Taneja; +Cc: linux-fbdev, linux-omap, sumit.semwal, rob

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

On Wed, 2012-08-08 at 11:27 +0530, Archit Taneja wrote:

> I am a bit unclear about resolution when it comes to command mode panels.

Right, it's a bit confusing. And I'm not 100% sure how to manage the
rotation.

> For command mode panels, we can perform rotation at the panel side. That 
> is, the panel refreshes itself by fetching pixels from it's buffer in a 
> rotated way. Is that right?

Yes. Well, actually I think the panel stores the pixels in rotated
manner when it receives them from OMAP, but it's practically the same.

One thing to realize is that this kind of rotation is a bit limited:
because there's only one buffer, OMAP will write pixels to the buffers
at the same time as the panel shows them. When rotating, this leads to
tearing.

If the panel has double buffer, that solves the problem, but I haven't
seen such panels. Another option is to update the panel in two parts,
like N9 does, but that's timing sensitive and a bit tricky.

> If the original resolution is 864x480, and we set rotation at panel side 
> to make the rotation 480x864, the DISPC manager size should also be 
> configured at 480x864 right?

Yep. When we use the panel rotation, from OMAP's point of view the panel
resolution has changed.

> We seem to be setting the manager timings only once when DSI is enabled. 
> After that, setting rotation doesn't impact manager size.

Hmm, previously the mgr size was set before each update. I wonder if
that code has been dropped, probably because we removed the support for
partial updates at one point. Without partial updates, the size stays
the same, except obviously with rotation. I think I just forgot about
rotation at that time.

> I am asking this to understand if we need to keep resolution as a 
> separate parameter than timings. That is, timings represents the initial 
> width and height of the panel, and resolution represents the current 
> width and height of the panel.

I'm not sure. I think that OMAP doesn't really need to know about the
initial resolution. It doesn't really matter from OMAP's point of view.

I think I originally kept timings and resolution separately, and the
idea was that timings represent the panel's timings, i.e. how it updates
the screen from its own memory. And resolution represents the usable
resolution, from OMAP's point of view.

While I haven't seen such a cmd mode panel, there could be a command
sent to the panel to configure its timings. For this we need real
timings, not the rotated resolution.

However, even in that case the DISPC doesn't need to know about those
timings, they would be handled by the panel driver (which could,
perhaps, reconfigure the DSI bus speed to match the new timings). So I
think that inside omapdss, we don't need separate timings and resolution
for DSI cmd mode panels.

 Tomi


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

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

* Re: [RFC 08/17] OMAPDSS: DSI: Maintain own copy of timings in driver data
@ 2012-08-08  6:15         ` Tomi Valkeinen
  0 siblings, 0 replies; 122+ messages in thread
From: Tomi Valkeinen @ 2012-08-08  6:15 UTC (permalink / raw)
  To: Archit Taneja; +Cc: linux-fbdev, linux-omap, sumit.semwal, rob

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

On Wed, 2012-08-08 at 11:27 +0530, Archit Taneja wrote:

> I am a bit unclear about resolution when it comes to command mode panels.

Right, it's a bit confusing. And I'm not 100% sure how to manage the
rotation.

> For command mode panels, we can perform rotation at the panel side. That 
> is, the panel refreshes itself by fetching pixels from it's buffer in a 
> rotated way. Is that right?

Yes. Well, actually I think the panel stores the pixels in rotated
manner when it receives them from OMAP, but it's practically the same.

One thing to realize is that this kind of rotation is a bit limited:
because there's only one buffer, OMAP will write pixels to the buffers
at the same time as the panel shows them. When rotating, this leads to
tearing.

If the panel has double buffer, that solves the problem, but I haven't
seen such panels. Another option is to update the panel in two parts,
like N9 does, but that's timing sensitive and a bit tricky.

> If the original resolution is 864x480, and we set rotation at panel side 
> to make the rotation 480x864, the DISPC manager size should also be 
> configured at 480x864 right?

Yep. When we use the panel rotation, from OMAP's point of view the panel
resolution has changed.

> We seem to be setting the manager timings only once when DSI is enabled. 
> After that, setting rotation doesn't impact manager size.

Hmm, previously the mgr size was set before each update. I wonder if
that code has been dropped, probably because we removed the support for
partial updates at one point. Without partial updates, the size stays
the same, except obviously with rotation. I think I just forgot about
rotation at that time.

> I am asking this to understand if we need to keep resolution as a 
> separate parameter than timings. That is, timings represents the initial 
> width and height of the panel, and resolution represents the current 
> width and height of the panel.

I'm not sure. I think that OMAP doesn't really need to know about the
initial resolution. It doesn't really matter from OMAP's point of view.

I think I originally kept timings and resolution separately, and the
idea was that timings represent the panel's timings, i.e. how it updates
the screen from its own memory. And resolution represents the usable
resolution, from OMAP's point of view.

While I haven't seen such a cmd mode panel, there could be a command
sent to the panel to configure its timings. For this we need real
timings, not the rotated resolution.

However, even in that case the DISPC doesn't need to know about those
timings, they would be handled by the panel driver (which could,
perhaps, reconfigure the DSI bus speed to match the new timings). So I
think that inside omapdss, we don't need separate timings and resolution
for DSI cmd mode panels.

 Tomi


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

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

* Re: [RFC 00/17] OMAPDSS: Change way of passing timings from panel driver to interface
@ 2012-08-08  6:17     ` Archit Taneja
  0 siblings, 0 replies; 122+ messages in thread
From: Archit Taneja @ 2012-08-08  6:17 UTC (permalink / raw)
  To: Tomi Valkeinen; +Cc: linux-fbdev, linux-omap, sumit.semwal, rob

On Tuesday 07 August 2012 08:02 PM, Tomi Valkeinen wrote:
> On Wed, 2012-08-01 at 16:01 +0530, Archit Taneja wrote:
>> This series tries to make interface drivers less dependent on omap_dss_device
>> which represents a panel/device connected to that interface. The current way of
>> configuring an interface is to populate the panel's omap_dss_device instance
>> with parameters common to the panel and the interface, they are either populated
>> in the board file, or in the panel driver. Panel timings, number of lanes
>> connected to interface, and pixel format are examples of such parameters, these
>> are then extracted by the interface driver to configure itself.
>
> The series looks good. I had only a few comments to make, but obviously
> this needs quite a bit of testing. I'll try it out.

One thing I'm not sure about is whether these new functions should be 
aware of the state of the output. For example, if we call set_timings() 
with DSI video mode which is already enabled, the timings won't really 
take any impact.

Similar issues would occur when we try to make other ops like 
set_data_lines() or set_pixel_format(). These need to be called before 
the output is enabled. I was wondering if we would need to add 
intelligence here to make panel drivers less likely to make mistakes.

Archit

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

* Re: [RFC 00/17] OMAPDSS: Change way of passing timings from panel driver to interface
  2012-08-08  6:17     ` Archit Taneja
@ 2012-08-08  6:25       ` Tomi Valkeinen
  -1 siblings, 0 replies; 122+ messages in thread
From: Tomi Valkeinen @ 2012-08-08  6:25 UTC (permalink / raw)
  To: Archit Taneja; +Cc: linux-fbdev, linux-omap, sumit.semwal, rob

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

On Wed, 2012-08-08 at 11:35 +0530, Archit Taneja wrote:
> On Tuesday 07 August 2012 08:02 PM, Tomi Valkeinen wrote:
> > On Wed, 2012-08-01 at 16:01 +0530, Archit Taneja wrote:
> >> This series tries to make interface drivers less dependent on omap_dss_device
> >> which represents a panel/device connected to that interface. The current way of
> >> configuring an interface is to populate the panel's omap_dss_device instance
> >> with parameters common to the panel and the interface, they are either populated
> >> in the board file, or in the panel driver. Panel timings, number of lanes
> >> connected to interface, and pixel format are examples of such parameters, these
> >> are then extracted by the interface driver to configure itself.
> >
> > The series looks good. I had only a few comments to make, but obviously
> > this needs quite a bit of testing. I'll try it out.
> 
> One thing I'm not sure about is whether these new functions should be 
> aware of the state of the output. For example, if we call set_timings() 
> with DSI video mode which is already enabled, the timings won't really 
> take any impact.
> 
> Similar issues would occur when we try to make other ops like 
> set_data_lines() or set_pixel_format(). These need to be called before 
> the output is enabled. I was wondering if we would need to add 
> intelligence here to make panel drivers less likely to make mistakes.

Hmm, true. It'd be nice if the functions returned -EBUSY if the
operation cannot be done while the output is enabled.

We have the dssdev->state, but we should get rid of that (or leave it to
panel drivers). It'd be good if the output drivers know whether the
output is enabled or not. I think this data is already tracked by
apply.c. It's about ovl managers, but I think that's practically the
same as output.

Calling dss_mgr_enable() will set mp->enabled = true, which could be
returned via dss_mgr_is_enabled() or such.

Then again, it wouldn't be many lines of codes to track the enable-state
in each output driver. So if we have any suspicions that mp->enabled
doesn't quite work for, say, dsi, we could just add a private "enabled"
member to dsi. But I don't right away see why dss_mgr_is_enabled()
wouldn't work.

 Tomi


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

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

* Re: [RFC 00/17] OMAPDSS: Change way of passing timings from panel driver to interface
@ 2012-08-08  6:25       ` Tomi Valkeinen
  0 siblings, 0 replies; 122+ messages in thread
From: Tomi Valkeinen @ 2012-08-08  6:25 UTC (permalink / raw)
  To: Archit Taneja; +Cc: linux-fbdev, linux-omap, sumit.semwal, rob

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

On Wed, 2012-08-08 at 11:35 +0530, Archit Taneja wrote:
> On Tuesday 07 August 2012 08:02 PM, Tomi Valkeinen wrote:
> > On Wed, 2012-08-01 at 16:01 +0530, Archit Taneja wrote:
> >> This series tries to make interface drivers less dependent on omap_dss_device
> >> which represents a panel/device connected to that interface. The current way of
> >> configuring an interface is to populate the panel's omap_dss_device instance
> >> with parameters common to the panel and the interface, they are either populated
> >> in the board file, or in the panel driver. Panel timings, number of lanes
> >> connected to interface, and pixel format are examples of such parameters, these
> >> are then extracted by the interface driver to configure itself.
> >
> > The series looks good. I had only a few comments to make, but obviously
> > this needs quite a bit of testing. I'll try it out.
> 
> One thing I'm not sure about is whether these new functions should be 
> aware of the state of the output. For example, if we call set_timings() 
> with DSI video mode which is already enabled, the timings won't really 
> take any impact.
> 
> Similar issues would occur when we try to make other ops like 
> set_data_lines() or set_pixel_format(). These need to be called before 
> the output is enabled. I was wondering if we would need to add 
> intelligence here to make panel drivers less likely to make mistakes.

Hmm, true. It'd be nice if the functions returned -EBUSY if the
operation cannot be done while the output is enabled.

We have the dssdev->state, but we should get rid of that (or leave it to
panel drivers). It'd be good if the output drivers know whether the
output is enabled or not. I think this data is already tracked by
apply.c. It's about ovl managers, but I think that's practically the
same as output.

Calling dss_mgr_enable() will set mp->enabled = true, which could be
returned via dss_mgr_is_enabled() or such.

Then again, it wouldn't be many lines of codes to track the enable-state
in each output driver. So if we have any suspicions that mp->enabled
doesn't quite work for, say, dsi, we could just add a private "enabled"
member to dsi. But I don't right away see why dss_mgr_is_enabled()
wouldn't work.

 Tomi


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

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

* Re: [RFC 08/17] OMAPDSS: DSI: Maintain own copy of timings in driver data
  2012-08-08  6:15         ` Tomi Valkeinen
@ 2012-08-08  6:41           ` Archit Taneja
  -1 siblings, 0 replies; 122+ messages in thread
From: Archit Taneja @ 2012-08-08  6:29 UTC (permalink / raw)
  To: Tomi Valkeinen; +Cc: linux-fbdev, linux-omap, sumit.semwal, rob

On Wednesday 08 August 2012 11:45 AM, Tomi Valkeinen wrote:
> On Wed, 2012-08-08 at 11:27 +0530, Archit Taneja wrote:
>
>> I am a bit unclear about resolution when it comes to command mode panels.
>
> Right, it's a bit confusing. And I'm not 100% sure how to manage the
> rotation.
>
>> For command mode panels, we can perform rotation at the panel side. That
>> is, the panel refreshes itself by fetching pixels from it's buffer in a
>> rotated way. Is that right?
>
> Yes. Well, actually I think the panel stores the pixels in rotated
> manner when it receives them from OMAP, but it's practically the same.
>
> One thing to realize is that this kind of rotation is a bit limited:
> because there's only one buffer, OMAP will write pixels to the buffers
> at the same time as the panel shows them. When rotating, this leads to
> tearing.
>
> If the panel has double buffer, that solves the problem, but I haven't
> seen such panels. Another option is to update the panel in two parts,
> like N9 does, but that's timing sensitive and a bit tricky.
>
>> If the original resolution is 864x480, and we set rotation at panel side
>> to make the rotation 480x864, the DISPC manager size should also be
>> configured at 480x864 right?
>
> Yep. When we use the panel rotation, from OMAP's point of view the panel
> resolution has changed.
>
>> We seem to be setting the manager timings only once when DSI is enabled.
>> After that, setting rotation doesn't impact manager size.
>
> Hmm, previously the mgr size was set before each update. I wonder if
> that code has been dropped, probably because we removed the support for
> partial updates at one point. Without partial updates, the size stays
> the same, except obviously with rotation. I think I just forgot about
> rotation at that time.

I tried out rotation on Taal, and it only works for 180 degrees(and 0 of 
course), 90 and 270 result in no output. I'll add a 
dss_mgr_set_timings() in omap_dsi_update, that should sort of fix it, 
but someone would need to reconfigure the connected overlays too before 
trying out an update.

>
>> I am asking this to understand if we need to keep resolution as a
>> separate parameter than timings. That is, timings represents the initial
>> width and height of the panel, and resolution represents the current
>> width and height of the panel.
>
> I'm not sure. I think that OMAP doesn't really need to know about the
> initial resolution. It doesn't really matter from OMAP's point of view.
>
> I think I originally kept timings and resolution separately, and the
> idea was that timings represent the panel's timings, i.e. how it updates
> the screen from its own memory. And resolution represents the usable
> resolution, from OMAP's point of view.
>
> While I haven't seen such a cmd mode panel, there could be a command
> sent to the panel to configure its timings. For this we need real
> timings, not the rotated resolution.
>
> However, even in that case the DISPC doesn't need to know about those
> timings, they would be handled by the panel driver (which could,
> perhaps, reconfigure the DSI bus speed to match the new timings). So I
> think that inside omapdss, we don't need separate timings and resolution
> for DSI cmd mode panels.

Ok.

Archit

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

* Re: [RFC 08/17] OMAPDSS: DSI: Maintain own copy of timings in driver data
@ 2012-08-08  6:41           ` Archit Taneja
  0 siblings, 0 replies; 122+ messages in thread
From: Archit Taneja @ 2012-08-08  6:41 UTC (permalink / raw)
  To: Tomi Valkeinen; +Cc: linux-fbdev, linux-omap, sumit.semwal, rob

On Wednesday 08 August 2012 11:45 AM, Tomi Valkeinen wrote:
> On Wed, 2012-08-08 at 11:27 +0530, Archit Taneja wrote:
>
>> I am a bit unclear about resolution when it comes to command mode panels.
>
> Right, it's a bit confusing. And I'm not 100% sure how to manage the
> rotation.
>
>> For command mode panels, we can perform rotation at the panel side. That
>> is, the panel refreshes itself by fetching pixels from it's buffer in a
>> rotated way. Is that right?
>
> Yes. Well, actually I think the panel stores the pixels in rotated
> manner when it receives them from OMAP, but it's practically the same.
>
> One thing to realize is that this kind of rotation is a bit limited:
> because there's only one buffer, OMAP will write pixels to the buffers
> at the same time as the panel shows them. When rotating, this leads to
> tearing.
>
> If the panel has double buffer, that solves the problem, but I haven't
> seen such panels. Another option is to update the panel in two parts,
> like N9 does, but that's timing sensitive and a bit tricky.
>
>> If the original resolution is 864x480, and we set rotation at panel side
>> to make the rotation 480x864, the DISPC manager size should also be
>> configured at 480x864 right?
>
> Yep. When we use the panel rotation, from OMAP's point of view the panel
> resolution has changed.
>
>> We seem to be setting the manager timings only once when DSI is enabled.
>> After that, setting rotation doesn't impact manager size.
>
> Hmm, previously the mgr size was set before each update. I wonder if
> that code has been dropped, probably because we removed the support for
> partial updates at one point. Without partial updates, the size stays
> the same, except obviously with rotation. I think I just forgot about
> rotation at that time.

I tried out rotation on Taal, and it only works for 180 degrees(and 0 of 
course), 90 and 270 result in no output. I'll add a 
dss_mgr_set_timings() in omap_dsi_update, that should sort of fix it, 
but someone would need to reconfigure the connected overlays too before 
trying out an update.

>
>> I am asking this to understand if we need to keep resolution as a
>> separate parameter than timings. That is, timings represents the initial
>> width and height of the panel, and resolution represents the current
>> width and height of the panel.
>
> I'm not sure. I think that OMAP doesn't really need to know about the
> initial resolution. It doesn't really matter from OMAP's point of view.
>
> I think I originally kept timings and resolution separately, and the
> idea was that timings represent the panel's timings, i.e. how it updates
> the screen from its own memory. And resolution represents the usable
> resolution, from OMAP's point of view.
>
> While I haven't seen such a cmd mode panel, there could be a command
> sent to the panel to configure its timings. For this we need real
> timings, not the rotated resolution.
>
> However, even in that case the DISPC doesn't need to know about those
> timings, they would be handled by the panel driver (which could,
> perhaps, reconfigure the DSI bus speed to match the new timings). So I
> think that inside omapdss, we don't need separate timings and resolution
> for DSI cmd mode panels.

Ok.

Archit

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

* Re: [RFC 00/17] OMAPDSS: Change way of passing timings from panel driver to interface
  2012-08-08  6:25       ` Tomi Valkeinen
@ 2012-08-08  6:59         ` Archit Taneja
  -1 siblings, 0 replies; 122+ messages in thread
From: Archit Taneja @ 2012-08-08  6:47 UTC (permalink / raw)
  To: Tomi Valkeinen; +Cc: linux-fbdev, linux-omap, sumit.semwal, rob

On Wednesday 08 August 2012 11:55 AM, Tomi Valkeinen wrote:
> On Wed, 2012-08-08 at 11:35 +0530, Archit Taneja wrote:
>> On Tuesday 07 August 2012 08:02 PM, Tomi Valkeinen wrote:
>>> On Wed, 2012-08-01 at 16:01 +0530, Archit Taneja wrote:
>>>> This series tries to make interface drivers less dependent on omap_dss_device
>>>> which represents a panel/device connected to that interface. The current way of
>>>> configuring an interface is to populate the panel's omap_dss_device instance
>>>> with parameters common to the panel and the interface, they are either populated
>>>> in the board file, or in the panel driver. Panel timings, number of lanes
>>>> connected to interface, and pixel format are examples of such parameters, these
>>>> are then extracted by the interface driver to configure itself.
>>>
>>> The series looks good. I had only a few comments to make, but obviously
>>> this needs quite a bit of testing. I'll try it out.
>>
>> One thing I'm not sure about is whether these new functions should be
>> aware of the state of the output. For example, if we call set_timings()
>> with DSI video mode which is already enabled, the timings won't really
>> take any impact.
>>
>> Similar issues would occur when we try to make other ops like
>> set_data_lines() or set_pixel_format(). These need to be called before
>> the output is enabled. I was wondering if we would need to add
>> intelligence here to make panel drivers less likely to make mistakes.
>
> Hmm, true. It'd be nice if the functions returned -EBUSY if the
> operation cannot be done while the output is enabled.
>
> We have the dssdev->state, but we should get rid of that (or leave it to
> panel drivers). It'd be good if the output drivers know whether the
> output is enabled or not. I think this data is already tracked by
> apply.c. It's about ovl managers, but I think that's practically the
> same as output.
>
> Calling dss_mgr_enable() will set mp->enabled = true, which could be
> returned via dss_mgr_is_enabled() or such.
>
> Then again, it wouldn't be many lines of codes to track the enable-state
> in each output driver. So if we have any suspicions that mp->enabled
> doesn't quite work for, say, dsi, we could just add a private "enabled"
> member to dsi. But I don't right away see why dss_mgr_is_enabled()
> wouldn't work.
>

I think we had discussed previously that it may not the best idea to see 
if a manager is enabled via mp->enabled as it's always possible that it 
changes afterwards. Same for any other parameter in APPLY's private 
data. This was the reason why we passed privtate data to DISPC functions 
rather than creating apply helper functions which return the value of a 
private data. For example, we pass manager timings to dispc_ovl_setup(), 
instead of DISPC using a function like dss_mgr_get_timings().

I also don't see why dss_mgr_is_enabled() wouldn't work. The only places 
where the manager's state will change are the output's enable and 
disable ops. The mutex maintained by the output would ensure 
sequential-ity between the output's enable() and set_timings() op, and 
hence ensure the manager's state we see is fine.

If we manage the 'enabled' state for each output interface, we would be 
a bit more consistent with respect to other parameters. For example, 
timings is maintained by both manager and the output. Also, if we need 
to separate out manager configurations from outputs in the future, it 
would probably be better for the output to query it's own state rather 
than depending on the manager, which could be configured either earlier 
or later.

Archit


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

* Re: [RFC 00/17] OMAPDSS: Change way of passing timings from panel driver to interface
@ 2012-08-08  6:59         ` Archit Taneja
  0 siblings, 0 replies; 122+ messages in thread
From: Archit Taneja @ 2012-08-08  6:59 UTC (permalink / raw)
  To: Tomi Valkeinen; +Cc: linux-fbdev, linux-omap, sumit.semwal, rob

On Wednesday 08 August 2012 11:55 AM, Tomi Valkeinen wrote:
> On Wed, 2012-08-08 at 11:35 +0530, Archit Taneja wrote:
>> On Tuesday 07 August 2012 08:02 PM, Tomi Valkeinen wrote:
>>> On Wed, 2012-08-01 at 16:01 +0530, Archit Taneja wrote:
>>>> This series tries to make interface drivers less dependent on omap_dss_device
>>>> which represents a panel/device connected to that interface. The current way of
>>>> configuring an interface is to populate the panel's omap_dss_device instance
>>>> with parameters common to the panel and the interface, they are either populated
>>>> in the board file, or in the panel driver. Panel timings, number of lanes
>>>> connected to interface, and pixel format are examples of such parameters, these
>>>> are then extracted by the interface driver to configure itself.
>>>
>>> The series looks good. I had only a few comments to make, but obviously
>>> this needs quite a bit of testing. I'll try it out.
>>
>> One thing I'm not sure about is whether these new functions should be
>> aware of the state of the output. For example, if we call set_timings()
>> with DSI video mode which is already enabled, the timings won't really
>> take any impact.
>>
>> Similar issues would occur when we try to make other ops like
>> set_data_lines() or set_pixel_format(). These need to be called before
>> the output is enabled. I was wondering if we would need to add
>> intelligence here to make panel drivers less likely to make mistakes.
>
> Hmm, true. It'd be nice if the functions returned -EBUSY if the
> operation cannot be done while the output is enabled.
>
> We have the dssdev->state, but we should get rid of that (or leave it to
> panel drivers). It'd be good if the output drivers know whether the
> output is enabled or not. I think this data is already tracked by
> apply.c. It's about ovl managers, but I think that's practically the
> same as output.
>
> Calling dss_mgr_enable() will set mp->enabled = true, which could be
> returned via dss_mgr_is_enabled() or such.
>
> Then again, it wouldn't be many lines of codes to track the enable-state
> in each output driver. So if we have any suspicions that mp->enabled
> doesn't quite work for, say, dsi, we could just add a private "enabled"
> member to dsi. But I don't right away see why dss_mgr_is_enabled()
> wouldn't work.
>

I think we had discussed previously that it may not the best idea to see 
if a manager is enabled via mp->enabled as it's always possible that it 
changes afterwards. Same for any other parameter in APPLY's private 
data. This was the reason why we passed privtate data to DISPC functions 
rather than creating apply helper functions which return the value of a 
private data. For example, we pass manager timings to dispc_ovl_setup(), 
instead of DISPC using a function like dss_mgr_get_timings().

I also don't see why dss_mgr_is_enabled() wouldn't work. The only places 
where the manager's state will change are the output's enable and 
disable ops. The mutex maintained by the output would ensure 
sequential-ity between the output's enable() and set_timings() op, and 
hence ensure the manager's state we see is fine.

If we manage the 'enabled' state for each output interface, we would be 
a bit more consistent with respect to other parameters. For example, 
timings is maintained by both manager and the output. Also, if we need 
to separate out manager configurations from outputs in the future, it 
would probably be better for the output to query it's own state rather 
than depending on the manager, which could be configured either earlier 
or later.

Archit


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

* Re: [RFC 08/17] OMAPDSS: DSI: Maintain own copy of timings in driver data
  2012-08-08  6:41           ` Archit Taneja
@ 2012-08-08  7:10             ` Tomi Valkeinen
  -1 siblings, 0 replies; 122+ messages in thread
From: Tomi Valkeinen @ 2012-08-08  7:10 UTC (permalink / raw)
  To: Archit Taneja; +Cc: linux-fbdev, linux-omap, sumit.semwal, rob

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

On Wed, 2012-08-08 at 11:59 +0530, Archit Taneja wrote:

> I tried out rotation on Taal, and it only works for 180 degrees(and 0 of 
> course), 90 and 270 result in no output. I'll add a 
> dss_mgr_set_timings() in omap_dsi_update, that should sort of fix it, 
> but someone would need to reconfigure the connected overlays too before 
> trying out an update.

Right, but that's something omapdss/panel cannot do, it must be done by
the user. The same problem is there with changing, say, DPI mode also.

Btw, can you separate smaller cleanups/fixes to another patch series, to
make this series even slightly smaller? I think at least the first
patches in this series are quite separate, and the rotation fix is also.

 Tomi


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

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

* Re: [RFC 08/17] OMAPDSS: DSI: Maintain own copy of timings in driver data
@ 2012-08-08  7:10             ` Tomi Valkeinen
  0 siblings, 0 replies; 122+ messages in thread
From: Tomi Valkeinen @ 2012-08-08  7:10 UTC (permalink / raw)
  To: Archit Taneja; +Cc: linux-fbdev, linux-omap, sumit.semwal, rob

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

On Wed, 2012-08-08 at 11:59 +0530, Archit Taneja wrote:

> I tried out rotation on Taal, and it only works for 180 degrees(and 0 of 
> course), 90 and 270 result in no output. I'll add a 
> dss_mgr_set_timings() in omap_dsi_update, that should sort of fix it, 
> but someone would need to reconfigure the connected overlays too before 
> trying out an update.

Right, but that's something omapdss/panel cannot do, it must be done by
the user. The same problem is there with changing, say, DPI mode also.

Btw, can you separate smaller cleanups/fixes to another patch series, to
make this series even slightly smaller? I think at least the first
patches in this series are quite separate, and the rotation fix is also.

 Tomi


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

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

* Re: [RFC 00/17] OMAPDSS: Change way of passing timings from panel driver to interface
  2012-08-08  6:59         ` Archit Taneja
@ 2012-08-08  7:27           ` Tomi Valkeinen
  -1 siblings, 0 replies; 122+ messages in thread
From: Tomi Valkeinen @ 2012-08-08  7:27 UTC (permalink / raw)
  To: Archit Taneja; +Cc: linux-fbdev, linux-omap, sumit.semwal, rob

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

On Wed, 2012-08-08 at 12:17 +0530, Archit Taneja wrote:
> On Wednesday 08 August 2012 11:55 AM, Tomi Valkeinen wrote:
> > On Wed, 2012-08-08 at 11:35 +0530, Archit Taneja wrote:
> >> On Tuesday 07 August 2012 08:02 PM, Tomi Valkeinen wrote:
> >>> On Wed, 2012-08-01 at 16:01 +0530, Archit Taneja wrote:
> >>>> This series tries to make interface drivers less dependent on omap_dss_device
> >>>> which represents a panel/device connected to that interface. The current way of
> >>>> configuring an interface is to populate the panel's omap_dss_device instance
> >>>> with parameters common to the panel and the interface, they are either populated
> >>>> in the board file, or in the panel driver. Panel timings, number of lanes
> >>>> connected to interface, and pixel format are examples of such parameters, these
> >>>> are then extracted by the interface driver to configure itself.
> >>>
> >>> The series looks good. I had only a few comments to make, but obviously
> >>> this needs quite a bit of testing. I'll try it out.
> >>
> >> One thing I'm not sure about is whether these new functions should be
> >> aware of the state of the output. For example, if we call set_timings()
> >> with DSI video mode which is already enabled, the timings won't really
> >> take any impact.
> >>
> >> Similar issues would occur when we try to make other ops like
> >> set_data_lines() or set_pixel_format(). These need to be called before
> >> the output is enabled. I was wondering if we would need to add
> >> intelligence here to make panel drivers less likely to make mistakes.
> >
> > Hmm, true. It'd be nice if the functions returned -EBUSY if the
> > operation cannot be done while the output is enabled.
> >
> > We have the dssdev->state, but we should get rid of that (or leave it to
> > panel drivers). It'd be good if the output drivers know whether the
> > output is enabled or not. I think this data is already tracked by
> > apply.c. It's about ovl managers, but I think that's practically the
> > same as output.
> >
> > Calling dss_mgr_enable() will set mp->enabled = true, which could be
> > returned via dss_mgr_is_enabled() or such.
> >
> > Then again, it wouldn't be many lines of codes to track the enable-state
> > in each output driver. So if we have any suspicions that mp->enabled
> > doesn't quite work for, say, dsi, we could just add a private "enabled"
> > member to dsi. But I don't right away see why dss_mgr_is_enabled()
> > wouldn't work.
> >
> 
> I think we had discussed previously that it may not the best idea to see 
> if a manager is enabled via mp->enabled as it's always possible that it 
> changes afterwards. Same for any other parameter in APPLY's private 
> data. This was the reason why we passed privtate data to DISPC functions 
> rather than creating apply helper functions which return the value of a 
> private data. For example, we pass manager timings to dispc_ovl_setup(), 
> instead of DISPC using a function like dss_mgr_get_timings().

I think that's slightly different problem. The dispc case has an issue
with locking. If dispc_ovl_setup() is called with the apply's spinlock
taken, neither dispc_ovl_setup() nor dss_mgr_get_timings() can take the
lock. But if dispc_ovl_setup() is called from somewhere else, it should
take the lock. Also, if dispc_ovl_setup() would call a function in
apply, it'd be calling "upwards" to a higher level component.

With the output driver calling apply, none of those problems is present,
I believe.

> I also don't see why dss_mgr_is_enabled() wouldn't work. The only places 
> where the manager's state will change are the output's enable and 
> disable ops. The mutex maintained by the output would ensure 
> sequential-ity between the output's enable() and set_timings() op, and 
> hence ensure the manager's state we see is fine.
> 
> If we manage the 'enabled' state for each output interface, we would be 
> a bit more consistent with respect to other parameters. For example, 
> timings is maintained by both manager and the output. Also, if we need 
> to separate out manager configurations from outputs in the future, it 
> would probably be better for the output to query it's own state rather 
> than depending on the manager, which could be configured either earlier 
> or later.

Two things that came to my mind:

If the output driver uses dss_mgr_is_enabled(), if both DPI and DSI
output drivers use the same manager, they'd both see themselves as
enabled. Of course only one can work at a time, so I'm not sure if
that's a practical problem. And if we had some kind of link between the
mgr and the output driver this would not be an issue.

The second thing is that we're not strictly required to have DISPC
connected to DSI or RFBI. We could use CPU/sDMA to output the image.
This is quite theoretical, though.

So, I think using dss_mgr_is_enabled() would work, but I'm still not
100% sure...

Well, perhaps the code should be such that dss_mgr_is_enabled() is used
to see if the mgr is enabled, not if the output is enabled. What I mean
with this is that if, say, set_data_lines() calls dispc to set the data
lines, we are really interested in if the dispc's mgr is enabled, not if
the DSI is enabled.

And if some other function changes DSI configuration (but doesn't touch
dispc), then we're not really interested in if the mgr is enabled, but
if the DSI is enabled.

That's a bit more complex than using only dss_mgr_is_enabled() or using
only output specific enable-flag, but I think it's more correct. In
DPI's case only dss_mgr_is_enabled() is probably needed. For DSI we may
need a separate private enable-flag.

 Tomi


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

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

* Re: [RFC 00/17] OMAPDSS: Change way of passing timings from panel driver to interface
@ 2012-08-08  7:27           ` Tomi Valkeinen
  0 siblings, 0 replies; 122+ messages in thread
From: Tomi Valkeinen @ 2012-08-08  7:27 UTC (permalink / raw)
  To: Archit Taneja; +Cc: linux-fbdev, linux-omap, sumit.semwal, rob

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

On Wed, 2012-08-08 at 12:17 +0530, Archit Taneja wrote:
> On Wednesday 08 August 2012 11:55 AM, Tomi Valkeinen wrote:
> > On Wed, 2012-08-08 at 11:35 +0530, Archit Taneja wrote:
> >> On Tuesday 07 August 2012 08:02 PM, Tomi Valkeinen wrote:
> >>> On Wed, 2012-08-01 at 16:01 +0530, Archit Taneja wrote:
> >>>> This series tries to make interface drivers less dependent on omap_dss_device
> >>>> which represents a panel/device connected to that interface. The current way of
> >>>> configuring an interface is to populate the panel's omap_dss_device instance
> >>>> with parameters common to the panel and the interface, they are either populated
> >>>> in the board file, or in the panel driver. Panel timings, number of lanes
> >>>> connected to interface, and pixel format are examples of such parameters, these
> >>>> are then extracted by the interface driver to configure itself.
> >>>
> >>> The series looks good. I had only a few comments to make, but obviously
> >>> this needs quite a bit of testing. I'll try it out.
> >>
> >> One thing I'm not sure about is whether these new functions should be
> >> aware of the state of the output. For example, if we call set_timings()
> >> with DSI video mode which is already enabled, the timings won't really
> >> take any impact.
> >>
> >> Similar issues would occur when we try to make other ops like
> >> set_data_lines() or set_pixel_format(). These need to be called before
> >> the output is enabled. I was wondering if we would need to add
> >> intelligence here to make panel drivers less likely to make mistakes.
> >
> > Hmm, true. It'd be nice if the functions returned -EBUSY if the
> > operation cannot be done while the output is enabled.
> >
> > We have the dssdev->state, but we should get rid of that (or leave it to
> > panel drivers). It'd be good if the output drivers know whether the
> > output is enabled or not. I think this data is already tracked by
> > apply.c. It's about ovl managers, but I think that's practically the
> > same as output.
> >
> > Calling dss_mgr_enable() will set mp->enabled = true, which could be
> > returned via dss_mgr_is_enabled() or such.
> >
> > Then again, it wouldn't be many lines of codes to track the enable-state
> > in each output driver. So if we have any suspicions that mp->enabled
> > doesn't quite work for, say, dsi, we could just add a private "enabled"
> > member to dsi. But I don't right away see why dss_mgr_is_enabled()
> > wouldn't work.
> >
> 
> I think we had discussed previously that it may not the best idea to see 
> if a manager is enabled via mp->enabled as it's always possible that it 
> changes afterwards. Same for any other parameter in APPLY's private 
> data. This was the reason why we passed privtate data to DISPC functions 
> rather than creating apply helper functions which return the value of a 
> private data. For example, we pass manager timings to dispc_ovl_setup(), 
> instead of DISPC using a function like dss_mgr_get_timings().

I think that's slightly different problem. The dispc case has an issue
with locking. If dispc_ovl_setup() is called with the apply's spinlock
taken, neither dispc_ovl_setup() nor dss_mgr_get_timings() can take the
lock. But if dispc_ovl_setup() is called from somewhere else, it should
take the lock. Also, if dispc_ovl_setup() would call a function in
apply, it'd be calling "upwards" to a higher level component.

With the output driver calling apply, none of those problems is present,
I believe.

> I also don't see why dss_mgr_is_enabled() wouldn't work. The only places 
> where the manager's state will change are the output's enable and 
> disable ops. The mutex maintained by the output would ensure 
> sequential-ity between the output's enable() and set_timings() op, and 
> hence ensure the manager's state we see is fine.
> 
> If we manage the 'enabled' state for each output interface, we would be 
> a bit more consistent with respect to other parameters. For example, 
> timings is maintained by both manager and the output. Also, if we need 
> to separate out manager configurations from outputs in the future, it 
> would probably be better for the output to query it's own state rather 
> than depending on the manager, which could be configured either earlier 
> or later.

Two things that came to my mind:

If the output driver uses dss_mgr_is_enabled(), if both DPI and DSI
output drivers use the same manager, they'd both see themselves as
enabled. Of course only one can work at a time, so I'm not sure if
that's a practical problem. And if we had some kind of link between the
mgr and the output driver this would not be an issue.

The second thing is that we're not strictly required to have DISPC
connected to DSI or RFBI. We could use CPU/sDMA to output the image.
This is quite theoretical, though.

So, I think using dss_mgr_is_enabled() would work, but I'm still not
100% sure...

Well, perhaps the code should be such that dss_mgr_is_enabled() is used
to see if the mgr is enabled, not if the output is enabled. What I mean
with this is that if, say, set_data_lines() calls dispc to set the data
lines, we are really interested in if the dispc's mgr is enabled, not if
the DSI is enabled.

And if some other function changes DSI configuration (but doesn't touch
dispc), then we're not really interested in if the mgr is enabled, but
if the DSI is enabled.

That's a bit more complex than using only dss_mgr_is_enabled() or using
only output specific enable-flag, but I think it's more correct. In
DPI's case only dss_mgr_is_enabled() is probably needed. For DSI we may
need a separate private enable-flag.

 Tomi


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

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

* Re: [RFC 08/17] OMAPDSS: DSI: Maintain own copy of timings in driver data
  2012-08-08  7:10             ` Tomi Valkeinen
@ 2012-08-08  8:06               ` Archit Taneja
  -1 siblings, 0 replies; 122+ messages in thread
From: Archit Taneja @ 2012-08-08  7:54 UTC (permalink / raw)
  To: Tomi Valkeinen; +Cc: linux-fbdev, linux-omap, sumit.semwal, rob

On Wednesday 08 August 2012 12:40 PM, Tomi Valkeinen wrote:
> On Wed, 2012-08-08 at 11:59 +0530, Archit Taneja wrote:
>
>> I tried out rotation on Taal, and it only works for 180 degrees(and 0 of
>> course), 90 and 270 result in no output. I'll add a
>> dss_mgr_set_timings() in omap_dsi_update, that should sort of fix it,
>> but someone would need to reconfigure the connected overlays too before
>> trying out an update.
>
> Right, but that's something omapdss/panel cannot do, it must be done by
> the user. The same problem is there with changing, say, DPI mode also.
>
> Btw, can you separate smaller cleanups/fixes to another patch series, to
> make this series even slightly smaller? I think at least the first
> patches in this series are quite separate, and the rotation fix is also.

Right, I'll do that.

Archit


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

* Re: [RFC 00/17] OMAPDSS: Change way of passing timings from panel driver to interface
  2012-08-08  7:27           ` Tomi Valkeinen
@ 2012-08-08  8:11             ` Archit Taneja
  -1 siblings, 0 replies; 122+ messages in thread
From: Archit Taneja @ 2012-08-08  7:59 UTC (permalink / raw)
  To: Tomi Valkeinen; +Cc: linux-fbdev, linux-omap, sumit.semwal, rob

On Wednesday 08 August 2012 12:57 PM, Tomi Valkeinen wrote:
> On Wed, 2012-08-08 at 12:17 +0530, Archit Taneja wrote:
>> On Wednesday 08 August 2012 11:55 AM, Tomi Valkeinen wrote:
>>> On Wed, 2012-08-08 at 11:35 +0530, Archit Taneja wrote:
>>>> On Tuesday 07 August 2012 08:02 PM, Tomi Valkeinen wrote:
>>>>> On Wed, 2012-08-01 at 16:01 +0530, Archit Taneja wrote:
>>>>>> This series tries to make interface drivers less dependent on omap_dss_device
>>>>>> which represents a panel/device connected to that interface. The current way of
>>>>>> configuring an interface is to populate the panel's omap_dss_device instance
>>>>>> with parameters common to the panel and the interface, they are either populated
>>>>>> in the board file, or in the panel driver. Panel timings, number of lanes
>>>>>> connected to interface, and pixel format are examples of such parameters, these
>>>>>> are then extracted by the interface driver to configure itself.
>>>>>
>>>>> The series looks good. I had only a few comments to make, but obviously
>>>>> this needs quite a bit of testing. I'll try it out.
>>>>
>>>> One thing I'm not sure about is whether these new functions should be
>>>> aware of the state of the output. For example, if we call set_timings()
>>>> with DSI video mode which is already enabled, the timings won't really
>>>> take any impact.
>>>>
>>>> Similar issues would occur when we try to make other ops like
>>>> set_data_lines() or set_pixel_format(). These need to be called before
>>>> the output is enabled. I was wondering if we would need to add
>>>> intelligence here to make panel drivers less likely to make mistakes.
>>>
>>> Hmm, true. It'd be nice if the functions returned -EBUSY if the
>>> operation cannot be done while the output is enabled.
>>>
>>> We have the dssdev->state, but we should get rid of that (or leave it to
>>> panel drivers). It'd be good if the output drivers know whether the
>>> output is enabled or not. I think this data is already tracked by
>>> apply.c. It's about ovl managers, but I think that's practically the
>>> same as output.
>>>
>>> Calling dss_mgr_enable() will set mp->enabled = true, which could be
>>> returned via dss_mgr_is_enabled() or such.
>>>
>>> Then again, it wouldn't be many lines of codes to track the enable-state
>>> in each output driver. So if we have any suspicions that mp->enabled
>>> doesn't quite work for, say, dsi, we could just add a private "enabled"
>>> member to dsi. But I don't right away see why dss_mgr_is_enabled()
>>> wouldn't work.
>>>
>>
>> I think we had discussed previously that it may not the best idea to see
>> if a manager is enabled via mp->enabled as it's always possible that it
>> changes afterwards. Same for any other parameter in APPLY's private
>> data. This was the reason why we passed privtate data to DISPC functions
>> rather than creating apply helper functions which return the value of a
>> private data. For example, we pass manager timings to dispc_ovl_setup(),
>> instead of DISPC using a function like dss_mgr_get_timings().
>
> I think that's slightly different problem. The dispc case has an issue
> with locking. If dispc_ovl_setup() is called with the apply's spinlock
> taken, neither dispc_ovl_setup() nor dss_mgr_get_timings() can take the
> lock. But if dispc_ovl_setup() is called from somewhere else, it should
> take the lock. Also, if dispc_ovl_setup() would call a function in
> apply, it'd be calling "upwards" to a higher level component.
>
> With the output driver calling apply, none of those problems is present,
> I believe.
>
>> I also don't see why dss_mgr_is_enabled() wouldn't work. The only places
>> where the manager's state will change are the output's enable and
>> disable ops. The mutex maintained by the output would ensure
>> sequential-ity between the output's enable() and set_timings() op, and
>> hence ensure the manager's state we see is fine.
>>
>> If we manage the 'enabled' state for each output interface, we would be
>> a bit more consistent with respect to other parameters. For example,
>> timings is maintained by both manager and the output. Also, if we need
>> to separate out manager configurations from outputs in the future, it
>> would probably be better for the output to query it's own state rather
>> than depending on the manager, which could be configured either earlier
>> or later.
>
> Two things that came to my mind:
>
> If the output driver uses dss_mgr_is_enabled(), if both DPI and DSI
> output drivers use the same manager, they'd both see themselves as
> enabled. Of course only one can work at a time, so I'm not sure if
> that's a practical problem. And if we had some kind of link between the
> mgr and the output driver this would not be an issue.
>
> The second thing is that we're not strictly required to have DISPC
> connected to DSI or RFBI. We could use CPU/sDMA to output the image.
> This is quite theoretical, though.
>
> So, I think using dss_mgr_is_enabled() would work, but I'm still not
> 100% sure...
>
> Well, perhaps the code should be such that dss_mgr_is_enabled() is used
> to see if the mgr is enabled, not if the output is enabled. What I mean
> with this is that if, say, set_data_lines() calls dispc to set the data
> lines, we are really interested in if the dispc's mgr is enabled, not if
> the DSI is enabled.
>
> And if some other function changes DSI configuration (but doesn't touch
> dispc), then we're not really interested in if the mgr is enabled, but
> if the DSI is enabled.
>
> That's a bit more complex than using only dss_mgr_is_enabled() or using
> only output specific enable-flag, but I think it's more correct. In
> DPI's case only dss_mgr_is_enabled() is probably needed. For DSI we may
> need a separate private enable-flag.

Okay, one thing which I want to align on is that most of these functions 
don't really do the actual configurations. That is, they'll just update 
the private data, and the actual configuration will only happen on enable.

We would want set_timings() op to have a direct impact. But we wouldn't 
want the same for setting the data lines, that could be clubbed with 
other configurations at enable. That's okay, right?

Archit

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

* Re: [RFC 08/17] OMAPDSS: DSI: Maintain own copy of timings in driver data
@ 2012-08-08  8:06               ` Archit Taneja
  0 siblings, 0 replies; 122+ messages in thread
From: Archit Taneja @ 2012-08-08  8:06 UTC (permalink / raw)
  To: Tomi Valkeinen; +Cc: linux-fbdev, linux-omap, sumit.semwal, rob

On Wednesday 08 August 2012 12:40 PM, Tomi Valkeinen wrote:
> On Wed, 2012-08-08 at 11:59 +0530, Archit Taneja wrote:
>
>> I tried out rotation on Taal, and it only works for 180 degrees(and 0 of
>> course), 90 and 270 result in no output. I'll add a
>> dss_mgr_set_timings() in omap_dsi_update, that should sort of fix it,
>> but someone would need to reconfigure the connected overlays too before
>> trying out an update.
>
> Right, but that's something omapdss/panel cannot do, it must be done by
> the user. The same problem is there with changing, say, DPI mode also.
>
> Btw, can you separate smaller cleanups/fixes to another patch series, to
> make this series even slightly smaller? I think at least the first
> patches in this series are quite separate, and the rotation fix is also.

Right, I'll do that.

Archit


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

* Re: [RFC 00/17] OMAPDSS: Change way of passing timings from panel driver to interface
@ 2012-08-08  8:11             ` Archit Taneja
  0 siblings, 0 replies; 122+ messages in thread
From: Archit Taneja @ 2012-08-08  8:11 UTC (permalink / raw)
  To: Tomi Valkeinen; +Cc: linux-fbdev, linux-omap, sumit.semwal, rob

On Wednesday 08 August 2012 12:57 PM, Tomi Valkeinen wrote:
> On Wed, 2012-08-08 at 12:17 +0530, Archit Taneja wrote:
>> On Wednesday 08 August 2012 11:55 AM, Tomi Valkeinen wrote:
>>> On Wed, 2012-08-08 at 11:35 +0530, Archit Taneja wrote:
>>>> On Tuesday 07 August 2012 08:02 PM, Tomi Valkeinen wrote:
>>>>> On Wed, 2012-08-01 at 16:01 +0530, Archit Taneja wrote:
>>>>>> This series tries to make interface drivers less dependent on omap_dss_device
>>>>>> which represents a panel/device connected to that interface. The current way of
>>>>>> configuring an interface is to populate the panel's omap_dss_device instance
>>>>>> with parameters common to the panel and the interface, they are either populated
>>>>>> in the board file, or in the panel driver. Panel timings, number of lanes
>>>>>> connected to interface, and pixel format are examples of such parameters, these
>>>>>> are then extracted by the interface driver to configure itself.
>>>>>
>>>>> The series looks good. I had only a few comments to make, but obviously
>>>>> this needs quite a bit of testing. I'll try it out.
>>>>
>>>> One thing I'm not sure about is whether these new functions should be
>>>> aware of the state of the output. For example, if we call set_timings()
>>>> with DSI video mode which is already enabled, the timings won't really
>>>> take any impact.
>>>>
>>>> Similar issues would occur when we try to make other ops like
>>>> set_data_lines() or set_pixel_format(). These need to be called before
>>>> the output is enabled. I was wondering if we would need to add
>>>> intelligence here to make panel drivers less likely to make mistakes.
>>>
>>> Hmm, true. It'd be nice if the functions returned -EBUSY if the
>>> operation cannot be done while the output is enabled.
>>>
>>> We have the dssdev->state, but we should get rid of that (or leave it to
>>> panel drivers). It'd be good if the output drivers know whether the
>>> output is enabled or not. I think this data is already tracked by
>>> apply.c. It's about ovl managers, but I think that's practically the
>>> same as output.
>>>
>>> Calling dss_mgr_enable() will set mp->enabled = true, which could be
>>> returned via dss_mgr_is_enabled() or such.
>>>
>>> Then again, it wouldn't be many lines of codes to track the enable-state
>>> in each output driver. So if we have any suspicions that mp->enabled
>>> doesn't quite work for, say, dsi, we could just add a private "enabled"
>>> member to dsi. But I don't right away see why dss_mgr_is_enabled()
>>> wouldn't work.
>>>
>>
>> I think we had discussed previously that it may not the best idea to see
>> if a manager is enabled via mp->enabled as it's always possible that it
>> changes afterwards. Same for any other parameter in APPLY's private
>> data. This was the reason why we passed privtate data to DISPC functions
>> rather than creating apply helper functions which return the value of a
>> private data. For example, we pass manager timings to dispc_ovl_setup(),
>> instead of DISPC using a function like dss_mgr_get_timings().
>
> I think that's slightly different problem. The dispc case has an issue
> with locking. If dispc_ovl_setup() is called with the apply's spinlock
> taken, neither dispc_ovl_setup() nor dss_mgr_get_timings() can take the
> lock. But if dispc_ovl_setup() is called from somewhere else, it should
> take the lock. Also, if dispc_ovl_setup() would call a function in
> apply, it'd be calling "upwards" to a higher level component.
>
> With the output driver calling apply, none of those problems is present,
> I believe.
>
>> I also don't see why dss_mgr_is_enabled() wouldn't work. The only places
>> where the manager's state will change are the output's enable and
>> disable ops. The mutex maintained by the output would ensure
>> sequential-ity between the output's enable() and set_timings() op, and
>> hence ensure the manager's state we see is fine.
>>
>> If we manage the 'enabled' state for each output interface, we would be
>> a bit more consistent with respect to other parameters. For example,
>> timings is maintained by both manager and the output. Also, if we need
>> to separate out manager configurations from outputs in the future, it
>> would probably be better for the output to query it's own state rather
>> than depending on the manager, which could be configured either earlier
>> or later.
>
> Two things that came to my mind:
>
> If the output driver uses dss_mgr_is_enabled(), if both DPI and DSI
> output drivers use the same manager, they'd both see themselves as
> enabled. Of course only one can work at a time, so I'm not sure if
> that's a practical problem. And if we had some kind of link between the
> mgr and the output driver this would not be an issue.
>
> The second thing is that we're not strictly required to have DISPC
> connected to DSI or RFBI. We could use CPU/sDMA to output the image.
> This is quite theoretical, though.
>
> So, I think using dss_mgr_is_enabled() would work, but I'm still not
> 100% sure...
>
> Well, perhaps the code should be such that dss_mgr_is_enabled() is used
> to see if the mgr is enabled, not if the output is enabled. What I mean
> with this is that if, say, set_data_lines() calls dispc to set the data
> lines, we are really interested in if the dispc's mgr is enabled, not if
> the DSI is enabled.
>
> And if some other function changes DSI configuration (but doesn't touch
> dispc), then we're not really interested in if the mgr is enabled, but
> if the DSI is enabled.
>
> That's a bit more complex than using only dss_mgr_is_enabled() or using
> only output specific enable-flag, but I think it's more correct. In
> DPI's case only dss_mgr_is_enabled() is probably needed. For DSI we may
> need a separate private enable-flag.

Okay, one thing which I want to align on is that most of these functions 
don't really do the actual configurations. That is, they'll just update 
the private data, and the actual configuration will only happen on enable.

We would want set_timings() op to have a direct impact. But we wouldn't 
want the same for setting the data lines, that could be clubbed with 
other configurations at enable. That's okay, right?

Archit

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

* Re: [RFC 00/17] OMAPDSS: Change way of passing timings from panel driver to interface
  2012-08-08  8:11             ` Archit Taneja
@ 2012-08-08  8:13               ` Tomi Valkeinen
  -1 siblings, 0 replies; 122+ messages in thread
From: Tomi Valkeinen @ 2012-08-08  8:13 UTC (permalink / raw)
  To: Archit Taneja; +Cc: linux-fbdev, linux-omap, sumit.semwal, rob

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

On Wed, 2012-08-08 at 13:29 +0530, Archit Taneja wrote:

> Okay, one thing which I want to align on is that most of these functions 
> don't really do the actual configurations. That is, they'll just update 
> the private data, and the actual configuration will only happen on enable.
> 
> We would want set_timings() op to have a direct impact. But we wouldn't 
> want the same for setting the data lines, that could be clubbed with 
> other configurations at enable. That's okay, right?

I'm not sure we want/need set_timings to have direct impact. Changing
the timings on the fly has some problems, like the output size changing
to smaller than the overlays, and we perhaps may need to adjust the
clock dividers (dispc's, DSI PLL's or PRCM's).

It feels just much easier and safer to require that the mgr is disabled
when these changes are made. And as far as I can see, there shouldn't be
any need to change the timings via the shadow registers, as quickly as
possible and during vblank...

This makes me also think that if the output related settings can only be
changed when the output is off, the apply mechanism is not really needed
at all for these. Not that it causes any harm, but just a point I
realized.

 Tomi


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

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

* Re: [RFC 00/17] OMAPDSS: Change way of passing timings from panel driver to interface
@ 2012-08-08  8:13               ` Tomi Valkeinen
  0 siblings, 0 replies; 122+ messages in thread
From: Tomi Valkeinen @ 2012-08-08  8:13 UTC (permalink / raw)
  To: Archit Taneja; +Cc: linux-fbdev, linux-omap, sumit.semwal, rob

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

On Wed, 2012-08-08 at 13:29 +0530, Archit Taneja wrote:

> Okay, one thing which I want to align on is that most of these functions 
> don't really do the actual configurations. That is, they'll just update 
> the private data, and the actual configuration will only happen on enable.
> 
> We would want set_timings() op to have a direct impact. But we wouldn't 
> want the same for setting the data lines, that could be clubbed with 
> other configurations at enable. That's okay, right?

I'm not sure we want/need set_timings to have direct impact. Changing
the timings on the fly has some problems, like the output size changing
to smaller than the overlays, and we perhaps may need to adjust the
clock dividers (dispc's, DSI PLL's or PRCM's).

It feels just much easier and safer to require that the mgr is disabled
when these changes are made. And as far as I can see, there shouldn't be
any need to change the timings via the shadow registers, as quickly as
possible and during vblank...

This makes me also think that if the output related settings can only be
changed when the output is off, the apply mechanism is not really needed
at all for these. Not that it causes any harm, but just a point I
realized.

 Tomi


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

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

* Re: [RFC 00/17] OMAPDSS: Change way of passing timings from panel driver to interface
  2012-08-08  8:13               ` Tomi Valkeinen
@ 2012-08-08  8:50                 ` Archit Taneja
  -1 siblings, 0 replies; 122+ messages in thread
From: Archit Taneja @ 2012-08-08  8:38 UTC (permalink / raw)
  To: Tomi Valkeinen; +Cc: linux-fbdev, linux-omap, sumit.semwal, rob

On Wednesday 08 August 2012 01:43 PM, Tomi Valkeinen wrote:
> On Wed, 2012-08-08 at 13:29 +0530, Archit Taneja wrote:
>
>> Okay, one thing which I want to align on is that most of these functions
>> don't really do the actual configurations. That is, they'll just update
>> the private data, and the actual configuration will only happen on enable.
>>
>> We would want set_timings() op to have a direct impact. But we wouldn't
>> want the same for setting the data lines, that could be clubbed with
>> other configurations at enable. That's okay, right?
>
> I'm not sure we want/need set_timings to have direct impact. Changing
> the timings on the fly has some problems, like the output size changing
> to smaller than the overlays, and we perhaps may need to adjust the
> clock dividers (dispc's, DSI PLL's or PRCM's).
>
> It feels just much easier and safer to require that the mgr is disabled
> when these changes are made. And as far as I can see, there shouldn't be
> any need to change the timings via the shadow registers, as quickly as
> possible and during vblank...

That makes sense. But currently set_timings for DPI has a direct impact. 
HDMI/VENC/SDI take the easier route of disabling and enabling the interface.

I agree it's safer and easier to make sure things are disabled first, 
but maybe it's good to have the capability set hdmi timings on the fly 
in the future, it would make the switch faster, same goes for reading edid.

What I meant to ask was whether we should do the same for something like 
dpi_set_data_lines(), that is, disable dpi, update the data_lines 
private data with a new value, and enable dpi again.

>
> This makes me also think that if the output related settings can only be
> changed when the output is off, the apply mechanism is not really needed
> at all for these. Not that it causes any harm, but just a point I
> realized.

Hmm, unfortunately you are right. It's still good to have all the DISPC 
writes only in APPLY though, and it gives us the option to do some 
operation on the fly if needed in the future.

Archit


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

* Re: [RFC 00/17] OMAPDSS: Change way of passing timings from panel driver to interface
  2012-08-08  8:50                 ` Archit Taneja
@ 2012-08-08  8:48                   ` Tomi Valkeinen
  -1 siblings, 0 replies; 122+ messages in thread
From: Tomi Valkeinen @ 2012-08-08  8:48 UTC (permalink / raw)
  To: Archit Taneja; +Cc: linux-fbdev, linux-omap, sumit.semwal, rob

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

On Wed, 2012-08-08 at 14:08 +0530, Archit Taneja wrote:
> On Wednesday 08 August 2012 01:43 PM, Tomi Valkeinen wrote:
> > On Wed, 2012-08-08 at 13:29 +0530, Archit Taneja wrote:
> >
> >> Okay, one thing which I want to align on is that most of these functions
> >> don't really do the actual configurations. That is, they'll just update
> >> the private data, and the actual configuration will only happen on enable.
> >>
> >> We would want set_timings() op to have a direct impact. But we wouldn't
> >> want the same for setting the data lines, that could be clubbed with
> >> other configurations at enable. That's okay, right?
> >
> > I'm not sure we want/need set_timings to have direct impact. Changing
> > the timings on the fly has some problems, like the output size changing
> > to smaller than the overlays, and we perhaps may need to adjust the
> > clock dividers (dispc's, DSI PLL's or PRCM's).
> >
> > It feels just much easier and safer to require that the mgr is disabled
> > when these changes are made. And as far as I can see, there shouldn't be
> > any need to change the timings via the shadow registers, as quickly as
> > possible and during vblank...
> 
> That makes sense. But currently set_timings for DPI has a direct impact. 
> HDMI/VENC/SDI take the easier route of disabling and enabling the interface.
> 
> I agree it's safer and easier to make sure things are disabled first, 
> but maybe it's good to have the capability set hdmi timings on the fly 
> in the future, it would make the switch faster, same goes for reading edid.

When do we need to switch mode quickly? Reading edid should not require
disabling the output for sure.

HDMI is a bit broken currently, though. I think we first enable the
whole stuff, including video output using VGA, then we read EDID, then
we change the mode.

We should just enable enough of HDMI to be able to read EDID, and start
the video output with the correct mode. This needs some restructuring of
the driver, though. I tried it once quickly, but it turned out not to be
trivial.

> What I meant to ask was whether we should do the same for something like 
> dpi_set_data_lines(), that is, disable dpi, update the data_lines 
> private data with a new value, and enable dpi again.

Hmm, I think it's better to leave disabling and enabling the output to
the panel driver. So when the panel driver wants to use
dpi_set_data_lines(), it needs to first disable the DPI output. If it
doesn't, dpi_set_data_lines() returns -EBUSY.

Otherwise if the panel driver does something like:

dpi_set_foo()
dpi_set_bar()

Both of those could first disable output, change setting, enable output.
Instead the panel should first disable, then call those, and then
enable.

 Tomi


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

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

* Re: [RFC 00/17] OMAPDSS: Change way of passing timings from panel driver to interface
@ 2012-08-08  8:48                   ` Tomi Valkeinen
  0 siblings, 0 replies; 122+ messages in thread
From: Tomi Valkeinen @ 2012-08-08  8:48 UTC (permalink / raw)
  To: Archit Taneja; +Cc: linux-fbdev, linux-omap, sumit.semwal, rob

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

On Wed, 2012-08-08 at 14:08 +0530, Archit Taneja wrote:
> On Wednesday 08 August 2012 01:43 PM, Tomi Valkeinen wrote:
> > On Wed, 2012-08-08 at 13:29 +0530, Archit Taneja wrote:
> >
> >> Okay, one thing which I want to align on is that most of these functions
> >> don't really do the actual configurations. That is, they'll just update
> >> the private data, and the actual configuration will only happen on enable.
> >>
> >> We would want set_timings() op to have a direct impact. But we wouldn't
> >> want the same for setting the data lines, that could be clubbed with
> >> other configurations at enable. That's okay, right?
> >
> > I'm not sure we want/need set_timings to have direct impact. Changing
> > the timings on the fly has some problems, like the output size changing
> > to smaller than the overlays, and we perhaps may need to adjust the
> > clock dividers (dispc's, DSI PLL's or PRCM's).
> >
> > It feels just much easier and safer to require that the mgr is disabled
> > when these changes are made. And as far as I can see, there shouldn't be
> > any need to change the timings via the shadow registers, as quickly as
> > possible and during vblank...
> 
> That makes sense. But currently set_timings for DPI has a direct impact. 
> HDMI/VENC/SDI take the easier route of disabling and enabling the interface.
> 
> I agree it's safer and easier to make sure things are disabled first, 
> but maybe it's good to have the capability set hdmi timings on the fly 
> in the future, it would make the switch faster, same goes for reading edid.

When do we need to switch mode quickly? Reading edid should not require
disabling the output for sure.

HDMI is a bit broken currently, though. I think we first enable the
whole stuff, including video output using VGA, then we read EDID, then
we change the mode.

We should just enable enough of HDMI to be able to read EDID, and start
the video output with the correct mode. This needs some restructuring of
the driver, though. I tried it once quickly, but it turned out not to be
trivial.

> What I meant to ask was whether we should do the same for something like 
> dpi_set_data_lines(), that is, disable dpi, update the data_lines 
> private data with a new value, and enable dpi again.

Hmm, I think it's better to leave disabling and enabling the output to
the panel driver. So when the panel driver wants to use
dpi_set_data_lines(), it needs to first disable the DPI output. If it
doesn't, dpi_set_data_lines() returns -EBUSY.

Otherwise if the panel driver does something like:

dpi_set_foo()
dpi_set_bar()

Both of those could first disable output, change setting, enable output.
Instead the panel should first disable, then call those, and then
enable.

 Tomi


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

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

* Re: [RFC 00/17] OMAPDSS: Change way of passing timings from panel driver to interface
@ 2012-08-08  8:50                 ` Archit Taneja
  0 siblings, 0 replies; 122+ messages in thread
From: Archit Taneja @ 2012-08-08  8:50 UTC (permalink / raw)
  To: Tomi Valkeinen; +Cc: linux-fbdev, linux-omap, sumit.semwal, rob

On Wednesday 08 August 2012 01:43 PM, Tomi Valkeinen wrote:
> On Wed, 2012-08-08 at 13:29 +0530, Archit Taneja wrote:
>
>> Okay, one thing which I want to align on is that most of these functions
>> don't really do the actual configurations. That is, they'll just update
>> the private data, and the actual configuration will only happen on enable.
>>
>> We would want set_timings() op to have a direct impact. But we wouldn't
>> want the same for setting the data lines, that could be clubbed with
>> other configurations at enable. That's okay, right?
>
> I'm not sure we want/need set_timings to have direct impact. Changing
> the timings on the fly has some problems, like the output size changing
> to smaller than the overlays, and we perhaps may need to adjust the
> clock dividers (dispc's, DSI PLL's or PRCM's).
>
> It feels just much easier and safer to require that the mgr is disabled
> when these changes are made. And as far as I can see, there shouldn't be
> any need to change the timings via the shadow registers, as quickly as
> possible and during vblank...

That makes sense. But currently set_timings for DPI has a direct impact. 
HDMI/VENC/SDI take the easier route of disabling and enabling the interface.

I agree it's safer and easier to make sure things are disabled first, 
but maybe it's good to have the capability set hdmi timings on the fly 
in the future, it would make the switch faster, same goes for reading edid.

What I meant to ask was whether we should do the same for something like 
dpi_set_data_lines(), that is, disable dpi, update the data_lines 
private data with a new value, and enable dpi again.

>
> This makes me also think that if the output related settings can only be
> changed when the output is off, the apply mechanism is not really needed
> at all for these. Not that it causes any harm, but just a point I
> realized.

Hmm, unfortunately you are right. It's still good to have all the DISPC 
writes only in APPLY though, and it gives us the option to do some 
operation on the fly if needed in the future.

Archit


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

* Re: [RFC 00/17] OMAPDSS: Change way of passing timings from panel driver to interface
  2012-08-08  8:48                   ` Tomi Valkeinen
@ 2012-08-08  9:36                     ` Archit Taneja
  -1 siblings, 0 replies; 122+ messages in thread
From: Archit Taneja @ 2012-08-08  9:24 UTC (permalink / raw)
  To: Tomi Valkeinen; +Cc: linux-fbdev, linux-omap, sumit.semwal, rob

On Wednesday 08 August 2012 02:18 PM, Tomi Valkeinen wrote:
> On Wed, 2012-08-08 at 14:08 +0530, Archit Taneja wrote:
>> On Wednesday 08 August 2012 01:43 PM, Tomi Valkeinen wrote:
>>> On Wed, 2012-08-08 at 13:29 +0530, Archit Taneja wrote:
>>>
>>>> Okay, one thing which I want to align on is that most of these functions
>>>> don't really do the actual configurations. That is, they'll just update
>>>> the private data, and the actual configuration will only happen on enable.
>>>>
>>>> We would want set_timings() op to have a direct impact. But we wouldn't
>>>> want the same for setting the data lines, that could be clubbed with
>>>> other configurations at enable. That's okay, right?
>>>
>>> I'm not sure we want/need set_timings to have direct impact. Changing
>>> the timings on the fly has some problems, like the output size changing
>>> to smaller than the overlays, and we perhaps may need to adjust the
>>> clock dividers (dispc's, DSI PLL's or PRCM's).
>>>
>>> It feels just much easier and safer to require that the mgr is disabled
>>> when these changes are made. And as far as I can see, there shouldn't be
>>> any need to change the timings via the shadow registers, as quickly as
>>> possible and during vblank...
>>
>> That makes sense. But currently set_timings for DPI has a direct impact.
>> HDMI/VENC/SDI take the easier route of disabling and enabling the interface.
>>
>> I agree it's safer and easier to make sure things are disabled first,
>> but maybe it's good to have the capability set hdmi timings on the fly
>> in the future, it would make the switch faster, same goes for reading edid.
>
> When do we need to switch mode quickly? Reading edid should not require
> disabling the output for sure.

I think I'm just finding excuses to find a use for my work done in 
APPLYing manager related registers.

You are right about edid. Changing HDMI timings take a couple of seconds 
now, I was wondering how much that has to do with us completely 
disabling/enabling hdmi. it may be just the slowness of the monitors 
which causes this.

>
> HDMI is a bit broken currently, though. I think we first enable the
> whole stuff, including video output using VGA, then we read EDID, then
> we change the mode.
>
> We should just enable enough of HDMI to be able to read EDID, and start
> the video output with the correct mode. This needs some restructuring of
> the driver, though. I tried it once quickly, but it turned out not to be
> trivial.

Right. Most likely this restructuring would allow us to modify only the 
hdmi timings part when setting a new timing. We could check how much 
time we save then :)

>
>> What I meant to ask was whether we should do the same for something like
>> dpi_set_data_lines(), that is, disable dpi, update the data_lines
>> private data with a new value, and enable dpi again.
>
> Hmm, I think it's better to leave disabling and enabling the output to
> the panel driver. So when the panel driver wants to use
> dpi_set_data_lines(), it needs to first disable the DPI output. If it
> doesn't, dpi_set_data_lines() returns -EBUSY.
>
> Otherwise if the panel driver does something like:
>
> dpi_set_foo()
> dpi_set_bar()
>
> Both of those could first disable output, change setting, enable output.
> Instead the panel should first disable, then call those, and then
> enable.

Right, that makes sense.

Archit


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

* Re: [RFC 00/17] OMAPDSS: Change way of passing timings from panel driver to interface
@ 2012-08-08  9:36                     ` Archit Taneja
  0 siblings, 0 replies; 122+ messages in thread
From: Archit Taneja @ 2012-08-08  9:36 UTC (permalink / raw)
  To: Tomi Valkeinen; +Cc: linux-fbdev, linux-omap, sumit.semwal, rob

On Wednesday 08 August 2012 02:18 PM, Tomi Valkeinen wrote:
> On Wed, 2012-08-08 at 14:08 +0530, Archit Taneja wrote:
>> On Wednesday 08 August 2012 01:43 PM, Tomi Valkeinen wrote:
>>> On Wed, 2012-08-08 at 13:29 +0530, Archit Taneja wrote:
>>>
>>>> Okay, one thing which I want to align on is that most of these functions
>>>> don't really do the actual configurations. That is, they'll just update
>>>> the private data, and the actual configuration will only happen on enable.
>>>>
>>>> We would want set_timings() op to have a direct impact. But we wouldn't
>>>> want the same for setting the data lines, that could be clubbed with
>>>> other configurations at enable. That's okay, right?
>>>
>>> I'm not sure we want/need set_timings to have direct impact. Changing
>>> the timings on the fly has some problems, like the output size changing
>>> to smaller than the overlays, and we perhaps may need to adjust the
>>> clock dividers (dispc's, DSI PLL's or PRCM's).
>>>
>>> It feels just much easier and safer to require that the mgr is disabled
>>> when these changes are made. And as far as I can see, there shouldn't be
>>> any need to change the timings via the shadow registers, as quickly as
>>> possible and during vblank...
>>
>> That makes sense. But currently set_timings for DPI has a direct impact.
>> HDMI/VENC/SDI take the easier route of disabling and enabling the interface.
>>
>> I agree it's safer and easier to make sure things are disabled first,
>> but maybe it's good to have the capability set hdmi timings on the fly
>> in the future, it would make the switch faster, same goes for reading edid.
>
> When do we need to switch mode quickly? Reading edid should not require
> disabling the output for sure.

I think I'm just finding excuses to find a use for my work done in 
APPLYing manager related registers.

You are right about edid. Changing HDMI timings take a couple of seconds 
now, I was wondering how much that has to do with us completely 
disabling/enabling hdmi. it may be just the slowness of the monitors 
which causes this.

>
> HDMI is a bit broken currently, though. I think we first enable the
> whole stuff, including video output using VGA, then we read EDID, then
> we change the mode.
>
> We should just enable enough of HDMI to be able to read EDID, and start
> the video output with the correct mode. This needs some restructuring of
> the driver, though. I tried it once quickly, but it turned out not to be
> trivial.

Right. Most likely this restructuring would allow us to modify only the 
hdmi timings part when setting a new timing. We could check how much 
time we save then :)

>
>> What I meant to ask was whether we should do the same for something like
>> dpi_set_data_lines(), that is, disable dpi, update the data_lines
>> private data with a new value, and enable dpi again.
>
> Hmm, I think it's better to leave disabling and enabling the output to
> the panel driver. So when the panel driver wants to use
> dpi_set_data_lines(), it needs to first disable the DPI output. If it
> doesn't, dpi_set_data_lines() returns -EBUSY.
>
> Otherwise if the panel driver does something like:
>
> dpi_set_foo()
> dpi_set_bar()
>
> Both of those could first disable output, change setting, enable output.
> Instead the panel should first disable, then call those, and then
> enable.

Right, that makes sense.

Archit


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

* [PATCH v2 00/13] OMAPDSS: Change way of passing timings from panel driver to interface
  2012-08-01 10:43 ` Archit Taneja
@ 2012-08-09 11:55   ` Archit Taneja
  -1 siblings, 0 replies; 122+ messages in thread
From: Archit Taneja @ 2012-08-09 11:49 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-fbdev, linux-omap, Archit Taneja

This is a follow up series. The orginal one can be seen here:

http://marc.info/?l=linux-omap&m=134381744304672&w=2

Changes in v2:
- Removed misc fixes out of this set
- Not trying to optimize SDI when setting new timings, using the old strategy
- Added a function for setting size for DSI command mode panels
- Added a fix which ensures the manager sizes is correctly set for rotation in
  command mode panels.

The tree/branch can be found here:

git://gitorious.org/~boddob/linux-omap-dss2/archit-dss2-clone.git pass_timings_interface_2

Archit Taneja (13):
  OMAPDSS: DPI: Maintain our own timings field in driver data
  OMAPDSS: DPI displays: Take care of panel timings in the driver
    itself
  OMAPDSS: DSI: Maintain own copy of timings in driver data
  OMAPDSS: DSI: Add function to set panel size for command mode panels
  OMAPDSS: DSI: Update manager timings on a manual update
  OMAPDSS: HDMI: Use our own omap_video_timings field when setting
    interface timings
  OMAPDSS: HDMI: Add a get_timing function for HDMI interface
  OMAPDSS: HDMI: Add locking for hdmi interface get/set timing
    functions
  OMAPDSS: SDI: Create a function to set timings
  OMAPDSS: SDI: Maintain our own timings field in driver data
  OMAPDSS: VENC: Split VENC into interface and panel driver
  OMAPDSS: VENC: Maintain our own timings field in driver data
  OMAPDSS: VENC: Add a get_timing function for VENC interface

 drivers/video/omap2/displays/panel-acx565akm.c     |   13 +-
 drivers/video/omap2/displays/panel-generic-dpi.c   |    6 +-
 .../omap2/displays/panel-lgphilips-lb035q02.c      |    2 +
 .../omap2/displays/panel-nec-nl8048hl11-01b.c      |    2 +
 drivers/video/omap2/displays/panel-picodlp.c       |    3 +
 .../video/omap2/displays/panel-sharp-ls037v7dw01.c |    2 +
 drivers/video/omap2/displays/panel-taal.c          |   14 ++
 drivers/video/omap2/displays/panel-tfp410.c        |    5 +-
 .../video/omap2/displays/panel-tpo-td043mtea1.c    |    6 +-
 drivers/video/omap2/dss/Makefile                   |    2 +-
 drivers/video/omap2/dss/dpi.c                      |   12 +-
 drivers/video/omap2/dss/dsi.c                      |   86 +++++---
 drivers/video/omap2/dss/dss.h                      |   17 +-
 drivers/video/omap2/dss/hdmi.c                     |   55 +++--
 drivers/video/omap2/dss/hdmi_panel.c               |   12 +-
 drivers/video/omap2/dss/sdi.c                      |   20 +-
 drivers/video/omap2/dss/venc.c                     |  233 ++++++--------------
 drivers/video/omap2/dss/venc_panel.c               |  231 +++++++++++++++++++
 include/video/omapdss.h                            |    9 +-
 19 files changed, 490 insertions(+), 240 deletions(-)
 create mode 100644 drivers/video/omap2/dss/venc_panel.c

-- 
1.7.9.5


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

* [PATCH v2 01/13] OMAPDSS: DPI: Maintain our own timings field in driver data
  2012-08-09 11:55   ` Archit Taneja
@ 2012-08-09 11:56     ` Archit Taneja
  -1 siblings, 0 replies; 122+ messages in thread
From: Archit Taneja @ 2012-08-09 11:49 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-fbdev, linux-omap, Archit Taneja

The DPI driver currently relies on the timings in omap_dss_device struct to
configure the DISPC accordingly. This makes the DPI interface driver dependent
on the omap_dss_device struct.

Make the DPI driver data maintain it's own timings field. The panel driver is
expected to call dpi_set_timings()(renamed to omapdss_dpi_set_timings) to set
these timings before the panel is enabled.

In the set_timings() op, we still ensure that the omap_dss_device timings
(dssdev->panel.timings) are configured. This will later be configured only by
the DPI panel drivers.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/displays/panel-generic-dpi.c   |    4 +++-
 .../omap2/displays/panel-lgphilips-lb035q02.c      |    2 ++
 .../omap2/displays/panel-nec-nl8048hl11-01b.c      |    2 ++
 drivers/video/omap2/displays/panel-picodlp.c       |    3 +++
 .../video/omap2/displays/panel-sharp-ls037v7dw01.c |    2 ++
 drivers/video/omap2/displays/panel-tfp410.c        |    4 +++-
 .../video/omap2/displays/panel-tpo-td043mtea1.c    |    4 +++-
 drivers/video/omap2/dss/dpi.c                      |   11 +++++++----
 include/video/omapdss.h                            |    4 ++--
 9 files changed, 27 insertions(+), 9 deletions(-)

diff --git a/drivers/video/omap2/displays/panel-generic-dpi.c b/drivers/video/omap2/displays/panel-generic-dpi.c
index 69e78a5..8d4e102 100644
--- a/drivers/video/omap2/displays/panel-generic-dpi.c
+++ b/drivers/video/omap2/displays/panel-generic-dpi.c
@@ -565,6 +565,8 @@ static int generic_dpi_panel_power_on(struct omap_dss_device *dssdev)
 	if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
 		return 0;
 
+	omapdss_dpi_set_timings(dssdev, &dssdev->panel.timings);
+
 	r = omapdss_dpi_display_enable(dssdev);
 	if (r)
 		goto err0;
@@ -726,7 +728,7 @@ static void generic_dpi_panel_set_timings(struct omap_dss_device *dssdev,
 
 	mutex_lock(&drv_data->lock);
 
-	dpi_set_timings(dssdev, timings);
+	omapdss_dpi_set_timings(dssdev, 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 8028077..7e52aee 100644
--- a/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c
+++ b/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c
@@ -55,6 +55,8 @@ static int lb035q02_panel_power_on(struct omap_dss_device *dssdev)
 	if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
 		return 0;
 
+	omapdss_dpi_set_timings(dssdev, &dssdev->panel.timings);
+
 	r = omapdss_dpi_display_enable(dssdev);
 	if (r)
 		goto err0;
diff --git a/drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c b/drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c
index b122b0f..e501c40 100644
--- a/drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c
+++ b/drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c
@@ -175,6 +175,8 @@ static int nec_8048_panel_power_on(struct omap_dss_device *dssdev)
 	if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
 		return 0;
 
+	omapdss_dpi_set_timings(dssdev, &dssdev->panel.timings);
+
 	r = omapdss_dpi_display_enable(dssdev);
 	if (r)
 		goto err0;
diff --git a/drivers/video/omap2/displays/panel-picodlp.c b/drivers/video/omap2/displays/panel-picodlp.c
index 2d35bd3..0d7a8ff 100644
--- a/drivers/video/omap2/displays/panel-picodlp.c
+++ b/drivers/video/omap2/displays/panel-picodlp.c
@@ -377,6 +377,9 @@ static int picodlp_panel_power_on(struct omap_dss_device *dssdev)
 	 * then only i2c commands can be successfully sent to dpp2600
 	 */
 	msleep(1000);
+
+	omapdss_dpi_set_timings(dssdev, &dssdev->panel.timings);
+
 	r = omapdss_dpi_display_enable(dssdev);
 	if (r) {
 		dev_err(&dssdev->dev, "failed to enable DPI\n");
diff --git a/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c b/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c
index bd86ba9..1486a81 100644
--- a/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c
+++ b/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c
@@ -142,6 +142,8 @@ static int sharp_ls_power_on(struct omap_dss_device *dssdev)
 	if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
 		return 0;
 
+	omapdss_dpi_set_timings(dssdev, &dssdev->panel.timings);
+
 	r = omapdss_dpi_display_enable(dssdev);
 	if (r)
 		goto err0;
diff --git a/drivers/video/omap2/displays/panel-tfp410.c b/drivers/video/omap2/displays/panel-tfp410.c
index 40cc0cfa..c6f9503 100644
--- a/drivers/video/omap2/displays/panel-tfp410.c
+++ b/drivers/video/omap2/displays/panel-tfp410.c
@@ -65,6 +65,8 @@ static int tfp410_power_on(struct omap_dss_device *dssdev)
 	if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
 		return 0;
 
+	omapdss_dpi_set_timings(dssdev, &dssdev->panel.timings);
+
 	r = omapdss_dpi_display_enable(dssdev);
 	if (r)
 		goto err0;
@@ -231,7 +233,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);
-	dpi_set_timings(dssdev, timings);
+	omapdss_dpi_set_timings(dssdev, timings);
 	mutex_unlock(&ddata->lock);
 }
 
diff --git a/drivers/video/omap2/displays/panel-tpo-td043mtea1.c b/drivers/video/omap2/displays/panel-tpo-td043mtea1.c
index fa7baa6..ecb163e 100644
--- a/drivers/video/omap2/displays/panel-tpo-td043mtea1.c
+++ b/drivers/video/omap2/displays/panel-tpo-td043mtea1.c
@@ -337,6 +337,8 @@ static int tpo_td043_enable_dss(struct omap_dss_device *dssdev)
 	if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
 		return 0;
 
+	omapdss_dpi_set_timings(dssdev, &dssdev->panel.timings);
+
 	r = omapdss_dpi_display_enable(dssdev);
 	if (r)
 		goto err0;
@@ -480,7 +482,7 @@ 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)
 {
-	dpi_set_timings(dssdev, timings);
+	omapdss_dpi_set_timings(dssdev, timings);
 }
 
 static int tpo_td043_check_timings(struct omap_dss_device *dssdev,
diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c
index add47fe..96dd1a4 100644
--- a/drivers/video/omap2/dss/dpi.c
+++ b/drivers/video/omap2/dss/dpi.c
@@ -41,6 +41,7 @@ static struct {
 
 	struct mutex lock;
 
+	struct omap_video_timings timings;
 	struct dss_lcd_mgr_config mgr_config;
 } dpi;
 
@@ -138,7 +139,7 @@ static int dpi_set_dispc_clk(unsigned long pck_req, unsigned long *fck,
 
 static int dpi_set_mode(struct omap_dss_device *dssdev)
 {
-	struct omap_video_timings *t = &dssdev->panel.timings;
+	struct omap_video_timings *t = &dpi.timings;
 	int lck_div = 0, pck_div = 0;
 	unsigned long fck = 0;
 	unsigned long pck;
@@ -293,8 +294,8 @@ void omapdss_dpi_display_disable(struct omap_dss_device *dssdev)
 }
 EXPORT_SYMBOL(omapdss_dpi_display_disable);
 
-void dpi_set_timings(struct omap_dss_device *dssdev,
-			struct omap_video_timings *timings)
+void omapdss_dpi_set_timings(struct omap_dss_device *dssdev,
+		struct omap_video_timings *timings)
 {
 	int r;
 
@@ -302,7 +303,9 @@ void dpi_set_timings(struct omap_dss_device *dssdev,
 
 	mutex_lock(&dpi.lock);
 
+	dpi.timings = *timings;
 	dssdev->panel.timings = *timings;
+
 	if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) {
 		r = dispc_runtime_get();
 		if (r)
@@ -317,7 +320,7 @@ void dpi_set_timings(struct omap_dss_device *dssdev,
 
 	mutex_unlock(&dpi.lock);
 }
-EXPORT_SYMBOL(dpi_set_timings);
+EXPORT_SYMBOL(omapdss_dpi_set_timings);
 
 int dpi_check_timings(struct omap_dss_device *dssdev,
 			struct omap_video_timings *timings)
diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index 6f7581b..ebf2ebd 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -751,8 +751,8 @@ void omapdss_dsi_display_disable(struct omap_dss_device *dssdev,
 
 int omapdss_dpi_display_enable(struct omap_dss_device *dssdev);
 void omapdss_dpi_display_disable(struct omap_dss_device *dssdev);
-void dpi_set_timings(struct omap_dss_device *dssdev,
-			struct omap_video_timings *timings);
+void omapdss_dpi_set_timings(struct omap_dss_device *dssdev,
+		struct omap_video_timings *timings);
 int dpi_check_timings(struct omap_dss_device *dssdev,
 			struct omap_video_timings *timings);
 
-- 
1.7.9.5


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

* [PATCH v2 02/13] OMAPDSS: DPI displays: Take care of panel timings in the driver itself
  2012-08-09 11:55   ` Archit Taneja
@ 2012-08-09 11:56     ` Archit Taneja
  -1 siblings, 0 replies; 122+ messages in thread
From: Archit Taneja @ 2012-08-09 11:49 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-fbdev, linux-omap, Archit Taneja

The timings maintained in omap_dss_device(dssdev->panel.timings) should be
maintained by the panel driver itself. It's the panel drivers responsibility
to update it if a new set of timings is to be configured. The DPI interface
driver shouldn't be responsible of updating the panel timings, it's responsible
of maintianing it's own copy of timings.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/displays/panel-generic-dpi.c   |    2 ++
 drivers/video/omap2/displays/panel-tfp410.c        |    1 +
 .../video/omap2/displays/panel-tpo-td043mtea1.c    |    2 ++
 drivers/video/omap2/dss/dpi.c                      |    1 -
 4 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/video/omap2/displays/panel-generic-dpi.c b/drivers/video/omap2/displays/panel-generic-dpi.c
index 8d4e102..a07e18c 100644
--- a/drivers/video/omap2/displays/panel-generic-dpi.c
+++ b/drivers/video/omap2/displays/panel-generic-dpi.c
@@ -730,6 +730,8 @@ static void generic_dpi_panel_set_timings(struct omap_dss_device *dssdev,
 
 	omapdss_dpi_set_timings(dssdev, timings);
 
+	dssdev->panel.timings = *timings;
+
 	mutex_unlock(&drv_data->lock);
 }
 
diff --git a/drivers/video/omap2/displays/panel-tfp410.c b/drivers/video/omap2/displays/panel-tfp410.c
index c6f9503..9397236 100644
--- a/drivers/video/omap2/displays/panel-tfp410.c
+++ b/drivers/video/omap2/displays/panel-tfp410.c
@@ -234,6 +234,7 @@ static void tfp410_set_timings(struct omap_dss_device *dssdev,
 
 	mutex_lock(&ddata->lock);
 	omapdss_dpi_set_timings(dssdev, timings);
+	dssdev->panel.timings = *timings;
 	mutex_unlock(&ddata->lock);
 }
 
diff --git a/drivers/video/omap2/displays/panel-tpo-td043mtea1.c b/drivers/video/omap2/displays/panel-tpo-td043mtea1.c
index ecb163e..3f47f5f 100644
--- a/drivers/video/omap2/displays/panel-tpo-td043mtea1.c
+++ b/drivers/video/omap2/displays/panel-tpo-td043mtea1.c
@@ -483,6 +483,8 @@ static void tpo_td043_set_timings(struct omap_dss_device *dssdev,
 		struct omap_video_timings *timings)
 {
 	omapdss_dpi_set_timings(dssdev, timings);
+
+	dssdev->panel.timings = *timings;
 }
 
 static int tpo_td043_check_timings(struct omap_dss_device *dssdev,
diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c
index 96dd1a4..6c43d80 100644
--- a/drivers/video/omap2/dss/dpi.c
+++ b/drivers/video/omap2/dss/dpi.c
@@ -304,7 +304,6 @@ void omapdss_dpi_set_timings(struct omap_dss_device *dssdev,
 	mutex_lock(&dpi.lock);
 
 	dpi.timings = *timings;
-	dssdev->panel.timings = *timings;
 
 	if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) {
 		r = dispc_runtime_get();
-- 
1.7.9.5


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

* [PATCH v2 03/13] OMAPDSS: DSI: Maintain own copy of timings in driver data
  2012-08-09 11:55   ` Archit Taneja
@ 2012-08-09 11:56     ` Archit Taneja
  -1 siblings, 0 replies; 122+ messages in thread
From: Archit Taneja @ 2012-08-09 11:49 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-fbdev, linux-omap, Archit Taneja

The DSI driver currently relies on the timings in omap_dss_device struct to
configure the DISPC and DSI blocks accordingly. This makes the DSI interface
driver dependent on the omap_dss_device struct.

Make the DSI driver data maintain it's own timings field. A DSI video mode panel
driver is expected to call omapdss_dsi_set_timings() to set these timings before
the panel is enabled.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/dss/dsi.c |   58 +++++++++++++++++++++++++----------------
 include/video/omapdss.h       |    2 ++
 2 files changed, 38 insertions(+), 22 deletions(-)

diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index 27c27c4..815b606 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -333,6 +333,7 @@ struct dsi_data {
 	unsigned scp_clk_refcount;
 
 	struct dss_lcd_mgr_config mgr_config;
+	struct omap_video_timings timings;
 };
 
 struct dsi_packet_sent_handler_data {
@@ -3607,9 +3608,10 @@ static void dsi_config_vp_num_line_buffers(struct omap_dss_device *dssdev)
 	int num_line_buffers;
 
 	if (dssdev->panel.dsi_mode == OMAP_DSS_DSI_VIDEO_MODE) {
+		struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
 		int bpp = dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt);
 		unsigned line_buf_size = dsi_get_line_buf_size(dsidev);
-		struct omap_video_timings *timings = &dssdev->panel.timings;
+		struct omap_video_timings *timings = &dsi->timings;
 		/*
 		 * Don't use line buffers if width is greater than the video
 		 * port's line buffer size
@@ -3738,7 +3740,7 @@ static void dsi_config_cmd_mode_interleaving(struct omap_dss_device *dssdev)
 	int ddr_clk_pre, ddr_clk_post, enter_hs_mode_lat, exit_hs_mode_lat;
 	int tclk_trail, ths_exit, exiths_clk;
 	bool ddr_alwon;
-	struct omap_video_timings *timings = &dssdev->panel.timings;
+	struct omap_video_timings *timings = &dsi->timings;
 	int bpp = dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt);
 	int ndl = dsi->num_lanes_used - 1;
 	const struct omapdss_clock_config *clks;
@@ -3996,7 +3998,7 @@ static void dsi_proto_timings(struct omap_dss_device *dssdev)
 		int vbp = dssdev->panel.dsi_vm_data.vbp;
 		int window_sync = dssdev->panel.dsi_vm_data.window_sync;
 		bool hsync_end = dssdev->panel.dsi_vm_data.vp_hsync_end;
-		struct omap_video_timings *timings = &dssdev->panel.timings;
+		struct omap_video_timings *timings = &dsi->timings;
 		int bpp = dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt);
 		int tl, t_he, width_bytes;
 
@@ -4105,6 +4107,7 @@ 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 dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
 	int bpp = dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt);
 	u8 data_type;
 	u16 word_count;
@@ -4135,7 +4138,7 @@ int dsi_enable_video_output(struct omap_dss_device *dssdev, int channel)
 		/* MODE, 1 = video mode */
 		REG_FLD_MOD(dsidev, DSI_VC_CTRL(channel), 1, 4, 4);
 
-		word_count = DIV_ROUND_UP(dssdev->panel.timings.x_res * bpp, 8);
+		word_count = DIV_ROUND_UP(dsi->timings.x_res * bpp, 8);
 
 		dsi_vc_write_long_header(dsidev, channel, data_type,
 				word_count, 0);
@@ -4370,7 +4373,6 @@ static int dsi_display_init_dispc(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_video_timings timings;
 	const struct omapdss_clock_config *clks;
 	int r, lcd_id;
 	u32 irq = 0;
@@ -4380,14 +4382,14 @@ static int dsi_display_init_dispc(struct omap_dss_device *dssdev)
 
 		dssdev->driver->get_resolution(dssdev, &dw, &dh);
 
-		timings.x_res = dw;
-		timings.y_res = dh;
-		timings.hsw = 1;
-		timings.hfp = 1;
-		timings.hbp = 1;
-		timings.vsw = 1;
-		timings.vfp = 0;
-		timings.vbp = 0;
+		dsi->timings.x_res = dw;
+		dsi->timings.y_res = dh;
+		dsi->timings.hsw = 1;
+		dsi->timings.hfp = 1;
+		dsi->timings.hbp = 1;
+		dsi->timings.vsw = 1;
+		dsi->timings.vfp = 0;
+		dsi->timings.vbp = 0;
 
 		irq = dispc_mgr_get_framedone_irq(dssdev->manager->id);
 
@@ -4401,8 +4403,6 @@ static int dsi_display_init_dispc(struct omap_dss_device *dssdev)
 		dsi->mgr_config.stallmode = true;
 		dsi->mgr_config.fifohandcheck = true;
 	} else {
-		timings = dssdev->panel.timings;
-
 		dsi->mgr_config.stallmode = false;
 		dsi->mgr_config.fifohandcheck = false;
 	}
@@ -4411,14 +4411,14 @@ static int dsi_display_init_dispc(struct omap_dss_device *dssdev)
 	 * override interlace, logic level and edge related parameters in
 	 * omap_video_timings with default values
 	 */
-	timings.interlace = false;
-	timings.hsync_level = OMAPDSS_SIG_ACTIVE_HIGH;
-	timings.vsync_level = OMAPDSS_SIG_ACTIVE_HIGH;
-	timings.data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE;
-	timings.de_level = OMAPDSS_SIG_ACTIVE_HIGH;
-	timings.sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES;
+	dsi->timings.interlace = false;
+	dsi->timings.hsync_level = OMAPDSS_SIG_ACTIVE_HIGH;
+	dsi->timings.vsync_level = OMAPDSS_SIG_ACTIVE_HIGH;
+	dsi->timings.data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE;
+	dsi->timings.de_level = OMAPDSS_SIG_ACTIVE_HIGH;
+	dsi->timings.sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES;
 
-	dss_mgr_set_timings(dssdev->manager, &timings);
+	dss_mgr_set_timings(dssdev->manager, &dsi->timings);
 
 	switch (dssdev->manager->id) {
 	case OMAP_DSS_CHANNEL_LCD:
@@ -4688,6 +4688,20 @@ 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,
+		struct omap_video_timings *timings)
+{
+	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
+
+	mutex_lock(&dsi->lock);
+
+	dsi->timings = *timings;
+
+	mutex_unlock(&dsi->lock);
+}
+EXPORT_SYMBOL(omapdss_dsi_set_timings);
+
 static int __init dsi_init_display(struct omap_dss_device *dssdev)
 {
 	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index ebf2ebd..a2cd133 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -736,6 +736,8 @@ int omap_dispc_wait_for_irq_interruptible_timeout(u32 irqmask,
 void omapdss_dsi_vc_enable_hs(struct omap_dss_device *dssdev, 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,
+		struct omap_video_timings *timings);
 
 int omap_dsi_update(struct omap_dss_device *dssdev, int channel,
 		void (*callback)(int, void *), void *data);
-- 
1.7.9.5


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

* [PATCH v2 04/13] OMAPDSS: DSI: Add function to set panel size for command mode panels
  2012-08-09 11:55   ` Archit Taneja
@ 2012-08-09 11:56     ` Archit Taneja
  -1 siblings, 0 replies; 122+ messages in thread
From: Archit Taneja @ 2012-08-09 11:49 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-fbdev, linux-omap, Archit Taneja

DSI command mode panels don't need to configure a full set of timings to
configure DSI, they only require the width and the height of the panel in
pixels.

Use omapdss_dsi_set_size for command mode panels, omapdss_dsi_set_timings is
meant for video mode panels. When performing rotation via chaning the address
mode of the panel, we would need to swap width and height when doing 90 or 270
rotation. Make sure that omapdss_dsi_set_size() makes the new width and height
visible to DSI.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/displays/panel-taal.c |   14 ++++++++++++++
 drivers/video/omap2/dss/dsi.c             |   23 ++++++++++++++++-------
 include/video/omapdss.h                   |    1 +
 3 files changed, 31 insertions(+), 7 deletions(-)

diff --git a/drivers/video/omap2/displays/panel-taal.c b/drivers/video/omap2/displays/panel-taal.c
index 3f5acc7..c3bca2f 100644
--- a/drivers/video/omap2/displays/panel-taal.c
+++ b/drivers/video/omap2/displays/panel-taal.c
@@ -1060,6 +1060,9 @@ static int taal_power_on(struct omap_dss_device *dssdev)
 		goto err0;
 	};
 
+	omapdss_dsi_set_size(dssdev, dssdev->panel.timings.x_res,
+		dssdev->panel.timings.y_res);
+
 	r = omapdss_dsi_display_enable(dssdev);
 	if (r) {
 		dev_err(&dssdev->dev, "failed to enable DSI\n");
@@ -1487,6 +1490,7 @@ static int taal_get_te(struct omap_dss_device *dssdev)
 static int taal_rotate(struct omap_dss_device *dssdev, u8 rotate)
 {
 	struct taal_data *td = dev_get_drvdata(&dssdev->dev);
+	u16 dw, dh;
 	int r;
 
 	dev_dbg(&dssdev->dev, "rotate %d\n", rotate);
@@ -1508,6 +1512,16 @@ static int taal_rotate(struct omap_dss_device *dssdev, u8 rotate)
 			goto err;
 	}
 
+	if (rotate == 0 || rotate == 2) {
+		dw = dssdev->panel.timings.x_res;
+		dh = dssdev->panel.timings.y_res;
+	} else {
+		dw = dssdev->panel.timings.y_res;
+		dh = dssdev->panel.timings.x_res;
+	}
+
+	omapdss_dsi_set_size(dssdev, dw, dh);
+
 	td->rotate = rotate;
 
 	dsi_bus_unlock(dssdev);
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index 815b606..eb364d4 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -4330,7 +4330,8 @@ int omap_dsi_update(struct omap_dss_device *dssdev, int channel,
 	dsi->framedone_callback = callback;
 	dsi->framedone_data = data;
 
-	dssdev->driver->get_resolution(dssdev, &dw, &dh);
+	dw = dsi->timings.x_res;
+	dh = dsi->timings.y_res;
 
 #ifdef DEBUG
 	dsi->update_bytes = dw * dh *
@@ -4378,12 +4379,6 @@ static int dsi_display_init_dispc(struct omap_dss_device *dssdev)
 	u32 irq = 0;
 
 	if (dssdev->panel.dsi_mode == OMAP_DSS_DSI_CMD_MODE) {
-		u16 dw, dh;
-
-		dssdev->driver->get_resolution(dssdev, &dw, &dh);
-
-		dsi->timings.x_res = dw;
-		dsi->timings.y_res = dh;
 		dsi->timings.hsw = 1;
 		dsi->timings.hfp = 1;
 		dsi->timings.hbp = 1;
@@ -4702,6 +4697,20 @@ 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)
+{
+	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
+
+	mutex_lock(&dsi->lock);
+
+	dsi->timings.x_res = w;
+	dsi->timings.y_res = h;
+
+	mutex_unlock(&dsi->lock);
+}
+EXPORT_SYMBOL(omapdss_dsi_set_size);
+
 static int __init dsi_init_display(struct omap_dss_device *dssdev)
 {
 	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index a2cd133..a85b3fb 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -738,6 +738,7 @@ void omapdss_dsi_vc_enable_hs(struct omap_dss_device *dssdev, int channel,
 int omapdss_dsi_enable_te(struct omap_dss_device *dssdev, bool enable);
 void omapdss_dsi_set_timings(struct omap_dss_device *dssdev,
 		struct omap_video_timings *timings);
+void omapdss_dsi_set_size(struct omap_dss_device *dssdev, u16 w, u16 h);
 
 int omap_dsi_update(struct omap_dss_device *dssdev, int channel,
 		void (*callback)(int, void *), void *data);
-- 
1.7.9.5


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

* [PATCH v2 05/13] OMAPDSS: DSI: Update manager timings on a manual update
  2012-08-09 11:55   ` Archit Taneja
@ 2012-08-09 11:56     ` Archit Taneja
  -1 siblings, 0 replies; 122+ messages in thread
From: Archit Taneja @ 2012-08-09 11:49 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-fbdev, linux-omap, Archit Taneja

During a command mode update using DISPC video port, we may need to swap the
connected overlay manager's width and height when 90 or 270 degree rotation is
done via the panel by changing it's address mode.

Call dss_mgr_set_timings() in update_screen_dispc() before starting the manager
update. The new manager size is updated in the 'timings' field of DSI driver's
private data via omapdss_dsi_set_size(). A panel driver is expected to call this
when performing rotation.

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

diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index eb364d4..6e1c74b 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -4180,8 +4180,7 @@ void dsi_disable_video_output(struct omap_dss_device *dssdev, int channel)
 }
 EXPORT_SYMBOL(dsi_disable_video_output);
 
-static void dsi_update_screen_dispc(struct omap_dss_device *dssdev,
-		u16 w, u16 h)
+static void dsi_update_screen_dispc(struct omap_dss_device *dssdev)
 {
 	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
 	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
@@ -4195,6 +4194,8 @@ static void dsi_update_screen_dispc(struct omap_dss_device *dssdev,
 	int r;
 	const unsigned channel = dsi->update_channel;
 	const unsigned line_buf_size = dsi_get_line_buf_size(dsidev);
+	u16 w = dsi->timings.x_res;
+	u16 h = dsi->timings.y_res;
 
 	DSSDBG("dsi_update_screen_dispc(%dx%d)\n", w, h);
 
@@ -4244,6 +4245,8 @@ 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_start_update(dssdev->manager);
 
 	if (dsi->te_enabled) {
@@ -4337,7 +4340,7 @@ int omap_dsi_update(struct omap_dss_device *dssdev, int channel,
 	dsi->update_bytes = dw * dh *
 		dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt) / 8;
 #endif
-	dsi_update_screen_dispc(dssdev, dw, dh);
+	dsi_update_screen_dispc(dssdev);
 
 	return 0;
 }
-- 
1.7.9.5


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

* [PATCH v2 06/13] OMAPDSS: HDMI: Use our own omap_video_timings field when setting interface timings
  2012-08-09 11:55   ` Archit Taneja
@ 2012-08-09 11:56     ` Archit Taneja
  -1 siblings, 0 replies; 122+ messages in thread
From: Archit Taneja @ 2012-08-09 11:49 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-fbdev, linux-omap, Archit Taneja

The hdmi driver currently updates only the 'code' member of hdmi_config when
the op omapdss_hdmi_display_set_timing() is called by the hdmi panel driver.
The 'timing' field of hdmi_config is updated only when hdmi_power_on is called.
It makes more sense to configure the whole hdmi_config field in the set_timing
op called by the panel driver. This way, we don't need to call both functions
to ensure that our hdmi_config is configured correctly. Also, we don't need to
calculate hdmi_config during hdmi_power_on, or rely on the omap_video_timings
in the panel's omap_dss_device struct.

A default timing is now configured in hdmi's probe if the panel driver doesn't
set any timing, or doesn't set a valid timing before enabling the panel. Also,
when setting manager timings, use the omap_video_timing calculated by
hdmi_get_timings(), this returns the timings as specified in the CEA/VESA
tables, don't use the one provided by the panel driver directly.

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

diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index 8a9630b..7e38ffd 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -485,7 +485,8 @@ static inline unsigned long hdmi_get_pixel_clock(void)
 #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);
+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);
diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c
index 6635b09..bdf1c33 100644
--- a/drivers/video/omap2/dss/hdmi.c
+++ b/drivers/video/omap2/dss/hdmi.c
@@ -462,7 +462,6 @@ static int hdmi_power_on(struct omap_dss_device *dssdev)
 {
 	const struct omapdss_clock_config *clks;
 	int r;
-	const struct hdmi_config *timing;
 	struct omap_video_timings *p;
 	unsigned long phy;
 
@@ -472,22 +471,10 @@ static int hdmi_power_on(struct omap_dss_device *dssdev)
 
 	dss_mgr_disable(dssdev->manager);
 
-	p = &dssdev->panel.timings;
+	p = &hdmi.ip_data.cfg.timings;
 
-	DSSDBG("hdmi_power_on x_res= %d y_res = %d\n",
-		dssdev->panel.timings.x_res,
-		dssdev->panel.timings.y_res);
+	DSSDBG("hdmi_power_on x_res= %d y_res = %d\n", p->x_res, p->y_res);
 
-	timing = hdmi_get_timings();
-	if (timing == NULL) {
-		/* HDMI code 4 corresponds to 640 * 480 VGA */
-		hdmi.ip_data.cfg.cm.code = 4;
-		/* DVI mode 1 corresponds to HDMI 0 to DVI */
-		hdmi.ip_data.cfg.cm.mode = HDMI_DVI;
-		hdmi.ip_data.cfg = vesa_timings[0];
-	} else {
-		hdmi.ip_data.cfg = *timing;
-	}
 	phy = p->pixel_clock;
 
 	hdmi_compute_pll(phy, &hdmi.ip_data.pll_data);
@@ -525,7 +512,7 @@ static int hdmi_power_on(struct omap_dss_device *dssdev)
 	dispc_enable_gamma_table(0);
 
 	/* tv size */
-	dss_mgr_set_timings(dssdev->manager, &dssdev->panel.timings);
+	dss_mgr_set_timings(dssdev->manager, p);
 
 	r = hdmi.ip_data.ops->video_enable(&hdmi.ip_data);
 	if (r)
@@ -571,13 +558,18 @@ 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_device *dssdev,
+		struct omap_video_timings *timings)
 {
 	struct hdmi_cm cm;
+	const struct hdmi_config *t;
+
+	cm = hdmi_get_code(timings);
+	hdmi.ip_data.cfg.cm = cm;
 
-	cm = hdmi_get_code(&dssdev->panel.timings);
-	hdmi.ip_data.cfg.cm.code = cm.code;
-	hdmi.ip_data.cfg.cm.mode = cm.mode;
+	t = hdmi_get_timings();
+	if (t != NULL)
+		hdmi.ip_data.cfg = *t;
 
 	if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) {
 		int r;
@@ -588,7 +580,7 @@ void omapdss_hdmi_display_set_timing(struct omap_dss_device *dssdev)
 		if (r)
 			DSSERR("failed to power on device\n");
 	} else {
-		dss_mgr_set_timings(dssdev->manager, &dssdev->panel.timings);
+		dss_mgr_set_timings(dssdev->manager, &t->timings);
 	}
 }
 
@@ -933,6 +925,13 @@ static int __init omapdss_hdmihw_probe(struct platform_device *pdev)
 	hdmi.ip_data.core_av_offset = HDMI_CORE_AV;
 	hdmi.ip_data.pll_offset = HDMI_PLLCTRL;
 	hdmi.ip_data.phy_offset = HDMI_PHY;
+
+	/*
+	 * initialize hdmi timings to default value:
+	 * HDMI code 4(VGA) and HDMI mode 1(DVI)
+	 */
+	hdmi.ip_data.cfg = vesa_timings[0];
+
 	mutex_init(&hdmi.ip_data.lock);
 
 	hdmi_panel_init();
diff --git a/drivers/video/omap2/dss/hdmi_panel.c b/drivers/video/omap2/dss/hdmi_panel.c
index e10844f..8dce206 100644
--- a/drivers/video/omap2/dss/hdmi_panel.c
+++ b/drivers/video/omap2/dss/hdmi_panel.c
@@ -336,8 +336,8 @@ static void hdmi_set_timings(struct omap_dss_device *dssdev,
 	 */
 	hdmi_panel_audio_disable(dssdev);
 
+	omapdss_hdmi_display_set_timing(dssdev, timings);
 	dssdev->panel.timings = *timings;
-	omapdss_hdmi_display_set_timing(dssdev);
 
 	mutex_unlock(&hdmi.lock);
 }
-- 
1.7.9.5


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

* [PATCH v2 07/13] OMAPDSS: HDMI: Add a get_timing function for HDMI interface
  2012-08-09 11:55   ` Archit Taneja
@ 2012-08-09 11:56     ` Archit Taneja
  -1 siblings, 0 replies; 122+ messages in thread
From: Archit Taneja @ 2012-08-09 11:49 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-fbdev, linux-omap, Archit Taneja

Add function omapdss_hdmi_display_get_timing() which returns the timings
maintained by the HDMI interface driver in it's hdmi_config field. This
prevents the need for the panel driver to configure default timings in it's
probe.

This function is just intended to be used once during the panel driver's probe.
It makes sense for those interfaces which can be configured to a default timing.

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

diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index 7e38ffd..df49c5d 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -485,6 +485,8 @@ static inline unsigned long hdmi_get_pixel_clock(void)
 #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_get_timing(struct omap_dss_device *dssdev,
+		struct omap_video_timings *timings);
 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,
diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c
index bdf1c33..f577c8e 100644
--- a/drivers/video/omap2/dss/hdmi.c
+++ b/drivers/video/omap2/dss/hdmi.c
@@ -544,6 +544,12 @@ static void hdmi_power_off(struct omap_dss_device *dssdev)
 	hdmi_runtime_put();
 }
 
+void omapdss_hdmi_display_get_timing(struct omap_dss_device *dssdev,
+		struct omap_video_timings *timings)
+{
+	*timings = hdmi.ip_data.cfg.timings;
+}
+
 int omapdss_hdmi_display_check_timing(struct omap_dss_device *dssdev,
 					struct omap_video_timings *timings)
 {
diff --git a/drivers/video/omap2/dss/hdmi_panel.c b/drivers/video/omap2/dss/hdmi_panel.c
index 8dce206..8473193 100644
--- a/drivers/video/omap2/dss/hdmi_panel.c
+++ b/drivers/video/omap2/dss/hdmi_panel.c
@@ -41,13 +41,13 @@ static struct {
 
 static int hdmi_panel_probe(struct omap_dss_device *dssdev)
 {
+	struct omap_video_timings timings;
+
 	DSSDBG("ENTER hdmi_panel_probe\n");
 
-	dssdev->panel.timings = (struct omap_video_timings)
-			{ 640, 480, 25175, 96, 16, 48, 2, 11, 31,
-				OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
-				false,
-			};
+	omapdss_hdmi_display_get_timing(dssdev, &timings);
+
+	dssdev->panel.timings = timings;
 
 	DSSDBG("hdmi_panel_probe x_res= %d y_res = %d\n",
 		dssdev->panel.timings.x_res,
-- 
1.7.9.5


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

* [PATCH v2 08/13] OMAPDSS: HDMI: Add locking for hdmi interface get/set timing functions
  2012-08-09 11:55   ` Archit Taneja
@ 2012-08-09 11:56     ` Archit Taneja
  -1 siblings, 0 replies; 122+ messages in thread
From: Archit Taneja @ 2012-08-09 11:49 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-fbdev, linux-omap, Archit Taneja

The hdmi interface driver exposes functions to the hdmi panel driver to
get and configure the interface timings maintained by the hdmi driver.

These timings(stored in hdmi.ip_data.cfg) should be protected by the hdmi lock
to ensure they are called sequentially, this is similar to how hdmi enable and
disable functions need locking.

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

diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c
index f577c8e..171c695 100644
--- a/drivers/video/omap2/dss/hdmi.c
+++ b/drivers/video/omap2/dss/hdmi.c
@@ -547,7 +547,11 @@ static void hdmi_power_off(struct omap_dss_device *dssdev)
 void omapdss_hdmi_display_get_timing(struct omap_dss_device *dssdev,
 		struct omap_video_timings *timings)
 {
+	mutex_lock(&hdmi.lock);
+
 	*timings = hdmi.ip_data.cfg.timings;
+
+	mutex_unlock(&hdmi.lock);
 }
 
 int omapdss_hdmi_display_check_timing(struct omap_dss_device *dssdev,
@@ -570,6 +574,8 @@ void omapdss_hdmi_display_set_timing(struct omap_dss_device *dssdev,
 	struct hdmi_cm cm;
 	const struct hdmi_config *t;
 
+	mutex_lock(&hdmi.lock);
+
 	cm = hdmi_get_code(timings);
 	hdmi.ip_data.cfg.cm = cm;
 
@@ -588,6 +594,8 @@ void omapdss_hdmi_display_set_timing(struct omap_dss_device *dssdev,
 	} else {
 		dss_mgr_set_timings(dssdev->manager, &t->timings);
 	}
+
+	mutex_unlock(&hdmi.lock);
 }
 
 static void hdmi_dump_regs(struct seq_file *s)
-- 
1.7.9.5


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

* [PATCH v2 09/13] OMAPDSS: SDI: Create a function to set timings
  2012-08-09 11:55   ` Archit Taneja
@ 2012-08-09 11:56     ` Archit Taneja
  -1 siblings, 0 replies; 122+ messages in thread
From: Archit Taneja @ 2012-08-09 11:49 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-fbdev, linux-omap, Archit Taneja

Create function omapdss_sdi_set_timings(). Configuring new timings is done the
same way as before, SDI is disabled, and re-enabled with the new timings in
dssdev. This just moves the code from the panel drivers to the SDI driver.

The panel drivers shouldn't be aware of how SDI manages to configure a new set
of timings. This should be taken care of by the SDI driver itself.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/displays/panel-acx565akm.c |   13 +------------
 drivers/video/omap2/dss/sdi.c                  |   17 +++++++++++++++++
 include/video/omapdss.h                        |    2 ++
 3 files changed, 20 insertions(+), 12 deletions(-)

diff --git a/drivers/video/omap2/displays/panel-acx565akm.c b/drivers/video/omap2/displays/panel-acx565akm.c
index eaeed43..11bdc88 100644
--- a/drivers/video/omap2/displays/panel-acx565akm.c
+++ b/drivers/video/omap2/displays/panel-acx565akm.c
@@ -731,18 +731,7 @@ 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)
 {
-	int r;
-
-	if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
-		omapdss_sdi_display_disable(dssdev);
-
-	dssdev->panel.timings = *timings;
-
-	if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) {
-		r = omapdss_sdi_display_enable(dssdev);
-		if (r)
-			dev_err(&dssdev->dev, "%s enable failed\n", __func__);
-	}
+	omapdss_sdi_set_timings(dssdev, timings);
 }
 
 static int acx_panel_check_timings(struct omap_dss_device *dssdev,
diff --git a/drivers/video/omap2/dss/sdi.c b/drivers/video/omap2/dss/sdi.c
index 5d31699..0474962 100644
--- a/drivers/video/omap2/dss/sdi.c
+++ b/drivers/video/omap2/dss/sdi.c
@@ -146,6 +146,23 @@ void omapdss_sdi_display_disable(struct omap_dss_device *dssdev)
 }
 EXPORT_SYMBOL(omapdss_sdi_display_disable);
 
+void omapdss_sdi_set_timings(struct omap_dss_device *dssdev,
+		struct omap_video_timings *timings)
+{
+	int r;
+
+	dssdev->panel.timings = *timings;
+
+	if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) {
+		omapdss_sdi_display_disable(dssdev);
+
+		r = omapdss_sdi_display_enable(dssdev);
+		if (r)
+			DSSERR("failed to set new timings\n");
+	}
+}
+EXPORT_SYMBOL(omapdss_sdi_set_timings);
+
 static int __init sdi_init_display(struct omap_dss_device *dssdev)
 {
 	DSSDBG("SDI init\n");
diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index a85b3fb..c5c013e 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -761,6 +761,8 @@ int dpi_check_timings(struct omap_dss_device *dssdev,
 
 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,
+		struct omap_video_timings *timings);
 
 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] 122+ messages in thread

* [PATCH v2 10/13] OMAPDSS: SDI: Maintain our own timings field in driver data
  2012-08-09 11:55   ` Archit Taneja
@ 2012-08-09 11:56     ` Archit Taneja
  -1 siblings, 0 replies; 122+ messages in thread
From: Archit Taneja @ 2012-08-09 11:49 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-fbdev, linux-omap, Archit Taneja

The SDI driver currently relies on the timings in omap_dss_device struct to
configure the DISPC accordingly. This makes the SDI interface driver dependent
on the omap_dss_device struct.

Make the SDI driver data maintain it's own timings field. The panel driver is
expected to call omapdss_sdi_set_timings() to set these timings before the panel
is enabled.

Make the SDI panel driver configure the new timings is the omap_dss_device
struct(dssdev->panel.timings). The SDI driver is responsible for maintaining
only it's own copy of timings.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/displays/panel-acx565akm.c |    4 ++++
 drivers/video/omap2/dss/sdi.c                  |    5 +++--
 2 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/video/omap2/displays/panel-acx565akm.c b/drivers/video/omap2/displays/panel-acx565akm.c
index 11bdc88..77fe59f 100644
--- a/drivers/video/omap2/displays/panel-acx565akm.c
+++ b/drivers/video/omap2/displays/panel-acx565akm.c
@@ -600,6 +600,8 @@ static int acx_panel_power_on(struct omap_dss_device *dssdev)
 
 	mutex_lock(&md->mutex);
 
+	omapdss_sdi_set_timings(dssdev, &dssdev->panel.timings);
+
 	r = omapdss_sdi_display_enable(dssdev);
 	if (r) {
 		pr_err("%s sdi enable failed\n", __func__);
@@ -732,6 +734,8 @@ static void acx_panel_set_timings(struct omap_dss_device *dssdev,
 		struct omap_video_timings *timings)
 {
 	omapdss_sdi_set_timings(dssdev, timings);
+
+	dssdev->panel.timings = *timings;
 }
 
 static int acx_panel_check_timings(struct omap_dss_device *dssdev,
diff --git a/drivers/video/omap2/dss/sdi.c b/drivers/video/omap2/dss/sdi.c
index 0474962..243e96d 100644
--- a/drivers/video/omap2/dss/sdi.c
+++ b/drivers/video/omap2/dss/sdi.c
@@ -34,6 +34,7 @@ static struct {
 	struct regulator *vdds_sdi_reg;
 
 	struct dss_lcd_mgr_config mgr_config;
+	struct omap_video_timings timings;
 } sdi;
 
 static void sdi_config_lcd_manager(struct omap_dss_device *dssdev)
@@ -51,7 +52,7 @@ static void sdi_config_lcd_manager(struct omap_dss_device *dssdev)
 
 int omapdss_sdi_display_enable(struct omap_dss_device *dssdev)
 {
-	struct omap_video_timings *t = &dssdev->panel.timings;
+	struct omap_video_timings *t = &sdi.timings;
 	struct dss_clock_info dss_cinfo;
 	struct dispc_clock_info dispc_cinfo;
 	unsigned long pck;
@@ -151,7 +152,7 @@ void omapdss_sdi_set_timings(struct omap_dss_device *dssdev,
 {
 	int r;
 
-	dssdev->panel.timings = *timings;
+	sdi.timings = *timings;
 
 	if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) {
 		omapdss_sdi_display_disable(dssdev);
-- 
1.7.9.5


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

* [PATCH v2 11/13] OMAPDSS: VENC: Split VENC into interface and panel driver
  2012-08-09 11:55   ` Archit Taneja
@ 2012-08-09 11:56     ` Archit Taneja
  -1 siblings, 0 replies; 122+ messages in thread
From: Archit Taneja @ 2012-08-09 11:49 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-fbdev, linux-omap, Archit Taneja

The current venc.c driver contains both the interface and panel driver code.
This makes the driver hard to read, and difficult to understand the work split
between the interface and panel driver and the how the locking works.

This also makes it easier to clearly define the VENC interface ops called by the
panel driver.

Split venc.c into venc.c and venc_panel.c representing the interface and panel
driver respectively. This split is done along the lines of the HDMI interface
and panel drivers.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/dss/Makefile     |    2 +-
 drivers/video/omap2/dss/dss.h        |   10 ++
 drivers/video/omap2/dss/venc.c       |  208 ++++++++----------------------
 drivers/video/omap2/dss/venc_panel.c |  231 ++++++++++++++++++++++++++++++++++
 4 files changed, 295 insertions(+), 156 deletions(-)
 create mode 100644 drivers/video/omap2/dss/venc_panel.c

diff --git a/drivers/video/omap2/dss/Makefile b/drivers/video/omap2/dss/Makefile
index 5c450b0..30a48fb 100644
--- a/drivers/video/omap2/dss/Makefile
+++ b/drivers/video/omap2/dss/Makefile
@@ -3,7 +3,7 @@ omapdss-y := core.o dss.o dss_features.o dispc.o dispc_coefs.o display.o \
 	manager.o overlay.o apply.o
 omapdss-$(CONFIG_OMAP2_DSS_DPI) += dpi.o
 omapdss-$(CONFIG_OMAP2_DSS_RFBI) += rfbi.o
-omapdss-$(CONFIG_OMAP2_DSS_VENC) += venc.o
+omapdss-$(CONFIG_OMAP2_DSS_VENC) += venc.o venc_panel.o
 omapdss-$(CONFIG_OMAP2_DSS_SDI) += sdi.o
 omapdss-$(CONFIG_OMAP2_DSS_DSI) += dsi.o
 omapdss-$(CONFIG_OMAP4_DSS_HDMI) += hdmi.o \
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index df49c5d..69b6ab9 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -470,6 +470,16 @@ 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,
+		struct omap_video_timings *timings);
+int omapdss_venc_check_timings(struct omap_dss_device *dssdev,
+		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);
+int venc_panel_init(void);
+void venc_panel_exit(void);
 
 /* HDMI */
 #ifdef CONFIG_OMAP4_DSS_HDMI
diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c
index 3a22087..ffca542 100644
--- a/drivers/video/omap2/dss/venc.c
+++ b/drivers/video/omap2/dss/venc.c
@@ -427,6 +427,10 @@ static int venc_power_on(struct omap_dss_device *dssdev)
 	u32 l;
 	int r;
 
+	r = venc_runtime_get();
+	if (r)
+		goto err0;
+
 	venc_reset();
 	venc_write_config(venc_timings_to_config(&dssdev->panel.timings));
 
@@ -449,26 +453,22 @@ static int venc_power_on(struct omap_dss_device *dssdev)
 
 	r = regulator_enable(venc.vdda_dac_reg);
 	if (r)
-		goto err;
-
-	if (dssdev->platform_enable)
-		dssdev->platform_enable(dssdev);
+		goto err1;
 
 	r = dss_mgr_enable(dssdev->manager);
 	if (r)
-		goto err;
+		goto err2;
 
 	return 0;
 
-err:
+err2:
+	regulator_disable(venc.vdda_dac_reg);
+err1:
 	venc_write_reg(VENC_OUTPUT_CONTROL, 0);
 	dss_set_dac_pwrdn_bgz(0);
 
-	if (dssdev->platform_disable)
-		dssdev->platform_disable(dssdev);
-
-	regulator_disable(venc.vdda_dac_reg);
-
+	venc_runtime_put();
+err0:
 	return r;
 }
 
@@ -479,10 +479,9 @@ static void venc_power_off(struct omap_dss_device *dssdev)
 
 	dss_mgr_disable(dssdev->manager);
 
-	if (dssdev->platform_disable)
-		dssdev->platform_disable(dssdev);
-
 	regulator_disable(venc.vdda_dac_reg);
+
+	venc_runtime_put();
 }
 
 unsigned long venc_get_pixel_clock(void)
@@ -491,171 +490,95 @@ unsigned long venc_get_pixel_clock(void)
 	return 13500000;
 }
 
-static ssize_t display_output_type_show(struct device *dev,
-		struct device_attribute *attr, char *buf)
+int omapdss_venc_display_enable(struct omap_dss_device *dssdev)
 {
-	struct omap_dss_device *dssdev = to_dss_device(dev);
-	const char *ret;
-
-	switch (dssdev->phy.venc.type) {
-	case OMAP_DSS_VENC_TYPE_COMPOSITE:
-		ret = "composite";
-		break;
-	case OMAP_DSS_VENC_TYPE_SVIDEO:
-		ret = "svideo";
-		break;
-	default:
-		return -EINVAL;
-	}
+	int r;
 
-	return snprintf(buf, PAGE_SIZE, "%s\n", ret);
-}
-
-static ssize_t display_output_type_store(struct device *dev,
-		struct device_attribute *attr, const char *buf, size_t size)
-{
-	struct omap_dss_device *dssdev = to_dss_device(dev);
-	enum omap_dss_venc_type new_type;
-
-	if (sysfs_streq("composite", buf))
-		new_type = OMAP_DSS_VENC_TYPE_COMPOSITE;
-	else if (sysfs_streq("svideo", buf))
-		new_type = OMAP_DSS_VENC_TYPE_SVIDEO;
-	else
-		return -EINVAL;
+	DSSDBG("venc_display_enable\n");
 
 	mutex_lock(&venc.venc_lock);
 
-	if (dssdev->phy.venc.type != new_type) {
-		dssdev->phy.venc.type = new_type;
-		if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) {
-			venc_power_off(dssdev);
-			venc_power_on(dssdev);
-		}
+	if (dssdev->manager == NULL) {
+		DSSERR("Failed to enable display: no manager\n");
+		r = -ENODEV;
+		goto err0;
 	}
 
-	mutex_unlock(&venc.venc_lock);
-
-	return size;
-}
-
-static DEVICE_ATTR(output_type, S_IRUGO | S_IWUSR,
-		display_output_type_show, display_output_type_store);
-
-/* driver */
-static int venc_panel_probe(struct omap_dss_device *dssdev)
-{
-	dssdev->panel.timings = omap_dss_pal_timings;
-
-	return device_create_file(&dssdev->dev, &dev_attr_output_type);
-}
-
-static void venc_panel_remove(struct omap_dss_device *dssdev)
-{
-	device_remove_file(&dssdev->dev, &dev_attr_output_type);
-}
-
-static int venc_panel_enable(struct omap_dss_device *dssdev)
-{
-	int r = 0;
-
-	DSSDBG("venc_enable_display\n");
-
-	mutex_lock(&venc.venc_lock);
-
 	r = omap_dss_start_device(dssdev);
 	if (r) {
 		DSSERR("failed to start device\n");
 		goto err0;
 	}
 
-	if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) {
-		r = -EINVAL;
-		goto err1;
-	}
+	if (dssdev->platform_enable)
+		dssdev->platform_enable(dssdev);
 
-	r = venc_runtime_get();
-	if (r)
-		goto err1;
 
 	r = venc_power_on(dssdev);
 	if (r)
-		goto err2;
+		goto err1;
 
 	venc.wss_data = 0;
 
-	dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
-
 	mutex_unlock(&venc.venc_lock);
+
 	return 0;
-err2:
-	venc_runtime_put();
 err1:
+	if (dssdev->platform_disable)
+		dssdev->platform_disable(dssdev);
 	omap_dss_stop_device(dssdev);
 err0:
 	mutex_unlock(&venc.venc_lock);
-
 	return r;
 }
 
-static void venc_panel_disable(struct omap_dss_device *dssdev)
+void omapdss_venc_display_disable(struct omap_dss_device *dssdev)
 {
-	DSSDBG("venc_disable_display\n");
+	DSSDBG("venc_display_disable\n");
 
 	mutex_lock(&venc.venc_lock);
 
-	if (dssdev->state == OMAP_DSS_DISPLAY_DISABLED)
-		goto end;
-
-	if (dssdev->state == OMAP_DSS_DISPLAY_SUSPENDED) {
-		/* suspended is the same as disabled with venc */
-		dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
-		goto end;
-	}
-
 	venc_power_off(dssdev);
 
-	venc_runtime_put();
-
-	dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
-
 	omap_dss_stop_device(dssdev);
-end:
-	mutex_unlock(&venc.venc_lock);
-}
 
-static int venc_panel_suspend(struct omap_dss_device *dssdev)
-{
-	venc_panel_disable(dssdev);
-	return 0;
-}
+	if (dssdev->platform_disable)
+		dssdev->platform_disable(dssdev);
 
-static int venc_panel_resume(struct omap_dss_device *dssdev)
-{
-	return venc_panel_enable(dssdev);
+	mutex_unlock(&venc.venc_lock);
 }
 
-static void venc_set_timings(struct omap_dss_device *dssdev,
-			struct omap_video_timings *timings)
+void omapdss_venc_set_timings(struct omap_dss_device *dssdev,
+		struct omap_video_timings *timings)
 {
 	DSSDBG("venc_set_timings\n");
 
+	mutex_lock(&venc.venc_lock);
+
 	/* Reset WSS data when the TV standard changes. */
 	if (memcmp(&dssdev->panel.timings, timings, sizeof(*timings)))
 		venc.wss_data = 0;
 
 	dssdev->panel.timings = *timings;
+
 	if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) {
+		int r;
+
 		/* turn the venc off and on to get new timings to use */
-		venc_panel_disable(dssdev);
-		venc_panel_enable(dssdev);
+		venc_power_off(dssdev);
+
+		r = venc_power_on(dssdev);
+		if (r)
+			DSSERR("failed to power on VENC\n");
 	} else {
 		dss_mgr_set_timings(dssdev->manager, timings);
 	}
+
+	mutex_unlock(&venc.venc_lock);
 }
 
-static int venc_check_timings(struct omap_dss_device *dssdev,
-			struct omap_video_timings *timings)
+int omapdss_venc_check_timings(struct omap_dss_device *dssdev,
+		struct omap_video_timings *timings)
 {
 	DSSDBG("venc_check_timings\n");
 
@@ -668,13 +591,13 @@ static int venc_check_timings(struct omap_dss_device *dssdev,
 	return -EINVAL;
 }
 
-static u32 venc_get_wss(struct omap_dss_device *dssdev)
+u32 omapdss_venc_get_wss(struct omap_dss_device *dssdev)
 {
 	/* Invert due to VENC_L21_WC_CTL:INV=1 */
 	return (venc.wss_data >> 8) ^ 0xfffff;
 }
 
-static int venc_set_wss(struct omap_dss_device *dssdev,	u32 wss)
+int omapdss_venc_set_wss(struct omap_dss_device *dssdev, u32 wss)
 {
 	const struct venc_config *config;
 	int r;
@@ -703,31 +626,6 @@ err:
 	return r;
 }
 
-static struct omap_dss_driver venc_driver = {
-	.probe		= venc_panel_probe,
-	.remove		= venc_panel_remove,
-
-	.enable		= venc_panel_enable,
-	.disable	= venc_panel_disable,
-	.suspend	= venc_panel_suspend,
-	.resume		= venc_panel_resume,
-
-	.get_resolution	= omapdss_default_get_resolution,
-	.get_recommended_bpp = omapdss_default_get_recommended_bpp,
-
-	.set_timings	= venc_set_timings,
-	.check_timings	= venc_check_timings,
-
-	.get_wss	= venc_get_wss,
-	.set_wss	= venc_set_wss,
-
-	.driver         = {
-		.name   = "venc",
-		.owner  = THIS_MODULE,
-	},
-};
-/* driver end */
-
 static int __init venc_init_display(struct omap_dss_device *dssdev)
 {
 	DSSDBG("init_display\n");
@@ -897,9 +795,9 @@ static int __init omap_venchw_probe(struct platform_device *pdev)
 
 	venc_runtime_put();
 
-	r = omap_dss_register_driver(&venc_driver);
+	r = venc_panel_init();
 	if (r)
-		goto err_reg_panel_driver;
+		goto err_panel_init;
 
 	dss_debugfs_create_file("venc", venc_dump_regs);
 
@@ -907,7 +805,7 @@ static int __init omap_venchw_probe(struct platform_device *pdev)
 
 	return 0;
 
-err_reg_panel_driver:
+err_panel_init:
 err_runtime_get:
 	pm_runtime_disable(&pdev->dev);
 	venc_put_clocks();
@@ -923,7 +821,7 @@ static int __exit omap_venchw_remove(struct platform_device *pdev)
 		venc.vdda_dac_reg = NULL;
 	}
 
-	omap_dss_unregister_driver(&venc_driver);
+	venc_panel_exit();
 
 	pm_runtime_disable(&pdev->dev);
 	venc_put_clocks();
diff --git a/drivers/video/omap2/dss/venc_panel.c b/drivers/video/omap2/dss/venc_panel.c
new file mode 100644
index 0000000..6b31298
--- /dev/null
+++ b/drivers/video/omap2/dss/venc_panel.c
@@ -0,0 +1,231 @@
+/*
+ * Copyright (C) 2009 Nokia Corporation
+ * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
+ *
+ * VENC panel driver
+ *
+ * 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/err.h>
+#include <linux/io.h>
+#include <linux/mutex.h>
+#include <linux/module.h>
+
+#include <video/omapdss.h>
+
+#include "dss.h"
+
+static struct {
+	struct mutex lock;
+} venc_panel;
+
+static ssize_t display_output_type_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct omap_dss_device *dssdev = to_dss_device(dev);
+	const char *ret;
+
+	switch (dssdev->phy.venc.type) {
+	case OMAP_DSS_VENC_TYPE_COMPOSITE:
+		ret = "composite";
+		break;
+	case OMAP_DSS_VENC_TYPE_SVIDEO:
+		ret = "svideo";
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return snprintf(buf, PAGE_SIZE, "%s\n", ret);
+}
+
+static ssize_t display_output_type_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t size)
+{
+	struct omap_dss_device *dssdev = to_dss_device(dev);
+	enum omap_dss_venc_type new_type;
+
+	if (sysfs_streq("composite", buf))
+		new_type = OMAP_DSS_VENC_TYPE_COMPOSITE;
+	else if (sysfs_streq("svideo", buf))
+		new_type = OMAP_DSS_VENC_TYPE_SVIDEO;
+	else
+		return -EINVAL;
+
+	mutex_lock(&venc_panel.lock);
+
+	if (dssdev->phy.venc.type != new_type) {
+		dssdev->phy.venc.type = new_type;
+		if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) {
+			omapdss_venc_display_disable(dssdev);
+			omapdss_venc_display_enable(dssdev);
+		}
+	}
+
+	mutex_unlock(&venc_panel.lock);
+
+	return size;
+}
+
+static DEVICE_ATTR(output_type, S_IRUGO | S_IWUSR,
+		display_output_type_show, display_output_type_store);
+
+static int venc_panel_probe(struct omap_dss_device *dssdev)
+{
+	mutex_init(&venc_panel.lock);
+
+	/* set initial timings to PAL */
+	dssdev->panel.timings = (struct omap_video_timings)
+		{ 720, 574, 13500, 64, 12, 68, 5, 5, 41,
+			OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
+			true,
+		};
+
+	return device_create_file(&dssdev->dev, &dev_attr_output_type);
+}
+
+static void venc_panel_remove(struct omap_dss_device *dssdev)
+{
+	device_remove_file(&dssdev->dev, &dev_attr_output_type);
+}
+
+static int venc_panel_enable(struct omap_dss_device *dssdev)
+{
+	int r;
+
+	dev_dbg(&dssdev->dev, "venc_panel_enable\n");
+
+	mutex_lock(&venc_panel.lock);
+
+	if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) {
+		r = -EINVAL;
+		goto err;
+	}
+
+	r = omapdss_venc_display_enable(dssdev);
+	if (r)
+		goto err;
+
+	dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
+
+	mutex_unlock(&venc_panel.lock);
+
+	return 0;
+err:
+	mutex_unlock(&venc_panel.lock);
+
+	return r;
+}
+
+static void venc_panel_disable(struct omap_dss_device *dssdev)
+{
+	dev_dbg(&dssdev->dev, "venc_panel_disable\n");
+
+	mutex_lock(&venc_panel.lock);
+
+	if (dssdev->state == OMAP_DSS_DISPLAY_DISABLED)
+		goto end;
+
+	if (dssdev->state == OMAP_DSS_DISPLAY_SUSPENDED) {
+		/* suspended is the same as disabled with venc */
+		dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
+		goto end;
+	}
+
+	omapdss_venc_display_disable(dssdev);
+
+	dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
+end:
+	mutex_unlock(&venc_panel.lock);
+}
+
+static int venc_panel_suspend(struct omap_dss_device *dssdev)
+{
+	venc_panel_disable(dssdev);
+	return 0;
+}
+
+static int venc_panel_resume(struct omap_dss_device *dssdev)
+{
+	return venc_panel_enable(dssdev);
+}
+
+static void venc_panel_set_timings(struct omap_dss_device *dssdev,
+		struct omap_video_timings *timings)
+{
+	dev_dbg(&dssdev->dev, "venc_panel_set_timings\n");
+
+	mutex_lock(&venc_panel.lock);
+
+	omapdss_venc_set_timings(dssdev, timings);
+
+	mutex_unlock(&venc_panel.lock);
+}
+
+static int venc_panel_check_timings(struct omap_dss_device *dssdev,
+		struct omap_video_timings *timings)
+{
+	dev_dbg(&dssdev->dev, "venc_panel_check_timings\n");
+
+	return omapdss_venc_check_timings(dssdev, timings);
+}
+
+static u32 venc_panel_get_wss(struct omap_dss_device *dssdev)
+{
+	dev_dbg(&dssdev->dev, "venc_panel_get_wss\n");
+
+	return omapdss_venc_get_wss(dssdev);
+}
+
+static int venc_panel_set_wss(struct omap_dss_device *dssdev, u32 wss)
+{
+	dev_dbg(&dssdev->dev, "venc_panel_set_wss\n");
+
+	return omapdss_venc_set_wss(dssdev, wss);
+}
+
+static struct omap_dss_driver venc_driver = {
+	.probe		= venc_panel_probe,
+	.remove		= venc_panel_remove,
+
+	.enable		= venc_panel_enable,
+	.disable	= venc_panel_disable,
+	.suspend	= venc_panel_suspend,
+	.resume		= venc_panel_resume,
+
+	.get_resolution	= omapdss_default_get_resolution,
+	.get_recommended_bpp = omapdss_default_get_recommended_bpp,
+
+	.set_timings	= venc_panel_set_timings,
+	.check_timings	= venc_panel_check_timings,
+
+	.get_wss	= venc_panel_get_wss,
+	.set_wss	= venc_panel_set_wss,
+
+	.driver         = {
+		.name   = "venc",
+		.owner  = THIS_MODULE,
+	},
+};
+
+int venc_panel_init(void)
+{
+	return omap_dss_register_driver(&venc_driver);
+}
+
+void venc_panel_exit(void)
+{
+	omap_dss_unregister_driver(&venc_driver);
+}
-- 
1.7.9.5


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

* [PATCH v2 12/13] OMAPDSS: VENC: Maintain our own timings field in driver data
  2012-08-09 11:55   ` Archit Taneja
@ 2012-08-09 11:56     ` Archit Taneja
  -1 siblings, 0 replies; 122+ messages in thread
From: Archit Taneja @ 2012-08-09 11:49 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-fbdev, linux-omap, Archit Taneja

The VENC driver currently relies on the timings in omap_dss_device struct to
configure the DISPC and VENC blocks accordingly. This makes the VENC interface
driver dependent on the omap_dss_device struct.

Make the VENC driver data maintain it's own timings field. The panel driver is
expected to call omapdss_venc_set_timings() to set these timings before the
panel is enabled.

Make the VENC panel driver configure the new timings is the omap_dss_device
struct(dssdev->panel.timings). The VENC driver is responsible for maintaining
only it's own copy of timings.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/dss/venc.c       |   12 +++++++-----
 drivers/video/omap2/dss/venc_panel.c |    1 +
 2 files changed, 8 insertions(+), 5 deletions(-)

diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c
index ffca542..d96025e 100644
--- a/drivers/video/omap2/dss/venc.c
+++ b/drivers/video/omap2/dss/venc.c
@@ -300,6 +300,8 @@ static struct {
 	struct regulator *vdda_dac_reg;
 
 	struct clk	*tv_dac_clk;
+
+	struct omap_video_timings timings;
 } venc;
 
 static inline void venc_write_reg(int idx, u32 val)
@@ -432,7 +434,7 @@ static int venc_power_on(struct omap_dss_device *dssdev)
 		goto err0;
 
 	venc_reset();
-	venc_write_config(venc_timings_to_config(&dssdev->panel.timings));
+	venc_write_config(venc_timings_to_config(&venc.timings));
 
 	dss_set_venc_output(dssdev->phy.venc.type);
 	dss_set_dac_pwrdn_bgz(1);
@@ -449,7 +451,7 @@ static int venc_power_on(struct omap_dss_device *dssdev)
 
 	venc_write_reg(VENC_OUTPUT_CONTROL, l);
 
-	dss_mgr_set_timings(dssdev->manager, &dssdev->panel.timings);
+	dss_mgr_set_timings(dssdev->manager, &venc.timings);
 
 	r = regulator_enable(venc.vdda_dac_reg);
 	if (r)
@@ -556,10 +558,10 @@ void omapdss_venc_set_timings(struct omap_dss_device *dssdev,
 	mutex_lock(&venc.venc_lock);
 
 	/* Reset WSS data when the TV standard changes. */
-	if (memcmp(&dssdev->panel.timings, timings, sizeof(*timings)))
+	if (memcmp(&venc.timings, timings, sizeof(*timings)))
 		venc.wss_data = 0;
 
-	dssdev->panel.timings = *timings;
+	venc.timings = *timings;
 
 	if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) {
 		int r;
@@ -606,7 +608,7 @@ int omapdss_venc_set_wss(struct omap_dss_device *dssdev, u32 wss)
 
 	mutex_lock(&venc.venc_lock);
 
-	config = venc_timings_to_config(&dssdev->panel.timings);
+	config = venc_timings_to_config(&venc.timings);
 
 	/* Invert due to VENC_L21_WC_CTL:INV=1 */
 	venc.wss_data = (wss ^ 0xfffff) << 8;
diff --git a/drivers/video/omap2/dss/venc_panel.c b/drivers/video/omap2/dss/venc_panel.c
index 6b31298..350b0d9 100644
--- a/drivers/video/omap2/dss/venc_panel.c
+++ b/drivers/video/omap2/dss/venc_panel.c
@@ -170,6 +170,7 @@ static void venc_panel_set_timings(struct omap_dss_device *dssdev,
 	mutex_lock(&venc_panel.lock);
 
 	omapdss_venc_set_timings(dssdev, timings);
+	dssdev->panel.timings = *timings;
 
 	mutex_unlock(&venc_panel.lock);
 }
-- 
1.7.9.5


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

* [PATCH v2 13/13] OMAPDSS: VENC: Add a get_timing function for VENC interface
  2012-08-09 11:55   ` Archit Taneja
@ 2012-08-09 11:56     ` Archit Taneja
  -1 siblings, 0 replies; 122+ messages in thread
From: Archit Taneja @ 2012-08-09 11:49 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-fbdev, linux-omap, Archit Taneja

Add function omapdss_venc_get_timing() which returns the timings
maintained by the VENC interface driver in it's driver data. This is just used
once by the driver during it's probe. This prevents the need for the panel
driver to configure default timings in it's probe.

Int the VENC interface's probe, the timings field is set to PAL as a default
value. The get_timing op makes more sense for interfaces which can be configured
to a default timing.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/dss/dss.h        |    2 ++
 drivers/video/omap2/dss/venc.c       |   13 +++++++++++++
 drivers/video/omap2/dss/venc_panel.c |   11 +++++------
 3 files changed, 20 insertions(+), 6 deletions(-)

diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index 69b6ab9..3fe76c0 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -474,6 +474,8 @@ 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,
 		struct omap_video_timings *timings);
+void omapdss_venc_get_timings(struct omap_dss_device *dssdev,
+		struct omap_video_timings *timings);
 int omapdss_venc_check_timings(struct omap_dss_device *dssdev,
 		struct omap_video_timings *timings);
 u32 omapdss_venc_get_wss(struct omap_dss_device *dssdev);
diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c
index d96025e..42f97ac 100644
--- a/drivers/video/omap2/dss/venc.c
+++ b/drivers/video/omap2/dss/venc.c
@@ -579,6 +579,18 @@ void omapdss_venc_set_timings(struct omap_dss_device *dssdev,
 	mutex_unlock(&venc.venc_lock);
 }
 
+void omapdss_venc_get_timings(struct omap_dss_device *dssdev,
+		struct omap_video_timings *timings)
+{
+	DSSDBG("venc_set_timings\n");
+
+	mutex_lock(&venc.venc_lock);
+
+	*timings = venc.timings;
+
+	mutex_unlock(&venc.venc_lock);
+}
+
 int omapdss_venc_check_timings(struct omap_dss_device *dssdev,
 		struct omap_video_timings *timings)
 {
@@ -768,6 +780,7 @@ static int __init omap_venchw_probe(struct platform_device *pdev)
 	mutex_init(&venc.venc_lock);
 
 	venc.wss_data = 0;
+	venc.timings = omap_dss_pal_timings;
 
 	venc_mem = platform_get_resource(venc.pdev, IORESOURCE_MEM, 0);
 	if (!venc_mem) {
diff --git a/drivers/video/omap2/dss/venc_panel.c b/drivers/video/omap2/dss/venc_panel.c
index 350b0d9..fe9958d 100644
--- a/drivers/video/omap2/dss/venc_panel.c
+++ b/drivers/video/omap2/dss/venc_panel.c
@@ -84,14 +84,13 @@ static DEVICE_ATTR(output_type, S_IRUGO | S_IWUSR,
 
 static int venc_panel_probe(struct omap_dss_device *dssdev)
 {
+	struct omap_video_timings timings;
+
 	mutex_init(&venc_panel.lock);
 
-	/* set initial timings to PAL */
-	dssdev->panel.timings = (struct omap_video_timings)
-		{ 720, 574, 13500, 64, 12, 68, 5, 5, 41,
-			OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
-			true,
-		};
+	omapdss_venc_get_timings(dssdev, &timings);
+
+	dssdev->panel.timings = timings;
 
 	return device_create_file(&dssdev->dev, &dev_attr_output_type);
 }
-- 
1.7.9.5


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

* [PATCH v2 00/13] OMAPDSS: Change way of passing timings from panel driver to interface
@ 2012-08-09 11:55   ` Archit Taneja
  0 siblings, 0 replies; 122+ messages in thread
From: Archit Taneja @ 2012-08-09 11:55 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-fbdev, linux-omap, Archit Taneja

This is a follow up series. The orginal one can be seen here:

http://marc.info/?l=linux-omap&m\x134381744304672&w=2

Changes in v2:
- Removed misc fixes out of this set
- Not trying to optimize SDI when setting new timings, using the old strategy
- Added a function for setting size for DSI command mode panels
- Added a fix which ensures the manager sizes is correctly set for rotation in
  command mode panels.

The tree/branch can be found here:

git://gitorious.org/~boddob/linux-omap-dss2/archit-dss2-clone.git pass_timings_interface_2

Archit Taneja (13):
  OMAPDSS: DPI: Maintain our own timings field in driver data
  OMAPDSS: DPI displays: Take care of panel timings in the driver
    itself
  OMAPDSS: DSI: Maintain own copy of timings in driver data
  OMAPDSS: DSI: Add function to set panel size for command mode panels
  OMAPDSS: DSI: Update manager timings on a manual update
  OMAPDSS: HDMI: Use our own omap_video_timings field when setting
    interface timings
  OMAPDSS: HDMI: Add a get_timing function for HDMI interface
  OMAPDSS: HDMI: Add locking for hdmi interface get/set timing
    functions
  OMAPDSS: SDI: Create a function to set timings
  OMAPDSS: SDI: Maintain our own timings field in driver data
  OMAPDSS: VENC: Split VENC into interface and panel driver
  OMAPDSS: VENC: Maintain our own timings field in driver data
  OMAPDSS: VENC: Add a get_timing function for VENC interface

 drivers/video/omap2/displays/panel-acx565akm.c     |   13 +-
 drivers/video/omap2/displays/panel-generic-dpi.c   |    6 +-
 .../omap2/displays/panel-lgphilips-lb035q02.c      |    2 +
 .../omap2/displays/panel-nec-nl8048hl11-01b.c      |    2 +
 drivers/video/omap2/displays/panel-picodlp.c       |    3 +
 .../video/omap2/displays/panel-sharp-ls037v7dw01.c |    2 +
 drivers/video/omap2/displays/panel-taal.c          |   14 ++
 drivers/video/omap2/displays/panel-tfp410.c        |    5 +-
 .../video/omap2/displays/panel-tpo-td043mtea1.c    |    6 +-
 drivers/video/omap2/dss/Makefile                   |    2 +-
 drivers/video/omap2/dss/dpi.c                      |   12 +-
 drivers/video/omap2/dss/dsi.c                      |   86 +++++---
 drivers/video/omap2/dss/dss.h                      |   17 +-
 drivers/video/omap2/dss/hdmi.c                     |   55 +++--
 drivers/video/omap2/dss/hdmi_panel.c               |   12 +-
 drivers/video/omap2/dss/sdi.c                      |   20 +-
 drivers/video/omap2/dss/venc.c                     |  233 ++++++--------------
 drivers/video/omap2/dss/venc_panel.c               |  231 +++++++++++++++++++
 include/video/omapdss.h                            |    9 +-
 19 files changed, 490 insertions(+), 240 deletions(-)
 create mode 100644 drivers/video/omap2/dss/venc_panel.c

-- 
1.7.9.5


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

* [PATCH v2 01/13] OMAPDSS: DPI: Maintain our own timings field in driver data
@ 2012-08-09 11:56     ` Archit Taneja
  0 siblings, 0 replies; 122+ messages in thread
From: Archit Taneja @ 2012-08-09 11:56 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-fbdev, linux-omap, Archit Taneja

The DPI driver currently relies on the timings in omap_dss_device struct to
configure the DISPC accordingly. This makes the DPI interface driver dependent
on the omap_dss_device struct.

Make the DPI driver data maintain it's own timings field. The panel driver is
expected to call dpi_set_timings()(renamed to omapdss_dpi_set_timings) to set
these timings before the panel is enabled.

In the set_timings() op, we still ensure that the omap_dss_device timings
(dssdev->panel.timings) are configured. This will later be configured only by
the DPI panel drivers.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/displays/panel-generic-dpi.c   |    4 +++-
 .../omap2/displays/panel-lgphilips-lb035q02.c      |    2 ++
 .../omap2/displays/panel-nec-nl8048hl11-01b.c      |    2 ++
 drivers/video/omap2/displays/panel-picodlp.c       |    3 +++
 .../video/omap2/displays/panel-sharp-ls037v7dw01.c |    2 ++
 drivers/video/omap2/displays/panel-tfp410.c        |    4 +++-
 .../video/omap2/displays/panel-tpo-td043mtea1.c    |    4 +++-
 drivers/video/omap2/dss/dpi.c                      |   11 +++++++----
 include/video/omapdss.h                            |    4 ++--
 9 files changed, 27 insertions(+), 9 deletions(-)

diff --git a/drivers/video/omap2/displays/panel-generic-dpi.c b/drivers/video/omap2/displays/panel-generic-dpi.c
index 69e78a5..8d4e102 100644
--- a/drivers/video/omap2/displays/panel-generic-dpi.c
+++ b/drivers/video/omap2/displays/panel-generic-dpi.c
@@ -565,6 +565,8 @@ static int generic_dpi_panel_power_on(struct omap_dss_device *dssdev)
 	if (dssdev->state = OMAP_DSS_DISPLAY_ACTIVE)
 		return 0;
 
+	omapdss_dpi_set_timings(dssdev, &dssdev->panel.timings);
+
 	r = omapdss_dpi_display_enable(dssdev);
 	if (r)
 		goto err0;
@@ -726,7 +728,7 @@ static void generic_dpi_panel_set_timings(struct omap_dss_device *dssdev,
 
 	mutex_lock(&drv_data->lock);
 
-	dpi_set_timings(dssdev, timings);
+	omapdss_dpi_set_timings(dssdev, 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 8028077..7e52aee 100644
--- a/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c
+++ b/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c
@@ -55,6 +55,8 @@ static int lb035q02_panel_power_on(struct omap_dss_device *dssdev)
 	if (dssdev->state = OMAP_DSS_DISPLAY_ACTIVE)
 		return 0;
 
+	omapdss_dpi_set_timings(dssdev, &dssdev->panel.timings);
+
 	r = omapdss_dpi_display_enable(dssdev);
 	if (r)
 		goto err0;
diff --git a/drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c b/drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c
index b122b0f..e501c40 100644
--- a/drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c
+++ b/drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c
@@ -175,6 +175,8 @@ static int nec_8048_panel_power_on(struct omap_dss_device *dssdev)
 	if (dssdev->state = OMAP_DSS_DISPLAY_ACTIVE)
 		return 0;
 
+	omapdss_dpi_set_timings(dssdev, &dssdev->panel.timings);
+
 	r = omapdss_dpi_display_enable(dssdev);
 	if (r)
 		goto err0;
diff --git a/drivers/video/omap2/displays/panel-picodlp.c b/drivers/video/omap2/displays/panel-picodlp.c
index 2d35bd3..0d7a8ff 100644
--- a/drivers/video/omap2/displays/panel-picodlp.c
+++ b/drivers/video/omap2/displays/panel-picodlp.c
@@ -377,6 +377,9 @@ static int picodlp_panel_power_on(struct omap_dss_device *dssdev)
 	 * then only i2c commands can be successfully sent to dpp2600
 	 */
 	msleep(1000);
+
+	omapdss_dpi_set_timings(dssdev, &dssdev->panel.timings);
+
 	r = omapdss_dpi_display_enable(dssdev);
 	if (r) {
 		dev_err(&dssdev->dev, "failed to enable DPI\n");
diff --git a/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c b/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c
index bd86ba9..1486a81 100644
--- a/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c
+++ b/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c
@@ -142,6 +142,8 @@ static int sharp_ls_power_on(struct omap_dss_device *dssdev)
 	if (dssdev->state = OMAP_DSS_DISPLAY_ACTIVE)
 		return 0;
 
+	omapdss_dpi_set_timings(dssdev, &dssdev->panel.timings);
+
 	r = omapdss_dpi_display_enable(dssdev);
 	if (r)
 		goto err0;
diff --git a/drivers/video/omap2/displays/panel-tfp410.c b/drivers/video/omap2/displays/panel-tfp410.c
index 40cc0cfa..c6f9503 100644
--- a/drivers/video/omap2/displays/panel-tfp410.c
+++ b/drivers/video/omap2/displays/panel-tfp410.c
@@ -65,6 +65,8 @@ static int tfp410_power_on(struct omap_dss_device *dssdev)
 	if (dssdev->state = OMAP_DSS_DISPLAY_ACTIVE)
 		return 0;
 
+	omapdss_dpi_set_timings(dssdev, &dssdev->panel.timings);
+
 	r = omapdss_dpi_display_enable(dssdev);
 	if (r)
 		goto err0;
@@ -231,7 +233,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);
-	dpi_set_timings(dssdev, timings);
+	omapdss_dpi_set_timings(dssdev, timings);
 	mutex_unlock(&ddata->lock);
 }
 
diff --git a/drivers/video/omap2/displays/panel-tpo-td043mtea1.c b/drivers/video/omap2/displays/panel-tpo-td043mtea1.c
index fa7baa6..ecb163e 100644
--- a/drivers/video/omap2/displays/panel-tpo-td043mtea1.c
+++ b/drivers/video/omap2/displays/panel-tpo-td043mtea1.c
@@ -337,6 +337,8 @@ static int tpo_td043_enable_dss(struct omap_dss_device *dssdev)
 	if (dssdev->state = OMAP_DSS_DISPLAY_ACTIVE)
 		return 0;
 
+	omapdss_dpi_set_timings(dssdev, &dssdev->panel.timings);
+
 	r = omapdss_dpi_display_enable(dssdev);
 	if (r)
 		goto err0;
@@ -480,7 +482,7 @@ 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)
 {
-	dpi_set_timings(dssdev, timings);
+	omapdss_dpi_set_timings(dssdev, timings);
 }
 
 static int tpo_td043_check_timings(struct omap_dss_device *dssdev,
diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c
index add47fe..96dd1a4 100644
--- a/drivers/video/omap2/dss/dpi.c
+++ b/drivers/video/omap2/dss/dpi.c
@@ -41,6 +41,7 @@ static struct {
 
 	struct mutex lock;
 
+	struct omap_video_timings timings;
 	struct dss_lcd_mgr_config mgr_config;
 } dpi;
 
@@ -138,7 +139,7 @@ static int dpi_set_dispc_clk(unsigned long pck_req, unsigned long *fck,
 
 static int dpi_set_mode(struct omap_dss_device *dssdev)
 {
-	struct omap_video_timings *t = &dssdev->panel.timings;
+	struct omap_video_timings *t = &dpi.timings;
 	int lck_div = 0, pck_div = 0;
 	unsigned long fck = 0;
 	unsigned long pck;
@@ -293,8 +294,8 @@ void omapdss_dpi_display_disable(struct omap_dss_device *dssdev)
 }
 EXPORT_SYMBOL(omapdss_dpi_display_disable);
 
-void dpi_set_timings(struct omap_dss_device *dssdev,
-			struct omap_video_timings *timings)
+void omapdss_dpi_set_timings(struct omap_dss_device *dssdev,
+		struct omap_video_timings *timings)
 {
 	int r;
 
@@ -302,7 +303,9 @@ void dpi_set_timings(struct omap_dss_device *dssdev,
 
 	mutex_lock(&dpi.lock);
 
+	dpi.timings = *timings;
 	dssdev->panel.timings = *timings;
+
 	if (dssdev->state = OMAP_DSS_DISPLAY_ACTIVE) {
 		r = dispc_runtime_get();
 		if (r)
@@ -317,7 +320,7 @@ void dpi_set_timings(struct omap_dss_device *dssdev,
 
 	mutex_unlock(&dpi.lock);
 }
-EXPORT_SYMBOL(dpi_set_timings);
+EXPORT_SYMBOL(omapdss_dpi_set_timings);
 
 int dpi_check_timings(struct omap_dss_device *dssdev,
 			struct omap_video_timings *timings)
diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index 6f7581b..ebf2ebd 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -751,8 +751,8 @@ void omapdss_dsi_display_disable(struct omap_dss_device *dssdev,
 
 int omapdss_dpi_display_enable(struct omap_dss_device *dssdev);
 void omapdss_dpi_display_disable(struct omap_dss_device *dssdev);
-void dpi_set_timings(struct omap_dss_device *dssdev,
-			struct omap_video_timings *timings);
+void omapdss_dpi_set_timings(struct omap_dss_device *dssdev,
+		struct omap_video_timings *timings);
 int dpi_check_timings(struct omap_dss_device *dssdev,
 			struct omap_video_timings *timings);
 
-- 
1.7.9.5


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

* [PATCH v2 02/13] OMAPDSS: DPI displays: Take care of panel timings in the driver itself
@ 2012-08-09 11:56     ` Archit Taneja
  0 siblings, 0 replies; 122+ messages in thread
From: Archit Taneja @ 2012-08-09 11:56 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-fbdev, linux-omap, Archit Taneja

The timings maintained in omap_dss_device(dssdev->panel.timings) should be
maintained by the panel driver itself. It's the panel drivers responsibility
to update it if a new set of timings is to be configured. The DPI interface
driver shouldn't be responsible of updating the panel timings, it's responsible
of maintianing it's own copy of timings.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/displays/panel-generic-dpi.c   |    2 ++
 drivers/video/omap2/displays/panel-tfp410.c        |    1 +
 .../video/omap2/displays/panel-tpo-td043mtea1.c    |    2 ++
 drivers/video/omap2/dss/dpi.c                      |    1 -
 4 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/video/omap2/displays/panel-generic-dpi.c b/drivers/video/omap2/displays/panel-generic-dpi.c
index 8d4e102..a07e18c 100644
--- a/drivers/video/omap2/displays/panel-generic-dpi.c
+++ b/drivers/video/omap2/displays/panel-generic-dpi.c
@@ -730,6 +730,8 @@ static void generic_dpi_panel_set_timings(struct omap_dss_device *dssdev,
 
 	omapdss_dpi_set_timings(dssdev, timings);
 
+	dssdev->panel.timings = *timings;
+
 	mutex_unlock(&drv_data->lock);
 }
 
diff --git a/drivers/video/omap2/displays/panel-tfp410.c b/drivers/video/omap2/displays/panel-tfp410.c
index c6f9503..9397236 100644
--- a/drivers/video/omap2/displays/panel-tfp410.c
+++ b/drivers/video/omap2/displays/panel-tfp410.c
@@ -234,6 +234,7 @@ static void tfp410_set_timings(struct omap_dss_device *dssdev,
 
 	mutex_lock(&ddata->lock);
 	omapdss_dpi_set_timings(dssdev, timings);
+	dssdev->panel.timings = *timings;
 	mutex_unlock(&ddata->lock);
 }
 
diff --git a/drivers/video/omap2/displays/panel-tpo-td043mtea1.c b/drivers/video/omap2/displays/panel-tpo-td043mtea1.c
index ecb163e..3f47f5f 100644
--- a/drivers/video/omap2/displays/panel-tpo-td043mtea1.c
+++ b/drivers/video/omap2/displays/panel-tpo-td043mtea1.c
@@ -483,6 +483,8 @@ static void tpo_td043_set_timings(struct omap_dss_device *dssdev,
 		struct omap_video_timings *timings)
 {
 	omapdss_dpi_set_timings(dssdev, timings);
+
+	dssdev->panel.timings = *timings;
 }
 
 static int tpo_td043_check_timings(struct omap_dss_device *dssdev,
diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c
index 96dd1a4..6c43d80 100644
--- a/drivers/video/omap2/dss/dpi.c
+++ b/drivers/video/omap2/dss/dpi.c
@@ -304,7 +304,6 @@ void omapdss_dpi_set_timings(struct omap_dss_device *dssdev,
 	mutex_lock(&dpi.lock);
 
 	dpi.timings = *timings;
-	dssdev->panel.timings = *timings;
 
 	if (dssdev->state = OMAP_DSS_DISPLAY_ACTIVE) {
 		r = dispc_runtime_get();
-- 
1.7.9.5


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

* [PATCH v2 03/13] OMAPDSS: DSI: Maintain own copy of timings in driver data
@ 2012-08-09 11:56     ` Archit Taneja
  0 siblings, 0 replies; 122+ messages in thread
From: Archit Taneja @ 2012-08-09 11:56 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-fbdev, linux-omap, Archit Taneja

The DSI driver currently relies on the timings in omap_dss_device struct to
configure the DISPC and DSI blocks accordingly. This makes the DSI interface
driver dependent on the omap_dss_device struct.

Make the DSI driver data maintain it's own timings field. A DSI video mode panel
driver is expected to call omapdss_dsi_set_timings() to set these timings before
the panel is enabled.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/dss/dsi.c |   58 +++++++++++++++++++++++++----------------
 include/video/omapdss.h       |    2 ++
 2 files changed, 38 insertions(+), 22 deletions(-)

diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index 27c27c4..815b606 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -333,6 +333,7 @@ struct dsi_data {
 	unsigned scp_clk_refcount;
 
 	struct dss_lcd_mgr_config mgr_config;
+	struct omap_video_timings timings;
 };
 
 struct dsi_packet_sent_handler_data {
@@ -3607,9 +3608,10 @@ static void dsi_config_vp_num_line_buffers(struct omap_dss_device *dssdev)
 	int num_line_buffers;
 
 	if (dssdev->panel.dsi_mode = OMAP_DSS_DSI_VIDEO_MODE) {
+		struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
 		int bpp = dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt);
 		unsigned line_buf_size = dsi_get_line_buf_size(dsidev);
-		struct omap_video_timings *timings = &dssdev->panel.timings;
+		struct omap_video_timings *timings = &dsi->timings;
 		/*
 		 * Don't use line buffers if width is greater than the video
 		 * port's line buffer size
@@ -3738,7 +3740,7 @@ static void dsi_config_cmd_mode_interleaving(struct omap_dss_device *dssdev)
 	int ddr_clk_pre, ddr_clk_post, enter_hs_mode_lat, exit_hs_mode_lat;
 	int tclk_trail, ths_exit, exiths_clk;
 	bool ddr_alwon;
-	struct omap_video_timings *timings = &dssdev->panel.timings;
+	struct omap_video_timings *timings = &dsi->timings;
 	int bpp = dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt);
 	int ndl = dsi->num_lanes_used - 1;
 	const struct omapdss_clock_config *clks;
@@ -3996,7 +3998,7 @@ static void dsi_proto_timings(struct omap_dss_device *dssdev)
 		int vbp = dssdev->panel.dsi_vm_data.vbp;
 		int window_sync = dssdev->panel.dsi_vm_data.window_sync;
 		bool hsync_end = dssdev->panel.dsi_vm_data.vp_hsync_end;
-		struct omap_video_timings *timings = &dssdev->panel.timings;
+		struct omap_video_timings *timings = &dsi->timings;
 		int bpp = dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt);
 		int tl, t_he, width_bytes;
 
@@ -4105,6 +4107,7 @@ 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 dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
 	int bpp = dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt);
 	u8 data_type;
 	u16 word_count;
@@ -4135,7 +4138,7 @@ int dsi_enable_video_output(struct omap_dss_device *dssdev, int channel)
 		/* MODE, 1 = video mode */
 		REG_FLD_MOD(dsidev, DSI_VC_CTRL(channel), 1, 4, 4);
 
-		word_count = DIV_ROUND_UP(dssdev->panel.timings.x_res * bpp, 8);
+		word_count = DIV_ROUND_UP(dsi->timings.x_res * bpp, 8);
 
 		dsi_vc_write_long_header(dsidev, channel, data_type,
 				word_count, 0);
@@ -4370,7 +4373,6 @@ static int dsi_display_init_dispc(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_video_timings timings;
 	const struct omapdss_clock_config *clks;
 	int r, lcd_id;
 	u32 irq = 0;
@@ -4380,14 +4382,14 @@ static int dsi_display_init_dispc(struct omap_dss_device *dssdev)
 
 		dssdev->driver->get_resolution(dssdev, &dw, &dh);
 
-		timings.x_res = dw;
-		timings.y_res = dh;
-		timings.hsw = 1;
-		timings.hfp = 1;
-		timings.hbp = 1;
-		timings.vsw = 1;
-		timings.vfp = 0;
-		timings.vbp = 0;
+		dsi->timings.x_res = dw;
+		dsi->timings.y_res = dh;
+		dsi->timings.hsw = 1;
+		dsi->timings.hfp = 1;
+		dsi->timings.hbp = 1;
+		dsi->timings.vsw = 1;
+		dsi->timings.vfp = 0;
+		dsi->timings.vbp = 0;
 
 		irq = dispc_mgr_get_framedone_irq(dssdev->manager->id);
 
@@ -4401,8 +4403,6 @@ static int dsi_display_init_dispc(struct omap_dss_device *dssdev)
 		dsi->mgr_config.stallmode = true;
 		dsi->mgr_config.fifohandcheck = true;
 	} else {
-		timings = dssdev->panel.timings;
-
 		dsi->mgr_config.stallmode = false;
 		dsi->mgr_config.fifohandcheck = false;
 	}
@@ -4411,14 +4411,14 @@ static int dsi_display_init_dispc(struct omap_dss_device *dssdev)
 	 * override interlace, logic level and edge related parameters in
 	 * omap_video_timings with default values
 	 */
-	timings.interlace = false;
-	timings.hsync_level = OMAPDSS_SIG_ACTIVE_HIGH;
-	timings.vsync_level = OMAPDSS_SIG_ACTIVE_HIGH;
-	timings.data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE;
-	timings.de_level = OMAPDSS_SIG_ACTIVE_HIGH;
-	timings.sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES;
+	dsi->timings.interlace = false;
+	dsi->timings.hsync_level = OMAPDSS_SIG_ACTIVE_HIGH;
+	dsi->timings.vsync_level = OMAPDSS_SIG_ACTIVE_HIGH;
+	dsi->timings.data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE;
+	dsi->timings.de_level = OMAPDSS_SIG_ACTIVE_HIGH;
+	dsi->timings.sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES;
 
-	dss_mgr_set_timings(dssdev->manager, &timings);
+	dss_mgr_set_timings(dssdev->manager, &dsi->timings);
 
 	switch (dssdev->manager->id) {
 	case OMAP_DSS_CHANNEL_LCD:
@@ -4688,6 +4688,20 @@ 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,
+		struct omap_video_timings *timings)
+{
+	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
+
+	mutex_lock(&dsi->lock);
+
+	dsi->timings = *timings;
+
+	mutex_unlock(&dsi->lock);
+}
+EXPORT_SYMBOL(omapdss_dsi_set_timings);
+
 static int __init dsi_init_display(struct omap_dss_device *dssdev)
 {
 	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index ebf2ebd..a2cd133 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -736,6 +736,8 @@ int omap_dispc_wait_for_irq_interruptible_timeout(u32 irqmask,
 void omapdss_dsi_vc_enable_hs(struct omap_dss_device *dssdev, 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,
+		struct omap_video_timings *timings);
 
 int omap_dsi_update(struct omap_dss_device *dssdev, int channel,
 		void (*callback)(int, void *), void *data);
-- 
1.7.9.5


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

* [PATCH v2 04/13] OMAPDSS: DSI: Add function to set panel size for command mode panels
@ 2012-08-09 11:56     ` Archit Taneja
  0 siblings, 0 replies; 122+ messages in thread
From: Archit Taneja @ 2012-08-09 11:56 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-fbdev, linux-omap, Archit Taneja

DSI command mode panels don't need to configure a full set of timings to
configure DSI, they only require the width and the height of the panel in
pixels.

Use omapdss_dsi_set_size for command mode panels, omapdss_dsi_set_timings is
meant for video mode panels. When performing rotation via chaning the address
mode of the panel, we would need to swap width and height when doing 90 or 270
rotation. Make sure that omapdss_dsi_set_size() makes the new width and height
visible to DSI.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/displays/panel-taal.c |   14 ++++++++++++++
 drivers/video/omap2/dss/dsi.c             |   23 ++++++++++++++++-------
 include/video/omapdss.h                   |    1 +
 3 files changed, 31 insertions(+), 7 deletions(-)

diff --git a/drivers/video/omap2/displays/panel-taal.c b/drivers/video/omap2/displays/panel-taal.c
index 3f5acc7..c3bca2f 100644
--- a/drivers/video/omap2/displays/panel-taal.c
+++ b/drivers/video/omap2/displays/panel-taal.c
@@ -1060,6 +1060,9 @@ static int taal_power_on(struct omap_dss_device *dssdev)
 		goto err0;
 	};
 
+	omapdss_dsi_set_size(dssdev, dssdev->panel.timings.x_res,
+		dssdev->panel.timings.y_res);
+
 	r = omapdss_dsi_display_enable(dssdev);
 	if (r) {
 		dev_err(&dssdev->dev, "failed to enable DSI\n");
@@ -1487,6 +1490,7 @@ static int taal_get_te(struct omap_dss_device *dssdev)
 static int taal_rotate(struct omap_dss_device *dssdev, u8 rotate)
 {
 	struct taal_data *td = dev_get_drvdata(&dssdev->dev);
+	u16 dw, dh;
 	int r;
 
 	dev_dbg(&dssdev->dev, "rotate %d\n", rotate);
@@ -1508,6 +1512,16 @@ static int taal_rotate(struct omap_dss_device *dssdev, u8 rotate)
 			goto err;
 	}
 
+	if (rotate = 0 || rotate = 2) {
+		dw = dssdev->panel.timings.x_res;
+		dh = dssdev->panel.timings.y_res;
+	} else {
+		dw = dssdev->panel.timings.y_res;
+		dh = dssdev->panel.timings.x_res;
+	}
+
+	omapdss_dsi_set_size(dssdev, dw, dh);
+
 	td->rotate = rotate;
 
 	dsi_bus_unlock(dssdev);
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index 815b606..eb364d4 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -4330,7 +4330,8 @@ int omap_dsi_update(struct omap_dss_device *dssdev, int channel,
 	dsi->framedone_callback = callback;
 	dsi->framedone_data = data;
 
-	dssdev->driver->get_resolution(dssdev, &dw, &dh);
+	dw = dsi->timings.x_res;
+	dh = dsi->timings.y_res;
 
 #ifdef DEBUG
 	dsi->update_bytes = dw * dh *
@@ -4378,12 +4379,6 @@ static int dsi_display_init_dispc(struct omap_dss_device *dssdev)
 	u32 irq = 0;
 
 	if (dssdev->panel.dsi_mode = OMAP_DSS_DSI_CMD_MODE) {
-		u16 dw, dh;
-
-		dssdev->driver->get_resolution(dssdev, &dw, &dh);
-
-		dsi->timings.x_res = dw;
-		dsi->timings.y_res = dh;
 		dsi->timings.hsw = 1;
 		dsi->timings.hfp = 1;
 		dsi->timings.hbp = 1;
@@ -4702,6 +4697,20 @@ 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)
+{
+	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
+
+	mutex_lock(&dsi->lock);
+
+	dsi->timings.x_res = w;
+	dsi->timings.y_res = h;
+
+	mutex_unlock(&dsi->lock);
+}
+EXPORT_SYMBOL(omapdss_dsi_set_size);
+
 static int __init dsi_init_display(struct omap_dss_device *dssdev)
 {
 	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index a2cd133..a85b3fb 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -738,6 +738,7 @@ void omapdss_dsi_vc_enable_hs(struct omap_dss_device *dssdev, int channel,
 int omapdss_dsi_enable_te(struct omap_dss_device *dssdev, bool enable);
 void omapdss_dsi_set_timings(struct omap_dss_device *dssdev,
 		struct omap_video_timings *timings);
+void omapdss_dsi_set_size(struct omap_dss_device *dssdev, u16 w, u16 h);
 
 int omap_dsi_update(struct omap_dss_device *dssdev, int channel,
 		void (*callback)(int, void *), void *data);
-- 
1.7.9.5


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

* [PATCH v2 05/13] OMAPDSS: DSI: Update manager timings on a manual update
@ 2012-08-09 11:56     ` Archit Taneja
  0 siblings, 0 replies; 122+ messages in thread
From: Archit Taneja @ 2012-08-09 11:56 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-fbdev, linux-omap, Archit Taneja

During a command mode update using DISPC video port, we may need to swap the
connected overlay manager's width and height when 90 or 270 degree rotation is
done via the panel by changing it's address mode.

Call dss_mgr_set_timings() in update_screen_dispc() before starting the manager
update. The new manager size is updated in the 'timings' field of DSI driver's
private data via omapdss_dsi_set_size(). A panel driver is expected to call this
when performing rotation.

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

diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index eb364d4..6e1c74b 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -4180,8 +4180,7 @@ void dsi_disable_video_output(struct omap_dss_device *dssdev, int channel)
 }
 EXPORT_SYMBOL(dsi_disable_video_output);
 
-static void dsi_update_screen_dispc(struct omap_dss_device *dssdev,
-		u16 w, u16 h)
+static void dsi_update_screen_dispc(struct omap_dss_device *dssdev)
 {
 	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
 	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
@@ -4195,6 +4194,8 @@ static void dsi_update_screen_dispc(struct omap_dss_device *dssdev,
 	int r;
 	const unsigned channel = dsi->update_channel;
 	const unsigned line_buf_size = dsi_get_line_buf_size(dsidev);
+	u16 w = dsi->timings.x_res;
+	u16 h = dsi->timings.y_res;
 
 	DSSDBG("dsi_update_screen_dispc(%dx%d)\n", w, h);
 
@@ -4244,6 +4245,8 @@ 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_start_update(dssdev->manager);
 
 	if (dsi->te_enabled) {
@@ -4337,7 +4340,7 @@ int omap_dsi_update(struct omap_dss_device *dssdev, int channel,
 	dsi->update_bytes = dw * dh *
 		dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt) / 8;
 #endif
-	dsi_update_screen_dispc(dssdev, dw, dh);
+	dsi_update_screen_dispc(dssdev);
 
 	return 0;
 }
-- 
1.7.9.5


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

* [PATCH v2 06/13] OMAPDSS: HDMI: Use our own omap_video_timings field when setting interface timings
@ 2012-08-09 11:56     ` Archit Taneja
  0 siblings, 0 replies; 122+ messages in thread
From: Archit Taneja @ 2012-08-09 11:56 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-fbdev, linux-omap, Archit Taneja

The hdmi driver currently updates only the 'code' member of hdmi_config when
the op omapdss_hdmi_display_set_timing() is called by the hdmi panel driver.
The 'timing' field of hdmi_config is updated only when hdmi_power_on is called.
It makes more sense to configure the whole hdmi_config field in the set_timing
op called by the panel driver. This way, we don't need to call both functions
to ensure that our hdmi_config is configured correctly. Also, we don't need to
calculate hdmi_config during hdmi_power_on, or rely on the omap_video_timings
in the panel's omap_dss_device struct.

A default timing is now configured in hdmi's probe if the panel driver doesn't
set any timing, or doesn't set a valid timing before enabling the panel. Also,
when setting manager timings, use the omap_video_timing calculated by
hdmi_get_timings(), this returns the timings as specified in the CEA/VESA
tables, don't use the one provided by the panel driver directly.

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

diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index 8a9630b..7e38ffd 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -485,7 +485,8 @@ static inline unsigned long hdmi_get_pixel_clock(void)
 #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);
+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);
diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c
index 6635b09..bdf1c33 100644
--- a/drivers/video/omap2/dss/hdmi.c
+++ b/drivers/video/omap2/dss/hdmi.c
@@ -462,7 +462,6 @@ static int hdmi_power_on(struct omap_dss_device *dssdev)
 {
 	const struct omapdss_clock_config *clks;
 	int r;
-	const struct hdmi_config *timing;
 	struct omap_video_timings *p;
 	unsigned long phy;
 
@@ -472,22 +471,10 @@ static int hdmi_power_on(struct omap_dss_device *dssdev)
 
 	dss_mgr_disable(dssdev->manager);
 
-	p = &dssdev->panel.timings;
+	p = &hdmi.ip_data.cfg.timings;
 
-	DSSDBG("hdmi_power_on x_res= %d y_res = %d\n",
-		dssdev->panel.timings.x_res,
-		dssdev->panel.timings.y_res);
+	DSSDBG("hdmi_power_on x_res= %d y_res = %d\n", p->x_res, p->y_res);
 
-	timing = hdmi_get_timings();
-	if (timing = NULL) {
-		/* HDMI code 4 corresponds to 640 * 480 VGA */
-		hdmi.ip_data.cfg.cm.code = 4;
-		/* DVI mode 1 corresponds to HDMI 0 to DVI */
-		hdmi.ip_data.cfg.cm.mode = HDMI_DVI;
-		hdmi.ip_data.cfg = vesa_timings[0];
-	} else {
-		hdmi.ip_data.cfg = *timing;
-	}
 	phy = p->pixel_clock;
 
 	hdmi_compute_pll(phy, &hdmi.ip_data.pll_data);
@@ -525,7 +512,7 @@ static int hdmi_power_on(struct omap_dss_device *dssdev)
 	dispc_enable_gamma_table(0);
 
 	/* tv size */
-	dss_mgr_set_timings(dssdev->manager, &dssdev->panel.timings);
+	dss_mgr_set_timings(dssdev->manager, p);
 
 	r = hdmi.ip_data.ops->video_enable(&hdmi.ip_data);
 	if (r)
@@ -571,13 +558,18 @@ 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_device *dssdev,
+		struct omap_video_timings *timings)
 {
 	struct hdmi_cm cm;
+	const struct hdmi_config *t;
+
+	cm = hdmi_get_code(timings);
+	hdmi.ip_data.cfg.cm = cm;
 
-	cm = hdmi_get_code(&dssdev->panel.timings);
-	hdmi.ip_data.cfg.cm.code = cm.code;
-	hdmi.ip_data.cfg.cm.mode = cm.mode;
+	t = hdmi_get_timings();
+	if (t != NULL)
+		hdmi.ip_data.cfg = *t;
 
 	if (dssdev->state = OMAP_DSS_DISPLAY_ACTIVE) {
 		int r;
@@ -588,7 +580,7 @@ void omapdss_hdmi_display_set_timing(struct omap_dss_device *dssdev)
 		if (r)
 			DSSERR("failed to power on device\n");
 	} else {
-		dss_mgr_set_timings(dssdev->manager, &dssdev->panel.timings);
+		dss_mgr_set_timings(dssdev->manager, &t->timings);
 	}
 }
 
@@ -933,6 +925,13 @@ static int __init omapdss_hdmihw_probe(struct platform_device *pdev)
 	hdmi.ip_data.core_av_offset = HDMI_CORE_AV;
 	hdmi.ip_data.pll_offset = HDMI_PLLCTRL;
 	hdmi.ip_data.phy_offset = HDMI_PHY;
+
+	/*
+	 * initialize hdmi timings to default value:
+	 * HDMI code 4(VGA) and HDMI mode 1(DVI)
+	 */
+	hdmi.ip_data.cfg = vesa_timings[0];
+
 	mutex_init(&hdmi.ip_data.lock);
 
 	hdmi_panel_init();
diff --git a/drivers/video/omap2/dss/hdmi_panel.c b/drivers/video/omap2/dss/hdmi_panel.c
index e10844f..8dce206 100644
--- a/drivers/video/omap2/dss/hdmi_panel.c
+++ b/drivers/video/omap2/dss/hdmi_panel.c
@@ -336,8 +336,8 @@ static void hdmi_set_timings(struct omap_dss_device *dssdev,
 	 */
 	hdmi_panel_audio_disable(dssdev);
 
+	omapdss_hdmi_display_set_timing(dssdev, timings);
 	dssdev->panel.timings = *timings;
-	omapdss_hdmi_display_set_timing(dssdev);
 
 	mutex_unlock(&hdmi.lock);
 }
-- 
1.7.9.5


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

* [PATCH v2 07/13] OMAPDSS: HDMI: Add a get_timing function for HDMI interface
@ 2012-08-09 11:56     ` Archit Taneja
  0 siblings, 0 replies; 122+ messages in thread
From: Archit Taneja @ 2012-08-09 11:56 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-fbdev, linux-omap, Archit Taneja

Add function omapdss_hdmi_display_get_timing() which returns the timings
maintained by the HDMI interface driver in it's hdmi_config field. This
prevents the need for the panel driver to configure default timings in it's
probe.

This function is just intended to be used once during the panel driver's probe.
It makes sense for those interfaces which can be configured to a default timing.

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

diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index 7e38ffd..df49c5d 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -485,6 +485,8 @@ static inline unsigned long hdmi_get_pixel_clock(void)
 #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_get_timing(struct omap_dss_device *dssdev,
+		struct omap_video_timings *timings);
 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,
diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c
index bdf1c33..f577c8e 100644
--- a/drivers/video/omap2/dss/hdmi.c
+++ b/drivers/video/omap2/dss/hdmi.c
@@ -544,6 +544,12 @@ static void hdmi_power_off(struct omap_dss_device *dssdev)
 	hdmi_runtime_put();
 }
 
+void omapdss_hdmi_display_get_timing(struct omap_dss_device *dssdev,
+		struct omap_video_timings *timings)
+{
+	*timings = hdmi.ip_data.cfg.timings;
+}
+
 int omapdss_hdmi_display_check_timing(struct omap_dss_device *dssdev,
 					struct omap_video_timings *timings)
 {
diff --git a/drivers/video/omap2/dss/hdmi_panel.c b/drivers/video/omap2/dss/hdmi_panel.c
index 8dce206..8473193 100644
--- a/drivers/video/omap2/dss/hdmi_panel.c
+++ b/drivers/video/omap2/dss/hdmi_panel.c
@@ -41,13 +41,13 @@ static struct {
 
 static int hdmi_panel_probe(struct omap_dss_device *dssdev)
 {
+	struct omap_video_timings timings;
+
 	DSSDBG("ENTER hdmi_panel_probe\n");
 
-	dssdev->panel.timings = (struct omap_video_timings)
-			{ 640, 480, 25175, 96, 16, 48, 2, 11, 31,
-				OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
-				false,
-			};
+	omapdss_hdmi_display_get_timing(dssdev, &timings);
+
+	dssdev->panel.timings = timings;
 
 	DSSDBG("hdmi_panel_probe x_res= %d y_res = %d\n",
 		dssdev->panel.timings.x_res,
-- 
1.7.9.5


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

* [PATCH v2 08/13] OMAPDSS: HDMI: Add locking for hdmi interface get/set timing functions
@ 2012-08-09 11:56     ` Archit Taneja
  0 siblings, 0 replies; 122+ messages in thread
From: Archit Taneja @ 2012-08-09 11:56 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-fbdev, linux-omap, Archit Taneja

The hdmi interface driver exposes functions to the hdmi panel driver to
get and configure the interface timings maintained by the hdmi driver.

These timings(stored in hdmi.ip_data.cfg) should be protected by the hdmi lock
to ensure they are called sequentially, this is similar to how hdmi enable and
disable functions need locking.

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

diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c
index f577c8e..171c695 100644
--- a/drivers/video/omap2/dss/hdmi.c
+++ b/drivers/video/omap2/dss/hdmi.c
@@ -547,7 +547,11 @@ static void hdmi_power_off(struct omap_dss_device *dssdev)
 void omapdss_hdmi_display_get_timing(struct omap_dss_device *dssdev,
 		struct omap_video_timings *timings)
 {
+	mutex_lock(&hdmi.lock);
+
 	*timings = hdmi.ip_data.cfg.timings;
+
+	mutex_unlock(&hdmi.lock);
 }
 
 int omapdss_hdmi_display_check_timing(struct omap_dss_device *dssdev,
@@ -570,6 +574,8 @@ void omapdss_hdmi_display_set_timing(struct omap_dss_device *dssdev,
 	struct hdmi_cm cm;
 	const struct hdmi_config *t;
 
+	mutex_lock(&hdmi.lock);
+
 	cm = hdmi_get_code(timings);
 	hdmi.ip_data.cfg.cm = cm;
 
@@ -588,6 +594,8 @@ void omapdss_hdmi_display_set_timing(struct omap_dss_device *dssdev,
 	} else {
 		dss_mgr_set_timings(dssdev->manager, &t->timings);
 	}
+
+	mutex_unlock(&hdmi.lock);
 }
 
 static void hdmi_dump_regs(struct seq_file *s)
-- 
1.7.9.5


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

* [PATCH v2 09/13] OMAPDSS: SDI: Create a function to set timings
@ 2012-08-09 11:56     ` Archit Taneja
  0 siblings, 0 replies; 122+ messages in thread
From: Archit Taneja @ 2012-08-09 11:56 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-fbdev, linux-omap, Archit Taneja

Create function omapdss_sdi_set_timings(). Configuring new timings is done the
same way as before, SDI is disabled, and re-enabled with the new timings in
dssdev. This just moves the code from the panel drivers to the SDI driver.

The panel drivers shouldn't be aware of how SDI manages to configure a new set
of timings. This should be taken care of by the SDI driver itself.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/displays/panel-acx565akm.c |   13 +------------
 drivers/video/omap2/dss/sdi.c                  |   17 +++++++++++++++++
 include/video/omapdss.h                        |    2 ++
 3 files changed, 20 insertions(+), 12 deletions(-)

diff --git a/drivers/video/omap2/displays/panel-acx565akm.c b/drivers/video/omap2/displays/panel-acx565akm.c
index eaeed43..11bdc88 100644
--- a/drivers/video/omap2/displays/panel-acx565akm.c
+++ b/drivers/video/omap2/displays/panel-acx565akm.c
@@ -731,18 +731,7 @@ 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)
 {
-	int r;
-
-	if (dssdev->state = OMAP_DSS_DISPLAY_ACTIVE)
-		omapdss_sdi_display_disable(dssdev);
-
-	dssdev->panel.timings = *timings;
-
-	if (dssdev->state = OMAP_DSS_DISPLAY_ACTIVE) {
-		r = omapdss_sdi_display_enable(dssdev);
-		if (r)
-			dev_err(&dssdev->dev, "%s enable failed\n", __func__);
-	}
+	omapdss_sdi_set_timings(dssdev, timings);
 }
 
 static int acx_panel_check_timings(struct omap_dss_device *dssdev,
diff --git a/drivers/video/omap2/dss/sdi.c b/drivers/video/omap2/dss/sdi.c
index 5d31699..0474962 100644
--- a/drivers/video/omap2/dss/sdi.c
+++ b/drivers/video/omap2/dss/sdi.c
@@ -146,6 +146,23 @@ void omapdss_sdi_display_disable(struct omap_dss_device *dssdev)
 }
 EXPORT_SYMBOL(omapdss_sdi_display_disable);
 
+void omapdss_sdi_set_timings(struct omap_dss_device *dssdev,
+		struct omap_video_timings *timings)
+{
+	int r;
+
+	dssdev->panel.timings = *timings;
+
+	if (dssdev->state = OMAP_DSS_DISPLAY_ACTIVE) {
+		omapdss_sdi_display_disable(dssdev);
+
+		r = omapdss_sdi_display_enable(dssdev);
+		if (r)
+			DSSERR("failed to set new timings\n");
+	}
+}
+EXPORT_SYMBOL(omapdss_sdi_set_timings);
+
 static int __init sdi_init_display(struct omap_dss_device *dssdev)
 {
 	DSSDBG("SDI init\n");
diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index a85b3fb..c5c013e 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -761,6 +761,8 @@ int dpi_check_timings(struct omap_dss_device *dssdev,
 
 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,
+		struct omap_video_timings *timings);
 
 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] 122+ messages in thread

* [PATCH v2 10/13] OMAPDSS: SDI: Maintain our own timings field in driver data
@ 2012-08-09 11:56     ` Archit Taneja
  0 siblings, 0 replies; 122+ messages in thread
From: Archit Taneja @ 2012-08-09 11:56 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-fbdev, linux-omap, Archit Taneja

The SDI driver currently relies on the timings in omap_dss_device struct to
configure the DISPC accordingly. This makes the SDI interface driver dependent
on the omap_dss_device struct.

Make the SDI driver data maintain it's own timings field. The panel driver is
expected to call omapdss_sdi_set_timings() to set these timings before the panel
is enabled.

Make the SDI panel driver configure the new timings is the omap_dss_device
struct(dssdev->panel.timings). The SDI driver is responsible for maintaining
only it's own copy of timings.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/displays/panel-acx565akm.c |    4 ++++
 drivers/video/omap2/dss/sdi.c                  |    5 +++--
 2 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/video/omap2/displays/panel-acx565akm.c b/drivers/video/omap2/displays/panel-acx565akm.c
index 11bdc88..77fe59f 100644
--- a/drivers/video/omap2/displays/panel-acx565akm.c
+++ b/drivers/video/omap2/displays/panel-acx565akm.c
@@ -600,6 +600,8 @@ static int acx_panel_power_on(struct omap_dss_device *dssdev)
 
 	mutex_lock(&md->mutex);
 
+	omapdss_sdi_set_timings(dssdev, &dssdev->panel.timings);
+
 	r = omapdss_sdi_display_enable(dssdev);
 	if (r) {
 		pr_err("%s sdi enable failed\n", __func__);
@@ -732,6 +734,8 @@ static void acx_panel_set_timings(struct omap_dss_device *dssdev,
 		struct omap_video_timings *timings)
 {
 	omapdss_sdi_set_timings(dssdev, timings);
+
+	dssdev->panel.timings = *timings;
 }
 
 static int acx_panel_check_timings(struct omap_dss_device *dssdev,
diff --git a/drivers/video/omap2/dss/sdi.c b/drivers/video/omap2/dss/sdi.c
index 0474962..243e96d 100644
--- a/drivers/video/omap2/dss/sdi.c
+++ b/drivers/video/omap2/dss/sdi.c
@@ -34,6 +34,7 @@ static struct {
 	struct regulator *vdds_sdi_reg;
 
 	struct dss_lcd_mgr_config mgr_config;
+	struct omap_video_timings timings;
 } sdi;
 
 static void sdi_config_lcd_manager(struct omap_dss_device *dssdev)
@@ -51,7 +52,7 @@ static void sdi_config_lcd_manager(struct omap_dss_device *dssdev)
 
 int omapdss_sdi_display_enable(struct omap_dss_device *dssdev)
 {
-	struct omap_video_timings *t = &dssdev->panel.timings;
+	struct omap_video_timings *t = &sdi.timings;
 	struct dss_clock_info dss_cinfo;
 	struct dispc_clock_info dispc_cinfo;
 	unsigned long pck;
@@ -151,7 +152,7 @@ void omapdss_sdi_set_timings(struct omap_dss_device *dssdev,
 {
 	int r;
 
-	dssdev->panel.timings = *timings;
+	sdi.timings = *timings;
 
 	if (dssdev->state = OMAP_DSS_DISPLAY_ACTIVE) {
 		omapdss_sdi_display_disable(dssdev);
-- 
1.7.9.5


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

* [PATCH v2 11/13] OMAPDSS: VENC: Split VENC into interface and panel driver
@ 2012-08-09 11:56     ` Archit Taneja
  0 siblings, 0 replies; 122+ messages in thread
From: Archit Taneja @ 2012-08-09 11:56 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-fbdev, linux-omap, Archit Taneja

The current venc.c driver contains both the interface and panel driver code.
This makes the driver hard to read, and difficult to understand the work split
between the interface and panel driver and the how the locking works.

This also makes it easier to clearly define the VENC interface ops called by the
panel driver.

Split venc.c into venc.c and venc_panel.c representing the interface and panel
driver respectively. This split is done along the lines of the HDMI interface
and panel drivers.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/dss/Makefile     |    2 +-
 drivers/video/omap2/dss/dss.h        |   10 ++
 drivers/video/omap2/dss/venc.c       |  208 ++++++++----------------------
 drivers/video/omap2/dss/venc_panel.c |  231 ++++++++++++++++++++++++++++++++++
 4 files changed, 295 insertions(+), 156 deletions(-)
 create mode 100644 drivers/video/omap2/dss/venc_panel.c

diff --git a/drivers/video/omap2/dss/Makefile b/drivers/video/omap2/dss/Makefile
index 5c450b0..30a48fb 100644
--- a/drivers/video/omap2/dss/Makefile
+++ b/drivers/video/omap2/dss/Makefile
@@ -3,7 +3,7 @@ omapdss-y := core.o dss.o dss_features.o dispc.o dispc_coefs.o display.o \
 	manager.o overlay.o apply.o
 omapdss-$(CONFIG_OMAP2_DSS_DPI) += dpi.o
 omapdss-$(CONFIG_OMAP2_DSS_RFBI) += rfbi.o
-omapdss-$(CONFIG_OMAP2_DSS_VENC) += venc.o
+omapdss-$(CONFIG_OMAP2_DSS_VENC) += venc.o venc_panel.o
 omapdss-$(CONFIG_OMAP2_DSS_SDI) += sdi.o
 omapdss-$(CONFIG_OMAP2_DSS_DSI) += dsi.o
 omapdss-$(CONFIG_OMAP4_DSS_HDMI) += hdmi.o \
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index df49c5d..69b6ab9 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -470,6 +470,16 @@ 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,
+		struct omap_video_timings *timings);
+int omapdss_venc_check_timings(struct omap_dss_device *dssdev,
+		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);
+int venc_panel_init(void);
+void venc_panel_exit(void);
 
 /* HDMI */
 #ifdef CONFIG_OMAP4_DSS_HDMI
diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c
index 3a22087..ffca542 100644
--- a/drivers/video/omap2/dss/venc.c
+++ b/drivers/video/omap2/dss/venc.c
@@ -427,6 +427,10 @@ static int venc_power_on(struct omap_dss_device *dssdev)
 	u32 l;
 	int r;
 
+	r = venc_runtime_get();
+	if (r)
+		goto err0;
+
 	venc_reset();
 	venc_write_config(venc_timings_to_config(&dssdev->panel.timings));
 
@@ -449,26 +453,22 @@ static int venc_power_on(struct omap_dss_device *dssdev)
 
 	r = regulator_enable(venc.vdda_dac_reg);
 	if (r)
-		goto err;
-
-	if (dssdev->platform_enable)
-		dssdev->platform_enable(dssdev);
+		goto err1;
 
 	r = dss_mgr_enable(dssdev->manager);
 	if (r)
-		goto err;
+		goto err2;
 
 	return 0;
 
-err:
+err2:
+	regulator_disable(venc.vdda_dac_reg);
+err1:
 	venc_write_reg(VENC_OUTPUT_CONTROL, 0);
 	dss_set_dac_pwrdn_bgz(0);
 
-	if (dssdev->platform_disable)
-		dssdev->platform_disable(dssdev);
-
-	regulator_disable(venc.vdda_dac_reg);
-
+	venc_runtime_put();
+err0:
 	return r;
 }
 
@@ -479,10 +479,9 @@ static void venc_power_off(struct omap_dss_device *dssdev)
 
 	dss_mgr_disable(dssdev->manager);
 
-	if (dssdev->platform_disable)
-		dssdev->platform_disable(dssdev);
-
 	regulator_disable(venc.vdda_dac_reg);
+
+	venc_runtime_put();
 }
 
 unsigned long venc_get_pixel_clock(void)
@@ -491,171 +490,95 @@ unsigned long venc_get_pixel_clock(void)
 	return 13500000;
 }
 
-static ssize_t display_output_type_show(struct device *dev,
-		struct device_attribute *attr, char *buf)
+int omapdss_venc_display_enable(struct omap_dss_device *dssdev)
 {
-	struct omap_dss_device *dssdev = to_dss_device(dev);
-	const char *ret;
-
-	switch (dssdev->phy.venc.type) {
-	case OMAP_DSS_VENC_TYPE_COMPOSITE:
-		ret = "composite";
-		break;
-	case OMAP_DSS_VENC_TYPE_SVIDEO:
-		ret = "svideo";
-		break;
-	default:
-		return -EINVAL;
-	}
+	int r;
 
-	return snprintf(buf, PAGE_SIZE, "%s\n", ret);
-}
-
-static ssize_t display_output_type_store(struct device *dev,
-		struct device_attribute *attr, const char *buf, size_t size)
-{
-	struct omap_dss_device *dssdev = to_dss_device(dev);
-	enum omap_dss_venc_type new_type;
-
-	if (sysfs_streq("composite", buf))
-		new_type = OMAP_DSS_VENC_TYPE_COMPOSITE;
-	else if (sysfs_streq("svideo", buf))
-		new_type = OMAP_DSS_VENC_TYPE_SVIDEO;
-	else
-		return -EINVAL;
+	DSSDBG("venc_display_enable\n");
 
 	mutex_lock(&venc.venc_lock);
 
-	if (dssdev->phy.venc.type != new_type) {
-		dssdev->phy.venc.type = new_type;
-		if (dssdev->state = OMAP_DSS_DISPLAY_ACTIVE) {
-			venc_power_off(dssdev);
-			venc_power_on(dssdev);
-		}
+	if (dssdev->manager = NULL) {
+		DSSERR("Failed to enable display: no manager\n");
+		r = -ENODEV;
+		goto err0;
 	}
 
-	mutex_unlock(&venc.venc_lock);
-
-	return size;
-}
-
-static DEVICE_ATTR(output_type, S_IRUGO | S_IWUSR,
-		display_output_type_show, display_output_type_store);
-
-/* driver */
-static int venc_panel_probe(struct omap_dss_device *dssdev)
-{
-	dssdev->panel.timings = omap_dss_pal_timings;
-
-	return device_create_file(&dssdev->dev, &dev_attr_output_type);
-}
-
-static void venc_panel_remove(struct omap_dss_device *dssdev)
-{
-	device_remove_file(&dssdev->dev, &dev_attr_output_type);
-}
-
-static int venc_panel_enable(struct omap_dss_device *dssdev)
-{
-	int r = 0;
-
-	DSSDBG("venc_enable_display\n");
-
-	mutex_lock(&venc.venc_lock);
-
 	r = omap_dss_start_device(dssdev);
 	if (r) {
 		DSSERR("failed to start device\n");
 		goto err0;
 	}
 
-	if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) {
-		r = -EINVAL;
-		goto err1;
-	}
+	if (dssdev->platform_enable)
+		dssdev->platform_enable(dssdev);
 
-	r = venc_runtime_get();
-	if (r)
-		goto err1;
 
 	r = venc_power_on(dssdev);
 	if (r)
-		goto err2;
+		goto err1;
 
 	venc.wss_data = 0;
 
-	dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
-
 	mutex_unlock(&venc.venc_lock);
+
 	return 0;
-err2:
-	venc_runtime_put();
 err1:
+	if (dssdev->platform_disable)
+		dssdev->platform_disable(dssdev);
 	omap_dss_stop_device(dssdev);
 err0:
 	mutex_unlock(&venc.venc_lock);
-
 	return r;
 }
 
-static void venc_panel_disable(struct omap_dss_device *dssdev)
+void omapdss_venc_display_disable(struct omap_dss_device *dssdev)
 {
-	DSSDBG("venc_disable_display\n");
+	DSSDBG("venc_display_disable\n");
 
 	mutex_lock(&venc.venc_lock);
 
-	if (dssdev->state = OMAP_DSS_DISPLAY_DISABLED)
-		goto end;
-
-	if (dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED) {
-		/* suspended is the same as disabled with venc */
-		dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
-		goto end;
-	}
-
 	venc_power_off(dssdev);
 
-	venc_runtime_put();
-
-	dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
-
 	omap_dss_stop_device(dssdev);
-end:
-	mutex_unlock(&venc.venc_lock);
-}
 
-static int venc_panel_suspend(struct omap_dss_device *dssdev)
-{
-	venc_panel_disable(dssdev);
-	return 0;
-}
+	if (dssdev->platform_disable)
+		dssdev->platform_disable(dssdev);
 
-static int venc_panel_resume(struct omap_dss_device *dssdev)
-{
-	return venc_panel_enable(dssdev);
+	mutex_unlock(&venc.venc_lock);
 }
 
-static void venc_set_timings(struct omap_dss_device *dssdev,
-			struct omap_video_timings *timings)
+void omapdss_venc_set_timings(struct omap_dss_device *dssdev,
+		struct omap_video_timings *timings)
 {
 	DSSDBG("venc_set_timings\n");
 
+	mutex_lock(&venc.venc_lock);
+
 	/* Reset WSS data when the TV standard changes. */
 	if (memcmp(&dssdev->panel.timings, timings, sizeof(*timings)))
 		venc.wss_data = 0;
 
 	dssdev->panel.timings = *timings;
+
 	if (dssdev->state = OMAP_DSS_DISPLAY_ACTIVE) {
+		int r;
+
 		/* turn the venc off and on to get new timings to use */
-		venc_panel_disable(dssdev);
-		venc_panel_enable(dssdev);
+		venc_power_off(dssdev);
+
+		r = venc_power_on(dssdev);
+		if (r)
+			DSSERR("failed to power on VENC\n");
 	} else {
 		dss_mgr_set_timings(dssdev->manager, timings);
 	}
+
+	mutex_unlock(&venc.venc_lock);
 }
 
-static int venc_check_timings(struct omap_dss_device *dssdev,
-			struct omap_video_timings *timings)
+int omapdss_venc_check_timings(struct omap_dss_device *dssdev,
+		struct omap_video_timings *timings)
 {
 	DSSDBG("venc_check_timings\n");
 
@@ -668,13 +591,13 @@ static int venc_check_timings(struct omap_dss_device *dssdev,
 	return -EINVAL;
 }
 
-static u32 venc_get_wss(struct omap_dss_device *dssdev)
+u32 omapdss_venc_get_wss(struct omap_dss_device *dssdev)
 {
 	/* Invert due to VENC_L21_WC_CTL:INV=1 */
 	return (venc.wss_data >> 8) ^ 0xfffff;
 }
 
-static int venc_set_wss(struct omap_dss_device *dssdev,	u32 wss)
+int omapdss_venc_set_wss(struct omap_dss_device *dssdev, u32 wss)
 {
 	const struct venc_config *config;
 	int r;
@@ -703,31 +626,6 @@ err:
 	return r;
 }
 
-static struct omap_dss_driver venc_driver = {
-	.probe		= venc_panel_probe,
-	.remove		= venc_panel_remove,
-
-	.enable		= venc_panel_enable,
-	.disable	= venc_panel_disable,
-	.suspend	= venc_panel_suspend,
-	.resume		= venc_panel_resume,
-
-	.get_resolution	= omapdss_default_get_resolution,
-	.get_recommended_bpp = omapdss_default_get_recommended_bpp,
-
-	.set_timings	= venc_set_timings,
-	.check_timings	= venc_check_timings,
-
-	.get_wss	= venc_get_wss,
-	.set_wss	= venc_set_wss,
-
-	.driver         = {
-		.name   = "venc",
-		.owner  = THIS_MODULE,
-	},
-};
-/* driver end */
-
 static int __init venc_init_display(struct omap_dss_device *dssdev)
 {
 	DSSDBG("init_display\n");
@@ -897,9 +795,9 @@ static int __init omap_venchw_probe(struct platform_device *pdev)
 
 	venc_runtime_put();
 
-	r = omap_dss_register_driver(&venc_driver);
+	r = venc_panel_init();
 	if (r)
-		goto err_reg_panel_driver;
+		goto err_panel_init;
 
 	dss_debugfs_create_file("venc", venc_dump_regs);
 
@@ -907,7 +805,7 @@ static int __init omap_venchw_probe(struct platform_device *pdev)
 
 	return 0;
 
-err_reg_panel_driver:
+err_panel_init:
 err_runtime_get:
 	pm_runtime_disable(&pdev->dev);
 	venc_put_clocks();
@@ -923,7 +821,7 @@ static int __exit omap_venchw_remove(struct platform_device *pdev)
 		venc.vdda_dac_reg = NULL;
 	}
 
-	omap_dss_unregister_driver(&venc_driver);
+	venc_panel_exit();
 
 	pm_runtime_disable(&pdev->dev);
 	venc_put_clocks();
diff --git a/drivers/video/omap2/dss/venc_panel.c b/drivers/video/omap2/dss/venc_panel.c
new file mode 100644
index 0000000..6b31298
--- /dev/null
+++ b/drivers/video/omap2/dss/venc_panel.c
@@ -0,0 +1,231 @@
+/*
+ * Copyright (C) 2009 Nokia Corporation
+ * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
+ *
+ * VENC panel driver
+ *
+ * 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/err.h>
+#include <linux/io.h>
+#include <linux/mutex.h>
+#include <linux/module.h>
+
+#include <video/omapdss.h>
+
+#include "dss.h"
+
+static struct {
+	struct mutex lock;
+} venc_panel;
+
+static ssize_t display_output_type_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct omap_dss_device *dssdev = to_dss_device(dev);
+	const char *ret;
+
+	switch (dssdev->phy.venc.type) {
+	case OMAP_DSS_VENC_TYPE_COMPOSITE:
+		ret = "composite";
+		break;
+	case OMAP_DSS_VENC_TYPE_SVIDEO:
+		ret = "svideo";
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return snprintf(buf, PAGE_SIZE, "%s\n", ret);
+}
+
+static ssize_t display_output_type_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t size)
+{
+	struct omap_dss_device *dssdev = to_dss_device(dev);
+	enum omap_dss_venc_type new_type;
+
+	if (sysfs_streq("composite", buf))
+		new_type = OMAP_DSS_VENC_TYPE_COMPOSITE;
+	else if (sysfs_streq("svideo", buf))
+		new_type = OMAP_DSS_VENC_TYPE_SVIDEO;
+	else
+		return -EINVAL;
+
+	mutex_lock(&venc_panel.lock);
+
+	if (dssdev->phy.venc.type != new_type) {
+		dssdev->phy.venc.type = new_type;
+		if (dssdev->state = OMAP_DSS_DISPLAY_ACTIVE) {
+			omapdss_venc_display_disable(dssdev);
+			omapdss_venc_display_enable(dssdev);
+		}
+	}
+
+	mutex_unlock(&venc_panel.lock);
+
+	return size;
+}
+
+static DEVICE_ATTR(output_type, S_IRUGO | S_IWUSR,
+		display_output_type_show, display_output_type_store);
+
+static int venc_panel_probe(struct omap_dss_device *dssdev)
+{
+	mutex_init(&venc_panel.lock);
+
+	/* set initial timings to PAL */
+	dssdev->panel.timings = (struct omap_video_timings)
+		{ 720, 574, 13500, 64, 12, 68, 5, 5, 41,
+			OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
+			true,
+		};
+
+	return device_create_file(&dssdev->dev, &dev_attr_output_type);
+}
+
+static void venc_panel_remove(struct omap_dss_device *dssdev)
+{
+	device_remove_file(&dssdev->dev, &dev_attr_output_type);
+}
+
+static int venc_panel_enable(struct omap_dss_device *dssdev)
+{
+	int r;
+
+	dev_dbg(&dssdev->dev, "venc_panel_enable\n");
+
+	mutex_lock(&venc_panel.lock);
+
+	if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) {
+		r = -EINVAL;
+		goto err;
+	}
+
+	r = omapdss_venc_display_enable(dssdev);
+	if (r)
+		goto err;
+
+	dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
+
+	mutex_unlock(&venc_panel.lock);
+
+	return 0;
+err:
+	mutex_unlock(&venc_panel.lock);
+
+	return r;
+}
+
+static void venc_panel_disable(struct omap_dss_device *dssdev)
+{
+	dev_dbg(&dssdev->dev, "venc_panel_disable\n");
+
+	mutex_lock(&venc_panel.lock);
+
+	if (dssdev->state = OMAP_DSS_DISPLAY_DISABLED)
+		goto end;
+
+	if (dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED) {
+		/* suspended is the same as disabled with venc */
+		dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
+		goto end;
+	}
+
+	omapdss_venc_display_disable(dssdev);
+
+	dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
+end:
+	mutex_unlock(&venc_panel.lock);
+}
+
+static int venc_panel_suspend(struct omap_dss_device *dssdev)
+{
+	venc_panel_disable(dssdev);
+	return 0;
+}
+
+static int venc_panel_resume(struct omap_dss_device *dssdev)
+{
+	return venc_panel_enable(dssdev);
+}
+
+static void venc_panel_set_timings(struct omap_dss_device *dssdev,
+		struct omap_video_timings *timings)
+{
+	dev_dbg(&dssdev->dev, "venc_panel_set_timings\n");
+
+	mutex_lock(&venc_panel.lock);
+
+	omapdss_venc_set_timings(dssdev, timings);
+
+	mutex_unlock(&venc_panel.lock);
+}
+
+static int venc_panel_check_timings(struct omap_dss_device *dssdev,
+		struct omap_video_timings *timings)
+{
+	dev_dbg(&dssdev->dev, "venc_panel_check_timings\n");
+
+	return omapdss_venc_check_timings(dssdev, timings);
+}
+
+static u32 venc_panel_get_wss(struct omap_dss_device *dssdev)
+{
+	dev_dbg(&dssdev->dev, "venc_panel_get_wss\n");
+
+	return omapdss_venc_get_wss(dssdev);
+}
+
+static int venc_panel_set_wss(struct omap_dss_device *dssdev, u32 wss)
+{
+	dev_dbg(&dssdev->dev, "venc_panel_set_wss\n");
+
+	return omapdss_venc_set_wss(dssdev, wss);
+}
+
+static struct omap_dss_driver venc_driver = {
+	.probe		= venc_panel_probe,
+	.remove		= venc_panel_remove,
+
+	.enable		= venc_panel_enable,
+	.disable	= venc_panel_disable,
+	.suspend	= venc_panel_suspend,
+	.resume		= venc_panel_resume,
+
+	.get_resolution	= omapdss_default_get_resolution,
+	.get_recommended_bpp = omapdss_default_get_recommended_bpp,
+
+	.set_timings	= venc_panel_set_timings,
+	.check_timings	= venc_panel_check_timings,
+
+	.get_wss	= venc_panel_get_wss,
+	.set_wss	= venc_panel_set_wss,
+
+	.driver         = {
+		.name   = "venc",
+		.owner  = THIS_MODULE,
+	},
+};
+
+int venc_panel_init(void)
+{
+	return omap_dss_register_driver(&venc_driver);
+}
+
+void venc_panel_exit(void)
+{
+	omap_dss_unregister_driver(&venc_driver);
+}
-- 
1.7.9.5


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

* [PATCH v2 12/13] OMAPDSS: VENC: Maintain our own timings field in driver data
@ 2012-08-09 11:56     ` Archit Taneja
  0 siblings, 0 replies; 122+ messages in thread
From: Archit Taneja @ 2012-08-09 11:56 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-fbdev, linux-omap, Archit Taneja

The VENC driver currently relies on the timings in omap_dss_device struct to
configure the DISPC and VENC blocks accordingly. This makes the VENC interface
driver dependent on the omap_dss_device struct.

Make the VENC driver data maintain it's own timings field. The panel driver is
expected to call omapdss_venc_set_timings() to set these timings before the
panel is enabled.

Make the VENC panel driver configure the new timings is the omap_dss_device
struct(dssdev->panel.timings). The VENC driver is responsible for maintaining
only it's own copy of timings.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/dss/venc.c       |   12 +++++++-----
 drivers/video/omap2/dss/venc_panel.c |    1 +
 2 files changed, 8 insertions(+), 5 deletions(-)

diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c
index ffca542..d96025e 100644
--- a/drivers/video/omap2/dss/venc.c
+++ b/drivers/video/omap2/dss/venc.c
@@ -300,6 +300,8 @@ static struct {
 	struct regulator *vdda_dac_reg;
 
 	struct clk	*tv_dac_clk;
+
+	struct omap_video_timings timings;
 } venc;
 
 static inline void venc_write_reg(int idx, u32 val)
@@ -432,7 +434,7 @@ static int venc_power_on(struct omap_dss_device *dssdev)
 		goto err0;
 
 	venc_reset();
-	venc_write_config(venc_timings_to_config(&dssdev->panel.timings));
+	venc_write_config(venc_timings_to_config(&venc.timings));
 
 	dss_set_venc_output(dssdev->phy.venc.type);
 	dss_set_dac_pwrdn_bgz(1);
@@ -449,7 +451,7 @@ static int venc_power_on(struct omap_dss_device *dssdev)
 
 	venc_write_reg(VENC_OUTPUT_CONTROL, l);
 
-	dss_mgr_set_timings(dssdev->manager, &dssdev->panel.timings);
+	dss_mgr_set_timings(dssdev->manager, &venc.timings);
 
 	r = regulator_enable(venc.vdda_dac_reg);
 	if (r)
@@ -556,10 +558,10 @@ void omapdss_venc_set_timings(struct omap_dss_device *dssdev,
 	mutex_lock(&venc.venc_lock);
 
 	/* Reset WSS data when the TV standard changes. */
-	if (memcmp(&dssdev->panel.timings, timings, sizeof(*timings)))
+	if (memcmp(&venc.timings, timings, sizeof(*timings)))
 		venc.wss_data = 0;
 
-	dssdev->panel.timings = *timings;
+	venc.timings = *timings;
 
 	if (dssdev->state = OMAP_DSS_DISPLAY_ACTIVE) {
 		int r;
@@ -606,7 +608,7 @@ int omapdss_venc_set_wss(struct omap_dss_device *dssdev, u32 wss)
 
 	mutex_lock(&venc.venc_lock);
 
-	config = venc_timings_to_config(&dssdev->panel.timings);
+	config = venc_timings_to_config(&venc.timings);
 
 	/* Invert due to VENC_L21_WC_CTL:INV=1 */
 	venc.wss_data = (wss ^ 0xfffff) << 8;
diff --git a/drivers/video/omap2/dss/venc_panel.c b/drivers/video/omap2/dss/venc_panel.c
index 6b31298..350b0d9 100644
--- a/drivers/video/omap2/dss/venc_panel.c
+++ b/drivers/video/omap2/dss/venc_panel.c
@@ -170,6 +170,7 @@ static void venc_panel_set_timings(struct omap_dss_device *dssdev,
 	mutex_lock(&venc_panel.lock);
 
 	omapdss_venc_set_timings(dssdev, timings);
+	dssdev->panel.timings = *timings;
 
 	mutex_unlock(&venc_panel.lock);
 }
-- 
1.7.9.5


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

* [PATCH v2 13/13] OMAPDSS: VENC: Add a get_timing function for VENC interface
@ 2012-08-09 11:56     ` Archit Taneja
  0 siblings, 0 replies; 122+ messages in thread
From: Archit Taneja @ 2012-08-09 11:56 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-fbdev, linux-omap, Archit Taneja

Add function omapdss_venc_get_timing() which returns the timings
maintained by the VENC interface driver in it's driver data. This is just used
once by the driver during it's probe. This prevents the need for the panel
driver to configure default timings in it's probe.

Int the VENC interface's probe, the timings field is set to PAL as a default
value. The get_timing op makes more sense for interfaces which can be configured
to a default timing.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/dss/dss.h        |    2 ++
 drivers/video/omap2/dss/venc.c       |   13 +++++++++++++
 drivers/video/omap2/dss/venc_panel.c |   11 +++++------
 3 files changed, 20 insertions(+), 6 deletions(-)

diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index 69b6ab9..3fe76c0 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -474,6 +474,8 @@ 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,
 		struct omap_video_timings *timings);
+void omapdss_venc_get_timings(struct omap_dss_device *dssdev,
+		struct omap_video_timings *timings);
 int omapdss_venc_check_timings(struct omap_dss_device *dssdev,
 		struct omap_video_timings *timings);
 u32 omapdss_venc_get_wss(struct omap_dss_device *dssdev);
diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c
index d96025e..42f97ac 100644
--- a/drivers/video/omap2/dss/venc.c
+++ b/drivers/video/omap2/dss/venc.c
@@ -579,6 +579,18 @@ void omapdss_venc_set_timings(struct omap_dss_device *dssdev,
 	mutex_unlock(&venc.venc_lock);
 }
 
+void omapdss_venc_get_timings(struct omap_dss_device *dssdev,
+		struct omap_video_timings *timings)
+{
+	DSSDBG("venc_set_timings\n");
+
+	mutex_lock(&venc.venc_lock);
+
+	*timings = venc.timings;
+
+	mutex_unlock(&venc.venc_lock);
+}
+
 int omapdss_venc_check_timings(struct omap_dss_device *dssdev,
 		struct omap_video_timings *timings)
 {
@@ -768,6 +780,7 @@ static int __init omap_venchw_probe(struct platform_device *pdev)
 	mutex_init(&venc.venc_lock);
 
 	venc.wss_data = 0;
+	venc.timings = omap_dss_pal_timings;
 
 	venc_mem = platform_get_resource(venc.pdev, IORESOURCE_MEM, 0);
 	if (!venc_mem) {
diff --git a/drivers/video/omap2/dss/venc_panel.c b/drivers/video/omap2/dss/venc_panel.c
index 350b0d9..fe9958d 100644
--- a/drivers/video/omap2/dss/venc_panel.c
+++ b/drivers/video/omap2/dss/venc_panel.c
@@ -84,14 +84,13 @@ static DEVICE_ATTR(output_type, S_IRUGO | S_IWUSR,
 
 static int venc_panel_probe(struct omap_dss_device *dssdev)
 {
+	struct omap_video_timings timings;
+
 	mutex_init(&venc_panel.lock);
 
-	/* set initial timings to PAL */
-	dssdev->panel.timings = (struct omap_video_timings)
-		{ 720, 574, 13500, 64, 12, 68, 5, 5, 41,
-			OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
-			true,
-		};
+	omapdss_venc_get_timings(dssdev, &timings);
+
+	dssdev->panel.timings = timings;
 
 	return device_create_file(&dssdev->dev, &dev_attr_output_type);
 }
-- 
1.7.9.5


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

* Re: [PATCH v2 07/13] OMAPDSS: HDMI: Add a get_timing function for HDMI interface
  2012-08-09 11:56     ` Archit Taneja
@ 2012-08-14 13:02       ` Tomi Valkeinen
  -1 siblings, 0 replies; 122+ messages in thread
From: Tomi Valkeinen @ 2012-08-14 13:02 UTC (permalink / raw)
  To: Archit Taneja; +Cc: linux-fbdev, linux-omap

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

Hi,

On Thu, 2012-08-09 at 17:19 +0530, Archit Taneja wrote:
> Add function omapdss_hdmi_display_get_timing() which returns the timings
> maintained by the HDMI interface driver in it's hdmi_config field. This
> prevents the need for the panel driver to configure default timings in it's
> probe.
> 
> This function is just intended to be used once during the panel driver's probe.
> It makes sense for those interfaces which can be configured to a default timing.

I'm not sure about this patch. So I think the basic idea here is that
HDMI will use VGA video mode if, for whatever reason, no better mode is
found out.

After this change, the panel driver doesn't seem to do that. Instead it
uses whatever mode was used previously by the hdmi output driver.

Is the only reason for this patch to clean up the hdmi_panel driver? We
could have a dss helper function which returns the timings for VGA
(well, just a public const variable would be enough), and the panel
driver could use that to initialize the timings struct.

 Tomi


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

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

* Re: [PATCH v2 07/13] OMAPDSS: HDMI: Add a get_timing function for HDMI interface
@ 2012-08-14 13:02       ` Tomi Valkeinen
  0 siblings, 0 replies; 122+ messages in thread
From: Tomi Valkeinen @ 2012-08-14 13:02 UTC (permalink / raw)
  To: Archit Taneja; +Cc: linux-fbdev, linux-omap

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

Hi,

On Thu, 2012-08-09 at 17:19 +0530, Archit Taneja wrote:
> Add function omapdss_hdmi_display_get_timing() which returns the timings
> maintained by the HDMI interface driver in it's hdmi_config field. This
> prevents the need for the panel driver to configure default timings in it's
> probe.
> 
> This function is just intended to be used once during the panel driver's probe.
> It makes sense for those interfaces which can be configured to a default timing.

I'm not sure about this patch. So I think the basic idea here is that
HDMI will use VGA video mode if, for whatever reason, no better mode is
found out.

After this change, the panel driver doesn't seem to do that. Instead it
uses whatever mode was used previously by the hdmi output driver.

Is the only reason for this patch to clean up the hdmi_panel driver? We
could have a dss helper function which returns the timings for VGA
(well, just a public const variable would be enough), and the panel
driver could use that to initialize the timings struct.

 Tomi


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

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

* Re: [PATCH v2 07/13] OMAPDSS: HDMI: Add a get_timing function for HDMI interface
  2012-08-14 13:02       ` Tomi Valkeinen
@ 2012-08-14 13:27         ` Archit Taneja
  -1 siblings, 0 replies; 122+ messages in thread
From: Archit Taneja @ 2012-08-14 13:15 UTC (permalink / raw)
  To: Tomi Valkeinen; +Cc: linux-fbdev, linux-omap

On Tuesday 14 August 2012 06:32 PM, Tomi Valkeinen wrote:
> Hi,
>
> On Thu, 2012-08-09 at 17:19 +0530, Archit Taneja wrote:
>> Add function omapdss_hdmi_display_get_timing() which returns the timings
>> maintained by the HDMI interface driver in it's hdmi_config field. This
>> prevents the need for the panel driver to configure default timings in it's
>> probe.
>>
>> This function is just intended to be used once during the panel driver's probe.
>> It makes sense for those interfaces which can be configured to a default timing.
>
> I'm not sure about this patch. So I think the basic idea here is that
> HDMI will use VGA video mode if, for whatever reason, no better mode is
> found out.
>
> After this change, the panel driver doesn't seem to do that. Instead it
> uses whatever mode was used previously by the hdmi output driver.
>
> Is the only reason for this patch to clean up the hdmi_panel driver? We
> could have a dss helper function which returns the timings for VGA
> (well, just a public const variable would be enough), and the panel
> driver could use that to initialize the timings struct.

Yes, that's the only reason, basically, to sync the panel with the 
timings to which the hdmi output driver configured itself during it's 
probe. We don't use hdmi_get_timing anywhere apart from here.

I thought it would be clean to retrieve the timings by taking whatever 
is stored in the hdmi output driver, but we could leave it to a 
hardcoded VGA as before.

I have done the same for venc, let me know if you think these should be 
removed.

Archit

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

* Re: [PATCH v2 07/13] OMAPDSS: HDMI: Add a get_timing function for HDMI interface
@ 2012-08-14 13:27         ` Archit Taneja
  0 siblings, 0 replies; 122+ messages in thread
From: Archit Taneja @ 2012-08-14 13:27 UTC (permalink / raw)
  To: Tomi Valkeinen; +Cc: linux-fbdev, linux-omap

On Tuesday 14 August 2012 06:32 PM, Tomi Valkeinen wrote:
> Hi,
>
> On Thu, 2012-08-09 at 17:19 +0530, Archit Taneja wrote:
>> Add function omapdss_hdmi_display_get_timing() which returns the timings
>> maintained by the HDMI interface driver in it's hdmi_config field. This
>> prevents the need for the panel driver to configure default timings in it's
>> probe.
>>
>> This function is just intended to be used once during the panel driver's probe.
>> It makes sense for those interfaces which can be configured to a default timing.
>
> I'm not sure about this patch. So I think the basic idea here is that
> HDMI will use VGA video mode if, for whatever reason, no better mode is
> found out.
>
> After this change, the panel driver doesn't seem to do that. Instead it
> uses whatever mode was used previously by the hdmi output driver.
>
> Is the only reason for this patch to clean up the hdmi_panel driver? We
> could have a dss helper function which returns the timings for VGA
> (well, just a public const variable would be enough), and the panel
> driver could use that to initialize the timings struct.

Yes, that's the only reason, basically, to sync the panel with the 
timings to which the hdmi output driver configured itself during it's 
probe. We don't use hdmi_get_timing anywhere apart from here.

I thought it would be clean to retrieve the timings by taking whatever 
is stored in the hdmi output driver, but we could leave it to a 
hardcoded VGA as before.

I have done the same for venc, let me know if you think these should be 
removed.

Archit

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

* Re: [PATCH v2 09/13] OMAPDSS: SDI: Create a function to set timings
  2012-08-09 11:56     ` Archit Taneja
@ 2012-08-14 13:44       ` Tomi Valkeinen
  -1 siblings, 0 replies; 122+ messages in thread
From: Tomi Valkeinen @ 2012-08-14 13:44 UTC (permalink / raw)
  To: Archit Taneja; +Cc: linux-fbdev, linux-omap

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

On Thu, 2012-08-09 at 17:19 +0530, Archit Taneja wrote:
> Create function omapdss_sdi_set_timings(). Configuring new timings is done the
> same way as before, SDI is disabled, and re-enabled with the new timings in
> dssdev. This just moves the code from the panel drivers to the SDI driver.
> 
> The panel drivers shouldn't be aware of how SDI manages to configure a new set
> of timings. This should be taken care of by the SDI driver itself.

I'm not sure about this one. Although I see that dpi.c does currently
the same thing as you're doing in your patch.

One thing is that we should try to remove dssdev uses from the output
drivers, including use of dssdev->state. 

The other thing is that I don't think the output driver should disable &
enable the output during set timings. I think sdi's set_timings should
return EBUSY if the output is enabled. The same way as other
configuration functions should (like dpi_set_data_lines or such).

I'm actually not sure if even the panel driver should disable & enable
the output during set_timings. Perhaps it should be the caller's
(omapdrm or such) responsibility....

My reasoning here is that disabling & enabling the video output is not
invisible to the upper layers, so doing it "in secret" may be bad.

Then again, perhaps timings can be changed freely on some other
platforms, and then it'd be nice if the panel driver wouldn't disable &
enable the output.

So I'm again not quite sure what's the best way to handle this... (of
the dssdev->state I'm sure, its use should be removed from omapdss). Any
thoughts?

 Tomi


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

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

* Re: [PATCH v2 09/13] OMAPDSS: SDI: Create a function to set timings
@ 2012-08-14 13:44       ` Tomi Valkeinen
  0 siblings, 0 replies; 122+ messages in thread
From: Tomi Valkeinen @ 2012-08-14 13:44 UTC (permalink / raw)
  To: Archit Taneja; +Cc: linux-fbdev, linux-omap

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

On Thu, 2012-08-09 at 17:19 +0530, Archit Taneja wrote:
> Create function omapdss_sdi_set_timings(). Configuring new timings is done the
> same way as before, SDI is disabled, and re-enabled with the new timings in
> dssdev. This just moves the code from the panel drivers to the SDI driver.
> 
> The panel drivers shouldn't be aware of how SDI manages to configure a new set
> of timings. This should be taken care of by the SDI driver itself.

I'm not sure about this one. Although I see that dpi.c does currently
the same thing as you're doing in your patch.

One thing is that we should try to remove dssdev uses from the output
drivers, including use of dssdev->state. 

The other thing is that I don't think the output driver should disable &
enable the output during set timings. I think sdi's set_timings should
return EBUSY if the output is enabled. The same way as other
configuration functions should (like dpi_set_data_lines or such).

I'm actually not sure if even the panel driver should disable & enable
the output during set_timings. Perhaps it should be the caller's
(omapdrm or such) responsibility....

My reasoning here is that disabling & enabling the video output is not
invisible to the upper layers, so doing it "in secret" may be bad.

Then again, perhaps timings can be changed freely on some other
platforms, and then it'd be nice if the panel driver wouldn't disable &
enable the output.

So I'm again not quite sure what's the best way to handle this... (of
the dssdev->state I'm sure, its use should be removed from omapdss). Any
thoughts?

 Tomi


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

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

* Re: [PATCH v2 07/13] OMAPDSS: HDMI: Add a get_timing function for HDMI interface
  2012-08-14 13:27         ` Archit Taneja
@ 2012-08-14 14:10           ` Tomi Valkeinen
  -1 siblings, 0 replies; 122+ messages in thread
From: Tomi Valkeinen @ 2012-08-14 14:10 UTC (permalink / raw)
  To: Archit Taneja; +Cc: linux-fbdev, linux-omap

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

On Tue, 2012-08-14 at 18:45 +0530, Archit Taneja wrote:
> On Tuesday 14 August 2012 06:32 PM, Tomi Valkeinen wrote:
> > Hi,
> >
> > On Thu, 2012-08-09 at 17:19 +0530, Archit Taneja wrote:
> >> Add function omapdss_hdmi_display_get_timing() which returns the timings
> >> maintained by the HDMI interface driver in it's hdmi_config field. This
> >> prevents the need for the panel driver to configure default timings in it's
> >> probe.
> >>
> >> This function is just intended to be used once during the panel driver's probe.
> >> It makes sense for those interfaces which can be configured to a default timing.
> >
> > I'm not sure about this patch. So I think the basic idea here is that
> > HDMI will use VGA video mode if, for whatever reason, no better mode is
> > found out.
> >
> > After this change, the panel driver doesn't seem to do that. Instead it
> > uses whatever mode was used previously by the hdmi output driver.
> >
> > Is the only reason for this patch to clean up the hdmi_panel driver? We
> > could have a dss helper function which returns the timings for VGA
> > (well, just a public const variable would be enough), and the panel
> > driver could use that to initialize the timings struct.
> 
> Yes, that's the only reason, basically, to sync the panel with the 
> timings to which the hdmi output driver configured itself during it's 
> probe. We don't use hdmi_get_timing anywhere apart from here.

Does the hdmi output driver even need to configure any defaults?
Wouldn't it be ok to presume that the panel driver configures the
timings?

I don't think it's sensible to think about default values in the output
driver generally (well, at least for things like timings). Although in
HDMI's case VGA is quite sensible default, but that's not the case for
any other output.

So I think generally we should just trust the panel driver to tell the
output driver what configuration should be used before the panel driver
enables the output.

That said, it doesn't hurt that the output drivers initialize their own
datastructures to something relatively sane to avoid any BUG() or WARN()
calls in the omapdss. Although we could also somehow track if the
timings has been set, and return an error when enabling the display if
timings hasn't been set. But that requires an extra flag, so perhaps
it's simpler to have some initial values in the output driver also.

> I thought it would be clean to retrieve the timings by taking whatever 
> is stored in the hdmi output driver, but we could leave it to a 
> hardcoded VGA as before.

My main worry is that it's not easily clear what is going on if you look
at the panel code. It looks that the panel just uses whatever is in the
output driver. It's not clear that it is always VGA. What if the
previous mode was something else?

I think it's much clearer if the panel driver sets the timings
explicitly before enabling the output. It doesn't have to be in panel's
probe, although that's perhaps the easiest place for it.

> I have done the same for venc, let me know if you think these should be 
> removed.

Well, I agree that the initial timings code in hdmi and venc is a bit
ugly. I don't think it's bad as such, just that the timings are standard
ones, and instead of having all the timings numbers there, we should
have a common place for them.

 Tomi


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

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

* Re: [PATCH v2 07/13] OMAPDSS: HDMI: Add a get_timing function for HDMI interface
@ 2012-08-14 14:10           ` Tomi Valkeinen
  0 siblings, 0 replies; 122+ messages in thread
From: Tomi Valkeinen @ 2012-08-14 14:10 UTC (permalink / raw)
  To: Archit Taneja; +Cc: linux-fbdev, linux-omap

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

On Tue, 2012-08-14 at 18:45 +0530, Archit Taneja wrote:
> On Tuesday 14 August 2012 06:32 PM, Tomi Valkeinen wrote:
> > Hi,
> >
> > On Thu, 2012-08-09 at 17:19 +0530, Archit Taneja wrote:
> >> Add function omapdss_hdmi_display_get_timing() which returns the timings
> >> maintained by the HDMI interface driver in it's hdmi_config field. This
> >> prevents the need for the panel driver to configure default timings in it's
> >> probe.
> >>
> >> This function is just intended to be used once during the panel driver's probe.
> >> It makes sense for those interfaces which can be configured to a default timing.
> >
> > I'm not sure about this patch. So I think the basic idea here is that
> > HDMI will use VGA video mode if, for whatever reason, no better mode is
> > found out.
> >
> > After this change, the panel driver doesn't seem to do that. Instead it
> > uses whatever mode was used previously by the hdmi output driver.
> >
> > Is the only reason for this patch to clean up the hdmi_panel driver? We
> > could have a dss helper function which returns the timings for VGA
> > (well, just a public const variable would be enough), and the panel
> > driver could use that to initialize the timings struct.
> 
> Yes, that's the only reason, basically, to sync the panel with the 
> timings to which the hdmi output driver configured itself during it's 
> probe. We don't use hdmi_get_timing anywhere apart from here.

Does the hdmi output driver even need to configure any defaults?
Wouldn't it be ok to presume that the panel driver configures the
timings?

I don't think it's sensible to think about default values in the output
driver generally (well, at least for things like timings). Although in
HDMI's case VGA is quite sensible default, but that's not the case for
any other output.

So I think generally we should just trust the panel driver to tell the
output driver what configuration should be used before the panel driver
enables the output.

That said, it doesn't hurt that the output drivers initialize their own
datastructures to something relatively sane to avoid any BUG() or WARN()
calls in the omapdss. Although we could also somehow track if the
timings has been set, and return an error when enabling the display if
timings hasn't been set. But that requires an extra flag, so perhaps
it's simpler to have some initial values in the output driver also.

> I thought it would be clean to retrieve the timings by taking whatever 
> is stored in the hdmi output driver, but we could leave it to a 
> hardcoded VGA as before.

My main worry is that it's not easily clear what is going on if you look
at the panel code. It looks that the panel just uses whatever is in the
output driver. It's not clear that it is always VGA. What if the
previous mode was something else?

I think it's much clearer if the panel driver sets the timings
explicitly before enabling the output. It doesn't have to be in panel's
probe, although that's perhaps the easiest place for it.

> I have done the same for venc, let me know if you think these should be 
> removed.

Well, I agree that the initial timings code in hdmi and venc is a bit
ugly. I don't think it's bad as such, just that the timings are standard
ones, and instead of having all the timings numbers there, we should
have a common place for them.

 Tomi


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

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

* Re: [PATCH v2 09/13] OMAPDSS: SDI: Create a function to set timings
  2012-08-14 13:44       ` Tomi Valkeinen
@ 2012-08-14 17:08         ` Archit Taneja
  -1 siblings, 0 replies; 122+ messages in thread
From: Archit Taneja @ 2012-08-14 16:56 UTC (permalink / raw)
  To: Tomi Valkeinen; +Cc: linux-fbdev, linux-omap

On Tuesday 14 August 2012 07:14 PM, Tomi Valkeinen wrote:
> On Thu, 2012-08-09 at 17:19 +0530, Archit Taneja wrote:
>> Create function omapdss_sdi_set_timings(). Configuring new timings is done the
>> same way as before, SDI is disabled, and re-enabled with the new timings in
>> dssdev. This just moves the code from the panel drivers to the SDI driver.
>>
>> The panel drivers shouldn't be aware of how SDI manages to configure a new set
>> of timings. This should be taken care of by the SDI driver itself.
>
> I'm not sure about this one. Although I see that dpi.c does currently
> the same thing as you're doing in your patch.

Even HDMI does the same thing.

>
> One thing is that we should try to remove dssdev uses from the output
> drivers, including use of dssdev->state.

Yes, we could do that by keeping a state of the output(and also checking 
state of the manager)

>
> The other thing is that I don't think the output driver should disable &
> enable the output during set timings. I think sdi's set_timings should
> return EBUSY if the output is enabled. The same way as other
> configuration functions should (like dpi_set_data_lines or such).
>
> I'm actually not sure if even the panel driver should disable & enable
> the output during set_timings. Perhaps it should be the caller's
> (omapdrm or such) responsibility....
>
> My reasoning here is that disabling & enabling the video output is not
> invisible to the upper layers, so doing it "in secret" may be bad.
>
> Then again, perhaps timings can be changed freely on some other
> platforms, and then it'd be nice if the panel driver wouldn't disable &
> enable the output.
>
> So I'm again not quite sure what's the best way to handle this... (of
> the dssdev->state I'm sure, its use should be removed from omapdss). Any
> thoughts?

I guess it depends on how drm/fb want to use it. I guess an output 
should have a set_timings() kind of op if it can do it seamlessly. I 
guess we can do that easily in DPI, for example, we could reduce the fps 
from 60 to 30 without causing an artefacts(I think). For outputs which 
can't do it, we could remove the set_timings totally.

However, it'll be kind of inconsistent for some outputs to set timings, 
and for others to not, and if in the future drm/fb gets exposed to ops 
too, we may have dirty checks to see if set_timings is populated or not.

The easiest way would be to make all set_timings just update the copy of 
the timings output has, and expect drm/fb to disable and re enable the 
panel. We may end up doing unnecessary gpio resets and configuration of 
the panels though.

Archit


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

* Re: [PATCH v2 09/13] OMAPDSS: SDI: Create a function to set timings
@ 2012-08-14 17:08         ` Archit Taneja
  0 siblings, 0 replies; 122+ messages in thread
From: Archit Taneja @ 2012-08-14 17:08 UTC (permalink / raw)
  To: Tomi Valkeinen; +Cc: linux-fbdev, linux-omap

On Tuesday 14 August 2012 07:14 PM, Tomi Valkeinen wrote:
> On Thu, 2012-08-09 at 17:19 +0530, Archit Taneja wrote:
>> Create function omapdss_sdi_set_timings(). Configuring new timings is done the
>> same way as before, SDI is disabled, and re-enabled with the new timings in
>> dssdev. This just moves the code from the panel drivers to the SDI driver.
>>
>> The panel drivers shouldn't be aware of how SDI manages to configure a new set
>> of timings. This should be taken care of by the SDI driver itself.
>
> I'm not sure about this one. Although I see that dpi.c does currently
> the same thing as you're doing in your patch.

Even HDMI does the same thing.

>
> One thing is that we should try to remove dssdev uses from the output
> drivers, including use of dssdev->state.

Yes, we could do that by keeping a state of the output(and also checking 
state of the manager)

>
> The other thing is that I don't think the output driver should disable &
> enable the output during set timings. I think sdi's set_timings should
> return EBUSY if the output is enabled. The same way as other
> configuration functions should (like dpi_set_data_lines or such).
>
> I'm actually not sure if even the panel driver should disable & enable
> the output during set_timings. Perhaps it should be the caller's
> (omapdrm or such) responsibility....
>
> My reasoning here is that disabling & enabling the video output is not
> invisible to the upper layers, so doing it "in secret" may be bad.
>
> Then again, perhaps timings can be changed freely on some other
> platforms, and then it'd be nice if the panel driver wouldn't disable &
> enable the output.
>
> So I'm again not quite sure what's the best way to handle this... (of
> the dssdev->state I'm sure, its use should be removed from omapdss). Any
> thoughts?

I guess it depends on how drm/fb want to use it. I guess an output 
should have a set_timings() kind of op if it can do it seamlessly. I 
guess we can do that easily in DPI, for example, we could reduce the fps 
from 60 to 30 without causing an artefacts(I think). For outputs which 
can't do it, we could remove the set_timings totally.

However, it'll be kind of inconsistent for some outputs to set timings, 
and for others to not, and if in the future drm/fb gets exposed to ops 
too, we may have dirty checks to see if set_timings is populated or not.

The easiest way would be to make all set_timings just update the copy of 
the timings output has, and expect drm/fb to disable and re enable the 
panel. We may end up doing unnecessary gpio resets and configuration of 
the panels though.

Archit


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

* Re: [PATCH v2 07/13] OMAPDSS: HDMI: Add a get_timing function for HDMI interface
  2012-08-14 14:10           ` Tomi Valkeinen
@ 2012-08-14 17:28             ` Archit Taneja
  -1 siblings, 0 replies; 122+ messages in thread
From: Archit Taneja @ 2012-08-14 17:16 UTC (permalink / raw)
  To: Tomi Valkeinen; +Cc: linux-fbdev, linux-omap

On Tuesday 14 August 2012 07:40 PM, Tomi Valkeinen wrote:
> On Tue, 2012-08-14 at 18:45 +0530, Archit Taneja wrote:
>> On Tuesday 14 August 2012 06:32 PM, Tomi Valkeinen wrote:
>>> Hi,
>>>
>>> On Thu, 2012-08-09 at 17:19 +0530, Archit Taneja wrote:
>>>> Add function omapdss_hdmi_display_get_timing() which returns the timings
>>>> maintained by the HDMI interface driver in it's hdmi_config field. This
>>>> prevents the need for the panel driver to configure default timings in it's
>>>> probe.
>>>>
>>>> This function is just intended to be used once during the panel driver's probe.
>>>> It makes sense for those interfaces which can be configured to a default timing.
>>>
>>> I'm not sure about this patch. So I think the basic idea here is that
>>> HDMI will use VGA video mode if, for whatever reason, no better mode is
>>> found out.
>>>
>>> After this change, the panel driver doesn't seem to do that. Instead it
>>> uses whatever mode was used previously by the hdmi output driver.
>>>
>>> Is the only reason for this patch to clean up the hdmi_panel driver? We
>>> could have a dss helper function which returns the timings for VGA
>>> (well, just a public const variable would be enough), and the panel
>>> driver could use that to initialize the timings struct.
>>
>> Yes, that's the only reason, basically, to sync the panel with the
>> timings to which the hdmi output driver configured itself during it's
>> probe. We don't use hdmi_get_timing anywhere apart from here.
>
> Does the hdmi output driver even need to configure any defaults?
> Wouldn't it be ok to presume that the panel driver configures the
> timings?
>
> I don't think it's sensible to think about default values in the output
> driver generally (well, at least for things like timings). Although in
> HDMI's case VGA is quite sensible default, but that's not the case for
> any other output.
>
> So I think generally we should just trust the panel driver to tell the
> output driver what configuration should be used before the panel driver
> enables the output.
>
> That said, it doesn't hurt that the output drivers initialize their own
> datastructures to something relatively sane to avoid any BUG() or WARN()
> calls in the omapdss. Although we could also somehow track if the
> timings has been set, and return an error when enabling the display if
> timings hasn't been set. But that requires an extra flag, so perhaps
> it's simpler to have some initial values in the output driver also.
>
>> I thought it would be clean to retrieve the timings by taking whatever
>> is stored in the hdmi output driver, but we could leave it to a
>> hardcoded VGA as before.
>
> My main worry is that it's not easily clear what is going on if you look
> at the panel code. It looks that the panel just uses whatever is in the
> output driver. It's not clear that it is always VGA. What if the
> previous mode was something else?
>
> I think it's much clearer if the panel driver sets the timings
> explicitly before enabling the output. It doesn't have to be in panel's
> probe, although that's perhaps the easiest place for it.
>
>> I have done the same for venc, let me know if you think these should be
>> removed.
>
> Well, I agree that the initial timings code in hdmi and venc is a bit
> ugly. I don't think it's bad as such, just that the timings are standard
> ones, and instead of having all the timings numbers there, we should
> have a common place for them.

Okay, I'll remove the get_timing ops, keep defaults in the panel 
driver's probe, have a const variable for the defaults to make it look 
less ugly, and make sure that there is a set_timings for the output in 
the hdmi and venc panel drivers before they are enabled, it sort of okay 
for hdmi and venc panel drivers as there is going to be only one of them 
and be in our control.

Archit

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

* Re: [PATCH v2 07/13] OMAPDSS: HDMI: Add a get_timing function for HDMI interface
@ 2012-08-14 17:28             ` Archit Taneja
  0 siblings, 0 replies; 122+ messages in thread
From: Archit Taneja @ 2012-08-14 17:28 UTC (permalink / raw)
  To: Tomi Valkeinen; +Cc: linux-fbdev, linux-omap

On Tuesday 14 August 2012 07:40 PM, Tomi Valkeinen wrote:
> On Tue, 2012-08-14 at 18:45 +0530, Archit Taneja wrote:
>> On Tuesday 14 August 2012 06:32 PM, Tomi Valkeinen wrote:
>>> Hi,
>>>
>>> On Thu, 2012-08-09 at 17:19 +0530, Archit Taneja wrote:
>>>> Add function omapdss_hdmi_display_get_timing() which returns the timings
>>>> maintained by the HDMI interface driver in it's hdmi_config field. This
>>>> prevents the need for the panel driver to configure default timings in it's
>>>> probe.
>>>>
>>>> This function is just intended to be used once during the panel driver's probe.
>>>> It makes sense for those interfaces which can be configured to a default timing.
>>>
>>> I'm not sure about this patch. So I think the basic idea here is that
>>> HDMI will use VGA video mode if, for whatever reason, no better mode is
>>> found out.
>>>
>>> After this change, the panel driver doesn't seem to do that. Instead it
>>> uses whatever mode was used previously by the hdmi output driver.
>>>
>>> Is the only reason for this patch to clean up the hdmi_panel driver? We
>>> could have a dss helper function which returns the timings for VGA
>>> (well, just a public const variable would be enough), and the panel
>>> driver could use that to initialize the timings struct.
>>
>> Yes, that's the only reason, basically, to sync the panel with the
>> timings to which the hdmi output driver configured itself during it's
>> probe. We don't use hdmi_get_timing anywhere apart from here.
>
> Does the hdmi output driver even need to configure any defaults?
> Wouldn't it be ok to presume that the panel driver configures the
> timings?
>
> I don't think it's sensible to think about default values in the output
> driver generally (well, at least for things like timings). Although in
> HDMI's case VGA is quite sensible default, but that's not the case for
> any other output.
>
> So I think generally we should just trust the panel driver to tell the
> output driver what configuration should be used before the panel driver
> enables the output.
>
> That said, it doesn't hurt that the output drivers initialize their own
> datastructures to something relatively sane to avoid any BUG() or WARN()
> calls in the omapdss. Although we could also somehow track if the
> timings has been set, and return an error when enabling the display if
> timings hasn't been set. But that requires an extra flag, so perhaps
> it's simpler to have some initial values in the output driver also.
>
>> I thought it would be clean to retrieve the timings by taking whatever
>> is stored in the hdmi output driver, but we could leave it to a
>> hardcoded VGA as before.
>
> My main worry is that it's not easily clear what is going on if you look
> at the panel code. It looks that the panel just uses whatever is in the
> output driver. It's not clear that it is always VGA. What if the
> previous mode was something else?
>
> I think it's much clearer if the panel driver sets the timings
> explicitly before enabling the output. It doesn't have to be in panel's
> probe, although that's perhaps the easiest place for it.
>
>> I have done the same for venc, let me know if you think these should be
>> removed.
>
> Well, I agree that the initial timings code in hdmi and venc is a bit
> ugly. I don't think it's bad as such, just that the timings are standard
> ones, and instead of having all the timings numbers there, we should
> have a common place for them.

Okay, I'll remove the get_timing ops, keep defaults in the panel 
driver's probe, have a const variable for the defaults to make it look 
less ugly, and make sure that there is a set_timings for the output in 
the hdmi and venc panel drivers before they are enabled, it sort of okay 
for hdmi and venc panel drivers as there is going to be only one of them 
and be in our control.

Archit

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

* Re: [PATCH v2 09/13] OMAPDSS: SDI: Create a function to set timings
  2012-08-14 17:08         ` Archit Taneja
@ 2012-08-14 17:33           ` Tomi Valkeinen
  -1 siblings, 0 replies; 122+ messages in thread
From: Tomi Valkeinen @ 2012-08-14 17:33 UTC (permalink / raw)
  To: Archit Taneja, Rob Clark; +Cc: linux-fbdev, linux-omap

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

On Tue, 2012-08-14 at 22:26 +0530, Archit Taneja wrote:
> On Tuesday 14 August 2012 07:14 PM, Tomi Valkeinen wrote:

> I guess it depends on how drm/fb want to use it. I guess an output 
> should have a set_timings() kind of op if it can do it seamlessly. I 
> guess we can do that easily in DPI, for example, we could reduce the fps 
> from 60 to 30 without causing an artefacts(I think). For outputs which 

Yes, that kind of thing is easy to do by just changing the pck divider,
which is in a shadow register. I mean, "easy" in theory, at least. Our
clock calculation doesn't work like that currently, though, so it could
end up changing DSS fck.

> can't do it, we could remove the set_timings totally.

But we do need set_timings for other outputs also (like sdi). We just
can't change them just like that. Only outputs that do not need timings
are DSI command mode and rfbi.

> However, it'll be kind of inconsistent for some outputs to set timings, 
> and for others to not, and if in the future drm/fb gets exposed to ops 
> too, we may have dirty checks to see if set_timings is populated or not.
> 
> The easiest way would be to make all set_timings just update the copy of 
> the timings output has, and expect drm/fb to disable and re enable the 
> panel. We may end up doing unnecessary gpio resets and configuration of 
> the panels though.

I think changing things like timings is quite a rare operation. The only
case it'd be necessary to change timings often, with speed, and without
artifacts would be the fps drop you mentioned, for lower power use with
panels that don't mind the fps drop.

If I understood correctly, Rob said that drm already disables the output
when changing the mode, when I asked if it's ok for the apply's
set_timings to require the output to be off.

In any case this is not a big issue, I mean, it's not causing any
problems. Somebody is going to disable the output anyway when changing
the timings. Perhaps even these patches are good, because they make the
set_timings consistent across the output drivers (don't they?).

 Tomi


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

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

* Re: [PATCH v2 09/13] OMAPDSS: SDI: Create a function to set timings
@ 2012-08-14 17:33           ` Tomi Valkeinen
  0 siblings, 0 replies; 122+ messages in thread
From: Tomi Valkeinen @ 2012-08-14 17:33 UTC (permalink / raw)
  To: Archit Taneja, Rob Clark; +Cc: linux-fbdev, linux-omap

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

On Tue, 2012-08-14 at 22:26 +0530, Archit Taneja wrote:
> On Tuesday 14 August 2012 07:14 PM, Tomi Valkeinen wrote:

> I guess it depends on how drm/fb want to use it. I guess an output 
> should have a set_timings() kind of op if it can do it seamlessly. I 
> guess we can do that easily in DPI, for example, we could reduce the fps 
> from 60 to 30 without causing an artefacts(I think). For outputs which 

Yes, that kind of thing is easy to do by just changing the pck divider,
which is in a shadow register. I mean, "easy" in theory, at least. Our
clock calculation doesn't work like that currently, though, so it could
end up changing DSS fck.

> can't do it, we could remove the set_timings totally.

But we do need set_timings for other outputs also (like sdi). We just
can't change them just like that. Only outputs that do not need timings
are DSI command mode and rfbi.

> However, it'll be kind of inconsistent for some outputs to set timings, 
> and for others to not, and if in the future drm/fb gets exposed to ops 
> too, we may have dirty checks to see if set_timings is populated or not.
> 
> The easiest way would be to make all set_timings just update the copy of 
> the timings output has, and expect drm/fb to disable and re enable the 
> panel. We may end up doing unnecessary gpio resets and configuration of 
> the panels though.

I think changing things like timings is quite a rare operation. The only
case it'd be necessary to change timings often, with speed, and without
artifacts would be the fps drop you mentioned, for lower power use with
panels that don't mind the fps drop.

If I understood correctly, Rob said that drm already disables the output
when changing the mode, when I asked if it's ok for the apply's
set_timings to require the output to be off.

In any case this is not a big issue, I mean, it's not causing any
problems. Somebody is going to disable the output anyway when changing
the timings. Perhaps even these patches are good, because they make the
set_timings consistent across the output drivers (don't they?).

 Tomi


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

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

* Re: [PATCH v2 09/13] OMAPDSS: SDI: Create a function to set timings
  2012-08-14 17:33           ` Tomi Valkeinen
@ 2012-08-14 19:20             ` Archit Taneja
  -1 siblings, 0 replies; 122+ messages in thread
From: Archit Taneja @ 2012-08-14 19:08 UTC (permalink / raw)
  To: Tomi Valkeinen; +Cc: Rob Clark, linux-fbdev, linux-omap

On Tuesday 14 August 2012 11:03 PM, Tomi Valkeinen wrote:
> On Tue, 2012-08-14 at 22:26 +0530, Archit Taneja wrote:
>> On Tuesday 14 August 2012 07:14 PM, Tomi Valkeinen wrote:
>
>> I guess it depends on how drm/fb want to use it. I guess an output
>> should have a set_timings() kind of op if it can do it seamlessly. I
>> guess we can do that easily in DPI, for example, we could reduce the fps
>> from 60 to 30 without causing an artefacts(I think). For outputs which
>
> Yes, that kind of thing is easy to do by just changing the pck divider,
> which is in a shadow register. I mean, "easy" in theory, at least. Our
> clock calculation doesn't work like that currently, though, so it could
> end up changing DSS fck.
>
>> can't do it, we could remove the set_timings totally.
>
> But we do need set_timings for other outputs also (like sdi). We just
> can't change them just like that. Only outputs that do not need timings
> are DSI command mode and rfbi.
>
>> However, it'll be kind of inconsistent for some outputs to set timings,
>> and for others to not, and if in the future drm/fb gets exposed to ops
>> too, we may have dirty checks to see if set_timings is populated or not.
>>
>> The easiest way would be to make all set_timings just update the copy of
>> the timings output has, and expect drm/fb to disable and re enable the
>> panel. We may end up doing unnecessary gpio resets and configuration of
>> the panels though.
>
> I think changing things like timings is quite a rare operation. The only
> case it'd be necessary to change timings often, with speed, and without
> artifacts would be the fps drop you mentioned, for lower power use with
> panels that don't mind the fps drop.
>
> If I understood correctly, Rob said that drm already disables the output
> when changing the mode, when I asked if it's ok for the apply's
> set_timings to require the output to be off.
>
> In any case this is not a big issue, I mean, it's not causing any
> problems. Somebody is going to disable the output anyway when changing
> the timings. Perhaps even these patches are good, because they make the
> set_timings consistent across the output drivers (don't they?).

Yes, they do, there isn't a set_timings for RFBI though, only a 
set_size, and DSI has set_timings for video mode and a set_size for 
command mode, I haven't put checks in the ops for a panel driver to 
wrongly call set_timings in commmand mode, and set_size in video mode.

I haven't done that yet because a future patch of mine will have a DSI 
specific op called set_operation_mode() to make us independent of 
dssdev->panel.dsi_mode, there is no guarantee that the panel driver to 
first call set_operation_mode(), and then set_timings(), so I'm not sure 
yet how to deal with that. Probably having a mode/state which says that 
a field is unintialized might help, but that would overcomplicate things.

Archit


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

* Re: [PATCH v2 09/13] OMAPDSS: SDI: Create a function to set timings
@ 2012-08-14 19:20             ` Archit Taneja
  0 siblings, 0 replies; 122+ messages in thread
From: Archit Taneja @ 2012-08-14 19:20 UTC (permalink / raw)
  To: Tomi Valkeinen; +Cc: Rob Clark, linux-fbdev, linux-omap

On Tuesday 14 August 2012 11:03 PM, Tomi Valkeinen wrote:
> On Tue, 2012-08-14 at 22:26 +0530, Archit Taneja wrote:
>> On Tuesday 14 August 2012 07:14 PM, Tomi Valkeinen wrote:
>
>> I guess it depends on how drm/fb want to use it. I guess an output
>> should have a set_timings() kind of op if it can do it seamlessly. I
>> guess we can do that easily in DPI, for example, we could reduce the fps
>> from 60 to 30 without causing an artefacts(I think). For outputs which
>
> Yes, that kind of thing is easy to do by just changing the pck divider,
> which is in a shadow register. I mean, "easy" in theory, at least. Our
> clock calculation doesn't work like that currently, though, so it could
> end up changing DSS fck.
>
>> can't do it, we could remove the set_timings totally.
>
> But we do need set_timings for other outputs also (like sdi). We just
> can't change them just like that. Only outputs that do not need timings
> are DSI command mode and rfbi.
>
>> However, it'll be kind of inconsistent for some outputs to set timings,
>> and for others to not, and if in the future drm/fb gets exposed to ops
>> too, we may have dirty checks to see if set_timings is populated or not.
>>
>> The easiest way would be to make all set_timings just update the copy of
>> the timings output has, and expect drm/fb to disable and re enable the
>> panel. We may end up doing unnecessary gpio resets and configuration of
>> the panels though.
>
> I think changing things like timings is quite a rare operation. The only
> case it'd be necessary to change timings often, with speed, and without
> artifacts would be the fps drop you mentioned, for lower power use with
> panels that don't mind the fps drop.
>
> If I understood correctly, Rob said that drm already disables the output
> when changing the mode, when I asked if it's ok for the apply's
> set_timings to require the output to be off.
>
> In any case this is not a big issue, I mean, it's not causing any
> problems. Somebody is going to disable the output anyway when changing
> the timings. Perhaps even these patches are good, because they make the
> set_timings consistent across the output drivers (don't they?).

Yes, they do, there isn't a set_timings for RFBI though, only a 
set_size, and DSI has set_timings for video mode and a set_size for 
command mode, I haven't put checks in the ops for a panel driver to 
wrongly call set_timings in commmand mode, and set_size in video mode.

I haven't done that yet because a future patch of mine will have a DSI 
specific op called set_operation_mode() to make us independent of 
dssdev->panel.dsi_mode, there is no guarantee that the panel driver to 
first call set_operation_mode(), and then set_timings(), so I'm not sure 
yet how to deal with that. Probably having a mode/state which says that 
a field is unintialized might help, but that would overcomplicate things.

Archit


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

* Re: [PATCH v2 09/13] OMAPDSS: SDI: Create a function to set timings
  2012-08-14 17:08         ` Archit Taneja
@ 2012-08-14 19:26           ` Rob Clark
  -1 siblings, 0 replies; 122+ messages in thread
From: Rob Clark @ 2012-08-14 19:26 UTC (permalink / raw)
  To: Archit Taneja; +Cc: Tomi Valkeinen, linux-fbdev, linux-omap

On Tue, Aug 14, 2012 at 11:56 AM, Archit Taneja <archit@ti.com> wrote:
> On Tuesday 14 August 2012 07:14 PM, Tomi Valkeinen wrote:
>>
>> On Thu, 2012-08-09 at 17:19 +0530, Archit Taneja wrote:
>>>
>>> Create function omapdss_sdi_set_timings(). Configuring new timings is
>>> done the
>>> same way as before, SDI is disabled, and re-enabled with the new timings
>>> in
>>> dssdev. This just moves the code from the panel drivers to the SDI
>>> driver.
>>>
>>> The panel drivers shouldn't be aware of how SDI manages to configure a
>>> new set
>>> of timings. This should be taken care of by the SDI driver itself.
>>
>>
>> I'm not sure about this one. Although I see that dpi.c does currently
>> the same thing as you're doing in your patch.
>
>
> Even HDMI does the same thing.
>
>
>>
>> One thing is that we should try to remove dssdev uses from the output
>> drivers, including use of dssdev->state.
>
>
> Yes, we could do that by keeping a state of the output(and also checking
> state of the manager)
>
>
>>
>> The other thing is that I don't think the output driver should disable &
>> enable the output during set timings. I think sdi's set_timings should
>> return EBUSY if the output is enabled. The same way as other
>> configuration functions should (like dpi_set_data_lines or such).
>>
>> I'm actually not sure if even the panel driver should disable & enable
>> the output during set_timings. Perhaps it should be the caller's
>> (omapdrm or such) responsibility....
>>
>> My reasoning here is that disabling & enabling the video output is not
>> invisible to the upper layers, so doing it "in secret" may be bad.
>>
>> Then again, perhaps timings can be changed freely on some other
>> platforms, and then it'd be nice if the panel driver wouldn't disable &
>> enable the output.
>>
>> So I'm again not quite sure what's the best way to handle this... (of
>> the dssdev->state I'm sure, its use should be removed from omapdss). Any
>> thoughts?
>
>
> I guess it depends on how drm/fb want to use it. I guess an output should
> have a set_timings() kind of op if it can do it seamlessly. I guess we can
> do that easily in DPI, for example, we could reduce the fps from 60 to 30
> without causing an artefacts(I think). For outputs which can't do it, we
> could remove the set_timings totally.

fwiw, drm wouldn't try to change timings on the fly..  or at least it
is bracketed by a call to the driver's crtc->prepare() and
crtc->commit() fxns (which in our case disable/enable output).

I haven't seen much userspace that tries to do things like this,
except maybe some apps like xbmc which seem to have some options to
attempt to change timings to align w/ video playback framerate.  I am
a bit curious how many tv's and drivers could support this in a
glitch-free way.

BR,
-R

> However, it'll be kind of inconsistent for some outputs to set timings, and
> for others to not, and if in the future drm/fb gets exposed to ops too, we
> may have dirty checks to see if set_timings is populated or not.
>
> The easiest way would be to make all set_timings just update the copy of the
> timings output has, and expect drm/fb to disable and re enable the panel. We
> may end up doing unnecessary gpio resets and configuration of the panels
> though.
>
> Archit
>
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* Re: [PATCH v2 09/13] OMAPDSS: SDI: Create a function to set timings
@ 2012-08-14 19:26           ` Rob Clark
  0 siblings, 0 replies; 122+ messages in thread
From: Rob Clark @ 2012-08-14 19:26 UTC (permalink / raw)
  To: Archit Taneja; +Cc: Tomi Valkeinen, linux-fbdev, linux-omap

On Tue, Aug 14, 2012 at 11:56 AM, Archit Taneja <archit@ti.com> wrote:
> On Tuesday 14 August 2012 07:14 PM, Tomi Valkeinen wrote:
>>
>> On Thu, 2012-08-09 at 17:19 +0530, Archit Taneja wrote:
>>>
>>> Create function omapdss_sdi_set_timings(). Configuring new timings is
>>> done the
>>> same way as before, SDI is disabled, and re-enabled with the new timings
>>> in
>>> dssdev. This just moves the code from the panel drivers to the SDI
>>> driver.
>>>
>>> The panel drivers shouldn't be aware of how SDI manages to configure a
>>> new set
>>> of timings. This should be taken care of by the SDI driver itself.
>>
>>
>> I'm not sure about this one. Although I see that dpi.c does currently
>> the same thing as you're doing in your patch.
>
>
> Even HDMI does the same thing.
>
>
>>
>> One thing is that we should try to remove dssdev uses from the output
>> drivers, including use of dssdev->state.
>
>
> Yes, we could do that by keeping a state of the output(and also checking
> state of the manager)
>
>
>>
>> The other thing is that I don't think the output driver should disable &
>> enable the output during set timings. I think sdi's set_timings should
>> return EBUSY if the output is enabled. The same way as other
>> configuration functions should (like dpi_set_data_lines or such).
>>
>> I'm actually not sure if even the panel driver should disable & enable
>> the output during set_timings. Perhaps it should be the caller's
>> (omapdrm or such) responsibility....
>>
>> My reasoning here is that disabling & enabling the video output is not
>> invisible to the upper layers, so doing it "in secret" may be bad.
>>
>> Then again, perhaps timings can be changed freely on some other
>> platforms, and then it'd be nice if the panel driver wouldn't disable &
>> enable the output.
>>
>> So I'm again not quite sure what's the best way to handle this... (of
>> the dssdev->state I'm sure, its use should be removed from omapdss). Any
>> thoughts?
>
>
> I guess it depends on how drm/fb want to use it. I guess an output should
> have a set_timings() kind of op if it can do it seamlessly. I guess we can
> do that easily in DPI, for example, we could reduce the fps from 60 to 30
> without causing an artefacts(I think). For outputs which can't do it, we
> could remove the set_timings totally.

fwiw, drm wouldn't try to change timings on the fly..  or at least it
is bracketed by a call to the driver's crtc->prepare() and
crtc->commit() fxns (which in our case disable/enable output).

I haven't seen much userspace that tries to do things like this,
except maybe some apps like xbmc which seem to have some options to
attempt to change timings to align w/ video playback framerate.  I am
a bit curious how many tv's and drivers could support this in a
glitch-free way.

BR,
-R

> However, it'll be kind of inconsistent for some outputs to set timings, and
> for others to not, and if in the future drm/fb gets exposed to ops too, we
> may have dirty checks to see if set_timings is populated or not.
>
> The easiest way would be to make all set_timings just update the copy of the
> timings output has, and expect drm/fb to disable and re enable the panel. We
> may end up doing unnecessary gpio resets and configuration of the panels
> though.
>
> Archit
>
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* Re: [PATCH v2 09/13] OMAPDSS: SDI: Create a function to set timings
  2012-08-14 19:20             ` Archit Taneja
@ 2012-08-15  6:43               ` Tomi Valkeinen
  -1 siblings, 0 replies; 122+ messages in thread
From: Tomi Valkeinen @ 2012-08-15  6:43 UTC (permalink / raw)
  To: Archit Taneja; +Cc: Rob Clark, linux-fbdev, linux-omap

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

On Wed, 2012-08-15 at 00:38 +0530, Archit Taneja wrote:
> On Tuesday 14 August 2012 11:03 PM, Tomi Valkeinen wrote:
> > On Tue, 2012-08-14 at 22:26 +0530, Archit Taneja wrote:
> >> On Tuesday 14 August 2012 07:14 PM, Tomi Valkeinen wrote:
> >
> >> I guess it depends on how drm/fb want to use it. I guess an output
> >> should have a set_timings() kind of op if it can do it seamlessly. I
> >> guess we can do that easily in DPI, for example, we could reduce the fps
> >> from 60 to 30 without causing an artefacts(I think). For outputs which
> >
> > Yes, that kind of thing is easy to do by just changing the pck divider,
> > which is in a shadow register. I mean, "easy" in theory, at least. Our
> > clock calculation doesn't work like that currently, though, so it could
> > end up changing DSS fck.
> >
> >> can't do it, we could remove the set_timings totally.
> >
> > But we do need set_timings for other outputs also (like sdi). We just
> > can't change them just like that. Only outputs that do not need timings
> > are DSI command mode and rfbi.
> >
> >> However, it'll be kind of inconsistent for some outputs to set timings,
> >> and for others to not, and if in the future drm/fb gets exposed to ops
> >> too, we may have dirty checks to see if set_timings is populated or not.
> >>
> >> The easiest way would be to make all set_timings just update the copy of
> >> the timings output has, and expect drm/fb to disable and re enable the
> >> panel. We may end up doing unnecessary gpio resets and configuration of
> >> the panels though.
> >
> > I think changing things like timings is quite a rare operation. The only
> > case it'd be necessary to change timings often, with speed, and without
> > artifacts would be the fps drop you mentioned, for lower power use with
> > panels that don't mind the fps drop.
> >
> > If I understood correctly, Rob said that drm already disables the output
> > when changing the mode, when I asked if it's ok for the apply's
> > set_timings to require the output to be off.
> >
> > In any case this is not a big issue, I mean, it's not causing any
> > problems. Somebody is going to disable the output anyway when changing
> > the timings. Perhaps even these patches are good, because they make the
> > set_timings consistent across the output drivers (don't they?).
> 
> Yes, they do, there isn't a set_timings for RFBI though, only a 
> set_size, and DSI has set_timings for video mode and a set_size for 
> command mode, I haven't put checks in the ops for a panel driver to 
> wrongly call set_timings in commmand mode, and set_size in video mode.

Ok. Well, perhaps we should go forward with these patches then. They
make things consistent, and we don't really know which would be the best
way to handle this, so the method in your patches is as good as some
other.

The dssdev->state needs to be removed at some point, but that can be a
separate task.

> I haven't done that yet because a future patch of mine will have a DSI 
> specific op called set_operation_mode() to make us independent of 
> dssdev->panel.dsi_mode, there is no guarantee that the panel driver to 
> first call set_operation_mode(), and then set_timings(), so I'm not sure 
> yet how to deal with that. Probably having a mode/state which says that 
> a field is unintialized might help, but that would overcomplicate things.

Well, we can define that set_operation_mode needs to be called before
any other dsi functions. They are kernel drivers, we can presume they
act correctly (although we should of course try to handle error cases
anyway). If they don't, we need to fix them.

If you want to be extra safe there, you could add third value to the
dsi_mode enum: UNDEFINED or such (I guess this is what you meant also).
By default dsi's mode would be undefined, and functions could check it.
But I agree it'd add lots of checks all around.

 Tomi


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

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

* Re: [PATCH v2 09/13] OMAPDSS: SDI: Create a function to set timings
@ 2012-08-15  6:43               ` Tomi Valkeinen
  0 siblings, 0 replies; 122+ messages in thread
From: Tomi Valkeinen @ 2012-08-15  6:43 UTC (permalink / raw)
  To: Archit Taneja; +Cc: Rob Clark, linux-fbdev, linux-omap

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

On Wed, 2012-08-15 at 00:38 +0530, Archit Taneja wrote:
> On Tuesday 14 August 2012 11:03 PM, Tomi Valkeinen wrote:
> > On Tue, 2012-08-14 at 22:26 +0530, Archit Taneja wrote:
> >> On Tuesday 14 August 2012 07:14 PM, Tomi Valkeinen wrote:
> >
> >> I guess it depends on how drm/fb want to use it. I guess an output
> >> should have a set_timings() kind of op if it can do it seamlessly. I
> >> guess we can do that easily in DPI, for example, we could reduce the fps
> >> from 60 to 30 without causing an artefacts(I think). For outputs which
> >
> > Yes, that kind of thing is easy to do by just changing the pck divider,
> > which is in a shadow register. I mean, "easy" in theory, at least. Our
> > clock calculation doesn't work like that currently, though, so it could
> > end up changing DSS fck.
> >
> >> can't do it, we could remove the set_timings totally.
> >
> > But we do need set_timings for other outputs also (like sdi). We just
> > can't change them just like that. Only outputs that do not need timings
> > are DSI command mode and rfbi.
> >
> >> However, it'll be kind of inconsistent for some outputs to set timings,
> >> and for others to not, and if in the future drm/fb gets exposed to ops
> >> too, we may have dirty checks to see if set_timings is populated or not.
> >>
> >> The easiest way would be to make all set_timings just update the copy of
> >> the timings output has, and expect drm/fb to disable and re enable the
> >> panel. We may end up doing unnecessary gpio resets and configuration of
> >> the panels though.
> >
> > I think changing things like timings is quite a rare operation. The only
> > case it'd be necessary to change timings often, with speed, and without
> > artifacts would be the fps drop you mentioned, for lower power use with
> > panels that don't mind the fps drop.
> >
> > If I understood correctly, Rob said that drm already disables the output
> > when changing the mode, when I asked if it's ok for the apply's
> > set_timings to require the output to be off.
> >
> > In any case this is not a big issue, I mean, it's not causing any
> > problems. Somebody is going to disable the output anyway when changing
> > the timings. Perhaps even these patches are good, because they make the
> > set_timings consistent across the output drivers (don't they?).
> 
> Yes, they do, there isn't a set_timings for RFBI though, only a 
> set_size, and DSI has set_timings for video mode and a set_size for 
> command mode, I haven't put checks in the ops for a panel driver to 
> wrongly call set_timings in commmand mode, and set_size in video mode.

Ok. Well, perhaps we should go forward with these patches then. They
make things consistent, and we don't really know which would be the best
way to handle this, so the method in your patches is as good as some
other.

The dssdev->state needs to be removed at some point, but that can be a
separate task.

> I haven't done that yet because a future patch of mine will have a DSI 
> specific op called set_operation_mode() to make us independent of 
> dssdev->panel.dsi_mode, there is no guarantee that the panel driver to 
> first call set_operation_mode(), and then set_timings(), so I'm not sure 
> yet how to deal with that. Probably having a mode/state which says that 
> a field is unintialized might help, but that would overcomplicate things.

Well, we can define that set_operation_mode needs to be called before
any other dsi functions. They are kernel drivers, we can presume they
act correctly (although we should of course try to handle error cases
anyway). If they don't, we need to fix them.

If you want to be extra safe there, you could add third value to the
dsi_mode enum: UNDEFINED or such (I guess this is what you meant also).
By default dsi's mode would be undefined, and functions could check it.
But I agree it'd add lots of checks all around.

 Tomi


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

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

end of thread, other threads:[~2012-08-15  6:43 UTC | newest]

Thread overview: 122+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-08-01 10:31 [RFC 00/17] OMAPDSS: Change way of passing timings from panel driver to interface Archit Taneja
2012-08-01 10:43 ` Archit Taneja
2012-08-01 10:31 ` [RFC 01/17] OMAPDSS: APPLY: Constify timings argument in dss_mgr_set_timings Archit Taneja
2012-08-01 10:43   ` Archit Taneja
2012-08-01 10:31 ` [RFC 02/17] OMAPDSS: DPI: Remove omap_dss_device arguments in dpi_set_dsi_clk/dpi_set_dispc_clk Archit Taneja
2012-08-01 10:43   ` Archit Taneja
2012-08-01 10:31 ` [RFC 03/17] OMAPDSS: HDMI: Remove omap_dss_device argument from hdmi_compute_pll Archit Taneja
2012-08-01 10:43   ` Archit Taneja
2012-08-01 10:31 ` [RFC 04/17] OMAPDSS: DPI: Add locking for DPI interface Archit Taneja
2012-08-01 10:43   ` Archit Taneja
2012-08-01 10:31 ` [RFC 05/17] OMAPDSS: DPI: Maintain our own timings field in driver data Archit Taneja
2012-08-01 10:43   ` Archit Taneja
2012-08-01 10:31 ` [RFC 06/17] OMAPDSS: DPI displays: Take care of panel timings in the driver itself Archit Taneja
2012-08-01 10:43   ` Archit Taneja
2012-08-01 10:31 ` [RFC 07/17] OMAPDSS: Displays: Add locking in generic DPI panel driver Archit Taneja
2012-08-01 10:43   ` Archit Taneja
2012-08-01 10:31 ` [RFC 08/17] OMAPDSS: DSI: Maintain own copy of timings in driver data Archit Taneja
2012-08-01 10:43   ` Archit Taneja
2012-08-07 14:07   ` Tomi Valkeinen
2012-08-07 14:07     ` Tomi Valkeinen
2012-08-08  5:57     ` Archit Taneja
2012-08-08  6:09       ` Archit Taneja
2012-08-08  6:15       ` Tomi Valkeinen
2012-08-08  6:15         ` Tomi Valkeinen
2012-08-08  6:29         ` Archit Taneja
2012-08-08  6:41           ` Archit Taneja
2012-08-08  7:10           ` Tomi Valkeinen
2012-08-08  7:10             ` Tomi Valkeinen
2012-08-08  7:54             ` Archit Taneja
2012-08-08  8:06               ` Archit Taneja
2012-08-01 10:31 ` [RFC 09/17] OMAPDSS: HDMI: Use our own omap_video_timings field when setting interface timings Archit Taneja
2012-08-01 10:43   ` Archit Taneja
2012-08-01 10:31 ` [RFC 10/17] OMAPDSS: HDMI: Add a get_timing function for HDMI interface Archit Taneja
2012-08-01 10:43   ` Archit Taneja
2012-08-01 10:31 ` [RFC 11/17] OMAPDSS: HDMI: Add locking for hdmi interface get/set timing functions Archit Taneja
2012-08-01 10:43   ` Archit Taneja
2012-08-01 10:31 ` [RFC 12/17] OMAPDSS: SDI: Create a separate function for timing/clock configurations Archit Taneja
2012-08-01 10:43   ` Archit Taneja
2012-08-01 10:31 ` [RFC 13/17] OMAPDSS: SDI: Create a function to set timings Archit Taneja
2012-08-01 10:43   ` Archit Taneja
2012-08-07 14:20   ` Tomi Valkeinen
2012-08-07 14:20     ` Tomi Valkeinen
2012-08-08  5:58     ` Archit Taneja
2012-08-08  6:10       ` Archit Taneja
2012-08-01 10:31 ` [RFC 14/17] OMAPDSS: SDI: Maintain our own timings field in driver data Archit Taneja
2012-08-01 10:43   ` Archit Taneja
2012-08-01 10:31 ` [RFC 15/17] OMAPDSS: VENC: Split VENC into interface and panel driver Archit Taneja
2012-08-01 10:43   ` Archit Taneja
2012-08-01 10:31 ` [RFC 16/17] OMAPDSS: VENC: Maintain our own timings field in driver data Archit Taneja
2012-08-01 10:43   ` Archit Taneja
2012-08-01 10:31 ` [RFC 17/17] OMAPDSS: VENC: Add a get_timing function for VENC interface Archit Taneja
2012-08-01 10:43   ` Archit Taneja
2012-08-01 10:35 ` [RFC 00/17] OMAPDSS: Change way of passing timings from panel driver to interface Archit Taneja
2012-08-01 10:47   ` Archit Taneja
2012-08-07 14:32 ` Tomi Valkeinen
2012-08-07 14:32   ` Tomi Valkeinen
2012-08-08  6:05   ` Archit Taneja
2012-08-08  6:17     ` Archit Taneja
2012-08-08  6:25     ` Tomi Valkeinen
2012-08-08  6:25       ` Tomi Valkeinen
2012-08-08  6:47       ` Archit Taneja
2012-08-08  6:59         ` Archit Taneja
2012-08-08  7:27         ` Tomi Valkeinen
2012-08-08  7:27           ` Tomi Valkeinen
2012-08-08  7:59           ` Archit Taneja
2012-08-08  8:11             ` Archit Taneja
2012-08-08  8:13             ` Tomi Valkeinen
2012-08-08  8:13               ` Tomi Valkeinen
2012-08-08  8:38               ` Archit Taneja
2012-08-08  8:50                 ` Archit Taneja
2012-08-08  8:48                 ` Tomi Valkeinen
2012-08-08  8:48                   ` Tomi Valkeinen
2012-08-08  9:24                   ` Archit Taneja
2012-08-08  9:36                     ` Archit Taneja
2012-08-09 11:49 ` [PATCH v2 00/13] " Archit Taneja
2012-08-09 11:55   ` Archit Taneja
2012-08-09 11:49   ` [PATCH v2 01/13] OMAPDSS: DPI: Maintain our own timings field in driver data Archit Taneja
2012-08-09 11:56     ` Archit Taneja
2012-08-09 11:49   ` [PATCH v2 02/13] OMAPDSS: DPI displays: Take care of panel timings in the driver itself Archit Taneja
2012-08-09 11:56     ` Archit Taneja
2012-08-09 11:49   ` [PATCH v2 03/13] OMAPDSS: DSI: Maintain own copy of timings in driver data Archit Taneja
2012-08-09 11:56     ` Archit Taneja
2012-08-09 11:49   ` [PATCH v2 04/13] OMAPDSS: DSI: Add function to set panel size for command mode panels Archit Taneja
2012-08-09 11:56     ` Archit Taneja
2012-08-09 11:49   ` [PATCH v2 05/13] OMAPDSS: DSI: Update manager timings on a manual update Archit Taneja
2012-08-09 11:56     ` Archit Taneja
2012-08-09 11:49   ` [PATCH v2 06/13] OMAPDSS: HDMI: Use our own omap_video_timings field when setting interface timings Archit Taneja
2012-08-09 11:56     ` Archit Taneja
2012-08-09 11:49   ` [PATCH v2 07/13] OMAPDSS: HDMI: Add a get_timing function for HDMI interface Archit Taneja
2012-08-09 11:56     ` Archit Taneja
2012-08-14 13:02     ` Tomi Valkeinen
2012-08-14 13:02       ` Tomi Valkeinen
2012-08-14 13:15       ` Archit Taneja
2012-08-14 13:27         ` Archit Taneja
2012-08-14 14:10         ` Tomi Valkeinen
2012-08-14 14:10           ` Tomi Valkeinen
2012-08-14 17:16           ` Archit Taneja
2012-08-14 17:28             ` Archit Taneja
2012-08-09 11:49   ` [PATCH v2 08/13] OMAPDSS: HDMI: Add locking for hdmi interface get/set timing functions Archit Taneja
2012-08-09 11:56     ` Archit Taneja
2012-08-09 11:49   ` [PATCH v2 09/13] OMAPDSS: SDI: Create a function to set timings Archit Taneja
2012-08-09 11:56     ` Archit Taneja
2012-08-14 13:44     ` Tomi Valkeinen
2012-08-14 13:44       ` Tomi Valkeinen
2012-08-14 16:56       ` Archit Taneja
2012-08-14 17:08         ` Archit Taneja
2012-08-14 17:33         ` Tomi Valkeinen
2012-08-14 17:33           ` Tomi Valkeinen
2012-08-14 19:08           ` Archit Taneja
2012-08-14 19:20             ` Archit Taneja
2012-08-15  6:43             ` Tomi Valkeinen
2012-08-15  6:43               ` Tomi Valkeinen
2012-08-14 19:26         ` Rob Clark
2012-08-14 19:26           ` Rob Clark
2012-08-09 11:49   ` [PATCH v2 10/13] OMAPDSS: SDI: Maintain our own timings field in driver data Archit Taneja
2012-08-09 11:56     ` Archit Taneja
2012-08-09 11:49   ` [PATCH v2 11/13] OMAPDSS: VENC: Split VENC into interface and panel driver Archit Taneja
2012-08-09 11:56     ` Archit Taneja
2012-08-09 11:49   ` [PATCH v2 12/13] OMAPDSS: VENC: Maintain our own timings field in driver data Archit Taneja
2012-08-09 11:56     ` Archit Taneja
2012-08-09 11:49   ` [PATCH v2 13/13] OMAPDSS: VENC: Add a get_timing function for VENC interface Archit Taneja
2012-08-09 11:56     ` 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.