[PATCH 5/7] drm/i915: Move the BIOS FB intel_framebuffer_init() to the display code

Ville Syrjala <[email protected]>
Newsgroups org.freedesktop.lists.intel-gfx,org.freedesktop.lists.intel-xe
Organization Intel Finland Oy - BIC 0357606-4 - c/o Alberga Business Park, 6 krs Bertel Jungin Aukio 5, 02600 Espoo, Finland
Message-ID <[email protected]>
From: Ville Syrjälä <[email protected]>

Clean up the alloc_initial_plane_obj() interface by moving all
framebuffer stuff to the display side, and just pass the actual
gem object from the i915/xe code.

The xe_bo_create_pin_map_at_novm() disaster does require us to
introduce a new .free_obj() parent interface hook so that if the
FB init fail we can undo all the things that
xe_bo_create_pin_map_at_novm() did earlier. Once the framebuffer
has been initialized xe_display_bo_framebuffer_fini() is supposed
to take care of this cleanup. Although I think this is still
completely broken if intel_framebuffer_init() fails late enough
that it itself calls intel_bo_framebuffer_fini(). In that case
we'll end up doing the same cleanup twice, and I expect explosions.
The proper fix for this mess would be to either nuke
xe_bo_create_pin_map_at_novm() and do things in a more sane way,
or keep xe_bo_create_pin_map_at_novm() but have it construct
a special bo that does the appropriate cleanup from its own
.destroy() hook.

Signed-off-by: Ville Syrjälä <[email protected]>
---
 .../drm/i915/display/intel_display_types.h    |  1 -
 .../drm/i915/display/intel_initial_plane.c    | 43 ++++++++++-----
 drivers/gpu/drm/i915/i915_initial_plane.c     | 52 ++++--------------
 drivers/gpu/drm/xe/display/xe_initial_plane.c | 54 ++++---------------
 include/drm/intel/display_parent_interface.h  |  2 +-
 5 files changed, 51 insertions(+), 101 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index 17336ad6d5e9..8772acfe4847 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -761,7 +761,6 @@ struct intel_plane_state {
 
 struct intel_initial_plane_config {
 	struct drm_framebuffer *fb;
-	struct i915_vma *vma;
 	int size;
 	u32 base;
 	u8 rotation;
diff --git a/drivers/gpu/drm/i915/display/intel_initial_plane.c b/drivers/gpu/drm/i915/display/intel_initial_plane.c
index 67e4bbbd0d6a..40afb3172cd1 100644
--- a/drivers/gpu/drm/i915/display/intel_initial_plane.c
+++ b/drivers/gpu/drm/i915/display/intel_initial_plane.c
@@ -4,6 +4,7 @@
 #include <linux/iopoll.h>
 
 #include <drm/drm_blend.h>
+#include <drm/drm_gem.h>
 #include <drm/drm_print.h>
 #include <drm/intel/display_parent_interface.h>
 
@@ -67,11 +68,20 @@ intel_reuse_initial_plane_fb(struct intel_crtc *this,
 	return NULL;
 }
 
-static struct drm_gem_object *
-intel_alloc_initial_plane_obj(struct intel_display *display,
-			      struct intel_initial_plane_config *plane_config)
+static struct drm_framebuffer *
+intel_alloc_initial_plane_fb(struct intel_display *display,
+			     struct intel_initial_plane_config *plane_config)
 {
 	struct drm_framebuffer *fb = plane_config->fb;
+	struct drm_mode_fb_cmd2 mode_cmd = {
+		.pixel_format = fb->format->format,
+		.width = fb->width,
+		.height = fb->height,
+		.pitches[0] = fb->pitches[0],
+		.modifier[0] = fb->modifier,
+		.flags = DRM_MODE_FB_MODIFIERS,
+	};
+	struct drm_gem_object *obj;
 
 	switch (fb->modifier) {
 	case DRM_FORMAT_MOD_LINEAR:
@@ -106,7 +116,20 @@ intel_alloc_initial_plane_obj(struct intel_display *display,
 		return NULL;
 	}
 
-	return display->parent->initial_plane->alloc_obj(display->drm, plane_config);
+	obj = display->parent->initial_plane->alloc_obj(display->drm, plane_config);
+	if (!obj)
+		return NULL;
+
+	if (intel_framebuffer_init(to_intel_framebuffer(fb), obj,
+				   fb->format, &mode_cmd)) {
+		display->parent->initial_plane->free_obj(obj);
+		drm_dbg_kms(display->drm, "initial FB init failed\n");
+		return NULL;
+	}
+
+	drm_gem_object_put(obj);
+
+	return fb;
 }
 
 static void
@@ -127,13 +150,11 @@ intel_find_initial_plane_obj(struct intel_crtc *crtc,
 	if (!plane_config->fb)
 		goto nofb;
 
-	if (intel_alloc_initial_plane_obj(display, plane_config)) {
-		fb = plane_config->fb;
-	} else {
+	fb = intel_alloc_initial_plane_fb(display, plane_config);
+	if (!fb)
 		fb = intel_reuse_initial_plane_fb(crtc, all_plane_configs);
-		if (!fb)
-			goto nofb;
-	}
+	if (!fb)
+		goto nofb;
 
 	plane_state->uapi.rotation = plane_config->rotation;
 	intel_fb_fill_view(to_intel_framebuffer(fb),
@@ -189,8 +210,6 @@ static void plane_config_fini(struct intel_display *display,
 
 		plane_config->fb = NULL;
 	}
-
-	display->parent->initial_plane->config_fini(plane_config);
 }
 
 void intel_initial_plane_config(struct intel_display *display)
diff --git a/drivers/gpu/drm/i915/i915_initial_plane.c b/drivers/gpu/drm/i915/i915_initial_plane.c
index bd5fd11fdc49..bbe5960b1b14 100644
--- a/drivers/gpu/drm/i915/i915_initial_plane.c
+++ b/drivers/gpu/drm/i915/i915_initial_plane.c
@@ -78,10 +78,11 @@ initial_plane_phys(struct drm_i915_private *i915,
 	return true;
 }
 
-static struct i915_vma *
-initial_plane_vma(struct drm_i915_private *i915,
-		  struct intel_initial_plane_config *plane_config)
+static struct drm_gem_object *
+i915_alloc_initial_plane_obj(struct drm_device *drm,
+			     struct intel_initial_plane_config *plane_config)
 {
+	struct drm_i915_private *i915 = to_i915(drm);
 	struct intel_memory_region *mem;
 	struct drm_i915_gem_object *obj;
 	struct drm_mm_node orig_mm = {};
@@ -203,7 +204,7 @@ initial_plane_vma(struct drm_i915_private *i915,
 		    "Initial plane fb bound to 0x%x in the ggtt (original 0x%x)\n",
 		    i915_ggtt_offset(vma), plane_config->base);
 
-	return vma;
+	return &obj->base;
 
 err_obj:
 	if (drm_mm_node_allocated(&orig_mm))
@@ -212,39 +213,10 @@ initial_plane_vma(struct drm_i915_private *i915,
 	return NULL;
 }
 
-static struct drm_gem_object *
-i915_alloc_initial_plane_obj(struct drm_device *drm,
-			     struct intel_initial_plane_config *plane_config)
+static void
+i915_free_initial_plane_obj(struct drm_gem_object *obj)
 {
-	struct drm_i915_private *i915 = to_i915(drm);
-	struct drm_mode_fb_cmd2 mode_cmd = {};
-	struct drm_framebuffer *fb = plane_config->fb;
-	struct i915_vma *vma;
-
-	vma = initial_plane_vma(i915, plane_config);
-	if (!vma)
-		return NULL;
-
-	mode_cmd.pixel_format = fb->format->format;
-	mode_cmd.width = fb->width;
-	mode_cmd.height = fb->height;
-	mode_cmd.pitches[0] = fb->pitches[0];
-	mode_cmd.modifier[0] = fb->modifier;
-	mode_cmd.flags = DRM_MODE_FB_MODIFIERS;
-
-	if (intel_framebuffer_init(to_intel_framebuffer(fb),
-				   intel_bo_to_drm_bo(vma->obj),
-				   fb->format, &mode_cmd)) {
-		drm_dbg_kms(&i915->drm, "intel fb init failed\n");
-		goto err_vma;
-	}
-
-	plane_config->vma = vma;
-	return intel_bo_to_drm_bo(vma->obj);
-
-err_vma:
-	i915_vma_put(vma);
-	return NULL;
+	drm_gem_object_put(obj);
 }
 
 static int
@@ -275,14 +247,8 @@ i915_initial_plane_setup(struct drm_plane_state *_plane_state,
 	return 0;
 }
 
-static void i915_plane_config_fini(struct intel_initial_plane_config *plane_config)
-{
-	if (plane_config->vma)
-		i915_vma_put(plane_config->vma);
-}
-
 const struct intel_display_initial_plane_interface i915_display_initial_plane_interface = {
 	.alloc_obj = i915_alloc_initial_plane_obj,
+	.free_obj = i915_free_initial_plane_obj,
 	.setup = i915_initial_plane_setup,
-	.config_fini = i915_plane_config_fini,
 };
diff --git a/drivers/gpu/drm/xe/display/xe_initial_plane.c b/drivers/gpu/drm/xe/display/xe_initial_plane.c
index 1aff8a8304b0..d45ad2ba418c 100644
--- a/drivers/gpu/drm/xe/display/xe_initial_plane.c
+++ b/drivers/gpu/drm/xe/display/xe_initial_plane.c
@@ -37,10 +37,11 @@ static bool need_pte_local(struct xe_device *xe)
 	return IS_DGFX(xe) || has_lmembar(xe);
 }
 
-static struct xe_bo *
-initial_plane_bo(struct xe_device *xe,
-		 struct intel_initial_plane_config *plane_config)
+static struct drm_gem_object *
+xe_alloc_initial_plane_obj(struct drm_device *drm,
+			   struct intel_initial_plane_config *plane_config)
 {
+	struct xe_device *xe = to_xe_device(drm);
 	struct xe_tile *tile0 = xe_device_get_root_tile(xe);
 	struct xe_bo *bo;
 	resource_size_t phys_base;
@@ -120,42 +121,13 @@ initial_plane_bo(struct xe_device *xe,
 		return NULL;
 	}
 
-	return bo;
-}
-
-static struct drm_gem_object *
-xe_alloc_initial_plane_obj(struct drm_device *drm,
-			   struct intel_initial_plane_config *plane_config)
-{
-	struct xe_device *xe = to_xe_device(drm);
-	struct drm_mode_fb_cmd2 mode_cmd = { 0 };
-	struct drm_framebuffer *fb = plane_config->fb;
-	struct xe_bo *bo;
-
-	mode_cmd.pixel_format = fb->format->format;
-	mode_cmd.width = fb->width;
-	mode_cmd.height = fb->height;
-	mode_cmd.pitches[0] = fb->pitches[0];
-	mode_cmd.modifier[0] = fb->modifier;
-	mode_cmd.flags = DRM_MODE_FB_MODIFIERS;
-
-	bo = initial_plane_bo(xe, plane_config);
-	if (!bo)
-		return NULL;
-
-	if (intel_framebuffer_init(to_intel_framebuffer(fb),
-				   &bo->ttm.base, fb->format, &mode_cmd)) {
-		drm_dbg_kms(&xe->drm, "intel fb init failed\n");
-		goto err_bo;
-	}
-	/* Reference handed over to fb */
-	xe_bo_put(bo);
-
 	return &bo->ttm.base;
+}
 
-err_bo:
-	xe_bo_unpin_map_no_vm(bo);
-	return NULL;
+static void
+xe_free_initial_plane_obj(struct drm_gem_object *obj)
+{
+	xe_bo_unpin_map_no_vm(gem_to_xe_bo(obj));
 }
 
 static int
@@ -179,17 +151,11 @@ xe_initial_plane_setup(struct drm_plane_state *_plane_state,
 
 	plane_state->surf = offset;
 
-	plane_config->vma = vma;
-
 	return 0;
 }
 
-static void xe_plane_config_fini(struct intel_initial_plane_config *plane_config)
-{
-}
-
 const struct intel_display_initial_plane_interface xe_display_initial_plane_interface = {
 	.alloc_obj = xe_alloc_initial_plane_obj,
+	.free_obj = xe_free_initial_plane_obj,
 	.setup = xe_initial_plane_setup,
-	.config_fini = xe_plane_config_fini,
 };
diff --git a/include/drm/intel/display_parent_interface.h b/include/drm/intel/display_parent_interface.h
index 26aed8878b16..173c01d41385 100644
--- a/include/drm/intel/display_parent_interface.h
+++ b/include/drm/intel/display_parent_interface.h
@@ -126,9 +126,9 @@ struct intel_display_hdcp_interface {
 
 struct intel_display_initial_plane_interface {
 	struct drm_gem_object *(*alloc_obj)(struct drm_device *drm, struct intel_initial_plane_config *plane_config);
+	void (*free_obj)(struct drm_gem_object *obj);
 	int (*setup)(struct drm_plane_state *plane_state, struct intel_initial_plane_config *plane_config,
 		     struct drm_framebuffer *fb);
-	void (*config_fini)(struct intel_initial_plane_config *plane_config);
 };
 
 struct intel_display_irq_interface {
-- 
2.54.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.