Define function for prepare and cleanup hooks which help map
and unmap drm framebuffer since we need these address to do
register writes in WD_SURF and WD_STRIDE register.

Signed-off-by: Suraj Kandpal <suraj.kand...@intel.com>
---
 .../gpu/drm/i915/display/intel_writeback.c    | 68 +++++++++++++++++++
 1 file changed, 68 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_writeback.c 
b/drivers/gpu/drm/i915/display/intel_writeback.c
index 8d24b1ee0a2a..f1570a638422 100644
--- a/drivers/gpu/drm/i915/display/intel_writeback.c
+++ b/drivers/gpu/drm/i915/display/intel_writeback.c
@@ -4,6 +4,7 @@
  */
 
 #include <linux/slab.h>
+#include <linux/err.h>
 #include <drm/drm_atomic_state_helper.h>
 #include <drm/drm_writeback.h>
 #include <drm/drm_modeset_helper_vtables.h>
@@ -11,13 +12,16 @@
 #include <drm/drm_fourcc.h>
 #include <drm/drm_encoder.h>
 #include <drm/drm_edid.h>
+#include <drm/drm_gem_framebuffer_helper.h>
 
 #include "i915_drv.h"
+#include "i915_vma.h"
 #include "intel_atomic.h"
 #include "intel_de.h"
 #include "intel_display_types.h"
 #include "intel_display_driver.h"
 #include "intel_connector.h"
+#include "intel_fb_pin.h"
 #include "intel_writeback.h"
 #include "intel_writeback_reg.h"
 
@@ -107,6 +111,68 @@ static int intel_writeback_get_modes(struct drm_connector 
*connector)
        return drm_add_modes_noedid(connector, 3840, 2160);
 }
 
+static int intel_writeback_prepare_job(struct drm_writeback_connector 
*wb_connector,
+                                      struct drm_writeback_job *job)
+{
+       struct intel_writeback_connector *wb_conn =
+               to_intel_writeback_connector(wb_connector);
+       struct i915_vma *vma;
+       struct intel_writeback_job *wb_job;
+       unsigned long out_flags = 0;
+       const struct i915_gtt_view view = {
+               .type = I915_GTT_VIEW_NORMAL,
+       };
+       int ret;
+
+       if (!job->fb)
+               return 0;
+
+       if (job->fb->modifier != DRM_FORMAT_MOD_LINEAR)
+               return -EINVAL;
+
+       wb_job = kzalloc(sizeof(*wb_job), GFP_KERNEL);
+       if (!wb_job)
+               return -ENOMEM;
+
+       vma = intel_fb_pin_to_ggtt(job->fb, &view, 4 * 1024, 0, 0, true, 
&out_flags);
+       if (IS_ERR(vma)) {
+               drm_err(job->fb->dev, "Failed to map framebuffer: %d\n", ret);
+               ret = PTR_ERR(vma);
+               goto err;
+       }
+
+       wb_job->fb = job->fb;
+       wb_job->vma = vma;
+       wb_job->wb_connector = wb_connector;
+       drm_framebuffer_get(wb_job->fb);
+       job->priv = wb_job;
+       wb_conn->job = wb_job;
+
+       return 0;
+
+err:
+       kfree(wb_job);
+       return ret;
+}
+
+static void intel_writeback_cleanup_job(struct drm_writeback_connector 
*connector,
+                                       struct drm_writeback_job *job)
+{
+       struct intel_writeback_job *wb_job = job->priv;
+       struct i915_vma *vma;
+       unsigned long out_flags = 0;
+
+       if (!job->fb)
+               return;
+
+       vma = wb_job->vma;
+       wb_job->vma = NULL;
+       intel_fb_unpin_vma(vma, out_flags);
+       drm_framebuffer_put(wb_job->fb);
+       kfree(wb_job);
+       job->priv = NULL;
+}
+
 static struct drm_writeback_connector *
 intel_get_writeback_connector(struct drm_connector *connector)
 {
@@ -140,6 +206,8 @@ static const struct drm_connector_helper_funcs 
conn_helper_funcs = {
        .get_writeback_connector = intel_get_writeback_connector,
        .get_modes = intel_writeback_get_modes,
        .mode_valid = intel_writeback_mode_valid,
+       .prepare_writeback_job = intel_writeback_prepare_job,
+       .cleanup_writeback_job = intel_writeback_cleanup_job,
 };
 
 static const struct drm_writeback_connector_helper_funcs 
writeback_conn_helper_funcs = {
-- 
2.34.1

Reply via email to