linux-fbdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 01/15] OMAPDSS: fix AM43xx minimum pixel clock divider
@ 2015-02-26 12:48 Tomi Valkeinen
  2015-02-26 12:48 ` [PATCH 02/15] OMAPDSS: HDMI5: Increase DDC SDA-HOLD time Tomi Valkeinen
                   ` (13 more replies)
  0 siblings, 14 replies; 15+ messages in thread
From: Tomi Valkeinen @ 2015-02-26 12:48 UTC (permalink / raw)
  To: linux-omap, linux-fbdev; +Cc: Tomi Valkeinen

AM43xx supports pixel clock divider of 1, just like all OMAP3+ SoCs. Fix
the minimum divider value.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
 drivers/video/fbdev/omap2/dss/dss_features.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/video/fbdev/omap2/dss/dss_features.c b/drivers/video/fbdev/omap2/dss/dss_features.c
index 376270b777f8..b0b6dfd657bf 100644
--- a/drivers/video/fbdev/omap2/dss/dss_features.c
+++ b/drivers/video/fbdev/omap2/dss/dss_features.c
@@ -440,7 +440,7 @@ static const struct dss_param_range omap3_dss_param_range[] = {
 
 static const struct dss_param_range am43xx_dss_param_range[] = {
 	[FEAT_PARAM_DSS_FCK]			= { 0, 200000000 },
-	[FEAT_PARAM_DSS_PCD]			= { 2, 255 },
+	[FEAT_PARAM_DSS_PCD]			= { 1, 255 },
 	[FEAT_PARAM_DOWNSCALE]			= { 1, 4 },
 	[FEAT_PARAM_LINEWIDTH]			= { 1, 1024 },
 };
-- 
2.3.0


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

* [PATCH 02/15] OMAPDSS: HDMI5: Increase DDC SDA-HOLD time
  2015-02-26 12:48 [PATCH 01/15] OMAPDSS: fix AM43xx minimum pixel clock divider Tomi Valkeinen
@ 2015-02-26 12:48 ` Tomi Valkeinen
  2015-02-26 12:48 ` [PATCH 03/15] OMAPDSS: fix paddr check for TILER addresses Tomi Valkeinen
                   ` (12 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Tomi Valkeinen @ 2015-02-26 12:48 UTC (permalink / raw)
  To: linux-omap, linux-fbdev; +Cc: Tomi Valkeinen

It has been observed that the current SDA-HOLD time is too short for
some board/cable/monitor combinations. Increase the SDA-HOLD time to
1000ns.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
 drivers/video/fbdev/omap2/dss/hdmi5_core.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/video/fbdev/omap2/dss/hdmi5_core.c b/drivers/video/fbdev/omap2/dss/hdmi5_core.c
index a3cfe3d708f7..bfc0c4c297d6 100644
--- a/drivers/video/fbdev/omap2/dss/hdmi5_core.c
+++ b/drivers/video/fbdev/omap2/dss/hdmi5_core.c
@@ -55,7 +55,7 @@ static void hdmi_core_ddc_init(struct hdmi_core_data *core)
 	const unsigned ss_scl_low = 4700;		/* ns */
 	const unsigned fs_scl_high = 600;		/* ns */
 	const unsigned fs_scl_low = 1300;		/* ns */
-	const unsigned sda_hold = 300;			/* ns */
+	const unsigned sda_hold = 1000;			/* ns */
 	const unsigned sfr_div = 10;
 	unsigned long long sfr;
 	unsigned v;
-- 
2.3.0


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

* [PATCH 03/15] OMAPDSS: fix paddr check for TILER addresses
  2015-02-26 12:48 [PATCH 01/15] OMAPDSS: fix AM43xx minimum pixel clock divider Tomi Valkeinen
  2015-02-26 12:48 ` [PATCH 02/15] OMAPDSS: HDMI5: Increase DDC SDA-HOLD time Tomi Valkeinen
@ 2015-02-26 12:48 ` Tomi Valkeinen
  2015-02-26 12:48 ` [PATCH 04/15] OMAPDSS: TFP410: fix input sync signals Tomi Valkeinen
                   ` (11 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Tomi Valkeinen @ 2015-02-26 12:48 UTC (permalink / raw)
  To: linux-omap, linux-fbdev; +Cc: Tomi Valkeinen

The DISPC driver checks that the buffer address is not 0. However, when
using TILER, the address space is TILER specific and 0 is a valid
address.

Fix the check to allow address of 0 for TILER.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Reported-by: srinivas pulukuru <srinivas.pulukuru@ti.com>
---
 drivers/video/fbdev/omap2/dss/dispc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/video/fbdev/omap2/dss/dispc.c b/drivers/video/fbdev/omap2/dss/dispc.c
index 31b743c70272..a19a1d4b2d19 100644
--- a/drivers/video/fbdev/omap2/dss/dispc.c
+++ b/drivers/video/fbdev/omap2/dss/dispc.c
@@ -2441,7 +2441,7 @@ static int dispc_ovl_setup_common(enum omap_plane plane,
 	unsigned long pclk = dispc_plane_pclk_rate(plane);
 	unsigned long lclk = dispc_plane_lclk_rate(plane);
 
-	if (paddr = 0)
+	if (paddr = 0 && rotation_type != OMAP_DSS_ROT_TILER)
 		return -EINVAL;
 
 	out_width = out_width = 0 ? width : out_width;
-- 
2.3.0


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

* [PATCH 04/15] OMAPDSS: TFP410: fix input sync signals
  2015-02-26 12:48 [PATCH 01/15] OMAPDSS: fix AM43xx minimum pixel clock divider Tomi Valkeinen
  2015-02-26 12:48 ` [PATCH 02/15] OMAPDSS: HDMI5: Increase DDC SDA-HOLD time Tomi Valkeinen
  2015-02-26 12:48 ` [PATCH 03/15] OMAPDSS: fix paddr check for TILER addresses Tomi Valkeinen
@ 2015-02-26 12:48 ` Tomi Valkeinen
  2015-02-26 12:48 ` [PATCH 05/15] OMAPDSS: DISPC: remove OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES Tomi Valkeinen
                   ` (10 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Tomi Valkeinen @ 2015-02-26 12:48 UTC (permalink / raw)
  To: linux-omap, linux-fbdev; +Cc: Tomi Valkeinen

TFP410 requires that DE is active high and the data and syncs are driven
on rising pixel clock edge. However, at the moment the driver doesn't
request such syncs, and the end result is that the sync settings depend
on default values, which are not right in all cases.

Set the sync values explicitly.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
 drivers/video/fbdev/omap2/displays-new/encoder-tfp410.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/drivers/video/fbdev/omap2/displays-new/encoder-tfp410.c b/drivers/video/fbdev/omap2/displays-new/encoder-tfp410.c
index 92919a74e715..d9048b3df495 100644
--- a/drivers/video/fbdev/omap2/displays-new/encoder-tfp410.c
+++ b/drivers/video/fbdev/omap2/displays-new/encoder-tfp410.c
@@ -114,12 +114,21 @@ static void tfp410_disable(struct omap_dss_device *dssdev)
 	dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
 }
 
+static void tfp410_fix_timings(struct omap_video_timings *timings)
+{
+	timings->data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE;
+	timings->sync_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE;
+	timings->de_level = OMAPDSS_SIG_ACTIVE_HIGH;
+}
+
 static void tfp410_set_timings(struct omap_dss_device *dssdev,
 		struct omap_video_timings *timings)
 {
 	struct panel_drv_data *ddata = to_panel_data(dssdev);
 	struct omap_dss_device *in = ddata->in;
 
+	tfp410_fix_timings(timings);
+
 	ddata->timings = *timings;
 	dssdev->panel.timings = *timings;
 
@@ -140,6 +149,8 @@ static int tfp410_check_timings(struct omap_dss_device *dssdev,
 	struct panel_drv_data *ddata = to_panel_data(dssdev);
 	struct omap_dss_device *in = ddata->in;
 
+	tfp410_fix_timings(timings);
+
 	return in->ops.dpi->check_timings(in, timings);
 }
 
-- 
2.3.0


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

* [PATCH 05/15] OMAPDSS: DISPC: remove OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES
  2015-02-26 12:48 [PATCH 01/15] OMAPDSS: fix AM43xx minimum pixel clock divider Tomi Valkeinen
                   ` (2 preceding siblings ...)
  2015-02-26 12:48 ` [PATCH 04/15] OMAPDSS: TFP410: fix input sync signals Tomi Valkeinen
@ 2015-02-26 12:48 ` Tomi Valkeinen
  2015-02-26 12:49 ` [PATCH 06/15] OMAPDSS: DISPC: explicit handling for sync and de levels Tomi Valkeinen
                   ` (9 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Tomi Valkeinen @ 2015-02-26 12:48 UTC (permalink / raw)
  To: linux-omap, linux-fbdev; +Cc: Tomi Valkeinen

DISPC can drive data lines either on rising or falling pixel clock edge,
which can be configured by the user.

Sync lines can also be driven on rising or falling pixel clock edge, but
additionally the HW can be configured to drive the sync lines on
opposite clock edge from the data lines.

This opposite edge setting does not make any sense, as the same effect
can be achieved by just setting the sync lines to be driven on the other
edge compared to the data lines. It feels like some kind of backward
compatibility option, even if all DSS versions seem to have the same
implementation.

To simplify the code and configuration of the signals, and to make the
dispc timings more compatible with what is used on other platforms,
let's just remove the whole opposite-edge support.

The drivers that used OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES setting are
changed so that they use the opposite setting from the data edge.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
 drivers/gpu/drm/omapdrm/omap_connector.c                       |  2 +-
 drivers/video/fbdev/omap2/displays-new/connector-dvi.c         |  2 +-
 .../video/fbdev/omap2/displays-new/panel-lgphilips-lb035q02.c  |  2 +-
 .../video/fbdev/omap2/displays-new/panel-sharp-ls037v7dw01.c   |  2 +-
 drivers/video/fbdev/omap2/displays-new/panel-sony-acx565akm.c  |  2 +-
 drivers/video/fbdev/omap2/displays-new/panel-tpo-td028ttec1.c  |  2 +-
 drivers/video/fbdev/omap2/displays-new/panel-tpo-td043mtea1.c  |  2 +-
 drivers/video/fbdev/omap2/dss/dispc.c                          | 10 +++-------
 drivers/video/fbdev/omap2/dss/display.c                        |  4 +++-
 drivers/video/fbdev/omap2/dss/dsi.c                            |  2 +-
 drivers/video/fbdev/omap2/dss/rfbi.c                           |  2 +-
 drivers/video/fbdev/omap2/omapfb/omapfb-main.c                 |  4 ++--
 include/video/omapdss.h                                        |  1 -
 13 files changed, 17 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/omap_connector.c b/drivers/gpu/drm/omapdrm/omap_connector.c
index a94b11f7859d..2c2173bc3f00 100644
--- a/drivers/gpu/drm/omapdrm/omap_connector.c
+++ b/drivers/gpu/drm/omapdrm/omap_connector.c
@@ -102,7 +102,7 @@ void copy_timings_drm_to_omap(struct omap_video_timings *timings,
 
 	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;
+	timings->sync_pclk_edge = OMAPDSS_DRIVE_SIG_FALLING_EDGE;
 }
 
 static enum drm_connector_status omap_connector_detect(
diff --git a/drivers/video/fbdev/omap2/displays-new/connector-dvi.c b/drivers/video/fbdev/omap2/displays-new/connector-dvi.c
index 0cdc97413020..a8ce920fa797 100644
--- a/drivers/video/fbdev/omap2/displays-new/connector-dvi.c
+++ b/drivers/video/fbdev/omap2/displays-new/connector-dvi.c
@@ -37,7 +37,7 @@ static const struct omap_video_timings dvic_default_timings = {
 	.hsync_level	= OMAPDSS_SIG_ACTIVE_HIGH,
 	.data_pclk_edge	= OMAPDSS_DRIVE_SIG_RISING_EDGE,
 	.de_level	= OMAPDSS_SIG_ACTIVE_HIGH,
-	.sync_pclk_edge	= OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES,
+	.sync_pclk_edge	= OMAPDSS_DRIVE_SIG_FALLING_EDGE,
 };
 
 struct panel_drv_data {
diff --git a/drivers/video/fbdev/omap2/displays-new/panel-lgphilips-lb035q02.c b/drivers/video/fbdev/omap2/displays-new/panel-lgphilips-lb035q02.c
index 27d4fcfa1824..9974a37a11af 100644
--- a/drivers/video/fbdev/omap2/displays-new/panel-lgphilips-lb035q02.c
+++ b/drivers/video/fbdev/omap2/displays-new/panel-lgphilips-lb035q02.c
@@ -37,7 +37,7 @@ static struct omap_video_timings lb035q02_timings = {
 	.hsync_level	= OMAPDSS_SIG_ACTIVE_LOW,
 	.data_pclk_edge	= OMAPDSS_DRIVE_SIG_RISING_EDGE,
 	.de_level	= OMAPDSS_SIG_ACTIVE_HIGH,
-	.sync_pclk_edge	= OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES,
+	.sync_pclk_edge	= OMAPDSS_DRIVE_SIG_FALLING_EDGE,
 };
 
 struct panel_drv_data {
diff --git a/drivers/video/fbdev/omap2/displays-new/panel-sharp-ls037v7dw01.c b/drivers/video/fbdev/omap2/displays-new/panel-sharp-ls037v7dw01.c
index 18b19b6e1ac2..eae263702964 100644
--- a/drivers/video/fbdev/omap2/displays-new/panel-sharp-ls037v7dw01.c
+++ b/drivers/video/fbdev/omap2/displays-new/panel-sharp-ls037v7dw01.c
@@ -54,7 +54,7 @@ static const struct omap_video_timings sharp_ls_timings = {
 	.hsync_level	= OMAPDSS_SIG_ACTIVE_LOW,
 	.data_pclk_edge	= OMAPDSS_DRIVE_SIG_RISING_EDGE,
 	.de_level	= OMAPDSS_SIG_ACTIVE_HIGH,
-	.sync_pclk_edge	= OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES,
+	.sync_pclk_edge	= OMAPDSS_DRIVE_SIG_FALLING_EDGE,
 };
 
 #define to_panel_data(p) container_of(p, struct panel_drv_data, dssdev)
diff --git a/drivers/video/fbdev/omap2/displays-new/panel-sony-acx565akm.c b/drivers/video/fbdev/omap2/displays-new/panel-sony-acx565akm.c
index 337ccc5c0f5e..90cbc4c3406c 100644
--- a/drivers/video/fbdev/omap2/displays-new/panel-sony-acx565akm.c
+++ b/drivers/video/fbdev/omap2/displays-new/panel-sony-acx565akm.c
@@ -108,7 +108,7 @@ static const struct omap_video_timings acx565akm_panel_timings = {
 
 	.data_pclk_edge	= OMAPDSS_DRIVE_SIG_RISING_EDGE,
 	.de_level	= OMAPDSS_SIG_ACTIVE_HIGH,
-	.sync_pclk_edge	= OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES,
+	.sync_pclk_edge	= OMAPDSS_DRIVE_SIG_FALLING_EDGE,
 };
 
 #define to_panel_data(p) container_of(p, struct panel_drv_data, dssdev)
diff --git a/drivers/video/fbdev/omap2/displays-new/panel-tpo-td028ttec1.c b/drivers/video/fbdev/omap2/displays-new/panel-tpo-td028ttec1.c
index fbba0b8ca871..9edc51133c59 100644
--- a/drivers/video/fbdev/omap2/displays-new/panel-tpo-td028ttec1.c
+++ b/drivers/video/fbdev/omap2/displays-new/panel-tpo-td028ttec1.c
@@ -58,7 +58,7 @@ static struct omap_video_timings td028ttec1_panel_timings = {
 
 	.data_pclk_edge	= OMAPDSS_DRIVE_SIG_FALLING_EDGE,
 	.de_level	= OMAPDSS_SIG_ACTIVE_HIGH,
-	.sync_pclk_edge	= OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES,
+	.sync_pclk_edge	= OMAPDSS_DRIVE_SIG_RISING_EDGE,
 };
 
 #define JBT_COMMAND	0x000
diff --git a/drivers/video/fbdev/omap2/displays-new/panel-tpo-td043mtea1.c b/drivers/video/fbdev/omap2/displays-new/panel-tpo-td043mtea1.c
index 5aba76bca25a..79e4a029aab9 100644
--- a/drivers/video/fbdev/omap2/displays-new/panel-tpo-td043mtea1.c
+++ b/drivers/video/fbdev/omap2/displays-new/panel-tpo-td043mtea1.c
@@ -91,7 +91,7 @@ static const struct omap_video_timings tpo_td043_timings = {
 	.hsync_level	= OMAPDSS_SIG_ACTIVE_LOW,
 	.data_pclk_edge	= OMAPDSS_DRIVE_SIG_FALLING_EDGE,
 	.de_level	= OMAPDSS_SIG_ACTIVE_HIGH,
-	.sync_pclk_edge	= OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES,
+	.sync_pclk_edge	= OMAPDSS_DRIVE_SIG_RISING_EDGE,
 };
 
 #define to_panel_data(p) container_of(p, struct panel_drv_data, dssdev)
diff --git a/drivers/video/fbdev/omap2/dss/dispc.c b/drivers/video/fbdev/omap2/dss/dispc.c
index a19a1d4b2d19..11bd780fcdfa 100644
--- a/drivers/video/fbdev/omap2/dss/dispc.c
+++ b/drivers/video/fbdev/omap2/dss/dispc.c
@@ -2934,22 +2934,18 @@ static void _dispc_mgr_set_lcd_timings(enum omap_channel channel, int hsw,
 	case OMAPDSS_DRIVE_SIG_FALLING_EDGE:
 		ipc = true;
 		break;
-	case OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES:
 	default:
 		BUG();
 	}
 
+	/* always use the 'rf' setting */
+	onoff = true;
+
 	switch (sync_pclk_edge) {
-	case OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES:
-		onoff = false;
-		rf = false;
-		break;
 	case OMAPDSS_DRIVE_SIG_FALLING_EDGE:
-		onoff = true;
 		rf = false;
 		break;
 	case OMAPDSS_DRIVE_SIG_RISING_EDGE:
-		onoff = true;
 		rf = true;
 		break;
 	default:
diff --git a/drivers/video/fbdev/omap2/dss/display.c b/drivers/video/fbdev/omap2/dss/display.c
index 2412a0dd0c13..a6fd2d35ad60 100644
--- a/drivers/video/fbdev/omap2/dss/display.c
+++ b/drivers/video/fbdev/omap2/dss/display.c
@@ -295,7 +295,9 @@ void videomode_to_omap_video_timings(const struct videomode *vm,
 		OMAPDSS_DRIVE_SIG_RISING_EDGE :
 		OMAPDSS_DRIVE_SIG_FALLING_EDGE;
 
-	ovt->sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES;
+	ovt->sync_pclk_edge = vm->flags & DISPLAY_FLAGS_PIXDATA_POSEDGE ?
+		OMAPDSS_DRIVE_SIG_FALLING_EDGE :
+		OMAPDSS_DRIVE_SIG_RISING_EDGE;
 }
 EXPORT_SYMBOL(videomode_to_omap_video_timings);
 
diff --git a/drivers/video/fbdev/omap2/dss/dsi.c b/drivers/video/fbdev/omap2/dss/dsi.c
index 5081f6fb1737..28b0bc11669d 100644
--- a/drivers/video/fbdev/omap2/dss/dsi.c
+++ b/drivers/video/fbdev/omap2/dss/dsi.c
@@ -4137,7 +4137,7 @@ static int dsi_display_init_dispc(struct platform_device *dsidev,
 	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;
+	dsi->timings.sync_pclk_edge = OMAPDSS_DRIVE_SIG_FALLING_EDGE;
 
 	dss_mgr_set_timings(mgr, &dsi->timings);
 
diff --git a/drivers/video/fbdev/omap2/dss/rfbi.c b/drivers/video/fbdev/omap2/dss/rfbi.c
index 28e694b11ff9..065effca9236 100644
--- a/drivers/video/fbdev/omap2/dss/rfbi.c
+++ b/drivers/video/fbdev/omap2/dss/rfbi.c
@@ -869,7 +869,7 @@ static void rfbi_config_lcd_manager(struct omap_dss_device *dssdev)
 	rfbi.timings.vsync_level = OMAPDSS_SIG_ACTIVE_HIGH;
 	rfbi.timings.data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE;
 	rfbi.timings.de_level = OMAPDSS_SIG_ACTIVE_HIGH;
-	rfbi.timings.sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES;
+	rfbi.timings.sync_pclk_edge = OMAPDSS_DRIVE_SIG_FALLING_EDGE;
 
 	dss_mgr_set_timings(mgr, &rfbi.timings);
 }
diff --git a/drivers/video/fbdev/omap2/omapfb/omapfb-main.c b/drivers/video/fbdev/omap2/omapfb/omapfb-main.c
index 22f07f88bc40..4f0cbb54d4db 100644
--- a/drivers/video/fbdev/omap2/omapfb/omapfb-main.c
+++ b/drivers/video/fbdev/omap2/omapfb/omapfb-main.c
@@ -2073,7 +2073,7 @@ static int omapfb_mode_to_timings(const char *mode_str,
 	} else {
 		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;
+		timings->sync_pclk_edge = OMAPDSS_DRIVE_SIG_FALLING_EDGE;
 	}
 
 	timings->pixelclock = PICOS2KHZ(var->pixclock) * 1000;
@@ -2223,7 +2223,7 @@ static void fb_videomode_to_omap_timings(struct fb_videomode *m,
 	} else {
 		t->data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE;
 		t->de_level = OMAPDSS_SIG_ACTIVE_HIGH;
-		t->sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES;
+		t->sync_pclk_edge = OMAPDSS_DRIVE_SIG_FALLING_EDGE;
 	}
 
 	t->x_res = m->xres;
diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index 60de61fea8e3..7414e4a97508 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -134,7 +134,6 @@ enum omap_dss_signal_level {
 };
 
 enum omap_dss_signal_edge {
-	OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES,
 	OMAPDSS_DRIVE_SIG_RISING_EDGE,
 	OMAPDSS_DRIVE_SIG_FALLING_EDGE,
 };
-- 
2.3.0


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

* [PATCH 06/15] OMAPDSS: DISPC: explicit handling for sync and de levels
  2015-02-26 12:48 [PATCH 01/15] OMAPDSS: fix AM43xx minimum pixel clock divider Tomi Valkeinen
                   ` (3 preceding siblings ...)
  2015-02-26 12:48 ` [PATCH 05/15] OMAPDSS: DISPC: remove OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES Tomi Valkeinen
@ 2015-02-26 12:49 ` Tomi Valkeinen
  2015-02-26 12:49 ` [PATCH 07/15] OMAPDSS: change signal_level & signal_edge enum values Tomi Valkeinen
                   ` (8 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Tomi Valkeinen @ 2015-02-26 12:49 UTC (permalink / raw)
  To: linux-omap, linux-fbdev; +Cc: Tomi Valkeinen

When configuring the lcd timings, instead of writing enum values
directly to the HW, use switch-case to get the value to be programmed.

This is safer and also allows us to change the enum values.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
 drivers/video/fbdev/omap2/dss/dispc.c | 41 +++++++++++++++++++++++++++++++----
 1 file changed, 37 insertions(+), 4 deletions(-)

diff --git a/drivers/video/fbdev/omap2/dss/dispc.c b/drivers/video/fbdev/omap2/dss/dispc.c
index 11bd780fcdfa..8805266a52f4 100644
--- a/drivers/video/fbdev/omap2/dss/dispc.c
+++ b/drivers/video/fbdev/omap2/dss/dispc.c
@@ -2915,7 +2915,7 @@ static void _dispc_mgr_set_lcd_timings(enum omap_channel channel, int hsw,
 
 {
 	u32 timing_h, timing_v, l;
-	bool onoff, rf, ipc;
+	bool onoff, rf, ipc, vs, hs, de;
 
 	timing_h = FLD_VAL(hsw-1, dispc.feat->sw_start, 0) |
 			FLD_VAL(hfp-1, dispc.feat->fp_start, 8) |
@@ -2927,6 +2927,39 @@ static void _dispc_mgr_set_lcd_timings(enum omap_channel channel, int hsw,
 	dispc_write_reg(DISPC_TIMING_H(channel), timing_h);
 	dispc_write_reg(DISPC_TIMING_V(channel), timing_v);
 
+	switch (vsync_level) {
+	case OMAPDSS_SIG_ACTIVE_LOW:
+		vs = true;
+		break;
+	case OMAPDSS_SIG_ACTIVE_HIGH:
+		vs = false;
+		break;
+	default:
+		BUG();
+	}
+
+	switch (hsync_level) {
+	case OMAPDSS_SIG_ACTIVE_LOW:
+		hs = true;
+		break;
+	case OMAPDSS_SIG_ACTIVE_HIGH:
+		hs = false;
+		break;
+	default:
+		BUG();
+	}
+
+	switch (de_level) {
+	case OMAPDSS_SIG_ACTIVE_LOW:
+		de = true;
+		break;
+	case OMAPDSS_SIG_ACTIVE_HIGH:
+		de = false;
+		break;
+	default:
+		BUG();
+	}
+
 	switch (data_pclk_edge) {
 	case OMAPDSS_DRIVE_SIG_RISING_EDGE:
 		ipc = false;
@@ -2954,10 +2987,10 @@ static void _dispc_mgr_set_lcd_timings(enum omap_channel channel, int hsw,
 
 	l = FLD_VAL(onoff, 17, 17) |
 		FLD_VAL(rf, 16, 16) |
-		FLD_VAL(de_level, 15, 15) |
+		FLD_VAL(de, 15, 15) |
 		FLD_VAL(ipc, 14, 14) |
-		FLD_VAL(hsync_level, 13, 13) |
-		FLD_VAL(vsync_level, 12, 12);
+		FLD_VAL(hs, 13, 13) |
+		FLD_VAL(vs, 12, 12);
 
 	dispc_write_reg(DISPC_POL_FREQ(channel), l);
 
-- 
2.3.0


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

* [PATCH 07/15] OMAPDSS: change signal_level & signal_edge enum values
  2015-02-26 12:48 [PATCH 01/15] OMAPDSS: fix AM43xx minimum pixel clock divider Tomi Valkeinen
                   ` (4 preceding siblings ...)
  2015-02-26 12:49 ` [PATCH 06/15] OMAPDSS: DISPC: explicit handling for sync and de levels Tomi Valkeinen
@ 2015-02-26 12:49 ` Tomi Valkeinen
  2015-02-26 12:49 ` [PATCH 08/15] OMAPDSS: DISPC: change sync_pclk_edge default value Tomi Valkeinen
                   ` (7 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Tomi Valkeinen @ 2015-02-26 12:49 UTC (permalink / raw)
  To: linux-omap, linux-fbdev; +Cc: Tomi Valkeinen

At the moment the enum values for ACTIVE_HIGH and RISING_EDGE are 0, and
ACTIVE_LOW and FALLING_EDGE are 1, to match the values programmed to HW.
The previous patch removed this dependency.

Swap the enum values the other way around. This doesn't change the
behavior in any way, but makes it easier to debug as value of '1' means
HIGH or RISING.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
 include/video/omapdss.h | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index 7414e4a97508..45a230190720 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -129,13 +129,13 @@ enum omap_rfbi_te_mode {
 };
 
 enum omap_dss_signal_level {
-	OMAPDSS_SIG_ACTIVE_HIGH	= 0,
-	OMAPDSS_SIG_ACTIVE_LOW	= 1,
+	OMAPDSS_SIG_ACTIVE_LOW,
+	OMAPDSS_SIG_ACTIVE_HIGH,
 };
 
 enum omap_dss_signal_edge {
-	OMAPDSS_DRIVE_SIG_RISING_EDGE,
 	OMAPDSS_DRIVE_SIG_FALLING_EDGE,
+	OMAPDSS_DRIVE_SIG_RISING_EDGE,
 };
 
 enum omap_dss_venc_type {
-- 
2.3.0


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

* [PATCH 08/15] OMAPDSS: DISPC: change sync_pclk_edge default value
  2015-02-26 12:48 [PATCH 01/15] OMAPDSS: fix AM43xx minimum pixel clock divider Tomi Valkeinen
                   ` (5 preceding siblings ...)
  2015-02-26 12:49 ` [PATCH 07/15] OMAPDSS: change signal_level & signal_edge enum values Tomi Valkeinen
@ 2015-02-26 12:49 ` Tomi Valkeinen
  2015-02-26 12:49 ` [PATCH 09/15] OMAPDSS: DISPC: fix div by zero issue in overlay scaling Tomi Valkeinen
                   ` (6 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Tomi Valkeinen @ 2015-02-26 12:49 UTC (permalink / raw)
  To: linux-omap, linux-fbdev; +Cc: Tomi Valkeinen

The common 'struct videomode' does not have a flag to select when the
sync signals should be driven.

The default behavior of DISPC HW is to drive the sync signal on the
opposite pixel clock edge from data signal, which is also what the
videomode_to_omap_video_timings() uses.

However, it looks like what panels usually expect is that the data and
sync signals are driven on the same edge, so let's change
videomode_to_omap_video_timings() to set the sync_pclk_edge accordingly.

Note that this only affect panels drivers that use
videomode_to_omap_video_timings(), probably when getting the video
timings directly from DT data. The drivers can still configure the
sync_pclk_edge independently if they so wish.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
 drivers/video/fbdev/omap2/dss/display.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/video/fbdev/omap2/dss/display.c b/drivers/video/fbdev/omap2/dss/display.c
index a6fd2d35ad60..ef5b9027985d 100644
--- a/drivers/video/fbdev/omap2/dss/display.c
+++ b/drivers/video/fbdev/omap2/dss/display.c
@@ -295,9 +295,7 @@ void videomode_to_omap_video_timings(const struct videomode *vm,
 		OMAPDSS_DRIVE_SIG_RISING_EDGE :
 		OMAPDSS_DRIVE_SIG_FALLING_EDGE;
 
-	ovt->sync_pclk_edge = vm->flags & DISPLAY_FLAGS_PIXDATA_POSEDGE ?
-		OMAPDSS_DRIVE_SIG_FALLING_EDGE :
-		OMAPDSS_DRIVE_SIG_RISING_EDGE;
+	ovt->sync_pclk_edge = ovt->data_pclk_edge;
 }
 EXPORT_SYMBOL(videomode_to_omap_video_timings);
 
-- 
2.3.0


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

* [PATCH 09/15] OMAPDSS: DISPC: fix div by zero issue in overlay scaling
  2015-02-26 12:48 [PATCH 01/15] OMAPDSS: fix AM43xx minimum pixel clock divider Tomi Valkeinen
                   ` (6 preceding siblings ...)
  2015-02-26 12:49 ` [PATCH 08/15] OMAPDSS: DISPC: change sync_pclk_edge default value Tomi Valkeinen
@ 2015-02-26 12:49 ` Tomi Valkeinen
  2015-02-26 12:49 ` [PATCH 10/15] OMAPDSS: DISPC: lock access to DISPC_CONTROL & DISPC_CONFIG Tomi Valkeinen
                   ` (5 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Tomi Valkeinen @ 2015-02-26 12:49 UTC (permalink / raw)
  To: linux-omap, linux-fbdev; +Cc: Tomi Valkeinen

omapdrm doesn't always configure the overlays correctly, causing the
overlay setup functions to be called with zero timings. This leads to
division by zero error.

This happens, for example, when a HDMI cable is not connected, but a
user tries to setup a plane with scaling.

Fixing omapdrm is a big job, so for now let's check for the bad timings
in DISPC and return an error.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
 drivers/video/fbdev/omap2/dss/dispc.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/drivers/video/fbdev/omap2/dss/dispc.c b/drivers/video/fbdev/omap2/dss/dispc.c
index 8805266a52f4..1123111d3940 100644
--- a/drivers/video/fbdev/omap2/dss/dispc.c
+++ b/drivers/video/fbdev/omap2/dss/dispc.c
@@ -2322,6 +2322,11 @@ static int dispc_ovl_calc_scaling(unsigned long pclk, unsigned long lclk,
 	if (width = out_width && height = out_height)
 		return 0;
 
+	if (pclk = 0 || mgr_timings->pixelclock = 0) {
+		DSSERR("cannot calculate scaling settings: pclk is zero\n");
+		return -EINVAL;
+	}
+
 	if ((caps & OMAP_DSS_OVL_CAP_SCALE) = 0)
 		return -EINVAL;
 
-- 
2.3.0


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

* [PATCH 10/15] OMAPDSS: DISPC: lock access to DISPC_CONTROL & DISPC_CONFIG
  2015-02-26 12:48 [PATCH 01/15] OMAPDSS: fix AM43xx minimum pixel clock divider Tomi Valkeinen
                   ` (7 preceding siblings ...)
  2015-02-26 12:49 ` [PATCH 09/15] OMAPDSS: DISPC: fix div by zero issue in overlay scaling Tomi Valkeinen
@ 2015-02-26 12:49 ` Tomi Valkeinen
  2015-02-26 12:49 ` [PATCH 11/15] OMAPDSS: setup default fifo thresholds Tomi Valkeinen
                   ` (4 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Tomi Valkeinen @ 2015-02-26 12:49 UTC (permalink / raw)
  To: linux-omap, linux-fbdev; +Cc: Tomi Valkeinen

Dispc driver presumes that the callers handle locking for all normal
functions. However, omapdrm doesn't handle this, and presumes that all
overlay manager registers are private to that overlay manager, and thus
presumes that configurations for overlay managers can be written via
different threads freely.

For many registers the above is true. The exceptions are DISPC_CONTROL
and DISPC_CONFIG registers, which contain bits for both LCD and TV
overlay managers.

Fixing this properly in omapdrm means a big omapdrm rewrite. So, for
now, add locking to dispc for the problematic registers.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Reported-by: Somnath Mukherjee <somnath@ti.com>
---
 drivers/video/fbdev/omap2/dss/dispc.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/drivers/video/fbdev/omap2/dss/dispc.c b/drivers/video/fbdev/omap2/dss/dispc.c
index 1123111d3940..766c985cbfa7 100644
--- a/drivers/video/fbdev/omap2/dss/dispc.c
+++ b/drivers/video/fbdev/omap2/dss/dispc.c
@@ -123,6 +123,9 @@ static struct {
 
 	struct regmap *syscon_pol;
 	u32 syscon_pol_offset;
+
+	/* DISPC_CONTROL & DISPC_CONFIG lock*/
+	spinlock_t control_lock;
 } dispc;
 
 enum omap_color_component {
@@ -261,7 +264,16 @@ static u32 mgr_fld_read(enum omap_channel channel, enum mgr_reg_fields regfld)
 static void mgr_fld_write(enum omap_channel channel,
 					enum mgr_reg_fields regfld, int val) {
 	const struct dispc_reg_field rfld = mgr_desc[channel].reg_desc[regfld];
+	const bool need_lock = rfld.reg = DISPC_CONTROL || rfld.reg = DISPC_CONFIG;
+	unsigned long flags;
+
+	if (need_lock)
+		spin_lock_irqsave(&dispc.control_lock, flags);
+
 	REG_FLD_MOD(rfld.reg, val, rfld.high, rfld.low);
+
+	if (need_lock)
+		spin_unlock_irqrestore(&dispc.control_lock, flags);
 }
 
 #define SR(reg) \
@@ -3804,6 +3816,8 @@ static int __init omap_dispchw_probe(struct platform_device *pdev)
 
 	dispc.pdev = pdev;
 
+	spin_lock_init(&dispc.control_lock);
+
 	r = dispc_init_features(dispc.pdev);
 	if (r)
 		return r;
-- 
2.3.0


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

* [PATCH 11/15] OMAPDSS: setup default fifo thresholds
  2015-02-26 12:48 [PATCH 01/15] OMAPDSS: fix AM43xx minimum pixel clock divider Tomi Valkeinen
                   ` (8 preceding siblings ...)
  2015-02-26 12:49 ` [PATCH 10/15] OMAPDSS: DISPC: lock access to DISPC_CONTROL & DISPC_CONFIG Tomi Valkeinen
@ 2015-02-26 12:49 ` Tomi Valkeinen
  2015-02-26 12:49 ` [PATCH 12/15] OMAPDSS: Add support for MFLAG Tomi Valkeinen
                   ` (3 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Tomi Valkeinen @ 2015-02-26 12:49 UTC (permalink / raw)
  To: linux-omap, linux-fbdev; +Cc: Tomi Valkeinen

At the moment we don't setup FIFO thresholds by default in omapdss. It's
supposed to be done by the user of omapdss. And that is missing from
omapdrm, causing unoptimal thresholds to be used when using omapdrm.

While I believe it's in theory better to allow the user of omapdss to
setup the fifo thresholds, in practice we always use the same values,
and we could as well setup the thresholds in omapdss.

Furthermore, in omapdss init we always swap the FIFO used for GFX and WB
overlays, but we don't swap the FIFO thresholds for those overlays
(which is the reason for omapdrm using unoptimal HW reset values). So
it would make sense to setup the thresholds to account for the swapping
of the FIFOs.

So, this patch adds code to setup default FIFO tresholds at omapdss
init.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
 drivers/video/fbdev/omap2/dss/dispc.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/drivers/video/fbdev/omap2/dss/dispc.c b/drivers/video/fbdev/omap2/dss/dispc.c
index 766c985cbfa7..6296a3e5124f 100644
--- a/drivers/video/fbdev/omap2/dss/dispc.c
+++ b/drivers/video/fbdev/omap2/dss/dispc.c
@@ -1138,6 +1138,7 @@ static void dispc_init_fifos(void)
 	int fifo;
 	u8 start, end;
 	u32 unit;
+	int i;
 
 	unit = dss_feat_get_buffer_size_unit();
 
@@ -1177,6 +1178,20 @@ static void dispc_init_fifos(void)
 		dispc.fifo_assignment[OMAP_DSS_GFX] = OMAP_DSS_WB;
 		dispc.fifo_assignment[OMAP_DSS_WB] = OMAP_DSS_GFX;
 	}
+
+	/*
+	 * Setup default fifo thresholds.
+	 */
+	for (i = 0; i < dss_feat_get_num_ovls(); ++i) {
+		u32 low, high;
+		const bool use_fifomerge = false;
+		const bool manual_update = false;
+
+		dispc_ovl_compute_fifo_thresholds(i, &low, &high,
+			use_fifomerge, manual_update);
+
+		dispc_ovl_set_fifo_threshold(i, low, high);
+	}
 }
 
 static u32 dispc_ovl_get_fifo_size(enum omap_plane plane)
-- 
2.3.0


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

* [PATCH 12/15] OMAPDSS: Add support for MFLAG
  2015-02-26 12:48 [PATCH 01/15] OMAPDSS: fix AM43xx minimum pixel clock divider Tomi Valkeinen
                   ` (9 preceding siblings ...)
  2015-02-26 12:49 ` [PATCH 11/15] OMAPDSS: setup default fifo thresholds Tomi Valkeinen
@ 2015-02-26 12:49 ` Tomi Valkeinen
  2015-02-26 12:49 ` [PATCH 13/15] OMAPDSS: workaround for MFLAG + NV12 issue Tomi Valkeinen
                   ` (2 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Tomi Valkeinen @ 2015-02-26 12:49 UTC (permalink / raw)
  To: linux-omap, linux-fbdev; +Cc: Tomi Valkeinen

OMAP5 has support for MFLAG feature, which allows DSS to dynamically
increase the priority of DISPC's DMA traffic. At the moment we don't
have support for it.

It was noticed that on DRA7 with high bandwidth use cases we see FIFO
underflows. Implementing MFLAG support removed those underflows.
Interestingly, on OMAP5 uEVM no such overflows were seen.

This patch adds a simple MFLAG implementation, where we use a fixed
MFLAG threshold value based on the FIFO size. The thresholds are set to
4/8 of fifo size for low threshold, and 5/8 of fifo size for high
threshold.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
 drivers/video/fbdev/omap2/dss/dispc.c | 50 +++++++++++++++++++++++++++++++++++
 1 file changed, 50 insertions(+)

diff --git a/drivers/video/fbdev/omap2/dss/dispc.c b/drivers/video/fbdev/omap2/dss/dispc.c
index 6296a3e5124f..6b056d0ce187 100644
--- a/drivers/video/fbdev/omap2/dss/dispc.c
+++ b/drivers/video/fbdev/omap2/dss/dispc.c
@@ -1305,6 +1305,53 @@ void dispc_ovl_compute_fifo_thresholds(enum omap_plane plane,
 }
 EXPORT_SYMBOL(dispc_ovl_compute_fifo_thresholds);
 
+static void dispc_ovl_set_mflag(enum omap_plane plane, bool enable)
+{
+	int bit;
+
+	if (plane = OMAP_DSS_GFX)
+		bit = 14;
+	else
+		bit = 23;
+
+	REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), enable, bit, bit);
+}
+
+static void dispc_ovl_set_mflag_threshold(enum omap_plane plane,
+	int low, int high)
+{
+	dispc_write_reg(DISPC_OVL_MFLAG_THRESHOLD(plane),
+		FLD_VAL(high, 31, 16) |	FLD_VAL(low, 15, 0));
+}
+
+static void dispc_init_mflag(void)
+{
+	int i;
+
+	dispc_write_reg(DISPC_GLOBAL_MFLAG_ATTRIBUTE,
+		(2 << 0) |	/* MFLAG_CTRL = enable */
+		(0 << 2));	/* MFLAG_START = disable */
+
+	for (i = 0; i < dss_feat_get_num_ovls(); ++i) {
+		u32 size = dispc_ovl_get_fifo_size(i);
+		u32 unit = dss_feat_get_buffer_size_unit();
+		u32 low, high;
+
+		dispc_ovl_set_mflag(i, true);
+
+		/*
+		 * Simulation team suggests below thesholds:
+		 * HT = fifosize * 5 / 8;
+		 * LT = fifosize * 4 / 8;
+		 */
+
+		low = size * 4 / 8 / unit;
+		high = size * 5 / 8 / unit;
+
+		dispc_ovl_set_mflag_threshold(i, low, high);
+	}
+}
+
 static void dispc_ovl_set_fir(enum omap_plane plane,
 				int hinc, int vinc,
 				enum omap_color_component color_comp)
@@ -3630,6 +3677,9 @@ static void _omap_dispc_initial_config(void)
 
 	if (dispc.feat->mstandby_workaround)
 		REG_FLD_MOD(DISPC_MSTANDBY_CTRL, 1, 0, 0);
+
+	if (dss_has_feature(FEAT_MFLAG))
+		dispc_init_mflag();
 }
 
 static const struct dispc_features omap24xx_dispc_feats __initconst = {
-- 
2.3.0


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

* [PATCH 13/15] OMAPDSS: workaround for MFLAG + NV12 issue
  2015-02-26 12:48 [PATCH 01/15] OMAPDSS: fix AM43xx minimum pixel clock divider Tomi Valkeinen
                   ` (10 preceding siblings ...)
  2015-02-26 12:49 ` [PATCH 12/15] OMAPDSS: Add support for MFLAG Tomi Valkeinen
@ 2015-02-26 12:49 ` Tomi Valkeinen
  2015-02-26 12:49 ` [PATCH 14/15] OMAPDSS: HDMI: hdmi synclost work-around Tomi Valkeinen
  2015-02-26 12:49 ` [PATCH 15/15] OMAPDSS: disable VT switch Tomi Valkeinen
  13 siblings, 0 replies; 15+ messages in thread
From: Tomi Valkeinen @ 2015-02-26 12:49 UTC (permalink / raw)
  To: linux-omap, linux-fbdev; +Cc: Tomi Valkeinen

It was found that having two displays enabled and having an NV12 overlay
on one of the displays will cause underflows/synclosts. Debugging this
pointed to some issue with MFLAG.

It is unclear why this issue is happening, but it looks like there is a
HW bug related to MFLAG and FIFO management. Disabling MFLAG makes this
issue go away, but then we lose the benefit of MFLAG. Also forcing MFLAG
always on makes the issue go away.

Also, using certain values for MFLAG_START, MFLAG thresholds and PRELOAD
makes the issue go away, but there was no obvious logic to which values
work and which don't.

As a workaround until more information about this is found, force MFLAG
always on to make NV12 usable.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
 drivers/video/fbdev/omap2/dss/dispc.c | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/drivers/video/fbdev/omap2/dss/dispc.c b/drivers/video/fbdev/omap2/dss/dispc.c
index 6b056d0ce187..f4fc77d9d3bf 100644
--- a/drivers/video/fbdev/omap2/dss/dispc.c
+++ b/drivers/video/fbdev/omap2/dss/dispc.c
@@ -1328,8 +1328,18 @@ static void dispc_init_mflag(void)
 {
 	int i;
 
+	/*
+	 * HACK: NV12 color format and MFLAG seem to have problems working
+	 * together: using two displays, and having an NV12 overlay on one of
+	 * the displays will cause underflows/synclosts when MFLAG_CTRL=2.
+	 * Changing MFLAG thresholds and PRELOAD to certain values seem to
+	 * remove the errors, but there doesn't seem to be a clear logic on
+	 * which values work and which not.
+	 *
+	 * As a work-around, set force MFLAG to always on.
+	 */
 	dispc_write_reg(DISPC_GLOBAL_MFLAG_ATTRIBUTE,
-		(2 << 0) |	/* MFLAG_CTRL = enable */
+		(1 << 0) |	/* MFLAG_CTRL = force always on */
 		(0 << 2));	/* MFLAG_START = disable */
 
 	for (i = 0; i < dss_feat_get_num_ovls(); ++i) {
-- 
2.3.0


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

* [PATCH 14/15] OMAPDSS: HDMI: hdmi synclost work-around
  2015-02-26 12:48 [PATCH 01/15] OMAPDSS: fix AM43xx minimum pixel clock divider Tomi Valkeinen
                   ` (11 preceding siblings ...)
  2015-02-26 12:49 ` [PATCH 13/15] OMAPDSS: workaround for MFLAG + NV12 issue Tomi Valkeinen
@ 2015-02-26 12:49 ` Tomi Valkeinen
  2015-02-26 12:49 ` [PATCH 15/15] OMAPDSS: disable VT switch Tomi Valkeinen
  13 siblings, 0 replies; 15+ messages in thread
From: Tomi Valkeinen @ 2015-02-26 12:49 UTC (permalink / raw)
  To: linux-omap, linux-fbdev; +Cc: Tomi Valkeinen

DISPC and HDMI have synchronization issues when enabling or disabling
the output. The symptoms are a lot of sync-lost errors and occasionally
dispc gets "stuck" and we never get FRAMEDONE when disabling.

Testing has shown that this is somehow related to the time when DISPC's
output gets enabled:

- If DISPC is disabled when HDMI is in vertical blanking area, DISPC
  often gets stuck.
- If DISPC is disabled after vertical blanking area, no sync lost errors
  are seen.
- If DISPC is enabled right after HDMI VSYNC event, no sync lost errors
  are seen.

This patch is a simple work-around for the above issues:

- Before enabling DISPC output, we wait for HDMI VSYNC.
- Before disabling DISPC output, we wait for HDMI VSYNC and VSW+VBP.

This is not perfect WA, as it relies on the enable/disable of DISPC
happening relatively soon after the wait has ended. In practice I
presume there is at least ~10ms timewindow to accomplish the DISPC
enable/disable, which I hope is enough.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
 drivers/video/fbdev/omap2/dss/hdmi4.c | 50 +++++++++++++++++++++++++++++++++++
 drivers/video/fbdev/omap2/dss/hdmi5.c | 50 +++++++++++++++++++++++++++++++++++
 2 files changed, 100 insertions(+)

diff --git a/drivers/video/fbdev/omap2/dss/hdmi4.c b/drivers/video/fbdev/omap2/dss/hdmi4.c
index 916d47978f41..39cdd164d2ae 100644
--- a/drivers/video/fbdev/omap2/dss/hdmi4.c
+++ b/drivers/video/fbdev/omap2/dss/hdmi4.c
@@ -217,6 +217,26 @@ static int hdmi_power_on_full(struct omap_dss_device *dssdev)
 	if (r)
 		goto err_vid_enable;
 
+	/*
+	 * XXX Seems that on we easily get a flood of sync-lost errors when
+	 * enabling the output. This seems to be related to the time between
+	 * HDMI VSYNC and enabling the DISPC output.
+	 *
+	 * Testing shows that the sync-lost errors do not happen if we enable
+	 * the DISPC output very soon after HDMI VBLANK. So wait here for
+	 * VBLANK to reduce the chances of sync-losts.
+	 */
+	hdmi_write_reg(hdmi.wp.base, HDMI_WP_IRQSTATUS, HDMI_IRQ_VIDEO_VSYNC);
+
+	while (true) {
+		u32 v = hdmi_read_reg(hdmi.wp.base, HDMI_WP_IRQSTATUS_RAW);
+
+		if (v & HDMI_IRQ_VIDEO_VSYNC)
+			break;
+
+		usleep_range(500, 1000);
+	}
+
 	r = dss_mgr_enable(mgr);
 	if (r)
 		goto err_mgr_enable;
@@ -242,9 +262,39 @@ err_pll_enable:
 static void hdmi_power_off_full(struct omap_dss_device *dssdev)
 {
 	struct omap_overlay_manager *mgr = hdmi.output.manager;
+	const struct omap_video_timings *t;
+	unsigned vblank;
 
 	hdmi_wp_clear_irqenable(&hdmi.wp, 0xffffffff);
 
+	/*
+	 * XXX Seems that on we easily get a flood of sync-lost errors when
+	 * disabling the output, and sometimes the DISPC seems to get stuck and
+	 * we never get FRAMEDONE. This seems to happen if we disable DISPC
+	 * output during HDMI VBLANK.
+	 *
+	 * To reduce the possibility for sync-lost errors, calculate the time
+	 * for the vertical blanking, wait for VBLANK, then wait until VBLANK
+	 * ends.
+	 */
+	t = &hdmi.cfg.timings;
+	vblank = t->hfp + t->hsw + t->hbp + t->x_res;
+	vblank *= t->vsw + t->vbp;
+	vblank = (vblank * 1000) / (t->pixelclock / 1000);
+
+	hdmi_write_reg(hdmi.wp.base, HDMI_WP_IRQSTATUS, HDMI_IRQ_VIDEO_VSYNC);
+
+	while (true) {
+		u32 v = hdmi_read_reg(hdmi.wp.base, HDMI_WP_IRQSTATUS_RAW);
+
+		if (v & HDMI_IRQ_VIDEO_VSYNC)
+			break;
+
+		usleep_range(500, 1000);
+	}
+
+	usleep_range(vblank, vblank + 1000);
+
 	dss_mgr_disable(mgr);
 
 	hdmi_wp_video_stop(&hdmi.wp);
diff --git a/drivers/video/fbdev/omap2/dss/hdmi5.c b/drivers/video/fbdev/omap2/dss/hdmi5.c
index 3f0b34a7031a..65a91ac87a6a 100644
--- a/drivers/video/fbdev/omap2/dss/hdmi5.c
+++ b/drivers/video/fbdev/omap2/dss/hdmi5.c
@@ -234,6 +234,26 @@ static int hdmi_power_on_full(struct omap_dss_device *dssdev)
 	if (r)
 		goto err_vid_enable;
 
+	/*
+	 * XXX Seems that on we easily get a flood of sync-lost errors when
+	 * enabling the output. This seems to be related to the time between
+	 * HDMI VSYNC and enabling the DISPC output.
+	 *
+	 * Testing shows that the sync-lost errors do not happen if we enable
+	 * the DISPC output very soon after HDMI VBLANK. So wait here for
+	 * VBLANK to reduce the chances of sync-losts.
+	 */
+	hdmi_write_reg(hdmi.wp.base, HDMI_WP_IRQSTATUS, HDMI_IRQ_VIDEO_VSYNC);
+
+	while (true) {
+		u32 v = hdmi_read_reg(hdmi.wp.base, HDMI_WP_IRQSTATUS_RAW);
+
+		if (v & HDMI_IRQ_VIDEO_VSYNC)
+			break;
+
+		usleep_range(500, 1000);
+	}
+
 	r = dss_mgr_enable(mgr);
 	if (r)
 		goto err_mgr_enable;
@@ -259,9 +279,39 @@ err_pll_enable:
 static void hdmi_power_off_full(struct omap_dss_device *dssdev)
 {
 	struct omap_overlay_manager *mgr = hdmi.output.manager;
+	const struct omap_video_timings *t;
+	unsigned vblank;
 
 	hdmi_wp_clear_irqenable(&hdmi.wp, 0xffffffff);
 
+	/*
+	 * XXX Seems that on we easily get a flood of sync-lost errors when
+	 * disabling the output, and sometimes the DISPC seems to get stuck and
+	 * we never get FRAMEDONE. This seems to happen if we disable DISPC
+	 * output during HDMI VBLANK.
+	 *
+	 * To reduce the possibility for sync-lost errors, calculate the time
+	 * for the vertical blanking, wait for VBLANK, then wait until VBLANK
+	 * ends.
+	 */
+	t = &hdmi.cfg.timings;
+	vblank = t->hfp + t->hsw + t->hbp + t->x_res;
+	vblank *= t->vsw + t->vbp;
+	vblank = (vblank * 1000) / (t->pixelclock / 1000);
+
+	hdmi_write_reg(hdmi.wp.base, HDMI_WP_IRQSTATUS, HDMI_IRQ_VIDEO_VSYNC);
+
+	while (true) {
+		u32 v = hdmi_read_reg(hdmi.wp.base, HDMI_WP_IRQSTATUS_RAW);
+
+		if (v & HDMI_IRQ_VIDEO_VSYNC)
+			break;
+
+		usleep_range(500, 1000);
+	}
+
+	usleep_range(vblank, vblank + 1000);
+
 	dss_mgr_disable(mgr);
 
 	hdmi_wp_video_stop(&hdmi.wp);
-- 
2.3.0


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

* [PATCH 15/15] OMAPDSS: disable VT switch
  2015-02-26 12:48 [PATCH 01/15] OMAPDSS: fix AM43xx minimum pixel clock divider Tomi Valkeinen
                   ` (12 preceding siblings ...)
  2015-02-26 12:49 ` [PATCH 14/15] OMAPDSS: HDMI: hdmi synclost work-around Tomi Valkeinen
@ 2015-02-26 12:49 ` Tomi Valkeinen
  13 siblings, 0 replies; 15+ messages in thread
From: Tomi Valkeinen @ 2015-02-26 12:49 UTC (permalink / raw)
  To: linux-omap, linux-fbdev; +Cc: Tomi Valkeinen, NeilBrown

We don't need VT switch when suspending/resuming, so disable it. This
speeds up suspend/resume.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Cc: NeilBrown <neil@brown.name>
---
 drivers/video/fbdev/omap2/dss/dss.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/video/fbdev/omap2/dss/dss.c b/drivers/video/fbdev/omap2/dss/dss.c
index a6d10d4279f3..7f978b6a34e8 100644
--- a/drivers/video/fbdev/omap2/dss/dss.c
+++ b/drivers/video/fbdev/omap2/dss/dss.c
@@ -38,6 +38,7 @@
 #include <linux/regmap.h>
 #include <linux/of.h>
 #include <linux/regulator/consumer.h>
+#include <linux/suspend.h>
 
 #include <video/omapdss.h>
 
@@ -1138,6 +1139,8 @@ static int __init omap_dsshw_probe(struct platform_device *pdev)
 
 	dss_debugfs_create_file("dss", dss_dump_regs);
 
+	pm_set_vt_switch(0);
+
 	return 0;
 
 err_pll_init:
-- 
2.3.0


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

end of thread, other threads:[~2015-02-26 12:49 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-02-26 12:48 [PATCH 01/15] OMAPDSS: fix AM43xx minimum pixel clock divider Tomi Valkeinen
2015-02-26 12:48 ` [PATCH 02/15] OMAPDSS: HDMI5: Increase DDC SDA-HOLD time Tomi Valkeinen
2015-02-26 12:48 ` [PATCH 03/15] OMAPDSS: fix paddr check for TILER addresses Tomi Valkeinen
2015-02-26 12:48 ` [PATCH 04/15] OMAPDSS: TFP410: fix input sync signals Tomi Valkeinen
2015-02-26 12:48 ` [PATCH 05/15] OMAPDSS: DISPC: remove OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES Tomi Valkeinen
2015-02-26 12:49 ` [PATCH 06/15] OMAPDSS: DISPC: explicit handling for sync and de levels Tomi Valkeinen
2015-02-26 12:49 ` [PATCH 07/15] OMAPDSS: change signal_level & signal_edge enum values Tomi Valkeinen
2015-02-26 12:49 ` [PATCH 08/15] OMAPDSS: DISPC: change sync_pclk_edge default value Tomi Valkeinen
2015-02-26 12:49 ` [PATCH 09/15] OMAPDSS: DISPC: fix div by zero issue in overlay scaling Tomi Valkeinen
2015-02-26 12:49 ` [PATCH 10/15] OMAPDSS: DISPC: lock access to DISPC_CONTROL & DISPC_CONFIG Tomi Valkeinen
2015-02-26 12:49 ` [PATCH 11/15] OMAPDSS: setup default fifo thresholds Tomi Valkeinen
2015-02-26 12:49 ` [PATCH 12/15] OMAPDSS: Add support for MFLAG Tomi Valkeinen
2015-02-26 12:49 ` [PATCH 13/15] OMAPDSS: workaround for MFLAG + NV12 issue Tomi Valkeinen
2015-02-26 12:49 ` [PATCH 14/15] OMAPDSS: HDMI: hdmi synclost work-around Tomi Valkeinen
2015-02-26 12:49 ` [PATCH 15/15] OMAPDSS: disable VT switch Tomi Valkeinen

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).