@@ -8,6 +8,7 @@
#include "intel_dpt.h"
#include "intel_fb.h"
#include "intel_fb_pin.h"
+#include "xe_fb_pin.h"
#include "xe_ggtt.h"
#include "xe_gt.h"
@@ -119,12 +120,11 @@ static void xe_fb_dpt_free(struct i915_vma *vma, struct intel_framebuffer *fb)
vma->dpt = NULL;
}
-static int xe_fb_dpt_map_ggtt(struct xe_bo *dpt)
+static int xe_fb_dpt_map_ggtt(struct xe_bo *dpt, u64 ggtt_start)
{
struct xe_device *xe = xe_bo_device(dpt);
struct xe_tile *tile0 = xe_device_get_root_tile(xe);
struct xe_ggtt *ggtt = tile0->mem.ggtt;
- u64 start = 0, end = U64_MAX;
u64 alignment = XE_PAGE_SIZE;
int err;
@@ -139,8 +139,9 @@ static int xe_fb_dpt_map_ggtt(struct xe_bo *dpt)
if (err)
goto out_put;
- err = drm_mm_insert_node_in_range(&ggtt->mm, &dpt->ggtt_node, dpt->size,
- alignment, 0, start, end, 0);
+ err = xe_ggtt_insert_special_node_locked(ggtt, &dpt->ggtt_node, dpt->size,
+ alignment, ggtt_start, U64_MAX,
+ ggtt_start ? DRM_MM_INSERT_HIGH : 0);
if (!err)
xe_ggtt_map_bo(ggtt, dpt);
mutex_unlock(&ggtt->lock);
@@ -188,7 +189,7 @@ static void xe_fb_dpt_unpin_free(struct i915_vma *vma, struct intel_framebuffer
static int __xe_pin_fb_vma_dpt(struct intel_framebuffer *fb,
const struct i915_gtt_view *view,
- struct i915_vma *vma)
+ struct i915_vma *vma, u64 ggtt_start)
{
struct xe_device *xe = to_xe_device(fb->base.dev);
struct xe_tile *tile0 = xe_device_get_root_tile(xe);
@@ -237,7 +238,7 @@ static int __xe_pin_fb_vma_dpt(struct intel_framebuffer *fb,
rot_info->plane[i].dst_stride);
}
- ret = xe_fb_dpt_map_ggtt(dpt);
+ ret = xe_fb_dpt_map_ggtt(dpt, ggtt_start);
if (ret)
xe_fb_dpt_unpin_free(vma, fb);
return ret;
@@ -269,7 +270,7 @@ write_ggtt_rotated(struct xe_bo *bo, struct xe_ggtt *ggtt, u32 *ggtt_ofs, u32 bo
static int __xe_pin_fb_vma_ggtt(struct intel_framebuffer *fb,
const struct i915_gtt_view *view,
- struct i915_vma *vma)
+ struct i915_vma *vma, u64 ggtt_start)
{
struct xe_bo *bo = intel_fb_obj(&fb->base);
struct xe_device *xe = to_xe_device(fb->base.dev);
@@ -295,7 +296,8 @@ static int __xe_pin_fb_vma_ggtt(struct intel_framebuffer *fb,
u32 x, size = bo->ttm.base.size;
ret = xe_ggtt_insert_special_node_locked(ggtt, &vma->node, size,
- align, 0);
+ align, ggtt_start, U64_MAX,
+ ggtt_start ? DRM_MM_INSERT_HIGH : 0);
if (ret)
goto out_unlock;
@@ -313,7 +315,7 @@ static int __xe_pin_fb_vma_ggtt(struct intel_framebuffer *fb,
u32 size = intel_rotation_info_size(rot_info) * XE_PAGE_SIZE;
ret = xe_ggtt_insert_special_node_locked(ggtt, &vma->node, size,
- align, 0);
+ align, ggtt_start, U64_MAX, 0);
if (ret)
goto out_unlock;
@@ -336,7 +338,8 @@ static int __xe_pin_fb_vma_ggtt(struct intel_framebuffer *fb,
}
static struct i915_vma *__xe_pin_fb_vma(struct intel_framebuffer *fb,
- const struct i915_gtt_view *view)
+ const struct i915_gtt_view *view,
+ u64 ggtt_start)
{
struct drm_device *dev = fb->base.dev;
struct xe_device *xe = to_xe_device(dev);
@@ -384,9 +387,9 @@ static struct i915_vma *__xe_pin_fb_vma(struct intel_framebuffer *fb,
vma->bo = bo;
if (intel_fb_uses_dpt(&fb->base))
- ret = __xe_pin_fb_vma_dpt(fb, view, vma);
+ ret = __xe_pin_fb_vma_dpt(fb, view, vma, ggtt_start);
else
- ret = __xe_pin_fb_vma_ggtt(fb, view, vma);
+ ret = __xe_pin_fb_vma_ggtt(fb, view, vma, ggtt_start);
if (ret)
goto err_unpin;
@@ -430,7 +433,16 @@ intel_pin_and_fence_fb_obj(struct drm_framebuffer *fb,
{
*out_flags = 0;
- return __xe_pin_fb_vma(to_intel_framebuffer(fb), view);
+ return __xe_pin_fb_vma(to_intel_framebuffer(fb), view, 0);
+}
+
+
+struct i915_vma *
+xe_pin_and_fence_fb_obj_initial(struct drm_framebuffer *fb,
+ const struct i915_gtt_view *view,
+ u64 ggtt_start)
+{
+ return __xe_pin_fb_vma(to_intel_framebuffer(fb), view, ggtt_start);
}
void intel_unpin_fb_vma(struct i915_vma *vma, unsigned long flags)
@@ -447,7 +459,7 @@ int intel_plane_pin_fb(struct intel_plane_state *plane_state)
/* We reject creating !SCANOUT fb's, so this is weird.. */
drm_WARN_ON(bo->ttm.base.dev, !(bo->flags & XE_BO_FLAG_SCANOUT));
- vma = __xe_pin_fb_vma(to_intel_framebuffer(fb), &plane_state->view.gtt);
+ vma = __xe_pin_fb_vma(to_intel_framebuffer(fb), &plane_state->view.gtt, 0);
if (IS_ERR(vma))
return PTR_ERR(vma);
new file mode 100644
@@ -0,0 +1,20 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright © 2024 Intel Corporation
+ */
+
+#ifndef __XE_FB_PIN_H__
+#define __XE_FB_PIN_H__
+
+#include <linux/types.h>
+
+struct i915_vma;
+struct drm_framebuffer;
+struct i915_gtt_view;
+
+struct i915_vma *
+xe_pin_and_fence_fb_obj_initial(struct drm_framebuffer *fb,
+ const struct i915_gtt_view *view,
+ u64 ggtt_start);
+
+#endif
@@ -18,6 +18,7 @@
#include "intel_fb_pin.h"
#include "intel_frontbuffer.h"
#include "intel_plane_initial.h"
+#include "xe_fb_pin.h"
static bool
intel_reuse_initial_plane_obj(struct intel_crtc *this,
@@ -63,7 +64,7 @@ initial_plane_bo(struct xe_device *xe,
if (plane_config->size == 0)
return NULL;
- flags = XE_BO_FLAG_PINNED | XE_BO_FLAG_SCANOUT | XE_BO_FLAG_GGTT;
+ flags = XE_BO_FLAG_PINNED | XE_BO_FLAG_SCANOUT;
base = round_down(plane_config->base, page_size);
if (IS_DGFX(xe)) {
@@ -193,6 +194,7 @@ intel_find_initial_plane_obj(struct intel_crtc *crtc,
to_intel_crtc_state(crtc->base.state);
struct drm_framebuffer *fb;
struct i915_vma *vma;
+ u64 ggtt_start = 0;
/*
* TODO:
@@ -202,17 +204,20 @@ intel_find_initial_plane_obj(struct intel_crtc *crtc,
if (!plane_config->fb)
return;
- if (intel_alloc_initial_plane_obj(crtc, plane_config))
+ if (intel_alloc_initial_plane_obj(crtc, plane_config)) {
fb = &plane_config->fb->base;
- else if (!intel_reuse_initial_plane_obj(crtc, plane_configs, &fb))
+
+ /* Ensure that new GGTT mapping is not overwriting the original mapping */
+ ggtt_start = plane_config->base + intel_fb_obj(fb)->ttm.base.size;
+ } else if (!intel_reuse_initial_plane_obj(crtc, plane_configs, &fb)) {
goto nofb;
+ }
plane_state->uapi.rotation = plane_config->rotation;
intel_fb_fill_view(to_intel_framebuffer(fb),
plane_state->uapi.rotation, &plane_state->view);
- vma = intel_pin_and_fence_fb_obj(fb, false, &plane_state->view.gtt,
- false, &plane_state->flags);
+ vma = xe_pin_and_fence_fb_obj_initial(fb, &plane_state->view.gtt, ggtt_start);
if (IS_ERR(vma))
goto nofb;
@@ -354,23 +354,10 @@ void xe_ggtt_deballoon(struct xe_ggtt *ggtt, struct drm_mm_node *node)
}
int xe_ggtt_insert_special_node_locked(struct xe_ggtt *ggtt, struct drm_mm_node *node,
- u32 size, u32 align, u32 mm_flags)
+ u32 size, u32 align, u64 start, u64 end, u32 mm_flags)
{
- return drm_mm_insert_node_generic(&ggtt->mm, node, size, align, 0,
- mm_flags);
-}
-
-int xe_ggtt_insert_special_node(struct xe_ggtt *ggtt, struct drm_mm_node *node,
- u32 size, u32 align)
-{
- int ret;
-
- mutex_lock(&ggtt->lock);
- ret = xe_ggtt_insert_special_node_locked(ggtt, node, size,
- align, DRM_MM_INSERT_HIGH);
- mutex_unlock(&ggtt->lock);
-
- return ret;
+ return drm_mm_insert_node_in_range(&ggtt->mm, node, size, align, 0,
+ start, end, mm_flags);
}
void xe_ggtt_map_bo(struct xe_ggtt *ggtt, struct xe_bo *bo)
@@ -18,11 +18,10 @@ void xe_ggtt_printk(struct xe_ggtt *ggtt, const char *prefix);
int xe_ggtt_balloon(struct xe_ggtt *ggtt, u64 start, u64 size, struct drm_mm_node *node);
void xe_ggtt_deballoon(struct xe_ggtt *ggtt, struct drm_mm_node *node);
-int xe_ggtt_insert_special_node(struct xe_ggtt *ggtt, struct drm_mm_node *node,
- u32 size, u32 align);
int xe_ggtt_insert_special_node_locked(struct xe_ggtt *ggtt,
struct drm_mm_node *node,
- u32 size, u32 align, u32 mm_flags);
+ u32 size, u32 align,
+ u64 start, u64 end, u32 mm_flags);
void xe_ggtt_remove_node(struct xe_ggtt *ggtt, struct drm_mm_node *node,
bool invalidate);
void xe_ggtt_map_bo(struct xe_ggtt *ggtt, struct xe_bo *bo);
Instead of overwriting the original GGTT mapping accidentally, allocate a new GGTT mapping above the original GGTT mapping. Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> --- drivers/gpu/drm/xe/display/xe_fb_pin.c | 40 ++++++++++++------- drivers/gpu/drm/xe/display/xe_fb_pin.h | 20 ++++++++++ drivers/gpu/drm/xe/display/xe_plane_initial.c | 15 ++++--- drivers/gpu/drm/xe/xe_ggtt.c | 19 ++------- drivers/gpu/drm/xe/xe_ggtt.h | 5 +-- 5 files changed, 61 insertions(+), 38 deletions(-) create mode 100644 drivers/gpu/drm/xe/display/xe_fb_pin.h