# Base git commit: 2dcd0af568b0
# (Linux 4.6)
# 
# Author:    Russell King (Mon 25 Jul 15:16:11 BST 2016)
# Committer: Russell King (Mon  8 Aug 09:56:12 BST 2016)
# 
#   drm/armada: clean up armada_drm_plane_work_run()
# 
#   Make armada_drm_plane_work_run() take the drm_plane pointer rather than
#   our private pointer.  This allows us to localise the conversion between
#   these two pointers inside armada_drm_plane_work_run(), rather than at
#   every call site.
# 
#   Signed-off-by: Russell King
# 
#   f03ab59625c40fa919ed520740d54319aa1dac4a
#    drivers/gpu/drm/armada/armada_crtc.c | 27 +++++++++++----------------
#    1 file changed, 11 insertions(+), 16 deletions(-)
# 
# Author:    Russell King (Tue 17 May 13:51:08 BST 2016)
# Committer: Russell King (Mon  8 Aug 09:53:37 BST 2016)
# 
#   drm/armada: add tracing support
# 
#   Add tracing support to the Armada video overlay and interrupt code.
# 
#   Signed-off-by: Russell King
# 
#   1f86659bb91dd7da33fb644a619473d6c53a753f
#    drivers/gpu/drm/armada/Makefile         |  2 +-
#    drivers/gpu/drm/armada/armada_crtc.c    |  3 ++
#    drivers/gpu/drm/armada/armada_overlay.c |  7 ++++
#    drivers/gpu/drm/armada/armada_trace.c   |  4 ++
#    drivers/gpu/drm/armada/armada_trace.h   | 66 +++++++++++++++++++++++++++++++++
#    5 files changed, 81 insertions(+), 1 deletion(-)
#    create mode 100644 drivers/gpu/drm/armada/armada_trace.c
#    create mode 100644 drivers/gpu/drm/armada/armada_trace.h
# 
# Author:    Gustavo Padovan (Tue  5 Jul 01:04:48 BST 2016)
# Committer: Russell King (Wed  6 Jul 11:28:51 BST 2016)
# 
#   drm/armada: use drm_crtc_handle_vblank()
# 
#   Remove legacy usage of drm_handle_vblank()
# 
#   Signed-off-by: Gustavo Padovan
#   Signed-off-by: Russell King
# 
#   a3d23918633f65121fe943ea2a04e2f1ac64fcb1
#    drivers/gpu/drm/armada/armada_crtc.c | 2 +-
#    1 file changed, 1 insertion(+), 1 deletion(-)
# 
diff --git a/drivers/gpu/drm/armada/Makefile b/drivers/gpu/drm/armada/Makefile
index ffd673615772..a18f156c8b66 100644
--- a/drivers/gpu/drm/armada/Makefile
+++ b/drivers/gpu/drm/armada/Makefile
@@ -1,5 +1,5 @@
 armada-y	:= armada_crtc.o armada_drv.o armada_fb.o armada_fbdev.o \
-		   armada_gem.o armada_overlay.o
+		   armada_gem.o armada_overlay.o armada_trace.o
 armada-y	+= armada_510.o
 armada-$(CONFIG_DEBUG_FS) += armada_debugfs.o
 
diff --git a/drivers/gpu/drm/armada/armada_crtc.c b/drivers/gpu/drm/armada/armada_crtc.c
index 0293eb74d777..df4807fb9623 100644
--- a/drivers/gpu/drm/armada/armada_crtc.c
+++ b/drivers/gpu/drm/armada/armada_crtc.c
@@ -18,6 +18,7 @@
 #include "armada_fb.h"
 #include "armada_gem.h"
 #include "armada_hw.h"
+#include "armada_trace.h"
 
 struct armada_frame_work {
 	struct armada_plane_work work;
@@ -192,17 +193,18 @@ static unsigned armada_drm_crtc_calc_fb(struct drm_framebuffer *fb,
 }
 
 static void armada_drm_plane_work_run(struct armada_crtc *dcrtc,
-	struct armada_plane *plane)
+	struct drm_plane *plane)
 {
-	struct armada_plane_work *work = xchg(&plane->work, NULL);
+	struct armada_plane *dplane = drm_to_armada_plane(plane);
+	struct armada_plane_work *work = xchg(&dplane->work, NULL);
 
 	/* Handle any pending frame work. */
 	if (work) {
-		work->fn(dcrtc, plane, work);
+		work->fn(dcrtc, dplane, work);
 		drm_vblank_put(dcrtc->crtc.dev, dcrtc->num);
 	}
 
-	wake_up(&plane->frame_wait);
+	wake_up(&dplane->frame_wait);
 }
 
 int armada_drm_plane_work_queue(struct armada_crtc *dcrtc,
@@ -307,14 +309,12 @@ static void armada_drm_crtc_finish_fb(struct armada_crtc *dcrtc,
 
 static void armada_drm_vblank_off(struct armada_crtc *dcrtc)
 {
-	struct armada_plane *plane = drm_to_armada_plane(dcrtc->crtc.primary);
-
 	/*
 	 * Tell the DRM core that vblank IRQs aren't going to happen for
 	 * a while.  This cleans up any pending vblank events for us.
 	 */
 	drm_crtc_vblank_off(&dcrtc->crtc);
-	armada_drm_plane_work_run(dcrtc, plane);
+	armada_drm_plane_work_run(dcrtc, dcrtc->crtc.primary);
 }
 
 void armada_drm_crtc_gamma_set(struct drm_crtc *crtc, u16 r, u16 g, u16 b,
@@ -410,14 +410,12 @@ static void armada_drm_crtc_irq(struct armada_crtc *dcrtc, u32 stat)
 		DRM_ERROR("graphics underflow on crtc %u\n", dcrtc->num);
 
 	if (stat & VSYNC_IRQ)
-		drm_handle_vblank(dcrtc->crtc.dev, dcrtc->num);
+		drm_crtc_handle_vblank(&dcrtc->crtc);
 
 	spin_lock(&dcrtc->irq_lock);
 	ovl_plane = dcrtc->plane;
-	if (ovl_plane) {
-		struct armada_plane *plane = drm_to_armada_plane(ovl_plane);
-		armada_drm_plane_work_run(dcrtc, plane);
-	}
+	if (ovl_plane)
+		armada_drm_plane_work_run(dcrtc, ovl_plane);
 
 	if (stat & GRA_FRAME_IRQ && dcrtc->interlaced) {
 		int i = stat & GRA_FRAME_IRQ0 ? 0 : 1;
@@ -447,10 +445,8 @@ static void armada_drm_crtc_irq(struct armada_crtc *dcrtc, u32 stat)
 
 	spin_unlock(&dcrtc->irq_lock);
 
-	if (stat & GRA_FRAME_IRQ) {
-		struct armada_plane *plane = drm_to_armada_plane(dcrtc->crtc.primary);
-		armada_drm_plane_work_run(dcrtc, plane);
-	}
+	if (stat & GRA_FRAME_IRQ)
+		armada_drm_plane_work_run(dcrtc, dcrtc->crtc.primary);
 }
 
 static irqreturn_t armada_drm_irq(int irq, void *arg)
@@ -464,6 +460,8 @@ static irqreturn_t armada_drm_irq(int irq, void *arg)
 	 */
 	writel_relaxed(0, dcrtc->base + LCD_SPU_IRQ_ISR);
 
+	trace_armada_drm_irq(&dcrtc->crtc, stat);
+
 	/* Mask out those interrupts we haven't enabled */
 	v = stat & dcrtc->irq_ena;
 
@@ -1037,7 +1035,7 @@ static int armada_drm_crtc_page_flip(struct drm_crtc *crtc,
 	 * interrupt, so complete it now.
 	 */
 	if (dpms_blanked(dcrtc->dpms))
-		armada_drm_plane_work_run(dcrtc, drm_to_armada_plane(dcrtc->crtc.primary));
+		armada_drm_plane_work_run(dcrtc, dcrtc->crtc.primary);
 
 	return 0;
 }
diff --git a/drivers/gpu/drm/armada/armada_overlay.c b/drivers/gpu/drm/armada/armada_overlay.c
index 148e8a42b2c6..7ba8db01fbe1 100644
--- a/drivers/gpu/drm/armada/armada_overlay.c
+++ b/drivers/gpu/drm/armada/armada_overlay.c
@@ -15,6 +15,7 @@
 #include "armada_hw.h"
 #include <drm/armada_drm.h>
 #include "armada_ioctlP.h"
+#include "armada_trace.h"
 
 struct armada_ovl_plane_properties {
 	uint32_t colorkey_yr;
@@ -87,6 +88,8 @@ static void armada_ovl_plane_work(struct armada_crtc *dcrtc,
 {
 	struct armada_ovl_plane *dplane = container_of(plane, struct armada_ovl_plane, base);
 
+	trace_armada_ovl_plane_work(&dcrtc->crtc, &plane->base);
+
 	armada_drm_crtc_update_regs(dcrtc, dplane->vbl.regs);
 	armada_ovl_retire_fb(dplane, NULL);
 }
@@ -120,6 +123,10 @@ armada_ovl_plane_update(struct drm_plane *plane, struct drm_crtc *crtc,
 	bool visible;
 	int ret;
 
+	trace_armada_ovl_plane_update(plane, crtc, fb,
+				 crtc_x, crtc_y, crtc_w, crtc_h,
+				 src_x, src_y, src_w, src_h);
+
 	ret = drm_plane_helper_check_update(plane, crtc, fb, &src, &dest, &clip,
 					    0, INT_MAX, true, false, &visible);
 	if (ret)
diff --git a/drivers/gpu/drm/armada/armada_trace.c b/drivers/gpu/drm/armada/armada_trace.c
new file mode 100644
index 000000000000..068b336ba75f
--- /dev/null
+++ b/drivers/gpu/drm/armada/armada_trace.c
@@ -0,0 +1,4 @@
+#ifndef __CHECKER__
+#define CREATE_TRACE_POINTS
+#include "armada_trace.h"
+#endif
diff --git a/drivers/gpu/drm/armada/armada_trace.h b/drivers/gpu/drm/armada/armada_trace.h
new file mode 100644
index 000000000000..dc0cba70fd1a
--- /dev/null
+++ b/drivers/gpu/drm/armada/armada_trace.h
@@ -0,0 +1,66 @@
+#if !defined(ARMADA_TRACE_H) || defined(TRACE_HEADER_MULTI_READ)
+#define ARMADA_TRACE_H
+
+#include <linux/tracepoint.h>
+#include <drm/drmP.h>
+
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM armada
+#define TRACE_INCLUDE_FILE armada_trace
+
+TRACE_EVENT(armada_drm_irq,
+	TP_PROTO(struct drm_crtc *crtc, u32 stat),
+	TP_ARGS(crtc, stat),
+	TP_STRUCT__entry(
+		__field(struct drm_crtc *, crtc)
+		__field(u32, stat)
+	),
+	TP_fast_assign(
+		__entry->crtc = crtc;
+		__entry->stat = stat;
+	),
+	TP_printk("crtc %p stat 0x%08x",
+		__entry->crtc, __entry->stat)
+);
+
+TRACE_EVENT(armada_ovl_plane_update,
+	TP_PROTO(struct drm_plane *plane, struct drm_crtc *crtc,
+		     struct drm_framebuffer *fb,
+		     int crtc_x, int crtc_y, unsigned crtc_w, unsigned crtc_h,
+		     uint32_t src_x, uint32_t src_y, uint32_t src_w, uint32_t src_h),
+	TP_ARGS(plane, crtc, fb, crtc_x, crtc_y, crtc_w, crtc_h, src_x, src_y, src_w, src_h),
+	TP_STRUCT__entry(
+		__field(struct drm_plane *, plane)
+		__field(struct drm_crtc *, crtc)
+		__field(struct drm_framebuffer *, fb)
+	),
+	TP_fast_assign(
+		__entry->plane = plane;
+		__entry->crtc = crtc;
+		__entry->fb = fb;
+	),
+	TP_printk("plane %p crtc %p fb %p",
+		__entry->plane, __entry->crtc, __entry->fb)
+);
+
+TRACE_EVENT(armada_ovl_plane_work,
+	TP_PROTO(struct drm_crtc *crtc, struct drm_plane *plane),
+	TP_ARGS(crtc, plane),
+	TP_STRUCT__entry(
+		__field(struct drm_plane *, plane)
+		__field(struct drm_crtc *, crtc)
+	),
+	TP_fast_assign(
+		__entry->plane = plane;
+		__entry->crtc = crtc;
+	),
+	TP_printk("plane %p crtc %p",
+		__entry->plane, __entry->crtc)
+);
+
+#endif
+
+/* This part must be outside protection */
+#undef TRACE_INCLUDE_PATH
+#define TRACE_INCLUDE_PATH .
+#include <trace/define_trace.h>
