Skip to content

Commit

Permalink
drm/i915: Extract intel_frontbuffer active tracking
Browse files Browse the repository at this point in the history
Move the active tracking for the frontbuffer operations out of the
i915_gem_object and into its own first class (refcounted) object. In the
process of detangling, we switch from low level request tracking to the
easier i915_active -- with the plan that this avoids any potential
atomic callbacks as the frontbuffer tracking wishes to sleep as it
flushes.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: Matthew Auld <matthew.auld@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20190816074635.26062-1-chris@chris-wilson.co.uk
  • Loading branch information
Chris Wilson committed Aug 16, 2019
1 parent e5dadff commit 8e7cb17
Show file tree
Hide file tree
Showing 17 changed files with 306 additions and 260 deletions.
3 changes: 0 additions & 3 deletions Documentation/gpu/i915.rst
Original file line number Diff line number Diff line change
Expand Up @@ -91,9 +91,6 @@ Frontbuffer Tracking
.. kernel-doc:: drivers/gpu/drm/i915/display/intel_frontbuffer.c
:internal:

.. kernel-doc:: drivers/gpu/drm/i915/i915_gem.c
:functions: i915_gem_track_fb

Display FIFO Underrun Reporting
-------------------------------

Expand Down
70 changes: 33 additions & 37 deletions drivers/gpu/drm/i915/display/intel_display.c
Original file line number Diff line number Diff line change
Expand Up @@ -3049,12 +3049,13 @@ intel_alloc_initial_plane_obj(struct intel_crtc *crtc,
{
struct drm_device *dev = crtc->base.dev;
struct drm_i915_private *dev_priv = to_i915(dev);
struct drm_i915_gem_object *obj = NULL;
struct drm_mode_fb_cmd2 mode_cmd = { 0 };
struct drm_framebuffer *fb = &plane_config->fb->base;
u32 base_aligned = round_down(plane_config->base, PAGE_SIZE);
u32 size_aligned = round_up(plane_config->base + plane_config->size,
PAGE_SIZE);
struct drm_i915_gem_object *obj;
bool ret = false;

size_aligned -= base_aligned;

Expand Down Expand Up @@ -3096,7 +3097,7 @@ intel_alloc_initial_plane_obj(struct intel_crtc *crtc,
break;
default:
MISSING_CASE(plane_config->tiling);
return false;
goto out;
}

mode_cmd.pixel_format = fb->format->format;
Expand All @@ -3108,16 +3109,15 @@ intel_alloc_initial_plane_obj(struct intel_crtc *crtc,

if (intel_framebuffer_init(to_intel_framebuffer(fb), obj, &mode_cmd)) {
DRM_DEBUG_KMS("intel fb init failed\n");
goto out_unref_obj;
goto out;
}


DRM_DEBUG_KMS("initial plane fb obj %p\n", obj);
return true;

out_unref_obj:
ret = true;
out:
i915_gem_object_put(obj);
return false;
return ret;
}

static void
Expand Down Expand Up @@ -3174,14 +3174,19 @@ static void intel_plane_disable_noatomic(struct intel_crtc *crtc,
intel_disable_plane(plane, crtc_state);
}

static struct intel_frontbuffer *
to_intel_frontbuffer(struct drm_framebuffer *fb)
{
return fb ? to_intel_framebuffer(fb)->frontbuffer : NULL;
}

static void
intel_find_initial_plane_obj(struct intel_crtc *intel_crtc,
struct intel_initial_plane_config *plane_config)
{
struct drm_device *dev = intel_crtc->base.dev;
struct drm_i915_private *dev_priv = to_i915(dev);
struct drm_crtc *c;
struct drm_i915_gem_object *obj;
struct drm_plane *primary = intel_crtc->base.primary;
struct drm_plane_state *plane_state = primary->state;
struct intel_plane *intel_plane = to_intel_plane(primary);
Expand Down Expand Up @@ -3257,8 +3262,7 @@ intel_find_initial_plane_obj(struct intel_crtc *intel_crtc,
return;
}

obj = intel_fb_obj(fb);
intel_fb_obj_flush(obj, ORIGIN_DIRTYFB);
intel_frontbuffer_flush(to_intel_frontbuffer(fb), ORIGIN_DIRTYFB);

plane_state->src_x = 0;
plane_state->src_y = 0;
Expand All @@ -3273,14 +3277,14 @@ intel_find_initial_plane_obj(struct intel_crtc *intel_crtc,
intel_state->base.src = drm_plane_state_src(plane_state);
intel_state->base.dst = drm_plane_state_dest(plane_state);

if (i915_gem_object_is_tiled(obj))
if (plane_config->tiling)
dev_priv->preserve_bios_swizzle = true;

plane_state->fb = fb;
plane_state->crtc = &intel_crtc->base;

atomic_or(to_intel_plane(primary)->frontbuffer_bit,
&obj->frontbuffer_bits);
&to_intel_frontbuffer(fb)->bits);
}

static int skl_max_plane_width(const struct drm_framebuffer *fb,
Expand Down Expand Up @@ -14132,9 +14136,9 @@ static void intel_atomic_track_fbs(struct intel_atomic_state *state)

for_each_oldnew_intel_plane_in_state(state, plane, old_plane_state,
new_plane_state, i)
i915_gem_track_fb(intel_fb_obj(old_plane_state->base.fb),
intel_fb_obj(new_plane_state->base.fb),
plane->frontbuffer_bit);
intel_frontbuffer_track(to_intel_frontbuffer(old_plane_state->base.fb),
to_intel_frontbuffer(new_plane_state->base.fb),
plane->frontbuffer_bit);
}

static int intel_atomic_commit(struct drm_device *dev,
Expand Down Expand Up @@ -14418,7 +14422,7 @@ intel_prepare_plane_fb(struct drm_plane *plane,
return ret;

fb_obj_bump_render_priority(obj);
intel_fb_obj_flush(obj, ORIGIN_DIRTYFB);
intel_frontbuffer_flush(obj->frontbuffer, ORIGIN_DIRTYFB);

if (!new_state->fence) { /* implicit fencing */
struct dma_fence *fence;
Expand Down Expand Up @@ -14681,13 +14685,12 @@ intel_legacy_cursor_update(struct drm_plane *plane,
struct drm_modeset_acquire_ctx *ctx)
{
struct drm_i915_private *dev_priv = to_i915(crtc->dev);
int ret;
struct drm_plane_state *old_plane_state, *new_plane_state;
struct intel_plane *intel_plane = to_intel_plane(plane);
struct drm_framebuffer *old_fb;
struct intel_crtc_state *crtc_state =
to_intel_crtc_state(crtc->state);
struct intel_crtc_state *new_crtc_state;
int ret;

/*
* When crtc is inactive or there is a modeset pending,
Expand Down Expand Up @@ -14755,11 +14758,10 @@ intel_legacy_cursor_update(struct drm_plane *plane,
if (ret)
goto out_unlock;

intel_fb_obj_flush(intel_fb_obj(fb), ORIGIN_FLIP);

old_fb = old_plane_state->fb;
i915_gem_track_fb(intel_fb_obj(old_fb), intel_fb_obj(fb),
intel_plane->frontbuffer_bit);
intel_frontbuffer_flush(to_intel_frontbuffer(fb), ORIGIN_FLIP);
intel_frontbuffer_track(to_intel_frontbuffer(old_plane_state->fb),
to_intel_frontbuffer(fb),
intel_plane->frontbuffer_bit);

/* Swap plane state */
plane->state = new_plane_state;
Expand Down Expand Up @@ -15540,15 +15542,9 @@ static void intel_setup_outputs(struct drm_i915_private *dev_priv)
static void intel_user_framebuffer_destroy(struct drm_framebuffer *fb)
{
struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb);
struct drm_i915_gem_object *obj = intel_fb_obj(fb);

drm_framebuffer_cleanup(fb);

i915_gem_object_lock(obj);
WARN_ON(!obj->framebuffer_references--);
i915_gem_object_unlock(obj);

i915_gem_object_put(obj);
intel_frontbuffer_put(intel_fb->frontbuffer);

kfree(intel_fb);
}
Expand Down Expand Up @@ -15576,7 +15572,7 @@ static int intel_user_framebuffer_dirty(struct drm_framebuffer *fb,
struct drm_i915_gem_object *obj = intel_fb_obj(fb);

i915_gem_object_flush_if_display(obj);
intel_fb_obj_flush(obj, ORIGIN_DIRTYFB);
intel_frontbuffer_flush(to_intel_frontbuffer(fb), ORIGIN_DIRTYFB);

return 0;
}
Expand All @@ -15598,8 +15594,11 @@ static int intel_framebuffer_init(struct intel_framebuffer *intel_fb,
int ret = -EINVAL;
int i;

intel_fb->frontbuffer = intel_frontbuffer_get(obj);
if (!intel_fb->frontbuffer)
return -ENOMEM;

i915_gem_object_lock(obj);
obj->framebuffer_references++;
tiling = i915_gem_object_get_tiling(obj);
stride = i915_gem_object_get_stride(obj);
i915_gem_object_unlock(obj);
Expand Down Expand Up @@ -15716,9 +15715,7 @@ static int intel_framebuffer_init(struct intel_framebuffer *intel_fb,
return 0;

err:
i915_gem_object_lock(obj);
obj->framebuffer_references--;
i915_gem_object_unlock(obj);
intel_frontbuffer_put(intel_fb->frontbuffer);
return ret;
}

Expand All @@ -15736,8 +15733,7 @@ intel_user_framebuffer_create(struct drm_device *dev,
return ERR_PTR(-ENOENT);

fb = intel_framebuffer_create(obj, &mode_cmd);
if (IS_ERR(fb))
i915_gem_object_put(obj);
i915_gem_object_put(obj);

return fb;
}
Expand Down
1 change: 1 addition & 0 deletions drivers/gpu/drm/i915/display/intel_display_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ enum intel_broadcast_rgb {

struct intel_framebuffer {
struct drm_framebuffer base;
struct intel_frontbuffer *frontbuffer;
struct intel_rotation_info rot_info;

/* for each plane in the normal GTT view */
Expand Down
40 changes: 16 additions & 24 deletions drivers/gpu/drm/i915/display/intel_fbdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,14 @@
#include "intel_fbdev.h"
#include "intel_frontbuffer.h"

static void intel_fbdev_invalidate(struct intel_fbdev *ifbdev)
static struct intel_frontbuffer *to_frontbuffer(struct intel_fbdev *ifbdev)
{
struct drm_i915_gem_object *obj = intel_fb_obj(&ifbdev->fb->base);
unsigned int origin =
ifbdev->vma_flags & PLANE_HAS_FENCE ? ORIGIN_GTT : ORIGIN_CPU;
return ifbdev->fb->frontbuffer;
}

intel_fb_obj_invalidate(obj, origin);
static void intel_fbdev_invalidate(struct intel_fbdev *ifbdev)
{
intel_frontbuffer_invalidate(to_frontbuffer(ifbdev), ORIGIN_CPU);
}

static int intel_fbdev_set_par(struct fb_info *info)
Expand Down Expand Up @@ -120,7 +121,7 @@ static int intelfb_alloc(struct drm_fb_helper *helper,
struct drm_i915_private *dev_priv = to_i915(dev);
struct drm_mode_fb_cmd2 mode_cmd = {};
struct drm_i915_gem_object *obj;
int size, ret;
int size;

/* we don't do packed 24bpp */
if (sizes->surface_bpp == 24)
Expand All @@ -147,24 +148,16 @@ static int intelfb_alloc(struct drm_fb_helper *helper,
obj = i915_gem_object_create_shmem(dev_priv, size);
if (IS_ERR(obj)) {
DRM_ERROR("failed to allocate framebuffer\n");
ret = PTR_ERR(obj);
goto err;
return PTR_ERR(obj);
}

fb = intel_framebuffer_create(obj, &mode_cmd);
if (IS_ERR(fb)) {
ret = PTR_ERR(fb);
goto err_obj;
}
i915_gem_object_put(obj);
if (IS_ERR(fb))
return PTR_ERR(fb);

ifbdev->fb = to_intel_framebuffer(fb);

return 0;

err_obj:
i915_gem_object_put(obj);
err:
return ret;
}

static int intelfb_create(struct drm_fb_helper *helper,
Expand All @@ -180,7 +173,6 @@ static int intelfb_create(struct drm_fb_helper *helper,
const struct i915_ggtt_view view = {
.type = I915_GGTT_VIEW_NORMAL,
};
struct drm_framebuffer *fb;
intel_wakeref_t wakeref;
struct fb_info *info;
struct i915_vma *vma;
Expand Down Expand Up @@ -226,8 +218,7 @@ static int intelfb_create(struct drm_fb_helper *helper,
goto out_unlock;
}

fb = &ifbdev->fb->base;
intel_fb_obj_flush(intel_fb_obj(fb), ORIGIN_DIRTYFB);
intel_frontbuffer_flush(to_frontbuffer(ifbdev), ORIGIN_DIRTYFB);

info = drm_fb_helper_alloc_fbi(helper);
if (IS_ERR(info)) {
Expand All @@ -236,7 +227,7 @@ static int intelfb_create(struct drm_fb_helper *helper,
goto out_unpin;
}

ifbdev->helper.fb = fb;
ifbdev->helper.fb = &ifbdev->fb->base;

info->fbops = &intelfb_ops;

Expand All @@ -263,13 +254,14 @@ static int intelfb_create(struct drm_fb_helper *helper,
* If the object is stolen however, it will be full of whatever
* garbage was left in there.
*/
if (intel_fb_obj(fb)->stolen && !prealloc)
if (vma->obj->stolen && !prealloc)
memset_io(info->screen_base, 0, info->screen_size);

/* Use default scratch pixmap (info->pixmap.flags = FB_PIXMAP_SYSTEM) */

DRM_DEBUG_KMS("allocated %dx%d fb: 0x%08x\n",
fb->width, fb->height, i915_ggtt_offset(vma));
ifbdev->fb->base.width, ifbdev->fb->base.height,
i915_ggtt_offset(vma));
ifbdev->vma = vma;
ifbdev->vma_flags = flags;

Expand Down
Loading

0 comments on commit 8e7cb17

Please sign in to comment.