All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 0/8] drm/rockchip: covert to support atomic API
@ 2015-12-17  3:01 ` Mark Yao
  0 siblings, 0 replies; 51+ messages in thread
From: Mark Yao @ 2015-12-17  3:01 UTC (permalink / raw)
  To: David Airlie, Heiko Stuebner, dri-devel, linux-arm-kernel,
	linux-rockchip, linux-kernel
  Cc: Mark Yao

The series of patches coverting drm rockchip to atomic API, do some
cleanup and some fixes on atomic side.

TODO: fence is not support on current version.

Tested on rk3288 popmetal board.

All guys can test it with following url:
 test case: https://github.com/markyzq/libdrm.git atomictest
 kernel:
  https://github.com/markyzq/kernel-drm-rockchip.git drm-rockchip-next-12-17

Changes in v3:
Reported by kbuild test robot
- fix rockchip_crtc_wait_for_update undefined when build drm rockchip as modules.

Changes in v2:
- Optimization commit planes sequence.
- Get vblank count on atomic_begin to protect vblank event.
Advised by Daniel Stone
- Direct return -EINVAL when yuv address is not support, instead of adjust it.
- code formating and cleanup.
Advised by Thierry Reding & Daniel Vetter
- Hook mode_set into crtc enable instead of hack crtc enable on mode set.

v2: http://www.spinics.net/lists/arm-kernel/msg468423.html
v1: http://lists.freedesktop.org/archives/dri-devel/2015-November/095745.html

Mark Yao (8):
  drm/rockchip: Use new vblank api drm_crtc_vblank_*
  drm/rockchip: vop: replace dpms with enable/disable
  drm/rockchip: Convert to support atomic API
  drm/rockchip: Optimization vop mode set
  drm/rockchip: support atomic asynchronous commit
  drm/rockchip: direct config connecter gate and out_mode
  drm: bridge/dw_hdmi: add atomic API support
  drm/rockchip: dw_hdmi: use encoder enable function

 drivers/gpu/drm/bridge/dw_hdmi.c            |   23 +-
 drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c |   14 +-
 drivers/gpu/drm/rockchip/rockchip_drm_drv.c |   21 +-
 drivers/gpu/drm/rockchip/rockchip_drm_drv.h |   20 +-
 drivers/gpu/drm/rockchip/rockchip_drm_fb.c  |  123 +++++
 drivers/gpu/drm/rockchip/rockchip_drm_vop.c |  782 +++++++++++----------------
 6 files changed, 495 insertions(+), 488 deletions(-)

-- 
1.7.9.5



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

* [PATCH v3 0/8] drm/rockchip: covert to support atomic API
@ 2015-12-17  3:01 ` Mark Yao
  0 siblings, 0 replies; 51+ messages in thread
From: Mark Yao @ 2015-12-17  3:01 UTC (permalink / raw)
  To: David Airlie, Heiko Stuebner, dri-devel, linux-arm-kernel,
	linux-rockchip, linux-kernel

The series of patches coverting drm rockchip to atomic API, do some
cleanup and some fixes on atomic side.

TODO: fence is not support on current version.

Tested on rk3288 popmetal board.

All guys can test it with following url:
 test case: https://github.com/markyzq/libdrm.git atomictest
 kernel:
  https://github.com/markyzq/kernel-drm-rockchip.git drm-rockchip-next-12-17

Changes in v3:
Reported by kbuild test robot
- fix rockchip_crtc_wait_for_update undefined when build drm rockchip as modules.

Changes in v2:
- Optimization commit planes sequence.
- Get vblank count on atomic_begin to protect vblank event.
Advised by Daniel Stone
- Direct return -EINVAL when yuv address is not support, instead of adjust it.
- code formating and cleanup.
Advised by Thierry Reding & Daniel Vetter
- Hook mode_set into crtc enable instead of hack crtc enable on mode set.

v2: http://www.spinics.net/lists/arm-kernel/msg468423.html
v1: http://lists.freedesktop.org/archives/dri-devel/2015-November/095745.html

Mark Yao (8):
  drm/rockchip: Use new vblank api drm_crtc_vblank_*
  drm/rockchip: vop: replace dpms with enable/disable
  drm/rockchip: Convert to support atomic API
  drm/rockchip: Optimization vop mode set
  drm/rockchip: support atomic asynchronous commit
  drm/rockchip: direct config connecter gate and out_mode
  drm: bridge/dw_hdmi: add atomic API support
  drm/rockchip: dw_hdmi: use encoder enable function

 drivers/gpu/drm/bridge/dw_hdmi.c            |   23 +-
 drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c |   14 +-
 drivers/gpu/drm/rockchip/rockchip_drm_drv.c |   21 +-
 drivers/gpu/drm/rockchip/rockchip_drm_drv.h |   20 +-
 drivers/gpu/drm/rockchip/rockchip_drm_fb.c  |  123 +++++
 drivers/gpu/drm/rockchip/rockchip_drm_vop.c |  782 +++++++++++----------------
 6 files changed, 495 insertions(+), 488 deletions(-)

-- 
1.7.9.5


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

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

* [PATCH v3 0/8] drm/rockchip: covert to support atomic API
@ 2015-12-17  3:01 ` Mark Yao
  0 siblings, 0 replies; 51+ messages in thread
From: Mark Yao @ 2015-12-17  3:01 UTC (permalink / raw)
  To: linux-arm-kernel

The series of patches coverting drm rockchip to atomic API, do some
cleanup and some fixes on atomic side.

TODO: fence is not support on current version.

Tested on rk3288 popmetal board.

All guys can test it with following url:
 test case: https://github.com/markyzq/libdrm.git atomictest
 kernel:
  https://github.com/markyzq/kernel-drm-rockchip.git drm-rockchip-next-12-17

Changes in v3:
Reported by kbuild test robot
- fix rockchip_crtc_wait_for_update undefined when build drm rockchip as modules.

Changes in v2:
- Optimization commit planes sequence.
- Get vblank count on atomic_begin to protect vblank event.
Advised by Daniel Stone
- Direct return -EINVAL when yuv address is not support, instead of adjust it.
- code formating and cleanup.
Advised by Thierry Reding & Daniel Vetter
- Hook mode_set into crtc enable instead of hack crtc enable on mode set.

v2: http://www.spinics.net/lists/arm-kernel/msg468423.html
v1: http://lists.freedesktop.org/archives/dri-devel/2015-November/095745.html

Mark Yao (8):
  drm/rockchip: Use new vblank api drm_crtc_vblank_*
  drm/rockchip: vop: replace dpms with enable/disable
  drm/rockchip: Convert to support atomic API
  drm/rockchip: Optimization vop mode set
  drm/rockchip: support atomic asynchronous commit
  drm/rockchip: direct config connecter gate and out_mode
  drm: bridge/dw_hdmi: add atomic API support
  drm/rockchip: dw_hdmi: use encoder enable function

 drivers/gpu/drm/bridge/dw_hdmi.c            |   23 +-
 drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c |   14 +-
 drivers/gpu/drm/rockchip/rockchip_drm_drv.c |   21 +-
 drivers/gpu/drm/rockchip/rockchip_drm_drv.h |   20 +-
 drivers/gpu/drm/rockchip/rockchip_drm_fb.c  |  123 +++++
 drivers/gpu/drm/rockchip/rockchip_drm_vop.c |  782 +++++++++++----------------
 6 files changed, 495 insertions(+), 488 deletions(-)

-- 
1.7.9.5

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

* [PATCH v3 1/8] drm/rockchip: Use new vblank api drm_crtc_vblank_*
  2015-12-17  3:01 ` Mark Yao
  (?)
@ 2015-12-17  3:01   ` Mark Yao
  -1 siblings, 0 replies; 51+ messages in thread
From: Mark Yao @ 2015-12-17  3:01 UTC (permalink / raw)
  To: David Airlie, Heiko Stuebner, dri-devel, linux-arm-kernel,
	linux-rockchip, linux-kernel
  Cc: Mark Yao

No functional update, drm_vblank_* is the legacy version of
drm_crtc_vblank_*. and use new api make driver more clean.

Signed-off-by: Mark Yao <mark.yao@rock-chips.com>
---
Changes in v3: None
Changes in v2: None

 drivers/gpu/drm/rockchip/rockchip_drm_drv.c |   13 +++++++------
 drivers/gpu/drm/rockchip/rockchip_drm_drv.h |    7 +++----
 drivers/gpu/drm/rockchip/rockchip_drm_vop.c |   24 +++++++++++-------------
 3 files changed, 21 insertions(+), 23 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
index f22e1e1..cfd9b83 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
@@ -64,11 +64,11 @@ void rockchip_drm_dma_detach_device(struct drm_device *drm_dev,
 }
 EXPORT_SYMBOL_GPL(rockchip_drm_dma_detach_device);
 
-int rockchip_register_crtc_funcs(struct drm_device *dev,
-				 const struct rockchip_crtc_funcs *crtc_funcs,
-				 int pipe)
+int rockchip_register_crtc_funcs(struct drm_crtc *crtc,
+				 const struct rockchip_crtc_funcs *crtc_funcs)
 {
-	struct rockchip_drm_private *priv = dev->dev_private;
+	int pipe = drm_crtc_index(crtc);
+	struct rockchip_drm_private *priv = crtc->dev->dev_private;
 
 	if (pipe > ROCKCHIP_MAX_CRTC)
 		return -EINVAL;
@@ -79,9 +79,10 @@ int rockchip_register_crtc_funcs(struct drm_device *dev,
 }
 EXPORT_SYMBOL_GPL(rockchip_register_crtc_funcs);
 
-void rockchip_unregister_crtc_funcs(struct drm_device *dev, int pipe)
+void rockchip_unregister_crtc_funcs(struct drm_crtc *crtc)
 {
-	struct rockchip_drm_private *priv = dev->dev_private;
+	int pipe = drm_crtc_index(crtc);
+	struct rockchip_drm_private *priv = crtc->dev->dev_private;
 
 	if (pipe > ROCKCHIP_MAX_CRTC)
 		return;
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
index dc4e5f0..069d6d4 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
@@ -52,10 +52,9 @@ struct rockchip_drm_private {
 	const struct rockchip_crtc_funcs *crtc_funcs[ROCKCHIP_MAX_CRTC];
 };
 
-int rockchip_register_crtc_funcs(struct drm_device *dev,
-				 const struct rockchip_crtc_funcs *crtc_funcs,
-				 int pipe);
-void rockchip_unregister_crtc_funcs(struct drm_device *dev, int pipe);
+int rockchip_register_crtc_funcs(struct drm_crtc *crtc,
+				 const struct rockchip_crtc_funcs *crtc_funcs);
+void rockchip_unregister_crtc_funcs(struct drm_crtc *crtc);
 int rockchip_drm_encoder_get_mux_id(struct device_node *node,
 				    struct drm_encoder *encoder);
 int rockchip_drm_crtc_mode_config(struct drm_crtc *crtc, int connector_type,
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index dd8e086..f82c7ba 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -119,8 +119,6 @@ struct vop {
 	/* vop dclk reset */
 	struct reset_control *dclk_rst;
 
-	int pipe;
-
 	struct vop_win win[];
 };
 
@@ -692,7 +690,7 @@ static void vop_enable(struct drm_crtc *crtc)
 
 	enable_irq(vop->irq);
 
-	drm_vblank_on(vop->drm_dev, vop->pipe);
+	drm_crtc_vblank_on(crtc);
 
 	return;
 
@@ -711,7 +709,7 @@ static void vop_disable(struct drm_crtc *crtc)
 	if (!vop->is_enabled)
 		return;
 
-	drm_vblank_off(crtc->dev, vop->pipe);
+	drm_crtc_vblank_off(crtc);
 
 	/*
 	 * Vop standby will take effect at end of current frame,
@@ -918,7 +916,7 @@ static int vop_update_plane_event(struct drm_plane *plane,
 	 */
 	mutex_lock(&vop->vsync_mutex);
 	if (fb != vop_win_last_pending_fb(vop_win)) {
-		ret = drm_vblank_get(plane->dev, vop->pipe);
+		ret = drm_crtc_vblank_get(crtc);
 		if (ret) {
 			DRM_ERROR("failed to get vblank, %d\n", ret);
 			mutex_unlock(&vop->vsync_mutex);
@@ -929,7 +927,7 @@ static int vop_update_plane_event(struct drm_plane *plane,
 
 		ret = vop_win_queue_fb(vop_win, fb, yrgb_mst, event);
 		if (ret) {
-			drm_vblank_put(plane->dev, vop->pipe);
+			drm_crtc_vblank_put(crtc);
 			mutex_unlock(&vop->vsync_mutex);
 			return ret;
 		}
@@ -1023,7 +1021,7 @@ static int vop_disable_plane(struct drm_plane *plane)
 
 	vop = to_vop(plane->crtc);
 
-	ret = drm_vblank_get(plane->dev, vop->pipe);
+	ret = drm_crtc_vblank_get(plane->crtc);
 	if (ret) {
 		DRM_ERROR("failed to get vblank, %d\n", ret);
 		return ret;
@@ -1033,7 +1031,7 @@ static int vop_disable_plane(struct drm_plane *plane)
 
 	ret = vop_win_queue_fb(vop_win, NULL, 0, NULL);
 	if (ret) {
-		drm_vblank_put(plane->dev, vop->pipe);
+		drm_crtc_vblank_put(plane->crtc);
 		mutex_unlock(&vop->vsync_mutex);
 		return ret;
 	}
@@ -1295,7 +1293,7 @@ static void vop_win_state_complete(struct vop_win *vop_win,
 	}
 
 	list_del(&state->head);
-	drm_vblank_put(crtc->dev, vop->pipe);
+	drm_crtc_vblank_put(crtc);
 }
 
 static void vop_crtc_destroy(struct drm_crtc *crtc)
@@ -1410,6 +1408,7 @@ done:
 static irqreturn_t vop_isr(int irq, void *data)
 {
 	struct vop *vop = data;
+	struct drm_crtc *crtc = &vop->crtc;
 	uint32_t intr0_reg, active_irqs;
 	unsigned long flags;
 	int ret = IRQ_NONE;
@@ -1438,7 +1437,7 @@ static irqreturn_t vop_isr(int irq, void *data)
 	}
 
 	if (active_irqs & FS_INTR) {
-		drm_handle_vblank(vop->drm_dev, vop->pipe);
+		drm_crtc_handle_vblank(crtc);
 		active_irqs &= ~FS_INTR;
 		ret = (vop->vsync_work_pending) ? IRQ_WAKE_THREAD : IRQ_HANDLED;
 	}
@@ -1531,8 +1530,7 @@ static int vop_create_crtc(struct vop *vop)
 
 	init_completion(&vop->dsp_hold_completion);
 	crtc->port = port;
-	vop->pipe = drm_crtc_index(crtc);
-	rockchip_register_crtc_funcs(drm_dev, &private_crtc_funcs, vop->pipe);
+	rockchip_register_crtc_funcs(crtc, &private_crtc_funcs);
 
 	return 0;
 
@@ -1548,7 +1546,7 @@ static void vop_destroy_crtc(struct vop *vop)
 {
 	struct drm_crtc *crtc = &vop->crtc;
 
-	rockchip_unregister_crtc_funcs(vop->drm_dev, vop->pipe);
+	rockchip_unregister_crtc_funcs(crtc);
 	of_node_put(crtc->port);
 	drm_crtc_cleanup(crtc);
 }
-- 
1.7.9.5



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

* [PATCH v3 1/8] drm/rockchip: Use new vblank api drm_crtc_vblank_*
@ 2015-12-17  3:01   ` Mark Yao
  0 siblings, 0 replies; 51+ messages in thread
From: Mark Yao @ 2015-12-17  3:01 UTC (permalink / raw)
  To: David Airlie, Heiko Stuebner, dri-devel, linux-arm-kernel,
	linux-rockchip, linux-kernel

No functional update, drm_vblank_* is the legacy version of
drm_crtc_vblank_*. and use new api make driver more clean.

Signed-off-by: Mark Yao <mark.yao@rock-chips.com>
---
Changes in v3: None
Changes in v2: None

 drivers/gpu/drm/rockchip/rockchip_drm_drv.c |   13 +++++++------
 drivers/gpu/drm/rockchip/rockchip_drm_drv.h |    7 +++----
 drivers/gpu/drm/rockchip/rockchip_drm_vop.c |   24 +++++++++++-------------
 3 files changed, 21 insertions(+), 23 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
index f22e1e1..cfd9b83 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
@@ -64,11 +64,11 @@ void rockchip_drm_dma_detach_device(struct drm_device *drm_dev,
 }
 EXPORT_SYMBOL_GPL(rockchip_drm_dma_detach_device);
 
-int rockchip_register_crtc_funcs(struct drm_device *dev,
-				 const struct rockchip_crtc_funcs *crtc_funcs,
-				 int pipe)
+int rockchip_register_crtc_funcs(struct drm_crtc *crtc,
+				 const struct rockchip_crtc_funcs *crtc_funcs)
 {
-	struct rockchip_drm_private *priv = dev->dev_private;
+	int pipe = drm_crtc_index(crtc);
+	struct rockchip_drm_private *priv = crtc->dev->dev_private;
 
 	if (pipe > ROCKCHIP_MAX_CRTC)
 		return -EINVAL;
@@ -79,9 +79,10 @@ int rockchip_register_crtc_funcs(struct drm_device *dev,
 }
 EXPORT_SYMBOL_GPL(rockchip_register_crtc_funcs);
 
-void rockchip_unregister_crtc_funcs(struct drm_device *dev, int pipe)
+void rockchip_unregister_crtc_funcs(struct drm_crtc *crtc)
 {
-	struct rockchip_drm_private *priv = dev->dev_private;
+	int pipe = drm_crtc_index(crtc);
+	struct rockchip_drm_private *priv = crtc->dev->dev_private;
 
 	if (pipe > ROCKCHIP_MAX_CRTC)
 		return;
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
index dc4e5f0..069d6d4 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
@@ -52,10 +52,9 @@ struct rockchip_drm_private {
 	const struct rockchip_crtc_funcs *crtc_funcs[ROCKCHIP_MAX_CRTC];
 };
 
-int rockchip_register_crtc_funcs(struct drm_device *dev,
-				 const struct rockchip_crtc_funcs *crtc_funcs,
-				 int pipe);
-void rockchip_unregister_crtc_funcs(struct drm_device *dev, int pipe);
+int rockchip_register_crtc_funcs(struct drm_crtc *crtc,
+				 const struct rockchip_crtc_funcs *crtc_funcs);
+void rockchip_unregister_crtc_funcs(struct drm_crtc *crtc);
 int rockchip_drm_encoder_get_mux_id(struct device_node *node,
 				    struct drm_encoder *encoder);
 int rockchip_drm_crtc_mode_config(struct drm_crtc *crtc, int connector_type,
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index dd8e086..f82c7ba 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -119,8 +119,6 @@ struct vop {
 	/* vop dclk reset */
 	struct reset_control *dclk_rst;
 
-	int pipe;
-
 	struct vop_win win[];
 };
 
@@ -692,7 +690,7 @@ static void vop_enable(struct drm_crtc *crtc)
 
 	enable_irq(vop->irq);
 
-	drm_vblank_on(vop->drm_dev, vop->pipe);
+	drm_crtc_vblank_on(crtc);
 
 	return;
 
@@ -711,7 +709,7 @@ static void vop_disable(struct drm_crtc *crtc)
 	if (!vop->is_enabled)
 		return;
 
-	drm_vblank_off(crtc->dev, vop->pipe);
+	drm_crtc_vblank_off(crtc);
 
 	/*
 	 * Vop standby will take effect at end of current frame,
@@ -918,7 +916,7 @@ static int vop_update_plane_event(struct drm_plane *plane,
 	 */
 	mutex_lock(&vop->vsync_mutex);
 	if (fb != vop_win_last_pending_fb(vop_win)) {
-		ret = drm_vblank_get(plane->dev, vop->pipe);
+		ret = drm_crtc_vblank_get(crtc);
 		if (ret) {
 			DRM_ERROR("failed to get vblank, %d\n", ret);
 			mutex_unlock(&vop->vsync_mutex);
@@ -929,7 +927,7 @@ static int vop_update_plane_event(struct drm_plane *plane,
 
 		ret = vop_win_queue_fb(vop_win, fb, yrgb_mst, event);
 		if (ret) {
-			drm_vblank_put(plane->dev, vop->pipe);
+			drm_crtc_vblank_put(crtc);
 			mutex_unlock(&vop->vsync_mutex);
 			return ret;
 		}
@@ -1023,7 +1021,7 @@ static int vop_disable_plane(struct drm_plane *plane)
 
 	vop = to_vop(plane->crtc);
 
-	ret = drm_vblank_get(plane->dev, vop->pipe);
+	ret = drm_crtc_vblank_get(plane->crtc);
 	if (ret) {
 		DRM_ERROR("failed to get vblank, %d\n", ret);
 		return ret;
@@ -1033,7 +1031,7 @@ static int vop_disable_plane(struct drm_plane *plane)
 
 	ret = vop_win_queue_fb(vop_win, NULL, 0, NULL);
 	if (ret) {
-		drm_vblank_put(plane->dev, vop->pipe);
+		drm_crtc_vblank_put(plane->crtc);
 		mutex_unlock(&vop->vsync_mutex);
 		return ret;
 	}
@@ -1295,7 +1293,7 @@ static void vop_win_state_complete(struct vop_win *vop_win,
 	}
 
 	list_del(&state->head);
-	drm_vblank_put(crtc->dev, vop->pipe);
+	drm_crtc_vblank_put(crtc);
 }
 
 static void vop_crtc_destroy(struct drm_crtc *crtc)
@@ -1410,6 +1408,7 @@ done:
 static irqreturn_t vop_isr(int irq, void *data)
 {
 	struct vop *vop = data;
+	struct drm_crtc *crtc = &vop->crtc;
 	uint32_t intr0_reg, active_irqs;
 	unsigned long flags;
 	int ret = IRQ_NONE;
@@ -1438,7 +1437,7 @@ static irqreturn_t vop_isr(int irq, void *data)
 	}
 
 	if (active_irqs & FS_INTR) {
-		drm_handle_vblank(vop->drm_dev, vop->pipe);
+		drm_crtc_handle_vblank(crtc);
 		active_irqs &= ~FS_INTR;
 		ret = (vop->vsync_work_pending) ? IRQ_WAKE_THREAD : IRQ_HANDLED;
 	}
@@ -1531,8 +1530,7 @@ static int vop_create_crtc(struct vop *vop)
 
 	init_completion(&vop->dsp_hold_completion);
 	crtc->port = port;
-	vop->pipe = drm_crtc_index(crtc);
-	rockchip_register_crtc_funcs(drm_dev, &private_crtc_funcs, vop->pipe);
+	rockchip_register_crtc_funcs(crtc, &private_crtc_funcs);
 
 	return 0;
 
@@ -1548,7 +1546,7 @@ static void vop_destroy_crtc(struct vop *vop)
 {
 	struct drm_crtc *crtc = &vop->crtc;
 
-	rockchip_unregister_crtc_funcs(vop->drm_dev, vop->pipe);
+	rockchip_unregister_crtc_funcs(crtc);
 	of_node_put(crtc->port);
 	drm_crtc_cleanup(crtc);
 }
-- 
1.7.9.5


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

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

* [PATCH v3 1/8] drm/rockchip: Use new vblank api drm_crtc_vblank_*
@ 2015-12-17  3:01   ` Mark Yao
  0 siblings, 0 replies; 51+ messages in thread
From: Mark Yao @ 2015-12-17  3:01 UTC (permalink / raw)
  To: linux-arm-kernel

No functional update, drm_vblank_* is the legacy version of
drm_crtc_vblank_*. and use new api make driver more clean.

Signed-off-by: Mark Yao <mark.yao@rock-chips.com>
---
Changes in v3: None
Changes in v2: None

 drivers/gpu/drm/rockchip/rockchip_drm_drv.c |   13 +++++++------
 drivers/gpu/drm/rockchip/rockchip_drm_drv.h |    7 +++----
 drivers/gpu/drm/rockchip/rockchip_drm_vop.c |   24 +++++++++++-------------
 3 files changed, 21 insertions(+), 23 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
index f22e1e1..cfd9b83 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
@@ -64,11 +64,11 @@ void rockchip_drm_dma_detach_device(struct drm_device *drm_dev,
 }
 EXPORT_SYMBOL_GPL(rockchip_drm_dma_detach_device);
 
-int rockchip_register_crtc_funcs(struct drm_device *dev,
-				 const struct rockchip_crtc_funcs *crtc_funcs,
-				 int pipe)
+int rockchip_register_crtc_funcs(struct drm_crtc *crtc,
+				 const struct rockchip_crtc_funcs *crtc_funcs)
 {
-	struct rockchip_drm_private *priv = dev->dev_private;
+	int pipe = drm_crtc_index(crtc);
+	struct rockchip_drm_private *priv = crtc->dev->dev_private;
 
 	if (pipe > ROCKCHIP_MAX_CRTC)
 		return -EINVAL;
@@ -79,9 +79,10 @@ int rockchip_register_crtc_funcs(struct drm_device *dev,
 }
 EXPORT_SYMBOL_GPL(rockchip_register_crtc_funcs);
 
-void rockchip_unregister_crtc_funcs(struct drm_device *dev, int pipe)
+void rockchip_unregister_crtc_funcs(struct drm_crtc *crtc)
 {
-	struct rockchip_drm_private *priv = dev->dev_private;
+	int pipe = drm_crtc_index(crtc);
+	struct rockchip_drm_private *priv = crtc->dev->dev_private;
 
 	if (pipe > ROCKCHIP_MAX_CRTC)
 		return;
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
index dc4e5f0..069d6d4 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
@@ -52,10 +52,9 @@ struct rockchip_drm_private {
 	const struct rockchip_crtc_funcs *crtc_funcs[ROCKCHIP_MAX_CRTC];
 };
 
-int rockchip_register_crtc_funcs(struct drm_device *dev,
-				 const struct rockchip_crtc_funcs *crtc_funcs,
-				 int pipe);
-void rockchip_unregister_crtc_funcs(struct drm_device *dev, int pipe);
+int rockchip_register_crtc_funcs(struct drm_crtc *crtc,
+				 const struct rockchip_crtc_funcs *crtc_funcs);
+void rockchip_unregister_crtc_funcs(struct drm_crtc *crtc);
 int rockchip_drm_encoder_get_mux_id(struct device_node *node,
 				    struct drm_encoder *encoder);
 int rockchip_drm_crtc_mode_config(struct drm_crtc *crtc, int connector_type,
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index dd8e086..f82c7ba 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -119,8 +119,6 @@ struct vop {
 	/* vop dclk reset */
 	struct reset_control *dclk_rst;
 
-	int pipe;
-
 	struct vop_win win[];
 };
 
@@ -692,7 +690,7 @@ static void vop_enable(struct drm_crtc *crtc)
 
 	enable_irq(vop->irq);
 
-	drm_vblank_on(vop->drm_dev, vop->pipe);
+	drm_crtc_vblank_on(crtc);
 
 	return;
 
@@ -711,7 +709,7 @@ static void vop_disable(struct drm_crtc *crtc)
 	if (!vop->is_enabled)
 		return;
 
-	drm_vblank_off(crtc->dev, vop->pipe);
+	drm_crtc_vblank_off(crtc);
 
 	/*
 	 * Vop standby will take effect at end of current frame,
@@ -918,7 +916,7 @@ static int vop_update_plane_event(struct drm_plane *plane,
 	 */
 	mutex_lock(&vop->vsync_mutex);
 	if (fb != vop_win_last_pending_fb(vop_win)) {
-		ret = drm_vblank_get(plane->dev, vop->pipe);
+		ret = drm_crtc_vblank_get(crtc);
 		if (ret) {
 			DRM_ERROR("failed to get vblank, %d\n", ret);
 			mutex_unlock(&vop->vsync_mutex);
@@ -929,7 +927,7 @@ static int vop_update_plane_event(struct drm_plane *plane,
 
 		ret = vop_win_queue_fb(vop_win, fb, yrgb_mst, event);
 		if (ret) {
-			drm_vblank_put(plane->dev, vop->pipe);
+			drm_crtc_vblank_put(crtc);
 			mutex_unlock(&vop->vsync_mutex);
 			return ret;
 		}
@@ -1023,7 +1021,7 @@ static int vop_disable_plane(struct drm_plane *plane)
 
 	vop = to_vop(plane->crtc);
 
-	ret = drm_vblank_get(plane->dev, vop->pipe);
+	ret = drm_crtc_vblank_get(plane->crtc);
 	if (ret) {
 		DRM_ERROR("failed to get vblank, %d\n", ret);
 		return ret;
@@ -1033,7 +1031,7 @@ static int vop_disable_plane(struct drm_plane *plane)
 
 	ret = vop_win_queue_fb(vop_win, NULL, 0, NULL);
 	if (ret) {
-		drm_vblank_put(plane->dev, vop->pipe);
+		drm_crtc_vblank_put(plane->crtc);
 		mutex_unlock(&vop->vsync_mutex);
 		return ret;
 	}
@@ -1295,7 +1293,7 @@ static void vop_win_state_complete(struct vop_win *vop_win,
 	}
 
 	list_del(&state->head);
-	drm_vblank_put(crtc->dev, vop->pipe);
+	drm_crtc_vblank_put(crtc);
 }
 
 static void vop_crtc_destroy(struct drm_crtc *crtc)
@@ -1410,6 +1408,7 @@ done:
 static irqreturn_t vop_isr(int irq, void *data)
 {
 	struct vop *vop = data;
+	struct drm_crtc *crtc = &vop->crtc;
 	uint32_t intr0_reg, active_irqs;
 	unsigned long flags;
 	int ret = IRQ_NONE;
@@ -1438,7 +1437,7 @@ static irqreturn_t vop_isr(int irq, void *data)
 	}
 
 	if (active_irqs & FS_INTR) {
-		drm_handle_vblank(vop->drm_dev, vop->pipe);
+		drm_crtc_handle_vblank(crtc);
 		active_irqs &= ~FS_INTR;
 		ret = (vop->vsync_work_pending) ? IRQ_WAKE_THREAD : IRQ_HANDLED;
 	}
@@ -1531,8 +1530,7 @@ static int vop_create_crtc(struct vop *vop)
 
 	init_completion(&vop->dsp_hold_completion);
 	crtc->port = port;
-	vop->pipe = drm_crtc_index(crtc);
-	rockchip_register_crtc_funcs(drm_dev, &private_crtc_funcs, vop->pipe);
+	rockchip_register_crtc_funcs(crtc, &private_crtc_funcs);
 
 	return 0;
 
@@ -1548,7 +1546,7 @@ static void vop_destroy_crtc(struct vop *vop)
 {
 	struct drm_crtc *crtc = &vop->crtc;
 
-	rockchip_unregister_crtc_funcs(vop->drm_dev, vop->pipe);
+	rockchip_unregister_crtc_funcs(crtc);
 	of_node_put(crtc->port);
 	drm_crtc_cleanup(crtc);
 }
-- 
1.7.9.5

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

* [PATCH v3 2/8] drm/rockchip: vop: replace dpms with enable/disable
  2015-12-17  3:01 ` Mark Yao
  (?)
@ 2015-12-17  3:01   ` Mark Yao
  -1 siblings, 0 replies; 51+ messages in thread
From: Mark Yao @ 2015-12-17  3:01 UTC (permalink / raw)
  To: David Airlie, Heiko Stuebner, dri-devel, linux-arm-kernel,
	linux-rockchip, linux-kernel
  Cc: Mark Yao

For vop, power by enable/disable is more suitable then legacy dpms
function, and enable/disable more closely to the new atomic API.

Signed-off-by: Mark Yao <mark.yao@rock-chips.com>
---
Changes in v3: None
Changes in v2: None

 drivers/gpu/drm/rockchip/rockchip_drm_vop.c |   37 +++------------------------
 1 file changed, 4 insertions(+), 33 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index f82c7ba..1e60ddd 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -632,7 +632,7 @@ static void vop_dsp_hold_valid_irq_disable(struct vop *vop)
 	spin_unlock_irqrestore(&vop->irq_lock, flags);
 }
 
-static void vop_enable(struct drm_crtc *crtc)
+static void vop_crtc_enable(struct drm_crtc *crtc)
 {
 	struct vop *vop = to_vop(crtc);
 	int ret;
@@ -702,7 +702,7 @@ err_disable_hclk:
 	clk_disable(vop->hclk);
 }
 
-static void vop_disable(struct drm_crtc *crtc)
+static void vop_crtc_disable(struct drm_crtc *crtc)
 {
 	struct vop *vop = to_vop(crtc);
 
@@ -1107,30 +1107,6 @@ static const struct rockchip_crtc_funcs private_crtc_funcs = {
 	.disable_vblank = vop_crtc_disable_vblank,
 };
 
-static void vop_crtc_dpms(struct drm_crtc *crtc, int mode)
-{
-	DRM_DEBUG_KMS("crtc[%d] mode[%d]\n", crtc->base.id, mode);
-
-	switch (mode) {
-	case DRM_MODE_DPMS_ON:
-		vop_enable(crtc);
-		break;
-	case DRM_MODE_DPMS_STANDBY:
-	case DRM_MODE_DPMS_SUSPEND:
-	case DRM_MODE_DPMS_OFF:
-		vop_disable(crtc);
-		break;
-	default:
-		DRM_DEBUG_KMS("unspecified mode %d\n", mode);
-		break;
-	}
-}
-
-static void vop_crtc_prepare(struct drm_crtc *crtc)
-{
-	vop_crtc_dpms(crtc, DRM_MODE_DPMS_ON);
-}
-
 static bool vop_crtc_mode_fixup(struct drm_crtc *crtc,
 				const struct drm_display_mode *mode,
 				struct drm_display_mode *adjusted_mode)
@@ -1241,17 +1217,12 @@ out:
 	return ret;
 }
 
-static void vop_crtc_commit(struct drm_crtc *crtc)
-{
-}
-
 static const struct drm_crtc_helper_funcs vop_crtc_helper_funcs = {
-	.dpms = vop_crtc_dpms,
-	.prepare = vop_crtc_prepare,
+	.enable = vop_crtc_enable,
+	.disable = vop_crtc_disable,
 	.mode_fixup = vop_crtc_mode_fixup,
 	.mode_set = vop_crtc_mode_set,
 	.mode_set_base = vop_crtc_mode_set_base,
-	.commit = vop_crtc_commit,
 };
 
 static int vop_crtc_page_flip(struct drm_crtc *crtc,
-- 
1.7.9.5



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

* [PATCH v3 2/8] drm/rockchip: vop: replace dpms with enable/disable
@ 2015-12-17  3:01   ` Mark Yao
  0 siblings, 0 replies; 51+ messages in thread
From: Mark Yao @ 2015-12-17  3:01 UTC (permalink / raw)
  To: David Airlie, Heiko Stuebner, dri-devel, linux-arm-kernel,
	linux-rockchip, linux-kernel

For vop, power by enable/disable is more suitable then legacy dpms
function, and enable/disable more closely to the new atomic API.

Signed-off-by: Mark Yao <mark.yao@rock-chips.com>
---
Changes in v3: None
Changes in v2: None

 drivers/gpu/drm/rockchip/rockchip_drm_vop.c |   37 +++------------------------
 1 file changed, 4 insertions(+), 33 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index f82c7ba..1e60ddd 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -632,7 +632,7 @@ static void vop_dsp_hold_valid_irq_disable(struct vop *vop)
 	spin_unlock_irqrestore(&vop->irq_lock, flags);
 }
 
-static void vop_enable(struct drm_crtc *crtc)
+static void vop_crtc_enable(struct drm_crtc *crtc)
 {
 	struct vop *vop = to_vop(crtc);
 	int ret;
@@ -702,7 +702,7 @@ err_disable_hclk:
 	clk_disable(vop->hclk);
 }
 
-static void vop_disable(struct drm_crtc *crtc)
+static void vop_crtc_disable(struct drm_crtc *crtc)
 {
 	struct vop *vop = to_vop(crtc);
 
@@ -1107,30 +1107,6 @@ static const struct rockchip_crtc_funcs private_crtc_funcs = {
 	.disable_vblank = vop_crtc_disable_vblank,
 };
 
-static void vop_crtc_dpms(struct drm_crtc *crtc, int mode)
-{
-	DRM_DEBUG_KMS("crtc[%d] mode[%d]\n", crtc->base.id, mode);
-
-	switch (mode) {
-	case DRM_MODE_DPMS_ON:
-		vop_enable(crtc);
-		break;
-	case DRM_MODE_DPMS_STANDBY:
-	case DRM_MODE_DPMS_SUSPEND:
-	case DRM_MODE_DPMS_OFF:
-		vop_disable(crtc);
-		break;
-	default:
-		DRM_DEBUG_KMS("unspecified mode %d\n", mode);
-		break;
-	}
-}
-
-static void vop_crtc_prepare(struct drm_crtc *crtc)
-{
-	vop_crtc_dpms(crtc, DRM_MODE_DPMS_ON);
-}
-
 static bool vop_crtc_mode_fixup(struct drm_crtc *crtc,
 				const struct drm_display_mode *mode,
 				struct drm_display_mode *adjusted_mode)
@@ -1241,17 +1217,12 @@ out:
 	return ret;
 }
 
-static void vop_crtc_commit(struct drm_crtc *crtc)
-{
-}
-
 static const struct drm_crtc_helper_funcs vop_crtc_helper_funcs = {
-	.dpms = vop_crtc_dpms,
-	.prepare = vop_crtc_prepare,
+	.enable = vop_crtc_enable,
+	.disable = vop_crtc_disable,
 	.mode_fixup = vop_crtc_mode_fixup,
 	.mode_set = vop_crtc_mode_set,
 	.mode_set_base = vop_crtc_mode_set_base,
-	.commit = vop_crtc_commit,
 };
 
 static int vop_crtc_page_flip(struct drm_crtc *crtc,
-- 
1.7.9.5


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

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

* [PATCH v3 2/8] drm/rockchip: vop: replace dpms with enable/disable
@ 2015-12-17  3:01   ` Mark Yao
  0 siblings, 0 replies; 51+ messages in thread
From: Mark Yao @ 2015-12-17  3:01 UTC (permalink / raw)
  To: linux-arm-kernel

For vop, power by enable/disable is more suitable then legacy dpms
function, and enable/disable more closely to the new atomic API.

Signed-off-by: Mark Yao <mark.yao@rock-chips.com>
---
Changes in v3: None
Changes in v2: None

 drivers/gpu/drm/rockchip/rockchip_drm_vop.c |   37 +++------------------------
 1 file changed, 4 insertions(+), 33 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index f82c7ba..1e60ddd 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -632,7 +632,7 @@ static void vop_dsp_hold_valid_irq_disable(struct vop *vop)
 	spin_unlock_irqrestore(&vop->irq_lock, flags);
 }
 
-static void vop_enable(struct drm_crtc *crtc)
+static void vop_crtc_enable(struct drm_crtc *crtc)
 {
 	struct vop *vop = to_vop(crtc);
 	int ret;
@@ -702,7 +702,7 @@ err_disable_hclk:
 	clk_disable(vop->hclk);
 }
 
-static void vop_disable(struct drm_crtc *crtc)
+static void vop_crtc_disable(struct drm_crtc *crtc)
 {
 	struct vop *vop = to_vop(crtc);
 
@@ -1107,30 +1107,6 @@ static const struct rockchip_crtc_funcs private_crtc_funcs = {
 	.disable_vblank = vop_crtc_disable_vblank,
 };
 
-static void vop_crtc_dpms(struct drm_crtc *crtc, int mode)
-{
-	DRM_DEBUG_KMS("crtc[%d] mode[%d]\n", crtc->base.id, mode);
-
-	switch (mode) {
-	case DRM_MODE_DPMS_ON:
-		vop_enable(crtc);
-		break;
-	case DRM_MODE_DPMS_STANDBY:
-	case DRM_MODE_DPMS_SUSPEND:
-	case DRM_MODE_DPMS_OFF:
-		vop_disable(crtc);
-		break;
-	default:
-		DRM_DEBUG_KMS("unspecified mode %d\n", mode);
-		break;
-	}
-}
-
-static void vop_crtc_prepare(struct drm_crtc *crtc)
-{
-	vop_crtc_dpms(crtc, DRM_MODE_DPMS_ON);
-}
-
 static bool vop_crtc_mode_fixup(struct drm_crtc *crtc,
 				const struct drm_display_mode *mode,
 				struct drm_display_mode *adjusted_mode)
@@ -1241,17 +1217,12 @@ out:
 	return ret;
 }
 
-static void vop_crtc_commit(struct drm_crtc *crtc)
-{
-}
-
 static const struct drm_crtc_helper_funcs vop_crtc_helper_funcs = {
-	.dpms = vop_crtc_dpms,
-	.prepare = vop_crtc_prepare,
+	.enable = vop_crtc_enable,
+	.disable = vop_crtc_disable,
 	.mode_fixup = vop_crtc_mode_fixup,
 	.mode_set = vop_crtc_mode_set,
 	.mode_set_base = vop_crtc_mode_set_base,
-	.commit = vop_crtc_commit,
 };
 
 static int vop_crtc_page_flip(struct drm_crtc *crtc,
-- 
1.7.9.5

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

* [PATCH v3 3/8] drm/rockchip: Convert to support atomic API
  2015-12-17  3:01 ` Mark Yao
  (?)
@ 2015-12-17  3:01   ` Mark Yao
  -1 siblings, 0 replies; 51+ messages in thread
From: Mark Yao @ 2015-12-17  3:01 UTC (permalink / raw)
  To: David Airlie, Heiko Stuebner, dri-devel, linux-arm-kernel,
	linux-rockchip, linux-kernel
  Cc: Mark Yao, Tomasz Figa

Rockchip vop not support hw vblank counter, needed check the committed
register if it's really take effect.

Signed-off-by: Mark Yao <mark.yao@rock-chips.com>
Signed-off-by: Tomasz Figa <tfiga@chromium.org>
---
Changes in v3:
Reported by kbuild test robot
- fix rockchip_crtc_wait_for_update undefined when build drm rockchip as modules.

Changes in v2:
- Optimization commit planes sequence.
- Get vblank count on atomic_begin to protect vblank event.
Adviced by Daniel Stone
- Direct return -EINVAL when yuv address is not support, instead of adjust it.
- code formating and cleanup.
Adviced by Thierry Reding & Daniel Vetter
- Hook mode_set into crtc enable instead of hack crtc enable on mode set.

 drivers/gpu/drm/rockchip/rockchip_drm_drv.c |    5 +-
 drivers/gpu/drm/rockchip/rockchip_drm_drv.h |    3 +-
 drivers/gpu/drm/rockchip/rockchip_drm_fb.c  |   95 ++++
 drivers/gpu/drm/rockchip/rockchip_drm_vop.c |  657 +++++++++++----------------
 4 files changed, 363 insertions(+), 397 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
index cfd9b83..ab3e0f6 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
@@ -213,6 +213,8 @@ static int rockchip_drm_load(struct drm_device *drm_dev, unsigned long flags)
 	 */
 	drm_dev->vblank_disable_allowed = true;
 
+	drm_mode_config_reset(drm_dev);
+
 	ret = rockchip_drm_fbdev_init(drm_dev);
 	if (ret)
 		goto err_vblank_cleanup;
@@ -276,7 +278,8 @@ const struct vm_operations_struct rockchip_drm_vm_ops = {
 };
 
 static struct drm_driver rockchip_drm_driver = {
-	.driver_features	= DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME,
+	.driver_features	= DRIVER_MODESET | DRIVER_GEM |
+				  DRIVER_PRIME | DRIVER_ATOMIC,
 	.load			= rockchip_drm_load,
 	.unload			= rockchip_drm_unload,
 	.lastclose		= rockchip_drm_lastclose,
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
index 069d6d4..4468f98 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
@@ -18,6 +18,7 @@
 #define _ROCKCHIP_DRM_DRV_H
 
 #include <drm/drm_fb_helper.h>
+#include <drm/drm_atomic_helper.h>
 #include <drm/drm_gem.h>
 
 #include <linux/module.h>
@@ -38,6 +39,7 @@ struct drm_connector;
 struct rockchip_crtc_funcs {
 	int (*enable_vblank)(struct drm_crtc *crtc);
 	void (*disable_vblank)(struct drm_crtc *crtc);
+	void (*wait_for_update)(struct drm_crtc *crtc);
 };
 
 /*
@@ -63,5 +65,4 @@ int rockchip_drm_dma_attach_device(struct drm_device *drm_dev,
 				   struct device *dev);
 void rockchip_drm_dma_detach_device(struct drm_device *drm_dev,
 				    struct device *dev);
-
 #endif /* _ROCKCHIP_DRM_DRV_H_ */
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
index b8ac591..7c974a4 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
@@ -15,6 +15,7 @@
 #include <linux/kernel.h>
 #include <drm/drm.h>
 #include <drm/drmP.h>
+#include <drm/drm_atomic.h>
 #include <drm/drm_fb_helper.h>
 #include <drm/drm_crtc_helper.h>
 
@@ -166,9 +167,103 @@ static void rockchip_drm_output_poll_changed(struct drm_device *dev)
 		drm_fb_helper_hotplug_event(fb_helper);
 }
 
+static void rockchip_crtc_wait_for_update(struct drm_crtc *crtc)
+{
+	struct rockchip_drm_private *priv = crtc->dev->dev_private;
+	int pipe = drm_crtc_index(crtc);
+	const struct rockchip_crtc_funcs *crtc_funcs = priv->crtc_funcs[pipe];
+
+	if (crtc_funcs && crtc_funcs->wait_for_update)
+		crtc_funcs->wait_for_update(crtc);
+}
+
+static void
+rockchip_atomic_wait_for_complete(struct drm_atomic_state *old_state)
+{
+	struct drm_crtc_state *old_crtc_state;
+	struct drm_crtc *crtc;
+	int i, ret;
+
+	for_each_crtc_in_state(old_state, crtc, old_crtc_state, i) {
+		/* No one cares about the old state, so abuse it for tracking
+		 * and store whether we hold a vblank reference (and should do a
+		 * vblank wait) in the ->enable boolean.
+		 */
+		old_crtc_state->enable = false;
+
+		if (!crtc->state->active)
+			continue;
+
+		ret = drm_crtc_vblank_get(crtc);
+		if (ret != 0)
+			continue;
+
+		old_crtc_state->enable = true;
+	}
+
+	for_each_crtc_in_state(old_state, crtc, old_crtc_state, i) {
+		if (!old_crtc_state->enable)
+			continue;
+
+		rockchip_crtc_wait_for_update(crtc);
+		drm_crtc_vblank_put(crtc);
+	}
+}
+
+int rockchip_drm_atomic_commit(struct drm_device *dev,
+			       struct drm_atomic_state *state,
+			       bool async)
+{
+	int ret;
+
+	if (async)
+		return -EBUSY;
+
+	ret = drm_atomic_helper_prepare_planes(dev, state);
+	if (ret)
+		return ret;
+
+	drm_atomic_helper_swap_state(dev, state);
+
+	/*
+	 * TODO: do fence wait here.
+	 */
+
+	/*
+	 * Rockchip crtc support runtime PM, can't update display planes
+	 * when crtc is disabled.
+	 *
+	 * drm_atomic_helper_commit comments detail that:
+	 *     For drivers supporting runtime PM the recommended sequence is
+	 *
+	 *     drm_atomic_helper_commit_modeset_disables(dev, state);
+	 *
+	 *     drm_atomic_helper_commit_modeset_enables(dev, state);
+	 *
+	 *     drm_atomic_helper_commit_planes(dev, state, true);
+	 *
+	 * See the kerneldoc entries for these three functions for more details.
+	 */
+	drm_atomic_helper_commit_modeset_disables(dev, state);
+
+	drm_atomic_helper_commit_modeset_enables(dev, state);
+
+	drm_atomic_helper_commit_planes(dev, state, true);
+
+	rockchip_atomic_wait_for_complete(state);
+
+	drm_atomic_helper_cleanup_planes(dev, state);
+
+	drm_atomic_state_free(state);
+
+	return 0;
+}
+
 static const struct drm_mode_config_funcs rockchip_drm_mode_config_funcs = {
 	.fb_create = rockchip_user_fb_create,
 	.output_poll_changed = rockchip_drm_output_poll_changed,
+	.atomic_check = drm_atomic_helper_check,
+	.atomic_commit = rockchip_drm_atomic_commit,
 };
 
 struct drm_framebuffer *
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index 1e60ddd..44f6154 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -14,6 +14,7 @@
 
 #include <drm/drm.h>
 #include <drm/drmP.h>
+#include <drm/drm_atomic.h>
 #include <drm/drm_crtc.h>
 #include <drm/drm_crtc_helper.h>
 #include <drm/drm_plane_helper.h>
@@ -63,12 +64,15 @@
 
 #define to_vop(x) container_of(x, struct vop, crtc)
 #define to_vop_win(x) container_of(x, struct vop_win, base)
+#define to_vop_plane_state(x) container_of(x, struct vop_plane_state, base)
 
-struct vop_win_state {
-	struct list_head head;
-	struct drm_framebuffer *fb;
+struct vop_plane_state {
+	struct drm_plane_state base;
+	int format;
+	struct drm_rect src;
+	struct drm_rect dest;
 	dma_addr_t yrgb_mst;
-	struct drm_pending_vblank_event *event;
+	bool enable;
 };
 
 struct vop_win {
@@ -76,8 +80,7 @@ struct vop_win {
 	const struct vop_win_data *data;
 	struct vop *vop;
 
-	struct list_head pending;
-	struct vop_win_state *active;
+	struct vop_plane_state state;
 };
 
 struct vop {
@@ -93,6 +96,8 @@ struct vop {
 	struct mutex vsync_mutex;
 	bool vsync_work_pending;
 	struct completion dsp_hold_completion;
+	struct completion wait_update_complete;
+	struct drm_pending_vblank_event *event;
 
 	const struct vop_data *data;
 
@@ -632,7 +637,7 @@ static void vop_dsp_hold_valid_irq_disable(struct vop *vop)
 	spin_unlock_irqrestore(&vop->irq_lock, flags);
 }
 
-static void vop_crtc_enable(struct drm_crtc *crtc)
+static void vop_enable(struct drm_crtc *crtc)
 {
 	struct vop *vop = to_vop(crtc);
 	int ret;
@@ -746,224 +751,188 @@ static void vop_crtc_disable(struct drm_crtc *crtc)
 	pm_runtime_put(vop->dev);
 }
 
-/*
- * Caller must hold vsync_mutex.
- */
-static struct drm_framebuffer *vop_win_last_pending_fb(struct vop_win *vop_win)
-{
-	struct vop_win_state *last;
-	struct vop_win_state *active = vop_win->active;
-
-	if (list_empty(&vop_win->pending))
-		return active ? active->fb : NULL;
-
-	last = list_last_entry(&vop_win->pending, struct vop_win_state, head);
-	return last ? last->fb : NULL;
-}
-
-/*
- * Caller must hold vsync_mutex.
- */
-static int vop_win_queue_fb(struct vop_win *vop_win,
-			    struct drm_framebuffer *fb, dma_addr_t yrgb_mst,
-			    struct drm_pending_vblank_event *event)
+static void vop_plane_destroy(struct drm_plane *plane)
 {
-	struct vop_win_state *state;
-
-	state = kzalloc(sizeof(*state), GFP_KERNEL);
-	if (!state)
-		return -ENOMEM;
-
-	state->fb = fb;
-	state->yrgb_mst = yrgb_mst;
-	state->event = event;
-
-	list_add_tail(&state->head, &vop_win->pending);
-
-	return 0;
+	drm_plane_cleanup(plane);
 }
 
-static int vop_update_plane_event(struct drm_plane *plane,
-				  struct drm_crtc *crtc,
-				  struct drm_framebuffer *fb, int crtc_x,
-				  int crtc_y, unsigned int crtc_w,
-				  unsigned int crtc_h, uint32_t src_x,
-				  uint32_t src_y, uint32_t src_w,
-				  uint32_t src_h,
-				  struct drm_pending_vblank_event *event)
+static int vop_plane_atomic_check(struct drm_plane *plane,
+			   struct drm_plane_state *state)
 {
+	struct drm_crtc *crtc = state->crtc;
+	struct drm_framebuffer *fb = state->fb;
 	struct vop_win *vop_win = to_vop_win(plane);
+	struct vop_plane_state *vop_plane_state = to_vop_plane_state(state);
 	const struct vop_win_data *win = vop_win->data;
-	struct vop *vop = to_vop(crtc);
-	struct drm_gem_object *obj;
-	struct rockchip_gem_object *rk_obj;
-	struct drm_gem_object *uv_obj;
-	struct rockchip_gem_object *rk_uv_obj;
-	unsigned long offset;
-	unsigned int actual_w;
-	unsigned int actual_h;
-	unsigned int dsp_stx;
-	unsigned int dsp_sty;
-	unsigned int y_vir_stride;
-	unsigned int uv_vir_stride = 0;
-	dma_addr_t yrgb_mst;
-	dma_addr_t uv_mst = 0;
-	enum vop_data_format format;
-	uint32_t val;
-	bool is_alpha;
-	bool rb_swap;
-	bool is_yuv;
 	bool visible;
 	int ret;
-	struct drm_rect dest = {
-		.x1 = crtc_x,
-		.y1 = crtc_y,
-		.x2 = crtc_x + crtc_w,
-		.y2 = crtc_y + crtc_h,
-	};
-	struct drm_rect src = {
-		/* 16.16 fixed point */
-		.x1 = src_x,
-		.y1 = src_y,
-		.x2 = src_x + src_w,
-		.y2 = src_y + src_h,
-	};
-	const struct drm_rect clip = {
-		.x2 = crtc->mode.hdisplay,
-		.y2 = crtc->mode.vdisplay,
-	};
-	bool can_position = plane->type != DRM_PLANE_TYPE_PRIMARY;
+	struct drm_rect *dest = &vop_plane_state->dest;
+	struct drm_rect *src = &vop_plane_state->src;
+	struct drm_rect clip;
 	int min_scale = win->phy->scl ? FRAC_16_16(1, 8) :
 					DRM_PLANE_HELPER_NO_SCALING;
 	int max_scale = win->phy->scl ? FRAC_16_16(8, 1) :
 					DRM_PLANE_HELPER_NO_SCALING;
 
-	ret = drm_plane_helper_check_update(plane, crtc, fb,
-					    &src, &dest, &clip,
+	crtc = crtc ? crtc : plane->state->crtc;
+	/*
+	 * Both crtc or plane->state->crtc can be null.
+	 */
+	if (!crtc || !fb)
+		goto out_disable;
+	src->x1 = state->src_x;
+	src->y1 = state->src_y;
+	src->x2 = state->src_x + state->src_w;
+	src->y2 = state->src_y + state->src_h;
+	dest->x1 = state->crtc_x;
+	dest->y1 = state->crtc_y;
+	dest->x2 = state->crtc_x + state->crtc_w;
+	dest->y2 = state->crtc_y + state->crtc_h;
+
+	clip.x1 = 0;
+	clip.y1 = 0;
+	clip.x2 = crtc->mode.hdisplay;
+	clip.y2 = crtc->mode.vdisplay;
+
+	ret = drm_plane_helper_check_update(plane, crtc, state->fb,
+					    src, dest, &clip,
 					    min_scale,
 					    max_scale,
-					    can_position, false, &visible);
+					    true, true, &visible);
 	if (ret)
 		return ret;
 
 	if (!visible)
-		return 0;
+		goto out_disable;
 
-	is_alpha = is_alpha_support(fb->pixel_format);
-	rb_swap = has_rb_swapped(fb->pixel_format);
-	is_yuv = is_yuv_support(fb->pixel_format);
+	vop_plane_state->format = vop_convert_format(fb->pixel_format);
+	if (vop_plane_state->format < 0)
+		return vop_plane_state->format;
 
-	format = vop_convert_format(fb->pixel_format);
-	if (format < 0)
-		return format;
-
-	obj = rockchip_fb_get_gem_obj(fb, 0);
-	if (!obj) {
-		DRM_ERROR("fail to get rockchip gem object from framebuffer\n");
+	/*
+	 * Src.x1 can be odd when do clip, but yuv plane start point
+	 * need align with 2 pixel.
+	 */
+	if (is_yuv_support(fb->pixel_format) && ((src->x1 >> 16) % 2))
 		return -EINVAL;
-	}
 
-	rk_obj = to_rockchip_obj(obj);
+	vop_plane_state->enable = true;
 
-	if (is_yuv) {
-		/*
-		 * Src.x1 can be odd when do clip, but yuv plane start point
-		 * need align with 2 pixel.
-		 */
-		val = (src.x1 >> 16) % 2;
-		src.x1 += val << 16;
-		src.x2 += val << 16;
-	}
+	return 0;
 
-	actual_w = (src.x2 - src.x1) >> 16;
-	actual_h = (src.y2 - src.y1) >> 16;
+out_disable:
+	vop_plane_state->enable = false;
+	return 0;
+}
 
-	dsp_stx = dest.x1 + crtc->mode.htotal - crtc->mode.hsync_start;
-	dsp_sty = dest.y1 + crtc->mode.vtotal - crtc->mode.vsync_start;
+static void vop_plane_atomic_disable(struct drm_plane *plane,
+				     struct drm_plane_state *old_state)
+{
+	struct vop_plane_state *vop_plane_state = to_vop_plane_state(old_state);
+	struct vop_win *vop_win = to_vop_win(plane);
+	const struct vop_win_data *win = vop_win->data;
+	struct vop *vop = to_vop(old_state->crtc);
 
-	offset = (src.x1 >> 16) * drm_format_plane_cpp(fb->pixel_format, 0);
-	offset += (src.y1 >> 16) * fb->pitches[0];
+	if (!old_state->crtc)
+		return;
 
-	yrgb_mst = rk_obj->dma_addr + offset + fb->offsets[0];
-	y_vir_stride = fb->pitches[0] >> 2;
+	spin_lock(&vop->reg_lock);
 
-	if (is_yuv) {
-		int hsub = drm_format_horz_chroma_subsampling(fb->pixel_format);
-		int vsub = drm_format_vert_chroma_subsampling(fb->pixel_format);
-		int bpp = drm_format_plane_cpp(fb->pixel_format, 1);
+	VOP_WIN_SET(vop, win, enable, 0);
 
-		uv_obj = rockchip_fb_get_gem_obj(fb, 1);
-		if (!uv_obj) {
-			DRM_ERROR("fail to get uv object from framebuffer\n");
-			return -EINVAL;
-		}
-		rk_uv_obj = to_rockchip_obj(uv_obj);
-		uv_vir_stride = fb->pitches[1] >> 2;
+	spin_unlock(&vop->reg_lock);
 
-		offset = (src.x1 >> 16) * bpp / hsub;
-		offset += (src.y1 >> 16) * fb->pitches[1] / vsub;
+	vop_plane_state->enable = false;
+}
 
-		uv_mst = rk_uv_obj->dma_addr + offset + fb->offsets[1];
-	}
+static void vop_plane_atomic_update(struct drm_plane *plane,
+		struct drm_plane_state *old_state)
+{
+	struct drm_plane_state *state = plane->state;
+	struct drm_crtc *crtc = state->crtc;
+	struct vop_win *vop_win = to_vop_win(plane);
+	struct vop_plane_state *vop_plane_state = to_vop_plane_state(state);
+	const struct vop_win_data *win = vop_win->data;
+	struct vop *vop = to_vop(state->crtc);
+	struct drm_framebuffer *fb = state->fb;
+	unsigned int actual_w, actual_h;
+	unsigned int dsp_stx, dsp_sty;
+	uint32_t act_info, dsp_info, dsp_st;
+	struct drm_rect *src = &vop_plane_state->src;
+	struct drm_rect *dest = &vop_plane_state->dest;
+	struct drm_gem_object *obj, *uv_obj;
+	struct rockchip_gem_object *rk_obj, *rk_uv_obj;
+	unsigned long offset;
+	dma_addr_t dma_addr;
+	uint32_t val;
+	bool rb_swap;
 
 	/*
-	 * If this plane update changes the plane's framebuffer, (or more
-	 * precisely, if this update has a different framebuffer than the last
-	 * update), enqueue it so we can track when it completes.
-	 *
-	 * Only when we discover that this update has completed, can we
-	 * unreference any previous framebuffers.
+	 * can't update plane when vop is disabled.
 	 */
-	mutex_lock(&vop->vsync_mutex);
-	if (fb != vop_win_last_pending_fb(vop_win)) {
-		ret = drm_crtc_vblank_get(crtc);
-		if (ret) {
-			DRM_ERROR("failed to get vblank, %d\n", ret);
-			mutex_unlock(&vop->vsync_mutex);
-			return ret;
-		}
-
-		drm_framebuffer_reference(fb);
+	if (!crtc)
+		return;
 
-		ret = vop_win_queue_fb(vop_win, fb, yrgb_mst, event);
-		if (ret) {
-			drm_crtc_vblank_put(crtc);
-			mutex_unlock(&vop->vsync_mutex);
-			return ret;
-		}
+	if (WARN_ON(!vop->is_enabled))
+		return;
 
-		vop->vsync_work_pending = true;
+	if (!vop_plane_state->enable) {
+		vop_plane_atomic_disable(plane, old_state);
+		return;
 	}
-	mutex_unlock(&vop->vsync_mutex);
+
+	obj = rockchip_fb_get_gem_obj(fb, 0);
+	rk_obj = to_rockchip_obj(obj);
+
+	actual_w = drm_rect_width(src) >> 16;
+	actual_h = drm_rect_height(src) >> 16;
+	act_info = (actual_h - 1) << 16 | ((actual_w - 1) & 0xffff);
+
+	dsp_info = (drm_rect_height(dest) - 1) << 16;
+	dsp_info |= (drm_rect_width(dest) - 1) & 0xffff;
+
+	dsp_stx = dest->x1 + crtc->mode.htotal - crtc->mode.hsync_start;
+	dsp_sty = dest->y1 + crtc->mode.vtotal - crtc->mode.vsync_start;
+	dsp_st = dsp_sty << 16 | (dsp_stx & 0xffff);
+
+	offset = (src->x1 >> 16) * drm_format_plane_cpp(fb->pixel_format, 0);
+	offset += (src->y1 >> 16) * fb->pitches[0];
+	vop_plane_state->yrgb_mst = rk_obj->dma_addr + offset + fb->offsets[0];
 
 	spin_lock(&vop->reg_lock);
 
-	VOP_WIN_SET(vop, win, format, format);
-	VOP_WIN_SET(vop, win, yrgb_vir, y_vir_stride);
-	VOP_WIN_SET(vop, win, yrgb_mst, yrgb_mst);
-	if (is_yuv) {
-		VOP_WIN_SET(vop, win, uv_vir, uv_vir_stride);
-		VOP_WIN_SET(vop, win, uv_mst, uv_mst);
+	VOP_WIN_SET(vop, win, format, vop_plane_state->format);
+	VOP_WIN_SET(vop, win, yrgb_vir, fb->pitches[0] >> 2);
+	VOP_WIN_SET(vop, win, yrgb_mst, vop_plane_state->yrgb_mst);
+	if (is_yuv_support(fb->pixel_format)) {
+		int hsub = drm_format_horz_chroma_subsampling(fb->pixel_format);
+		int vsub = drm_format_vert_chroma_subsampling(fb->pixel_format);
+		int bpp = drm_format_plane_cpp(fb->pixel_format, 1);
+
+		uv_obj = rockchip_fb_get_gem_obj(fb, 1);
+		rk_uv_obj = to_rockchip_obj(uv_obj);
+
+		offset = (src->x1 >> 16) * bpp / hsub;
+		offset += (src->y1 >> 16) * fb->pitches[1] / vsub;
+
+		dma_addr = rk_uv_obj->dma_addr + offset + fb->offsets[1];
+		VOP_WIN_SET(vop, win, uv_vir, fb->pitches[1] >> 2);
+		VOP_WIN_SET(vop, win, uv_mst, dma_addr);
 	}
 
 	if (win->phy->scl)
 		scl_vop_cal_scl_fac(vop, win, actual_w, actual_h,
-				    dest.x2 - dest.x1, dest.y2 - dest.y1,
+				    drm_rect_width(dest), drm_rect_height(dest),
 				    fb->pixel_format);
 
-	val = (actual_h - 1) << 16;
-	val |= (actual_w - 1) & 0xffff;
-	VOP_WIN_SET(vop, win, act_info, val);
+	VOP_WIN_SET(vop, win, act_info, act_info);
+	VOP_WIN_SET(vop, win, dsp_info, dsp_info);
+	VOP_WIN_SET(vop, win, dsp_st, dsp_st);
 
-	val = (dest.y2 - dest.y1 - 1) << 16;
-	val |= (dest.x2 - dest.x1 - 1) & 0xffff;
-	VOP_WIN_SET(vop, win, dsp_info, val);
-	val = dsp_sty << 16;
-	val |= dsp_stx & 0xffff;
-	VOP_WIN_SET(vop, win, dsp_st, val);
+	rb_swap = has_rb_swapped(fb->pixel_format);
 	VOP_WIN_SET(vop, win, rb_swap, rb_swap);
 
-	if (is_alpha) {
+	if (is_alpha_support(fb->pixel_format)) {
 		VOP_WIN_SET(vop, win, dst_alpha_ctl,
 			    DST_FACTOR_M0(ALPHA_SRC_INVERSE));
 		val = SRC_ALPHA_EN(1) | SRC_COLOR_M0(ALPHA_SRC_PRE_MUL) |
@@ -977,86 +946,70 @@ static int vop_update_plane_event(struct drm_plane *plane,
 	}
 
 	VOP_WIN_SET(vop, win, enable, 1);
-
-	vop_cfg_done(vop);
 	spin_unlock(&vop->reg_lock);
-
-	return 0;
 }
 
-static int vop_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
-			    struct drm_framebuffer *fb, int crtc_x, int crtc_y,
-			    unsigned int crtc_w, unsigned int crtc_h,
-			    uint32_t src_x, uint32_t src_y, uint32_t src_w,
-			    uint32_t src_h)
-{
-	return vop_update_plane_event(plane, crtc, fb, crtc_x, crtc_y, crtc_w,
-				      crtc_h, src_x, src_y, src_w, src_h,
-				      NULL);
-}
+static const struct drm_plane_helper_funcs plane_helper_funcs = {
+	.atomic_check = vop_plane_atomic_check,
+	.atomic_update = vop_plane_atomic_update,
+	.atomic_disable = vop_plane_atomic_disable,
+};
 
-static int vop_update_primary_plane(struct drm_crtc *crtc,
-				    struct drm_pending_vblank_event *event)
+void vop_atomic_plane_reset(struct drm_plane *plane)
 {
-	unsigned int crtc_w, crtc_h;
+	struct vop_plane_state *vop_plane_state =
+					to_vop_plane_state(plane->state);
 
-	crtc_w = crtc->primary->fb->width - crtc->x;
-	crtc_h = crtc->primary->fb->height - crtc->y;
+	if (plane->state && plane->state->fb)
+		drm_framebuffer_unreference(plane->state->fb);
+
+	kfree(vop_plane_state);
+	vop_plane_state = kzalloc(sizeof(*vop_plane_state), GFP_KERNEL);
+	if (!vop_plane_state)
+		return;
 
-	return vop_update_plane_event(crtc->primary, crtc, crtc->primary->fb,
-				      0, 0, crtc_w, crtc_h, crtc->x << 16,
-				      crtc->y << 16, crtc_w << 16,
-				      crtc_h << 16, event);
+	plane->state = &vop_plane_state->base;
+	plane->state->plane = plane;
 }
 
-static int vop_disable_plane(struct drm_plane *plane)
+struct drm_plane_state *
+vop_atomic_plane_duplicate_state(struct drm_plane *plane)
 {
-	struct vop_win *vop_win = to_vop_win(plane);
-	const struct vop_win_data *win = vop_win->data;
-	struct vop *vop;
-	int ret;
-
-	if (!plane->crtc)
-		return 0;
+	struct vop_plane_state *old_vop_plane_state;
+	struct vop_plane_state *vop_plane_state;
 
-	vop = to_vop(plane->crtc);
+	if (WARN_ON(!plane->state))
+		return NULL;
 
-	ret = drm_crtc_vblank_get(plane->crtc);
-	if (ret) {
-		DRM_ERROR("failed to get vblank, %d\n", ret);
-		return ret;
-	}
+	old_vop_plane_state = to_vop_plane_state(plane->state);
+	vop_plane_state = kmemdup(old_vop_plane_state,
+				  sizeof(*vop_plane_state), GFP_KERNEL);
+	if (!vop_plane_state)
+		return NULL;
 
-	mutex_lock(&vop->vsync_mutex);
+	__drm_atomic_helper_plane_duplicate_state(plane,
+						  &vop_plane_state->base);
 
-	ret = vop_win_queue_fb(vop_win, NULL, 0, NULL);
-	if (ret) {
-		drm_crtc_vblank_put(plane->crtc);
-		mutex_unlock(&vop->vsync_mutex);
-		return ret;
-	}
-
-	vop->vsync_work_pending = true;
-	mutex_unlock(&vop->vsync_mutex);
-
-	spin_lock(&vop->reg_lock);
-	VOP_WIN_SET(vop, win, enable, 0);
-	vop_cfg_done(vop);
-	spin_unlock(&vop->reg_lock);
-
-	return 0;
+	return &vop_plane_state->base;
 }
 
-static void vop_plane_destroy(struct drm_plane *plane)
+static void vop_atomic_plane_destroy_state(struct drm_plane *plane,
+					   struct drm_plane_state *state)
 {
-	vop_disable_plane(plane);
-	drm_plane_cleanup(plane);
+	struct vop_plane_state *vop_state = to_vop_plane_state(state);
+
+	__drm_atomic_helper_plane_destroy_state(plane, state);
+
+	kfree(vop_state);
 }
 
 static const struct drm_plane_funcs vop_plane_funcs = {
-	.update_plane = vop_update_plane,
-	.disable_plane = vop_disable_plane,
+	.update_plane	= drm_atomic_helper_update_plane,
+	.disable_plane	= drm_atomic_helper_disable_plane,
 	.destroy = vop_plane_destroy,
+	.reset = vop_atomic_plane_reset,
+	.atomic_duplicate_state = vop_atomic_plane_duplicate_state,
+	.atomic_destroy_state = vop_atomic_plane_destroy_state,
 };
 
 int rockchip_drm_crtc_mode_config(struct drm_crtc *crtc,
@@ -1077,7 +1030,7 @@ static int vop_crtc_enable_vblank(struct drm_crtc *crtc)
 	struct vop *vop = to_vop(crtc);
 	unsigned long flags;
 
-	if (!vop->is_enabled)
+	if (WARN_ON(!vop->is_enabled))
 		return -EPERM;
 
 	spin_lock_irqsave(&vop->irq_lock, flags);
@@ -1094,7 +1047,7 @@ static void vop_crtc_disable_vblank(struct drm_crtc *crtc)
 	struct vop *vop = to_vop(crtc);
 	unsigned long flags;
 
-	if (!vop->is_enabled)
+	if (WARN_ON(!vop->is_enabled))
 		return;
 
 	spin_lock_irqsave(&vop->irq_lock, flags);
@@ -1102,9 +1055,18 @@ static void vop_crtc_disable_vblank(struct drm_crtc *crtc)
 	spin_unlock_irqrestore(&vop->irq_lock, flags);
 }
 
+static void vop_crtc_wait_for_update(struct drm_crtc *crtc)
+{
+	struct vop *vop = to_vop(crtc);
+
+	reinit_completion(&vop->wait_update_complete);
+	WARN_ON(!wait_for_completion_timeout(&vop->wait_update_complete, 100));
+}
+
 static const struct rockchip_crtc_funcs private_crtc_funcs = {
 	.enable_vblank = vop_crtc_enable_vblank,
 	.disable_vblank = vop_crtc_disable_vblank,
+	.wait_for_update = vop_crtc_wait_for_update,
 };
 
 static bool vop_crtc_mode_fixup(struct drm_crtc *crtc,
@@ -1117,29 +1079,10 @@ static bool vop_crtc_mode_fixup(struct drm_crtc *crtc,
 	return true;
 }
 
-static int vop_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
-				  struct drm_framebuffer *old_fb)
-{
-	int ret;
-
-	crtc->x = x;
-	crtc->y = y;
-
-	ret = vop_update_primary_plane(crtc, NULL);
-	if (ret < 0) {
-		DRM_ERROR("fail to update plane\n");
-		return ret;
-	}
-
-	return 0;
-}
-
-static int vop_crtc_mode_set(struct drm_crtc *crtc,
-			     struct drm_display_mode *mode,
-			     struct drm_display_mode *adjusted_mode,
-			     int x, int y, struct drm_framebuffer *fb)
+static void vop_crtc_enable(struct drm_crtc *crtc)
 {
 	struct vop *vop = to_vop(crtc);
+	struct drm_display_mode *adjusted_mode = &crtc->state->adjusted_mode;
 	u16 hsync_len = adjusted_mode->hsync_end - adjusted_mode->hsync_start;
 	u16 hdisplay = adjusted_mode->hdisplay;
 	u16 htotal = adjusted_mode->htotal;
@@ -1150,9 +1093,9 @@ static int vop_crtc_mode_set(struct drm_crtc *crtc,
 	u16 vsync_len = adjusted_mode->vsync_end - adjusted_mode->vsync_start;
 	u16 vact_st = adjusted_mode->vtotal - adjusted_mode->vsync_start;
 	u16 vact_end = vact_st + vdisplay;
-	int ret, ret_clk;
 	uint32_t val;
 
+	vop_enable(crtc);
 	/*
 	 * disable dclk to stop frame scan, so that we can safe config mode and
 	 * enable iommu.
@@ -1172,7 +1115,6 @@ static int vop_crtc_mode_set(struct drm_crtc *crtc,
 	default:
 		DRM_ERROR("unsupport connector_type[%d]\n",
 			  vop->connector_type);
-		ret = -EINVAL;
 		goto out;
 	};
 	VOP_CTRL_SET(vop, out_mode, vop->connector_out_mode);
@@ -1194,9 +1136,6 @@ static int vop_crtc_mode_set(struct drm_crtc *crtc,
 	VOP_CTRL_SET(vop, vact_st_end, val);
 	VOP_CTRL_SET(vop, vpost_st_end, val);
 
-	ret = vop_crtc_mode_set_base(crtc, x, y, fb);
-	if (ret)
-		goto out;
 
 	/*
 	 * reset dclk, take all mode config affect, so the clk would run in
@@ -1208,172 +1147,97 @@ static int vop_crtc_mode_set(struct drm_crtc *crtc,
 
 	clk_set_rate(vop->dclk, adjusted_mode->clock * 1000);
 out:
-	ret_clk = clk_enable(vop->dclk);
-	if (ret_clk < 0) {
-		dev_err(vop->dev, "failed to enable dclk - %d\n", ret_clk);
-		return ret_clk;
-	}
-
-	return ret;
+	if (clk_enable(vop->dclk) < 0)
+		dev_err(vop->dev, "failed to enable dclk\n");
 }
 
-static const struct drm_crtc_helper_funcs vop_crtc_helper_funcs = {
-	.enable = vop_crtc_enable,
-	.disable = vop_crtc_disable,
-	.mode_fixup = vop_crtc_mode_fixup,
-	.mode_set = vop_crtc_mode_set,
-	.mode_set_base = vop_crtc_mode_set_base,
-};
-
-static int vop_crtc_page_flip(struct drm_crtc *crtc,
-			      struct drm_framebuffer *fb,
-			      struct drm_pending_vblank_event *event,
-			      uint32_t page_flip_flags)
+static void vop_crtc_atomic_flush(struct drm_crtc *crtc,
+				  struct drm_crtc_state *old_crtc_state)
 {
 	struct vop *vop = to_vop(crtc);
-	struct drm_framebuffer *old_fb = crtc->primary->fb;
-	int ret;
 
-	/* when the page flip is requested, crtc should be on */
-	if (!vop->is_enabled) {
-		DRM_DEBUG("page flip request rejected because crtc is off.\n");
-		return 0;
-	}
+	if (WARN_ON(!vop->is_enabled))
+		return;
 
-	crtc->primary->fb = fb;
+	spin_lock(&vop->reg_lock);
 
-	ret = vop_update_primary_plane(crtc, event);
-	if (ret)
-		crtc->primary->fb = old_fb;
+	vop_cfg_done(vop);
 
-	return ret;
+	spin_unlock(&vop->reg_lock);
 }
 
-static void vop_win_state_complete(struct vop_win *vop_win,
-				   struct vop_win_state *state)
+static void vop_crtc_atomic_begin(struct drm_crtc *crtc,
+				  struct drm_crtc_state *old_crtc_state)
 {
-	struct vop *vop = vop_win->vop;
-	struct drm_crtc *crtc = &vop->crtc;
-	struct drm_device *drm = crtc->dev;
-	unsigned long flags;
+	struct vop *vop = to_vop(crtc);
 
-	if (state->event) {
-		spin_lock_irqsave(&drm->event_lock, flags);
-		drm_crtc_send_vblank_event(crtc, state->event);
-		spin_unlock_irqrestore(&drm->event_lock, flags);
-	}
+	if (crtc->state->event) {
+		WARN_ON(drm_crtc_vblank_get(crtc) != 0);
 
-	list_del(&state->head);
-	drm_crtc_vblank_put(crtc);
+		vop->event = crtc->state->event;
+		crtc->state->event = NULL;
+	}
 }
 
+static const struct drm_crtc_helper_funcs vop_crtc_helper_funcs = {
+	.enable = vop_crtc_enable,
+	.disable = vop_crtc_disable,
+	.mode_fixup = vop_crtc_mode_fixup,
+	.atomic_flush = vop_crtc_atomic_flush,
+	.atomic_begin = vop_crtc_atomic_begin,
+};
+
 static void vop_crtc_destroy(struct drm_crtc *crtc)
 {
 	drm_crtc_cleanup(crtc);
 }
 
 static const struct drm_crtc_funcs vop_crtc_funcs = {
-	.set_config = drm_crtc_helper_set_config,
-	.page_flip = vop_crtc_page_flip,
+	.set_config = drm_atomic_helper_set_config,
+	.page_flip = drm_atomic_helper_page_flip,
 	.destroy = vop_crtc_destroy,
+	.reset = drm_atomic_helper_crtc_reset,
+	.atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
+	.atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
 };
 
-static bool vop_win_state_is_active(struct vop_win *vop_win,
-				    struct vop_win_state *state)
+static bool vop_win_pending_is_complete(struct vop_win *vop_win)
 {
-	bool active = false;
-
-	if (state->fb) {
-		dma_addr_t yrgb_mst;
-
-		/* check yrgb_mst to tell if pending_fb is now front */
-		yrgb_mst = VOP_WIN_GET_YRGBADDR(vop_win->vop, vop_win->data);
-
-		active = (yrgb_mst == state->yrgb_mst);
-	} else {
-		bool enabled;
-
-		/* if enable bit is clear, plane is now disabled */
-		enabled = VOP_WIN_GET(vop_win->vop, vop_win->data, enable);
-
-		active = (enabled == 0);
-	}
-
-	return active;
-}
+	struct drm_plane *plane = &vop_win->base;
+	struct vop_plane_state *state = to_vop_plane_state(plane->state);
+	dma_addr_t yrgb_mst;
 
-static void vop_win_state_destroy(struct vop_win_state *state)
-{
-	struct drm_framebuffer *fb = state->fb;
+	if (!state->enable)
+		return VOP_WIN_GET(vop_win->vop, vop_win->data, enable) == 0;
 
-	if (fb)
-		drm_framebuffer_unreference(fb);
+	yrgb_mst = VOP_WIN_GET_YRGBADDR(vop_win->vop, vop_win->data);
 
-	kfree(state);
+	return yrgb_mst == state->yrgb_mst;
 }
 
-static void vop_win_update_state(struct vop_win *vop_win)
+static void vop_handle_vblank(struct vop *vop)
 {
-	struct vop_win_state *state, *n, *new_active = NULL;
-
-	/* Check if any pending states are now active */
-	list_for_each_entry(state, &vop_win->pending, head)
-		if (vop_win_state_is_active(vop_win, state)) {
-			new_active = state;
-			break;
-		}
-
-	if (!new_active)
-		return;
+	struct drm_device *drm = vop->drm_dev;
+	struct drm_crtc *crtc = &vop->crtc;
+	unsigned long flags;
+	int i;
 
-	/*
-	 * Destroy any 'skipped' pending states - states that were queued
-	 * before the newly active state.
-	 */
-	list_for_each_entry_safe(state, n, &vop_win->pending, head) {
-		if (state == new_active)
-			break;
-		vop_win_state_complete(vop_win, state);
-		vop_win_state_destroy(state);
+	for (i = 0; i < vop->data->win_size; i++) {
+		if (!vop_win_pending_is_complete(&vop->win[i]))
+			return;
 	}
 
-	vop_win_state_complete(vop_win, new_active);
-
-	if (vop_win->active)
-		vop_win_state_destroy(vop_win->active);
-	vop_win->active = new_active;
-}
-
-static bool vop_win_has_pending_state(struct vop_win *vop_win)
-{
-	return !list_empty(&vop_win->pending);
-}
-
-static irqreturn_t vop_isr_thread(int irq, void *data)
-{
-	struct vop *vop = data;
-	const struct vop_data *vop_data = vop->data;
-	unsigned int i;
-
-	mutex_lock(&vop->vsync_mutex);
-
-	if (!vop->vsync_work_pending)
-		goto done;
+	if (vop->event) {
+		spin_lock_irqsave(&drm->event_lock, flags);
 
-	vop->vsync_work_pending = false;
+		drm_crtc_send_vblank_event(crtc, vop->event);
+		drm_crtc_vblank_put(crtc);
+		vop->event = NULL;
 
-	for (i = 0; i < vop_data->win_size; i++) {
-		struct vop_win *vop_win = &vop->win[i];
-
-		vop_win_update_state(vop_win);
-		if (vop_win_has_pending_state(vop_win))
-			vop->vsync_work_pending = true;
+		spin_unlock_irqrestore(&drm->event_lock, flags);
 	}
-
-done:
-	mutex_unlock(&vop->vsync_mutex);
-
-	return IRQ_HANDLED;
+	if (!completion_done(&vop->wait_update_complete))
+		complete(&vop->wait_update_complete);
 }
 
 static irqreturn_t vop_isr(int irq, void *data)
@@ -1409,8 +1273,9 @@ static irqreturn_t vop_isr(int irq, void *data)
 
 	if (active_irqs & FS_INTR) {
 		drm_crtc_handle_vblank(crtc);
+		vop_handle_vblank(vop);
 		active_irqs &= ~FS_INTR;
-		ret = (vop->vsync_work_pending) ? IRQ_WAKE_THREAD : IRQ_HANDLED;
+		ret = IRQ_HANDLED;
 	}
 
 	/* Unhandled irqs are spurious. */
@@ -1455,6 +1320,7 @@ static int vop_create_crtc(struct vop *vop)
 		}
 
 		plane = &vop_win->base;
+		drm_plane_helper_add(plane, &plane_helper_funcs);
 		if (plane->type == DRM_PLANE_TYPE_PRIMARY)
 			primary = plane;
 		else if (plane->type == DRM_PLANE_TYPE_CURSOR)
@@ -1490,6 +1356,7 @@ static int vop_create_crtc(struct vop *vop)
 			DRM_ERROR("failed to initialize overlay plane\n");
 			goto err_cleanup_crtc;
 		}
+		drm_plane_helper_add(&vop_win->base, &plane_helper_funcs);
 	}
 
 	port = of_get_child_by_name(dev->of_node, "port");
@@ -1500,6 +1367,7 @@ static int vop_create_crtc(struct vop *vop)
 	}
 
 	init_completion(&vop->dsp_hold_completion);
+	init_completion(&vop->wait_update_complete);
 	crtc->port = port;
 	rockchip_register_crtc_funcs(crtc, &private_crtc_funcs);
 
@@ -1633,7 +1501,6 @@ static void vop_win_init(struct vop *vop)
 
 		vop_win->data = win_data;
 		vop_win->vop = vop;
-		INIT_LIST_HEAD(&vop_win->pending);
 	}
 }
 
@@ -1694,8 +1561,8 @@ static int vop_bind(struct device *dev, struct device *master, void *data)
 
 	mutex_init(&vop->vsync_mutex);
 
-	ret = devm_request_threaded_irq(dev, vop->irq, vop_isr, vop_isr_thread,
-					IRQF_SHARED, dev_name(dev), vop);
+	ret = devm_request_irq(dev, vop->irq, vop_isr,
+			       IRQF_SHARED, dev_name(dev), vop);
 	if (ret)
 		return ret;
 
-- 
1.7.9.5



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

* [PATCH v3 3/8] drm/rockchip: Convert to support atomic API
@ 2015-12-17  3:01   ` Mark Yao
  0 siblings, 0 replies; 51+ messages in thread
From: Mark Yao @ 2015-12-17  3:01 UTC (permalink / raw)
  To: David Airlie, Heiko Stuebner, dri-devel, linux-arm-kernel,
	linux-rockchip, linux-kernel
  Cc: Tomasz Figa

Rockchip vop not support hw vblank counter, needed check the committed
register if it's really take effect.

Signed-off-by: Mark Yao <mark.yao@rock-chips.com>
Signed-off-by: Tomasz Figa <tfiga@chromium.org>
---
Changes in v3:
Reported by kbuild test robot
- fix rockchip_crtc_wait_for_update undefined when build drm rockchip as modules.

Changes in v2:
- Optimization commit planes sequence.
- Get vblank count on atomic_begin to protect vblank event.
Adviced by Daniel Stone
- Direct return -EINVAL when yuv address is not support, instead of adjust it.
- code formating and cleanup.
Adviced by Thierry Reding & Daniel Vetter
- Hook mode_set into crtc enable instead of hack crtc enable on mode set.

 drivers/gpu/drm/rockchip/rockchip_drm_drv.c |    5 +-
 drivers/gpu/drm/rockchip/rockchip_drm_drv.h |    3 +-
 drivers/gpu/drm/rockchip/rockchip_drm_fb.c  |   95 ++++
 drivers/gpu/drm/rockchip/rockchip_drm_vop.c |  657 +++++++++++----------------
 4 files changed, 363 insertions(+), 397 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
index cfd9b83..ab3e0f6 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
@@ -213,6 +213,8 @@ static int rockchip_drm_load(struct drm_device *drm_dev, unsigned long flags)
 	 */
 	drm_dev->vblank_disable_allowed = true;
 
+	drm_mode_config_reset(drm_dev);
+
 	ret = rockchip_drm_fbdev_init(drm_dev);
 	if (ret)
 		goto err_vblank_cleanup;
@@ -276,7 +278,8 @@ const struct vm_operations_struct rockchip_drm_vm_ops = {
 };
 
 static struct drm_driver rockchip_drm_driver = {
-	.driver_features	= DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME,
+	.driver_features	= DRIVER_MODESET | DRIVER_GEM |
+				  DRIVER_PRIME | DRIVER_ATOMIC,
 	.load			= rockchip_drm_load,
 	.unload			= rockchip_drm_unload,
 	.lastclose		= rockchip_drm_lastclose,
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
index 069d6d4..4468f98 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
@@ -18,6 +18,7 @@
 #define _ROCKCHIP_DRM_DRV_H
 
 #include <drm/drm_fb_helper.h>
+#include <drm/drm_atomic_helper.h>
 #include <drm/drm_gem.h>
 
 #include <linux/module.h>
@@ -38,6 +39,7 @@ struct drm_connector;
 struct rockchip_crtc_funcs {
 	int (*enable_vblank)(struct drm_crtc *crtc);
 	void (*disable_vblank)(struct drm_crtc *crtc);
+	void (*wait_for_update)(struct drm_crtc *crtc);
 };
 
 /*
@@ -63,5 +65,4 @@ int rockchip_drm_dma_attach_device(struct drm_device *drm_dev,
 				   struct device *dev);
 void rockchip_drm_dma_detach_device(struct drm_device *drm_dev,
 				    struct device *dev);
-
 #endif /* _ROCKCHIP_DRM_DRV_H_ */
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
index b8ac591..7c974a4 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
@@ -15,6 +15,7 @@
 #include <linux/kernel.h>
 #include <drm/drm.h>
 #include <drm/drmP.h>
+#include <drm/drm_atomic.h>
 #include <drm/drm_fb_helper.h>
 #include <drm/drm_crtc_helper.h>
 
@@ -166,9 +167,103 @@ static void rockchip_drm_output_poll_changed(struct drm_device *dev)
 		drm_fb_helper_hotplug_event(fb_helper);
 }
 
+static void rockchip_crtc_wait_for_update(struct drm_crtc *crtc)
+{
+	struct rockchip_drm_private *priv = crtc->dev->dev_private;
+	int pipe = drm_crtc_index(crtc);
+	const struct rockchip_crtc_funcs *crtc_funcs = priv->crtc_funcs[pipe];
+
+	if (crtc_funcs && crtc_funcs->wait_for_update)
+		crtc_funcs->wait_for_update(crtc);
+}
+
+static void
+rockchip_atomic_wait_for_complete(struct drm_atomic_state *old_state)
+{
+	struct drm_crtc_state *old_crtc_state;
+	struct drm_crtc *crtc;
+	int i, ret;
+
+	for_each_crtc_in_state(old_state, crtc, old_crtc_state, i) {
+		/* No one cares about the old state, so abuse it for tracking
+		 * and store whether we hold a vblank reference (and should do a
+		 * vblank wait) in the ->enable boolean.
+		 */
+		old_crtc_state->enable = false;
+
+		if (!crtc->state->active)
+			continue;
+
+		ret = drm_crtc_vblank_get(crtc);
+		if (ret != 0)
+			continue;
+
+		old_crtc_state->enable = true;
+	}
+
+	for_each_crtc_in_state(old_state, crtc, old_crtc_state, i) {
+		if (!old_crtc_state->enable)
+			continue;
+
+		rockchip_crtc_wait_for_update(crtc);
+		drm_crtc_vblank_put(crtc);
+	}
+}
+
+int rockchip_drm_atomic_commit(struct drm_device *dev,
+			       struct drm_atomic_state *state,
+			       bool async)
+{
+	int ret;
+
+	if (async)
+		return -EBUSY;
+
+	ret = drm_atomic_helper_prepare_planes(dev, state);
+	if (ret)
+		return ret;
+
+	drm_atomic_helper_swap_state(dev, state);
+
+	/*
+	 * TODO: do fence wait here.
+	 */
+
+	/*
+	 * Rockchip crtc support runtime PM, can't update display planes
+	 * when crtc is disabled.
+	 *
+	 * drm_atomic_helper_commit comments detail that:
+	 *     For drivers supporting runtime PM the recommended sequence is
+	 *
+	 *     drm_atomic_helper_commit_modeset_disables(dev, state);
+	 *
+	 *     drm_atomic_helper_commit_modeset_enables(dev, state);
+	 *
+	 *     drm_atomic_helper_commit_planes(dev, state, true);
+	 *
+	 * See the kerneldoc entries for these three functions for more details.
+	 */
+	drm_atomic_helper_commit_modeset_disables(dev, state);
+
+	drm_atomic_helper_commit_modeset_enables(dev, state);
+
+	drm_atomic_helper_commit_planes(dev, state, true);
+
+	rockchip_atomic_wait_for_complete(state);
+
+	drm_atomic_helper_cleanup_planes(dev, state);
+
+	drm_atomic_state_free(state);
+
+	return 0;
+}
+
 static const struct drm_mode_config_funcs rockchip_drm_mode_config_funcs = {
 	.fb_create = rockchip_user_fb_create,
 	.output_poll_changed = rockchip_drm_output_poll_changed,
+	.atomic_check = drm_atomic_helper_check,
+	.atomic_commit = rockchip_drm_atomic_commit,
 };
 
 struct drm_framebuffer *
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index 1e60ddd..44f6154 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -14,6 +14,7 @@
 
 #include <drm/drm.h>
 #include <drm/drmP.h>
+#include <drm/drm_atomic.h>
 #include <drm/drm_crtc.h>
 #include <drm/drm_crtc_helper.h>
 #include <drm/drm_plane_helper.h>
@@ -63,12 +64,15 @@
 
 #define to_vop(x) container_of(x, struct vop, crtc)
 #define to_vop_win(x) container_of(x, struct vop_win, base)
+#define to_vop_plane_state(x) container_of(x, struct vop_plane_state, base)
 
-struct vop_win_state {
-	struct list_head head;
-	struct drm_framebuffer *fb;
+struct vop_plane_state {
+	struct drm_plane_state base;
+	int format;
+	struct drm_rect src;
+	struct drm_rect dest;
 	dma_addr_t yrgb_mst;
-	struct drm_pending_vblank_event *event;
+	bool enable;
 };
 
 struct vop_win {
@@ -76,8 +80,7 @@ struct vop_win {
 	const struct vop_win_data *data;
 	struct vop *vop;
 
-	struct list_head pending;
-	struct vop_win_state *active;
+	struct vop_plane_state state;
 };
 
 struct vop {
@@ -93,6 +96,8 @@ struct vop {
 	struct mutex vsync_mutex;
 	bool vsync_work_pending;
 	struct completion dsp_hold_completion;
+	struct completion wait_update_complete;
+	struct drm_pending_vblank_event *event;
 
 	const struct vop_data *data;
 
@@ -632,7 +637,7 @@ static void vop_dsp_hold_valid_irq_disable(struct vop *vop)
 	spin_unlock_irqrestore(&vop->irq_lock, flags);
 }
 
-static void vop_crtc_enable(struct drm_crtc *crtc)
+static void vop_enable(struct drm_crtc *crtc)
 {
 	struct vop *vop = to_vop(crtc);
 	int ret;
@@ -746,224 +751,188 @@ static void vop_crtc_disable(struct drm_crtc *crtc)
 	pm_runtime_put(vop->dev);
 }
 
-/*
- * Caller must hold vsync_mutex.
- */
-static struct drm_framebuffer *vop_win_last_pending_fb(struct vop_win *vop_win)
-{
-	struct vop_win_state *last;
-	struct vop_win_state *active = vop_win->active;
-
-	if (list_empty(&vop_win->pending))
-		return active ? active->fb : NULL;
-
-	last = list_last_entry(&vop_win->pending, struct vop_win_state, head);
-	return last ? last->fb : NULL;
-}
-
-/*
- * Caller must hold vsync_mutex.
- */
-static int vop_win_queue_fb(struct vop_win *vop_win,
-			    struct drm_framebuffer *fb, dma_addr_t yrgb_mst,
-			    struct drm_pending_vblank_event *event)
+static void vop_plane_destroy(struct drm_plane *plane)
 {
-	struct vop_win_state *state;
-
-	state = kzalloc(sizeof(*state), GFP_KERNEL);
-	if (!state)
-		return -ENOMEM;
-
-	state->fb = fb;
-	state->yrgb_mst = yrgb_mst;
-	state->event = event;
-
-	list_add_tail(&state->head, &vop_win->pending);
-
-	return 0;
+	drm_plane_cleanup(plane);
 }
 
-static int vop_update_plane_event(struct drm_plane *plane,
-				  struct drm_crtc *crtc,
-				  struct drm_framebuffer *fb, int crtc_x,
-				  int crtc_y, unsigned int crtc_w,
-				  unsigned int crtc_h, uint32_t src_x,
-				  uint32_t src_y, uint32_t src_w,
-				  uint32_t src_h,
-				  struct drm_pending_vblank_event *event)
+static int vop_plane_atomic_check(struct drm_plane *plane,
+			   struct drm_plane_state *state)
 {
+	struct drm_crtc *crtc = state->crtc;
+	struct drm_framebuffer *fb = state->fb;
 	struct vop_win *vop_win = to_vop_win(plane);
+	struct vop_plane_state *vop_plane_state = to_vop_plane_state(state);
 	const struct vop_win_data *win = vop_win->data;
-	struct vop *vop = to_vop(crtc);
-	struct drm_gem_object *obj;
-	struct rockchip_gem_object *rk_obj;
-	struct drm_gem_object *uv_obj;
-	struct rockchip_gem_object *rk_uv_obj;
-	unsigned long offset;
-	unsigned int actual_w;
-	unsigned int actual_h;
-	unsigned int dsp_stx;
-	unsigned int dsp_sty;
-	unsigned int y_vir_stride;
-	unsigned int uv_vir_stride = 0;
-	dma_addr_t yrgb_mst;
-	dma_addr_t uv_mst = 0;
-	enum vop_data_format format;
-	uint32_t val;
-	bool is_alpha;
-	bool rb_swap;
-	bool is_yuv;
 	bool visible;
 	int ret;
-	struct drm_rect dest = {
-		.x1 = crtc_x,
-		.y1 = crtc_y,
-		.x2 = crtc_x + crtc_w,
-		.y2 = crtc_y + crtc_h,
-	};
-	struct drm_rect src = {
-		/* 16.16 fixed point */
-		.x1 = src_x,
-		.y1 = src_y,
-		.x2 = src_x + src_w,
-		.y2 = src_y + src_h,
-	};
-	const struct drm_rect clip = {
-		.x2 = crtc->mode.hdisplay,
-		.y2 = crtc->mode.vdisplay,
-	};
-	bool can_position = plane->type != DRM_PLANE_TYPE_PRIMARY;
+	struct drm_rect *dest = &vop_plane_state->dest;
+	struct drm_rect *src = &vop_plane_state->src;
+	struct drm_rect clip;
 	int min_scale = win->phy->scl ? FRAC_16_16(1, 8) :
 					DRM_PLANE_HELPER_NO_SCALING;
 	int max_scale = win->phy->scl ? FRAC_16_16(8, 1) :
 					DRM_PLANE_HELPER_NO_SCALING;
 
-	ret = drm_plane_helper_check_update(plane, crtc, fb,
-					    &src, &dest, &clip,
+	crtc = crtc ? crtc : plane->state->crtc;
+	/*
+	 * Both crtc or plane->state->crtc can be null.
+	 */
+	if (!crtc || !fb)
+		goto out_disable;
+	src->x1 = state->src_x;
+	src->y1 = state->src_y;
+	src->x2 = state->src_x + state->src_w;
+	src->y2 = state->src_y + state->src_h;
+	dest->x1 = state->crtc_x;
+	dest->y1 = state->crtc_y;
+	dest->x2 = state->crtc_x + state->crtc_w;
+	dest->y2 = state->crtc_y + state->crtc_h;
+
+	clip.x1 = 0;
+	clip.y1 = 0;
+	clip.x2 = crtc->mode.hdisplay;
+	clip.y2 = crtc->mode.vdisplay;
+
+	ret = drm_plane_helper_check_update(plane, crtc, state->fb,
+					    src, dest, &clip,
 					    min_scale,
 					    max_scale,
-					    can_position, false, &visible);
+					    true, true, &visible);
 	if (ret)
 		return ret;
 
 	if (!visible)
-		return 0;
+		goto out_disable;
 
-	is_alpha = is_alpha_support(fb->pixel_format);
-	rb_swap = has_rb_swapped(fb->pixel_format);
-	is_yuv = is_yuv_support(fb->pixel_format);
+	vop_plane_state->format = vop_convert_format(fb->pixel_format);
+	if (vop_plane_state->format < 0)
+		return vop_plane_state->format;
 
-	format = vop_convert_format(fb->pixel_format);
-	if (format < 0)
-		return format;
-
-	obj = rockchip_fb_get_gem_obj(fb, 0);
-	if (!obj) {
-		DRM_ERROR("fail to get rockchip gem object from framebuffer\n");
+	/*
+	 * Src.x1 can be odd when do clip, but yuv plane start point
+	 * need align with 2 pixel.
+	 */
+	if (is_yuv_support(fb->pixel_format) && ((src->x1 >> 16) % 2))
 		return -EINVAL;
-	}
 
-	rk_obj = to_rockchip_obj(obj);
+	vop_plane_state->enable = true;
 
-	if (is_yuv) {
-		/*
-		 * Src.x1 can be odd when do clip, but yuv plane start point
-		 * need align with 2 pixel.
-		 */
-		val = (src.x1 >> 16) % 2;
-		src.x1 += val << 16;
-		src.x2 += val << 16;
-	}
+	return 0;
 
-	actual_w = (src.x2 - src.x1) >> 16;
-	actual_h = (src.y2 - src.y1) >> 16;
+out_disable:
+	vop_plane_state->enable = false;
+	return 0;
+}
 
-	dsp_stx = dest.x1 + crtc->mode.htotal - crtc->mode.hsync_start;
-	dsp_sty = dest.y1 + crtc->mode.vtotal - crtc->mode.vsync_start;
+static void vop_plane_atomic_disable(struct drm_plane *plane,
+				     struct drm_plane_state *old_state)
+{
+	struct vop_plane_state *vop_plane_state = to_vop_plane_state(old_state);
+	struct vop_win *vop_win = to_vop_win(plane);
+	const struct vop_win_data *win = vop_win->data;
+	struct vop *vop = to_vop(old_state->crtc);
 
-	offset = (src.x1 >> 16) * drm_format_plane_cpp(fb->pixel_format, 0);
-	offset += (src.y1 >> 16) * fb->pitches[0];
+	if (!old_state->crtc)
+		return;
 
-	yrgb_mst = rk_obj->dma_addr + offset + fb->offsets[0];
-	y_vir_stride = fb->pitches[0] >> 2;
+	spin_lock(&vop->reg_lock);
 
-	if (is_yuv) {
-		int hsub = drm_format_horz_chroma_subsampling(fb->pixel_format);
-		int vsub = drm_format_vert_chroma_subsampling(fb->pixel_format);
-		int bpp = drm_format_plane_cpp(fb->pixel_format, 1);
+	VOP_WIN_SET(vop, win, enable, 0);
 
-		uv_obj = rockchip_fb_get_gem_obj(fb, 1);
-		if (!uv_obj) {
-			DRM_ERROR("fail to get uv object from framebuffer\n");
-			return -EINVAL;
-		}
-		rk_uv_obj = to_rockchip_obj(uv_obj);
-		uv_vir_stride = fb->pitches[1] >> 2;
+	spin_unlock(&vop->reg_lock);
 
-		offset = (src.x1 >> 16) * bpp / hsub;
-		offset += (src.y1 >> 16) * fb->pitches[1] / vsub;
+	vop_plane_state->enable = false;
+}
 
-		uv_mst = rk_uv_obj->dma_addr + offset + fb->offsets[1];
-	}
+static void vop_plane_atomic_update(struct drm_plane *plane,
+		struct drm_plane_state *old_state)
+{
+	struct drm_plane_state *state = plane->state;
+	struct drm_crtc *crtc = state->crtc;
+	struct vop_win *vop_win = to_vop_win(plane);
+	struct vop_plane_state *vop_plane_state = to_vop_plane_state(state);
+	const struct vop_win_data *win = vop_win->data;
+	struct vop *vop = to_vop(state->crtc);
+	struct drm_framebuffer *fb = state->fb;
+	unsigned int actual_w, actual_h;
+	unsigned int dsp_stx, dsp_sty;
+	uint32_t act_info, dsp_info, dsp_st;
+	struct drm_rect *src = &vop_plane_state->src;
+	struct drm_rect *dest = &vop_plane_state->dest;
+	struct drm_gem_object *obj, *uv_obj;
+	struct rockchip_gem_object *rk_obj, *rk_uv_obj;
+	unsigned long offset;
+	dma_addr_t dma_addr;
+	uint32_t val;
+	bool rb_swap;
 
 	/*
-	 * If this plane update changes the plane's framebuffer, (or more
-	 * precisely, if this update has a different framebuffer than the last
-	 * update), enqueue it so we can track when it completes.
-	 *
-	 * Only when we discover that this update has completed, can we
-	 * unreference any previous framebuffers.
+	 * can't update plane when vop is disabled.
 	 */
-	mutex_lock(&vop->vsync_mutex);
-	if (fb != vop_win_last_pending_fb(vop_win)) {
-		ret = drm_crtc_vblank_get(crtc);
-		if (ret) {
-			DRM_ERROR("failed to get vblank, %d\n", ret);
-			mutex_unlock(&vop->vsync_mutex);
-			return ret;
-		}
-
-		drm_framebuffer_reference(fb);
+	if (!crtc)
+		return;
 
-		ret = vop_win_queue_fb(vop_win, fb, yrgb_mst, event);
-		if (ret) {
-			drm_crtc_vblank_put(crtc);
-			mutex_unlock(&vop->vsync_mutex);
-			return ret;
-		}
+	if (WARN_ON(!vop->is_enabled))
+		return;
 
-		vop->vsync_work_pending = true;
+	if (!vop_plane_state->enable) {
+		vop_plane_atomic_disable(plane, old_state);
+		return;
 	}
-	mutex_unlock(&vop->vsync_mutex);
+
+	obj = rockchip_fb_get_gem_obj(fb, 0);
+	rk_obj = to_rockchip_obj(obj);
+
+	actual_w = drm_rect_width(src) >> 16;
+	actual_h = drm_rect_height(src) >> 16;
+	act_info = (actual_h - 1) << 16 | ((actual_w - 1) & 0xffff);
+
+	dsp_info = (drm_rect_height(dest) - 1) << 16;
+	dsp_info |= (drm_rect_width(dest) - 1) & 0xffff;
+
+	dsp_stx = dest->x1 + crtc->mode.htotal - crtc->mode.hsync_start;
+	dsp_sty = dest->y1 + crtc->mode.vtotal - crtc->mode.vsync_start;
+	dsp_st = dsp_sty << 16 | (dsp_stx & 0xffff);
+
+	offset = (src->x1 >> 16) * drm_format_plane_cpp(fb->pixel_format, 0);
+	offset += (src->y1 >> 16) * fb->pitches[0];
+	vop_plane_state->yrgb_mst = rk_obj->dma_addr + offset + fb->offsets[0];
 
 	spin_lock(&vop->reg_lock);
 
-	VOP_WIN_SET(vop, win, format, format);
-	VOP_WIN_SET(vop, win, yrgb_vir, y_vir_stride);
-	VOP_WIN_SET(vop, win, yrgb_mst, yrgb_mst);
-	if (is_yuv) {
-		VOP_WIN_SET(vop, win, uv_vir, uv_vir_stride);
-		VOP_WIN_SET(vop, win, uv_mst, uv_mst);
+	VOP_WIN_SET(vop, win, format, vop_plane_state->format);
+	VOP_WIN_SET(vop, win, yrgb_vir, fb->pitches[0] >> 2);
+	VOP_WIN_SET(vop, win, yrgb_mst, vop_plane_state->yrgb_mst);
+	if (is_yuv_support(fb->pixel_format)) {
+		int hsub = drm_format_horz_chroma_subsampling(fb->pixel_format);
+		int vsub = drm_format_vert_chroma_subsampling(fb->pixel_format);
+		int bpp = drm_format_plane_cpp(fb->pixel_format, 1);
+
+		uv_obj = rockchip_fb_get_gem_obj(fb, 1);
+		rk_uv_obj = to_rockchip_obj(uv_obj);
+
+		offset = (src->x1 >> 16) * bpp / hsub;
+		offset += (src->y1 >> 16) * fb->pitches[1] / vsub;
+
+		dma_addr = rk_uv_obj->dma_addr + offset + fb->offsets[1];
+		VOP_WIN_SET(vop, win, uv_vir, fb->pitches[1] >> 2);
+		VOP_WIN_SET(vop, win, uv_mst, dma_addr);
 	}
 
 	if (win->phy->scl)
 		scl_vop_cal_scl_fac(vop, win, actual_w, actual_h,
-				    dest.x2 - dest.x1, dest.y2 - dest.y1,
+				    drm_rect_width(dest), drm_rect_height(dest),
 				    fb->pixel_format);
 
-	val = (actual_h - 1) << 16;
-	val |= (actual_w - 1) & 0xffff;
-	VOP_WIN_SET(vop, win, act_info, val);
+	VOP_WIN_SET(vop, win, act_info, act_info);
+	VOP_WIN_SET(vop, win, dsp_info, dsp_info);
+	VOP_WIN_SET(vop, win, dsp_st, dsp_st);
 
-	val = (dest.y2 - dest.y1 - 1) << 16;
-	val |= (dest.x2 - dest.x1 - 1) & 0xffff;
-	VOP_WIN_SET(vop, win, dsp_info, val);
-	val = dsp_sty << 16;
-	val |= dsp_stx & 0xffff;
-	VOP_WIN_SET(vop, win, dsp_st, val);
+	rb_swap = has_rb_swapped(fb->pixel_format);
 	VOP_WIN_SET(vop, win, rb_swap, rb_swap);
 
-	if (is_alpha) {
+	if (is_alpha_support(fb->pixel_format)) {
 		VOP_WIN_SET(vop, win, dst_alpha_ctl,
 			    DST_FACTOR_M0(ALPHA_SRC_INVERSE));
 		val = SRC_ALPHA_EN(1) | SRC_COLOR_M0(ALPHA_SRC_PRE_MUL) |
@@ -977,86 +946,70 @@ static int vop_update_plane_event(struct drm_plane *plane,
 	}
 
 	VOP_WIN_SET(vop, win, enable, 1);
-
-	vop_cfg_done(vop);
 	spin_unlock(&vop->reg_lock);
-
-	return 0;
 }
 
-static int vop_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
-			    struct drm_framebuffer *fb, int crtc_x, int crtc_y,
-			    unsigned int crtc_w, unsigned int crtc_h,
-			    uint32_t src_x, uint32_t src_y, uint32_t src_w,
-			    uint32_t src_h)
-{
-	return vop_update_plane_event(plane, crtc, fb, crtc_x, crtc_y, crtc_w,
-				      crtc_h, src_x, src_y, src_w, src_h,
-				      NULL);
-}
+static const struct drm_plane_helper_funcs plane_helper_funcs = {
+	.atomic_check = vop_plane_atomic_check,
+	.atomic_update = vop_plane_atomic_update,
+	.atomic_disable = vop_plane_atomic_disable,
+};
 
-static int vop_update_primary_plane(struct drm_crtc *crtc,
-				    struct drm_pending_vblank_event *event)
+void vop_atomic_plane_reset(struct drm_plane *plane)
 {
-	unsigned int crtc_w, crtc_h;
+	struct vop_plane_state *vop_plane_state =
+					to_vop_plane_state(plane->state);
 
-	crtc_w = crtc->primary->fb->width - crtc->x;
-	crtc_h = crtc->primary->fb->height - crtc->y;
+	if (plane->state && plane->state->fb)
+		drm_framebuffer_unreference(plane->state->fb);
+
+	kfree(vop_plane_state);
+	vop_plane_state = kzalloc(sizeof(*vop_plane_state), GFP_KERNEL);
+	if (!vop_plane_state)
+		return;
 
-	return vop_update_plane_event(crtc->primary, crtc, crtc->primary->fb,
-				      0, 0, crtc_w, crtc_h, crtc->x << 16,
-				      crtc->y << 16, crtc_w << 16,
-				      crtc_h << 16, event);
+	plane->state = &vop_plane_state->base;
+	plane->state->plane = plane;
 }
 
-static int vop_disable_plane(struct drm_plane *plane)
+struct drm_plane_state *
+vop_atomic_plane_duplicate_state(struct drm_plane *plane)
 {
-	struct vop_win *vop_win = to_vop_win(plane);
-	const struct vop_win_data *win = vop_win->data;
-	struct vop *vop;
-	int ret;
-
-	if (!plane->crtc)
-		return 0;
+	struct vop_plane_state *old_vop_plane_state;
+	struct vop_plane_state *vop_plane_state;
 
-	vop = to_vop(plane->crtc);
+	if (WARN_ON(!plane->state))
+		return NULL;
 
-	ret = drm_crtc_vblank_get(plane->crtc);
-	if (ret) {
-		DRM_ERROR("failed to get vblank, %d\n", ret);
-		return ret;
-	}
+	old_vop_plane_state = to_vop_plane_state(plane->state);
+	vop_plane_state = kmemdup(old_vop_plane_state,
+				  sizeof(*vop_plane_state), GFP_KERNEL);
+	if (!vop_plane_state)
+		return NULL;
 
-	mutex_lock(&vop->vsync_mutex);
+	__drm_atomic_helper_plane_duplicate_state(plane,
+						  &vop_plane_state->base);
 
-	ret = vop_win_queue_fb(vop_win, NULL, 0, NULL);
-	if (ret) {
-		drm_crtc_vblank_put(plane->crtc);
-		mutex_unlock(&vop->vsync_mutex);
-		return ret;
-	}
-
-	vop->vsync_work_pending = true;
-	mutex_unlock(&vop->vsync_mutex);
-
-	spin_lock(&vop->reg_lock);
-	VOP_WIN_SET(vop, win, enable, 0);
-	vop_cfg_done(vop);
-	spin_unlock(&vop->reg_lock);
-
-	return 0;
+	return &vop_plane_state->base;
 }
 
-static void vop_plane_destroy(struct drm_plane *plane)
+static void vop_atomic_plane_destroy_state(struct drm_plane *plane,
+					   struct drm_plane_state *state)
 {
-	vop_disable_plane(plane);
-	drm_plane_cleanup(plane);
+	struct vop_plane_state *vop_state = to_vop_plane_state(state);
+
+	__drm_atomic_helper_plane_destroy_state(plane, state);
+
+	kfree(vop_state);
 }
 
 static const struct drm_plane_funcs vop_plane_funcs = {
-	.update_plane = vop_update_plane,
-	.disable_plane = vop_disable_plane,
+	.update_plane	= drm_atomic_helper_update_plane,
+	.disable_plane	= drm_atomic_helper_disable_plane,
 	.destroy = vop_plane_destroy,
+	.reset = vop_atomic_plane_reset,
+	.atomic_duplicate_state = vop_atomic_plane_duplicate_state,
+	.atomic_destroy_state = vop_atomic_plane_destroy_state,
 };
 
 int rockchip_drm_crtc_mode_config(struct drm_crtc *crtc,
@@ -1077,7 +1030,7 @@ static int vop_crtc_enable_vblank(struct drm_crtc *crtc)
 	struct vop *vop = to_vop(crtc);
 	unsigned long flags;
 
-	if (!vop->is_enabled)
+	if (WARN_ON(!vop->is_enabled))
 		return -EPERM;
 
 	spin_lock_irqsave(&vop->irq_lock, flags);
@@ -1094,7 +1047,7 @@ static void vop_crtc_disable_vblank(struct drm_crtc *crtc)
 	struct vop *vop = to_vop(crtc);
 	unsigned long flags;
 
-	if (!vop->is_enabled)
+	if (WARN_ON(!vop->is_enabled))
 		return;
 
 	spin_lock_irqsave(&vop->irq_lock, flags);
@@ -1102,9 +1055,18 @@ static void vop_crtc_disable_vblank(struct drm_crtc *crtc)
 	spin_unlock_irqrestore(&vop->irq_lock, flags);
 }
 
+static void vop_crtc_wait_for_update(struct drm_crtc *crtc)
+{
+	struct vop *vop = to_vop(crtc);
+
+	reinit_completion(&vop->wait_update_complete);
+	WARN_ON(!wait_for_completion_timeout(&vop->wait_update_complete, 100));
+}
+
 static const struct rockchip_crtc_funcs private_crtc_funcs = {
 	.enable_vblank = vop_crtc_enable_vblank,
 	.disable_vblank = vop_crtc_disable_vblank,
+	.wait_for_update = vop_crtc_wait_for_update,
 };
 
 static bool vop_crtc_mode_fixup(struct drm_crtc *crtc,
@@ -1117,29 +1079,10 @@ static bool vop_crtc_mode_fixup(struct drm_crtc *crtc,
 	return true;
 }
 
-static int vop_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
-				  struct drm_framebuffer *old_fb)
-{
-	int ret;
-
-	crtc->x = x;
-	crtc->y = y;
-
-	ret = vop_update_primary_plane(crtc, NULL);
-	if (ret < 0) {
-		DRM_ERROR("fail to update plane\n");
-		return ret;
-	}
-
-	return 0;
-}
-
-static int vop_crtc_mode_set(struct drm_crtc *crtc,
-			     struct drm_display_mode *mode,
-			     struct drm_display_mode *adjusted_mode,
-			     int x, int y, struct drm_framebuffer *fb)
+static void vop_crtc_enable(struct drm_crtc *crtc)
 {
 	struct vop *vop = to_vop(crtc);
+	struct drm_display_mode *adjusted_mode = &crtc->state->adjusted_mode;
 	u16 hsync_len = adjusted_mode->hsync_end - adjusted_mode->hsync_start;
 	u16 hdisplay = adjusted_mode->hdisplay;
 	u16 htotal = adjusted_mode->htotal;
@@ -1150,9 +1093,9 @@ static int vop_crtc_mode_set(struct drm_crtc *crtc,
 	u16 vsync_len = adjusted_mode->vsync_end - adjusted_mode->vsync_start;
 	u16 vact_st = adjusted_mode->vtotal - adjusted_mode->vsync_start;
 	u16 vact_end = vact_st + vdisplay;
-	int ret, ret_clk;
 	uint32_t val;
 
+	vop_enable(crtc);
 	/*
 	 * disable dclk to stop frame scan, so that we can safe config mode and
 	 * enable iommu.
@@ -1172,7 +1115,6 @@ static int vop_crtc_mode_set(struct drm_crtc *crtc,
 	default:
 		DRM_ERROR("unsupport connector_type[%d]\n",
 			  vop->connector_type);
-		ret = -EINVAL;
 		goto out;
 	};
 	VOP_CTRL_SET(vop, out_mode, vop->connector_out_mode);
@@ -1194,9 +1136,6 @@ static int vop_crtc_mode_set(struct drm_crtc *crtc,
 	VOP_CTRL_SET(vop, vact_st_end, val);
 	VOP_CTRL_SET(vop, vpost_st_end, val);
 
-	ret = vop_crtc_mode_set_base(crtc, x, y, fb);
-	if (ret)
-		goto out;
 
 	/*
 	 * reset dclk, take all mode config affect, so the clk would run in
@@ -1208,172 +1147,97 @@ static int vop_crtc_mode_set(struct drm_crtc *crtc,
 
 	clk_set_rate(vop->dclk, adjusted_mode->clock * 1000);
 out:
-	ret_clk = clk_enable(vop->dclk);
-	if (ret_clk < 0) {
-		dev_err(vop->dev, "failed to enable dclk - %d\n", ret_clk);
-		return ret_clk;
-	}
-
-	return ret;
+	if (clk_enable(vop->dclk) < 0)
+		dev_err(vop->dev, "failed to enable dclk\n");
 }
 
-static const struct drm_crtc_helper_funcs vop_crtc_helper_funcs = {
-	.enable = vop_crtc_enable,
-	.disable = vop_crtc_disable,
-	.mode_fixup = vop_crtc_mode_fixup,
-	.mode_set = vop_crtc_mode_set,
-	.mode_set_base = vop_crtc_mode_set_base,
-};
-
-static int vop_crtc_page_flip(struct drm_crtc *crtc,
-			      struct drm_framebuffer *fb,
-			      struct drm_pending_vblank_event *event,
-			      uint32_t page_flip_flags)
+static void vop_crtc_atomic_flush(struct drm_crtc *crtc,
+				  struct drm_crtc_state *old_crtc_state)
 {
 	struct vop *vop = to_vop(crtc);
-	struct drm_framebuffer *old_fb = crtc->primary->fb;
-	int ret;
 
-	/* when the page flip is requested, crtc should be on */
-	if (!vop->is_enabled) {
-		DRM_DEBUG("page flip request rejected because crtc is off.\n");
-		return 0;
-	}
+	if (WARN_ON(!vop->is_enabled))
+		return;
 
-	crtc->primary->fb = fb;
+	spin_lock(&vop->reg_lock);
 
-	ret = vop_update_primary_plane(crtc, event);
-	if (ret)
-		crtc->primary->fb = old_fb;
+	vop_cfg_done(vop);
 
-	return ret;
+	spin_unlock(&vop->reg_lock);
 }
 
-static void vop_win_state_complete(struct vop_win *vop_win,
-				   struct vop_win_state *state)
+static void vop_crtc_atomic_begin(struct drm_crtc *crtc,
+				  struct drm_crtc_state *old_crtc_state)
 {
-	struct vop *vop = vop_win->vop;
-	struct drm_crtc *crtc = &vop->crtc;
-	struct drm_device *drm = crtc->dev;
-	unsigned long flags;
+	struct vop *vop = to_vop(crtc);
 
-	if (state->event) {
-		spin_lock_irqsave(&drm->event_lock, flags);
-		drm_crtc_send_vblank_event(crtc, state->event);
-		spin_unlock_irqrestore(&drm->event_lock, flags);
-	}
+	if (crtc->state->event) {
+		WARN_ON(drm_crtc_vblank_get(crtc) != 0);
 
-	list_del(&state->head);
-	drm_crtc_vblank_put(crtc);
+		vop->event = crtc->state->event;
+		crtc->state->event = NULL;
+	}
 }
 
+static const struct drm_crtc_helper_funcs vop_crtc_helper_funcs = {
+	.enable = vop_crtc_enable,
+	.disable = vop_crtc_disable,
+	.mode_fixup = vop_crtc_mode_fixup,
+	.atomic_flush = vop_crtc_atomic_flush,
+	.atomic_begin = vop_crtc_atomic_begin,
+};
+
 static void vop_crtc_destroy(struct drm_crtc *crtc)
 {
 	drm_crtc_cleanup(crtc);
 }
 
 static const struct drm_crtc_funcs vop_crtc_funcs = {
-	.set_config = drm_crtc_helper_set_config,
-	.page_flip = vop_crtc_page_flip,
+	.set_config = drm_atomic_helper_set_config,
+	.page_flip = drm_atomic_helper_page_flip,
 	.destroy = vop_crtc_destroy,
+	.reset = drm_atomic_helper_crtc_reset,
+	.atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
+	.atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
 };
 
-static bool vop_win_state_is_active(struct vop_win *vop_win,
-				    struct vop_win_state *state)
+static bool vop_win_pending_is_complete(struct vop_win *vop_win)
 {
-	bool active = false;
-
-	if (state->fb) {
-		dma_addr_t yrgb_mst;
-
-		/* check yrgb_mst to tell if pending_fb is now front */
-		yrgb_mst = VOP_WIN_GET_YRGBADDR(vop_win->vop, vop_win->data);
-
-		active = (yrgb_mst == state->yrgb_mst);
-	} else {
-		bool enabled;
-
-		/* if enable bit is clear, plane is now disabled */
-		enabled = VOP_WIN_GET(vop_win->vop, vop_win->data, enable);
-
-		active = (enabled == 0);
-	}
-
-	return active;
-}
+	struct drm_plane *plane = &vop_win->base;
+	struct vop_plane_state *state = to_vop_plane_state(plane->state);
+	dma_addr_t yrgb_mst;
 
-static void vop_win_state_destroy(struct vop_win_state *state)
-{
-	struct drm_framebuffer *fb = state->fb;
+	if (!state->enable)
+		return VOP_WIN_GET(vop_win->vop, vop_win->data, enable) == 0;
 
-	if (fb)
-		drm_framebuffer_unreference(fb);
+	yrgb_mst = VOP_WIN_GET_YRGBADDR(vop_win->vop, vop_win->data);
 
-	kfree(state);
+	return yrgb_mst == state->yrgb_mst;
 }
 
-static void vop_win_update_state(struct vop_win *vop_win)
+static void vop_handle_vblank(struct vop *vop)
 {
-	struct vop_win_state *state, *n, *new_active = NULL;
-
-	/* Check if any pending states are now active */
-	list_for_each_entry(state, &vop_win->pending, head)
-		if (vop_win_state_is_active(vop_win, state)) {
-			new_active = state;
-			break;
-		}
-
-	if (!new_active)
-		return;
+	struct drm_device *drm = vop->drm_dev;
+	struct drm_crtc *crtc = &vop->crtc;
+	unsigned long flags;
+	int i;
 
-	/*
-	 * Destroy any 'skipped' pending states - states that were queued
-	 * before the newly active state.
-	 */
-	list_for_each_entry_safe(state, n, &vop_win->pending, head) {
-		if (state == new_active)
-			break;
-		vop_win_state_complete(vop_win, state);
-		vop_win_state_destroy(state);
+	for (i = 0; i < vop->data->win_size; i++) {
+		if (!vop_win_pending_is_complete(&vop->win[i]))
+			return;
 	}
 
-	vop_win_state_complete(vop_win, new_active);
-
-	if (vop_win->active)
-		vop_win_state_destroy(vop_win->active);
-	vop_win->active = new_active;
-}
-
-static bool vop_win_has_pending_state(struct vop_win *vop_win)
-{
-	return !list_empty(&vop_win->pending);
-}
-
-static irqreturn_t vop_isr_thread(int irq, void *data)
-{
-	struct vop *vop = data;
-	const struct vop_data *vop_data = vop->data;
-	unsigned int i;
-
-	mutex_lock(&vop->vsync_mutex);
-
-	if (!vop->vsync_work_pending)
-		goto done;
+	if (vop->event) {
+		spin_lock_irqsave(&drm->event_lock, flags);
 
-	vop->vsync_work_pending = false;
+		drm_crtc_send_vblank_event(crtc, vop->event);
+		drm_crtc_vblank_put(crtc);
+		vop->event = NULL;
 
-	for (i = 0; i < vop_data->win_size; i++) {
-		struct vop_win *vop_win = &vop->win[i];
-
-		vop_win_update_state(vop_win);
-		if (vop_win_has_pending_state(vop_win))
-			vop->vsync_work_pending = true;
+		spin_unlock_irqrestore(&drm->event_lock, flags);
 	}
-
-done:
-	mutex_unlock(&vop->vsync_mutex);
-
-	return IRQ_HANDLED;
+	if (!completion_done(&vop->wait_update_complete))
+		complete(&vop->wait_update_complete);
 }
 
 static irqreturn_t vop_isr(int irq, void *data)
@@ -1409,8 +1273,9 @@ static irqreturn_t vop_isr(int irq, void *data)
 
 	if (active_irqs & FS_INTR) {
 		drm_crtc_handle_vblank(crtc);
+		vop_handle_vblank(vop);
 		active_irqs &= ~FS_INTR;
-		ret = (vop->vsync_work_pending) ? IRQ_WAKE_THREAD : IRQ_HANDLED;
+		ret = IRQ_HANDLED;
 	}
 
 	/* Unhandled irqs are spurious. */
@@ -1455,6 +1320,7 @@ static int vop_create_crtc(struct vop *vop)
 		}
 
 		plane = &vop_win->base;
+		drm_plane_helper_add(plane, &plane_helper_funcs);
 		if (plane->type == DRM_PLANE_TYPE_PRIMARY)
 			primary = plane;
 		else if (plane->type == DRM_PLANE_TYPE_CURSOR)
@@ -1490,6 +1356,7 @@ static int vop_create_crtc(struct vop *vop)
 			DRM_ERROR("failed to initialize overlay plane\n");
 			goto err_cleanup_crtc;
 		}
+		drm_plane_helper_add(&vop_win->base, &plane_helper_funcs);
 	}
 
 	port = of_get_child_by_name(dev->of_node, "port");
@@ -1500,6 +1367,7 @@ static int vop_create_crtc(struct vop *vop)
 	}
 
 	init_completion(&vop->dsp_hold_completion);
+	init_completion(&vop->wait_update_complete);
 	crtc->port = port;
 	rockchip_register_crtc_funcs(crtc, &private_crtc_funcs);
 
@@ -1633,7 +1501,6 @@ static void vop_win_init(struct vop *vop)
 
 		vop_win->data = win_data;
 		vop_win->vop = vop;
-		INIT_LIST_HEAD(&vop_win->pending);
 	}
 }
 
@@ -1694,8 +1561,8 @@ static int vop_bind(struct device *dev, struct device *master, void *data)
 
 	mutex_init(&vop->vsync_mutex);
 
-	ret = devm_request_threaded_irq(dev, vop->irq, vop_isr, vop_isr_thread,
-					IRQF_SHARED, dev_name(dev), vop);
+	ret = devm_request_irq(dev, vop->irq, vop_isr,
+			       IRQF_SHARED, dev_name(dev), vop);
 	if (ret)
 		return ret;
 
-- 
1.7.9.5


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

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

* [PATCH v3 3/8] drm/rockchip: Convert to support atomic API
@ 2015-12-17  3:01   ` Mark Yao
  0 siblings, 0 replies; 51+ messages in thread
From: Mark Yao @ 2015-12-17  3:01 UTC (permalink / raw)
  To: linux-arm-kernel

Rockchip vop not support hw vblank counter, needed check the committed
register if it's really take effect.

Signed-off-by: Mark Yao <mark.yao@rock-chips.com>
Signed-off-by: Tomasz Figa <tfiga@chromium.org>
---
Changes in v3:
Reported by kbuild test robot
- fix rockchip_crtc_wait_for_update undefined when build drm rockchip as modules.

Changes in v2:
- Optimization commit planes sequence.
- Get vblank count on atomic_begin to protect vblank event.
Adviced by Daniel Stone
- Direct return -EINVAL when yuv address is not support, instead of adjust it.
- code formating and cleanup.
Adviced by Thierry Reding & Daniel Vetter
- Hook mode_set into crtc enable instead of hack crtc enable on mode set.

 drivers/gpu/drm/rockchip/rockchip_drm_drv.c |    5 +-
 drivers/gpu/drm/rockchip/rockchip_drm_drv.h |    3 +-
 drivers/gpu/drm/rockchip/rockchip_drm_fb.c  |   95 ++++
 drivers/gpu/drm/rockchip/rockchip_drm_vop.c |  657 +++++++++++----------------
 4 files changed, 363 insertions(+), 397 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
index cfd9b83..ab3e0f6 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
@@ -213,6 +213,8 @@ static int rockchip_drm_load(struct drm_device *drm_dev, unsigned long flags)
 	 */
 	drm_dev->vblank_disable_allowed = true;
 
+	drm_mode_config_reset(drm_dev);
+
 	ret = rockchip_drm_fbdev_init(drm_dev);
 	if (ret)
 		goto err_vblank_cleanup;
@@ -276,7 +278,8 @@ const struct vm_operations_struct rockchip_drm_vm_ops = {
 };
 
 static struct drm_driver rockchip_drm_driver = {
-	.driver_features	= DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME,
+	.driver_features	= DRIVER_MODESET | DRIVER_GEM |
+				  DRIVER_PRIME | DRIVER_ATOMIC,
 	.load			= rockchip_drm_load,
 	.unload			= rockchip_drm_unload,
 	.lastclose		= rockchip_drm_lastclose,
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
index 069d6d4..4468f98 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
@@ -18,6 +18,7 @@
 #define _ROCKCHIP_DRM_DRV_H
 
 #include <drm/drm_fb_helper.h>
+#include <drm/drm_atomic_helper.h>
 #include <drm/drm_gem.h>
 
 #include <linux/module.h>
@@ -38,6 +39,7 @@ struct drm_connector;
 struct rockchip_crtc_funcs {
 	int (*enable_vblank)(struct drm_crtc *crtc);
 	void (*disable_vblank)(struct drm_crtc *crtc);
+	void (*wait_for_update)(struct drm_crtc *crtc);
 };
 
 /*
@@ -63,5 +65,4 @@ int rockchip_drm_dma_attach_device(struct drm_device *drm_dev,
 				   struct device *dev);
 void rockchip_drm_dma_detach_device(struct drm_device *drm_dev,
 				    struct device *dev);
-
 #endif /* _ROCKCHIP_DRM_DRV_H_ */
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
index b8ac591..7c974a4 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
@@ -15,6 +15,7 @@
 #include <linux/kernel.h>
 #include <drm/drm.h>
 #include <drm/drmP.h>
+#include <drm/drm_atomic.h>
 #include <drm/drm_fb_helper.h>
 #include <drm/drm_crtc_helper.h>
 
@@ -166,9 +167,103 @@ static void rockchip_drm_output_poll_changed(struct drm_device *dev)
 		drm_fb_helper_hotplug_event(fb_helper);
 }
 
+static void rockchip_crtc_wait_for_update(struct drm_crtc *crtc)
+{
+	struct rockchip_drm_private *priv = crtc->dev->dev_private;
+	int pipe = drm_crtc_index(crtc);
+	const struct rockchip_crtc_funcs *crtc_funcs = priv->crtc_funcs[pipe];
+
+	if (crtc_funcs && crtc_funcs->wait_for_update)
+		crtc_funcs->wait_for_update(crtc);
+}
+
+static void
+rockchip_atomic_wait_for_complete(struct drm_atomic_state *old_state)
+{
+	struct drm_crtc_state *old_crtc_state;
+	struct drm_crtc *crtc;
+	int i, ret;
+
+	for_each_crtc_in_state(old_state, crtc, old_crtc_state, i) {
+		/* No one cares about the old state, so abuse it for tracking
+		 * and store whether we hold a vblank reference (and should do a
+		 * vblank wait) in the ->enable boolean.
+		 */
+		old_crtc_state->enable = false;
+
+		if (!crtc->state->active)
+			continue;
+
+		ret = drm_crtc_vblank_get(crtc);
+		if (ret != 0)
+			continue;
+
+		old_crtc_state->enable = true;
+	}
+
+	for_each_crtc_in_state(old_state, crtc, old_crtc_state, i) {
+		if (!old_crtc_state->enable)
+			continue;
+
+		rockchip_crtc_wait_for_update(crtc);
+		drm_crtc_vblank_put(crtc);
+	}
+}
+
+int rockchip_drm_atomic_commit(struct drm_device *dev,
+			       struct drm_atomic_state *state,
+			       bool async)
+{
+	int ret;
+
+	if (async)
+		return -EBUSY;
+
+	ret = drm_atomic_helper_prepare_planes(dev, state);
+	if (ret)
+		return ret;
+
+	drm_atomic_helper_swap_state(dev, state);
+
+	/*
+	 * TODO: do fence wait here.
+	 */
+
+	/*
+	 * Rockchip crtc support runtime PM, can't update display planes
+	 * when crtc is disabled.
+	 *
+	 * drm_atomic_helper_commit comments detail that:
+	 *     For drivers supporting runtime PM the recommended sequence is
+	 *
+	 *     drm_atomic_helper_commit_modeset_disables(dev, state);
+	 *
+	 *     drm_atomic_helper_commit_modeset_enables(dev, state);
+	 *
+	 *     drm_atomic_helper_commit_planes(dev, state, true);
+	 *
+	 * See the kerneldoc entries for these three functions for more details.
+	 */
+	drm_atomic_helper_commit_modeset_disables(dev, state);
+
+	drm_atomic_helper_commit_modeset_enables(dev, state);
+
+	drm_atomic_helper_commit_planes(dev, state, true);
+
+	rockchip_atomic_wait_for_complete(state);
+
+	drm_atomic_helper_cleanup_planes(dev, state);
+
+	drm_atomic_state_free(state);
+
+	return 0;
+}
+
 static const struct drm_mode_config_funcs rockchip_drm_mode_config_funcs = {
 	.fb_create = rockchip_user_fb_create,
 	.output_poll_changed = rockchip_drm_output_poll_changed,
+	.atomic_check = drm_atomic_helper_check,
+	.atomic_commit = rockchip_drm_atomic_commit,
 };
 
 struct drm_framebuffer *
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index 1e60ddd..44f6154 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -14,6 +14,7 @@
 
 #include <drm/drm.h>
 #include <drm/drmP.h>
+#include <drm/drm_atomic.h>
 #include <drm/drm_crtc.h>
 #include <drm/drm_crtc_helper.h>
 #include <drm/drm_plane_helper.h>
@@ -63,12 +64,15 @@
 
 #define to_vop(x) container_of(x, struct vop, crtc)
 #define to_vop_win(x) container_of(x, struct vop_win, base)
+#define to_vop_plane_state(x) container_of(x, struct vop_plane_state, base)
 
-struct vop_win_state {
-	struct list_head head;
-	struct drm_framebuffer *fb;
+struct vop_plane_state {
+	struct drm_plane_state base;
+	int format;
+	struct drm_rect src;
+	struct drm_rect dest;
 	dma_addr_t yrgb_mst;
-	struct drm_pending_vblank_event *event;
+	bool enable;
 };
 
 struct vop_win {
@@ -76,8 +80,7 @@ struct vop_win {
 	const struct vop_win_data *data;
 	struct vop *vop;
 
-	struct list_head pending;
-	struct vop_win_state *active;
+	struct vop_plane_state state;
 };
 
 struct vop {
@@ -93,6 +96,8 @@ struct vop {
 	struct mutex vsync_mutex;
 	bool vsync_work_pending;
 	struct completion dsp_hold_completion;
+	struct completion wait_update_complete;
+	struct drm_pending_vblank_event *event;
 
 	const struct vop_data *data;
 
@@ -632,7 +637,7 @@ static void vop_dsp_hold_valid_irq_disable(struct vop *vop)
 	spin_unlock_irqrestore(&vop->irq_lock, flags);
 }
 
-static void vop_crtc_enable(struct drm_crtc *crtc)
+static void vop_enable(struct drm_crtc *crtc)
 {
 	struct vop *vop = to_vop(crtc);
 	int ret;
@@ -746,224 +751,188 @@ static void vop_crtc_disable(struct drm_crtc *crtc)
 	pm_runtime_put(vop->dev);
 }
 
-/*
- * Caller must hold vsync_mutex.
- */
-static struct drm_framebuffer *vop_win_last_pending_fb(struct vop_win *vop_win)
-{
-	struct vop_win_state *last;
-	struct vop_win_state *active = vop_win->active;
-
-	if (list_empty(&vop_win->pending))
-		return active ? active->fb : NULL;
-
-	last = list_last_entry(&vop_win->pending, struct vop_win_state, head);
-	return last ? last->fb : NULL;
-}
-
-/*
- * Caller must hold vsync_mutex.
- */
-static int vop_win_queue_fb(struct vop_win *vop_win,
-			    struct drm_framebuffer *fb, dma_addr_t yrgb_mst,
-			    struct drm_pending_vblank_event *event)
+static void vop_plane_destroy(struct drm_plane *plane)
 {
-	struct vop_win_state *state;
-
-	state = kzalloc(sizeof(*state), GFP_KERNEL);
-	if (!state)
-		return -ENOMEM;
-
-	state->fb = fb;
-	state->yrgb_mst = yrgb_mst;
-	state->event = event;
-
-	list_add_tail(&state->head, &vop_win->pending);
-
-	return 0;
+	drm_plane_cleanup(plane);
 }
 
-static int vop_update_plane_event(struct drm_plane *plane,
-				  struct drm_crtc *crtc,
-				  struct drm_framebuffer *fb, int crtc_x,
-				  int crtc_y, unsigned int crtc_w,
-				  unsigned int crtc_h, uint32_t src_x,
-				  uint32_t src_y, uint32_t src_w,
-				  uint32_t src_h,
-				  struct drm_pending_vblank_event *event)
+static int vop_plane_atomic_check(struct drm_plane *plane,
+			   struct drm_plane_state *state)
 {
+	struct drm_crtc *crtc = state->crtc;
+	struct drm_framebuffer *fb = state->fb;
 	struct vop_win *vop_win = to_vop_win(plane);
+	struct vop_plane_state *vop_plane_state = to_vop_plane_state(state);
 	const struct vop_win_data *win = vop_win->data;
-	struct vop *vop = to_vop(crtc);
-	struct drm_gem_object *obj;
-	struct rockchip_gem_object *rk_obj;
-	struct drm_gem_object *uv_obj;
-	struct rockchip_gem_object *rk_uv_obj;
-	unsigned long offset;
-	unsigned int actual_w;
-	unsigned int actual_h;
-	unsigned int dsp_stx;
-	unsigned int dsp_sty;
-	unsigned int y_vir_stride;
-	unsigned int uv_vir_stride = 0;
-	dma_addr_t yrgb_mst;
-	dma_addr_t uv_mst = 0;
-	enum vop_data_format format;
-	uint32_t val;
-	bool is_alpha;
-	bool rb_swap;
-	bool is_yuv;
 	bool visible;
 	int ret;
-	struct drm_rect dest = {
-		.x1 = crtc_x,
-		.y1 = crtc_y,
-		.x2 = crtc_x + crtc_w,
-		.y2 = crtc_y + crtc_h,
-	};
-	struct drm_rect src = {
-		/* 16.16 fixed point */
-		.x1 = src_x,
-		.y1 = src_y,
-		.x2 = src_x + src_w,
-		.y2 = src_y + src_h,
-	};
-	const struct drm_rect clip = {
-		.x2 = crtc->mode.hdisplay,
-		.y2 = crtc->mode.vdisplay,
-	};
-	bool can_position = plane->type != DRM_PLANE_TYPE_PRIMARY;
+	struct drm_rect *dest = &vop_plane_state->dest;
+	struct drm_rect *src = &vop_plane_state->src;
+	struct drm_rect clip;
 	int min_scale = win->phy->scl ? FRAC_16_16(1, 8) :
 					DRM_PLANE_HELPER_NO_SCALING;
 	int max_scale = win->phy->scl ? FRAC_16_16(8, 1) :
 					DRM_PLANE_HELPER_NO_SCALING;
 
-	ret = drm_plane_helper_check_update(plane, crtc, fb,
-					    &src, &dest, &clip,
+	crtc = crtc ? crtc : plane->state->crtc;
+	/*
+	 * Both crtc or plane->state->crtc can be null.
+	 */
+	if (!crtc || !fb)
+		goto out_disable;
+	src->x1 = state->src_x;
+	src->y1 = state->src_y;
+	src->x2 = state->src_x + state->src_w;
+	src->y2 = state->src_y + state->src_h;
+	dest->x1 = state->crtc_x;
+	dest->y1 = state->crtc_y;
+	dest->x2 = state->crtc_x + state->crtc_w;
+	dest->y2 = state->crtc_y + state->crtc_h;
+
+	clip.x1 = 0;
+	clip.y1 = 0;
+	clip.x2 = crtc->mode.hdisplay;
+	clip.y2 = crtc->mode.vdisplay;
+
+	ret = drm_plane_helper_check_update(plane, crtc, state->fb,
+					    src, dest, &clip,
 					    min_scale,
 					    max_scale,
-					    can_position, false, &visible);
+					    true, true, &visible);
 	if (ret)
 		return ret;
 
 	if (!visible)
-		return 0;
+		goto out_disable;
 
-	is_alpha = is_alpha_support(fb->pixel_format);
-	rb_swap = has_rb_swapped(fb->pixel_format);
-	is_yuv = is_yuv_support(fb->pixel_format);
+	vop_plane_state->format = vop_convert_format(fb->pixel_format);
+	if (vop_plane_state->format < 0)
+		return vop_plane_state->format;
 
-	format = vop_convert_format(fb->pixel_format);
-	if (format < 0)
-		return format;
-
-	obj = rockchip_fb_get_gem_obj(fb, 0);
-	if (!obj) {
-		DRM_ERROR("fail to get rockchip gem object from framebuffer\n");
+	/*
+	 * Src.x1 can be odd when do clip, but yuv plane start point
+	 * need align with 2 pixel.
+	 */
+	if (is_yuv_support(fb->pixel_format) && ((src->x1 >> 16) % 2))
 		return -EINVAL;
-	}
 
-	rk_obj = to_rockchip_obj(obj);
+	vop_plane_state->enable = true;
 
-	if (is_yuv) {
-		/*
-		 * Src.x1 can be odd when do clip, but yuv plane start point
-		 * need align with 2 pixel.
-		 */
-		val = (src.x1 >> 16) % 2;
-		src.x1 += val << 16;
-		src.x2 += val << 16;
-	}
+	return 0;
 
-	actual_w = (src.x2 - src.x1) >> 16;
-	actual_h = (src.y2 - src.y1) >> 16;
+out_disable:
+	vop_plane_state->enable = false;
+	return 0;
+}
 
-	dsp_stx = dest.x1 + crtc->mode.htotal - crtc->mode.hsync_start;
-	dsp_sty = dest.y1 + crtc->mode.vtotal - crtc->mode.vsync_start;
+static void vop_plane_atomic_disable(struct drm_plane *plane,
+				     struct drm_plane_state *old_state)
+{
+	struct vop_plane_state *vop_plane_state = to_vop_plane_state(old_state);
+	struct vop_win *vop_win = to_vop_win(plane);
+	const struct vop_win_data *win = vop_win->data;
+	struct vop *vop = to_vop(old_state->crtc);
 
-	offset = (src.x1 >> 16) * drm_format_plane_cpp(fb->pixel_format, 0);
-	offset += (src.y1 >> 16) * fb->pitches[0];
+	if (!old_state->crtc)
+		return;
 
-	yrgb_mst = rk_obj->dma_addr + offset + fb->offsets[0];
-	y_vir_stride = fb->pitches[0] >> 2;
+	spin_lock(&vop->reg_lock);
 
-	if (is_yuv) {
-		int hsub = drm_format_horz_chroma_subsampling(fb->pixel_format);
-		int vsub = drm_format_vert_chroma_subsampling(fb->pixel_format);
-		int bpp = drm_format_plane_cpp(fb->pixel_format, 1);
+	VOP_WIN_SET(vop, win, enable, 0);
 
-		uv_obj = rockchip_fb_get_gem_obj(fb, 1);
-		if (!uv_obj) {
-			DRM_ERROR("fail to get uv object from framebuffer\n");
-			return -EINVAL;
-		}
-		rk_uv_obj = to_rockchip_obj(uv_obj);
-		uv_vir_stride = fb->pitches[1] >> 2;
+	spin_unlock(&vop->reg_lock);
 
-		offset = (src.x1 >> 16) * bpp / hsub;
-		offset += (src.y1 >> 16) * fb->pitches[1] / vsub;
+	vop_plane_state->enable = false;
+}
 
-		uv_mst = rk_uv_obj->dma_addr + offset + fb->offsets[1];
-	}
+static void vop_plane_atomic_update(struct drm_plane *plane,
+		struct drm_plane_state *old_state)
+{
+	struct drm_plane_state *state = plane->state;
+	struct drm_crtc *crtc = state->crtc;
+	struct vop_win *vop_win = to_vop_win(plane);
+	struct vop_plane_state *vop_plane_state = to_vop_plane_state(state);
+	const struct vop_win_data *win = vop_win->data;
+	struct vop *vop = to_vop(state->crtc);
+	struct drm_framebuffer *fb = state->fb;
+	unsigned int actual_w, actual_h;
+	unsigned int dsp_stx, dsp_sty;
+	uint32_t act_info, dsp_info, dsp_st;
+	struct drm_rect *src = &vop_plane_state->src;
+	struct drm_rect *dest = &vop_plane_state->dest;
+	struct drm_gem_object *obj, *uv_obj;
+	struct rockchip_gem_object *rk_obj, *rk_uv_obj;
+	unsigned long offset;
+	dma_addr_t dma_addr;
+	uint32_t val;
+	bool rb_swap;
 
 	/*
-	 * If this plane update changes the plane's framebuffer, (or more
-	 * precisely, if this update has a different framebuffer than the last
-	 * update), enqueue it so we can track when it completes.
-	 *
-	 * Only when we discover that this update has completed, can we
-	 * unreference any previous framebuffers.
+	 * can't update plane when vop is disabled.
 	 */
-	mutex_lock(&vop->vsync_mutex);
-	if (fb != vop_win_last_pending_fb(vop_win)) {
-		ret = drm_crtc_vblank_get(crtc);
-		if (ret) {
-			DRM_ERROR("failed to get vblank, %d\n", ret);
-			mutex_unlock(&vop->vsync_mutex);
-			return ret;
-		}
-
-		drm_framebuffer_reference(fb);
+	if (!crtc)
+		return;
 
-		ret = vop_win_queue_fb(vop_win, fb, yrgb_mst, event);
-		if (ret) {
-			drm_crtc_vblank_put(crtc);
-			mutex_unlock(&vop->vsync_mutex);
-			return ret;
-		}
+	if (WARN_ON(!vop->is_enabled))
+		return;
 
-		vop->vsync_work_pending = true;
+	if (!vop_plane_state->enable) {
+		vop_plane_atomic_disable(plane, old_state);
+		return;
 	}
-	mutex_unlock(&vop->vsync_mutex);
+
+	obj = rockchip_fb_get_gem_obj(fb, 0);
+	rk_obj = to_rockchip_obj(obj);
+
+	actual_w = drm_rect_width(src) >> 16;
+	actual_h = drm_rect_height(src) >> 16;
+	act_info = (actual_h - 1) << 16 | ((actual_w - 1) & 0xffff);
+
+	dsp_info = (drm_rect_height(dest) - 1) << 16;
+	dsp_info |= (drm_rect_width(dest) - 1) & 0xffff;
+
+	dsp_stx = dest->x1 + crtc->mode.htotal - crtc->mode.hsync_start;
+	dsp_sty = dest->y1 + crtc->mode.vtotal - crtc->mode.vsync_start;
+	dsp_st = dsp_sty << 16 | (dsp_stx & 0xffff);
+
+	offset = (src->x1 >> 16) * drm_format_plane_cpp(fb->pixel_format, 0);
+	offset += (src->y1 >> 16) * fb->pitches[0];
+	vop_plane_state->yrgb_mst = rk_obj->dma_addr + offset + fb->offsets[0];
 
 	spin_lock(&vop->reg_lock);
 
-	VOP_WIN_SET(vop, win, format, format);
-	VOP_WIN_SET(vop, win, yrgb_vir, y_vir_stride);
-	VOP_WIN_SET(vop, win, yrgb_mst, yrgb_mst);
-	if (is_yuv) {
-		VOP_WIN_SET(vop, win, uv_vir, uv_vir_stride);
-		VOP_WIN_SET(vop, win, uv_mst, uv_mst);
+	VOP_WIN_SET(vop, win, format, vop_plane_state->format);
+	VOP_WIN_SET(vop, win, yrgb_vir, fb->pitches[0] >> 2);
+	VOP_WIN_SET(vop, win, yrgb_mst, vop_plane_state->yrgb_mst);
+	if (is_yuv_support(fb->pixel_format)) {
+		int hsub = drm_format_horz_chroma_subsampling(fb->pixel_format);
+		int vsub = drm_format_vert_chroma_subsampling(fb->pixel_format);
+		int bpp = drm_format_plane_cpp(fb->pixel_format, 1);
+
+		uv_obj = rockchip_fb_get_gem_obj(fb, 1);
+		rk_uv_obj = to_rockchip_obj(uv_obj);
+
+		offset = (src->x1 >> 16) * bpp / hsub;
+		offset += (src->y1 >> 16) * fb->pitches[1] / vsub;
+
+		dma_addr = rk_uv_obj->dma_addr + offset + fb->offsets[1];
+		VOP_WIN_SET(vop, win, uv_vir, fb->pitches[1] >> 2);
+		VOP_WIN_SET(vop, win, uv_mst, dma_addr);
 	}
 
 	if (win->phy->scl)
 		scl_vop_cal_scl_fac(vop, win, actual_w, actual_h,
-				    dest.x2 - dest.x1, dest.y2 - dest.y1,
+				    drm_rect_width(dest), drm_rect_height(dest),
 				    fb->pixel_format);
 
-	val = (actual_h - 1) << 16;
-	val |= (actual_w - 1) & 0xffff;
-	VOP_WIN_SET(vop, win, act_info, val);
+	VOP_WIN_SET(vop, win, act_info, act_info);
+	VOP_WIN_SET(vop, win, dsp_info, dsp_info);
+	VOP_WIN_SET(vop, win, dsp_st, dsp_st);
 
-	val = (dest.y2 - dest.y1 - 1) << 16;
-	val |= (dest.x2 - dest.x1 - 1) & 0xffff;
-	VOP_WIN_SET(vop, win, dsp_info, val);
-	val = dsp_sty << 16;
-	val |= dsp_stx & 0xffff;
-	VOP_WIN_SET(vop, win, dsp_st, val);
+	rb_swap = has_rb_swapped(fb->pixel_format);
 	VOP_WIN_SET(vop, win, rb_swap, rb_swap);
 
-	if (is_alpha) {
+	if (is_alpha_support(fb->pixel_format)) {
 		VOP_WIN_SET(vop, win, dst_alpha_ctl,
 			    DST_FACTOR_M0(ALPHA_SRC_INVERSE));
 		val = SRC_ALPHA_EN(1) | SRC_COLOR_M0(ALPHA_SRC_PRE_MUL) |
@@ -977,86 +946,70 @@ static int vop_update_plane_event(struct drm_plane *plane,
 	}
 
 	VOP_WIN_SET(vop, win, enable, 1);
-
-	vop_cfg_done(vop);
 	spin_unlock(&vop->reg_lock);
-
-	return 0;
 }
 
-static int vop_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
-			    struct drm_framebuffer *fb, int crtc_x, int crtc_y,
-			    unsigned int crtc_w, unsigned int crtc_h,
-			    uint32_t src_x, uint32_t src_y, uint32_t src_w,
-			    uint32_t src_h)
-{
-	return vop_update_plane_event(plane, crtc, fb, crtc_x, crtc_y, crtc_w,
-				      crtc_h, src_x, src_y, src_w, src_h,
-				      NULL);
-}
+static const struct drm_plane_helper_funcs plane_helper_funcs = {
+	.atomic_check = vop_plane_atomic_check,
+	.atomic_update = vop_plane_atomic_update,
+	.atomic_disable = vop_plane_atomic_disable,
+};
 
-static int vop_update_primary_plane(struct drm_crtc *crtc,
-				    struct drm_pending_vblank_event *event)
+void vop_atomic_plane_reset(struct drm_plane *plane)
 {
-	unsigned int crtc_w, crtc_h;
+	struct vop_plane_state *vop_plane_state =
+					to_vop_plane_state(plane->state);
 
-	crtc_w = crtc->primary->fb->width - crtc->x;
-	crtc_h = crtc->primary->fb->height - crtc->y;
+	if (plane->state && plane->state->fb)
+		drm_framebuffer_unreference(plane->state->fb);
+
+	kfree(vop_plane_state);
+	vop_plane_state = kzalloc(sizeof(*vop_plane_state), GFP_KERNEL);
+	if (!vop_plane_state)
+		return;
 
-	return vop_update_plane_event(crtc->primary, crtc, crtc->primary->fb,
-				      0, 0, crtc_w, crtc_h, crtc->x << 16,
-				      crtc->y << 16, crtc_w << 16,
-				      crtc_h << 16, event);
+	plane->state = &vop_plane_state->base;
+	plane->state->plane = plane;
 }
 
-static int vop_disable_plane(struct drm_plane *plane)
+struct drm_plane_state *
+vop_atomic_plane_duplicate_state(struct drm_plane *plane)
 {
-	struct vop_win *vop_win = to_vop_win(plane);
-	const struct vop_win_data *win = vop_win->data;
-	struct vop *vop;
-	int ret;
-
-	if (!plane->crtc)
-		return 0;
+	struct vop_plane_state *old_vop_plane_state;
+	struct vop_plane_state *vop_plane_state;
 
-	vop = to_vop(plane->crtc);
+	if (WARN_ON(!plane->state))
+		return NULL;
 
-	ret = drm_crtc_vblank_get(plane->crtc);
-	if (ret) {
-		DRM_ERROR("failed to get vblank, %d\n", ret);
-		return ret;
-	}
+	old_vop_plane_state = to_vop_plane_state(plane->state);
+	vop_plane_state = kmemdup(old_vop_plane_state,
+				  sizeof(*vop_plane_state), GFP_KERNEL);
+	if (!vop_plane_state)
+		return NULL;
 
-	mutex_lock(&vop->vsync_mutex);
+	__drm_atomic_helper_plane_duplicate_state(plane,
+						  &vop_plane_state->base);
 
-	ret = vop_win_queue_fb(vop_win, NULL, 0, NULL);
-	if (ret) {
-		drm_crtc_vblank_put(plane->crtc);
-		mutex_unlock(&vop->vsync_mutex);
-		return ret;
-	}
-
-	vop->vsync_work_pending = true;
-	mutex_unlock(&vop->vsync_mutex);
-
-	spin_lock(&vop->reg_lock);
-	VOP_WIN_SET(vop, win, enable, 0);
-	vop_cfg_done(vop);
-	spin_unlock(&vop->reg_lock);
-
-	return 0;
+	return &vop_plane_state->base;
 }
 
-static void vop_plane_destroy(struct drm_plane *plane)
+static void vop_atomic_plane_destroy_state(struct drm_plane *plane,
+					   struct drm_plane_state *state)
 {
-	vop_disable_plane(plane);
-	drm_plane_cleanup(plane);
+	struct vop_plane_state *vop_state = to_vop_plane_state(state);
+
+	__drm_atomic_helper_plane_destroy_state(plane, state);
+
+	kfree(vop_state);
 }
 
 static const struct drm_plane_funcs vop_plane_funcs = {
-	.update_plane = vop_update_plane,
-	.disable_plane = vop_disable_plane,
+	.update_plane	= drm_atomic_helper_update_plane,
+	.disable_plane	= drm_atomic_helper_disable_plane,
 	.destroy = vop_plane_destroy,
+	.reset = vop_atomic_plane_reset,
+	.atomic_duplicate_state = vop_atomic_plane_duplicate_state,
+	.atomic_destroy_state = vop_atomic_plane_destroy_state,
 };
 
 int rockchip_drm_crtc_mode_config(struct drm_crtc *crtc,
@@ -1077,7 +1030,7 @@ static int vop_crtc_enable_vblank(struct drm_crtc *crtc)
 	struct vop *vop = to_vop(crtc);
 	unsigned long flags;
 
-	if (!vop->is_enabled)
+	if (WARN_ON(!vop->is_enabled))
 		return -EPERM;
 
 	spin_lock_irqsave(&vop->irq_lock, flags);
@@ -1094,7 +1047,7 @@ static void vop_crtc_disable_vblank(struct drm_crtc *crtc)
 	struct vop *vop = to_vop(crtc);
 	unsigned long flags;
 
-	if (!vop->is_enabled)
+	if (WARN_ON(!vop->is_enabled))
 		return;
 
 	spin_lock_irqsave(&vop->irq_lock, flags);
@@ -1102,9 +1055,18 @@ static void vop_crtc_disable_vblank(struct drm_crtc *crtc)
 	spin_unlock_irqrestore(&vop->irq_lock, flags);
 }
 
+static void vop_crtc_wait_for_update(struct drm_crtc *crtc)
+{
+	struct vop *vop = to_vop(crtc);
+
+	reinit_completion(&vop->wait_update_complete);
+	WARN_ON(!wait_for_completion_timeout(&vop->wait_update_complete, 100));
+}
+
 static const struct rockchip_crtc_funcs private_crtc_funcs = {
 	.enable_vblank = vop_crtc_enable_vblank,
 	.disable_vblank = vop_crtc_disable_vblank,
+	.wait_for_update = vop_crtc_wait_for_update,
 };
 
 static bool vop_crtc_mode_fixup(struct drm_crtc *crtc,
@@ -1117,29 +1079,10 @@ static bool vop_crtc_mode_fixup(struct drm_crtc *crtc,
 	return true;
 }
 
-static int vop_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
-				  struct drm_framebuffer *old_fb)
-{
-	int ret;
-
-	crtc->x = x;
-	crtc->y = y;
-
-	ret = vop_update_primary_plane(crtc, NULL);
-	if (ret < 0) {
-		DRM_ERROR("fail to update plane\n");
-		return ret;
-	}
-
-	return 0;
-}
-
-static int vop_crtc_mode_set(struct drm_crtc *crtc,
-			     struct drm_display_mode *mode,
-			     struct drm_display_mode *adjusted_mode,
-			     int x, int y, struct drm_framebuffer *fb)
+static void vop_crtc_enable(struct drm_crtc *crtc)
 {
 	struct vop *vop = to_vop(crtc);
+	struct drm_display_mode *adjusted_mode = &crtc->state->adjusted_mode;
 	u16 hsync_len = adjusted_mode->hsync_end - adjusted_mode->hsync_start;
 	u16 hdisplay = adjusted_mode->hdisplay;
 	u16 htotal = adjusted_mode->htotal;
@@ -1150,9 +1093,9 @@ static int vop_crtc_mode_set(struct drm_crtc *crtc,
 	u16 vsync_len = adjusted_mode->vsync_end - adjusted_mode->vsync_start;
 	u16 vact_st = adjusted_mode->vtotal - adjusted_mode->vsync_start;
 	u16 vact_end = vact_st + vdisplay;
-	int ret, ret_clk;
 	uint32_t val;
 
+	vop_enable(crtc);
 	/*
 	 * disable dclk to stop frame scan, so that we can safe config mode and
 	 * enable iommu.
@@ -1172,7 +1115,6 @@ static int vop_crtc_mode_set(struct drm_crtc *crtc,
 	default:
 		DRM_ERROR("unsupport connector_type[%d]\n",
 			  vop->connector_type);
-		ret = -EINVAL;
 		goto out;
 	};
 	VOP_CTRL_SET(vop, out_mode, vop->connector_out_mode);
@@ -1194,9 +1136,6 @@ static int vop_crtc_mode_set(struct drm_crtc *crtc,
 	VOP_CTRL_SET(vop, vact_st_end, val);
 	VOP_CTRL_SET(vop, vpost_st_end, val);
 
-	ret = vop_crtc_mode_set_base(crtc, x, y, fb);
-	if (ret)
-		goto out;
 
 	/*
 	 * reset dclk, take all mode config affect, so the clk would run in
@@ -1208,172 +1147,97 @@ static int vop_crtc_mode_set(struct drm_crtc *crtc,
 
 	clk_set_rate(vop->dclk, adjusted_mode->clock * 1000);
 out:
-	ret_clk = clk_enable(vop->dclk);
-	if (ret_clk < 0) {
-		dev_err(vop->dev, "failed to enable dclk - %d\n", ret_clk);
-		return ret_clk;
-	}
-
-	return ret;
+	if (clk_enable(vop->dclk) < 0)
+		dev_err(vop->dev, "failed to enable dclk\n");
 }
 
-static const struct drm_crtc_helper_funcs vop_crtc_helper_funcs = {
-	.enable = vop_crtc_enable,
-	.disable = vop_crtc_disable,
-	.mode_fixup = vop_crtc_mode_fixup,
-	.mode_set = vop_crtc_mode_set,
-	.mode_set_base = vop_crtc_mode_set_base,
-};
-
-static int vop_crtc_page_flip(struct drm_crtc *crtc,
-			      struct drm_framebuffer *fb,
-			      struct drm_pending_vblank_event *event,
-			      uint32_t page_flip_flags)
+static void vop_crtc_atomic_flush(struct drm_crtc *crtc,
+				  struct drm_crtc_state *old_crtc_state)
 {
 	struct vop *vop = to_vop(crtc);
-	struct drm_framebuffer *old_fb = crtc->primary->fb;
-	int ret;
 
-	/* when the page flip is requested, crtc should be on */
-	if (!vop->is_enabled) {
-		DRM_DEBUG("page flip request rejected because crtc is off.\n");
-		return 0;
-	}
+	if (WARN_ON(!vop->is_enabled))
+		return;
 
-	crtc->primary->fb = fb;
+	spin_lock(&vop->reg_lock);
 
-	ret = vop_update_primary_plane(crtc, event);
-	if (ret)
-		crtc->primary->fb = old_fb;
+	vop_cfg_done(vop);
 
-	return ret;
+	spin_unlock(&vop->reg_lock);
 }
 
-static void vop_win_state_complete(struct vop_win *vop_win,
-				   struct vop_win_state *state)
+static void vop_crtc_atomic_begin(struct drm_crtc *crtc,
+				  struct drm_crtc_state *old_crtc_state)
 {
-	struct vop *vop = vop_win->vop;
-	struct drm_crtc *crtc = &vop->crtc;
-	struct drm_device *drm = crtc->dev;
-	unsigned long flags;
+	struct vop *vop = to_vop(crtc);
 
-	if (state->event) {
-		spin_lock_irqsave(&drm->event_lock, flags);
-		drm_crtc_send_vblank_event(crtc, state->event);
-		spin_unlock_irqrestore(&drm->event_lock, flags);
-	}
+	if (crtc->state->event) {
+		WARN_ON(drm_crtc_vblank_get(crtc) != 0);
 
-	list_del(&state->head);
-	drm_crtc_vblank_put(crtc);
+		vop->event = crtc->state->event;
+		crtc->state->event = NULL;
+	}
 }
 
+static const struct drm_crtc_helper_funcs vop_crtc_helper_funcs = {
+	.enable = vop_crtc_enable,
+	.disable = vop_crtc_disable,
+	.mode_fixup = vop_crtc_mode_fixup,
+	.atomic_flush = vop_crtc_atomic_flush,
+	.atomic_begin = vop_crtc_atomic_begin,
+};
+
 static void vop_crtc_destroy(struct drm_crtc *crtc)
 {
 	drm_crtc_cleanup(crtc);
 }
 
 static const struct drm_crtc_funcs vop_crtc_funcs = {
-	.set_config = drm_crtc_helper_set_config,
-	.page_flip = vop_crtc_page_flip,
+	.set_config = drm_atomic_helper_set_config,
+	.page_flip = drm_atomic_helper_page_flip,
 	.destroy = vop_crtc_destroy,
+	.reset = drm_atomic_helper_crtc_reset,
+	.atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
+	.atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
 };
 
-static bool vop_win_state_is_active(struct vop_win *vop_win,
-				    struct vop_win_state *state)
+static bool vop_win_pending_is_complete(struct vop_win *vop_win)
 {
-	bool active = false;
-
-	if (state->fb) {
-		dma_addr_t yrgb_mst;
-
-		/* check yrgb_mst to tell if pending_fb is now front */
-		yrgb_mst = VOP_WIN_GET_YRGBADDR(vop_win->vop, vop_win->data);
-
-		active = (yrgb_mst == state->yrgb_mst);
-	} else {
-		bool enabled;
-
-		/* if enable bit is clear, plane is now disabled */
-		enabled = VOP_WIN_GET(vop_win->vop, vop_win->data, enable);
-
-		active = (enabled == 0);
-	}
-
-	return active;
-}
+	struct drm_plane *plane = &vop_win->base;
+	struct vop_plane_state *state = to_vop_plane_state(plane->state);
+	dma_addr_t yrgb_mst;
 
-static void vop_win_state_destroy(struct vop_win_state *state)
-{
-	struct drm_framebuffer *fb = state->fb;
+	if (!state->enable)
+		return VOP_WIN_GET(vop_win->vop, vop_win->data, enable) == 0;
 
-	if (fb)
-		drm_framebuffer_unreference(fb);
+	yrgb_mst = VOP_WIN_GET_YRGBADDR(vop_win->vop, vop_win->data);
 
-	kfree(state);
+	return yrgb_mst == state->yrgb_mst;
 }
 
-static void vop_win_update_state(struct vop_win *vop_win)
+static void vop_handle_vblank(struct vop *vop)
 {
-	struct vop_win_state *state, *n, *new_active = NULL;
-
-	/* Check if any pending states are now active */
-	list_for_each_entry(state, &vop_win->pending, head)
-		if (vop_win_state_is_active(vop_win, state)) {
-			new_active = state;
-			break;
-		}
-
-	if (!new_active)
-		return;
+	struct drm_device *drm = vop->drm_dev;
+	struct drm_crtc *crtc = &vop->crtc;
+	unsigned long flags;
+	int i;
 
-	/*
-	 * Destroy any 'skipped' pending states - states that were queued
-	 * before the newly active state.
-	 */
-	list_for_each_entry_safe(state, n, &vop_win->pending, head) {
-		if (state == new_active)
-			break;
-		vop_win_state_complete(vop_win, state);
-		vop_win_state_destroy(state);
+	for (i = 0; i < vop->data->win_size; i++) {
+		if (!vop_win_pending_is_complete(&vop->win[i]))
+			return;
 	}
 
-	vop_win_state_complete(vop_win, new_active);
-
-	if (vop_win->active)
-		vop_win_state_destroy(vop_win->active);
-	vop_win->active = new_active;
-}
-
-static bool vop_win_has_pending_state(struct vop_win *vop_win)
-{
-	return !list_empty(&vop_win->pending);
-}
-
-static irqreturn_t vop_isr_thread(int irq, void *data)
-{
-	struct vop *vop = data;
-	const struct vop_data *vop_data = vop->data;
-	unsigned int i;
-
-	mutex_lock(&vop->vsync_mutex);
-
-	if (!vop->vsync_work_pending)
-		goto done;
+	if (vop->event) {
+		spin_lock_irqsave(&drm->event_lock, flags);
 
-	vop->vsync_work_pending = false;
+		drm_crtc_send_vblank_event(crtc, vop->event);
+		drm_crtc_vblank_put(crtc);
+		vop->event = NULL;
 
-	for (i = 0; i < vop_data->win_size; i++) {
-		struct vop_win *vop_win = &vop->win[i];
-
-		vop_win_update_state(vop_win);
-		if (vop_win_has_pending_state(vop_win))
-			vop->vsync_work_pending = true;
+		spin_unlock_irqrestore(&drm->event_lock, flags);
 	}
-
-done:
-	mutex_unlock(&vop->vsync_mutex);
-
-	return IRQ_HANDLED;
+	if (!completion_done(&vop->wait_update_complete))
+		complete(&vop->wait_update_complete);
 }
 
 static irqreturn_t vop_isr(int irq, void *data)
@@ -1409,8 +1273,9 @@ static irqreturn_t vop_isr(int irq, void *data)
 
 	if (active_irqs & FS_INTR) {
 		drm_crtc_handle_vblank(crtc);
+		vop_handle_vblank(vop);
 		active_irqs &= ~FS_INTR;
-		ret = (vop->vsync_work_pending) ? IRQ_WAKE_THREAD : IRQ_HANDLED;
+		ret = IRQ_HANDLED;
 	}
 
 	/* Unhandled irqs are spurious. */
@@ -1455,6 +1320,7 @@ static int vop_create_crtc(struct vop *vop)
 		}
 
 		plane = &vop_win->base;
+		drm_plane_helper_add(plane, &plane_helper_funcs);
 		if (plane->type == DRM_PLANE_TYPE_PRIMARY)
 			primary = plane;
 		else if (plane->type == DRM_PLANE_TYPE_CURSOR)
@@ -1490,6 +1356,7 @@ static int vop_create_crtc(struct vop *vop)
 			DRM_ERROR("failed to initialize overlay plane\n");
 			goto err_cleanup_crtc;
 		}
+		drm_plane_helper_add(&vop_win->base, &plane_helper_funcs);
 	}
 
 	port = of_get_child_by_name(dev->of_node, "port");
@@ -1500,6 +1367,7 @@ static int vop_create_crtc(struct vop *vop)
 	}
 
 	init_completion(&vop->dsp_hold_completion);
+	init_completion(&vop->wait_update_complete);
 	crtc->port = port;
 	rockchip_register_crtc_funcs(crtc, &private_crtc_funcs);
 
@@ -1633,7 +1501,6 @@ static void vop_win_init(struct vop *vop)
 
 		vop_win->data = win_data;
 		vop_win->vop = vop;
-		INIT_LIST_HEAD(&vop_win->pending);
 	}
 }
 
@@ -1694,8 +1561,8 @@ static int vop_bind(struct device *dev, struct device *master, void *data)
 
 	mutex_init(&vop->vsync_mutex);
 
-	ret = devm_request_threaded_irq(dev, vop->irq, vop_isr, vop_isr_thread,
-					IRQF_SHARED, dev_name(dev), vop);
+	ret = devm_request_irq(dev, vop->irq, vop_isr,
+			       IRQF_SHARED, dev_name(dev), vop);
 	if (ret)
 		return ret;
 
-- 
1.7.9.5

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

* [PATCH v3 4/8] drm/rockchip: Optimization vop mode set
  2015-12-17  3:01 ` Mark Yao
  (?)
@ 2015-12-17  3:01   ` Mark Yao
  -1 siblings, 0 replies; 51+ messages in thread
From: Mark Yao @ 2015-12-17  3:01 UTC (permalink / raw)
  To: David Airlie, Heiko Stuebner, dri-devel, linux-arm-kernel,
	linux-rockchip, linux-kernel
  Cc: Mark Yao

Rk3288 vop timing registers is immediately register, when configure
timing on display active time, will cause tearing. use dclk reset is
not a good idea to avoid this tearing. we can avoid tearing by using
standby register.

Vop standby register will take effect at end of current frame, and
go back to work immediately when exit standby.

So we can use standby register to protect this context.

Signed-off-by: Mark Yao <mark.yao@rock-chips.com>
---
Changes in v3: None
Changes in v2: None
 drivers/gpu/drm/rockchip/rockchip_drm_vop.c |   51 ++++++++++++++++++---------
 1 file changed, 35 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index 44f6154..9ace3ae 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -1097,10 +1097,40 @@ static void vop_crtc_enable(struct drm_crtc *crtc)
 
 	vop_enable(crtc);
 	/*
-	 * disable dclk to stop frame scan, so that we can safe config mode and
-	 * enable iommu.
+	 * If dclk rate is zero, mean that scanout is stop,
+	 * we don't need wait any more.
 	 */
-	clk_disable(vop->dclk);
+	if (clk_get_rate(vop->dclk)) {
+		/*
+		 * Rk3288 vop timing register is immediately, when configure
+		 * display timing on display time, may cause tearing.
+		 *
+		 * Vop standby will take effect at end of current frame,
+		 * if dsp hold valid irq happen, it means standby complete.
+		 *
+		 * mode set:
+		 *    standby and wait complete --> |----
+		 *                                  | display time
+		 *                                  |----
+		 *                                  |---> dsp hold irq
+		 *     configure display timing --> |
+		 *         standby exit             |
+		 *                                  | new frame start.
+		 */
+
+		reinit_completion(&vop->dsp_hold_completion);
+		vop_dsp_hold_valid_irq_enable(vop);
+
+		spin_lock(&vop->reg_lock);
+
+		VOP_CTRL_SET(vop, standby, 1);
+
+		spin_unlock(&vop->reg_lock);
+
+		wait_for_completion(&vop->dsp_hold_completion);
+
+		vop_dsp_hold_valid_irq_disable(vop);
+	}
 
 	switch (vop->connector_type) {
 	case DRM_MODE_CONNECTOR_LVDS:
@@ -1115,7 +1145,6 @@ static void vop_crtc_enable(struct drm_crtc *crtc)
 	default:
 		DRM_ERROR("unsupport connector_type[%d]\n",
 			  vop->connector_type);
-		goto out;
 	};
 	VOP_CTRL_SET(vop, out_mode, vop->connector_out_mode);
 
@@ -1136,19 +1165,9 @@ static void vop_crtc_enable(struct drm_crtc *crtc)
 	VOP_CTRL_SET(vop, vact_st_end, val);
 	VOP_CTRL_SET(vop, vpost_st_end, val);
 
-
-	/*
-	 * reset dclk, take all mode config affect, so the clk would run in
-	 * correct frame.
-	 */
-	reset_control_assert(vop->dclk_rst);
-	usleep_range(10, 20);
-	reset_control_deassert(vop->dclk_rst);
-
 	clk_set_rate(vop->dclk, adjusted_mode->clock * 1000);
-out:
-	if (clk_enable(vop->dclk) < 0)
-		dev_err(vop->dev, "failed to enable dclk\n");
+
+	VOP_CTRL_SET(vop, standby, 0);
 }
 
 static void vop_crtc_atomic_flush(struct drm_crtc *crtc,
-- 
1.7.9.5



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

* [PATCH v3 4/8] drm/rockchip: Optimization vop mode set
@ 2015-12-17  3:01   ` Mark Yao
  0 siblings, 0 replies; 51+ messages in thread
From: Mark Yao @ 2015-12-17  3:01 UTC (permalink / raw)
  To: David Airlie, Heiko Stuebner, dri-devel, linux-arm-kernel,
	linux-rockchip, linux-kernel

Rk3288 vop timing registers is immediately register, when configure
timing on display active time, will cause tearing. use dclk reset is
not a good idea to avoid this tearing. we can avoid tearing by using
standby register.

Vop standby register will take effect at end of current frame, and
go back to work immediately when exit standby.

So we can use standby register to protect this context.

Signed-off-by: Mark Yao <mark.yao@rock-chips.com>
---
Changes in v3: None
Changes in v2: None
 drivers/gpu/drm/rockchip/rockchip_drm_vop.c |   51 ++++++++++++++++++---------
 1 file changed, 35 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index 44f6154..9ace3ae 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -1097,10 +1097,40 @@ static void vop_crtc_enable(struct drm_crtc *crtc)
 
 	vop_enable(crtc);
 	/*
-	 * disable dclk to stop frame scan, so that we can safe config mode and
-	 * enable iommu.
+	 * If dclk rate is zero, mean that scanout is stop,
+	 * we don't need wait any more.
 	 */
-	clk_disable(vop->dclk);
+	if (clk_get_rate(vop->dclk)) {
+		/*
+		 * Rk3288 vop timing register is immediately, when configure
+		 * display timing on display time, may cause tearing.
+		 *
+		 * Vop standby will take effect at end of current frame,
+		 * if dsp hold valid irq happen, it means standby complete.
+		 *
+		 * mode set:
+		 *    standby and wait complete --> |----
+		 *                                  | display time
+		 *                                  |----
+		 *                                  |---> dsp hold irq
+		 *     configure display timing --> |
+		 *         standby exit             |
+		 *                                  | new frame start.
+		 */
+
+		reinit_completion(&vop->dsp_hold_completion);
+		vop_dsp_hold_valid_irq_enable(vop);
+
+		spin_lock(&vop->reg_lock);
+
+		VOP_CTRL_SET(vop, standby, 1);
+
+		spin_unlock(&vop->reg_lock);
+
+		wait_for_completion(&vop->dsp_hold_completion);
+
+		vop_dsp_hold_valid_irq_disable(vop);
+	}
 
 	switch (vop->connector_type) {
 	case DRM_MODE_CONNECTOR_LVDS:
@@ -1115,7 +1145,6 @@ static void vop_crtc_enable(struct drm_crtc *crtc)
 	default:
 		DRM_ERROR("unsupport connector_type[%d]\n",
 			  vop->connector_type);
-		goto out;
 	};
 	VOP_CTRL_SET(vop, out_mode, vop->connector_out_mode);
 
@@ -1136,19 +1165,9 @@ static void vop_crtc_enable(struct drm_crtc *crtc)
 	VOP_CTRL_SET(vop, vact_st_end, val);
 	VOP_CTRL_SET(vop, vpost_st_end, val);
 
-
-	/*
-	 * reset dclk, take all mode config affect, so the clk would run in
-	 * correct frame.
-	 */
-	reset_control_assert(vop->dclk_rst);
-	usleep_range(10, 20);
-	reset_control_deassert(vop->dclk_rst);
-
 	clk_set_rate(vop->dclk, adjusted_mode->clock * 1000);
-out:
-	if (clk_enable(vop->dclk) < 0)
-		dev_err(vop->dev, "failed to enable dclk\n");
+
+	VOP_CTRL_SET(vop, standby, 0);
 }
 
 static void vop_crtc_atomic_flush(struct drm_crtc *crtc,
-- 
1.7.9.5


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

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

* [PATCH v3 4/8] drm/rockchip: Optimization vop mode set
@ 2015-12-17  3:01   ` Mark Yao
  0 siblings, 0 replies; 51+ messages in thread
From: Mark Yao @ 2015-12-17  3:01 UTC (permalink / raw)
  To: linux-arm-kernel

Rk3288 vop timing registers is immediately register, when configure
timing on display active time, will cause tearing. use dclk reset is
not a good idea to avoid this tearing. we can avoid tearing by using
standby register.

Vop standby register will take effect at end of current frame, and
go back to work immediately when exit standby.

So we can use standby register to protect this context.

Signed-off-by: Mark Yao <mark.yao@rock-chips.com>
---
Changes in v3: None
Changes in v2: None
 drivers/gpu/drm/rockchip/rockchip_drm_vop.c |   51 ++++++++++++++++++---------
 1 file changed, 35 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index 44f6154..9ace3ae 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -1097,10 +1097,40 @@ static void vop_crtc_enable(struct drm_crtc *crtc)
 
 	vop_enable(crtc);
 	/*
-	 * disable dclk to stop frame scan, so that we can safe config mode and
-	 * enable iommu.
+	 * If dclk rate is zero, mean that scanout is stop,
+	 * we don't need wait any more.
 	 */
-	clk_disable(vop->dclk);
+	if (clk_get_rate(vop->dclk)) {
+		/*
+		 * Rk3288 vop timing register is immediately, when configure
+		 * display timing on display time, may cause tearing.
+		 *
+		 * Vop standby will take effect at end of current frame,
+		 * if dsp hold valid irq happen, it means standby complete.
+		 *
+		 * mode set:
+		 *    standby and wait complete --> |----
+		 *                                  | display time
+		 *                                  |----
+		 *                                  |---> dsp hold irq
+		 *     configure display timing --> |
+		 *         standby exit             |
+		 *                                  | new frame start.
+		 */
+
+		reinit_completion(&vop->dsp_hold_completion);
+		vop_dsp_hold_valid_irq_enable(vop);
+
+		spin_lock(&vop->reg_lock);
+
+		VOP_CTRL_SET(vop, standby, 1);
+
+		spin_unlock(&vop->reg_lock);
+
+		wait_for_completion(&vop->dsp_hold_completion);
+
+		vop_dsp_hold_valid_irq_disable(vop);
+	}
 
 	switch (vop->connector_type) {
 	case DRM_MODE_CONNECTOR_LVDS:
@@ -1115,7 +1145,6 @@ static void vop_crtc_enable(struct drm_crtc *crtc)
 	default:
 		DRM_ERROR("unsupport connector_type[%d]\n",
 			  vop->connector_type);
-		goto out;
 	};
 	VOP_CTRL_SET(vop, out_mode, vop->connector_out_mode);
 
@@ -1136,19 +1165,9 @@ static void vop_crtc_enable(struct drm_crtc *crtc)
 	VOP_CTRL_SET(vop, vact_st_end, val);
 	VOP_CTRL_SET(vop, vpost_st_end, val);
 
-
-	/*
-	 * reset dclk, take all mode config affect, so the clk would run in
-	 * correct frame.
-	 */
-	reset_control_assert(vop->dclk_rst);
-	usleep_range(10, 20);
-	reset_control_deassert(vop->dclk_rst);
-
 	clk_set_rate(vop->dclk, adjusted_mode->clock * 1000);
-out:
-	if (clk_enable(vop->dclk) < 0)
-		dev_err(vop->dev, "failed to enable dclk\n");
+
+	VOP_CTRL_SET(vop, standby, 0);
 }
 
 static void vop_crtc_atomic_flush(struct drm_crtc *crtc,
-- 
1.7.9.5

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

* [PATCH v3 5/8] drm/rockchip: support atomic asynchronous commit
  2015-12-17  3:01 ` Mark Yao
  (?)
@ 2015-12-17  3:06   ` Mark Yao
  -1 siblings, 0 replies; 51+ messages in thread
From: Mark Yao @ 2015-12-17  3:06 UTC (permalink / raw)
  To: David Airlie, Heiko Stuebner, dri-devel, linux-arm-kernel,
	linux-rockchip, linux-kernel
  Cc: Mark Yao

If drm core requests a async commit, rockchip_drm_atomic_commit
will schedule a work task to update later.

Signed-off-by: Mark Yao <mark.yao@rock-chips.com>
---
Changes in v3: None
Changes in v2:
- serialize outstanding asynchronous commits
 drivers/gpu/drm/rockchip/rockchip_drm_drv.c |    3 ++
 drivers/gpu/drm/rockchip/rockchip_drm_drv.h |   10 +++++
 drivers/gpu/drm/rockchip/rockchip_drm_fb.c  |   54 ++++++++++++++++++++-------
 3 files changed, 54 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
index ab3e0f6..5edd5ccb 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
@@ -140,6 +140,9 @@ static int rockchip_drm_load(struct drm_device *drm_dev, unsigned long flags)
 	if (!private)
 		return -ENOMEM;
 
+	mutex_init(&private->commit.lock);
+	INIT_WORK(&private->commit.work, rockchip_drm_atomic_work);
+
 	drm_dev->dev_private = private;
 
 	drm_mode_config_init(drm_dev);
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
index 4468f98..bb8b076 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
@@ -42,6 +42,13 @@ struct rockchip_crtc_funcs {
 	void (*wait_for_update)(struct drm_crtc *crtc);
 };
 
+struct rockchip_atomic_commit {
+	struct work_struct	work;
+	struct drm_atomic_state *state;
+	struct drm_device *dev;
+	struct mutex lock;
+};
+
 /*
  * Rockchip drm private structure.
  *
@@ -52,8 +59,11 @@ struct rockchip_drm_private {
 	struct drm_fb_helper fbdev_helper;
 	struct drm_gem_object *fbdev_bo;
 	const struct rockchip_crtc_funcs *crtc_funcs[ROCKCHIP_MAX_CRTC];
+
+	struct rockchip_atomic_commit commit;
 };
 
+void rockchip_drm_atomic_work(struct work_struct *work);
 int rockchip_register_crtc_funcs(struct drm_crtc *crtc,
 				 const struct rockchip_crtc_funcs *crtc_funcs);
 void rockchip_unregister_crtc_funcs(struct drm_crtc *crtc);
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
index 7c974a4..0bc1d5e 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
@@ -210,20 +210,11 @@ rockchip_atomic_wait_for_complete(struct drm_atomic_state *old_state)
 	}
 }
 
-int rockchip_drm_atomic_commit(struct drm_device *dev,
-			       struct drm_atomic_state *state,
-			       bool async)
+static void
+rockchip_atomic_commit_complete(struct rockchip_atomic_commit *commit)
 {
-	int ret;
-
-	if (async)
-		return -EBUSY;
-
-	ret = drm_atomic_helper_prepare_planes(dev, state);
-	if (ret)
-		return ret;
-
-	drm_atomic_helper_swap_state(dev, state);
+	struct drm_atomic_state *state = commit->state;
+	struct drm_device *dev = commit->dev;
 
 	/*
 	 * TODO: do fence wait here.
@@ -255,6 +246,43 @@ int rockchip_drm_atomic_commit(struct drm_device *dev,
 	drm_atomic_helper_cleanup_planes(dev, state);
 
 	drm_atomic_state_free(state);
+}
+
+void rockchip_drm_atomic_work(struct work_struct *work)
+{
+	struct rockchip_atomic_commit *commit = container_of(work,
+					struct rockchip_atomic_commit, work);
+
+	rockchip_atomic_commit_complete(commit);
+}
+
+int rockchip_drm_atomic_commit(struct drm_device *dev,
+			       struct drm_atomic_state *state,
+			       bool async)
+{
+	struct rockchip_drm_private *private = dev->dev_private;
+	struct rockchip_atomic_commit *commit = &private->commit;
+	int ret;
+
+	ret = drm_atomic_helper_prepare_planes(dev, state);
+	if (ret)
+		return ret;
+
+	/* serialize outstanding asynchronous commits */
+	mutex_lock(&commit->lock);
+	flush_work(&commit->work);
+
+	drm_atomic_helper_swap_state(dev, state);
+
+	commit->dev = dev;
+	commit->state = state;
+
+	if (async)
+		schedule_work(&commit->work);
+	else
+		rockchip_atomic_commit_complete(commit);
+
+	mutex_unlock(&commit->lock);
 
 	return 0;
 }
-- 
1.7.9.5



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

* [PATCH v3 5/8] drm/rockchip: support atomic asynchronous commit
@ 2015-12-17  3:06   ` Mark Yao
  0 siblings, 0 replies; 51+ messages in thread
From: Mark Yao @ 2015-12-17  3:06 UTC (permalink / raw)
  To: David Airlie, Heiko Stuebner, dri-devel, linux-arm-kernel,
	linux-rockchip, linux-kernel

If drm core requests a async commit, rockchip_drm_atomic_commit
will schedule a work task to update later.

Signed-off-by: Mark Yao <mark.yao@rock-chips.com>
---
Changes in v3: None
Changes in v2:
- serialize outstanding asynchronous commits
 drivers/gpu/drm/rockchip/rockchip_drm_drv.c |    3 ++
 drivers/gpu/drm/rockchip/rockchip_drm_drv.h |   10 +++++
 drivers/gpu/drm/rockchip/rockchip_drm_fb.c  |   54 ++++++++++++++++++++-------
 3 files changed, 54 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
index ab3e0f6..5edd5ccb 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
@@ -140,6 +140,9 @@ static int rockchip_drm_load(struct drm_device *drm_dev, unsigned long flags)
 	if (!private)
 		return -ENOMEM;
 
+	mutex_init(&private->commit.lock);
+	INIT_WORK(&private->commit.work, rockchip_drm_atomic_work);
+
 	drm_dev->dev_private = private;
 
 	drm_mode_config_init(drm_dev);
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
index 4468f98..bb8b076 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
@@ -42,6 +42,13 @@ struct rockchip_crtc_funcs {
 	void (*wait_for_update)(struct drm_crtc *crtc);
 };
 
+struct rockchip_atomic_commit {
+	struct work_struct	work;
+	struct drm_atomic_state *state;
+	struct drm_device *dev;
+	struct mutex lock;
+};
+
 /*
  * Rockchip drm private structure.
  *
@@ -52,8 +59,11 @@ struct rockchip_drm_private {
 	struct drm_fb_helper fbdev_helper;
 	struct drm_gem_object *fbdev_bo;
 	const struct rockchip_crtc_funcs *crtc_funcs[ROCKCHIP_MAX_CRTC];
+
+	struct rockchip_atomic_commit commit;
 };
 
+void rockchip_drm_atomic_work(struct work_struct *work);
 int rockchip_register_crtc_funcs(struct drm_crtc *crtc,
 				 const struct rockchip_crtc_funcs *crtc_funcs);
 void rockchip_unregister_crtc_funcs(struct drm_crtc *crtc);
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
index 7c974a4..0bc1d5e 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
@@ -210,20 +210,11 @@ rockchip_atomic_wait_for_complete(struct drm_atomic_state *old_state)
 	}
 }
 
-int rockchip_drm_atomic_commit(struct drm_device *dev,
-			       struct drm_atomic_state *state,
-			       bool async)
+static void
+rockchip_atomic_commit_complete(struct rockchip_atomic_commit *commit)
 {
-	int ret;
-
-	if (async)
-		return -EBUSY;
-
-	ret = drm_atomic_helper_prepare_planes(dev, state);
-	if (ret)
-		return ret;
-
-	drm_atomic_helper_swap_state(dev, state);
+	struct drm_atomic_state *state = commit->state;
+	struct drm_device *dev = commit->dev;
 
 	/*
 	 * TODO: do fence wait here.
@@ -255,6 +246,43 @@ int rockchip_drm_atomic_commit(struct drm_device *dev,
 	drm_atomic_helper_cleanup_planes(dev, state);
 
 	drm_atomic_state_free(state);
+}
+
+void rockchip_drm_atomic_work(struct work_struct *work)
+{
+	struct rockchip_atomic_commit *commit = container_of(work,
+					struct rockchip_atomic_commit, work);
+
+	rockchip_atomic_commit_complete(commit);
+}
+
+int rockchip_drm_atomic_commit(struct drm_device *dev,
+			       struct drm_atomic_state *state,
+			       bool async)
+{
+	struct rockchip_drm_private *private = dev->dev_private;
+	struct rockchip_atomic_commit *commit = &private->commit;
+	int ret;
+
+	ret = drm_atomic_helper_prepare_planes(dev, state);
+	if (ret)
+		return ret;
+
+	/* serialize outstanding asynchronous commits */
+	mutex_lock(&commit->lock);
+	flush_work(&commit->work);
+
+	drm_atomic_helper_swap_state(dev, state);
+
+	commit->dev = dev;
+	commit->state = state;
+
+	if (async)
+		schedule_work(&commit->work);
+	else
+		rockchip_atomic_commit_complete(commit);
+
+	mutex_unlock(&commit->lock);
 
 	return 0;
 }
-- 
1.7.9.5


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

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

* [PATCH v3 5/8] drm/rockchip: support atomic asynchronous commit
@ 2015-12-17  3:06   ` Mark Yao
  0 siblings, 0 replies; 51+ messages in thread
From: Mark Yao @ 2015-12-17  3:06 UTC (permalink / raw)
  To: linux-arm-kernel

If drm core requests a async commit, rockchip_drm_atomic_commit
will schedule a work task to update later.

Signed-off-by: Mark Yao <mark.yao@rock-chips.com>
---
Changes in v3: None
Changes in v2:
- serialize outstanding asynchronous commits
 drivers/gpu/drm/rockchip/rockchip_drm_drv.c |    3 ++
 drivers/gpu/drm/rockchip/rockchip_drm_drv.h |   10 +++++
 drivers/gpu/drm/rockchip/rockchip_drm_fb.c  |   54 ++++++++++++++++++++-------
 3 files changed, 54 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
index ab3e0f6..5edd5ccb 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
@@ -140,6 +140,9 @@ static int rockchip_drm_load(struct drm_device *drm_dev, unsigned long flags)
 	if (!private)
 		return -ENOMEM;
 
+	mutex_init(&private->commit.lock);
+	INIT_WORK(&private->commit.work, rockchip_drm_atomic_work);
+
 	drm_dev->dev_private = private;
 
 	drm_mode_config_init(drm_dev);
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
index 4468f98..bb8b076 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
@@ -42,6 +42,13 @@ struct rockchip_crtc_funcs {
 	void (*wait_for_update)(struct drm_crtc *crtc);
 };
 
+struct rockchip_atomic_commit {
+	struct work_struct	work;
+	struct drm_atomic_state *state;
+	struct drm_device *dev;
+	struct mutex lock;
+};
+
 /*
  * Rockchip drm private structure.
  *
@@ -52,8 +59,11 @@ struct rockchip_drm_private {
 	struct drm_fb_helper fbdev_helper;
 	struct drm_gem_object *fbdev_bo;
 	const struct rockchip_crtc_funcs *crtc_funcs[ROCKCHIP_MAX_CRTC];
+
+	struct rockchip_atomic_commit commit;
 };
 
+void rockchip_drm_atomic_work(struct work_struct *work);
 int rockchip_register_crtc_funcs(struct drm_crtc *crtc,
 				 const struct rockchip_crtc_funcs *crtc_funcs);
 void rockchip_unregister_crtc_funcs(struct drm_crtc *crtc);
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
index 7c974a4..0bc1d5e 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
@@ -210,20 +210,11 @@ rockchip_atomic_wait_for_complete(struct drm_atomic_state *old_state)
 	}
 }
 
-int rockchip_drm_atomic_commit(struct drm_device *dev,
-			       struct drm_atomic_state *state,
-			       bool async)
+static void
+rockchip_atomic_commit_complete(struct rockchip_atomic_commit *commit)
 {
-	int ret;
-
-	if (async)
-		return -EBUSY;
-
-	ret = drm_atomic_helper_prepare_planes(dev, state);
-	if (ret)
-		return ret;
-
-	drm_atomic_helper_swap_state(dev, state);
+	struct drm_atomic_state *state = commit->state;
+	struct drm_device *dev = commit->dev;
 
 	/*
 	 * TODO: do fence wait here.
@@ -255,6 +246,43 @@ int rockchip_drm_atomic_commit(struct drm_device *dev,
 	drm_atomic_helper_cleanup_planes(dev, state);
 
 	drm_atomic_state_free(state);
+}
+
+void rockchip_drm_atomic_work(struct work_struct *work)
+{
+	struct rockchip_atomic_commit *commit = container_of(work,
+					struct rockchip_atomic_commit, work);
+
+	rockchip_atomic_commit_complete(commit);
+}
+
+int rockchip_drm_atomic_commit(struct drm_device *dev,
+			       struct drm_atomic_state *state,
+			       bool async)
+{
+	struct rockchip_drm_private *private = dev->dev_private;
+	struct rockchip_atomic_commit *commit = &private->commit;
+	int ret;
+
+	ret = drm_atomic_helper_prepare_planes(dev, state);
+	if (ret)
+		return ret;
+
+	/* serialize outstanding asynchronous commits */
+	mutex_lock(&commit->lock);
+	flush_work(&commit->work);
+
+	drm_atomic_helper_swap_state(dev, state);
+
+	commit->dev = dev;
+	commit->state = state;
+
+	if (async)
+		schedule_work(&commit->work);
+	else
+		rockchip_atomic_commit_complete(commit);
+
+	mutex_unlock(&commit->lock);
 
 	return 0;
 }
-- 
1.7.9.5

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

* [PATCH v3 6/8] drm/rockchip: direct config connecter gate and out_mode
  2015-12-17  3:01 ` Mark Yao
  (?)
@ 2015-12-17  3:08   ` Mark Yao
  -1 siblings, 0 replies; 51+ messages in thread
From: Mark Yao @ 2015-12-17  3:08 UTC (permalink / raw)
  To: David Airlie, Heiko Stuebner, dri-devel, linux-arm-kernel,
	linux-rockchip, linux-kernel
  Cc: Mark Yao

Both connecter gate and out_mode are not conflict with mode set
configure. Direct setting connecter gate and out_mode, that allow
connector do rockchip_drm_crtc_mode_config after mode set.

Signed-off-by: Mark Yao <mark.yao@rock-chips.com>
---
Changes in v3: None
Changes in v2: None
 drivers/gpu/drm/rockchip/rockchip_drm_vop.c |   39 +++++++++++++--------------
 1 file changed, 18 insertions(+), 21 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index 9ace3ae..6ded4cc 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -89,9 +89,6 @@ struct vop {
 	struct drm_device *drm_dev;
 	bool is_enabled;
 
-	int connector_type;
-	int connector_out_mode;
-
 	/* mutex vsync_ work */
 	struct mutex vsync_mutex;
 	bool vsync_work_pending;
@@ -1018,8 +1015,24 @@ int rockchip_drm_crtc_mode_config(struct drm_crtc *crtc,
 {
 	struct vop *vop = to_vop(crtc);
 
-	vop->connector_type = connector_type;
-	vop->connector_out_mode = out_mode;
+	if (WARN_ON(!vop->is_enabled))
+		return -EINVAL;
+
+	switch (connector_type) {
+	case DRM_MODE_CONNECTOR_LVDS:
+		VOP_CTRL_SET(vop, rgb_en, 1);
+		break;
+	case DRM_MODE_CONNECTOR_eDP:
+		VOP_CTRL_SET(vop, edp_en, 1);
+		break;
+	case DRM_MODE_CONNECTOR_HDMIA:
+		VOP_CTRL_SET(vop, hdmi_en, 1);
+		break;
+	default:
+		DRM_ERROR("unsupport connector_type[%d]\n", connector_type);
+		return -EINVAL;
+	};
+	VOP_CTRL_SET(vop, out_mode, out_mode);
 
 	return 0;
 }
@@ -1132,22 +1145,6 @@ static void vop_crtc_enable(struct drm_crtc *crtc)
 		vop_dsp_hold_valid_irq_disable(vop);
 	}
 
-	switch (vop->connector_type) {
-	case DRM_MODE_CONNECTOR_LVDS:
-		VOP_CTRL_SET(vop, rgb_en, 1);
-		break;
-	case DRM_MODE_CONNECTOR_eDP:
-		VOP_CTRL_SET(vop, edp_en, 1);
-		break;
-	case DRM_MODE_CONNECTOR_HDMIA:
-		VOP_CTRL_SET(vop, hdmi_en, 1);
-		break;
-	default:
-		DRM_ERROR("unsupport connector_type[%d]\n",
-			  vop->connector_type);
-	};
-	VOP_CTRL_SET(vop, out_mode, vop->connector_out_mode);
-
 	val = 0x8;
 	val |= (adjusted_mode->flags & DRM_MODE_FLAG_NHSYNC) ? 0 : 1;
 	val |= (adjusted_mode->flags & DRM_MODE_FLAG_NVSYNC) ? 0 : (1 << 1);
-- 
1.7.9.5



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

* [PATCH v3 6/8] drm/rockchip: direct config connecter gate and out_mode
@ 2015-12-17  3:08   ` Mark Yao
  0 siblings, 0 replies; 51+ messages in thread
From: Mark Yao @ 2015-12-17  3:08 UTC (permalink / raw)
  To: David Airlie, Heiko Stuebner, dri-devel, linux-arm-kernel,
	linux-rockchip, linux-kernel

Both connecter gate and out_mode are not conflict with mode set
configure. Direct setting connecter gate and out_mode, that allow
connector do rockchip_drm_crtc_mode_config after mode set.

Signed-off-by: Mark Yao <mark.yao@rock-chips.com>
---
Changes in v3: None
Changes in v2: None
 drivers/gpu/drm/rockchip/rockchip_drm_vop.c |   39 +++++++++++++--------------
 1 file changed, 18 insertions(+), 21 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index 9ace3ae..6ded4cc 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -89,9 +89,6 @@ struct vop {
 	struct drm_device *drm_dev;
 	bool is_enabled;
 
-	int connector_type;
-	int connector_out_mode;
-
 	/* mutex vsync_ work */
 	struct mutex vsync_mutex;
 	bool vsync_work_pending;
@@ -1018,8 +1015,24 @@ int rockchip_drm_crtc_mode_config(struct drm_crtc *crtc,
 {
 	struct vop *vop = to_vop(crtc);
 
-	vop->connector_type = connector_type;
-	vop->connector_out_mode = out_mode;
+	if (WARN_ON(!vop->is_enabled))
+		return -EINVAL;
+
+	switch (connector_type) {
+	case DRM_MODE_CONNECTOR_LVDS:
+		VOP_CTRL_SET(vop, rgb_en, 1);
+		break;
+	case DRM_MODE_CONNECTOR_eDP:
+		VOP_CTRL_SET(vop, edp_en, 1);
+		break;
+	case DRM_MODE_CONNECTOR_HDMIA:
+		VOP_CTRL_SET(vop, hdmi_en, 1);
+		break;
+	default:
+		DRM_ERROR("unsupport connector_type[%d]\n", connector_type);
+		return -EINVAL;
+	};
+	VOP_CTRL_SET(vop, out_mode, out_mode);
 
 	return 0;
 }
@@ -1132,22 +1145,6 @@ static void vop_crtc_enable(struct drm_crtc *crtc)
 		vop_dsp_hold_valid_irq_disable(vop);
 	}
 
-	switch (vop->connector_type) {
-	case DRM_MODE_CONNECTOR_LVDS:
-		VOP_CTRL_SET(vop, rgb_en, 1);
-		break;
-	case DRM_MODE_CONNECTOR_eDP:
-		VOP_CTRL_SET(vop, edp_en, 1);
-		break;
-	case DRM_MODE_CONNECTOR_HDMIA:
-		VOP_CTRL_SET(vop, hdmi_en, 1);
-		break;
-	default:
-		DRM_ERROR("unsupport connector_type[%d]\n",
-			  vop->connector_type);
-	};
-	VOP_CTRL_SET(vop, out_mode, vop->connector_out_mode);
-
 	val = 0x8;
 	val |= (adjusted_mode->flags & DRM_MODE_FLAG_NHSYNC) ? 0 : 1;
 	val |= (adjusted_mode->flags & DRM_MODE_FLAG_NVSYNC) ? 0 : (1 << 1);
-- 
1.7.9.5


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

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

* [PATCH v3 6/8] drm/rockchip: direct config connecter gate and out_mode
@ 2015-12-17  3:08   ` Mark Yao
  0 siblings, 0 replies; 51+ messages in thread
From: Mark Yao @ 2015-12-17  3:08 UTC (permalink / raw)
  To: linux-arm-kernel

Both connecter gate and out_mode are not conflict with mode set
configure. Direct setting connecter gate and out_mode, that allow
connector do rockchip_drm_crtc_mode_config after mode set.

Signed-off-by: Mark Yao <mark.yao@rock-chips.com>
---
Changes in v3: None
Changes in v2: None
 drivers/gpu/drm/rockchip/rockchip_drm_vop.c |   39 +++++++++++++--------------
 1 file changed, 18 insertions(+), 21 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index 9ace3ae..6ded4cc 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -89,9 +89,6 @@ struct vop {
 	struct drm_device *drm_dev;
 	bool is_enabled;
 
-	int connector_type;
-	int connector_out_mode;
-
 	/* mutex vsync_ work */
 	struct mutex vsync_mutex;
 	bool vsync_work_pending;
@@ -1018,8 +1015,24 @@ int rockchip_drm_crtc_mode_config(struct drm_crtc *crtc,
 {
 	struct vop *vop = to_vop(crtc);
 
-	vop->connector_type = connector_type;
-	vop->connector_out_mode = out_mode;
+	if (WARN_ON(!vop->is_enabled))
+		return -EINVAL;
+
+	switch (connector_type) {
+	case DRM_MODE_CONNECTOR_LVDS:
+		VOP_CTRL_SET(vop, rgb_en, 1);
+		break;
+	case DRM_MODE_CONNECTOR_eDP:
+		VOP_CTRL_SET(vop, edp_en, 1);
+		break;
+	case DRM_MODE_CONNECTOR_HDMIA:
+		VOP_CTRL_SET(vop, hdmi_en, 1);
+		break;
+	default:
+		DRM_ERROR("unsupport connector_type[%d]\n", connector_type);
+		return -EINVAL;
+	};
+	VOP_CTRL_SET(vop, out_mode, out_mode);
 
 	return 0;
 }
@@ -1132,22 +1145,6 @@ static void vop_crtc_enable(struct drm_crtc *crtc)
 		vop_dsp_hold_valid_irq_disable(vop);
 	}
 
-	switch (vop->connector_type) {
-	case DRM_MODE_CONNECTOR_LVDS:
-		VOP_CTRL_SET(vop, rgb_en, 1);
-		break;
-	case DRM_MODE_CONNECTOR_eDP:
-		VOP_CTRL_SET(vop, edp_en, 1);
-		break;
-	case DRM_MODE_CONNECTOR_HDMIA:
-		VOP_CTRL_SET(vop, hdmi_en, 1);
-		break;
-	default:
-		DRM_ERROR("unsupport connector_type[%d]\n",
-			  vop->connector_type);
-	};
-	VOP_CTRL_SET(vop, out_mode, vop->connector_out_mode);
-
 	val = 0x8;
 	val |= (adjusted_mode->flags & DRM_MODE_FLAG_NHSYNC) ? 0 : 1;
 	val |= (adjusted_mode->flags & DRM_MODE_FLAG_NVSYNC) ? 0 : (1 << 1);
-- 
1.7.9.5

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

* [PATCH v3 7/8] drm: bridge/dw_hdmi: add atomic API support
  2015-12-17  3:08   ` Mark Yao
  (?)
@ 2015-12-17  3:08     ` Mark Yao
  -1 siblings, 0 replies; 51+ messages in thread
From: Mark Yao @ 2015-12-17  3:08 UTC (permalink / raw)
  To: David Airlie, Heiko Stuebner, dri-devel, linux-arm-kernel,
	linux-rockchip, linux-kernel
  Cc: Mark Yao, Russell King, Philipp Zabel, Andy Yan, Fabio Estevam,
	Thierry Reding

Fill atomic needed funcs with default atomic helper library.

Rockchip use dw_hdmi, and drm/rockchip will covert to atomic api,
we need dw_hdmi support atomic funcs.

Now another drm driver use dw_hdmi is imx, not yet atomic, so
check DRIVER_ATOMIC at runtime to spilt atomic and not atomic.

Cc: Russell King <rmk+kernel@arm.linux.org.uk>
Cc: Philipp Zabel <p.zabel@pengutronix.de>
Cc: Andy Yan <andy.yan@rock-chips.com>
Cc: Fabio Estevam <fabio.estevam@freescale.com>
Cc: Thierry Reding <treding@nvidia.com>

Signed-off-by: Mark Yao <mark.yao@rock-chips.com>
---
Changes in v3: None
Changes in v2:
Adviced by Daniel Vetter
- check DRIVER_ATOMIC at runtime to spilt atomic and not atomic.

 drivers/gpu/drm/bridge/dw_hdmi.c |   23 +++++++++++++++++++++--
 1 file changed, 21 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/bridge/dw_hdmi.c b/drivers/gpu/drm/bridge/dw_hdmi.c
index 56de9f1..dc0bdd4 100644
--- a/drivers/gpu/drm/bridge/dw_hdmi.c
+++ b/drivers/gpu/drm/bridge/dw_hdmi.c
@@ -22,6 +22,7 @@
 
 #include <drm/drm_of.h>
 #include <drm/drmP.h>
+#include <drm/drm_atomic_helper.h>
 #include <drm/drm_crtc_helper.h>
 #include <drm/drm_edid.h>
 #include <drm/drm_encoder_slave.h>
@@ -1522,6 +1523,17 @@ static struct drm_connector_funcs dw_hdmi_connector_funcs = {
 	.force = dw_hdmi_connector_force,
 };
 
+static struct drm_connector_funcs dw_hdmi_atomic_connector_funcs = {
+	.dpms = drm_atomic_helper_connector_dpms,
+	.fill_modes = drm_helper_probe_single_connector_modes,
+	.detect = dw_hdmi_connector_detect,
+	.destroy = dw_hdmi_connector_destroy,
+	.force = dw_hdmi_connector_force,
+	.reset = drm_atomic_helper_connector_reset,
+	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
+	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
+};
+
 static struct drm_connector_helper_funcs dw_hdmi_connector_helper_funcs = {
 	.get_modes = dw_hdmi_connector_get_modes,
 	.mode_valid = dw_hdmi_connector_mode_valid,
@@ -1645,8 +1657,15 @@ static int dw_hdmi_register(struct drm_device *drm, struct dw_hdmi *hdmi)
 
 	drm_connector_helper_add(&hdmi->connector,
 				 &dw_hdmi_connector_helper_funcs);
-	drm_connector_init(drm, &hdmi->connector, &dw_hdmi_connector_funcs,
-			   DRM_MODE_CONNECTOR_HDMIA);
+
+	if (drm_core_check_feature(drm, DRIVER_ATOMIC))
+		drm_connector_init(drm, &hdmi->connector,
+				   &dw_hdmi_atomic_connector_funcs,
+				   DRM_MODE_CONNECTOR_HDMIA);
+	else
+		drm_connector_init(drm, &hdmi->connector,
+				   &dw_hdmi_connector_funcs,
+				   DRM_MODE_CONNECTOR_HDMIA);
 
 	hdmi->connector.encoder = encoder;
 
-- 
1.7.9.5



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

* [PATCH v3 7/8] drm: bridge/dw_hdmi: add atomic API support
@ 2015-12-17  3:08     ` Mark Yao
  0 siblings, 0 replies; 51+ messages in thread
From: Mark Yao @ 2015-12-17  3:08 UTC (permalink / raw)
  To: David Airlie, Heiko Stuebner, dri-devel, linux-arm-kernel,
	linux-rockchip, linux-kernel
  Cc: Fabio Estevam, Andy Yan, Russell King, Thierry Reding

Fill atomic needed funcs with default atomic helper library.

Rockchip use dw_hdmi, and drm/rockchip will covert to atomic api,
we need dw_hdmi support atomic funcs.

Now another drm driver use dw_hdmi is imx, not yet atomic, so
check DRIVER_ATOMIC at runtime to spilt atomic and not atomic.

Cc: Russell King <rmk+kernel@arm.linux.org.uk>
Cc: Philipp Zabel <p.zabel@pengutronix.de>
Cc: Andy Yan <andy.yan@rock-chips.com>
Cc: Fabio Estevam <fabio.estevam@freescale.com>
Cc: Thierry Reding <treding@nvidia.com>

Signed-off-by: Mark Yao <mark.yao@rock-chips.com>
---
Changes in v3: None
Changes in v2:
Adviced by Daniel Vetter
- check DRIVER_ATOMIC at runtime to spilt atomic and not atomic.

 drivers/gpu/drm/bridge/dw_hdmi.c |   23 +++++++++++++++++++++--
 1 file changed, 21 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/bridge/dw_hdmi.c b/drivers/gpu/drm/bridge/dw_hdmi.c
index 56de9f1..dc0bdd4 100644
--- a/drivers/gpu/drm/bridge/dw_hdmi.c
+++ b/drivers/gpu/drm/bridge/dw_hdmi.c
@@ -22,6 +22,7 @@
 
 #include <drm/drm_of.h>
 #include <drm/drmP.h>
+#include <drm/drm_atomic_helper.h>
 #include <drm/drm_crtc_helper.h>
 #include <drm/drm_edid.h>
 #include <drm/drm_encoder_slave.h>
@@ -1522,6 +1523,17 @@ static struct drm_connector_funcs dw_hdmi_connector_funcs = {
 	.force = dw_hdmi_connector_force,
 };
 
+static struct drm_connector_funcs dw_hdmi_atomic_connector_funcs = {
+	.dpms = drm_atomic_helper_connector_dpms,
+	.fill_modes = drm_helper_probe_single_connector_modes,
+	.detect = dw_hdmi_connector_detect,
+	.destroy = dw_hdmi_connector_destroy,
+	.force = dw_hdmi_connector_force,
+	.reset = drm_atomic_helper_connector_reset,
+	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
+	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
+};
+
 static struct drm_connector_helper_funcs dw_hdmi_connector_helper_funcs = {
 	.get_modes = dw_hdmi_connector_get_modes,
 	.mode_valid = dw_hdmi_connector_mode_valid,
@@ -1645,8 +1657,15 @@ static int dw_hdmi_register(struct drm_device *drm, struct dw_hdmi *hdmi)
 
 	drm_connector_helper_add(&hdmi->connector,
 				 &dw_hdmi_connector_helper_funcs);
-	drm_connector_init(drm, &hdmi->connector, &dw_hdmi_connector_funcs,
-			   DRM_MODE_CONNECTOR_HDMIA);
+
+	if (drm_core_check_feature(drm, DRIVER_ATOMIC))
+		drm_connector_init(drm, &hdmi->connector,
+				   &dw_hdmi_atomic_connector_funcs,
+				   DRM_MODE_CONNECTOR_HDMIA);
+	else
+		drm_connector_init(drm, &hdmi->connector,
+				   &dw_hdmi_connector_funcs,
+				   DRM_MODE_CONNECTOR_HDMIA);
 
 	hdmi->connector.encoder = encoder;
 
-- 
1.7.9.5


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

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

* [PATCH v3 7/8] drm: bridge/dw_hdmi: add atomic API support
@ 2015-12-17  3:08     ` Mark Yao
  0 siblings, 0 replies; 51+ messages in thread
From: Mark Yao @ 2015-12-17  3:08 UTC (permalink / raw)
  To: linux-arm-kernel

Fill atomic needed funcs with default atomic helper library.

Rockchip use dw_hdmi, and drm/rockchip will covert to atomic api,
we need dw_hdmi support atomic funcs.

Now another drm driver use dw_hdmi is imx, not yet atomic, so
check DRIVER_ATOMIC at runtime to spilt atomic and not atomic.

Cc: Russell King <rmk+kernel@arm.linux.org.uk>
Cc: Philipp Zabel <p.zabel@pengutronix.de>
Cc: Andy Yan <andy.yan@rock-chips.com>
Cc: Fabio Estevam <fabio.estevam@freescale.com>
Cc: Thierry Reding <treding@nvidia.com>

Signed-off-by: Mark Yao <mark.yao@rock-chips.com>
---
Changes in v3: None
Changes in v2:
Adviced by Daniel Vetter
- check DRIVER_ATOMIC at runtime to spilt atomic and not atomic.

 drivers/gpu/drm/bridge/dw_hdmi.c |   23 +++++++++++++++++++++--
 1 file changed, 21 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/bridge/dw_hdmi.c b/drivers/gpu/drm/bridge/dw_hdmi.c
index 56de9f1..dc0bdd4 100644
--- a/drivers/gpu/drm/bridge/dw_hdmi.c
+++ b/drivers/gpu/drm/bridge/dw_hdmi.c
@@ -22,6 +22,7 @@
 
 #include <drm/drm_of.h>
 #include <drm/drmP.h>
+#include <drm/drm_atomic_helper.h>
 #include <drm/drm_crtc_helper.h>
 #include <drm/drm_edid.h>
 #include <drm/drm_encoder_slave.h>
@@ -1522,6 +1523,17 @@ static struct drm_connector_funcs dw_hdmi_connector_funcs = {
 	.force = dw_hdmi_connector_force,
 };
 
+static struct drm_connector_funcs dw_hdmi_atomic_connector_funcs = {
+	.dpms = drm_atomic_helper_connector_dpms,
+	.fill_modes = drm_helper_probe_single_connector_modes,
+	.detect = dw_hdmi_connector_detect,
+	.destroy = dw_hdmi_connector_destroy,
+	.force = dw_hdmi_connector_force,
+	.reset = drm_atomic_helper_connector_reset,
+	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
+	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
+};
+
 static struct drm_connector_helper_funcs dw_hdmi_connector_helper_funcs = {
 	.get_modes = dw_hdmi_connector_get_modes,
 	.mode_valid = dw_hdmi_connector_mode_valid,
@@ -1645,8 +1657,15 @@ static int dw_hdmi_register(struct drm_device *drm, struct dw_hdmi *hdmi)
 
 	drm_connector_helper_add(&hdmi->connector,
 				 &dw_hdmi_connector_helper_funcs);
-	drm_connector_init(drm, &hdmi->connector, &dw_hdmi_connector_funcs,
-			   DRM_MODE_CONNECTOR_HDMIA);
+
+	if (drm_core_check_feature(drm, DRIVER_ATOMIC))
+		drm_connector_init(drm, &hdmi->connector,
+				   &dw_hdmi_atomic_connector_funcs,
+				   DRM_MODE_CONNECTOR_HDMIA);
+	else
+		drm_connector_init(drm, &hdmi->connector,
+				   &dw_hdmi_connector_funcs,
+				   DRM_MODE_CONNECTOR_HDMIA);
 
 	hdmi->connector.encoder = encoder;
 
-- 
1.7.9.5

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

* [PATCH 8/8] drm/rockchip: dw_hdmi: use encoder enable function
  2015-12-17  3:08   ` Mark Yao
  (?)
@ 2015-12-17  3:08     ` Mark Yao
  -1 siblings, 0 replies; 51+ messages in thread
From: Mark Yao @ 2015-12-17  3:08 UTC (permalink / raw)
  To: David Airlie, Heiko Stuebner, dri-devel, linux-arm-kernel,
	linux-rockchip, linux-kernel
  Cc: Mark Yao

encoder.enable is more compatible to atomic api than encoder.prepare/commit

Signed-off-by: Mark Yao <mark.yao@rock-chips.com>
---
Changes in v3: None
Changes in v2: None

 drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c |   14 +++++---------
 1 file changed, 5 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
index 525b5a8..8e1605c 100644
--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
@@ -195,12 +195,15 @@ static void dw_hdmi_rockchip_encoder_mode_set(struct drm_encoder *encoder,
 {
 }
 
-static void dw_hdmi_rockchip_encoder_commit(struct drm_encoder *encoder)
+static void dw_hdmi_rockchip_encoder_enable(struct drm_encoder *encoder)
 {
 	struct rockchip_hdmi *hdmi = to_rockchip_hdmi(encoder);
 	u32 val;
 	int mux;
 
+	rockchip_drm_crtc_mode_config(encoder->crtc, DRM_MODE_CONNECTOR_HDMIA,
+				      ROCKCHIP_OUT_MODE_AAAA);
+
 	mux = rockchip_drm_encoder_get_mux_id(hdmi->dev->of_node, encoder);
 	if (mux)
 		val = HDMI_SEL_VOP_LIT | (HDMI_SEL_VOP_LIT << 16);
@@ -212,17 +215,10 @@ static void dw_hdmi_rockchip_encoder_commit(struct drm_encoder *encoder)
 		(mux) ? "LIT" : "BIG");
 }
 
-static void dw_hdmi_rockchip_encoder_prepare(struct drm_encoder *encoder)
-{
-	rockchip_drm_crtc_mode_config(encoder->crtc, DRM_MODE_CONNECTOR_HDMIA,
-				      ROCKCHIP_OUT_MODE_AAAA);
-}
-
 static struct drm_encoder_helper_funcs dw_hdmi_rockchip_encoder_helper_funcs = {
 	.mode_fixup = dw_hdmi_rockchip_encoder_mode_fixup,
 	.mode_set   = dw_hdmi_rockchip_encoder_mode_set,
-	.prepare    = dw_hdmi_rockchip_encoder_prepare,
-	.commit     = dw_hdmi_rockchip_encoder_commit,
+	.enable     = dw_hdmi_rockchip_encoder_enable,
 	.disable    = dw_hdmi_rockchip_encoder_disable,
 };
 
-- 
1.7.9.5



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

* [PATCH 8/8] drm/rockchip: dw_hdmi: use encoder enable function
@ 2015-12-17  3:08     ` Mark Yao
  0 siblings, 0 replies; 51+ messages in thread
From: Mark Yao @ 2015-12-17  3:08 UTC (permalink / raw)
  To: David Airlie, Heiko Stuebner, dri-devel, linux-arm-kernel,
	linux-rockchip, linux-kernel

encoder.enable is more compatible to atomic api than encoder.prepare/commit

Signed-off-by: Mark Yao <mark.yao@rock-chips.com>
---
Changes in v3: None
Changes in v2: None

 drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c |   14 +++++---------
 1 file changed, 5 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
index 525b5a8..8e1605c 100644
--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
@@ -195,12 +195,15 @@ static void dw_hdmi_rockchip_encoder_mode_set(struct drm_encoder *encoder,
 {
 }
 
-static void dw_hdmi_rockchip_encoder_commit(struct drm_encoder *encoder)
+static void dw_hdmi_rockchip_encoder_enable(struct drm_encoder *encoder)
 {
 	struct rockchip_hdmi *hdmi = to_rockchip_hdmi(encoder);
 	u32 val;
 	int mux;
 
+	rockchip_drm_crtc_mode_config(encoder->crtc, DRM_MODE_CONNECTOR_HDMIA,
+				      ROCKCHIP_OUT_MODE_AAAA);
+
 	mux = rockchip_drm_encoder_get_mux_id(hdmi->dev->of_node, encoder);
 	if (mux)
 		val = HDMI_SEL_VOP_LIT | (HDMI_SEL_VOP_LIT << 16);
@@ -212,17 +215,10 @@ static void dw_hdmi_rockchip_encoder_commit(struct drm_encoder *encoder)
 		(mux) ? "LIT" : "BIG");
 }
 
-static void dw_hdmi_rockchip_encoder_prepare(struct drm_encoder *encoder)
-{
-	rockchip_drm_crtc_mode_config(encoder->crtc, DRM_MODE_CONNECTOR_HDMIA,
-				      ROCKCHIP_OUT_MODE_AAAA);
-}
-
 static struct drm_encoder_helper_funcs dw_hdmi_rockchip_encoder_helper_funcs = {
 	.mode_fixup = dw_hdmi_rockchip_encoder_mode_fixup,
 	.mode_set   = dw_hdmi_rockchip_encoder_mode_set,
-	.prepare    = dw_hdmi_rockchip_encoder_prepare,
-	.commit     = dw_hdmi_rockchip_encoder_commit,
+	.enable     = dw_hdmi_rockchip_encoder_enable,
 	.disable    = dw_hdmi_rockchip_encoder_disable,
 };
 
-- 
1.7.9.5


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

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

* [PATCH 8/8] drm/rockchip: dw_hdmi: use encoder enable function
@ 2015-12-17  3:08     ` Mark Yao
  0 siblings, 0 replies; 51+ messages in thread
From: Mark Yao @ 2015-12-17  3:08 UTC (permalink / raw)
  To: linux-arm-kernel

encoder.enable is more compatible to atomic api than encoder.prepare/commit

Signed-off-by: Mark Yao <mark.yao@rock-chips.com>
---
Changes in v3: None
Changes in v2: None

 drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c |   14 +++++---------
 1 file changed, 5 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
index 525b5a8..8e1605c 100644
--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
@@ -195,12 +195,15 @@ static void dw_hdmi_rockchip_encoder_mode_set(struct drm_encoder *encoder,
 {
 }
 
-static void dw_hdmi_rockchip_encoder_commit(struct drm_encoder *encoder)
+static void dw_hdmi_rockchip_encoder_enable(struct drm_encoder *encoder)
 {
 	struct rockchip_hdmi *hdmi = to_rockchip_hdmi(encoder);
 	u32 val;
 	int mux;
 
+	rockchip_drm_crtc_mode_config(encoder->crtc, DRM_MODE_CONNECTOR_HDMIA,
+				      ROCKCHIP_OUT_MODE_AAAA);
+
 	mux = rockchip_drm_encoder_get_mux_id(hdmi->dev->of_node, encoder);
 	if (mux)
 		val = HDMI_SEL_VOP_LIT | (HDMI_SEL_VOP_LIT << 16);
@@ -212,17 +215,10 @@ static void dw_hdmi_rockchip_encoder_commit(struct drm_encoder *encoder)
 		(mux) ? "LIT" : "BIG");
 }
 
-static void dw_hdmi_rockchip_encoder_prepare(struct drm_encoder *encoder)
-{
-	rockchip_drm_crtc_mode_config(encoder->crtc, DRM_MODE_CONNECTOR_HDMIA,
-				      ROCKCHIP_OUT_MODE_AAAA);
-}
-
 static struct drm_encoder_helper_funcs dw_hdmi_rockchip_encoder_helper_funcs = {
 	.mode_fixup = dw_hdmi_rockchip_encoder_mode_fixup,
 	.mode_set   = dw_hdmi_rockchip_encoder_mode_set,
-	.prepare    = dw_hdmi_rockchip_encoder_prepare,
-	.commit     = dw_hdmi_rockchip_encoder_commit,
+	.enable     = dw_hdmi_rockchip_encoder_enable,
 	.disable    = dw_hdmi_rockchip_encoder_disable,
 };
 
-- 
1.7.9.5

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

* [PATCH v3 7/8] drm: bridge/dw_hdmi: add atomic API support
  2015-12-17  3:01 ` Mark Yao
  (?)
@ 2015-12-17  3:11   ` Mark Yao
  -1 siblings, 0 replies; 51+ messages in thread
From: Mark Yao @ 2015-12-17  3:11 UTC (permalink / raw)
  To: David Airlie, Heiko Stuebner, dri-devel, linux-arm-kernel,
	linux-rockchip, linux-kernel
  Cc: Mark Yao, Russell King, Philipp Zabel, Andy Yan, Fabio Estevam,
	Thierry Reding

Fill atomic needed funcs with default atomic helper library.

Rockchip use dw_hdmi, and drm/rockchip will covert to atomic api,
we need dw_hdmi support atomic funcs.

Now another drm driver use dw_hdmi is imx, not yet atomic, so
check DRIVER_ATOMIC at runtime to spilt atomic and not atomic.

Cc: Russell King <rmk+kernel@arm.linux.org.uk>
Cc: Philipp Zabel <p.zabel@pengutronix.de>
Cc: Andy Yan <andy.yan@rock-chips.com>
Cc: Fabio Estevam <fabio.estevam@freescale.com>
Cc: Thierry Reding <treding@nvidia.com>

Signed-off-by: Mark Yao <mark.yao@rock-chips.com>
---
Changes in v3: None
Changes in v2:
Adviced by Daniel Vetter
- check DRIVER_ATOMIC at runtime to spilt atomic and not atomic.

 drivers/gpu/drm/bridge/dw_hdmi.c |   23 +++++++++++++++++++++--
 1 file changed, 21 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/bridge/dw_hdmi.c b/drivers/gpu/drm/bridge/dw_hdmi.c
index 56de9f1..dc0bdd4 100644
--- a/drivers/gpu/drm/bridge/dw_hdmi.c
+++ b/drivers/gpu/drm/bridge/dw_hdmi.c
@@ -22,6 +22,7 @@
 
 #include <drm/drm_of.h>
 #include <drm/drmP.h>
+#include <drm/drm_atomic_helper.h>
 #include <drm/drm_crtc_helper.h>
 #include <drm/drm_edid.h>
 #include <drm/drm_encoder_slave.h>
@@ -1522,6 +1523,17 @@ static struct drm_connector_funcs dw_hdmi_connector_funcs = {
 	.force = dw_hdmi_connector_force,
 };
 
+static struct drm_connector_funcs dw_hdmi_atomic_connector_funcs = {
+	.dpms = drm_atomic_helper_connector_dpms,
+	.fill_modes = drm_helper_probe_single_connector_modes,
+	.detect = dw_hdmi_connector_detect,
+	.destroy = dw_hdmi_connector_destroy,
+	.force = dw_hdmi_connector_force,
+	.reset = drm_atomic_helper_connector_reset,
+	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
+	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
+};
+
 static struct drm_connector_helper_funcs dw_hdmi_connector_helper_funcs = {
 	.get_modes = dw_hdmi_connector_get_modes,
 	.mode_valid = dw_hdmi_connector_mode_valid,
@@ -1645,8 +1657,15 @@ static int dw_hdmi_register(struct drm_device *drm, struct dw_hdmi *hdmi)
 
 	drm_connector_helper_add(&hdmi->connector,
 				 &dw_hdmi_connector_helper_funcs);
-	drm_connector_init(drm, &hdmi->connector, &dw_hdmi_connector_funcs,
-			   DRM_MODE_CONNECTOR_HDMIA);
+
+	if (drm_core_check_feature(drm, DRIVER_ATOMIC))
+		drm_connector_init(drm, &hdmi->connector,
+				   &dw_hdmi_atomic_connector_funcs,
+				   DRM_MODE_CONNECTOR_HDMIA);
+	else
+		drm_connector_init(drm, &hdmi->connector,
+				   &dw_hdmi_connector_funcs,
+				   DRM_MODE_CONNECTOR_HDMIA);
 
 	hdmi->connector.encoder = encoder;
 
-- 
1.7.9.5



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

* [PATCH v3 7/8] drm: bridge/dw_hdmi: add atomic API support
@ 2015-12-17  3:11   ` Mark Yao
  0 siblings, 0 replies; 51+ messages in thread
From: Mark Yao @ 2015-12-17  3:11 UTC (permalink / raw)
  To: David Airlie, Heiko Stuebner, dri-devel, linux-arm-kernel,
	linux-rockchip, linux-kernel
  Cc: Fabio Estevam, Andy Yan, Russell King, Thierry Reding

Fill atomic needed funcs with default atomic helper library.

Rockchip use dw_hdmi, and drm/rockchip will covert to atomic api,
we need dw_hdmi support atomic funcs.

Now another drm driver use dw_hdmi is imx, not yet atomic, so
check DRIVER_ATOMIC at runtime to spilt atomic and not atomic.

Cc: Russell King <rmk+kernel@arm.linux.org.uk>
Cc: Philipp Zabel <p.zabel@pengutronix.de>
Cc: Andy Yan <andy.yan@rock-chips.com>
Cc: Fabio Estevam <fabio.estevam@freescale.com>
Cc: Thierry Reding <treding@nvidia.com>

Signed-off-by: Mark Yao <mark.yao@rock-chips.com>
---
Changes in v3: None
Changes in v2:
Adviced by Daniel Vetter
- check DRIVER_ATOMIC at runtime to spilt atomic and not atomic.

 drivers/gpu/drm/bridge/dw_hdmi.c |   23 +++++++++++++++++++++--
 1 file changed, 21 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/bridge/dw_hdmi.c b/drivers/gpu/drm/bridge/dw_hdmi.c
index 56de9f1..dc0bdd4 100644
--- a/drivers/gpu/drm/bridge/dw_hdmi.c
+++ b/drivers/gpu/drm/bridge/dw_hdmi.c
@@ -22,6 +22,7 @@
 
 #include <drm/drm_of.h>
 #include <drm/drmP.h>
+#include <drm/drm_atomic_helper.h>
 #include <drm/drm_crtc_helper.h>
 #include <drm/drm_edid.h>
 #include <drm/drm_encoder_slave.h>
@@ -1522,6 +1523,17 @@ static struct drm_connector_funcs dw_hdmi_connector_funcs = {
 	.force = dw_hdmi_connector_force,
 };
 
+static struct drm_connector_funcs dw_hdmi_atomic_connector_funcs = {
+	.dpms = drm_atomic_helper_connector_dpms,
+	.fill_modes = drm_helper_probe_single_connector_modes,
+	.detect = dw_hdmi_connector_detect,
+	.destroy = dw_hdmi_connector_destroy,
+	.force = dw_hdmi_connector_force,
+	.reset = drm_atomic_helper_connector_reset,
+	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
+	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
+};
+
 static struct drm_connector_helper_funcs dw_hdmi_connector_helper_funcs = {
 	.get_modes = dw_hdmi_connector_get_modes,
 	.mode_valid = dw_hdmi_connector_mode_valid,
@@ -1645,8 +1657,15 @@ static int dw_hdmi_register(struct drm_device *drm, struct dw_hdmi *hdmi)
 
 	drm_connector_helper_add(&hdmi->connector,
 				 &dw_hdmi_connector_helper_funcs);
-	drm_connector_init(drm, &hdmi->connector, &dw_hdmi_connector_funcs,
-			   DRM_MODE_CONNECTOR_HDMIA);
+
+	if (drm_core_check_feature(drm, DRIVER_ATOMIC))
+		drm_connector_init(drm, &hdmi->connector,
+				   &dw_hdmi_atomic_connector_funcs,
+				   DRM_MODE_CONNECTOR_HDMIA);
+	else
+		drm_connector_init(drm, &hdmi->connector,
+				   &dw_hdmi_connector_funcs,
+				   DRM_MODE_CONNECTOR_HDMIA);
 
 	hdmi->connector.encoder = encoder;
 
-- 
1.7.9.5


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

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

* [PATCH v3 7/8] drm: bridge/dw_hdmi: add atomic API support
@ 2015-12-17  3:11   ` Mark Yao
  0 siblings, 0 replies; 51+ messages in thread
From: Mark Yao @ 2015-12-17  3:11 UTC (permalink / raw)
  To: linux-arm-kernel

Fill atomic needed funcs with default atomic helper library.

Rockchip use dw_hdmi, and drm/rockchip will covert to atomic api,
we need dw_hdmi support atomic funcs.

Now another drm driver use dw_hdmi is imx, not yet atomic, so
check DRIVER_ATOMIC at runtime to spilt atomic and not atomic.

Cc: Russell King <rmk+kernel@arm.linux.org.uk>
Cc: Philipp Zabel <p.zabel@pengutronix.de>
Cc: Andy Yan <andy.yan@rock-chips.com>
Cc: Fabio Estevam <fabio.estevam@freescale.com>
Cc: Thierry Reding <treding@nvidia.com>

Signed-off-by: Mark Yao <mark.yao@rock-chips.com>
---
Changes in v3: None
Changes in v2:
Adviced by Daniel Vetter
- check DRIVER_ATOMIC at runtime to spilt atomic and not atomic.

 drivers/gpu/drm/bridge/dw_hdmi.c |   23 +++++++++++++++++++++--
 1 file changed, 21 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/bridge/dw_hdmi.c b/drivers/gpu/drm/bridge/dw_hdmi.c
index 56de9f1..dc0bdd4 100644
--- a/drivers/gpu/drm/bridge/dw_hdmi.c
+++ b/drivers/gpu/drm/bridge/dw_hdmi.c
@@ -22,6 +22,7 @@
 
 #include <drm/drm_of.h>
 #include <drm/drmP.h>
+#include <drm/drm_atomic_helper.h>
 #include <drm/drm_crtc_helper.h>
 #include <drm/drm_edid.h>
 #include <drm/drm_encoder_slave.h>
@@ -1522,6 +1523,17 @@ static struct drm_connector_funcs dw_hdmi_connector_funcs = {
 	.force = dw_hdmi_connector_force,
 };
 
+static struct drm_connector_funcs dw_hdmi_atomic_connector_funcs = {
+	.dpms = drm_atomic_helper_connector_dpms,
+	.fill_modes = drm_helper_probe_single_connector_modes,
+	.detect = dw_hdmi_connector_detect,
+	.destroy = dw_hdmi_connector_destroy,
+	.force = dw_hdmi_connector_force,
+	.reset = drm_atomic_helper_connector_reset,
+	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
+	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
+};
+
 static struct drm_connector_helper_funcs dw_hdmi_connector_helper_funcs = {
 	.get_modes = dw_hdmi_connector_get_modes,
 	.mode_valid = dw_hdmi_connector_mode_valid,
@@ -1645,8 +1657,15 @@ static int dw_hdmi_register(struct drm_device *drm, struct dw_hdmi *hdmi)
 
 	drm_connector_helper_add(&hdmi->connector,
 				 &dw_hdmi_connector_helper_funcs);
-	drm_connector_init(drm, &hdmi->connector, &dw_hdmi_connector_funcs,
-			   DRM_MODE_CONNECTOR_HDMIA);
+
+	if (drm_core_check_feature(drm, DRIVER_ATOMIC))
+		drm_connector_init(drm, &hdmi->connector,
+				   &dw_hdmi_atomic_connector_funcs,
+				   DRM_MODE_CONNECTOR_HDMIA);
+	else
+		drm_connector_init(drm, &hdmi->connector,
+				   &dw_hdmi_connector_funcs,
+				   DRM_MODE_CONNECTOR_HDMIA);
 
 	hdmi->connector.encoder = encoder;
 
-- 
1.7.9.5

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

* [PATCH v3 8/8] drm/rockchip: dw_hdmi: use encoder enable function
  2015-12-17  3:01 ` Mark Yao
@ 2015-12-17  3:13   ` Mark Yao
  -1 siblings, 0 replies; 51+ messages in thread
From: Mark Yao @ 2015-12-17  3:13 UTC (permalink / raw)
  To: David Airlie, Heiko Stuebner, dri-devel, linux-arm-kernel,
	linux-rockchip, linux-kernel
  Cc: Mark Yao

encoder.enable is more compatible to atomic api than encoder.prepare/commit

Signed-off-by: Mark Yao <mark.yao@rock-chips.com>
---
Changes in v3: None
Changes in v2: None

 drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c |   14 +++++---------
 1 file changed, 5 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
index 525b5a8..8e1605c 100644
--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
@@ -195,12 +195,15 @@ static void dw_hdmi_rockchip_encoder_mode_set(struct drm_encoder *encoder,
 {
 }
 
-static void dw_hdmi_rockchip_encoder_commit(struct drm_encoder *encoder)
+static void dw_hdmi_rockchip_encoder_enable(struct drm_encoder *encoder)
 {
 	struct rockchip_hdmi *hdmi = to_rockchip_hdmi(encoder);
 	u32 val;
 	int mux;
 
+	rockchip_drm_crtc_mode_config(encoder->crtc, DRM_MODE_CONNECTOR_HDMIA,
+				      ROCKCHIP_OUT_MODE_AAAA);
+
 	mux = rockchip_drm_encoder_get_mux_id(hdmi->dev->of_node, encoder);
 	if (mux)
 		val = HDMI_SEL_VOP_LIT | (HDMI_SEL_VOP_LIT << 16);
@@ -212,17 +215,10 @@ static void dw_hdmi_rockchip_encoder_commit(struct drm_encoder *encoder)
 		(mux) ? "LIT" : "BIG");
 }
 
-static void dw_hdmi_rockchip_encoder_prepare(struct drm_encoder *encoder)
-{
-	rockchip_drm_crtc_mode_config(encoder->crtc, DRM_MODE_CONNECTOR_HDMIA,
-				      ROCKCHIP_OUT_MODE_AAAA);
-}
-
 static struct drm_encoder_helper_funcs dw_hdmi_rockchip_encoder_helper_funcs = {
 	.mode_fixup = dw_hdmi_rockchip_encoder_mode_fixup,
 	.mode_set   = dw_hdmi_rockchip_encoder_mode_set,
-	.prepare    = dw_hdmi_rockchip_encoder_prepare,
-	.commit     = dw_hdmi_rockchip_encoder_commit,
+	.enable     = dw_hdmi_rockchip_encoder_enable,
 	.disable    = dw_hdmi_rockchip_encoder_disable,
 };
 
-- 
1.7.9.5



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

* [PATCH v3 8/8] drm/rockchip: dw_hdmi: use encoder enable function
@ 2015-12-17  3:13   ` Mark Yao
  0 siblings, 0 replies; 51+ messages in thread
From: Mark Yao @ 2015-12-17  3:13 UTC (permalink / raw)
  To: linux-arm-kernel

encoder.enable is more compatible to atomic api than encoder.prepare/commit

Signed-off-by: Mark Yao <mark.yao@rock-chips.com>
---
Changes in v3: None
Changes in v2: None

 drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c |   14 +++++---------
 1 file changed, 5 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
index 525b5a8..8e1605c 100644
--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
@@ -195,12 +195,15 @@ static void dw_hdmi_rockchip_encoder_mode_set(struct drm_encoder *encoder,
 {
 }
 
-static void dw_hdmi_rockchip_encoder_commit(struct drm_encoder *encoder)
+static void dw_hdmi_rockchip_encoder_enable(struct drm_encoder *encoder)
 {
 	struct rockchip_hdmi *hdmi = to_rockchip_hdmi(encoder);
 	u32 val;
 	int mux;
 
+	rockchip_drm_crtc_mode_config(encoder->crtc, DRM_MODE_CONNECTOR_HDMIA,
+				      ROCKCHIP_OUT_MODE_AAAA);
+
 	mux = rockchip_drm_encoder_get_mux_id(hdmi->dev->of_node, encoder);
 	if (mux)
 		val = HDMI_SEL_VOP_LIT | (HDMI_SEL_VOP_LIT << 16);
@@ -212,17 +215,10 @@ static void dw_hdmi_rockchip_encoder_commit(struct drm_encoder *encoder)
 		(mux) ? "LIT" : "BIG");
 }
 
-static void dw_hdmi_rockchip_encoder_prepare(struct drm_encoder *encoder)
-{
-	rockchip_drm_crtc_mode_config(encoder->crtc, DRM_MODE_CONNECTOR_HDMIA,
-				      ROCKCHIP_OUT_MODE_AAAA);
-}
-
 static struct drm_encoder_helper_funcs dw_hdmi_rockchip_encoder_helper_funcs = {
 	.mode_fixup = dw_hdmi_rockchip_encoder_mode_fixup,
 	.mode_set   = dw_hdmi_rockchip_encoder_mode_set,
-	.prepare    = dw_hdmi_rockchip_encoder_prepare,
-	.commit     = dw_hdmi_rockchip_encoder_commit,
+	.enable     = dw_hdmi_rockchip_encoder_enable,
 	.disable    = dw_hdmi_rockchip_encoder_disable,
 };
 
-- 
1.7.9.5

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

* Re: [PATCH v3 7/8] drm: bridge/dw_hdmi: add atomic API support
  2015-12-17  3:08     ` Mark Yao
  (?)
@ 2015-12-17  3:15       ` Mark yao
  -1 siblings, 0 replies; 51+ messages in thread
From: Mark yao @ 2015-12-17  3:15 UTC (permalink / raw)
  To: David Airlie, Heiko Stuebner, dri-devel, linux-arm-kernel,
	linux-rockchip, linux-kernel
  Cc: Russell King, Philipp Zabel, Andy Yan, Fabio Estevam, Thierry Reding

Sorry, Ops, fat finger, discard this lost thread mail.

On 2015年12月17日 11:08, Mark Yao wrote:
> Fill atomic needed funcs with default atomic helper library.
>
> Rockchip use dw_hdmi, and drm/rockchip will covert to atomic api,
> we need dw_hdmi support atomic funcs.
>
> Now another drm driver use dw_hdmi is imx, not yet atomic, so
> check DRIVER_ATOMIC at runtime to spilt atomic and not atomic.
>
> Cc: Russell King <rmk+kernel@arm.linux.org.uk>
> Cc: Philipp Zabel <p.zabel@pengutronix.de>
> Cc: Andy Yan <andy.yan@rock-chips.com>
> Cc: Fabio Estevam <fabio.estevam@freescale.com>
> Cc: Thierry Reding <treding@nvidia.com>
>
> Signed-off-by: Mark Yao <mark.yao@rock-chips.com>
> ---
> Changes in v3: None
> Changes in v2:
> Adviced by Daniel Vetter
> - check DRIVER_ATOMIC at runtime to spilt atomic and not atomic.
>
>   drivers/gpu/drm/bridge/dw_hdmi.c |   23 +++++++++++++++++++++--
>   1 file changed, 21 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/bridge/dw_hdmi.c b/drivers/gpu/drm/bridge/dw_hdmi.c
> index 56de9f1..dc0bdd4 100644
> --- a/drivers/gpu/drm/bridge/dw_hdmi.c
> +++ b/drivers/gpu/drm/bridge/dw_hdmi.c
> @@ -22,6 +22,7 @@
>   
>   #include <drm/drm_of.h>
>   #include <drm/drmP.h>
> +#include <drm/drm_atomic_helper.h>
>   #include <drm/drm_crtc_helper.h>
>   #include <drm/drm_edid.h>
>   #include <drm/drm_encoder_slave.h>
> @@ -1522,6 +1523,17 @@ static struct drm_connector_funcs dw_hdmi_connector_funcs = {
>   	.force = dw_hdmi_connector_force,
>   };
>   
> +static struct drm_connector_funcs dw_hdmi_atomic_connector_funcs = {
> +	.dpms = drm_atomic_helper_connector_dpms,
> +	.fill_modes = drm_helper_probe_single_connector_modes,
> +	.detect = dw_hdmi_connector_detect,
> +	.destroy = dw_hdmi_connector_destroy,
> +	.force = dw_hdmi_connector_force,
> +	.reset = drm_atomic_helper_connector_reset,
> +	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
> +	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
> +};
> +
>   static struct drm_connector_helper_funcs dw_hdmi_connector_helper_funcs = {
>   	.get_modes = dw_hdmi_connector_get_modes,
>   	.mode_valid = dw_hdmi_connector_mode_valid,
> @@ -1645,8 +1657,15 @@ static int dw_hdmi_register(struct drm_device *drm, struct dw_hdmi *hdmi)
>   
>   	drm_connector_helper_add(&hdmi->connector,
>   				 &dw_hdmi_connector_helper_funcs);
> -	drm_connector_init(drm, &hdmi->connector, &dw_hdmi_connector_funcs,
> -			   DRM_MODE_CONNECTOR_HDMIA);
> +
> +	if (drm_core_check_feature(drm, DRIVER_ATOMIC))
> +		drm_connector_init(drm, &hdmi->connector,
> +				   &dw_hdmi_atomic_connector_funcs,
> +				   DRM_MODE_CONNECTOR_HDMIA);
> +	else
> +		drm_connector_init(drm, &hdmi->connector,
> +				   &dw_hdmi_connector_funcs,
> +				   DRM_MODE_CONNECTOR_HDMIA);
>   
>   	hdmi->connector.encoder = encoder;
>   


-- 
Mark Yao



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

* Re: [PATCH v3 7/8] drm: bridge/dw_hdmi: add atomic API support
@ 2015-12-17  3:15       ` Mark yao
  0 siblings, 0 replies; 51+ messages in thread
From: Mark yao @ 2015-12-17  3:15 UTC (permalink / raw)
  To: David Airlie, Heiko Stuebner, dri-devel, linux-arm-kernel,
	linux-rockchip, linux-kernel
  Cc: Fabio Estevam, Russell King, Thierry Reding, Andy Yan

Sorry, Ops, fat finger, discard this lost thread mail.

On 2015年12月17日 11:08, Mark Yao wrote:
> Fill atomic needed funcs with default atomic helper library.
>
> Rockchip use dw_hdmi, and drm/rockchip will covert to atomic api,
> we need dw_hdmi support atomic funcs.
>
> Now another drm driver use dw_hdmi is imx, not yet atomic, so
> check DRIVER_ATOMIC at runtime to spilt atomic and not atomic.
>
> Cc: Russell King <rmk+kernel@arm.linux.org.uk>
> Cc: Philipp Zabel <p.zabel@pengutronix.de>
> Cc: Andy Yan <andy.yan@rock-chips.com>
> Cc: Fabio Estevam <fabio.estevam@freescale.com>
> Cc: Thierry Reding <treding@nvidia.com>
>
> Signed-off-by: Mark Yao <mark.yao@rock-chips.com>
> ---
> Changes in v3: None
> Changes in v2:
> Adviced by Daniel Vetter
> - check DRIVER_ATOMIC at runtime to spilt atomic and not atomic.
>
>   drivers/gpu/drm/bridge/dw_hdmi.c |   23 +++++++++++++++++++++--
>   1 file changed, 21 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/bridge/dw_hdmi.c b/drivers/gpu/drm/bridge/dw_hdmi.c
> index 56de9f1..dc0bdd4 100644
> --- a/drivers/gpu/drm/bridge/dw_hdmi.c
> +++ b/drivers/gpu/drm/bridge/dw_hdmi.c
> @@ -22,6 +22,7 @@
>   
>   #include <drm/drm_of.h>
>   #include <drm/drmP.h>
> +#include <drm/drm_atomic_helper.h>
>   #include <drm/drm_crtc_helper.h>
>   #include <drm/drm_edid.h>
>   #include <drm/drm_encoder_slave.h>
> @@ -1522,6 +1523,17 @@ static struct drm_connector_funcs dw_hdmi_connector_funcs = {
>   	.force = dw_hdmi_connector_force,
>   };
>   
> +static struct drm_connector_funcs dw_hdmi_atomic_connector_funcs = {
> +	.dpms = drm_atomic_helper_connector_dpms,
> +	.fill_modes = drm_helper_probe_single_connector_modes,
> +	.detect = dw_hdmi_connector_detect,
> +	.destroy = dw_hdmi_connector_destroy,
> +	.force = dw_hdmi_connector_force,
> +	.reset = drm_atomic_helper_connector_reset,
> +	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
> +	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
> +};
> +
>   static struct drm_connector_helper_funcs dw_hdmi_connector_helper_funcs = {
>   	.get_modes = dw_hdmi_connector_get_modes,
>   	.mode_valid = dw_hdmi_connector_mode_valid,
> @@ -1645,8 +1657,15 @@ static int dw_hdmi_register(struct drm_device *drm, struct dw_hdmi *hdmi)
>   
>   	drm_connector_helper_add(&hdmi->connector,
>   				 &dw_hdmi_connector_helper_funcs);
> -	drm_connector_init(drm, &hdmi->connector, &dw_hdmi_connector_funcs,
> -			   DRM_MODE_CONNECTOR_HDMIA);
> +
> +	if (drm_core_check_feature(drm, DRIVER_ATOMIC))
> +		drm_connector_init(drm, &hdmi->connector,
> +				   &dw_hdmi_atomic_connector_funcs,
> +				   DRM_MODE_CONNECTOR_HDMIA);
> +	else
> +		drm_connector_init(drm, &hdmi->connector,
> +				   &dw_hdmi_connector_funcs,
> +				   DRM_MODE_CONNECTOR_HDMIA);
>   
>   	hdmi->connector.encoder = encoder;
>   


-- 
Mark Yao


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

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

* [PATCH v3 7/8] drm: bridge/dw_hdmi: add atomic API support
@ 2015-12-17  3:15       ` Mark yao
  0 siblings, 0 replies; 51+ messages in thread
From: Mark yao @ 2015-12-17  3:15 UTC (permalink / raw)
  To: linux-arm-kernel

Sorry, Ops, fat finger, discard this lost thread mail.

On 2015?12?17? 11:08, Mark Yao wrote:
> Fill atomic needed funcs with default atomic helper library.
>
> Rockchip use dw_hdmi, and drm/rockchip will covert to atomic api,
> we need dw_hdmi support atomic funcs.
>
> Now another drm driver use dw_hdmi is imx, not yet atomic, so
> check DRIVER_ATOMIC at runtime to spilt atomic and not atomic.
>
> Cc: Russell King <rmk+kernel@arm.linux.org.uk>
> Cc: Philipp Zabel <p.zabel@pengutronix.de>
> Cc: Andy Yan <andy.yan@rock-chips.com>
> Cc: Fabio Estevam <fabio.estevam@freescale.com>
> Cc: Thierry Reding <treding@nvidia.com>
>
> Signed-off-by: Mark Yao <mark.yao@rock-chips.com>
> ---
> Changes in v3: None
> Changes in v2:
> Adviced by Daniel Vetter
> - check DRIVER_ATOMIC at runtime to spilt atomic and not atomic.
>
>   drivers/gpu/drm/bridge/dw_hdmi.c |   23 +++++++++++++++++++++--
>   1 file changed, 21 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/bridge/dw_hdmi.c b/drivers/gpu/drm/bridge/dw_hdmi.c
> index 56de9f1..dc0bdd4 100644
> --- a/drivers/gpu/drm/bridge/dw_hdmi.c
> +++ b/drivers/gpu/drm/bridge/dw_hdmi.c
> @@ -22,6 +22,7 @@
>   
>   #include <drm/drm_of.h>
>   #include <drm/drmP.h>
> +#include <drm/drm_atomic_helper.h>
>   #include <drm/drm_crtc_helper.h>
>   #include <drm/drm_edid.h>
>   #include <drm/drm_encoder_slave.h>
> @@ -1522,6 +1523,17 @@ static struct drm_connector_funcs dw_hdmi_connector_funcs = {
>   	.force = dw_hdmi_connector_force,
>   };
>   
> +static struct drm_connector_funcs dw_hdmi_atomic_connector_funcs = {
> +	.dpms = drm_atomic_helper_connector_dpms,
> +	.fill_modes = drm_helper_probe_single_connector_modes,
> +	.detect = dw_hdmi_connector_detect,
> +	.destroy = dw_hdmi_connector_destroy,
> +	.force = dw_hdmi_connector_force,
> +	.reset = drm_atomic_helper_connector_reset,
> +	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
> +	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
> +};
> +
>   static struct drm_connector_helper_funcs dw_hdmi_connector_helper_funcs = {
>   	.get_modes = dw_hdmi_connector_get_modes,
>   	.mode_valid = dw_hdmi_connector_mode_valid,
> @@ -1645,8 +1657,15 @@ static int dw_hdmi_register(struct drm_device *drm, struct dw_hdmi *hdmi)
>   
>   	drm_connector_helper_add(&hdmi->connector,
>   				 &dw_hdmi_connector_helper_funcs);
> -	drm_connector_init(drm, &hdmi->connector, &dw_hdmi_connector_funcs,
> -			   DRM_MODE_CONNECTOR_HDMIA);
> +
> +	if (drm_core_check_feature(drm, DRIVER_ATOMIC))
> +		drm_connector_init(drm, &hdmi->connector,
> +				   &dw_hdmi_atomic_connector_funcs,
> +				   DRM_MODE_CONNECTOR_HDMIA);
> +	else
> +		drm_connector_init(drm, &hdmi->connector,
> +				   &dw_hdmi_connector_funcs,
> +				   DRM_MODE_CONNECTOR_HDMIA);
>   
>   	hdmi->connector.encoder = encoder;
>   


-- 
?ark Yao

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

* Re: [PATCH 8/8] drm/rockchip: dw_hdmi: use encoder enable function
  2015-12-17  3:08     ` Mark Yao
  (?)
@ 2015-12-17  3:16       ` Mark yao
  -1 siblings, 0 replies; 51+ messages in thread
From: Mark yao @ 2015-12-17  3:16 UTC (permalink / raw)
  To: David Airlie, Heiko Stuebner, dri-devel, linux-arm-kernel,
	linux-rockchip, linux-kernel

Sorry, Ops, fat finger, discard this lost thread mail.

On 2015年12月17日 11:08, Mark Yao wrote:
> encoder.enable is more compatible to atomic api than encoder.prepare/commit
>
> Signed-off-by: Mark Yao <mark.yao@rock-chips.com>
> ---
> Changes in v3: None
> Changes in v2: None
>
>   drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c |   14 +++++---------
>   1 file changed, 5 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
> index 525b5a8..8e1605c 100644
> --- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
> +++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
> @@ -195,12 +195,15 @@ static void dw_hdmi_rockchip_encoder_mode_set(struct drm_encoder *encoder,
>   {
>   }
>   
> -static void dw_hdmi_rockchip_encoder_commit(struct drm_encoder *encoder)
> +static void dw_hdmi_rockchip_encoder_enable(struct drm_encoder *encoder)
>   {
>   	struct rockchip_hdmi *hdmi = to_rockchip_hdmi(encoder);
>   	u32 val;
>   	int mux;
>   
> +	rockchip_drm_crtc_mode_config(encoder->crtc, DRM_MODE_CONNECTOR_HDMIA,
> +				      ROCKCHIP_OUT_MODE_AAAA);
> +
>   	mux = rockchip_drm_encoder_get_mux_id(hdmi->dev->of_node, encoder);
>   	if (mux)
>   		val = HDMI_SEL_VOP_LIT | (HDMI_SEL_VOP_LIT << 16);
> @@ -212,17 +215,10 @@ static void dw_hdmi_rockchip_encoder_commit(struct drm_encoder *encoder)
>   		(mux) ? "LIT" : "BIG");
>   }
>   
> -static void dw_hdmi_rockchip_encoder_prepare(struct drm_encoder *encoder)
> -{
> -	rockchip_drm_crtc_mode_config(encoder->crtc, DRM_MODE_CONNECTOR_HDMIA,
> -				      ROCKCHIP_OUT_MODE_AAAA);
> -}
> -
>   static struct drm_encoder_helper_funcs dw_hdmi_rockchip_encoder_helper_funcs = {
>   	.mode_fixup = dw_hdmi_rockchip_encoder_mode_fixup,
>   	.mode_set   = dw_hdmi_rockchip_encoder_mode_set,
> -	.prepare    = dw_hdmi_rockchip_encoder_prepare,
> -	.commit     = dw_hdmi_rockchip_encoder_commit,
> +	.enable     = dw_hdmi_rockchip_encoder_enable,
>   	.disable    = dw_hdmi_rockchip_encoder_disable,
>   };
>   


-- 
Mark Yao



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

* Re: [PATCH 8/8] drm/rockchip: dw_hdmi: use encoder enable function
@ 2015-12-17  3:16       ` Mark yao
  0 siblings, 0 replies; 51+ messages in thread
From: Mark yao @ 2015-12-17  3:16 UTC (permalink / raw)
  To: David Airlie, Heiko Stuebner, dri-devel, linux-arm-kernel,
	linux-rockchip, linux-kernel

Sorry, Ops, fat finger, discard this lost thread mail.

On 2015年12月17日 11:08, Mark Yao wrote:
> encoder.enable is more compatible to atomic api than encoder.prepare/commit
>
> Signed-off-by: Mark Yao <mark.yao@rock-chips.com>
> ---
> Changes in v3: None
> Changes in v2: None
>
>   drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c |   14 +++++---------
>   1 file changed, 5 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
> index 525b5a8..8e1605c 100644
> --- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
> +++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
> @@ -195,12 +195,15 @@ static void dw_hdmi_rockchip_encoder_mode_set(struct drm_encoder *encoder,
>   {
>   }
>   
> -static void dw_hdmi_rockchip_encoder_commit(struct drm_encoder *encoder)
> +static void dw_hdmi_rockchip_encoder_enable(struct drm_encoder *encoder)
>   {
>   	struct rockchip_hdmi *hdmi = to_rockchip_hdmi(encoder);
>   	u32 val;
>   	int mux;
>   
> +	rockchip_drm_crtc_mode_config(encoder->crtc, DRM_MODE_CONNECTOR_HDMIA,
> +				      ROCKCHIP_OUT_MODE_AAAA);
> +
>   	mux = rockchip_drm_encoder_get_mux_id(hdmi->dev->of_node, encoder);
>   	if (mux)
>   		val = HDMI_SEL_VOP_LIT | (HDMI_SEL_VOP_LIT << 16);
> @@ -212,17 +215,10 @@ static void dw_hdmi_rockchip_encoder_commit(struct drm_encoder *encoder)
>   		(mux) ? "LIT" : "BIG");
>   }
>   
> -static void dw_hdmi_rockchip_encoder_prepare(struct drm_encoder *encoder)
> -{
> -	rockchip_drm_crtc_mode_config(encoder->crtc, DRM_MODE_CONNECTOR_HDMIA,
> -				      ROCKCHIP_OUT_MODE_AAAA);
> -}
> -
>   static struct drm_encoder_helper_funcs dw_hdmi_rockchip_encoder_helper_funcs = {
>   	.mode_fixup = dw_hdmi_rockchip_encoder_mode_fixup,
>   	.mode_set   = dw_hdmi_rockchip_encoder_mode_set,
> -	.prepare    = dw_hdmi_rockchip_encoder_prepare,
> -	.commit     = dw_hdmi_rockchip_encoder_commit,
> +	.enable     = dw_hdmi_rockchip_encoder_enable,
>   	.disable    = dw_hdmi_rockchip_encoder_disable,
>   };
>   


-- 
Mark Yao


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

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

* [PATCH 8/8] drm/rockchip: dw_hdmi: use encoder enable function
@ 2015-12-17  3:16       ` Mark yao
  0 siblings, 0 replies; 51+ messages in thread
From: Mark yao @ 2015-12-17  3:16 UTC (permalink / raw)
  To: linux-arm-kernel

Sorry, Ops, fat finger, discard this lost thread mail.

On 2015?12?17? 11:08, Mark Yao wrote:
> encoder.enable is more compatible to atomic api than encoder.prepare/commit
>
> Signed-off-by: Mark Yao <mark.yao@rock-chips.com>
> ---
> Changes in v3: None
> Changes in v2: None
>
>   drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c |   14 +++++---------
>   1 file changed, 5 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
> index 525b5a8..8e1605c 100644
> --- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
> +++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
> @@ -195,12 +195,15 @@ static void dw_hdmi_rockchip_encoder_mode_set(struct drm_encoder *encoder,
>   {
>   }
>   
> -static void dw_hdmi_rockchip_encoder_commit(struct drm_encoder *encoder)
> +static void dw_hdmi_rockchip_encoder_enable(struct drm_encoder *encoder)
>   {
>   	struct rockchip_hdmi *hdmi = to_rockchip_hdmi(encoder);
>   	u32 val;
>   	int mux;
>   
> +	rockchip_drm_crtc_mode_config(encoder->crtc, DRM_MODE_CONNECTOR_HDMIA,
> +				      ROCKCHIP_OUT_MODE_AAAA);
> +
>   	mux = rockchip_drm_encoder_get_mux_id(hdmi->dev->of_node, encoder);
>   	if (mux)
>   		val = HDMI_SEL_VOP_LIT | (HDMI_SEL_VOP_LIT << 16);
> @@ -212,17 +215,10 @@ static void dw_hdmi_rockchip_encoder_commit(struct drm_encoder *encoder)
>   		(mux) ? "LIT" : "BIG");
>   }
>   
> -static void dw_hdmi_rockchip_encoder_prepare(struct drm_encoder *encoder)
> -{
> -	rockchip_drm_crtc_mode_config(encoder->crtc, DRM_MODE_CONNECTOR_HDMIA,
> -				      ROCKCHIP_OUT_MODE_AAAA);
> -}
> -
>   static struct drm_encoder_helper_funcs dw_hdmi_rockchip_encoder_helper_funcs = {
>   	.mode_fixup = dw_hdmi_rockchip_encoder_mode_fixup,
>   	.mode_set   = dw_hdmi_rockchip_encoder_mode_set,
> -	.prepare    = dw_hdmi_rockchip_encoder_prepare,
> -	.commit     = dw_hdmi_rockchip_encoder_commit,
> +	.enable     = dw_hdmi_rockchip_encoder_enable,
>   	.disable    = dw_hdmi_rockchip_encoder_disable,
>   };
>   


-- 
?ark Yao

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

* Re: [PATCH v3 0/8] drm/rockchip: covert to support atomic API
  2015-12-17  3:01 ` Mark Yao
  (?)
@ 2015-12-17 10:00   ` Heiko Stübner
  -1 siblings, 0 replies; 51+ messages in thread
From: Heiko Stübner @ 2015-12-17 10:00 UTC (permalink / raw)
  To: Mark Yao
  Cc: David Airlie, dri-devel, linux-arm-kernel, linux-rockchip, linux-kernel

Hi Mark,

Am Donnerstag, 17. Dezember 2015, 11:01:07 schrieb Mark Yao:
> The series of patches coverting drm rockchip to atomic API, do some
> cleanup and some fixes on atomic side.
> 
> TODO: fence is not support on current version.
> 
> Tested on rk3288 popmetal board.

In general this works nicely and hdmi is still working on my firefly, so

Tested-by: Heiko Stuebner <heiko@sntech.de>


I get one warning though, which seems to be related to fbcon grabbing
the framebuffer it seems.


HDMI plugged in on boot:

[    4.345329] ------------[ cut here ]------------
[    4.345360] WARNING: CPU: 1 PID: 66 at drivers/gpu/drm/drm_atomic_helper.c:682 drm_atomic_helper_update_legacy_modeset_state+0x6c/0x200()
[    4.345373] Modules linked in:
[    4.345386] CPU: 1 PID: 66 Comm: kworker/u8:1 Not tainted 4.4.0-rc5+ #2787
[    4.345392] Hardware name: Rockchip (Device Tree)
[    4.345411] Workqueue: deferwq deferred_probe_work_func
[    4.345438] [<c0019914>] (unwind_backtrace) from [<c0014bcc>] (show_stack+0x20/0x24)
[    4.345458] [<c0014bcc>] (show_stack) from [<c02c4344>] (dump_stack+0x84/0xb8)
[    4.345479] [<c02c4344>] (dump_stack) from [<c0029a20>] (warn_slowpath_common+0x98/0xc4)
[    4.345496] [<c0029a20>] (warn_slowpath_common) from [<c0029b08>] (warn_slowpath_null+0x2c/0x34)
[    4.345514] [<c0029b08>] (warn_slowpath_null) from [<c0361144>] (drm_atomic_helper_update_legacy_modeset_state+0x6c/0x200)
[    4.345534] [<c0361144>] (drm_atomic_helper_update_legacy_modeset_state) from [<c0361684>] (drm_atomic_helper_commit_modeset_disables+0x1e4/0x35c)
[    4.345557] [<c0361684>] (drm_atomic_helper_commit_modeset_disables) from [<c038782c>] (rockchip_atomic_commit_complete+0x34/0x108)
[    4.345576] [<c038782c>] (rockchip_atomic_commit_complete) from [<c0387984>] (rockchip_drm_atomic_commit+0x84/0xa0)
[    4.345594] [<c0387984>] (rockchip_drm_atomic_commit) from [<c0384c58>] (drm_atomic_commit+0x60/0x70)
[    4.345609] [<c0384c58>] (drm_atomic_commit) from [<c0363ab0>] (restore_fbdev_mode+0x128/0x258)
[    4.345625] [<c0363ab0>] (restore_fbdev_mode) from [<c0365208>] (drm_fb_helper_restore_fbdev_mode_unlocked+0x3c/0x80)
[    4.345640] [<c0365208>] (drm_fb_helper_restore_fbdev_mode_unlocked) from [<c036529c>] (drm_fb_helper_set_par+0x50/0x60)
[    4.345659] [<c036529c>] (drm_fb_helper_set_par) from [<c03052cc>] (fbcon_init+0x328/0x458)
[    4.345676] [<c03052cc>] (fbcon_init) from [<c033a66c>] (visual_init+0xc4/0x114)
[    4.345692] [<c033a66c>] (visual_init) from [<c033c098>] (do_bind_con_driver+0x1fc/0x330)
[    4.345707] [<c033c098>] (do_bind_con_driver) from [<c033c540>] (do_take_over_console+0x174/0x1b4)
[    4.345722] [<c033c540>] (do_take_over_console) from [<c0305464>] (do_fbcon_takeover+0x68/0xd0)
[    4.345738] [<c0305464>] (do_fbcon_takeover) from [<c0305c6c>] (fbcon_event_notify+0x3fc/0x7d8)
[    4.345756] [<c0305c6c>] (fbcon_event_notify) from [<c004d144>] (notifier_call_chain+0x58/0x80)
[    4.345771] [<c004d144>] (notifier_call_chain) from [<c004d4d4>] (__blocking_notifier_call_chain+0x54/0x6c)
[    4.345785] [<c004d4d4>] (__blocking_notifier_call_chain) from [<c004d514>] (blocking_notifier_call_chain+0x28/0x30)
[    4.345804] [<c004d514>] (blocking_notifier_call_chain) from [<c0308c68>] (fb_notifier_call_chain+0x24/0x2c)
[    4.345822] [<c0308c68>] (fb_notifier_call_chain) from [<c030aa7c>] (register_framebuffer+0x214/0x264)
[    4.345839] [<c030aa7c>] (register_framebuffer) from [<c0365a00>] (drm_fb_helper_initial_config+0x2dc/0x34c)
[    4.345856] [<c0365a00>] (drm_fb_helper_initial_config) from [<c038823c>] (rockchip_drm_fbdev_init+0x9c/0xe4)
[    4.345873] [<c038823c>] (rockchip_drm_fbdev_init) from [<c03876bc>] (rockchip_drm_load+0x25c/0x2b0)
[    4.345892] [<c03876bc>] (rockchip_drm_load) from [<c036eae4>] (drm_dev_register+0x80/0xc4)
[    4.345910] [<c036eae4>] (drm_dev_register) from [<c03873d4>] (rockchip_drm_bind+0x58/0x84)
[    4.345932] [<c03873d4>] (rockchip_drm_bind) from [<c03b4b54>] (try_to_bring_up_master.part.0+0xbc/0x114)
[    4.345950] [<c03b4b54>] (try_to_bring_up_master.part.0) from [<c03b4da0>] (component_add+0xb0/0x118)
[    4.345967] [<c03b4da0>] (component_add) from [<c038a2d8>] (vop_probe+0x40/0x4c)
[    4.345984] [<c038a2d8>] (vop_probe) from [<c03bc350>] (platform_drv_probe+0x60/0xb0)
[    4.345999] [<c03bc350>] (platform_drv_probe) from [<c03b9ffc>] (driver_probe_device+0x1a0/0x418)
[    4.346014] [<c03b9ffc>] (driver_probe_device) from [<c03ba3f8>] (__device_attach_driver+0x94/0xa0)
[    4.346028] [<c03ba3f8>] (__device_attach_driver) from [<c03b82a0>] (bus_for_each_drv+0x94/0xa4)
[    4.346042] [<c03b82a0>] (bus_for_each_drv) from [<c03b9d3c>] (__device_attach+0xa4/0x144)
[    4.346055] [<c03b9d3c>] (__device_attach) from [<c03ba564>] (device_initial_probe+0x1c/0x20)
[    4.346068] [<c03ba564>] (device_initial_probe) from [<c03b91d4>] (bus_probe_device+0x38/0x94)
[    4.346082] [<c03b91d4>] (bus_probe_device) from [<c03b9714>] (deferred_probe_work_func+0x8c/0xbc)
[    4.346098] [<c03b9714>] (deferred_probe_work_func) from [<c0045094>] (process_one_work+0x328/0x668)
[    4.346112] [<c0045094>] (process_one_work) from [<c0046304>] (worker_thread+0x2cc/0x41c)
[    4.346128] [<c0046304>] (worker_thread) from [<c004bbb8>] (kthread+0xf4/0x10c)
[    4.346146] [<c004bbb8>] (kthread) from [<c0010010>] (ret_from_fork+0x14/0x24)
[    4.346155] ---[ end trace 8cd78a9f6ee0a57e ]---


Plugging in HDMI after boot:

[   20.559534] ------------[ cut here ]------------
[   20.564412] WARNING: CPU: 3 PID: 74 at drivers/gpu/drm/drm_atomic_helper.c:682 drm_atomic_helper_update_legacy_modeset_state+0x6c/0x200()
[   20.576991] Modules linked in:
[   20.580175] CPU: 3 PID: 74 Comm: irq/51-ff980000 Not tainted 4.4.0-rc5+ #2787
[   20.587502] Hardware name: Rockchip (Device Tree)
[   20.592347] [<c0019914>] (unwind_backtrace) from [<c0014bcc>] (show_stack+0x20/0x24)
[   20.600319] [<c0014bcc>] (show_stack) from [<c02c4344>] (dump_stack+0x84/0xb8)
[   20.607776] [<c02c4344>] (dump_stack) from [<c0029a20>] (warn_slowpath_common+0x98/0xc4)
[   20.616087] [<c0029a20>] (warn_slowpath_common) from [<c0029b08>] (warn_slowpath_null+0x2c/0x34)
[   20.625106] [<c0029b08>] (warn_slowpath_null) from [<c0361144>] (drm_atomic_helper_update_legacy_modeset_state+0x6c/0x200)
[   20.636382] [<c0361144>] (drm_atomic_helper_update_legacy_modeset_state) from [<c0361684>] (drm_atomic_helper_commit_modeset_disables+0x1e4/0x35c)
[   20.649732] [<c0361684>] (drm_atomic_helper_commit_modeset_disables) from [<c038782c>] (rockchip_atomic_commit_complete+0x34/0x108)
[   20.661789] [<c038782c>] (rockchip_atomic_commit_complete) from [<c0387984>] (rockchip_drm_atomic_commit+0x84/0xa0)
[   20.672442] [<c0387984>] (rockchip_drm_atomic_commit) from [<c0384c58>] (drm_atomic_commit+0x60/0x70)
[   20.681711] [<c0384c58>] (drm_atomic_commit) from [<c0363ab0>] (restore_fbdev_mode+0x128/0x258)
[   20.690418] [<c0363ab0>] (restore_fbdev_mode) from [<c0365208>] (drm_fb_helper_restore_fbdev_mode_unlocked+0x3c/0x80)
[   20.701033] [<c0365208>] (drm_fb_helper_restore_fbdev_mode_unlocked) from [<c036529c>] (drm_fb_helper_set_par+0x50/0x60)
[   20.711907] [<c036529c>] (drm_fb_helper_set_par) from [<c03651b4>] (drm_fb_helper_hotplug_event+0xc8/0xe0)
[   20.721569] [<c03651b4>] (drm_fb_helper_hotplug_event) from [<c0387bd0>] (rockchip_drm_output_poll_changed+0x24/0x28)
[   20.732185] [<c0387bd0>] (rockchip_drm_output_poll_changed) from [<c035aaf8>] (drm_kms_helper_hotplug_event+0x34/0x38)
[   20.742891] [<c035aaf8>] (drm_kms_helper_hotplug_event) from [<c035b434>] (drm_helper_hpd_irq_event+0x120/0x150)
[   20.753078] [<c035b434>] (drm_helper_hpd_irq_event) from [<c038dd1c>] (dw_hdmi_irq+0x14c/0x18c)
[   20.761772] [<c038dd1c>] (dw_hdmi_irq) from [<c008d030>] (irq_thread_fn+0x2c/0x44)
[   20.769350] [<c008d030>] (irq_thread_fn) from [<c008d33c>] (irq_thread+0x118/0x21c)
[   20.777019] [<c008d33c>] (irq_thread) from [<c004bbb8>] (kthread+0xf4/0x10c)
[   20.784083] [<c004bbb8>] (kthread) from [<c0010010>] (ret_from_fork+0x14/0x24)
[   20.791300] ---[ end trace 3deaa51d288067a0 ]---


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

* Re: [PATCH v3 0/8] drm/rockchip: covert to support atomic API
@ 2015-12-17 10:00   ` Heiko Stübner
  0 siblings, 0 replies; 51+ messages in thread
From: Heiko Stübner @ 2015-12-17 10:00 UTC (permalink / raw)
  To: Mark Yao; +Cc: linux-rockchip, linux-arm-kernel, dri-devel, linux-kernel

Hi Mark,

Am Donnerstag, 17. Dezember 2015, 11:01:07 schrieb Mark Yao:
> The series of patches coverting drm rockchip to atomic API, do some
> cleanup and some fixes on atomic side.
> 
> TODO: fence is not support on current version.
> 
> Tested on rk3288 popmetal board.

In general this works nicely and hdmi is still working on my firefly, so

Tested-by: Heiko Stuebner <heiko@sntech.de>


I get one warning though, which seems to be related to fbcon grabbing
the framebuffer it seems.


HDMI plugged in on boot:

[    4.345329] ------------[ cut here ]------------
[    4.345360] WARNING: CPU: 1 PID: 66 at drivers/gpu/drm/drm_atomic_helper.c:682 drm_atomic_helper_update_legacy_modeset_state+0x6c/0x200()
[    4.345373] Modules linked in:
[    4.345386] CPU: 1 PID: 66 Comm: kworker/u8:1 Not tainted 4.4.0-rc5+ #2787
[    4.345392] Hardware name: Rockchip (Device Tree)
[    4.345411] Workqueue: deferwq deferred_probe_work_func
[    4.345438] [<c0019914>] (unwind_backtrace) from [<c0014bcc>] (show_stack+0x20/0x24)
[    4.345458] [<c0014bcc>] (show_stack) from [<c02c4344>] (dump_stack+0x84/0xb8)
[    4.345479] [<c02c4344>] (dump_stack) from [<c0029a20>] (warn_slowpath_common+0x98/0xc4)
[    4.345496] [<c0029a20>] (warn_slowpath_common) from [<c0029b08>] (warn_slowpath_null+0x2c/0x34)
[    4.345514] [<c0029b08>] (warn_slowpath_null) from [<c0361144>] (drm_atomic_helper_update_legacy_modeset_state+0x6c/0x200)
[    4.345534] [<c0361144>] (drm_atomic_helper_update_legacy_modeset_state) from [<c0361684>] (drm_atomic_helper_commit_modeset_disables+0x1e4/0x35c)
[    4.345557] [<c0361684>] (drm_atomic_helper_commit_modeset_disables) from [<c038782c>] (rockchip_atomic_commit_complete+0x34/0x108)
[    4.345576] [<c038782c>] (rockchip_atomic_commit_complete) from [<c0387984>] (rockchip_drm_atomic_commit+0x84/0xa0)
[    4.345594] [<c0387984>] (rockchip_drm_atomic_commit) from [<c0384c58>] (drm_atomic_commit+0x60/0x70)
[    4.345609] [<c0384c58>] (drm_atomic_commit) from [<c0363ab0>] (restore_fbdev_mode+0x128/0x258)
[    4.345625] [<c0363ab0>] (restore_fbdev_mode) from [<c0365208>] (drm_fb_helper_restore_fbdev_mode_unlocked+0x3c/0x80)
[    4.345640] [<c0365208>] (drm_fb_helper_restore_fbdev_mode_unlocked) from [<c036529c>] (drm_fb_helper_set_par+0x50/0x60)
[    4.345659] [<c036529c>] (drm_fb_helper_set_par) from [<c03052cc>] (fbcon_init+0x328/0x458)
[    4.345676] [<c03052cc>] (fbcon_init) from [<c033a66c>] (visual_init+0xc4/0x114)
[    4.345692] [<c033a66c>] (visual_init) from [<c033c098>] (do_bind_con_driver+0x1fc/0x330)
[    4.345707] [<c033c098>] (do_bind_con_driver) from [<c033c540>] (do_take_over_console+0x174/0x1b4)
[    4.345722] [<c033c540>] (do_take_over_console) from [<c0305464>] (do_fbcon_takeover+0x68/0xd0)
[    4.345738] [<c0305464>] (do_fbcon_takeover) from [<c0305c6c>] (fbcon_event_notify+0x3fc/0x7d8)
[    4.345756] [<c0305c6c>] (fbcon_event_notify) from [<c004d144>] (notifier_call_chain+0x58/0x80)
[    4.345771] [<c004d144>] (notifier_call_chain) from [<c004d4d4>] (__blocking_notifier_call_chain+0x54/0x6c)
[    4.345785] [<c004d4d4>] (__blocking_notifier_call_chain) from [<c004d514>] (blocking_notifier_call_chain+0x28/0x30)
[    4.345804] [<c004d514>] (blocking_notifier_call_chain) from [<c0308c68>] (fb_notifier_call_chain+0x24/0x2c)
[    4.345822] [<c0308c68>] (fb_notifier_call_chain) from [<c030aa7c>] (register_framebuffer+0x214/0x264)
[    4.345839] [<c030aa7c>] (register_framebuffer) from [<c0365a00>] (drm_fb_helper_initial_config+0x2dc/0x34c)
[    4.345856] [<c0365a00>] (drm_fb_helper_initial_config) from [<c038823c>] (rockchip_drm_fbdev_init+0x9c/0xe4)
[    4.345873] [<c038823c>] (rockchip_drm_fbdev_init) from [<c03876bc>] (rockchip_drm_load+0x25c/0x2b0)
[    4.345892] [<c03876bc>] (rockchip_drm_load) from [<c036eae4>] (drm_dev_register+0x80/0xc4)
[    4.345910] [<c036eae4>] (drm_dev_register) from [<c03873d4>] (rockchip_drm_bind+0x58/0x84)
[    4.345932] [<c03873d4>] (rockchip_drm_bind) from [<c03b4b54>] (try_to_bring_up_master.part.0+0xbc/0x114)
[    4.345950] [<c03b4b54>] (try_to_bring_up_master.part.0) from [<c03b4da0>] (component_add+0xb0/0x118)
[    4.345967] [<c03b4da0>] (component_add) from [<c038a2d8>] (vop_probe+0x40/0x4c)
[    4.345984] [<c038a2d8>] (vop_probe) from [<c03bc350>] (platform_drv_probe+0x60/0xb0)
[    4.345999] [<c03bc350>] (platform_drv_probe) from [<c03b9ffc>] (driver_probe_device+0x1a0/0x418)
[    4.346014] [<c03b9ffc>] (driver_probe_device) from [<c03ba3f8>] (__device_attach_driver+0x94/0xa0)
[    4.346028] [<c03ba3f8>] (__device_attach_driver) from [<c03b82a0>] (bus_for_each_drv+0x94/0xa4)
[    4.346042] [<c03b82a0>] (bus_for_each_drv) from [<c03b9d3c>] (__device_attach+0xa4/0x144)
[    4.346055] [<c03b9d3c>] (__device_attach) from [<c03ba564>] (device_initial_probe+0x1c/0x20)
[    4.346068] [<c03ba564>] (device_initial_probe) from [<c03b91d4>] (bus_probe_device+0x38/0x94)
[    4.346082] [<c03b91d4>] (bus_probe_device) from [<c03b9714>] (deferred_probe_work_func+0x8c/0xbc)
[    4.346098] [<c03b9714>] (deferred_probe_work_func) from [<c0045094>] (process_one_work+0x328/0x668)
[    4.346112] [<c0045094>] (process_one_work) from [<c0046304>] (worker_thread+0x2cc/0x41c)
[    4.346128] [<c0046304>] (worker_thread) from [<c004bbb8>] (kthread+0xf4/0x10c)
[    4.346146] [<c004bbb8>] (kthread) from [<c0010010>] (ret_from_fork+0x14/0x24)
[    4.346155] ---[ end trace 8cd78a9f6ee0a57e ]---


Plugging in HDMI after boot:

[   20.559534] ------------[ cut here ]------------
[   20.564412] WARNING: CPU: 3 PID: 74 at drivers/gpu/drm/drm_atomic_helper.c:682 drm_atomic_helper_update_legacy_modeset_state+0x6c/0x200()
[   20.576991] Modules linked in:
[   20.580175] CPU: 3 PID: 74 Comm: irq/51-ff980000 Not tainted 4.4.0-rc5+ #2787
[   20.587502] Hardware name: Rockchip (Device Tree)
[   20.592347] [<c0019914>] (unwind_backtrace) from [<c0014bcc>] (show_stack+0x20/0x24)
[   20.600319] [<c0014bcc>] (show_stack) from [<c02c4344>] (dump_stack+0x84/0xb8)
[   20.607776] [<c02c4344>] (dump_stack) from [<c0029a20>] (warn_slowpath_common+0x98/0xc4)
[   20.616087] [<c0029a20>] (warn_slowpath_common) from [<c0029b08>] (warn_slowpath_null+0x2c/0x34)
[   20.625106] [<c0029b08>] (warn_slowpath_null) from [<c0361144>] (drm_atomic_helper_update_legacy_modeset_state+0x6c/0x200)
[   20.636382] [<c0361144>] (drm_atomic_helper_update_legacy_modeset_state) from [<c0361684>] (drm_atomic_helper_commit_modeset_disables+0x1e4/0x35c)
[   20.649732] [<c0361684>] (drm_atomic_helper_commit_modeset_disables) from [<c038782c>] (rockchip_atomic_commit_complete+0x34/0x108)
[   20.661789] [<c038782c>] (rockchip_atomic_commit_complete) from [<c0387984>] (rockchip_drm_atomic_commit+0x84/0xa0)
[   20.672442] [<c0387984>] (rockchip_drm_atomic_commit) from [<c0384c58>] (drm_atomic_commit+0x60/0x70)
[   20.681711] [<c0384c58>] (drm_atomic_commit) from [<c0363ab0>] (restore_fbdev_mode+0x128/0x258)
[   20.690418] [<c0363ab0>] (restore_fbdev_mode) from [<c0365208>] (drm_fb_helper_restore_fbdev_mode_unlocked+0x3c/0x80)
[   20.701033] [<c0365208>] (drm_fb_helper_restore_fbdev_mode_unlocked) from [<c036529c>] (drm_fb_helper_set_par+0x50/0x60)
[   20.711907] [<c036529c>] (drm_fb_helper_set_par) from [<c03651b4>] (drm_fb_helper_hotplug_event+0xc8/0xe0)
[   20.721569] [<c03651b4>] (drm_fb_helper_hotplug_event) from [<c0387bd0>] (rockchip_drm_output_poll_changed+0x24/0x28)
[   20.732185] [<c0387bd0>] (rockchip_drm_output_poll_changed) from [<c035aaf8>] (drm_kms_helper_hotplug_event+0x34/0x38)
[   20.742891] [<c035aaf8>] (drm_kms_helper_hotplug_event) from [<c035b434>] (drm_helper_hpd_irq_event+0x120/0x150)
[   20.753078] [<c035b434>] (drm_helper_hpd_irq_event) from [<c038dd1c>] (dw_hdmi_irq+0x14c/0x18c)
[   20.761772] [<c038dd1c>] (dw_hdmi_irq) from [<c008d030>] (irq_thread_fn+0x2c/0x44)
[   20.769350] [<c008d030>] (irq_thread_fn) from [<c008d33c>] (irq_thread+0x118/0x21c)
[   20.777019] [<c008d33c>] (irq_thread) from [<c004bbb8>] (kthread+0xf4/0x10c)
[   20.784083] [<c004bbb8>] (kthread) from [<c0010010>] (ret_from_fork+0x14/0x24)
[   20.791300] ---[ end trace 3deaa51d288067a0 ]---

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

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

* [PATCH v3 0/8] drm/rockchip: covert to support atomic API
@ 2015-12-17 10:00   ` Heiko Stübner
  0 siblings, 0 replies; 51+ messages in thread
From: Heiko Stübner @ 2015-12-17 10:00 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Mark,

Am Donnerstag, 17. Dezember 2015, 11:01:07 schrieb Mark Yao:
> The series of patches coverting drm rockchip to atomic API, do some
> cleanup and some fixes on atomic side.
> 
> TODO: fence is not support on current version.
> 
> Tested on rk3288 popmetal board.

In general this works nicely and hdmi is still working on my firefly, so

Tested-by: Heiko Stuebner <heiko@sntech.de>


I get one warning though, which seems to be related to fbcon grabbing
the framebuffer it seems.


HDMI plugged in on boot:

[    4.345329] ------------[ cut here ]------------
[    4.345360] WARNING: CPU: 1 PID: 66 at drivers/gpu/drm/drm_atomic_helper.c:682 drm_atomic_helper_update_legacy_modeset_state+0x6c/0x200()
[    4.345373] Modules linked in:
[    4.345386] CPU: 1 PID: 66 Comm: kworker/u8:1 Not tainted 4.4.0-rc5+ #2787
[    4.345392] Hardware name: Rockchip (Device Tree)
[    4.345411] Workqueue: deferwq deferred_probe_work_func
[    4.345438] [<c0019914>] (unwind_backtrace) from [<c0014bcc>] (show_stack+0x20/0x24)
[    4.345458] [<c0014bcc>] (show_stack) from [<c02c4344>] (dump_stack+0x84/0xb8)
[    4.345479] [<c02c4344>] (dump_stack) from [<c0029a20>] (warn_slowpath_common+0x98/0xc4)
[    4.345496] [<c0029a20>] (warn_slowpath_common) from [<c0029b08>] (warn_slowpath_null+0x2c/0x34)
[    4.345514] [<c0029b08>] (warn_slowpath_null) from [<c0361144>] (drm_atomic_helper_update_legacy_modeset_state+0x6c/0x200)
[    4.345534] [<c0361144>] (drm_atomic_helper_update_legacy_modeset_state) from [<c0361684>] (drm_atomic_helper_commit_modeset_disables+0x1e4/0x35c)
[    4.345557] [<c0361684>] (drm_atomic_helper_commit_modeset_disables) from [<c038782c>] (rockchip_atomic_commit_complete+0x34/0x108)
[    4.345576] [<c038782c>] (rockchip_atomic_commit_complete) from [<c0387984>] (rockchip_drm_atomic_commit+0x84/0xa0)
[    4.345594] [<c0387984>] (rockchip_drm_atomic_commit) from [<c0384c58>] (drm_atomic_commit+0x60/0x70)
[    4.345609] [<c0384c58>] (drm_atomic_commit) from [<c0363ab0>] (restore_fbdev_mode+0x128/0x258)
[    4.345625] [<c0363ab0>] (restore_fbdev_mode) from [<c0365208>] (drm_fb_helper_restore_fbdev_mode_unlocked+0x3c/0x80)
[    4.345640] [<c0365208>] (drm_fb_helper_restore_fbdev_mode_unlocked) from [<c036529c>] (drm_fb_helper_set_par+0x50/0x60)
[    4.345659] [<c036529c>] (drm_fb_helper_set_par) from [<c03052cc>] (fbcon_init+0x328/0x458)
[    4.345676] [<c03052cc>] (fbcon_init) from [<c033a66c>] (visual_init+0xc4/0x114)
[    4.345692] [<c033a66c>] (visual_init) from [<c033c098>] (do_bind_con_driver+0x1fc/0x330)
[    4.345707] [<c033c098>] (do_bind_con_driver) from [<c033c540>] (do_take_over_console+0x174/0x1b4)
[    4.345722] [<c033c540>] (do_take_over_console) from [<c0305464>] (do_fbcon_takeover+0x68/0xd0)
[    4.345738] [<c0305464>] (do_fbcon_takeover) from [<c0305c6c>] (fbcon_event_notify+0x3fc/0x7d8)
[    4.345756] [<c0305c6c>] (fbcon_event_notify) from [<c004d144>] (notifier_call_chain+0x58/0x80)
[    4.345771] [<c004d144>] (notifier_call_chain) from [<c004d4d4>] (__blocking_notifier_call_chain+0x54/0x6c)
[    4.345785] [<c004d4d4>] (__blocking_notifier_call_chain) from [<c004d514>] (blocking_notifier_call_chain+0x28/0x30)
[    4.345804] [<c004d514>] (blocking_notifier_call_chain) from [<c0308c68>] (fb_notifier_call_chain+0x24/0x2c)
[    4.345822] [<c0308c68>] (fb_notifier_call_chain) from [<c030aa7c>] (register_framebuffer+0x214/0x264)
[    4.345839] [<c030aa7c>] (register_framebuffer) from [<c0365a00>] (drm_fb_helper_initial_config+0x2dc/0x34c)
[    4.345856] [<c0365a00>] (drm_fb_helper_initial_config) from [<c038823c>] (rockchip_drm_fbdev_init+0x9c/0xe4)
[    4.345873] [<c038823c>] (rockchip_drm_fbdev_init) from [<c03876bc>] (rockchip_drm_load+0x25c/0x2b0)
[    4.345892] [<c03876bc>] (rockchip_drm_load) from [<c036eae4>] (drm_dev_register+0x80/0xc4)
[    4.345910] [<c036eae4>] (drm_dev_register) from [<c03873d4>] (rockchip_drm_bind+0x58/0x84)
[    4.345932] [<c03873d4>] (rockchip_drm_bind) from [<c03b4b54>] (try_to_bring_up_master.part.0+0xbc/0x114)
[    4.345950] [<c03b4b54>] (try_to_bring_up_master.part.0) from [<c03b4da0>] (component_add+0xb0/0x118)
[    4.345967] [<c03b4da0>] (component_add) from [<c038a2d8>] (vop_probe+0x40/0x4c)
[    4.345984] [<c038a2d8>] (vop_probe) from [<c03bc350>] (platform_drv_probe+0x60/0xb0)
[    4.345999] [<c03bc350>] (platform_drv_probe) from [<c03b9ffc>] (driver_probe_device+0x1a0/0x418)
[    4.346014] [<c03b9ffc>] (driver_probe_device) from [<c03ba3f8>] (__device_attach_driver+0x94/0xa0)
[    4.346028] [<c03ba3f8>] (__device_attach_driver) from [<c03b82a0>] (bus_for_each_drv+0x94/0xa4)
[    4.346042] [<c03b82a0>] (bus_for_each_drv) from [<c03b9d3c>] (__device_attach+0xa4/0x144)
[    4.346055] [<c03b9d3c>] (__device_attach) from [<c03ba564>] (device_initial_probe+0x1c/0x20)
[    4.346068] [<c03ba564>] (device_initial_probe) from [<c03b91d4>] (bus_probe_device+0x38/0x94)
[    4.346082] [<c03b91d4>] (bus_probe_device) from [<c03b9714>] (deferred_probe_work_func+0x8c/0xbc)
[    4.346098] [<c03b9714>] (deferred_probe_work_func) from [<c0045094>] (process_one_work+0x328/0x668)
[    4.346112] [<c0045094>] (process_one_work) from [<c0046304>] (worker_thread+0x2cc/0x41c)
[    4.346128] [<c0046304>] (worker_thread) from [<c004bbb8>] (kthread+0xf4/0x10c)
[    4.346146] [<c004bbb8>] (kthread) from [<c0010010>] (ret_from_fork+0x14/0x24)
[    4.346155] ---[ end trace 8cd78a9f6ee0a57e ]---


Plugging in HDMI after boot:

[   20.559534] ------------[ cut here ]------------
[   20.564412] WARNING: CPU: 3 PID: 74 at drivers/gpu/drm/drm_atomic_helper.c:682 drm_atomic_helper_update_legacy_modeset_state+0x6c/0x200()
[   20.576991] Modules linked in:
[   20.580175] CPU: 3 PID: 74 Comm: irq/51-ff980000 Not tainted 4.4.0-rc5+ #2787
[   20.587502] Hardware name: Rockchip (Device Tree)
[   20.592347] [<c0019914>] (unwind_backtrace) from [<c0014bcc>] (show_stack+0x20/0x24)
[   20.600319] [<c0014bcc>] (show_stack) from [<c02c4344>] (dump_stack+0x84/0xb8)
[   20.607776] [<c02c4344>] (dump_stack) from [<c0029a20>] (warn_slowpath_common+0x98/0xc4)
[   20.616087] [<c0029a20>] (warn_slowpath_common) from [<c0029b08>] (warn_slowpath_null+0x2c/0x34)
[   20.625106] [<c0029b08>] (warn_slowpath_null) from [<c0361144>] (drm_atomic_helper_update_legacy_modeset_state+0x6c/0x200)
[   20.636382] [<c0361144>] (drm_atomic_helper_update_legacy_modeset_state) from [<c0361684>] (drm_atomic_helper_commit_modeset_disables+0x1e4/0x35c)
[   20.649732] [<c0361684>] (drm_atomic_helper_commit_modeset_disables) from [<c038782c>] (rockchip_atomic_commit_complete+0x34/0x108)
[   20.661789] [<c038782c>] (rockchip_atomic_commit_complete) from [<c0387984>] (rockchip_drm_atomic_commit+0x84/0xa0)
[   20.672442] [<c0387984>] (rockchip_drm_atomic_commit) from [<c0384c58>] (drm_atomic_commit+0x60/0x70)
[   20.681711] [<c0384c58>] (drm_atomic_commit) from [<c0363ab0>] (restore_fbdev_mode+0x128/0x258)
[   20.690418] [<c0363ab0>] (restore_fbdev_mode) from [<c0365208>] (drm_fb_helper_restore_fbdev_mode_unlocked+0x3c/0x80)
[   20.701033] [<c0365208>] (drm_fb_helper_restore_fbdev_mode_unlocked) from [<c036529c>] (drm_fb_helper_set_par+0x50/0x60)
[   20.711907] [<c036529c>] (drm_fb_helper_set_par) from [<c03651b4>] (drm_fb_helper_hotplug_event+0xc8/0xe0)
[   20.721569] [<c03651b4>] (drm_fb_helper_hotplug_event) from [<c0387bd0>] (rockchip_drm_output_poll_changed+0x24/0x28)
[   20.732185] [<c0387bd0>] (rockchip_drm_output_poll_changed) from [<c035aaf8>] (drm_kms_helper_hotplug_event+0x34/0x38)
[   20.742891] [<c035aaf8>] (drm_kms_helper_hotplug_event) from [<c035b434>] (drm_helper_hpd_irq_event+0x120/0x150)
[   20.753078] [<c035b434>] (drm_helper_hpd_irq_event) from [<c038dd1c>] (dw_hdmi_irq+0x14c/0x18c)
[   20.761772] [<c038dd1c>] (dw_hdmi_irq) from [<c008d030>] (irq_thread_fn+0x2c/0x44)
[   20.769350] [<c008d030>] (irq_thread_fn) from [<c008d33c>] (irq_thread+0x118/0x21c)
[   20.777019] [<c008d33c>] (irq_thread) from [<c004bbb8>] (kthread+0xf4/0x10c)
[   20.784083] [<c004bbb8>] (kthread) from [<c0010010>] (ret_from_fork+0x14/0x24)
[   20.791300] ---[ end trace 3deaa51d288067a0 ]---

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

* Re: [PATCH v3 0/8] drm/rockchip: covert to support atomic API
  2015-12-17 10:00   ` Heiko Stübner
  (?)
@ 2015-12-17 10:32     ` Mark yao
  -1 siblings, 0 replies; 51+ messages in thread
From: Mark yao @ 2015-12-17 10:32 UTC (permalink / raw)
  To: Heiko Stübner
  Cc: David Airlie, dri-devel, linux-arm-kernel, linux-rockchip, linux-kernel

On 2015年12月17日 18:00, Heiko Stübner wrote:
> Hi Mark,
>
> Am Donnerstag, 17. Dezember 2015, 11:01:07 schrieb Mark Yao:
>> The series of patches coverting drm rockchip to atomic API, do some
>> cleanup and some fixes on atomic side.
>>
>> TODO: fence is not support on current version.
>>
>> Tested on rk3288 popmetal board.
> In general this works nicely and hdmi is still working on my firefly, so
>
> Tested-by: Heiko Stuebner <heiko@sntech.de>

Thanks.

>
> I get one warning though, which seems to be related to fbcon grabbing
> the framebuffer it seems.
>
>
> HDMI plugged in on boot:
>
> [    4.345329] ------------[ cut here ]------------
> [    4.345360] WARNING: CPU: 1 PID: 66 at drivers/gpu/drm/drm_atomic_helper.c:682 drm_atomic_helper_update_legacy_modeset_state+0x6c/0x200()
> [    4.345373] Modules linked in:
> [    4.345386] CPU: 1 PID: 66 Comm: kworker/u8:1 Not tainted 4.4.0-rc5+ #2787
> [    4.345392] Hardware name: Rockchip (Device Tree)
> [    4.345411] Workqueue: deferwq deferred_probe_work_func
> [    4.345438] [<c0019914>] (unwind_backtrace) from [<c0014bcc>] (show_stack+0x20/0x24)
> [    4.345458] [<c0014bcc>] (show_stack) from [<c02c4344>] (dump_stack+0x84/0xb8)
> [    4.345479] [<c02c4344>] (dump_stack) from [<c0029a20>] (warn_slowpath_common+0x98/0xc4)
> [    4.345496] [<c0029a20>] (warn_slowpath_common) from [<c0029b08>] (warn_slowpath_null+0x2c/0x34)
> [    4.345514] [<c0029b08>] (warn_slowpath_null) from [<c0361144>] (drm_atomic_helper_update_legacy_modeset_state+0x6c/0x200)
> [    4.345534] [<c0361144>] (drm_atomic_helper_update_legacy_modeset_state) from [<c0361684>] (drm_atomic_helper_commit_modeset_disables+0x1e4/0x35c)
> [    4.345557] [<c0361684>] (drm_atomic_helper_commit_modeset_disables) from [<c038782c>] (rockchip_atomic_commit_complete+0x34/0x108)
> [    4.345576] [<c038782c>] (rockchip_atomic_commit_complete) from [<c0387984>] (rockchip_drm_atomic_commit+0x84/0xa0)
> [    4.345594] [<c0387984>] (rockchip_drm_atomic_commit) from [<c0384c58>] (drm_atomic_commit+0x60/0x70)
> [    4.345609] [<c0384c58>] (drm_atomic_commit) from [<c0363ab0>] (restore_fbdev_mode+0x128/0x258)
> [    4.345625] [<c0363ab0>] (restore_fbdev_mode) from [<c0365208>] (drm_fb_helper_restore_fbdev_mode_unlocked+0x3c/0x80)
> [    4.345640] [<c0365208>] (drm_fb_helper_restore_fbdev_mode_unlocked) from [<c036529c>] (drm_fb_helper_set_par+0x50/0x60)
> [    4.345659] [<c036529c>] (drm_fb_helper_set_par) from [<c03052cc>] (fbcon_init+0x328/0x458)
> [    4.345676] [<c03052cc>] (fbcon_init) from [<c033a66c>] (visual_init+0xc4/0x114)
> [    4.345692] [<c033a66c>] (visual_init) from [<c033c098>] (do_bind_con_driver+0x1fc/0x330)
> [    4.345707] [<c033c098>] (do_bind_con_driver) from [<c033c540>] (do_take_over_console+0x174/0x1b4)
> [    4.345722] [<c033c540>] (do_take_over_console) from [<c0305464>] (do_fbcon_takeover+0x68/0xd0)
> [    4.345738] [<c0305464>] (do_fbcon_takeover) from [<c0305c6c>] (fbcon_event_notify+0x3fc/0x7d8)
> [    4.345756] [<c0305c6c>] (fbcon_event_notify) from [<c004d144>] (notifier_call_chain+0x58/0x80)
> [    4.345771] [<c004d144>] (notifier_call_chain) from [<c004d4d4>] (__blocking_notifier_call_chain+0x54/0x6c)
> [    4.345785] [<c004d4d4>] (__blocking_notifier_call_chain) from [<c004d514>] (blocking_notifier_call_chain+0x28/0x30)
> [    4.345804] [<c004d514>] (blocking_notifier_call_chain) from [<c0308c68>] (fb_notifier_call_chain+0x24/0x2c)
> [    4.345822] [<c0308c68>] (fb_notifier_call_chain) from [<c030aa7c>] (register_framebuffer+0x214/0x264)
> [    4.345839] [<c030aa7c>] (register_framebuffer) from [<c0365a00>] (drm_fb_helper_initial_config+0x2dc/0x34c)
> [    4.345856] [<c0365a00>] (drm_fb_helper_initial_config) from [<c038823c>] (rockchip_drm_fbdev_init+0x9c/0xe4)
> [    4.345873] [<c038823c>] (rockchip_drm_fbdev_init) from [<c03876bc>] (rockchip_drm_load+0x25c/0x2b0)
> [    4.345892] [<c03876bc>] (rockchip_drm_load) from [<c036eae4>] (drm_dev_register+0x80/0xc4)
> [    4.345910] [<c036eae4>] (drm_dev_register) from [<c03873d4>] (rockchip_drm_bind+0x58/0x84)
> [    4.345932] [<c03873d4>] (rockchip_drm_bind) from [<c03b4b54>] (try_to_bring_up_master.part.0+0xbc/0x114)
> [    4.345950] [<c03b4b54>] (try_to_bring_up_master.part.0) from [<c03b4da0>] (component_add+0xb0/0x118)
> [    4.345967] [<c03b4da0>] (component_add) from [<c038a2d8>] (vop_probe+0x40/0x4c)
> [    4.345984] [<c038a2d8>] (vop_probe) from [<c03bc350>] (platform_drv_probe+0x60/0xb0)
> [    4.345999] [<c03bc350>] (platform_drv_probe) from [<c03b9ffc>] (driver_probe_device+0x1a0/0x418)
> [    4.346014] [<c03b9ffc>] (driver_probe_device) from [<c03ba3f8>] (__device_attach_driver+0x94/0xa0)
> [    4.346028] [<c03ba3f8>] (__device_attach_driver) from [<c03b82a0>] (bus_for_each_drv+0x94/0xa4)
> [    4.346042] [<c03b82a0>] (bus_for_each_drv) from [<c03b9d3c>] (__device_attach+0xa4/0x144)
> [    4.346055] [<c03b9d3c>] (__device_attach) from [<c03ba564>] (device_initial_probe+0x1c/0x20)
> [    4.346068] [<c03ba564>] (device_initial_probe) from [<c03b91d4>] (bus_probe_device+0x38/0x94)
> [    4.346082] [<c03b91d4>] (bus_probe_device) from [<c03b9714>] (deferred_probe_work_func+0x8c/0xbc)
> [    4.346098] [<c03b9714>] (deferred_probe_work_func) from [<c0045094>] (process_one_work+0x328/0x668)
> [    4.346112] [<c0045094>] (process_one_work) from [<c0046304>] (worker_thread+0x2cc/0x41c)
> [    4.346128] [<c0046304>] (worker_thread) from [<c004bbb8>] (kthread+0xf4/0x10c)
> [    4.346146] [<c004bbb8>] (kthread) from [<c0010010>] (ret_from_fork+0x14/0x24)
> [    4.346155] ---[ end trace 8cd78a9f6ee0a57e ]---
>
>
> Plugging in HDMI after boot:
>
> [   20.559534] ------------[ cut here ]------------
> [   20.564412] WARNING: CPU: 3 PID: 74 at drivers/gpu/drm/drm_atomic_helper.c:682 drm_atomic_helper_update_legacy_modeset_state+0x6c/0x200()
> [   20.576991] Modules linked in:
> [   20.580175] CPU: 3 PID: 74 Comm: irq/51-ff980000 Not tainted 4.4.0-rc5+ #2787
> [   20.587502] Hardware name: Rockchip (Device Tree)
> [   20.592347] [<c0019914>] (unwind_backtrace) from [<c0014bcc>] (show_stack+0x20/0x24)
> [   20.600319] [<c0014bcc>] (show_stack) from [<c02c4344>] (dump_stack+0x84/0xb8)
> [   20.607776] [<c02c4344>] (dump_stack) from [<c0029a20>] (warn_slowpath_common+0x98/0xc4)
> [   20.616087] [<c0029a20>] (warn_slowpath_common) from [<c0029b08>] (warn_slowpath_null+0x2c/0x34)
> [   20.625106] [<c0029b08>] (warn_slowpath_null) from [<c0361144>] (drm_atomic_helper_update_legacy_modeset_state+0x6c/0x200)
> [   20.636382] [<c0361144>] (drm_atomic_helper_update_legacy_modeset_state) from [<c0361684>] (drm_atomic_helper_commit_modeset_disables+0x1e4/0x35c)
> [   20.649732] [<c0361684>] (drm_atomic_helper_commit_modeset_disables) from [<c038782c>] (rockchip_atomic_commit_complete+0x34/0x108)
> [   20.661789] [<c038782c>] (rockchip_atomic_commit_complete) from [<c0387984>] (rockchip_drm_atomic_commit+0x84/0xa0)
> [   20.672442] [<c0387984>] (rockchip_drm_atomic_commit) from [<c0384c58>] (drm_atomic_commit+0x60/0x70)
> [   20.681711] [<c0384c58>] (drm_atomic_commit) from [<c0363ab0>] (restore_fbdev_mode+0x128/0x258)
> [   20.690418] [<c0363ab0>] (restore_fbdev_mode) from [<c0365208>] (drm_fb_helper_restore_fbdev_mode_unlocked+0x3c/0x80)
> [   20.701033] [<c0365208>] (drm_fb_helper_restore_fbdev_mode_unlocked) from [<c036529c>] (drm_fb_helper_set_par+0x50/0x60)
> [   20.711907] [<c036529c>] (drm_fb_helper_set_par) from [<c03651b4>] (drm_fb_helper_hotplug_event+0xc8/0xe0)
> [   20.721569] [<c03651b4>] (drm_fb_helper_hotplug_event) from [<c0387bd0>] (rockchip_drm_output_poll_changed+0x24/0x28)
> [   20.732185] [<c0387bd0>] (rockchip_drm_output_poll_changed) from [<c035aaf8>] (drm_kms_helper_hotplug_event+0x34/0x38)
> [   20.742891] [<c035aaf8>] (drm_kms_helper_hotplug_event) from [<c035b434>] (drm_helper_hpd_irq_event+0x120/0x150)
> [   20.753078] [<c035b434>] (drm_helper_hpd_irq_event) from [<c038dd1c>] (dw_hdmi_irq+0x14c/0x18c)
> [   20.761772] [<c038dd1c>] (dw_hdmi_irq) from [<c008d030>] (irq_thread_fn+0x2c/0x44)
> [   20.769350] [<c008d030>] (irq_thread_fn) from [<c008d33c>] (irq_thread+0x118/0x21c)
> [   20.777019] [<c008d33c>] (irq_thread) from [<c004bbb8>] (kthread+0xf4/0x10c)
> [   20.784083] [<c004bbb8>] (kthread) from [<c0010010>] (ret_from_fork+0x14/0x24)
> [   20.791300] ---[ end trace 3deaa51d288067a0 ]---
>
>
>
>
Hi Heiko
     This issue can be explained from following thread:
        https://lkml.org/lkml/2015/11/16/498

     You can fix it by following changes:

@@ -1667,8 +1667,6 @@ static int dw_hdmi_register(struct drm_device 
*drm, struct dw_hdmi *hdmi)
                                    &dw_hdmi_connector_funcs,
                                    DRM_MODE_CONNECTOR_HDMIA);

     -       hdmi->connector.encoder = encoder;


Thanks.

-- 
Mark Yao



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

* Re: [PATCH v3 0/8] drm/rockchip: covert to support atomic API
@ 2015-12-17 10:32     ` Mark yao
  0 siblings, 0 replies; 51+ messages in thread
From: Mark yao @ 2015-12-17 10:32 UTC (permalink / raw)
  To: Heiko Stübner
  Cc: linux-rockchip, linux-arm-kernel, dri-devel, linux-kernel

On 2015年12月17日 18:00, Heiko Stübner wrote:
> Hi Mark,
>
> Am Donnerstag, 17. Dezember 2015, 11:01:07 schrieb Mark Yao:
>> The series of patches coverting drm rockchip to atomic API, do some
>> cleanup and some fixes on atomic side.
>>
>> TODO: fence is not support on current version.
>>
>> Tested on rk3288 popmetal board.
> In general this works nicely and hdmi is still working on my firefly, so
>
> Tested-by: Heiko Stuebner <heiko@sntech.de>

Thanks.

>
> I get one warning though, which seems to be related to fbcon grabbing
> the framebuffer it seems.
>
>
> HDMI plugged in on boot:
>
> [    4.345329] ------------[ cut here ]------------
> [    4.345360] WARNING: CPU: 1 PID: 66 at drivers/gpu/drm/drm_atomic_helper.c:682 drm_atomic_helper_update_legacy_modeset_state+0x6c/0x200()
> [    4.345373] Modules linked in:
> [    4.345386] CPU: 1 PID: 66 Comm: kworker/u8:1 Not tainted 4.4.0-rc5+ #2787
> [    4.345392] Hardware name: Rockchip (Device Tree)
> [    4.345411] Workqueue: deferwq deferred_probe_work_func
> [    4.345438] [<c0019914>] (unwind_backtrace) from [<c0014bcc>] (show_stack+0x20/0x24)
> [    4.345458] [<c0014bcc>] (show_stack) from [<c02c4344>] (dump_stack+0x84/0xb8)
> [    4.345479] [<c02c4344>] (dump_stack) from [<c0029a20>] (warn_slowpath_common+0x98/0xc4)
> [    4.345496] [<c0029a20>] (warn_slowpath_common) from [<c0029b08>] (warn_slowpath_null+0x2c/0x34)
> [    4.345514] [<c0029b08>] (warn_slowpath_null) from [<c0361144>] (drm_atomic_helper_update_legacy_modeset_state+0x6c/0x200)
> [    4.345534] [<c0361144>] (drm_atomic_helper_update_legacy_modeset_state) from [<c0361684>] (drm_atomic_helper_commit_modeset_disables+0x1e4/0x35c)
> [    4.345557] [<c0361684>] (drm_atomic_helper_commit_modeset_disables) from [<c038782c>] (rockchip_atomic_commit_complete+0x34/0x108)
> [    4.345576] [<c038782c>] (rockchip_atomic_commit_complete) from [<c0387984>] (rockchip_drm_atomic_commit+0x84/0xa0)
> [    4.345594] [<c0387984>] (rockchip_drm_atomic_commit) from [<c0384c58>] (drm_atomic_commit+0x60/0x70)
> [    4.345609] [<c0384c58>] (drm_atomic_commit) from [<c0363ab0>] (restore_fbdev_mode+0x128/0x258)
> [    4.345625] [<c0363ab0>] (restore_fbdev_mode) from [<c0365208>] (drm_fb_helper_restore_fbdev_mode_unlocked+0x3c/0x80)
> [    4.345640] [<c0365208>] (drm_fb_helper_restore_fbdev_mode_unlocked) from [<c036529c>] (drm_fb_helper_set_par+0x50/0x60)
> [    4.345659] [<c036529c>] (drm_fb_helper_set_par) from [<c03052cc>] (fbcon_init+0x328/0x458)
> [    4.345676] [<c03052cc>] (fbcon_init) from [<c033a66c>] (visual_init+0xc4/0x114)
> [    4.345692] [<c033a66c>] (visual_init) from [<c033c098>] (do_bind_con_driver+0x1fc/0x330)
> [    4.345707] [<c033c098>] (do_bind_con_driver) from [<c033c540>] (do_take_over_console+0x174/0x1b4)
> [    4.345722] [<c033c540>] (do_take_over_console) from [<c0305464>] (do_fbcon_takeover+0x68/0xd0)
> [    4.345738] [<c0305464>] (do_fbcon_takeover) from [<c0305c6c>] (fbcon_event_notify+0x3fc/0x7d8)
> [    4.345756] [<c0305c6c>] (fbcon_event_notify) from [<c004d144>] (notifier_call_chain+0x58/0x80)
> [    4.345771] [<c004d144>] (notifier_call_chain) from [<c004d4d4>] (__blocking_notifier_call_chain+0x54/0x6c)
> [    4.345785] [<c004d4d4>] (__blocking_notifier_call_chain) from [<c004d514>] (blocking_notifier_call_chain+0x28/0x30)
> [    4.345804] [<c004d514>] (blocking_notifier_call_chain) from [<c0308c68>] (fb_notifier_call_chain+0x24/0x2c)
> [    4.345822] [<c0308c68>] (fb_notifier_call_chain) from [<c030aa7c>] (register_framebuffer+0x214/0x264)
> [    4.345839] [<c030aa7c>] (register_framebuffer) from [<c0365a00>] (drm_fb_helper_initial_config+0x2dc/0x34c)
> [    4.345856] [<c0365a00>] (drm_fb_helper_initial_config) from [<c038823c>] (rockchip_drm_fbdev_init+0x9c/0xe4)
> [    4.345873] [<c038823c>] (rockchip_drm_fbdev_init) from [<c03876bc>] (rockchip_drm_load+0x25c/0x2b0)
> [    4.345892] [<c03876bc>] (rockchip_drm_load) from [<c036eae4>] (drm_dev_register+0x80/0xc4)
> [    4.345910] [<c036eae4>] (drm_dev_register) from [<c03873d4>] (rockchip_drm_bind+0x58/0x84)
> [    4.345932] [<c03873d4>] (rockchip_drm_bind) from [<c03b4b54>] (try_to_bring_up_master.part.0+0xbc/0x114)
> [    4.345950] [<c03b4b54>] (try_to_bring_up_master.part.0) from [<c03b4da0>] (component_add+0xb0/0x118)
> [    4.345967] [<c03b4da0>] (component_add) from [<c038a2d8>] (vop_probe+0x40/0x4c)
> [    4.345984] [<c038a2d8>] (vop_probe) from [<c03bc350>] (platform_drv_probe+0x60/0xb0)
> [    4.345999] [<c03bc350>] (platform_drv_probe) from [<c03b9ffc>] (driver_probe_device+0x1a0/0x418)
> [    4.346014] [<c03b9ffc>] (driver_probe_device) from [<c03ba3f8>] (__device_attach_driver+0x94/0xa0)
> [    4.346028] [<c03ba3f8>] (__device_attach_driver) from [<c03b82a0>] (bus_for_each_drv+0x94/0xa4)
> [    4.346042] [<c03b82a0>] (bus_for_each_drv) from [<c03b9d3c>] (__device_attach+0xa4/0x144)
> [    4.346055] [<c03b9d3c>] (__device_attach) from [<c03ba564>] (device_initial_probe+0x1c/0x20)
> [    4.346068] [<c03ba564>] (device_initial_probe) from [<c03b91d4>] (bus_probe_device+0x38/0x94)
> [    4.346082] [<c03b91d4>] (bus_probe_device) from [<c03b9714>] (deferred_probe_work_func+0x8c/0xbc)
> [    4.346098] [<c03b9714>] (deferred_probe_work_func) from [<c0045094>] (process_one_work+0x328/0x668)
> [    4.346112] [<c0045094>] (process_one_work) from [<c0046304>] (worker_thread+0x2cc/0x41c)
> [    4.346128] [<c0046304>] (worker_thread) from [<c004bbb8>] (kthread+0xf4/0x10c)
> [    4.346146] [<c004bbb8>] (kthread) from [<c0010010>] (ret_from_fork+0x14/0x24)
> [    4.346155] ---[ end trace 8cd78a9f6ee0a57e ]---
>
>
> Plugging in HDMI after boot:
>
> [   20.559534] ------------[ cut here ]------------
> [   20.564412] WARNING: CPU: 3 PID: 74 at drivers/gpu/drm/drm_atomic_helper.c:682 drm_atomic_helper_update_legacy_modeset_state+0x6c/0x200()
> [   20.576991] Modules linked in:
> [   20.580175] CPU: 3 PID: 74 Comm: irq/51-ff980000 Not tainted 4.4.0-rc5+ #2787
> [   20.587502] Hardware name: Rockchip (Device Tree)
> [   20.592347] [<c0019914>] (unwind_backtrace) from [<c0014bcc>] (show_stack+0x20/0x24)
> [   20.600319] [<c0014bcc>] (show_stack) from [<c02c4344>] (dump_stack+0x84/0xb8)
> [   20.607776] [<c02c4344>] (dump_stack) from [<c0029a20>] (warn_slowpath_common+0x98/0xc4)
> [   20.616087] [<c0029a20>] (warn_slowpath_common) from [<c0029b08>] (warn_slowpath_null+0x2c/0x34)
> [   20.625106] [<c0029b08>] (warn_slowpath_null) from [<c0361144>] (drm_atomic_helper_update_legacy_modeset_state+0x6c/0x200)
> [   20.636382] [<c0361144>] (drm_atomic_helper_update_legacy_modeset_state) from [<c0361684>] (drm_atomic_helper_commit_modeset_disables+0x1e4/0x35c)
> [   20.649732] [<c0361684>] (drm_atomic_helper_commit_modeset_disables) from [<c038782c>] (rockchip_atomic_commit_complete+0x34/0x108)
> [   20.661789] [<c038782c>] (rockchip_atomic_commit_complete) from [<c0387984>] (rockchip_drm_atomic_commit+0x84/0xa0)
> [   20.672442] [<c0387984>] (rockchip_drm_atomic_commit) from [<c0384c58>] (drm_atomic_commit+0x60/0x70)
> [   20.681711] [<c0384c58>] (drm_atomic_commit) from [<c0363ab0>] (restore_fbdev_mode+0x128/0x258)
> [   20.690418] [<c0363ab0>] (restore_fbdev_mode) from [<c0365208>] (drm_fb_helper_restore_fbdev_mode_unlocked+0x3c/0x80)
> [   20.701033] [<c0365208>] (drm_fb_helper_restore_fbdev_mode_unlocked) from [<c036529c>] (drm_fb_helper_set_par+0x50/0x60)
> [   20.711907] [<c036529c>] (drm_fb_helper_set_par) from [<c03651b4>] (drm_fb_helper_hotplug_event+0xc8/0xe0)
> [   20.721569] [<c03651b4>] (drm_fb_helper_hotplug_event) from [<c0387bd0>] (rockchip_drm_output_poll_changed+0x24/0x28)
> [   20.732185] [<c0387bd0>] (rockchip_drm_output_poll_changed) from [<c035aaf8>] (drm_kms_helper_hotplug_event+0x34/0x38)
> [   20.742891] [<c035aaf8>] (drm_kms_helper_hotplug_event) from [<c035b434>] (drm_helper_hpd_irq_event+0x120/0x150)
> [   20.753078] [<c035b434>] (drm_helper_hpd_irq_event) from [<c038dd1c>] (dw_hdmi_irq+0x14c/0x18c)
> [   20.761772] [<c038dd1c>] (dw_hdmi_irq) from [<c008d030>] (irq_thread_fn+0x2c/0x44)
> [   20.769350] [<c008d030>] (irq_thread_fn) from [<c008d33c>] (irq_thread+0x118/0x21c)
> [   20.777019] [<c008d33c>] (irq_thread) from [<c004bbb8>] (kthread+0xf4/0x10c)
> [   20.784083] [<c004bbb8>] (kthread) from [<c0010010>] (ret_from_fork+0x14/0x24)
> [   20.791300] ---[ end trace 3deaa51d288067a0 ]---
>
>
>
>
Hi Heiko
     This issue can be explained from following thread:
        https://lkml.org/lkml/2015/11/16/498

     You can fix it by following changes:

@@ -1667,8 +1667,6 @@ static int dw_hdmi_register(struct drm_device 
*drm, struct dw_hdmi *hdmi)
                                    &dw_hdmi_connector_funcs,
                                    DRM_MODE_CONNECTOR_HDMIA);

     -       hdmi->connector.encoder = encoder;


Thanks.

-- 
Mark Yao


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

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

* [PATCH v3 0/8] drm/rockchip: covert to support atomic API
@ 2015-12-17 10:32     ` Mark yao
  0 siblings, 0 replies; 51+ messages in thread
From: Mark yao @ 2015-12-17 10:32 UTC (permalink / raw)
  To: linux-arm-kernel

On 2015?12?17? 18:00, Heiko St?bner wrote:
> Hi Mark,
>
> Am Donnerstag, 17. Dezember 2015, 11:01:07 schrieb Mark Yao:
>> The series of patches coverting drm rockchip to atomic API, do some
>> cleanup and some fixes on atomic side.
>>
>> TODO: fence is not support on current version.
>>
>> Tested on rk3288 popmetal board.
> In general this works nicely and hdmi is still working on my firefly, so
>
> Tested-by: Heiko Stuebner <heiko@sntech.de>

Thanks.

>
> I get one warning though, which seems to be related to fbcon grabbing
> the framebuffer it seems.
>
>
> HDMI plugged in on boot:
>
> [    4.345329] ------------[ cut here ]------------
> [    4.345360] WARNING: CPU: 1 PID: 66 at drivers/gpu/drm/drm_atomic_helper.c:682 drm_atomic_helper_update_legacy_modeset_state+0x6c/0x200()
> [    4.345373] Modules linked in:
> [    4.345386] CPU: 1 PID: 66 Comm: kworker/u8:1 Not tainted 4.4.0-rc5+ #2787
> [    4.345392] Hardware name: Rockchip (Device Tree)
> [    4.345411] Workqueue: deferwq deferred_probe_work_func
> [    4.345438] [<c0019914>] (unwind_backtrace) from [<c0014bcc>] (show_stack+0x20/0x24)
> [    4.345458] [<c0014bcc>] (show_stack) from [<c02c4344>] (dump_stack+0x84/0xb8)
> [    4.345479] [<c02c4344>] (dump_stack) from [<c0029a20>] (warn_slowpath_common+0x98/0xc4)
> [    4.345496] [<c0029a20>] (warn_slowpath_common) from [<c0029b08>] (warn_slowpath_null+0x2c/0x34)
> [    4.345514] [<c0029b08>] (warn_slowpath_null) from [<c0361144>] (drm_atomic_helper_update_legacy_modeset_state+0x6c/0x200)
> [    4.345534] [<c0361144>] (drm_atomic_helper_update_legacy_modeset_state) from [<c0361684>] (drm_atomic_helper_commit_modeset_disables+0x1e4/0x35c)
> [    4.345557] [<c0361684>] (drm_atomic_helper_commit_modeset_disables) from [<c038782c>] (rockchip_atomic_commit_complete+0x34/0x108)
> [    4.345576] [<c038782c>] (rockchip_atomic_commit_complete) from [<c0387984>] (rockchip_drm_atomic_commit+0x84/0xa0)
> [    4.345594] [<c0387984>] (rockchip_drm_atomic_commit) from [<c0384c58>] (drm_atomic_commit+0x60/0x70)
> [    4.345609] [<c0384c58>] (drm_atomic_commit) from [<c0363ab0>] (restore_fbdev_mode+0x128/0x258)
> [    4.345625] [<c0363ab0>] (restore_fbdev_mode) from [<c0365208>] (drm_fb_helper_restore_fbdev_mode_unlocked+0x3c/0x80)
> [    4.345640] [<c0365208>] (drm_fb_helper_restore_fbdev_mode_unlocked) from [<c036529c>] (drm_fb_helper_set_par+0x50/0x60)
> [    4.345659] [<c036529c>] (drm_fb_helper_set_par) from [<c03052cc>] (fbcon_init+0x328/0x458)
> [    4.345676] [<c03052cc>] (fbcon_init) from [<c033a66c>] (visual_init+0xc4/0x114)
> [    4.345692] [<c033a66c>] (visual_init) from [<c033c098>] (do_bind_con_driver+0x1fc/0x330)
> [    4.345707] [<c033c098>] (do_bind_con_driver) from [<c033c540>] (do_take_over_console+0x174/0x1b4)
> [    4.345722] [<c033c540>] (do_take_over_console) from [<c0305464>] (do_fbcon_takeover+0x68/0xd0)
> [    4.345738] [<c0305464>] (do_fbcon_takeover) from [<c0305c6c>] (fbcon_event_notify+0x3fc/0x7d8)
> [    4.345756] [<c0305c6c>] (fbcon_event_notify) from [<c004d144>] (notifier_call_chain+0x58/0x80)
> [    4.345771] [<c004d144>] (notifier_call_chain) from [<c004d4d4>] (__blocking_notifier_call_chain+0x54/0x6c)
> [    4.345785] [<c004d4d4>] (__blocking_notifier_call_chain) from [<c004d514>] (blocking_notifier_call_chain+0x28/0x30)
> [    4.345804] [<c004d514>] (blocking_notifier_call_chain) from [<c0308c68>] (fb_notifier_call_chain+0x24/0x2c)
> [    4.345822] [<c0308c68>] (fb_notifier_call_chain) from [<c030aa7c>] (register_framebuffer+0x214/0x264)
> [    4.345839] [<c030aa7c>] (register_framebuffer) from [<c0365a00>] (drm_fb_helper_initial_config+0x2dc/0x34c)
> [    4.345856] [<c0365a00>] (drm_fb_helper_initial_config) from [<c038823c>] (rockchip_drm_fbdev_init+0x9c/0xe4)
> [    4.345873] [<c038823c>] (rockchip_drm_fbdev_init) from [<c03876bc>] (rockchip_drm_load+0x25c/0x2b0)
> [    4.345892] [<c03876bc>] (rockchip_drm_load) from [<c036eae4>] (drm_dev_register+0x80/0xc4)
> [    4.345910] [<c036eae4>] (drm_dev_register) from [<c03873d4>] (rockchip_drm_bind+0x58/0x84)
> [    4.345932] [<c03873d4>] (rockchip_drm_bind) from [<c03b4b54>] (try_to_bring_up_master.part.0+0xbc/0x114)
> [    4.345950] [<c03b4b54>] (try_to_bring_up_master.part.0) from [<c03b4da0>] (component_add+0xb0/0x118)
> [    4.345967] [<c03b4da0>] (component_add) from [<c038a2d8>] (vop_probe+0x40/0x4c)
> [    4.345984] [<c038a2d8>] (vop_probe) from [<c03bc350>] (platform_drv_probe+0x60/0xb0)
> [    4.345999] [<c03bc350>] (platform_drv_probe) from [<c03b9ffc>] (driver_probe_device+0x1a0/0x418)
> [    4.346014] [<c03b9ffc>] (driver_probe_device) from [<c03ba3f8>] (__device_attach_driver+0x94/0xa0)
> [    4.346028] [<c03ba3f8>] (__device_attach_driver) from [<c03b82a0>] (bus_for_each_drv+0x94/0xa4)
> [    4.346042] [<c03b82a0>] (bus_for_each_drv) from [<c03b9d3c>] (__device_attach+0xa4/0x144)
> [    4.346055] [<c03b9d3c>] (__device_attach) from [<c03ba564>] (device_initial_probe+0x1c/0x20)
> [    4.346068] [<c03ba564>] (device_initial_probe) from [<c03b91d4>] (bus_probe_device+0x38/0x94)
> [    4.346082] [<c03b91d4>] (bus_probe_device) from [<c03b9714>] (deferred_probe_work_func+0x8c/0xbc)
> [    4.346098] [<c03b9714>] (deferred_probe_work_func) from [<c0045094>] (process_one_work+0x328/0x668)
> [    4.346112] [<c0045094>] (process_one_work) from [<c0046304>] (worker_thread+0x2cc/0x41c)
> [    4.346128] [<c0046304>] (worker_thread) from [<c004bbb8>] (kthread+0xf4/0x10c)
> [    4.346146] [<c004bbb8>] (kthread) from [<c0010010>] (ret_from_fork+0x14/0x24)
> [    4.346155] ---[ end trace 8cd78a9f6ee0a57e ]---
>
>
> Plugging in HDMI after boot:
>
> [   20.559534] ------------[ cut here ]------------
> [   20.564412] WARNING: CPU: 3 PID: 74 at drivers/gpu/drm/drm_atomic_helper.c:682 drm_atomic_helper_update_legacy_modeset_state+0x6c/0x200()
> [   20.576991] Modules linked in:
> [   20.580175] CPU: 3 PID: 74 Comm: irq/51-ff980000 Not tainted 4.4.0-rc5+ #2787
> [   20.587502] Hardware name: Rockchip (Device Tree)
> [   20.592347] [<c0019914>] (unwind_backtrace) from [<c0014bcc>] (show_stack+0x20/0x24)
> [   20.600319] [<c0014bcc>] (show_stack) from [<c02c4344>] (dump_stack+0x84/0xb8)
> [   20.607776] [<c02c4344>] (dump_stack) from [<c0029a20>] (warn_slowpath_common+0x98/0xc4)
> [   20.616087] [<c0029a20>] (warn_slowpath_common) from [<c0029b08>] (warn_slowpath_null+0x2c/0x34)
> [   20.625106] [<c0029b08>] (warn_slowpath_null) from [<c0361144>] (drm_atomic_helper_update_legacy_modeset_state+0x6c/0x200)
> [   20.636382] [<c0361144>] (drm_atomic_helper_update_legacy_modeset_state) from [<c0361684>] (drm_atomic_helper_commit_modeset_disables+0x1e4/0x35c)
> [   20.649732] [<c0361684>] (drm_atomic_helper_commit_modeset_disables) from [<c038782c>] (rockchip_atomic_commit_complete+0x34/0x108)
> [   20.661789] [<c038782c>] (rockchip_atomic_commit_complete) from [<c0387984>] (rockchip_drm_atomic_commit+0x84/0xa0)
> [   20.672442] [<c0387984>] (rockchip_drm_atomic_commit) from [<c0384c58>] (drm_atomic_commit+0x60/0x70)
> [   20.681711] [<c0384c58>] (drm_atomic_commit) from [<c0363ab0>] (restore_fbdev_mode+0x128/0x258)
> [   20.690418] [<c0363ab0>] (restore_fbdev_mode) from [<c0365208>] (drm_fb_helper_restore_fbdev_mode_unlocked+0x3c/0x80)
> [   20.701033] [<c0365208>] (drm_fb_helper_restore_fbdev_mode_unlocked) from [<c036529c>] (drm_fb_helper_set_par+0x50/0x60)
> [   20.711907] [<c036529c>] (drm_fb_helper_set_par) from [<c03651b4>] (drm_fb_helper_hotplug_event+0xc8/0xe0)
> [   20.721569] [<c03651b4>] (drm_fb_helper_hotplug_event) from [<c0387bd0>] (rockchip_drm_output_poll_changed+0x24/0x28)
> [   20.732185] [<c0387bd0>] (rockchip_drm_output_poll_changed) from [<c035aaf8>] (drm_kms_helper_hotplug_event+0x34/0x38)
> [   20.742891] [<c035aaf8>] (drm_kms_helper_hotplug_event) from [<c035b434>] (drm_helper_hpd_irq_event+0x120/0x150)
> [   20.753078] [<c035b434>] (drm_helper_hpd_irq_event) from [<c038dd1c>] (dw_hdmi_irq+0x14c/0x18c)
> [   20.761772] [<c038dd1c>] (dw_hdmi_irq) from [<c008d030>] (irq_thread_fn+0x2c/0x44)
> [   20.769350] [<c008d030>] (irq_thread_fn) from [<c008d33c>] (irq_thread+0x118/0x21c)
> [   20.777019] [<c008d33c>] (irq_thread) from [<c004bbb8>] (kthread+0xf4/0x10c)
> [   20.784083] [<c004bbb8>] (kthread) from [<c0010010>] (ret_from_fork+0x14/0x24)
> [   20.791300] ---[ end trace 3deaa51d288067a0 ]---
>
>
>
>
Hi Heiko
     This issue can be explained from following thread:
        https://lkml.org/lkml/2015/11/16/498

     You can fix it by following changes:

@@ -1667,8 +1667,6 @@ static int dw_hdmi_register(struct drm_device 
*drm, struct dw_hdmi *hdmi)
                                    &dw_hdmi_connector_funcs,
                                    DRM_MODE_CONNECTOR_HDMIA);

     -       hdmi->connector.encoder = encoder;


Thanks.

-- 
?ark Yao

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

* Re: [PATCH v3 0/8] drm/rockchip: covert to support atomic API
  2015-12-17 10:32     ` Mark yao
  (?)
@ 2015-12-17 12:03       ` Heiko Stübner
  -1 siblings, 0 replies; 51+ messages in thread
From: Heiko Stübner @ 2015-12-17 12:03 UTC (permalink / raw)
  To: Mark yao
  Cc: David Airlie, dri-devel, linux-arm-kernel, linux-rockchip, linux-kernel

Hi Mark,

Am Donnerstag, 17. Dezember 2015, 18:32:31 schrieb Mark yao:
> On 2015年12月17日 18:00, Heiko Stübner wrote:
> > Am Donnerstag, 17. Dezember 2015, 11:01:07 schrieb Mark Yao:
> >> The series of patches coverting drm rockchip to atomic API, do some
> >> cleanup and some fixes on atomic side.

[...]

> > Plugging in HDMI after boot:
> > 
> > [   20.559534] ------------[ cut here ]------------
> > [   20.564412] WARNING: CPU: 3 PID: 74 at
> > drivers/gpu/drm/drm_atomic_helper.c:682
> > drm_atomic_helper_update_legacy_modeset_state+0x6c/0x200() [   20.576991]
> > Modules linked in:
> > [   20.580175] CPU: 3 PID: 74 Comm: irq/51-ff980000 Not tainted 4.4.0-rc5+
> > #2787 [   20.587502] Hardware name: Rockchip (Device Tree)
> > [   20.592347] [<c0019914>] (unwind_backtrace) from [<c0014bcc>]
> > (show_stack+0x20/0x24) [   20.600319] [<c0014bcc>] (show_stack) from
> > [<c02c4344>] (dump_stack+0x84/0xb8) [   20.607776] [<c02c4344>]
> > (dump_stack) from [<c0029a20>] (warn_slowpath_common+0x98/0xc4) [  
> > 20.616087] [<c0029a20>] (warn_slowpath_common) from [<c0029b08>]
> > (warn_slowpath_null+0x2c/0x34) [   20.625106] [<c0029b08>]
> > (warn_slowpath_null) from [<c0361144>]
> > (drm_atomic_helper_update_legacy_modeset_state+0x6c/0x200) [   20.636382]
> > [<c0361144>] (drm_atomic_helper_update_legacy_modeset_state) from
> > [<c0361684>] (drm_atomic_helper_commit_modeset_disables+0x1e4/0x35c) [  
> > 20.649732] [<c0361684>] (drm_atomic_helper_commit_modeset_disables) from
> > [<c038782c>] (rockchip_atomic_commit_complete+0x34/0x108) [   20.661789]
> > [<c038782c>] (rockchip_atomic_commit_complete) from [<c0387984>]
> > (rockchip_drm_atomic_commit+0x84/0xa0) [   20.672442] [<c0387984>]
> > (rockchip_drm_atomic_commit) from [<c0384c58>]
> > (drm_atomic_commit+0x60/0x70) [   20.681711] [<c0384c58>]
> > (drm_atomic_commit) from [<c0363ab0>] (restore_fbdev_mode+0x128/0x258) [ 
> >  20.690418] [<c0363ab0>] (restore_fbdev_mode) from [<c0365208>]
> > (drm_fb_helper_restore_fbdev_mode_unlocked+0x3c/0x80) [   20.701033]
> > [<c0365208>] (drm_fb_helper_restore_fbdev_mode_unlocked) from
> > [<c036529c>] (drm_fb_helper_set_par+0x50/0x60) [   20.711907]
> > [<c036529c>] (drm_fb_helper_set_par) from [<c03651b4>]
> > (drm_fb_helper_hotplug_event+0xc8/0xe0) [   20.721569] [<c03651b4>]
> > (drm_fb_helper_hotplug_event) from [<c0387bd0>]
> > (rockchip_drm_output_poll_changed+0x24/0x28) [   20.732185] [<c0387bd0>]
> > (rockchip_drm_output_poll_changed) from [<c035aaf8>]
> > (drm_kms_helper_hotplug_event+0x34/0x38) [   20.742891] [<c035aaf8>]
> > (drm_kms_helper_hotplug_event) from [<c035b434>]
> > (drm_helper_hpd_irq_event+0x120/0x150) [   20.753078] [<c035b434>]
> > (drm_helper_hpd_irq_event) from [<c038dd1c>] (dw_hdmi_irq+0x14c/0x18c) [ 
> >  20.761772] [<c038dd1c>] (dw_hdmi_irq) from [<c008d030>]
> > (irq_thread_fn+0x2c/0x44) [   20.769350] [<c008d030>] (irq_thread_fn)
> > from [<c008d33c>] (irq_thread+0x118/0x21c) [   20.777019] [<c008d33c>]
> > (irq_thread) from [<c004bbb8>] (kthread+0xf4/0x10c) [   20.784083]
> > [<c004bbb8>] (kthread) from [<c0010010>] (ret_from_fork+0x14/0x24) [  
> > 20.791300] ---[ end trace 3deaa51d288067a0 ]---
> 
> Hi Heiko
>      This issue can be explained from following thread:
>         https://lkml.org/lkml/2015/11/16/498
> 
>      You can fix it by following changes:
> 
> @@ -1667,8 +1667,6 @@ static int dw_hdmi_register(struct drm_device
> *drm, struct dw_hdmi *hdmi)
>                                     &dw_hdmi_connector_funcs,
>                                     DRM_MODE_CONNECTOR_HDMIA);
> 
>      -       hdmi->connector.encoder = encoder;

yep that fixes the warning. From the thread you mention, it looks like that 
assignment should also be removed in the non-atomic case (i.MX)?

Or if it is really necessary there could also wrap it in a conditional to only 
be set for the non-atomic case.


Heiko

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

* Re: [PATCH v3 0/8] drm/rockchip: covert to support atomic API
@ 2015-12-17 12:03       ` Heiko Stübner
  0 siblings, 0 replies; 51+ messages in thread
From: Heiko Stübner @ 2015-12-17 12:03 UTC (permalink / raw)
  To: Mark yao; +Cc: linux-rockchip, linux-arm-kernel, dri-devel, linux-kernel

Hi Mark,

Am Donnerstag, 17. Dezember 2015, 18:32:31 schrieb Mark yao:
> On 2015年12月17日 18:00, Heiko Stübner wrote:
> > Am Donnerstag, 17. Dezember 2015, 11:01:07 schrieb Mark Yao:
> >> The series of patches coverting drm rockchip to atomic API, do some
> >> cleanup and some fixes on atomic side.

[...]

> > Plugging in HDMI after boot:
> > 
> > [   20.559534] ------------[ cut here ]------------
> > [   20.564412] WARNING: CPU: 3 PID: 74 at
> > drivers/gpu/drm/drm_atomic_helper.c:682
> > drm_atomic_helper_update_legacy_modeset_state+0x6c/0x200() [   20.576991]
> > Modules linked in:
> > [   20.580175] CPU: 3 PID: 74 Comm: irq/51-ff980000 Not tainted 4.4.0-rc5+
> > #2787 [   20.587502] Hardware name: Rockchip (Device Tree)
> > [   20.592347] [<c0019914>] (unwind_backtrace) from [<c0014bcc>]
> > (show_stack+0x20/0x24) [   20.600319] [<c0014bcc>] (show_stack) from
> > [<c02c4344>] (dump_stack+0x84/0xb8) [   20.607776] [<c02c4344>]
> > (dump_stack) from [<c0029a20>] (warn_slowpath_common+0x98/0xc4) [  
> > 20.616087] [<c0029a20>] (warn_slowpath_common) from [<c0029b08>]
> > (warn_slowpath_null+0x2c/0x34) [   20.625106] [<c0029b08>]
> > (warn_slowpath_null) from [<c0361144>]
> > (drm_atomic_helper_update_legacy_modeset_state+0x6c/0x200) [   20.636382]
> > [<c0361144>] (drm_atomic_helper_update_legacy_modeset_state) from
> > [<c0361684>] (drm_atomic_helper_commit_modeset_disables+0x1e4/0x35c) [  
> > 20.649732] [<c0361684>] (drm_atomic_helper_commit_modeset_disables) from
> > [<c038782c>] (rockchip_atomic_commit_complete+0x34/0x108) [   20.661789]
> > [<c038782c>] (rockchip_atomic_commit_complete) from [<c0387984>]
> > (rockchip_drm_atomic_commit+0x84/0xa0) [   20.672442] [<c0387984>]
> > (rockchip_drm_atomic_commit) from [<c0384c58>]
> > (drm_atomic_commit+0x60/0x70) [   20.681711] [<c0384c58>]
> > (drm_atomic_commit) from [<c0363ab0>] (restore_fbdev_mode+0x128/0x258) [ 
> >  20.690418] [<c0363ab0>] (restore_fbdev_mode) from [<c0365208>]
> > (drm_fb_helper_restore_fbdev_mode_unlocked+0x3c/0x80) [   20.701033]
> > [<c0365208>] (drm_fb_helper_restore_fbdev_mode_unlocked) from
> > [<c036529c>] (drm_fb_helper_set_par+0x50/0x60) [   20.711907]
> > [<c036529c>] (drm_fb_helper_set_par) from [<c03651b4>]
> > (drm_fb_helper_hotplug_event+0xc8/0xe0) [   20.721569] [<c03651b4>]
> > (drm_fb_helper_hotplug_event) from [<c0387bd0>]
> > (rockchip_drm_output_poll_changed+0x24/0x28) [   20.732185] [<c0387bd0>]
> > (rockchip_drm_output_poll_changed) from [<c035aaf8>]
> > (drm_kms_helper_hotplug_event+0x34/0x38) [   20.742891] [<c035aaf8>]
> > (drm_kms_helper_hotplug_event) from [<c035b434>]
> > (drm_helper_hpd_irq_event+0x120/0x150) [   20.753078] [<c035b434>]
> > (drm_helper_hpd_irq_event) from [<c038dd1c>] (dw_hdmi_irq+0x14c/0x18c) [ 
> >  20.761772] [<c038dd1c>] (dw_hdmi_irq) from [<c008d030>]
> > (irq_thread_fn+0x2c/0x44) [   20.769350] [<c008d030>] (irq_thread_fn)
> > from [<c008d33c>] (irq_thread+0x118/0x21c) [   20.777019] [<c008d33c>]
> > (irq_thread) from [<c004bbb8>] (kthread+0xf4/0x10c) [   20.784083]
> > [<c004bbb8>] (kthread) from [<c0010010>] (ret_from_fork+0x14/0x24) [  
> > 20.791300] ---[ end trace 3deaa51d288067a0 ]---
> 
> Hi Heiko
>      This issue can be explained from following thread:
>         https://lkml.org/lkml/2015/11/16/498
> 
>      You can fix it by following changes:
> 
> @@ -1667,8 +1667,6 @@ static int dw_hdmi_register(struct drm_device
> *drm, struct dw_hdmi *hdmi)
>                                     &dw_hdmi_connector_funcs,
>                                     DRM_MODE_CONNECTOR_HDMIA);
> 
>      -       hdmi->connector.encoder = encoder;

yep that fixes the warning. From the thread you mention, it looks like that 
assignment should also be removed in the non-atomic case (i.MX)?

Or if it is really necessary there could also wrap it in a conditional to only 
be set for the non-atomic case.


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

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

* [PATCH v3 0/8] drm/rockchip: covert to support atomic API
@ 2015-12-17 12:03       ` Heiko Stübner
  0 siblings, 0 replies; 51+ messages in thread
From: Heiko Stübner @ 2015-12-17 12:03 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Mark,

Am Donnerstag, 17. Dezember 2015, 18:32:31 schrieb Mark yao:
> On 2015?12?17? 18:00, Heiko St?bner wrote:
> > Am Donnerstag, 17. Dezember 2015, 11:01:07 schrieb Mark Yao:
> >> The series of patches coverting drm rockchip to atomic API, do some
> >> cleanup and some fixes on atomic side.

[...]

> > Plugging in HDMI after boot:
> > 
> > [   20.559534] ------------[ cut here ]------------
> > [   20.564412] WARNING: CPU: 3 PID: 74 at
> > drivers/gpu/drm/drm_atomic_helper.c:682
> > drm_atomic_helper_update_legacy_modeset_state+0x6c/0x200() [   20.576991]
> > Modules linked in:
> > [   20.580175] CPU: 3 PID: 74 Comm: irq/51-ff980000 Not tainted 4.4.0-rc5+
> > #2787 [   20.587502] Hardware name: Rockchip (Device Tree)
> > [   20.592347] [<c0019914>] (unwind_backtrace) from [<c0014bcc>]
> > (show_stack+0x20/0x24) [   20.600319] [<c0014bcc>] (show_stack) from
> > [<c02c4344>] (dump_stack+0x84/0xb8) [   20.607776] [<c02c4344>]
> > (dump_stack) from [<c0029a20>] (warn_slowpath_common+0x98/0xc4) [  
> > 20.616087] [<c0029a20>] (warn_slowpath_common) from [<c0029b08>]
> > (warn_slowpath_null+0x2c/0x34) [   20.625106] [<c0029b08>]
> > (warn_slowpath_null) from [<c0361144>]
> > (drm_atomic_helper_update_legacy_modeset_state+0x6c/0x200) [   20.636382]
> > [<c0361144>] (drm_atomic_helper_update_legacy_modeset_state) from
> > [<c0361684>] (drm_atomic_helper_commit_modeset_disables+0x1e4/0x35c) [  
> > 20.649732] [<c0361684>] (drm_atomic_helper_commit_modeset_disables) from
> > [<c038782c>] (rockchip_atomic_commit_complete+0x34/0x108) [   20.661789]
> > [<c038782c>] (rockchip_atomic_commit_complete) from [<c0387984>]
> > (rockchip_drm_atomic_commit+0x84/0xa0) [   20.672442] [<c0387984>]
> > (rockchip_drm_atomic_commit) from [<c0384c58>]
> > (drm_atomic_commit+0x60/0x70) [   20.681711] [<c0384c58>]
> > (drm_atomic_commit) from [<c0363ab0>] (restore_fbdev_mode+0x128/0x258) [ 
> >  20.690418] [<c0363ab0>] (restore_fbdev_mode) from [<c0365208>]
> > (drm_fb_helper_restore_fbdev_mode_unlocked+0x3c/0x80) [   20.701033]
> > [<c0365208>] (drm_fb_helper_restore_fbdev_mode_unlocked) from
> > [<c036529c>] (drm_fb_helper_set_par+0x50/0x60) [   20.711907]
> > [<c036529c>] (drm_fb_helper_set_par) from [<c03651b4>]
> > (drm_fb_helper_hotplug_event+0xc8/0xe0) [   20.721569] [<c03651b4>]
> > (drm_fb_helper_hotplug_event) from [<c0387bd0>]
> > (rockchip_drm_output_poll_changed+0x24/0x28) [   20.732185] [<c0387bd0>]
> > (rockchip_drm_output_poll_changed) from [<c035aaf8>]
> > (drm_kms_helper_hotplug_event+0x34/0x38) [   20.742891] [<c035aaf8>]
> > (drm_kms_helper_hotplug_event) from [<c035b434>]
> > (drm_helper_hpd_irq_event+0x120/0x150) [   20.753078] [<c035b434>]
> > (drm_helper_hpd_irq_event) from [<c038dd1c>] (dw_hdmi_irq+0x14c/0x18c) [ 
> >  20.761772] [<c038dd1c>] (dw_hdmi_irq) from [<c008d030>]
> > (irq_thread_fn+0x2c/0x44) [   20.769350] [<c008d030>] (irq_thread_fn)
> > from [<c008d33c>] (irq_thread+0x118/0x21c) [   20.777019] [<c008d33c>]
> > (irq_thread) from [<c004bbb8>] (kthread+0xf4/0x10c) [   20.784083]
> > [<c004bbb8>] (kthread) from [<c0010010>] (ret_from_fork+0x14/0x24) [  
> > 20.791300] ---[ end trace 3deaa51d288067a0 ]---
> 
> Hi Heiko
>      This issue can be explained from following thread:
>         https://lkml.org/lkml/2015/11/16/498
> 
>      You can fix it by following changes:
> 
> @@ -1667,8 +1667,6 @@ static int dw_hdmi_register(struct drm_device
> *drm, struct dw_hdmi *hdmi)
>                                     &dw_hdmi_connector_funcs,
>                                     DRM_MODE_CONNECTOR_HDMIA);
> 
>      -       hdmi->connector.encoder = encoder;

yep that fixes the warning. From the thread you mention, it looks like that 
assignment should also be removed in the non-atomic case (i.MX)?

Or if it is really necessary there could also wrap it in a conditional to only 
be set for the non-atomic case.


Heiko

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

* Re: [PATCH v3 0/8] drm/rockchip: covert to support atomic API
  2015-12-17 12:03       ` Heiko Stübner
  (?)
@ 2015-12-17 14:27         ` Daniel Vetter
  -1 siblings, 0 replies; 51+ messages in thread
From: Daniel Vetter @ 2015-12-17 14:27 UTC (permalink / raw)
  To: Heiko Stübner
  Cc: Mark yao, linux-rockchip, linux-arm-kernel, dri-devel, linux-kernel

On Thu, Dec 17, 2015 at 01:03:53PM +0100, Heiko Stübner wrote:
> Hi Mark,
> 
> Am Donnerstag, 17. Dezember 2015, 18:32:31 schrieb Mark yao:
> > On 2015年12月17日 18:00, Heiko Stübner wrote:
> > > Am Donnerstag, 17. Dezember 2015, 11:01:07 schrieb Mark Yao:
> > >> The series of patches coverting drm rockchip to atomic API, do some
> > >> cleanup and some fixes on atomic side.
> 
> [...]
> 
> > > Plugging in HDMI after boot:
> > > 
> > > [   20.559534] ------------[ cut here ]------------
> > > [   20.564412] WARNING: CPU: 3 PID: 74 at
> > > drivers/gpu/drm/drm_atomic_helper.c:682
> > > drm_atomic_helper_update_legacy_modeset_state+0x6c/0x200() [   20.576991]
> > > Modules linked in:
> > > [   20.580175] CPU: 3 PID: 74 Comm: irq/51-ff980000 Not tainted 4.4.0-rc5+
> > > #2787 [   20.587502] Hardware name: Rockchip (Device Tree)
> > > [   20.592347] [<c0019914>] (unwind_backtrace) from [<c0014bcc>]
> > > (show_stack+0x20/0x24) [   20.600319] [<c0014bcc>] (show_stack) from
> > > [<c02c4344>] (dump_stack+0x84/0xb8) [   20.607776] [<c02c4344>]
> > > (dump_stack) from [<c0029a20>] (warn_slowpath_common+0x98/0xc4) [  
> > > 20.616087] [<c0029a20>] (warn_slowpath_common) from [<c0029b08>]
> > > (warn_slowpath_null+0x2c/0x34) [   20.625106] [<c0029b08>]
> > > (warn_slowpath_null) from [<c0361144>]
> > > (drm_atomic_helper_update_legacy_modeset_state+0x6c/0x200) [   20.636382]
> > > [<c0361144>] (drm_atomic_helper_update_legacy_modeset_state) from
> > > [<c0361684>] (drm_atomic_helper_commit_modeset_disables+0x1e4/0x35c) [  
> > > 20.649732] [<c0361684>] (drm_atomic_helper_commit_modeset_disables) from
> > > [<c038782c>] (rockchip_atomic_commit_complete+0x34/0x108) [   20.661789]
> > > [<c038782c>] (rockchip_atomic_commit_complete) from [<c0387984>]
> > > (rockchip_drm_atomic_commit+0x84/0xa0) [   20.672442] [<c0387984>]
> > > (rockchip_drm_atomic_commit) from [<c0384c58>]
> > > (drm_atomic_commit+0x60/0x70) [   20.681711] [<c0384c58>]
> > > (drm_atomic_commit) from [<c0363ab0>] (restore_fbdev_mode+0x128/0x258) [ 
> > >  20.690418] [<c0363ab0>] (restore_fbdev_mode) from [<c0365208>]
> > > (drm_fb_helper_restore_fbdev_mode_unlocked+0x3c/0x80) [   20.701033]
> > > [<c0365208>] (drm_fb_helper_restore_fbdev_mode_unlocked) from
> > > [<c036529c>] (drm_fb_helper_set_par+0x50/0x60) [   20.711907]
> > > [<c036529c>] (drm_fb_helper_set_par) from [<c03651b4>]
> > > (drm_fb_helper_hotplug_event+0xc8/0xe0) [   20.721569] [<c03651b4>]
> > > (drm_fb_helper_hotplug_event) from [<c0387bd0>]
> > > (rockchip_drm_output_poll_changed+0x24/0x28) [   20.732185] [<c0387bd0>]
> > > (rockchip_drm_output_poll_changed) from [<c035aaf8>]
> > > (drm_kms_helper_hotplug_event+0x34/0x38) [   20.742891] [<c035aaf8>]
> > > (drm_kms_helper_hotplug_event) from [<c035b434>]
> > > (drm_helper_hpd_irq_event+0x120/0x150) [   20.753078] [<c035b434>]
> > > (drm_helper_hpd_irq_event) from [<c038dd1c>] (dw_hdmi_irq+0x14c/0x18c) [ 
> > >  20.761772] [<c038dd1c>] (dw_hdmi_irq) from [<c008d030>]
> > > (irq_thread_fn+0x2c/0x44) [   20.769350] [<c008d030>] (irq_thread_fn)
> > > from [<c008d33c>] (irq_thread+0x118/0x21c) [   20.777019] [<c008d33c>]
> > > (irq_thread) from [<c004bbb8>] (kthread+0xf4/0x10c) [   20.784083]
> > > [<c004bbb8>] (kthread) from [<c0010010>] (ret_from_fork+0x14/0x24) [  
> > > 20.791300] ---[ end trace 3deaa51d288067a0 ]---
> > 
> > Hi Heiko
> >      This issue can be explained from following thread:
> >         https://lkml.org/lkml/2015/11/16/498
> > 
> >      You can fix it by following changes:
> > 
> > @@ -1667,8 +1667,6 @@ static int dw_hdmi_register(struct drm_device
> > *drm, struct dw_hdmi *hdmi)
> >                                     &dw_hdmi_connector_funcs,
> >                                     DRM_MODE_CONNECTOR_HDMIA);
> > 
> >      -       hdmi->connector.encoder = encoder;
> 
> yep that fixes the warning. From the thread you mention, it looks like that 
> assignment should also be removed in the non-atomic case (i.MX)?
> 
> Or if it is really necessary there could also wrap it in a conditional to only 
> be set for the non-atomic case.

It wont work with non-atomic, but it'll only break things from the 2nd
modeset onwards. Someone needs to fix that bug, since afaiu the code it'd
blow up for non-atomic if you remove it on even the first modeset.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch

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

* Re: [PATCH v3 0/8] drm/rockchip: covert to support atomic API
@ 2015-12-17 14:27         ` Daniel Vetter
  0 siblings, 0 replies; 51+ messages in thread
From: Daniel Vetter @ 2015-12-17 14:27 UTC (permalink / raw)
  To: Heiko Stübner
  Cc: linux-rockchip, linux-kernel, dri-devel, linux-arm-kernel

On Thu, Dec 17, 2015 at 01:03:53PM +0100, Heiko Stübner wrote:
> Hi Mark,
> 
> Am Donnerstag, 17. Dezember 2015, 18:32:31 schrieb Mark yao:
> > On 2015年12月17日 18:00, Heiko Stübner wrote:
> > > Am Donnerstag, 17. Dezember 2015, 11:01:07 schrieb Mark Yao:
> > >> The series of patches coverting drm rockchip to atomic API, do some
> > >> cleanup and some fixes on atomic side.
> 
> [...]
> 
> > > Plugging in HDMI after boot:
> > > 
> > > [   20.559534] ------------[ cut here ]------------
> > > [   20.564412] WARNING: CPU: 3 PID: 74 at
> > > drivers/gpu/drm/drm_atomic_helper.c:682
> > > drm_atomic_helper_update_legacy_modeset_state+0x6c/0x200() [   20.576991]
> > > Modules linked in:
> > > [   20.580175] CPU: 3 PID: 74 Comm: irq/51-ff980000 Not tainted 4.4.0-rc5+
> > > #2787 [   20.587502] Hardware name: Rockchip (Device Tree)
> > > [   20.592347] [<c0019914>] (unwind_backtrace) from [<c0014bcc>]
> > > (show_stack+0x20/0x24) [   20.600319] [<c0014bcc>] (show_stack) from
> > > [<c02c4344>] (dump_stack+0x84/0xb8) [   20.607776] [<c02c4344>]
> > > (dump_stack) from [<c0029a20>] (warn_slowpath_common+0x98/0xc4) [  
> > > 20.616087] [<c0029a20>] (warn_slowpath_common) from [<c0029b08>]
> > > (warn_slowpath_null+0x2c/0x34) [   20.625106] [<c0029b08>]
> > > (warn_slowpath_null) from [<c0361144>]
> > > (drm_atomic_helper_update_legacy_modeset_state+0x6c/0x200) [   20.636382]
> > > [<c0361144>] (drm_atomic_helper_update_legacy_modeset_state) from
> > > [<c0361684>] (drm_atomic_helper_commit_modeset_disables+0x1e4/0x35c) [  
> > > 20.649732] [<c0361684>] (drm_atomic_helper_commit_modeset_disables) from
> > > [<c038782c>] (rockchip_atomic_commit_complete+0x34/0x108) [   20.661789]
> > > [<c038782c>] (rockchip_atomic_commit_complete) from [<c0387984>]
> > > (rockchip_drm_atomic_commit+0x84/0xa0) [   20.672442] [<c0387984>]
> > > (rockchip_drm_atomic_commit) from [<c0384c58>]
> > > (drm_atomic_commit+0x60/0x70) [   20.681711] [<c0384c58>]
> > > (drm_atomic_commit) from [<c0363ab0>] (restore_fbdev_mode+0x128/0x258) [ 
> > >  20.690418] [<c0363ab0>] (restore_fbdev_mode) from [<c0365208>]
> > > (drm_fb_helper_restore_fbdev_mode_unlocked+0x3c/0x80) [   20.701033]
> > > [<c0365208>] (drm_fb_helper_restore_fbdev_mode_unlocked) from
> > > [<c036529c>] (drm_fb_helper_set_par+0x50/0x60) [   20.711907]
> > > [<c036529c>] (drm_fb_helper_set_par) from [<c03651b4>]
> > > (drm_fb_helper_hotplug_event+0xc8/0xe0) [   20.721569] [<c03651b4>]
> > > (drm_fb_helper_hotplug_event) from [<c0387bd0>]
> > > (rockchip_drm_output_poll_changed+0x24/0x28) [   20.732185] [<c0387bd0>]
> > > (rockchip_drm_output_poll_changed) from [<c035aaf8>]
> > > (drm_kms_helper_hotplug_event+0x34/0x38) [   20.742891] [<c035aaf8>]
> > > (drm_kms_helper_hotplug_event) from [<c035b434>]
> > > (drm_helper_hpd_irq_event+0x120/0x150) [   20.753078] [<c035b434>]
> > > (drm_helper_hpd_irq_event) from [<c038dd1c>] (dw_hdmi_irq+0x14c/0x18c) [ 
> > >  20.761772] [<c038dd1c>] (dw_hdmi_irq) from [<c008d030>]
> > > (irq_thread_fn+0x2c/0x44) [   20.769350] [<c008d030>] (irq_thread_fn)
> > > from [<c008d33c>] (irq_thread+0x118/0x21c) [   20.777019] [<c008d33c>]
> > > (irq_thread) from [<c004bbb8>] (kthread+0xf4/0x10c) [   20.784083]
> > > [<c004bbb8>] (kthread) from [<c0010010>] (ret_from_fork+0x14/0x24) [  
> > > 20.791300] ---[ end trace 3deaa51d288067a0 ]---
> > 
> > Hi Heiko
> >      This issue can be explained from following thread:
> >         https://lkml.org/lkml/2015/11/16/498
> > 
> >      You can fix it by following changes:
> > 
> > @@ -1667,8 +1667,6 @@ static int dw_hdmi_register(struct drm_device
> > *drm, struct dw_hdmi *hdmi)
> >                                     &dw_hdmi_connector_funcs,
> >                                     DRM_MODE_CONNECTOR_HDMIA);
> > 
> >      -       hdmi->connector.encoder = encoder;
> 
> yep that fixes the warning. From the thread you mention, it looks like that 
> assignment should also be removed in the non-atomic case (i.MX)?
> 
> Or if it is really necessary there could also wrap it in a conditional to only 
> be set for the non-atomic case.

It wont work with non-atomic, but it'll only break things from the 2nd
modeset onwards. Someone needs to fix that bug, since afaiu the code it'd
blow up for non-atomic if you remove it on even the first modeset.
-Daniel
-- 
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] 51+ messages in thread

* [PATCH v3 0/8] drm/rockchip: covert to support atomic API
@ 2015-12-17 14:27         ` Daniel Vetter
  0 siblings, 0 replies; 51+ messages in thread
From: Daniel Vetter @ 2015-12-17 14:27 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Dec 17, 2015 at 01:03:53PM +0100, Heiko St?bner wrote:
> Hi Mark,
> 
> Am Donnerstag, 17. Dezember 2015, 18:32:31 schrieb Mark yao:
> > On 2015?12?17? 18:00, Heiko St?bner wrote:
> > > Am Donnerstag, 17. Dezember 2015, 11:01:07 schrieb Mark Yao:
> > >> The series of patches coverting drm rockchip to atomic API, do some
> > >> cleanup and some fixes on atomic side.
> 
> [...]
> 
> > > Plugging in HDMI after boot:
> > > 
> > > [   20.559534] ------------[ cut here ]------------
> > > [   20.564412] WARNING: CPU: 3 PID: 74 at
> > > drivers/gpu/drm/drm_atomic_helper.c:682
> > > drm_atomic_helper_update_legacy_modeset_state+0x6c/0x200() [   20.576991]
> > > Modules linked in:
> > > [   20.580175] CPU: 3 PID: 74 Comm: irq/51-ff980000 Not tainted 4.4.0-rc5+
> > > #2787 [   20.587502] Hardware name: Rockchip (Device Tree)
> > > [   20.592347] [<c0019914>] (unwind_backtrace) from [<c0014bcc>]
> > > (show_stack+0x20/0x24) [   20.600319] [<c0014bcc>] (show_stack) from
> > > [<c02c4344>] (dump_stack+0x84/0xb8) [   20.607776] [<c02c4344>]
> > > (dump_stack) from [<c0029a20>] (warn_slowpath_common+0x98/0xc4) [  
> > > 20.616087] [<c0029a20>] (warn_slowpath_common) from [<c0029b08>]
> > > (warn_slowpath_null+0x2c/0x34) [   20.625106] [<c0029b08>]
> > > (warn_slowpath_null) from [<c0361144>]
> > > (drm_atomic_helper_update_legacy_modeset_state+0x6c/0x200) [   20.636382]
> > > [<c0361144>] (drm_atomic_helper_update_legacy_modeset_state) from
> > > [<c0361684>] (drm_atomic_helper_commit_modeset_disables+0x1e4/0x35c) [  
> > > 20.649732] [<c0361684>] (drm_atomic_helper_commit_modeset_disables) from
> > > [<c038782c>] (rockchip_atomic_commit_complete+0x34/0x108) [   20.661789]
> > > [<c038782c>] (rockchip_atomic_commit_complete) from [<c0387984>]
> > > (rockchip_drm_atomic_commit+0x84/0xa0) [   20.672442] [<c0387984>]
> > > (rockchip_drm_atomic_commit) from [<c0384c58>]
> > > (drm_atomic_commit+0x60/0x70) [   20.681711] [<c0384c58>]
> > > (drm_atomic_commit) from [<c0363ab0>] (restore_fbdev_mode+0x128/0x258) [ 
> > >  20.690418] [<c0363ab0>] (restore_fbdev_mode) from [<c0365208>]
> > > (drm_fb_helper_restore_fbdev_mode_unlocked+0x3c/0x80) [   20.701033]
> > > [<c0365208>] (drm_fb_helper_restore_fbdev_mode_unlocked) from
> > > [<c036529c>] (drm_fb_helper_set_par+0x50/0x60) [   20.711907]
> > > [<c036529c>] (drm_fb_helper_set_par) from [<c03651b4>]
> > > (drm_fb_helper_hotplug_event+0xc8/0xe0) [   20.721569] [<c03651b4>]
> > > (drm_fb_helper_hotplug_event) from [<c0387bd0>]
> > > (rockchip_drm_output_poll_changed+0x24/0x28) [   20.732185] [<c0387bd0>]
> > > (rockchip_drm_output_poll_changed) from [<c035aaf8>]
> > > (drm_kms_helper_hotplug_event+0x34/0x38) [   20.742891] [<c035aaf8>]
> > > (drm_kms_helper_hotplug_event) from [<c035b434>]
> > > (drm_helper_hpd_irq_event+0x120/0x150) [   20.753078] [<c035b434>]
> > > (drm_helper_hpd_irq_event) from [<c038dd1c>] (dw_hdmi_irq+0x14c/0x18c) [ 
> > >  20.761772] [<c038dd1c>] (dw_hdmi_irq) from [<c008d030>]
> > > (irq_thread_fn+0x2c/0x44) [   20.769350] [<c008d030>] (irq_thread_fn)
> > > from [<c008d33c>] (irq_thread+0x118/0x21c) [   20.777019] [<c008d33c>]
> > > (irq_thread) from [<c004bbb8>] (kthread+0xf4/0x10c) [   20.784083]
> > > [<c004bbb8>] (kthread) from [<c0010010>] (ret_from_fork+0x14/0x24) [  
> > > 20.791300] ---[ end trace 3deaa51d288067a0 ]---
> > 
> > Hi Heiko
> >      This issue can be explained from following thread:
> >         https://lkml.org/lkml/2015/11/16/498
> > 
> >      You can fix it by following changes:
> > 
> > @@ -1667,8 +1667,6 @@ static int dw_hdmi_register(struct drm_device
> > *drm, struct dw_hdmi *hdmi)
> >                                     &dw_hdmi_connector_funcs,
> >                                     DRM_MODE_CONNECTOR_HDMIA);
> > 
> >      -       hdmi->connector.encoder = encoder;
> 
> yep that fixes the warning. From the thread you mention, it looks like that 
> assignment should also be removed in the non-atomic case (i.MX)?
> 
> Or if it is really necessary there could also wrap it in a conditional to only 
> be set for the non-atomic case.

It wont work with non-atomic, but it'll only break things from the 2nd
modeset onwards. Someone needs to fix that bug, since afaiu the code it'd
blow up for non-atomic if you remove it on even the first modeset.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch

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

* Re: [PATCH v3 0/8] drm/rockchip: covert to support atomic API
  2015-12-17  3:01 ` Mark Yao
                   ` (10 preceding siblings ...)
  (?)
@ 2015-12-21  2:28 ` Mark yao
  -1 siblings, 0 replies; 51+ messages in thread
From: Mark yao @ 2015-12-21  2:28 UTC (permalink / raw)
  To: David Airlie, Heiko Stuebner, dri-devel, linux-arm-kernel,
	linux-rockchip, linux-kernel

[-- Attachment #1: Type: text/html, Size: 3005 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] 51+ messages in thread

end of thread, other threads:[~2015-12-21  2:28 UTC | newest]

Thread overview: 51+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-12-17  3:01 [PATCH v3 0/8] drm/rockchip: covert to support atomic API Mark Yao
2015-12-17  3:01 ` Mark Yao
2015-12-17  3:01 ` Mark Yao
2015-12-17  3:01 ` [PATCH v3 1/8] drm/rockchip: Use new vblank api drm_crtc_vblank_* Mark Yao
2015-12-17  3:01   ` Mark Yao
2015-12-17  3:01   ` Mark Yao
2015-12-17  3:01 ` [PATCH v3 2/8] drm/rockchip: vop: replace dpms with enable/disable Mark Yao
2015-12-17  3:01   ` Mark Yao
2015-12-17  3:01   ` Mark Yao
2015-12-17  3:01 ` [PATCH v3 3/8] drm/rockchip: Convert to support atomic API Mark Yao
2015-12-17  3:01   ` Mark Yao
2015-12-17  3:01   ` Mark Yao
2015-12-17  3:01 ` [PATCH v3 4/8] drm/rockchip: Optimization vop mode set Mark Yao
2015-12-17  3:01   ` Mark Yao
2015-12-17  3:01   ` Mark Yao
2015-12-17  3:06 ` [PATCH v3 5/8] drm/rockchip: support atomic asynchronous commit Mark Yao
2015-12-17  3:06   ` Mark Yao
2015-12-17  3:06   ` Mark Yao
2015-12-17  3:08 ` [PATCH v3 6/8] drm/rockchip: direct config connecter gate and out_mode Mark Yao
2015-12-17  3:08   ` Mark Yao
2015-12-17  3:08   ` Mark Yao
2015-12-17  3:08   ` [PATCH v3 7/8] drm: bridge/dw_hdmi: add atomic API support Mark Yao
2015-12-17  3:08     ` Mark Yao
2015-12-17  3:08     ` Mark Yao
2015-12-17  3:15     ` Mark yao
2015-12-17  3:15       ` Mark yao
2015-12-17  3:15       ` Mark yao
2015-12-17  3:08   ` [PATCH 8/8] drm/rockchip: dw_hdmi: use encoder enable function Mark Yao
2015-12-17  3:08     ` Mark Yao
2015-12-17  3:08     ` Mark Yao
2015-12-17  3:16     ` Mark yao
2015-12-17  3:16       ` Mark yao
2015-12-17  3:16       ` Mark yao
2015-12-17  3:11 ` [PATCH v3 7/8] drm: bridge/dw_hdmi: add atomic API support Mark Yao
2015-12-17  3:11   ` Mark Yao
2015-12-17  3:11   ` Mark Yao
2015-12-17  3:13 ` [PATCH v3 8/8] drm/rockchip: dw_hdmi: use encoder enable function Mark Yao
2015-12-17  3:13   ` Mark Yao
2015-12-17 10:00 ` [PATCH v3 0/8] drm/rockchip: covert to support atomic API Heiko Stübner
2015-12-17 10:00   ` Heiko Stübner
2015-12-17 10:00   ` Heiko Stübner
2015-12-17 10:32   ` Mark yao
2015-12-17 10:32     ` Mark yao
2015-12-17 10:32     ` Mark yao
2015-12-17 12:03     ` Heiko Stübner
2015-12-17 12:03       ` Heiko Stübner
2015-12-17 12:03       ` Heiko Stübner
2015-12-17 14:27       ` Daniel Vetter
2015-12-17 14:27         ` Daniel Vetter
2015-12-17 14:27         ` Daniel Vetter
2015-12-21  2:28 ` Mark yao

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.