From: Shobhit Kumar <shobhit.kumar@linux.intel.com>
To: intel-gfx@lists.freedesktop.org, daniel@ffwll.ch
Cc: deepak.s@intel.com, Shobhit Kumar <shobhit.kumar@intel.com>,
akshu.agrawal@intel.com
Subject: [RFC v2] drm/i915/chv: Clip cursor for CHV pipe C HW Cursor pos < 0
Date: Wed, 29 Jun 2016 18:24:42 +0530 [thread overview]
Message-ID: <1467204882-23928-1-git-send-email-shobhit.kumar@linux.intel.com> (raw)
In-Reply-To: <1467116873-31987-1-git-send-email-shobhit.kumar@linux.intel.com>
From: Shobhit Kumar <shobhit.kumar@intel.com>
CHV pipe C hits underrun when we get negative crtc_x values of cursor.
To avoid this we clip and shift the cursor image by negative crtc_x
value.
v2: Make a copy of cursor plane state and allocate new gem object and fb
for clipped cursor and use that in case of negative cursor position
v3: Updated error handling
Pin the gem object before use.
Signed-off-by: Akshu Agrawal <akshu.agrawal@intel.com>
Signed-off-by: Shobhit Kumar <shobhit.kumar@intel.com>
---
drivers/gpu/drm/i915/i915_drv.h | 7 ++
drivers/gpu/drm/i915/intel_display.c | 131 ++++++++++++++++++++++++++++++++++-
2 files changed, 137 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 724d34b..1e59c02 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2041,6 +2041,13 @@ struct drm_i915_private {
struct intel_encoder *dig_port_map[I915_MAX_PORTS];
/*
+ * Temporary copy of cursor plane state for CHV PIPE_C
+ * Will be initialized only when crtc_x < 0 as there is a
+ * HW bug causing pipe underrun
+ */
+ struct intel_plane_state *cursor_state;
+
+ /*
* NOTE: This is the dri1/ums dungeon, don't add stuff here. Your patch
* will be rejected. Instead look for a better place.
*/
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index c3b5dc8..e6c103a 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -14456,6 +14456,132 @@ intel_update_cursor_plane(struct drm_plane *plane,
intel_crtc_update_cursor(crtc, state);
}
+static void
+intel_update_chv_pipe_c_cursor_plane(struct drm_plane *plane,
+ const struct intel_crtc_state *crtc_state,
+ const struct intel_plane_state *state)
+{
+ struct drm_crtc *crtc = crtc_state->base.crtc;
+ struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+ struct drm_device *dev = plane->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct drm_i915_gem_object *obj = intel_fb_obj(state->base.fb);
+ struct drm_i915_gem_object *cur_obj = NULL, *use_obj = NULL;
+ uint32_t addr;
+ struct intel_plane_state *cursor_state = dev_priv->cursor_state;
+ const struct intel_plane_state *use_state;
+ char __iomem *src, *dst;
+ bool pinned = true;
+
+ if (state->visible && state->base.crtc_x < 0) {
+ int bytes_per_pixel = state->base.fb->bits_per_pixel / 8;
+ int x = state->base.crtc_x;
+ int width = state->base.crtc_w;
+ int height = state->base.crtc_h;
+ struct drm_mode_fb_cmd2 mode_cmd = { 0 };
+ int i;
+
+ if (!cursor_state) {
+ cursor_state = kzalloc(sizeof(*cursor_state), GFP_KERNEL);
+ if (!cursor_state) {
+ use_state = state;
+ use_obj = obj;
+ goto update;
+ }
+
+ memcpy(cursor_state, state, sizeof(*state));
+
+ /* Allocate new gem object */
+ cur_obj = i915_gem_object_create(dev, obj->base.size);
+ if (IS_ERR(cur_obj))
+ goto gem_err;
+
+ mode_cmd.width = cursor_state->base.fb->width;
+ mode_cmd.height = cursor_state->base.fb->height;
+ mode_cmd.pitches[0] = cursor_state->base.fb->pitches[0];
+ mode_cmd.pixel_format = cursor_state->base.fb->pixel_format;
+
+ cursor_state->base.fb = intel_framebuffer_create(dev, &mode_cmd, cur_obj);
+ if (IS_ERR(cursor_state->base.fb)) {
+ drm_gem_object_unreference_unlocked(&cur_obj->base);
+ goto gem_err;
+ }
+
+ if (i915_gem_obj_ggtt_pin(cur_obj, 0, 0) < 0) {
+ drm_gem_object_unreference_unlocked(&cur_obj->base);
+ pinned = false;
+ goto cleanup;
+ }
+
+ dev_priv->cursor_state = cursor_state;
+ } else
+ cur_obj = intel_fb_obj(cursor_state->base.fb);
+
+ src = ioremap_wc(dev_priv->ggtt.mappable_base +
+ i915_gem_obj_ggtt_offset(obj),
+ obj->base.size);
+
+ dst = ioremap_wc(dev_priv->ggtt.mappable_base +
+ i915_gem_obj_ggtt_offset(cur_obj),
+ cur_obj->base.size);
+
+ /* shift the original cusrsor in to copy buffer offsetting -ive pos */
+ x = -x;
+ for (i = 0; i < height; i++) {
+ src += x * bytes_per_pixel;
+ memcpy(dst, src, (width - x) * bytes_per_pixel);
+ dst += (width - x) * bytes_per_pixel;
+ memset(dst, 0, x * bytes_per_pixel);
+ dst += x * bytes_per_pixel;
+ src += (width -x) * bytes_per_pixel;
+ }
+
+ iounmap(src);
+ iounmap(dst);
+
+ cursor_state->base.crtc_x = 0;
+ use_obj = cur_obj;
+ use_state = cursor_state;
+
+ goto update;
+ }
+
+cleanup:
+ if (cursor_state) {
+ struct intel_framebuffer *intel_fb = to_intel_framebuffer(cursor_state->base.fb);
+
+ if (pinned)
+ i915_gem_object_ggtt_unpin(cur_obj);
+
+ drm_framebuffer_cleanup(cursor_state->base.fb);
+ mutex_lock(&dev->struct_mutex);
+ drm_gem_object_unreference(&intel_fb->obj->base);
+ mutex_unlock(&dev->struct_mutex);
+ kfree(intel_fb);
+ }
+
+gem_err:
+ if (dev_priv->cursor_state) {
+ kfree(dev_priv->cursor_state);
+ dev_priv->cursor_state = NULL;
+ }
+
+ use_state = state;
+ use_obj = obj;
+
+update:
+ if (!use_obj)
+ addr = 0;
+ else if (!INTEL_INFO(dev)->cursor_needs_physical)
+ addr = i915_gem_obj_ggtt_offset(use_obj);
+ else
+ addr = use_obj->phys_handle->busaddr;
+
+ intel_crtc->cursor_addr = addr;
+
+ intel_crtc_update_cursor(crtc, use_state);
+}
+
static struct drm_plane *intel_cursor_plane_create(struct drm_device *dev,
int pipe)
{
@@ -14478,7 +14604,10 @@ static struct drm_plane *intel_cursor_plane_create(struct drm_device *dev,
cursor->plane = pipe;
cursor->frontbuffer_bit = INTEL_FRONTBUFFER_CURSOR(pipe);
cursor->check_plane = intel_check_cursor_plane;
- cursor->update_plane = intel_update_cursor_plane;
+ if (IS_CHERRYVIEW(dev) && pipe == PIPE_C)
+ cursor->update_plane = intel_update_chv_pipe_c_cursor_plane;
+ else
+ cursor->update_plane = intel_update_cursor_plane;
cursor->disable_plane = intel_disable_cursor_plane;
ret = drm_universal_plane_init(dev, &cursor->base, 0,
--
1.9.1
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
next prev parent reply other threads:[~2016-06-29 12:54 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-06-08 8:27 [PATCH 1/2] Revert "drm/i915: Workaround CHV pipe C cursor fail" Akshu Agrawal
2016-06-08 8:27 ` [PATCH 2/2] drm/i915: Crop cursor image for CHV pipe C cursor issue Akshu Agrawal
2016-06-08 8:40 ` Daniel Vetter
2016-06-08 10:18 ` Dave Gordon
2016-06-09 17:03 ` Daniel Vetter
2016-06-10 9:44 ` Agrawal, Akshu
2016-06-13 14:22 ` Daniel Vetter
2016-06-27 9:09 ` Shobhit Kumar
2016-06-28 12:27 ` [RFC] drm/i915/chv: Clip cursor for CHV pipe C HW Cursor pos < 0 Shobhit Kumar
2016-06-28 12:32 ` Shobhit Kumar
2016-06-29 12:54 ` Shobhit Kumar [this message]
2016-06-29 13:02 ` [RFC v2] " Shobhit Kumar
2016-07-01 8:00 ` Shobhit Kumar
2016-07-08 9:01 ` Shobhit Kumar
2016-06-08 8:51 ` [PATCH 2/2] drm/i915: Crop cursor image for CHV pipe C cursor issue kbuild test robot
2016-06-08 11:09 ` kbuild test robot
2016-06-08 8:31 ` ✗ Ro.CI.BAT: failure for series starting with [1/2] Revert "drm/i915: Workaround CHV pipe C cursor fail" Patchwork
2016-06-28 13:04 ` ✗ Ro.CI.BAT: failure for series starting with [1/2] Revert "drm/i915: Workaround CHV pipe C cursor fail" (rev2) Patchwork
2016-06-29 13:20 ` ✓ Ro.CI.BAT: success for series starting with [1/2] Revert "drm/i915: Workaround CHV pipe C cursor fail" (rev3) Patchwork
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1467204882-23928-1-git-send-email-shobhit.kumar@linux.intel.com \
--to=shobhit.kumar@linux.intel.com \
--cc=akshu.agrawal@intel.com \
--cc=daniel@ffwll.ch \
--cc=deepak.s@intel.com \
--cc=intel-gfx@lists.freedesktop.org \
--cc=shobhit.kumar@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.