linux-tegra.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [RFC PATCH 00/12] Tegra: Add DC one-shot support
@ 2015-05-11  1:38 Mark Zhang
       [not found] ` <1431308311-4470-1-git-send-email-markz-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
  0 siblings, 1 reply; 18+ messages in thread
From: Mark Zhang @ 2015-05-11  1:38 UTC (permalink / raw)
  To: thierry.reding-Re5JQEeQqe8AvxtiuMwx3w
  Cc: linux-tegra-u79uwXL29TY76Z2rM5mHXA,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

This patch set adds the Tegra dc one-shot support. The patch set is
tested on Dalmore + Sharp lq101r1sx01.

Basically this patch set is just for RFC. Some DRM files are changes,
I guess maybe there are better solutions for that. Also, Thierry
mentioned that "te-polarity" can be designed as a GPIO since not
every display controller has a dedicate TE pin like Tegra. So I
will try to create v2 after some comments are received.

Please be noticed that the patch #12 is not part of the feature,
it's just used for testing.

Mark Zhang (12):
  drm: Add a new mode flag: DRM_MODE_FLAG_PREFER_ONE_SHOT
  drm: panel: Add one-shot flag to Sharp lq101r1sx01 driver
  drm: panel: Turn on TE(Tearing Effect) on Sharp lq101r1sx01
  drm: Add DRM mode flag TE polarity
  dt: panel: Add property "te-polarity"
  drm: panel: Parse "te-polarity" in Sharp lq101r1sx01 driver
  drm/tegra: Set NC(Non-contiguous) mode to dc for one-shot
  drm/panel: Add panel func: idle/busy
  drm: dsi: Add "enter idle" & "exit idle" dcs functions
  drm: panel: Add idle/busy in Sharp lq101r1sx01 driver
  drm/tegra: Suspend dc/dsi/panel in one-shot mode
  JUST FOR TEST: Add one-shot trigger to update display

 .../bindings/panel/sharp,lq101r1sx01.txt           |   2 +
 arch/arm/boot/dts/tegra114-dalmore.dts             |   2 +
 drivers/gpu/drm/drm_mipi_dsi.c                     |  36 ++++++
 drivers/gpu/drm/panel/panel-sharp-lq101r1sx01.c    |  51 ++++++++-
 drivers/gpu/drm/tegra/dc.c                         | 124 ++++++++++++++++++---
 drivers/gpu/drm/tegra/dc.h                         |   5 +
 drivers/gpu/drm/tegra/drm.h                        |   4 +
 drivers/gpu/drm/tegra/dsi.c                        |  63 ++++++++++-
 include/drm/drm_mipi_dsi.h                         |   2 +
 include/drm/drm_panel.h                            |  18 +++
 include/uapi/drm/drm_mode.h                        |   3 +
 11 files changed, 290 insertions(+), 20 deletions(-)

-- 
2.1.4

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

* [RFC PATCH 01/12] drm: Add a new mode flag: DRM_MODE_FLAG_PREFER_ONE_SHOT
       [not found] ` <1431308311-4470-1-git-send-email-markz-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
@ 2015-05-11  1:38   ` Mark Zhang
       [not found]     ` <1431308311-4470-2-git-send-email-markz-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
  2015-05-11  1:38   ` [RFC PATCH 02/12] drm: panel: Add one-shot flag to Sharp lq101r1sx01 driver Mark Zhang
                     ` (10 subsequent siblings)
  11 siblings, 1 reply; 18+ messages in thread
From: Mark Zhang @ 2015-05-11  1:38 UTC (permalink / raw)
  To: thierry.reding-Re5JQEeQqe8AvxtiuMwx3w
  Cc: linux-tegra-u79uwXL29TY76Z2rM5mHXA,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

Normally this flag is set by panel driver so that crtc can enable
the "one-shot" mode(not scan frames continuously).

Signed-off-by: Mark Zhang <markz-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
---
 include/uapi/drm/drm_mode.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h
index dbeba949462a..5447a338e893 100644
--- a/include/uapi/drm/drm_mode.h
+++ b/include/uapi/drm/drm_mode.h
@@ -72,6 +72,7 @@
 #define  DRM_MODE_FLAG_3D_L_DEPTH_GFX_GFX_DEPTH	(6<<14)
 #define  DRM_MODE_FLAG_3D_TOP_AND_BOTTOM	(7<<14)
 #define  DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF	(8<<14)
+#define DRM_MODE_FLAG_PREFER_ONE_SHOT		(1<<19)
 
 
 /* DPMS flags */
-- 
2.1.4

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

* [RFC PATCH 02/12] drm: panel: Add one-shot flag to Sharp lq101r1sx01 driver
       [not found] ` <1431308311-4470-1-git-send-email-markz-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
  2015-05-11  1:38   ` [RFC PATCH 01/12] drm: Add a new mode flag: DRM_MODE_FLAG_PREFER_ONE_SHOT Mark Zhang
@ 2015-05-11  1:38   ` Mark Zhang
  2015-05-11  1:38   ` [RFC PATCH 03/12] drm: panel: Turn on TE(Tearing Effect) on Sharp lq101r1sx01 Mark Zhang
                     ` (9 subsequent siblings)
  11 siblings, 0 replies; 18+ messages in thread
From: Mark Zhang @ 2015-05-11  1:38 UTC (permalink / raw)
  To: thierry.reding-Re5JQEeQqe8AvxtiuMwx3w
  Cc: linux-tegra-u79uwXL29TY76Z2rM5mHXA,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

Sharp lq101r1sx01 has internal framebuffer so it doesn't
require crtc sending frames to it continuously.
So set the one-shot flag in the driver.

Signed-off-by: Mark Zhang <markz-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
---
 drivers/gpu/drm/panel/panel-sharp-lq101r1sx01.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/panel/panel-sharp-lq101r1sx01.c b/drivers/gpu/drm/panel/panel-sharp-lq101r1sx01.c
index 3cce3ca19601..19a67d2598c0 100644
--- a/drivers/gpu/drm/panel/panel-sharp-lq101r1sx01.c
+++ b/drivers/gpu/drm/panel/panel-sharp-lq101r1sx01.c
@@ -283,6 +283,7 @@ static const struct drm_display_mode default_mode = {
 	.vsync_start = 1600 + 4,
 	.vsync_end = 1600 + 4 + 8,
 	.vtotal = 1600 + 4 + 8 + 32,
+	.flags = DRM_MODE_FLAG_PREFER_ONE_SHOT,
 	.vrefresh = 60,
 };
 
-- 
2.1.4

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

* [RFC PATCH 03/12] drm: panel: Turn on TE(Tearing Effect) on Sharp lq101r1sx01
       [not found] ` <1431308311-4470-1-git-send-email-markz-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
  2015-05-11  1:38   ` [RFC PATCH 01/12] drm: Add a new mode flag: DRM_MODE_FLAG_PREFER_ONE_SHOT Mark Zhang
  2015-05-11  1:38   ` [RFC PATCH 02/12] drm: panel: Add one-shot flag to Sharp lq101r1sx01 driver Mark Zhang
@ 2015-05-11  1:38   ` Mark Zhang
  2015-05-11  1:38   ` [RFC PATCH 04/12] drm: Add DRM mode flag TE polarity Mark Zhang
                     ` (8 subsequent siblings)
  11 siblings, 0 replies; 18+ messages in thread
From: Mark Zhang @ 2015-05-11  1:38 UTC (permalink / raw)
  To: thierry.reding-Re5JQEeQqe8AvxtiuMwx3w
  Cc: linux-tegra-u79uwXL29TY76Z2rM5mHXA,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

Signed-off-by: Mark Zhang <markz-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
---
 drivers/gpu/drm/panel/panel-sharp-lq101r1sx01.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/drivers/gpu/drm/panel/panel-sharp-lq101r1sx01.c b/drivers/gpu/drm/panel/panel-sharp-lq101r1sx01.c
index 19a67d2598c0..b69f88cd15b2 100644
--- a/drivers/gpu/drm/panel/panel-sharp-lq101r1sx01.c
+++ b/drivers/gpu/drm/panel/panel-sharp-lq101r1sx01.c
@@ -238,6 +238,13 @@ static int sharp_panel_prepare(struct drm_panel *panel)
 		goto poweroff;
 	}
 
+	err = mipi_dsi_dcs_set_tear_on(sharp->link1,
+					MIPI_DSI_DCS_TEAR_MODE_VBLANK);
+	if (err < 0) {
+		dev_err(panel->dev, "failed to turn on TE: %d\n", err);
+		goto poweroff;
+	}
+
 	err = mipi_dsi_dcs_set_display_on(sharp->link1);
 	if (err < 0) {
 		dev_err(panel->dev, "failed to set display on: %d\n", err);
-- 
2.1.4

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

* [RFC PATCH 04/12] drm: Add DRM mode flag TE polarity
       [not found] ` <1431308311-4470-1-git-send-email-markz-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
                     ` (2 preceding siblings ...)
  2015-05-11  1:38   ` [RFC PATCH 03/12] drm: panel: Turn on TE(Tearing Effect) on Sharp lq101r1sx01 Mark Zhang
@ 2015-05-11  1:38   ` Mark Zhang
  2015-05-11  1:38   ` [RFC PATCH 05/12] dt: panel: Add property "te-polarity" Mark Zhang
                     ` (7 subsequent siblings)
  11 siblings, 0 replies; 18+ messages in thread
From: Mark Zhang @ 2015-05-11  1:38 UTC (permalink / raw)
  To: thierry.reding-Re5JQEeQqe8AvxtiuMwx3w
  Cc: linux-tegra-u79uwXL29TY76Z2rM5mHXA,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

Add 2 DRM mode flag: TE polarity high/low.

Signed-off-by: Mark Zhang <markz-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
---
 include/uapi/drm/drm_mode.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h
index 5447a338e893..b577cdfb76df 100644
--- a/include/uapi/drm/drm_mode.h
+++ b/include/uapi/drm/drm_mode.h
@@ -73,6 +73,8 @@
 #define  DRM_MODE_FLAG_3D_TOP_AND_BOTTOM	(7<<14)
 #define  DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF	(8<<14)
 #define DRM_MODE_FLAG_PREFER_ONE_SHOT		(1<<19)
+#define DRM_MODE_FLAG_TE_POLARITY_HIGH		(1<<20)
+#define DRM_MODE_FLAG_TE_POLARITY_LOW		(1<<21)
 
 
 /* DPMS flags */
-- 
2.1.4

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

* [RFC PATCH 05/12] dt: panel: Add property "te-polarity"
       [not found] ` <1431308311-4470-1-git-send-email-markz-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
                     ` (3 preceding siblings ...)
  2015-05-11  1:38   ` [RFC PATCH 04/12] drm: Add DRM mode flag TE polarity Mark Zhang
@ 2015-05-11  1:38   ` Mark Zhang
  2015-05-11  1:38   ` [RFC PATCH 06/12] drm: panel: Parse "te-polarity" in Sharp lq101r1sx01 driver Mark Zhang
                     ` (6 subsequent siblings)
  11 siblings, 0 replies; 18+ messages in thread
From: Mark Zhang @ 2015-05-11  1:38 UTC (permalink / raw)
  To: thierry.reding-Re5JQEeQqe8AvxtiuMwx3w
  Cc: linux-tegra-u79uwXL29TY76Z2rM5mHXA,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

te-polarity indicates the polarity of panel's TE(Tearing Effect) signal.
Normally the TE pin is connected to the host SoC. The display
controller will send a new frame to panel when the TE signal is
triggered.

Signed-off-by: Mark Zhang <markz-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
---
 Documentation/devicetree/bindings/panel/sharp,lq101r1sx01.txt | 2 ++
 arch/arm/boot/dts/tegra114-dalmore.dts                        | 2 ++
 2 files changed, 4 insertions(+)

diff --git a/Documentation/devicetree/bindings/panel/sharp,lq101r1sx01.txt b/Documentation/devicetree/bindings/panel/sharp,lq101r1sx01.txt
index f522bb8e47e1..680ebec9a927 100644
--- a/Documentation/devicetree/bindings/panel/sharp,lq101r1sx01.txt
+++ b/Documentation/devicetree/bindings/panel/sharp,lq101r1sx01.txt
@@ -23,6 +23,7 @@ Required properties (for DSI-LINK1 only):
 - link2: phandle to the DSI peripheral on the secondary link. Note that the
   presence of this property marks the containing node as DSI-LINK1.
 - power-supply: phandle of the regulator that provides the supply voltage
+- te-polarity: indicates the TE(Tearing Effect) polarity. 0: Low, 1: High.
 
 Optional properties (for DSI-LINK1 only):
 - backlight: phandle of the backlight device attached to the panel
@@ -38,6 +39,7 @@ Example:
 
 			power-supply = <...>;
 			backlight = <...>;
+			te-polarity = <0>;
 		};
 	};
 
diff --git a/arch/arm/boot/dts/tegra114-dalmore.dts b/arch/arm/boot/dts/tegra114-dalmore.dts
index 8b7aa0dcdc6e..fdb1cc4063a9 100644
--- a/arch/arm/boot/dts/tegra114-dalmore.dts
+++ b/arch/arm/boot/dts/tegra114-dalmore.dts
@@ -47,6 +47,8 @@
 
 				power-supply = <&avdd_lcd_reg>;
 				backlight = <&backlight>;
+
+				te-polarity = <0>; /* TE_POLARITY_LOW */
 			};
 		};
 	};
-- 
2.1.4

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

* [RFC PATCH 06/12] drm: panel: Parse "te-polarity" in Sharp lq101r1sx01 driver
       [not found] ` <1431308311-4470-1-git-send-email-markz-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
                     ` (4 preceding siblings ...)
  2015-05-11  1:38   ` [RFC PATCH 05/12] dt: panel: Add property "te-polarity" Mark Zhang
@ 2015-05-11  1:38   ` Mark Zhang
  2015-05-11  1:38   ` [RFC PATCH 07/12] drm/tegra: Set NC(Non-contiguous) mode to dc for one-shot Mark Zhang
                     ` (5 subsequent siblings)
  11 siblings, 0 replies; 18+ messages in thread
From: Mark Zhang @ 2015-05-11  1:38 UTC (permalink / raw)
  To: thierry.reding-Re5JQEeQqe8AvxtiuMwx3w
  Cc: linux-tegra-u79uwXL29TY76Z2rM5mHXA,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

Signed-off-by: Mark Zhang <markz-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
---
 drivers/gpu/drm/panel/panel-sharp-lq101r1sx01.c | 17 ++++++++++++++++-
 1 file changed, 16 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/panel/panel-sharp-lq101r1sx01.c b/drivers/gpu/drm/panel/panel-sharp-lq101r1sx01.c
index b69f88cd15b2..654575607864 100644
--- a/drivers/gpu/drm/panel/panel-sharp-lq101r1sx01.c
+++ b/drivers/gpu/drm/panel/panel-sharp-lq101r1sx01.c
@@ -27,6 +27,7 @@ struct sharp_panel {
 
 	struct backlight_device *backlight;
 	struct regulator *supply;
+	u32 te_polarity;
 
 	bool prepared;
 	bool enabled;
@@ -280,7 +281,7 @@ static int sharp_panel_enable(struct drm_panel *panel)
 	return 0;
 }
 
-static const struct drm_display_mode default_mode = {
+static struct drm_display_mode default_mode = {
 	.clock = 278000,
 	.hdisplay = 2560,
 	.hsync_start = 2560 + 128,
@@ -297,6 +298,12 @@ static const struct drm_display_mode default_mode = {
 static int sharp_panel_get_modes(struct drm_panel *panel)
 {
 	struct drm_display_mode *mode;
+	struct sharp_panel *sharp = to_sharp_panel(panel);
+
+	if (sharp->te_polarity)
+		default_mode.flags |= DRM_MODE_FLAG_TE_POLARITY_HIGH;
+	else
+		default_mode.flags |= DRM_MODE_FLAG_TE_POLARITY_LOW;
 
 	mode = drm_mode_duplicate(panel->drm, &default_mode);
 	if (!mode) {
@@ -341,6 +348,14 @@ static int sharp_panel_add(struct sharp_panel *sharp)
 	if (IS_ERR(sharp->supply))
 		return PTR_ERR(sharp->supply);
 
+	err = of_property_read_u32(sharp->link1->dev.of_node,
+					"te-polarity", &sharp->te_polarity);
+	if (err < 0) {
+		dev_err(&sharp->link1->dev,
+			"Read te-polarity failed: %d\n", err);
+		return err;
+	}
+
 	np = of_parse_phandle(sharp->link1->dev.of_node, "backlight", 0);
 	if (np) {
 		sharp->backlight = of_find_backlight_by_node(np);
-- 
2.1.4

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

* [RFC PATCH 07/12] drm/tegra: Set NC(Non-contiguous) mode to dc for one-shot
       [not found] ` <1431308311-4470-1-git-send-email-markz-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
                     ` (5 preceding siblings ...)
  2015-05-11  1:38   ` [RFC PATCH 06/12] drm: panel: Parse "te-polarity" in Sharp lq101r1sx01 driver Mark Zhang
@ 2015-05-11  1:38   ` Mark Zhang
  2015-05-11  1:38   ` [RFC PATCH 08/12] drm/panel: Add panel func: idle/busy Mark Zhang
                     ` (4 subsequent siblings)
  11 siblings, 0 replies; 18+ messages in thread
From: Mark Zhang @ 2015-05-11  1:38 UTC (permalink / raw)
  To: thierry.reding-Re5JQEeQqe8AvxtiuMwx3w
  Cc: linux-tegra-u79uwXL29TY76Z2rM5mHXA,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

If dc is about to work in one-shot mode, we need to set dc's scan
mode to NC(Non-contiguous).
There are 2 things which can make dc send frame again:
- TE signal is received
- Driver sets the NC_HOST_TRIG_ENABLE

Signed-off-by: Mark Zhang <markz-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
---
 drivers/gpu/drm/tegra/dc.c | 43 +++++++++++++++++++++++++++++--------------
 drivers/gpu/drm/tegra/dc.h |  5 +++++
 2 files changed, 34 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c
index a287e4fec865..b88c29322c6f 100644
--- a/drivers/gpu/drm/tegra/dc.c
+++ b/drivers/gpu/drm/tegra/dc.c
@@ -1248,10 +1248,26 @@ static void tegra_crtc_mode_set_nofb(struct drm_crtc *crtc)
 		tegra_dc_writel(dc, value, DC_DISP_INTERLACE_CONTROL);
 	}
 
-	value = tegra_dc_readl(dc, DC_CMD_DISPLAY_COMMAND);
-	value &= ~DISP_CTRL_MODE_MASK;
-	value |= DISP_CTRL_MODE_C_DISPLAY;
-	tegra_dc_writel(dc, value, DC_CMD_DISPLAY_COMMAND);
+	if (mode->flags & DRM_MODE_FLAG_PREFER_ONE_SHOT) {
+		/* enable MSF & set MSF polarity */
+		value = MSF_ENABLE | MSF_LSPI;
+		if (mode->flags & DRM_MODE_FLAG_TE_POLARITY_HIGH)
+			value |= MSF_POLARITY_HIGH;
+		else
+			value |= MSF_POLARITY_LOW;
+		tegra_dc_writel(dc, value, DC_CMD_DISPLAY_COMMAND_OPTION0);
+
+		/* set non-continuous mode */
+		value = tegra_dc_readl(dc, DC_CMD_DISPLAY_COMMAND);
+		value &= ~DISP_CTRL_MODE_MASK;
+		value |= DISP_CTRL_MODE_NC_DISPLAY;
+		tegra_dc_writel(dc, value, DC_CMD_DISPLAY_COMMAND);
+	} else {
+		value = tegra_dc_readl(dc, DC_CMD_DISPLAY_COMMAND);
+		value &= ~DISP_CTRL_MODE_MASK;
+		value |= DISP_CTRL_MODE_C_DISPLAY;
+		tegra_dc_writel(dc, value, DC_CMD_DISPLAY_COMMAND);
+	}
 
 	value = tegra_dc_readl(dc, DC_CMD_DISPLAY_POWER_CONTROL);
 	value |= PW0_ENABLE | PW1_ENABLE | PW2_ENABLE | PW3_ENABLE |
@@ -1319,16 +1335,11 @@ static irqreturn_t tegra_dc_irq(int irq, void *data)
 	status = tegra_dc_readl(dc, DC_CMD_INT_STATUS);
 	tegra_dc_writel(dc, status, DC_CMD_INT_STATUS);
 
-	if (status & FRAME_END_INT) {
-		/*
-		dev_dbg(dc->dev, "%s(): frame end\n", __func__);
-		*/
-	}
+	if (status & FRAME_END_INT)
+		dev_info(dc->dev, "%s(): frame end\n", __func__);
 
 	if (status & VBLANK_INT) {
-		/*
-		dev_dbg(dc->dev, "%s(): vertical blank\n", __func__);
-		*/
+		dev_info(dc->dev, "%s(): vertical blank\n", __func__);
 		drm_crtc_handle_vblank(&dc->base);
 		tegra_dc_finish_page_flip(dc);
 	}
@@ -1339,6 +1350,9 @@ static irqreturn_t tegra_dc_irq(int irq, void *data)
 		*/
 	}
 
+	if (status & MSF_INT)
+		dev_info(dc->dev, "MSF_INT received.\n");
+
 	return IRQ_HANDLED;
 }
 
@@ -1732,10 +1746,11 @@ static int tegra_dc_init(struct host1x_client *client)
 		WINDOW_B_THRESHOLD(1) | WINDOW_C_THRESHOLD(1);
 	tegra_dc_writel(dc, value, DC_DISP_DISP_MEM_HIGH_PRIORITY_TIMER);
 
-	value = VBLANK_INT | WIN_A_UF_INT | WIN_B_UF_INT | WIN_C_UF_INT;
+	value = VBLANK_INT | WIN_A_UF_INT | WIN_B_UF_INT |
+		WIN_C_UF_INT | MSF_INT;
 	tegra_dc_writel(dc, value, DC_CMD_INT_ENABLE);
 
-	value = WIN_A_UF_INT | WIN_B_UF_INT | WIN_C_UF_INT;
+	value = WIN_A_UF_INT | WIN_B_UF_INT | WIN_C_UF_INT | MSF_INT;
 	tegra_dc_writel(dc, value, DC_CMD_INT_MASK);
 
 	if (dc->soc->supports_border_color)
diff --git a/drivers/gpu/drm/tegra/dc.h b/drivers/gpu/drm/tegra/dc.h
index 55792daabbb5..4a2d0fec5853 100644
--- a/drivers/gpu/drm/tegra/dc.h
+++ b/drivers/gpu/drm/tegra/dc.h
@@ -27,6 +27,10 @@
 #define DC_CMD_CONT_SYNCPT_VSYNC		0x028
 #define  SYNCPT_VSYNC_ENABLE (1 << 8)
 #define DC_CMD_DISPLAY_COMMAND_OPTION0		0x031
+#define MSF_ENABLE                             (1 << 1)
+#define MSF_LSPI                               (0 << 2)
+#define MSF_POLARITY_HIGH                      (0 << 0)
+#define MSF_POLARITY_LOW                       (1 << 0)
 #define DC_CMD_DISPLAY_COMMAND			0x032
 #define DISP_CTRL_MODE_STOP (0 << 5)
 #define DISP_CTRL_MODE_C_DISPLAY (1 << 5)
@@ -53,6 +57,7 @@
 #define WIN_A_UF_INT  (1 << 8)
 #define WIN_B_UF_INT  (1 << 9)
 #define WIN_C_UF_INT  (1 << 10)
+#define MSF_INT       (1 << 12)
 #define WIN_A_OF_INT  (1 << 14)
 #define WIN_B_OF_INT  (1 << 15)
 #define WIN_C_OF_INT  (1 << 16)
-- 
2.1.4

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

* [RFC PATCH 08/12] drm/panel: Add panel func: idle/busy
       [not found] ` <1431308311-4470-1-git-send-email-markz-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
                     ` (6 preceding siblings ...)
  2015-05-11  1:38   ` [RFC PATCH 07/12] drm/tegra: Set NC(Non-contiguous) mode to dc for one-shot Mark Zhang
@ 2015-05-11  1:38   ` Mark Zhang
  2015-05-11  1:38   ` [RFC PATCH 09/12] drm: dsi: Add "enter idle" & "exit idle" dcs functions Mark Zhang
                     ` (3 subsequent siblings)
  11 siblings, 0 replies; 18+ messages in thread
From: Mark Zhang @ 2015-05-11  1:38 UTC (permalink / raw)
  To: thierry.reding-Re5JQEeQqe8AvxtiuMwx3w
  Cc: linux-tegra-u79uwXL29TY76Z2rM5mHXA,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

The "idle" function of a drm panel is used to tell panel
there are no more frames coming in and it should remain the
last frame it gets.
Normally this only makes sense for smart panels which has
internal framebuffer.

The "busy" function is opposite to "idle".

Signed-off-by: Mark Zhang <markz-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
---
 include/drm/drm_panel.h | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/include/drm/drm_panel.h b/include/drm/drm_panel.h
index 13ff44b28893..0025cd020c40 100644
--- a/include/drm/drm_panel.h
+++ b/include/drm/drm_panel.h
@@ -66,6 +66,8 @@ struct display_timing;
  * the panel. This is the job of the .unprepare() function.
  */
 struct drm_panel_funcs {
+	int (*idle)(struct drm_panel *panel);
+	int (*busy)(struct drm_panel *panel);
 	int (*disable)(struct drm_panel *panel);
 	int (*unprepare)(struct drm_panel *panel);
 	int (*prepare)(struct drm_panel *panel);
@@ -85,6 +87,22 @@ struct drm_panel {
 	struct list_head list;
 };
 
+static inline int drm_panel_idle(struct drm_panel *panel)
+{
+	if (panel && panel->funcs && panel->funcs->idle)
+		return panel->funcs->idle(panel);
+
+	return panel ? -ENOSYS : -EINVAL;
+}
+
+static inline int drm_panel_busy(struct drm_panel *panel)
+{
+	if (panel && panel->funcs && panel->funcs->busy)
+		return panel->funcs->busy(panel);
+
+	return panel ? -ENOSYS : -EINVAL;
+}
+
 static inline int drm_panel_unprepare(struct drm_panel *panel)
 {
 	if (panel && panel->funcs && panel->funcs->unprepare)
-- 
2.1.4

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

* [RFC PATCH 09/12] drm: dsi: Add "enter idle" & "exit idle" dcs functions
       [not found] ` <1431308311-4470-1-git-send-email-markz-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
                     ` (7 preceding siblings ...)
  2015-05-11  1:38   ` [RFC PATCH 08/12] drm/panel: Add panel func: idle/busy Mark Zhang
@ 2015-05-11  1:38   ` Mark Zhang
  2015-05-11  1:38   ` [RFC PATCH 10/12] drm: panel: Add idle/busy in Sharp lq101r1sx01 driver Mark Zhang
                     ` (2 subsequent siblings)
  11 siblings, 0 replies; 18+ messages in thread
From: Mark Zhang @ 2015-05-11  1:38 UTC (permalink / raw)
  To: thierry.reding-Re5JQEeQqe8AvxtiuMwx3w
  Cc: linux-tegra-u79uwXL29TY76Z2rM5mHXA,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

Signed-off-by: Mark Zhang <markz-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
---
 drivers/gpu/drm/drm_mipi_dsi.c | 36 ++++++++++++++++++++++++++++++++++++
 include/drm/drm_mipi_dsi.h     |  2 ++
 2 files changed, 38 insertions(+)

diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c
index 2d5ca8eec13a..9bc6ff75eb8f 100644
--- a/drivers/gpu/drm/drm_mipi_dsi.c
+++ b/drivers/gpu/drm/drm_mipi_dsi.c
@@ -862,6 +862,42 @@ int mipi_dsi_dcs_set_pixel_format(struct mipi_dsi_device *dsi, u8 format)
 }
 EXPORT_SYMBOL(mipi_dsi_dcs_set_pixel_format);
 
+/**
+ * mipi_dsi_dcs_enter_idle_mode()
+ * @dsi: DSI peripheral device
+ *
+ * Return: 0 on success or a negative error code on failure.
+ */
+int mipi_dsi_dcs_enter_idle_mode(struct mipi_dsi_device *dsi)
+{
+	ssize_t err;
+
+	err = mipi_dsi_dcs_write(dsi, MIPI_DCS_ENTER_IDLE_MODE, NULL, 0);
+	if (err < 0)
+		return err;
+
+	return 0;
+}
+EXPORT_SYMBOL(mipi_dsi_dcs_enter_idle_mode);
+
+/**
+ * mipi_dsi_dcs_exit_idle_mode()
+ * @dsi: DSI peripheral device
+ *
+ * Return: 0 on success or a negative error code on failure.
+ */
+int mipi_dsi_dcs_exit_idle_mode(struct mipi_dsi_device *dsi)
+{
+	ssize_t err;
+
+	err = mipi_dsi_dcs_write(dsi, MIPI_DCS_EXIT_IDLE_MODE, NULL, 0);
+	if (err < 0)
+		return err;
+
+	return 0;
+}
+EXPORT_SYMBOL(mipi_dsi_dcs_exit_idle_mode);
+
 static int mipi_dsi_drv_probe(struct device *dev)
 {
 	struct mipi_dsi_driver *drv = to_mipi_dsi_driver(dev->driver);
diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h
index f1d8d0dbb4f1..d949a8ef389f 100644
--- a/include/drm/drm_mipi_dsi.h
+++ b/include/drm/drm_mipi_dsi.h
@@ -214,6 +214,8 @@ int mipi_dsi_dcs_set_tear_off(struct mipi_dsi_device *dsi);
 int mipi_dsi_dcs_set_tear_on(struct mipi_dsi_device *dsi,
 			     enum mipi_dsi_dcs_tear_mode mode);
 int mipi_dsi_dcs_set_pixel_format(struct mipi_dsi_device *dsi, u8 format);
+int mipi_dsi_dcs_enter_idle_mode(struct mipi_dsi_device *dsi);
+int mipi_dsi_dcs_exit_idle_mode(struct mipi_dsi_device *dsi);
 
 /**
  * struct mipi_dsi_driver - DSI driver
-- 
2.1.4

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

* [RFC PATCH 10/12] drm: panel: Add idle/busy in Sharp lq101r1sx01 driver
       [not found] ` <1431308311-4470-1-git-send-email-markz-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
                     ` (8 preceding siblings ...)
  2015-05-11  1:38   ` [RFC PATCH 09/12] drm: dsi: Add "enter idle" & "exit idle" dcs functions Mark Zhang
@ 2015-05-11  1:38   ` Mark Zhang
  2015-05-11  1:38   ` [RFC PATCH 11/12] drm/tegra: Suspend dc/dsi/panel in one-shot mode Mark Zhang
  2015-05-11  1:38   ` [RFC PATCH 12/12] JUST FOR TEST: Add one-shot trigger to update display Mark Zhang
  11 siblings, 0 replies; 18+ messages in thread
From: Mark Zhang @ 2015-05-11  1:38 UTC (permalink / raw)
  To: thierry.reding-Re5JQEeQqe8AvxtiuMwx3w
  Cc: linux-tegra-u79uwXL29TY76Z2rM5mHXA,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

Signed-off-by: Mark Zhang <markz-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
---
 drivers/gpu/drm/panel/panel-sharp-lq101r1sx01.c | 26 +++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/drivers/gpu/drm/panel/panel-sharp-lq101r1sx01.c b/drivers/gpu/drm/panel/panel-sharp-lq101r1sx01.c
index 654575607864..a0a7c80f23d6 100644
--- a/drivers/gpu/drm/panel/panel-sharp-lq101r1sx01.c
+++ b/drivers/gpu/drm/panel/panel-sharp-lq101r1sx01.c
@@ -90,6 +90,18 @@ static __maybe_unused int sharp_panel_read(struct sharp_panel *sharp,
 	return err;
 }
 
+static int sharp_panel_idle(struct drm_panel *panel)
+{
+	struct sharp_panel *sharp = to_sharp_panel(panel);
+	int err = 0;
+
+	err = mipi_dsi_dcs_enter_idle_mode(sharp->link1);
+	if (err < 0)
+		dev_err(panel->dev, "failed to enter idle: %d\n", err);
+
+	return err;
+}
+
 static int sharp_panel_disable(struct drm_panel *panel)
 {
 	struct sharp_panel *sharp = to_sharp_panel(panel);
@@ -168,6 +180,18 @@ static int sharp_setup_symmetrical_split(struct mipi_dsi_device *left,
 	return 0;
 }
 
+static int sharp_panel_busy(struct drm_panel *panel)
+{
+	struct sharp_panel *sharp = to_sharp_panel(panel);
+	int err = 0;
+
+	err = mipi_dsi_dcs_exit_idle_mode(sharp->link1);
+	if (err < 0)
+		dev_err(panel->dev, "failed to exit idle: %d\n", err);
+
+	return err;
+}
+
 static int sharp_panel_prepare(struct drm_panel *panel)
 {
 	struct sharp_panel *sharp = to_sharp_panel(panel);
@@ -324,6 +348,8 @@ static int sharp_panel_get_modes(struct drm_panel *panel)
 }
 
 static const struct drm_panel_funcs sharp_panel_funcs = {
+	.idle = sharp_panel_idle,
+	.busy = sharp_panel_busy,
 	.disable = sharp_panel_disable,
 	.unprepare = sharp_panel_unprepare,
 	.prepare = sharp_panel_prepare,
-- 
2.1.4

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

* [RFC PATCH 11/12] drm/tegra: Suspend dc/dsi/panel in one-shot mode
       [not found] ` <1431308311-4470-1-git-send-email-markz-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
                     ` (9 preceding siblings ...)
  2015-05-11  1:38   ` [RFC PATCH 10/12] drm: panel: Add idle/busy in Sharp lq101r1sx01 driver Mark Zhang
@ 2015-05-11  1:38   ` Mark Zhang
  2015-05-11  1:38   ` [RFC PATCH 12/12] JUST FOR TEST: Add one-shot trigger to update display Mark Zhang
  11 siblings, 0 replies; 18+ messages in thread
From: Mark Zhang @ 2015-05-11  1:38 UTC (permalink / raw)
  To: thierry.reding-Re5JQEeQqe8AvxtiuMwx3w
  Cc: linux-tegra-u79uwXL29TY76Z2rM5mHXA,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

Signed-off-by: Mark Zhang <markz-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
---
 drivers/gpu/drm/tegra/dc.c  | 34 ++++++++++++++++++++++++
 drivers/gpu/drm/tegra/drm.h |  3 +++
 drivers/gpu/drm/tegra/dsi.c | 63 +++++++++++++++++++++++++++++++++++++++++----
 3 files changed, 95 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c
index b88c29322c6f..b8231e2e3c92 100644
--- a/drivers/gpu/drm/tegra/dc.c
+++ b/drivers/gpu/drm/tegra/dc.c
@@ -1330,6 +1330,7 @@ static const struct drm_crtc_helper_funcs tegra_crtc_helper_funcs = {
 static irqreturn_t tegra_dc_irq(int irq, void *data)
 {
 	struct tegra_dc *dc = data;
+	struct drm_display_mode *mode = &dc->base.state->adjusted_mode;
 	unsigned long status;
 
 	status = tegra_dc_readl(dc, DC_CMD_INT_STATUS);
@@ -1342,6 +1343,9 @@ static irqreturn_t tegra_dc_irq(int irq, void *data)
 		dev_info(dc->dev, "%s(): vertical blank\n", __func__);
 		drm_crtc_handle_vblank(&dc->base);
 		tegra_dc_finish_page_flip(dc);
+
+		if (mode->flags & DRM_MODE_FLAG_PREFER_ONE_SHOT)
+			schedule_work(&dc->one_shot_work);
 	}
 
 	if (status & (WIN_A_UF_INT | WIN_B_UF_INT | WIN_C_UF_INT)) {
@@ -1895,6 +1899,35 @@ static int tegra_dc_parse_dt(struct tegra_dc *dc)
 	return 0;
 }
 
+static void tegra_dc_one_shot_work(struct work_struct *work)
+{
+	struct tegra_dc *dc;
+	struct drm_connector *connector;
+	struct drm_device *drm;
+
+	dc = container_of(work, struct tegra_dc, one_shot_work);
+	drm = dc->base.dev;
+
+	dev_info(dc->dev, "one-shot: Suspend encoder & connector.\n");
+	drm_modeset_lock_all(drm);
+	list_for_each_entry(connector, &drm->mode_config.connector_list, head) {
+		if (connector->funcs->dpms)
+			connector->funcs->dpms(connector,
+						DRM_MODE_DPMS_SUSPEND);
+	}
+	drm_modeset_unlock_all(drm);
+
+	dev_info(dc->dev, "one-shot: Suspend dc.\n");
+	/* Stop dc since dc doesn't have dpms functions */
+	tegra_dc_stop(dc);
+	clk_disable_unprepare(dc->clk);
+
+	/*
+	 * TODO: Powergate dc. This requires we re-init all stuffs
+	 * next time we want to trigger the one-shot.
+	 */
+}
+
 static int tegra_dc_probe(struct platform_device *pdev)
 {
 	unsigned long flags = HOST1X_SYNCPT_CLIENT_MANAGED;
@@ -1913,6 +1946,7 @@ static int tegra_dc_probe(struct platform_device *pdev)
 
 	spin_lock_init(&dc->lock);
 	INIT_LIST_HEAD(&dc->list);
+	INIT_WORK(&dc->one_shot_work, tegra_dc_one_shot_work);
 	dc->dev = &pdev->dev;
 	dc->soc = id->data;
 
diff --git a/drivers/gpu/drm/tegra/drm.h b/drivers/gpu/drm/tegra/drm.h
index 659b2fcc986d..00daf427c831 100644
--- a/drivers/gpu/drm/tegra/drm.h
+++ b/drivers/gpu/drm/tegra/drm.h
@@ -12,6 +12,7 @@
 
 #include <uapi/drm/tegra_drm.h>
 #include <linux/host1x.h>
+#include <linux/workqueue.h>
 
 #include <drm/drmP.h>
 #include <drm/drm_crtc_helper.h>
@@ -130,6 +131,8 @@ struct tegra_dc {
 	/* page-flip handling */
 	struct drm_pending_vblank_event *event;
 
+	struct work_struct one_shot_work;
+
 	const struct tegra_dc_soc_info *soc;
 
 	struct iommu_domain *domain;
diff --git a/drivers/gpu/drm/tegra/dsi.c b/drivers/gpu/drm/tegra/dsi.c
index ed970f622903..7e00279982b7 100644
--- a/drivers/gpu/drm/tegra/dsi.c
+++ b/drivers/gpu/drm/tegra/dsi.c
@@ -726,10 +726,6 @@ static void tegra_dsi_soft_reset(struct tegra_dsi *dsi)
 		tegra_dsi_soft_reset(dsi->slave);
 }
 
-static void tegra_dsi_connector_dpms(struct drm_connector *connector, int mode)
-{
-}
-
 static void tegra_dsi_connector_reset(struct drm_connector *connector)
 {
 	struct tegra_dsi_state *state;
@@ -756,7 +752,7 @@ tegra_dsi_connector_duplicate_state(struct drm_connector *connector)
 }
 
 static const struct drm_connector_funcs tegra_dsi_connector_funcs = {
-	.dpms = tegra_dsi_connector_dpms,
+	.dpms = drm_helper_connector_dpms,
 	.reset = tegra_dsi_connector_reset,
 	.detect = tegra_output_connector_detect,
 	.fill_modes = drm_helper_probe_single_connector_modes,
@@ -784,6 +780,63 @@ static const struct drm_encoder_funcs tegra_dsi_encoder_funcs = {
 
 static void tegra_dsi_encoder_dpms(struct drm_encoder *encoder, int mode)
 {
+	struct tegra_output *output = encoder_to_output(encoder);
+	struct drm_crtc *crtc = encoder->crtc;
+	struct tegra_dc *dc = to_tegra_dc(encoder->crtc);
+	struct tegra_dsi *dsi = to_dsi(output);
+	struct tegra_dsi_state *state;
+	u32 value;
+	int err;
+
+	if (mode == DRM_MODE_DPMS_SUSPEND) {
+		tegra_dsi_video_disable(dsi);
+
+		if (dc) {
+			value = tegra_dc_readl(dc, DC_DISP_DISP_WIN_OPTIONS);
+			value &= ~DSI_ENABLE;
+			tegra_dc_writel(dc, value, DC_DISP_DISP_WIN_OPTIONS);
+
+			tegra_dc_commit(dc);
+		}
+
+		err = tegra_dsi_wait_idle(dsi, 100);
+		if (err < 0)
+			dev_dbg(dsi->dev, "failed to idle DSI: %d\n", err);
+
+		tegra_dsi_soft_reset(dsi);
+
+		if (output->panel)
+			drm_panel_idle(output->panel);
+
+		tegra_dsi_disable(dsi);
+	}
+
+	if (mode == DRM_MODE_DPMS_STANDBY) {
+		state = tegra_dsi_get_state(dsi);
+
+		tegra_dsi_set_timeout(dsi, state->bclk, state->vrefresh);
+
+		/*
+		 * The D-PHY timing fields are expressed in byte-clock cycles, so
+		 * multiply the period by 8.
+		 */
+		tegra_dsi_set_phy_timing(dsi, state->period * 8, &state->timing);
+
+		if (output->panel)
+			drm_panel_busy(output->panel);
+
+		tegra_dsi_configure(dsi, dc->pipe, &crtc->mode);
+
+		/* enable display controller */
+		value = tegra_dc_readl(dc, DC_DISP_DISP_WIN_OPTIONS);
+		value |= DSI_ENABLE;
+		tegra_dc_writel(dc, value, DC_DISP_DISP_WIN_OPTIONS);
+
+		tegra_dc_commit(dc);
+
+		/* enable DSI controller */
+		tegra_dsi_enable(dsi);
+	}
 }
 
 static void tegra_dsi_encoder_prepare(struct drm_encoder *encoder)
-- 
2.1.4

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

* [RFC PATCH 12/12] JUST FOR TEST: Add one-shot trigger to update display
       [not found] ` <1431308311-4470-1-git-send-email-markz-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
                     ` (10 preceding siblings ...)
  2015-05-11  1:38   ` [RFC PATCH 11/12] drm/tegra: Suspend dc/dsi/panel in one-shot mode Mark Zhang
@ 2015-05-11  1:38   ` Mark Zhang
  11 siblings, 0 replies; 18+ messages in thread
From: Mark Zhang @ 2015-05-11  1:38 UTC (permalink / raw)
  To: thierry.reding-Re5JQEeQqe8AvxtiuMwx3w
  Cc: linux-tegra-u79uwXL29TY76Z2rM5mHXA,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

This HACK adds a workqueue to refresh the display periodically.
This is used just for testing.

Signed-off-by: Mark Zhang <markz-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
---
 drivers/gpu/drm/tegra/dc.c  | 47 +++++++++++++++++++++++++++++++++++++++++++++
 drivers/gpu/drm/tegra/drm.h |  1 +
 2 files changed, 48 insertions(+)

diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c
index b8231e2e3c92..48bddc795995 100644
--- a/drivers/gpu/drm/tegra/dc.c
+++ b/drivers/gpu/drm/tegra/dc.c
@@ -1262,6 +1262,8 @@ static void tegra_crtc_mode_set_nofb(struct drm_crtc *crtc)
 		value &= ~DISP_CTRL_MODE_MASK;
 		value |= DISP_CTRL_MODE_NC_DISPLAY;
 		tegra_dc_writel(dc, value, DC_CMD_DISPLAY_COMMAND);
+
+		schedule_work(&dc->one_shot_trigger);
 	} else {
 		value = tegra_dc_readl(dc, DC_CMD_DISPLAY_COMMAND);
 		value &= ~DISP_CTRL_MODE_MASK;
@@ -1928,6 +1930,50 @@ static void tegra_dc_one_shot_work(struct work_struct *work)
 	 */
 }
 
+static void tegra_dc_one_shot_trigger(struct work_struct *work)
+{
+	struct tegra_dc *dc;
+	struct drm_connector *connector;
+	struct drm_device *drm;
+	unsigned long update_mask = GENERAL_ACT_REQ | NC_HOST_TRIG;
+	static int first_trigger = 1;
+	int err;
+	unsigned long value;
+
+	dc = container_of(work, struct tegra_dc, one_shot_trigger);
+	drm = dc->base.dev;
+	msleep(5000);
+
+	if (first_trigger) {
+		tegra_dc_writel(dc, update_mask, DC_CMD_STATE_CONTROL);
+		first_trigger = 0;
+		schedule_work(&dc->one_shot_trigger);
+		return;
+	}
+
+	dev_info(dc->dev, "one-shot: Wakeup dsi/panel.\n");
+	err = clk_prepare_enable(dc->clk);
+	if (err < 0)
+		dev_err(dc->dev, "failed to enable clock: %d\n", err);
+
+	value = tegra_dc_readl(dc, DC_CMD_DISPLAY_COMMAND);
+	value &= ~DISP_CTRL_MODE_MASK;
+	value |= DISP_CTRL_MODE_NC_DISPLAY;
+	tegra_dc_writel(dc, value, DC_CMD_DISPLAY_COMMAND);
+
+	drm_modeset_lock_all(drm);
+	list_for_each_entry(connector, &drm->mode_config.connector_list, head) {
+		if (connector->funcs->dpms)
+			connector->funcs->dpms(connector,
+						DRM_MODE_DPMS_STANDBY);
+	}
+	drm_modeset_unlock_all(drm);
+
+	/* Trigger the one-shot */
+	tegra_dc_writel(dc, update_mask, DC_CMD_STATE_CONTROL);
+	schedule_work(&dc->one_shot_trigger);
+}
+
 static int tegra_dc_probe(struct platform_device *pdev)
 {
 	unsigned long flags = HOST1X_SYNCPT_CLIENT_MANAGED;
@@ -1947,6 +1993,7 @@ static int tegra_dc_probe(struct platform_device *pdev)
 	spin_lock_init(&dc->lock);
 	INIT_LIST_HEAD(&dc->list);
 	INIT_WORK(&dc->one_shot_work, tegra_dc_one_shot_work);
+	INIT_WORK(&dc->one_shot_trigger, tegra_dc_one_shot_trigger);
 	dc->dev = &pdev->dev;
 	dc->soc = id->data;
 
diff --git a/drivers/gpu/drm/tegra/drm.h b/drivers/gpu/drm/tegra/drm.h
index 00daf427c831..5d606cacb098 100644
--- a/drivers/gpu/drm/tegra/drm.h
+++ b/drivers/gpu/drm/tegra/drm.h
@@ -132,6 +132,7 @@ struct tegra_dc {
 	struct drm_pending_vblank_event *event;
 
 	struct work_struct one_shot_work;
+	struct work_struct one_shot_trigger;
 
 	const struct tegra_dc_soc_info *soc;
 
-- 
2.1.4

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

* Re: [RFC PATCH 01/12] drm: Add a new mode flag: DRM_MODE_FLAG_PREFER_ONE_SHOT
       [not found]     ` <1431308311-4470-2-git-send-email-markz-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
@ 2015-05-11  9:27       ` Daniel Vetter
       [not found]         ` <20150511092743.GO15256-dv86pmgwkMBes7Z6vYuT8azUEOm+Xw19@public.gmane.org>
  0 siblings, 1 reply; 18+ messages in thread
From: Daniel Vetter @ 2015-05-11  9:27 UTC (permalink / raw)
  To: Mark Zhang
  Cc: thierry.reding-Re5JQEeQqe8AvxtiuMwx3w,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

On Mon, May 11, 2015 at 09:38:20AM +0800, Mark Zhang wrote:
> Normally this flag is set by panel driver so that crtc can enable
> the "one-shot" mode(not scan frames continuously).
> 
> Signed-off-by: Mark Zhang <markz-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
> ---
>  include/uapi/drm/drm_mode.h | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h
> index dbeba949462a..5447a338e893 100644
> --- a/include/uapi/drm/drm_mode.h
> +++ b/include/uapi/drm/drm_mode.h
> @@ -72,6 +72,7 @@
>  #define  DRM_MODE_FLAG_3D_L_DEPTH_GFX_GFX_DEPTH	(6<<14)
>  #define  DRM_MODE_FLAG_3D_TOP_AND_BOTTOM	(7<<14)
>  #define  DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF	(8<<14)
> +#define DRM_MODE_FLAG_PREFER_ONE_SHOT		(1<<19)

tbh this doesn't sound like a mode flag, but something which should be
attached to the drm_panel. Especially since all the single-frame modes are
highly sink/link specific. Why was this added here instead of to the
drm_panel metadata?
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch

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

* Re: [RFC PATCH 01/12] drm: Add a new mode flag: DRM_MODE_FLAG_PREFER_ONE_SHOT
       [not found]         ` <20150511092743.GO15256-dv86pmgwkMBes7Z6vYuT8azUEOm+Xw19@public.gmane.org>
@ 2015-05-11 16:34           ` Mark Zhang
  2015-05-12  6:35             ` Daniel Vetter
  0 siblings, 1 reply; 18+ messages in thread
From: Mark Zhang @ 2015-05-11 16:34 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: thierry.reding-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org

I just want to make things easier. If we adding this in panel's meta data, it will be harder to make crtc gets this, since normally encoder talks with panel and crtc talks with encoder. But yes, adding this in panel's metadata makes more sense so if there is a better way to do that, I'm happy to do the changes.

Mark
________________________________________
From: Daniel Vetter <daniel.vetter-/w4YWyX8dFk@public.gmane.org> on behalf of Daniel Vetter <daniel-/w4YWyX8dFk@public.gmane.org>
Sent: Monday, May 11, 2015 5:27 PM
To: Mark Zhang
Cc: thierry.reding-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org; linux-tegra-u79uwXL29TY76Z2rM5mHXA@public.gmane.org; dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org
Subject: Re: [RFC PATCH 01/12] drm: Add a new mode flag: DRM_MODE_FLAG_PREFER_ONE_SHOT

On Mon, May 11, 2015 at 09:38:20AM +0800, Mark Zhang wrote:
> Normally this flag is set by panel driver so that crtc can enable
> the "one-shot" mode(not scan frames continuously).
>
> Signed-off-by: Mark Zhang <markz-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
> ---
>  include/uapi/drm/drm_mode.h | 1 +
>  1 file changed, 1 insertion(+)
>
> diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h
> index dbeba949462a..5447a338e893 100644
> --- a/include/uapi/drm/drm_mode.h
> +++ b/include/uapi/drm/drm_mode.h
> @@ -72,6 +72,7 @@
>  #define  DRM_MODE_FLAG_3D_L_DEPTH_GFX_GFX_DEPTH      (6<<14)
>  #define  DRM_MODE_FLAG_3D_TOP_AND_BOTTOM     (7<<14)
>  #define  DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF  (8<<14)
> +#define DRM_MODE_FLAG_PREFER_ONE_SHOT                (1<<19)

tbh this doesn't sound like a mode flag, but something which should be
attached to the drm_panel. Especially since all the single-frame modes are
highly sink/link specific. Why was this added here instead of to the
drm_panel metadata?
-Daniel
--
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch

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

* Re: [RFC PATCH 01/12] drm: Add a new mode flag: DRM_MODE_FLAG_PREFER_ONE_SHOT
  2015-05-11 16:34           ` Mark Zhang
@ 2015-05-12  6:35             ` Daniel Vetter
  2015-05-12  8:23               ` Thierry Reding
  0 siblings, 1 reply; 18+ messages in thread
From: Daniel Vetter @ 2015-05-12  6:35 UTC (permalink / raw)
  To: Mark Zhang; +Cc: linux-tegra@vger.kernel.org, dri-devel@lists.freedesktop.org

On Mon, May 11, 2015 at 04:34:57PM +0000, Mark Zhang wrote:
> I just want to make things easier. If we adding this in panel's meta
> data, it will be harder to make crtc gets this, since normally encoder
> talks with panel and crtc talks with encoder. But yes, adding this in
> panel's metadata makes more sense so if there is a better way to do
> that, I'm happy to do the changes.

Adding something to the userspace ABI (which you've done here) because the
kernel-internals are designed in an awkward way right now is definitely
the wrong thing to do. With atomic you can easily add a bool
prefer_oneshot to drm_crtc_state to encode this. But I fear that with the
plain crtc helpers this just doesn't work properly. You could add a
driver-private internal in drm_display_mode->private_flags, but that might
clash with drivers existing use of this field.

In any way, this is definitely not something to add to uapi headers. Hence
Nacked-by: me.

Thanks, Daniel
> 
> Mark
> ________________________________________
> From: Daniel Vetter <daniel.vetter@ffwll.ch> on behalf of Daniel Vetter <daniel@ffwll.ch>
> Sent: Monday, May 11, 2015 5:27 PM
> To: Mark Zhang
> Cc: thierry.reding@gmail.com; linux-tegra@vger.kernel.org; dri-devel@lists.freedesktop.org
> Subject: Re: [RFC PATCH 01/12] drm: Add a new mode flag: DRM_MODE_FLAG_PREFER_ONE_SHOT
> 
> On Mon, May 11, 2015 at 09:38:20AM +0800, Mark Zhang wrote:
> > Normally this flag is set by panel driver so that crtc can enable
> > the "one-shot" mode(not scan frames continuously).
> >
> > Signed-off-by: Mark Zhang <markz@nvidia.com>
> > ---
> >  include/uapi/drm/drm_mode.h | 1 +
> >  1 file changed, 1 insertion(+)
> >
> > diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h
> > index dbeba949462a..5447a338e893 100644
> > --- a/include/uapi/drm/drm_mode.h
> > +++ b/include/uapi/drm/drm_mode.h
> > @@ -72,6 +72,7 @@
> >  #define  DRM_MODE_FLAG_3D_L_DEPTH_GFX_GFX_DEPTH      (6<<14)
> >  #define  DRM_MODE_FLAG_3D_TOP_AND_BOTTOM     (7<<14)
> >  #define  DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF  (8<<14)
> > +#define DRM_MODE_FLAG_PREFER_ONE_SHOT                (1<<19)
> 
> tbh this doesn't sound like a mode flag, but something which should be
> attached to the drm_panel. Especially since all the single-frame modes are
> highly sink/link specific. Why was this added here instead of to the
> drm_panel metadata?
> -Daniel
> --
> Daniel Vetter
> Software Engineer, Intel Corporation
> http://blog.ffwll.ch

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [RFC PATCH 01/12] drm: Add a new mode flag: DRM_MODE_FLAG_PREFER_ONE_SHOT
  2015-05-12  6:35             ` Daniel Vetter
@ 2015-05-12  8:23               ` Thierry Reding
  2015-05-12 11:31                 ` Daniel Vetter
  0 siblings, 1 reply; 18+ messages in thread
From: Thierry Reding @ 2015-05-12  8:23 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: linux-tegra@vger.kernel.org, Mark Zhang,
	dri-devel@lists.freedesktop.org


[-- Attachment #1.1: Type: text/plain, Size: 3078 bytes --]

On Tue, May 12, 2015 at 08:35:58AM +0200, Daniel Vetter wrote:
> On Mon, May 11, 2015 at 04:34:57PM +0000, Mark Zhang wrote:
> > I just want to make things easier. If we adding this in panel's meta
> > data, it will be harder to make crtc gets this, since normally encoder
> > talks with panel and crtc talks with encoder. But yes, adding this in
> > panel's metadata makes more sense so if there is a better way to do
> > that, I'm happy to do the changes.
> 
> Adding something to the userspace ABI (which you've done here) because the
> kernel-internals are designed in an awkward way right now is definitely
> the wrong thing to do. With atomic you can easily add a bool
> prefer_oneshot to drm_crtc_state to encode this. But I fear that with the
> plain crtc helpers this just doesn't work properly. You could add a
> driver-private internal in drm_display_mode->private_flags, but that might
> clash with drivers existing use of this field.
> 
> In any way, this is definitely not something to add to uapi headers. Hence
> Nacked-by: me.

Are there use-cases where one-shot mode is worse than continuous mode?
I'm thinking games that run at full FPS and such. If so, exposing this
to userspace is perhaps not a bad idea, albeit not via a mode flag. If
userspace had a way to set the preference, it could do so depending on
use-case.

Thierry

> > ________________________________________
> > From: Daniel Vetter <daniel.vetter@ffwll.ch> on behalf of Daniel Vetter <daniel@ffwll.ch>
> > Sent: Monday, May 11, 2015 5:27 PM
> > To: Mark Zhang
> > Cc: thierry.reding@gmail.com; linux-tegra@vger.kernel.org; dri-devel@lists.freedesktop.org
> > Subject: Re: [RFC PATCH 01/12] drm: Add a new mode flag: DRM_MODE_FLAG_PREFER_ONE_SHOT
> > 
> > On Mon, May 11, 2015 at 09:38:20AM +0800, Mark Zhang wrote:
> > > Normally this flag is set by panel driver so that crtc can enable
> > > the "one-shot" mode(not scan frames continuously).
> > >
> > > Signed-off-by: Mark Zhang <markz@nvidia.com>
> > > ---
> > >  include/uapi/drm/drm_mode.h | 1 +
> > >  1 file changed, 1 insertion(+)
> > >
> > > diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h
> > > index dbeba949462a..5447a338e893 100644
> > > --- a/include/uapi/drm/drm_mode.h
> > > +++ b/include/uapi/drm/drm_mode.h
> > > @@ -72,6 +72,7 @@
> > >  #define  DRM_MODE_FLAG_3D_L_DEPTH_GFX_GFX_DEPTH      (6<<14)
> > >  #define  DRM_MODE_FLAG_3D_TOP_AND_BOTTOM     (7<<14)
> > >  #define  DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF  (8<<14)
> > > +#define DRM_MODE_FLAG_PREFER_ONE_SHOT                (1<<19)
> > 
> > tbh this doesn't sound like a mode flag, but something which should be
> > attached to the drm_panel. Especially since all the single-frame modes are
> > highly sink/link specific. Why was this added here instead of to the
> > drm_panel metadata?
> > -Daniel
> > --
> > Daniel Vetter
> > Software Engineer, Intel Corporation
> > http://blog.ffwll.ch
> 
> -- 
> Daniel Vetter
> Software Engineer, Intel Corporation
> http://blog.ffwll.ch

[-- Attachment #1.2: Type: application/pgp-signature, Size: 819 bytes --]

[-- Attachment #2: Type: text/plain, Size: 159 bytes --]

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [RFC PATCH 01/12] drm: Add a new mode flag: DRM_MODE_FLAG_PREFER_ONE_SHOT
  2015-05-12  8:23               ` Thierry Reding
@ 2015-05-12 11:31                 ` Daniel Vetter
  0 siblings, 0 replies; 18+ messages in thread
From: Daniel Vetter @ 2015-05-12 11:31 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Mark Zhang, linux-tegra-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org

On Tue, May 12, 2015 at 10:23 AM, Thierry Reding
<thierry.reding-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
> On Tue, May 12, 2015 at 08:35:58AM +0200, Daniel Vetter wrote:
>> On Mon, May 11, 2015 at 04:34:57PM +0000, Mark Zhang wrote:
>> > I just want to make things easier. If we adding this in panel's meta
>> > data, it will be harder to make crtc gets this, since normally encoder
>> > talks with panel and crtc talks with encoder. But yes, adding this in
>> > panel's metadata makes more sense so if there is a better way to do
>> > that, I'm happy to do the changes.
>>
>> Adding something to the userspace ABI (which you've done here) because the
>> kernel-internals are designed in an awkward way right now is definitely
>> the wrong thing to do. With atomic you can easily add a bool
>> prefer_oneshot to drm_crtc_state to encode this. But I fear that with the
>> plain crtc helpers this just doesn't work properly. You could add a
>> driver-private internal in drm_display_mode->private_flags, but that might
>> clash with drivers existing use of this field.
>>
>> In any way, this is definitely not something to add to uapi headers. Hence
>> Nacked-by: me.
>
> Are there use-cases where one-shot mode is worse than continuous mode?
> I'm thinking games that run at full FPS and such. If so, exposing this
> to userspace is perhaps not a bad idea, albeit not via a mode flag. If
> userspace had a way to set the preference, it could do so depending on
> use-case.

If you have a case with jitter when the pageflips run at not-quite
60fps (just an example) then I think the kernel should cope with that
by disabling oneshot mode on its own. At least that's what i915 does.
Different story once we'll get variable refresh-rate support, but I
think that's an entirely different beast.

Also we don't need this as a mode flag, an atomic prop seems better
suited. Especially since the atomic prop avoids the mode_changed logic
of the helpers (which we want, no need to flicker when updating such a
hint), wheres anything that changes the mode will force a full modeset
by default.

Also if you expose this to userspace, you need userspace to use it
before merging.

drm_display_mode->private_flags still looks like the most suitable place.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch

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

end of thread, other threads:[~2015-05-12 11:31 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-05-11  1:38 [RFC PATCH 00/12] Tegra: Add DC one-shot support Mark Zhang
     [not found] ` <1431308311-4470-1-git-send-email-markz-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2015-05-11  1:38   ` [RFC PATCH 01/12] drm: Add a new mode flag: DRM_MODE_FLAG_PREFER_ONE_SHOT Mark Zhang
     [not found]     ` <1431308311-4470-2-git-send-email-markz-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2015-05-11  9:27       ` Daniel Vetter
     [not found]         ` <20150511092743.GO15256-dv86pmgwkMBes7Z6vYuT8azUEOm+Xw19@public.gmane.org>
2015-05-11 16:34           ` Mark Zhang
2015-05-12  6:35             ` Daniel Vetter
2015-05-12  8:23               ` Thierry Reding
2015-05-12 11:31                 ` Daniel Vetter
2015-05-11  1:38   ` [RFC PATCH 02/12] drm: panel: Add one-shot flag to Sharp lq101r1sx01 driver Mark Zhang
2015-05-11  1:38   ` [RFC PATCH 03/12] drm: panel: Turn on TE(Tearing Effect) on Sharp lq101r1sx01 Mark Zhang
2015-05-11  1:38   ` [RFC PATCH 04/12] drm: Add DRM mode flag TE polarity Mark Zhang
2015-05-11  1:38   ` [RFC PATCH 05/12] dt: panel: Add property "te-polarity" Mark Zhang
2015-05-11  1:38   ` [RFC PATCH 06/12] drm: panel: Parse "te-polarity" in Sharp lq101r1sx01 driver Mark Zhang
2015-05-11  1:38   ` [RFC PATCH 07/12] drm/tegra: Set NC(Non-contiguous) mode to dc for one-shot Mark Zhang
2015-05-11  1:38   ` [RFC PATCH 08/12] drm/panel: Add panel func: idle/busy Mark Zhang
2015-05-11  1:38   ` [RFC PATCH 09/12] drm: dsi: Add "enter idle" & "exit idle" dcs functions Mark Zhang
2015-05-11  1:38   ` [RFC PATCH 10/12] drm: panel: Add idle/busy in Sharp lq101r1sx01 driver Mark Zhang
2015-05-11  1:38   ` [RFC PATCH 11/12] drm/tegra: Suspend dc/dsi/panel in one-shot mode Mark Zhang
2015-05-11  1:38   ` [RFC PATCH 12/12] JUST FOR TEST: Add one-shot trigger to update display Mark Zhang

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).