The core provides now an ABI to userspace for generation of frame CRCs,
so implement the ->set_crc_source() callback and reuse as much code as
possible with the previous ABI implementation.

v2:
    - Leave the legacy implementation in place as the ABI implementation
      in the core is incompatible with it.

Signed-off-by: Tomeu Vizoso <tomeu.vizoso at collabora.com>
---

 drivers/gpu/drm/i915/i915_irq.c       | 57 ++++++++++++++++++++---------------
 drivers/gpu/drm/i915/intel_display.c  |  1 +
 drivers/gpu/drm/i915/intel_drv.h      |  1 +
 drivers/gpu/drm/i915/intel_pipe_crc.c | 17 +++++++++++
 4 files changed, 51 insertions(+), 25 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index b77d808b71cd..1c5c6bdbb66c 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -1492,41 +1492,48 @@ static void display_pipe_crc_irq_handler(struct 
drm_i915_private *dev_priv,
 {
        struct intel_pipe_crc *pipe_crc = &dev_priv->pipe_crc[pipe];
        struct intel_pipe_crc_entry *entry;
+       struct drm_crtc *crtc = intel_get_crtc_for_pipe(&dev_priv->drm, pipe);
+       struct drm_driver *driver = dev_priv->drm.driver;
+       uint32_t frame = driver->get_vblank_counter(&dev_priv->drm, pipe);
        int head, tail;

-       spin_lock(&pipe_crc->lock);
+       if (pipe_crc->opened) {
+               spin_lock(&pipe_crc->lock);

-       if (!pipe_crc->entries) {
-               spin_unlock(&pipe_crc->lock);
-               DRM_DEBUG_KMS("spurious interrupt\n");
-               return;
-       }
+               if (!pipe_crc->entries) {
+                       spin_unlock(&pipe_crc->lock);
+                       DRM_DEBUG_KMS("spurious interrupt\n");
+                       return;
+               }

-       head = pipe_crc->head;
-       tail = pipe_crc->tail;
+               head = pipe_crc->head;
+               tail = pipe_crc->tail;

-       if (CIRC_SPACE(head, tail, INTEL_PIPE_CRC_ENTRIES_NR) < 1) {
-               spin_unlock(&pipe_crc->lock);
-               DRM_ERROR("CRC buffer overflowing\n");
-               return;
-       }
+               if (CIRC_SPACE(head, tail, INTEL_PIPE_CRC_ENTRIES_NR) < 1) {
+                       spin_unlock(&pipe_crc->lock);
+                       DRM_ERROR("CRC buffer overflowing\n");
+                       return;
+               }

-       entry = &pipe_crc->entries[head];
+               entry = &pipe_crc->entries[head];

-       entry->frame = dev_priv->drm.driver->get_vblank_counter(&dev_priv->drm,
-                                                                pipe);
-       entry->crc[0] = crc0;
-       entry->crc[1] = crc1;
-       entry->crc[2] = crc2;
-       entry->crc[3] = crc3;
-       entry->crc[4] = crc4;
+               entry->frame = frame;
+               entry->crc[0] = crc0;
+               entry->crc[1] = crc1;
+               entry->crc[2] = crc2;
+               entry->crc[3] = crc3;
+               entry->crc[4] = crc4;

-       head = (head + 1) & (INTEL_PIPE_CRC_ENTRIES_NR - 1);
-       pipe_crc->head = head;
+               head = (head + 1) & (INTEL_PIPE_CRC_ENTRIES_NR - 1);
+               pipe_crc->head = head;

-       spin_unlock(&pipe_crc->lock);
+               spin_unlock(&pipe_crc->lock);

-       wake_up_interruptible(&pipe_crc->wq);
+               wake_up_interruptible(&pipe_crc->wq);
+       } else {
+               drm_crtc_add_crc_entry(crtc, frame, crc0, crc1, crc2, crc3,
+                                      crc4);
+       }
 }
 #else
 static inline void
diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index 111b350d1d7e..d91a2f779fb1 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -14019,6 +14019,7 @@ static const struct drm_crtc_funcs intel_crtc_funcs = {
        .page_flip = intel_crtc_page_flip,
        .atomic_duplicate_state = intel_crtc_duplicate_state,
        .atomic_destroy_state = intel_crtc_destroy_state,
+       .set_crc_source = intel_crtc_set_crc_source,
 };

 /**
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 5d06cb2425a1..4cd8689afe90 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1782,6 +1782,7 @@ void intel_color_load_luts(struct drm_crtc_state 
*crtc_state);
 /* intel_pipe_crc.c */
 int intel_pipe_crc_create(struct drm_minor *minor);
 void intel_pipe_crc_cleanup(struct drm_minor *minor);
+int intel_crtc_set_crc_source(struct drm_crtc *crtc, const char *source_name);
 extern const struct file_operations i915_display_crc_ctl_fops;

 #endif /* __INTEL_DRV_H__ */
diff --git a/drivers/gpu/drm/i915/intel_pipe_crc.c 
b/drivers/gpu/drm/i915/intel_pipe_crc.c
index 590e909bcf1b..51047ad37ffa 100644
--- a/drivers/gpu/drm/i915/intel_pipe_crc.c
+++ b/drivers/gpu/drm/i915/intel_pipe_crc.c
@@ -823,6 +823,11 @@ display_crc_ctl_parse_source(const char *buf, enum 
intel_pipe_crc_source *s)
 {
        int i;

+       if (!buf) {
+               *s = INTEL_PIPE_CRC_SOURCE_NONE;
+               return 0;
+       }
+
        for (i = 0; i < ARRAY_SIZE(pipe_crc_sources); i++)
                if (!strcmp(buf, pipe_crc_sources[i])) {
                        *s = i;
@@ -951,3 +956,15 @@ void intel_pipe_crc_cleanup(struct drm_minor *minor)
                drm_debugfs_remove_files(info_list, 1, minor);
        }
 }
+
+int intel_crtc_set_crc_source(struct drm_crtc *crtc, const char *source_name)
+{
+       enum intel_pipe_crc_source source;
+
+       if (display_crc_ctl_parse_source(source_name, &source) < 0) {
+               DRM_DEBUG_DRIVER("unknown source %s\n", source_name);
+               return -EINVAL;
+       }
+
+       return pipe_crc_set_source(crtc->dev, crtc->index, source);
+}
-- 
2.5.5

Reply via email to