* [PATCH 1/3] drm/i915: add SNB and IVB video sprite support
@ 2011-11-08 21:19 Jesse Barnes
2011-11-08 21:19 ` [PATCH 2/3] drm/i915: add destination color key support Jesse Barnes
2011-11-08 21:19 ` [PATCH 3/3] drm/i915: track sprite coverage and disable primary plane if possible Jesse Barnes
0 siblings, 2 replies; 9+ messages in thread
From: Jesse Barnes @ 2011-11-08 21:19 UTC (permalink / raw)
To: intel-gfx
The video sprites support various video surface formats natively and can
handle scaling as well. So add support for them using the new DRM core
sprite support functions.
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
---
drivers/gpu/drm/i915/Makefile | 1 +
drivers/gpu/drm/i915/i915_reg.h | 123 ++++++++++
drivers/gpu/drm/i915/intel_display.c | 29 ++-
drivers/gpu/drm/i915/intel_drv.h | 22 ++
drivers/gpu/drm/i915/intel_fb.c | 6 +
drivers/gpu/drm/i915/intel_sprite.c | 431 ++++++++++++++++++++++++++++++++++
6 files changed, 602 insertions(+), 10 deletions(-)
create mode 100644 drivers/gpu/drm/i915/intel_sprite.c
diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index 0ae6a7c..808b255 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -28,6 +28,7 @@ i915-y := i915_drv.o i915_dma.o i915_irq.o i915_mem.o \
intel_dvo.o \
intel_ringbuffer.o \
intel_overlay.o \
+ intel_sprite.o \
intel_opregion.o \
dvo_ch7xxx.o \
dvo_ch7017.o \
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 5a09416..b2270fa 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -2450,6 +2450,8 @@
#define WM3_LP_ILK 0x45110
#define WM3_LP_EN (1<<31)
#define WM1S_LP_ILK 0x45120
+#define WM2S_LP_IVB 0x45124
+#define WM3S_LP_IVB 0x45128
#define WM1S_LP_EN (1<<31)
/* Memory latency timer register */
@@ -2666,6 +2668,127 @@
#define _DSPBSURF 0x7119C
#define _DSPBTILEOFF 0x711A4
+/* Sprite A control */
+#define _DVSACNTR 0x72180
+#define DVS_ENABLE (1<<31)
+#define DVS_GAMMA_ENABLE (1<<30)
+#define DVS_PIXFORMAT_MASK (3<<25)
+#define DVS_FORMAT_YUV422 (0<<25)
+#define DVS_FORMAT_RGBX101010 (1<<25)
+#define DVS_FORMAT_RGBX888 (2<<25)
+#define DVS_FORMAT_RGBX161616 (3<<25)
+#define DVS_SOURCE_KEY (1<<22)
+#define DVS_RGB_ORDER_RGBX (1<<20)
+#define DVS_YUV_BYTE_ORDER_MASK (3<<16)
+#define DVS_YUV_ORDER_YUYV (0<<16)
+#define DVS_YUV_ORDER_UYVY (1<<16)
+#define DVS_YUV_ORDER_YVYU (2<<16)
+#define DVS_YUV_ORDER_VYUY (3<<16)
+#define DVS_DEST_KEY (1<<2)
+#define DVS_TRICKLE_FEED_DISABLE (1<<14)
+#define DVS_TILED (1<<10)
+#define _DVSASTRIDE 0x72188
+#define _DVSAPOS 0x7218c
+#define _DVSASIZE 0x72190
+#define _DVSAKEYVAL 0x72194
+#define _DVSAKEYMSK 0x72198
+#define _DVSASURF 0x7219c
+#define _DVSAKEYMAXVAL 0x721a0
+#define _DVSATILEOFF 0x721a4
+#define _DVSASURFLIVE 0x721ac
+#define _DVSASCALE 0x72204
+#define DVS_SCALE_ENABLE (1<<31)
+#define DVS_FILTER_MASK (3<<29)
+#define DVS_FILTER_MEDIUM (0<<29)
+#define DVS_FILTER_ENHANCING (1<<29)
+#define DVS_FILTER_SOFTENING (2<<29)
+#define _DVSAGAMC 0x72300
+
+#define _DVSBCNTR 0x73180
+#define _DVSBSTRIDE 0x73188
+#define _DVSBPOS 0x7318c
+#define _DVSBSIZE 0x73190
+#define _DVSBKEYVAL 0x73194
+#define _DVSBKEYMSK 0x73198
+#define _DVSBSURF 0x7319c
+#define _DVSBKEYMAXVAL 0x731a0
+#define _DVSBTILEOFF 0x731a4
+#define _DVSBSURFLIVE 0x731ac
+#define _DVSBSCALE 0x73204
+#define _DVSBGAMC 0x73300
+
+#define DVSCNTR(pipe) _PIPE(pipe, _DVSACNTR, _DVSBCNTR)
+#define DVSSTRIDE(pipe) _PIPE(pipe, _DVSASTRIDE, _DVSBSTRIDE)
+#define DVSPOS(pipe) _PIPE(pipe, _DVSAPOS, _DVSBPOS)
+#define DVSSURF(pipe) _PIPE(pipe, _DVSASURF, _DVSBSURF)
+#define DVSSIZE(pipe) _PIPE(pipe, _DVSASIZE, _DVSBSIZE)
+#define DVSSCALE(pipe) _PIPE(pipe, _DVSASCALE, _DVSBSCALE)
+#define DVSTILEOFF(pipe) _PIPE(pipe, _DVSATILEOFF, _DVSBTILEOFF)
+
+#define _SPRA_CTL 0x70280
+#define SPRITE_ENABLE (1<<31)
+#define SPRITE_GAMMA_ENABLE (1<<30)
+#define SPRITE_PIXFORMAT_MASK (7<<25)
+#define SPRITE_FORMAT_YUV422 (0<<25)
+#define SPRITE_FORMAT_RGBX101010 (1<<25)
+#define SPRITE_FORMAT_RGBX888 (2<<25)
+#define SPRITE_FORMAT_RGBX161616 (3<<25)
+#define SPRITE_FORMAT_YUV444 (4<<25)
+#define SPRITE_FORMAT_XBGR101010 (5<<25)
+#define SPRITE_CSC_ENABLE (1<<24)
+#define SPRITE_SOURCE_KEY (1<<22)
+#define SPRITE_RGB_ORDER_RGBX (1<<20) /* only for 888 and 161616 */
+#define SPRITE_YUV_TO_RGB_CSC_DISABLE (1<<19)
+#define SPRITE_YUV_CSC_FORMAT_BT709 (1<<18) /* 0 is BT601 */
+#define SPRITE_YUV_BYTE_ORDER_MASK (3<<16)
+#define SPRITE_YUV_ORDER_YUYV (0<<16)
+#define SPRITE_YUV_ORDER_UYVY (1<<16)
+#define SPRITE_YUV_ORDER_YVYU (2<<16)
+#define SPRITE_YUV_ORDER_VYUY (3<<16)
+#define SPRITE_TRICKLE_FEED_DISABLE (1<<14)
+#define SPRITE_INT_GAMMA_ENABLE (1<<13)
+#define SPRITE_TILED (1<<10)
+#define SPRITE_DEST_KEY (1<<2)
+#define _SPRA_STRIDE 0x70288
+#define _SPRA_POS 0x7028c
+#define _SPRA_SIZE 0x70290
+#define _SPRA_KEYVAL 0x70294
+#define _SPRA_KEYMSK 0x70298
+#define _SPRA_SURF 0x7029c
+#define _SPRA_KEYMAX 0x702a0
+#define _SPRA_TILEOFF 0x702a4
+#define _SPRA_SCALE 0x70304
+#define SPRITE_SCALE_ENABLE (1<<31)
+#define SPRITE_FILTER_MASK (3<<29)
+#define SPRITE_FILTER_MEDIUM (0<<29)
+#define SPRITE_FILTER_ENHANCING (1<<29)
+#define SPRITE_FILTER_SOFTENING (2<<29)
+#define _SPRA_GAMC 0x70400
+
+#define _SPRB_CTL 0x71280
+#define _SPRB_STRIDE 0x71288
+#define _SPRB_POS 0x7128c
+#define _SPRB_SIZE 0x71290
+#define _SPRB_KEYVAL 0x71294
+#define _SPRB_KEYMSK 0x71298
+#define _SPRB_SURF 0x7129c
+#define _SPRB_KEYMAX 0x712a0
+#define _SPRB_TILEOFF 0x712a4
+#define _SPRB_SCALE 0x71304
+#define _SPRB_GAMC 0x71400
+
+#define SPRCTL(pipe) _PIPE(pipe, _SPRA_CTL, _SPRB_CTL)
+#define SPRSTRIDE(pipe) _PIPE(pipe, _SPRA_STRIDE, _SPRB_STRIDE)
+#define SPRPOS(pipe) _PIPE(pipe, _SPRA_POS, _SPRB_POS)
+#define SPRSIZE(pipe) _PIPE(pipe, _SPRA_SIZE, _SPRB_SIZE)
+#define SPRKEYVAL(pipe) _PIPE(pipe, _SPRA_KEYVAL, _SPRB_KEYVAL)
+#define SPRKEYMSK(pipe) _PIPE(pipe, _SPRA_KEYMSK, _SPRB_KEYMSK)
+#define SPRSURF(pipe) _PIPE(pipe, _SPRA_SURF, _SPRB_SURF)
+#define SPRKEYMAX(pipe) _PIPE(pipe, _SPRA_KEYMAX, _SPRB_KEYMAX)
+#define SPRTILEOFF(pipe) _PIPE(pipe, _SPRA_TILEOFF, _SPRB_TILEOFF)
+#define SPRSCALE(pipe) _PIPE(pipe, _SPRA_SCALE, _SPRB_SCALE)
+#define SPRGAMC(pipe) _PIPE(pipe, _SPRA_GAMC, _SPRB_GAMC)
+
/* VBIOS regs */
#define VGACNTRL 0x71400
# define VGA_DISP_DISABLE (1 << 31)
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index aae7b03..09228dd 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -915,8 +915,8 @@ static void assert_panel_unlocked(struct drm_i915_private *dev_priv,
pipe_name(pipe));
}
-static void assert_pipe(struct drm_i915_private *dev_priv,
- enum pipe pipe, bool state)
+void assert_pipe(struct drm_i915_private *dev_priv,
+ enum pipe pipe, bool state)
{
int reg;
u32 val;
@@ -929,8 +929,6 @@ static void assert_pipe(struct drm_i915_private *dev_priv,
"pipe %c assertion failure (expected %s, current %s)\n",
pipe_name(pipe), state_string(state), state_string(cur_state));
}
-#define assert_pipe_enabled(d, p) assert_pipe(d, p, true)
-#define assert_pipe_disabled(d, p) assert_pipe(d, p, false)
static void assert_plane_enabled(struct drm_i915_private *dev_priv,
enum plane plane)
@@ -4439,7 +4437,8 @@ static void ironlake_update_wm(struct drm_device *dev)
ILK_LP0_CURSOR_LATENCY,
&plane_wm, &cursor_wm)) {
I915_WRITE(WM0_PIPEA_ILK,
- (plane_wm << WM0_PIPE_PLANE_SHIFT) | cursor_wm);
+ (plane_wm << WM0_PIPE_PLANE_SHIFT) |
+ (plane_wm << WM0_PIPE_SPRITE_SHIFT) | cursor_wm);
DRM_DEBUG_KMS("FIFO watermarks For pipe A -"
" plane %d, " "cursor: %d\n",
plane_wm, cursor_wm);
@@ -4453,7 +4452,8 @@ static void ironlake_update_wm(struct drm_device *dev)
ILK_LP0_CURSOR_LATENCY,
&plane_wm, &cursor_wm)) {
I915_WRITE(WM0_PIPEB_ILK,
- (plane_wm << WM0_PIPE_PLANE_SHIFT) | cursor_wm);
+ (plane_wm << WM0_PIPE_PLANE_SHIFT) |
+ (plane_wm << WM0_PIPE_SPRITE_SHIFT) | cursor_wm);
DRM_DEBUG_KMS("FIFO watermarks For pipe B -"
" plane %d, cursor: %d\n",
plane_wm, cursor_wm);
@@ -4521,7 +4521,8 @@ static void sandybridge_update_wm(struct drm_device *dev)
&sandybridge_cursor_wm_info, latency,
&plane_wm, &cursor_wm)) {
I915_WRITE(WM0_PIPEA_ILK,
- (plane_wm << WM0_PIPE_PLANE_SHIFT) | cursor_wm);
+ (plane_wm << WM0_PIPE_PLANE_SHIFT) |
+ (plane_wm << WM0_PIPE_SPRITE_SHIFT) | cursor_wm);
DRM_DEBUG_KMS("FIFO watermarks For pipe A -"
" plane %d, " "cursor: %d\n",
plane_wm, cursor_wm);
@@ -4533,7 +4534,8 @@ static void sandybridge_update_wm(struct drm_device *dev)
&sandybridge_cursor_wm_info, latency,
&plane_wm, &cursor_wm)) {
I915_WRITE(WM0_PIPEB_ILK,
- (plane_wm << WM0_PIPE_PLANE_SHIFT) | cursor_wm);
+ (plane_wm << WM0_PIPE_PLANE_SHIFT) |
+ (plane_wm << WM0_PIPE_SPRITE_SHIFT) | cursor_wm);
DRM_DEBUG_KMS("FIFO watermarks For pipe B -"
" plane %d, cursor: %d\n",
plane_wm, cursor_wm);
@@ -4547,7 +4549,8 @@ static void sandybridge_update_wm(struct drm_device *dev)
&sandybridge_cursor_wm_info, latency,
&plane_wm, &cursor_wm)) {
I915_WRITE(WM0_PIPEC_IVB,
- (plane_wm << WM0_PIPE_PLANE_SHIFT) | cursor_wm);
+ (plane_wm << WM0_PIPE_PLANE_SHIFT) |
+ (plane_wm << WM0_PIPE_SPRITE_SHIFT) | cursor_wm);
DRM_DEBUG_KMS("FIFO watermarks For pipe C -"
" plane %d, cursor: %d\n",
plane_wm, cursor_wm);
@@ -8693,7 +8696,7 @@ static void i915_disable_vga(struct drm_device *dev)
void intel_modeset_init(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
- int i;
+ int i, ret;
drm_mode_config_init(dev);
@@ -8723,6 +8726,12 @@ void intel_modeset_init(struct drm_device *dev)
for (i = 0; i < dev_priv->num_pipe; i++) {
intel_crtc_init(dev, i);
+ if (HAS_PCH_SPLIT(dev)) {
+ ret = intel_plane_init(dev, i);
+ if (ret)
+ DRM_ERROR("plane %d init failed: %d\n",
+ i, ret);
+ }
}
/* Just disable it once at startup */
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 23c5622..6284562 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -176,10 +176,26 @@ struct intel_crtc {
bool use_pll_a;
};
+struct intel_plane {
+ struct drm_plane base;
+ enum pipe pipe;
+ struct drm_i915_gem_object *obj;
+ int max_downscale;
+ u32 lut_r[1024], lut_g[1024], lut_b[1024];
+ void (*update_plane)(struct drm_plane *plane,
+ struct drm_framebuffer *fb, unsigned long start,
+ int crtc_x, int crtc_y,
+ unsigned int crtc_w, unsigned int crtc_h,
+ uint32_t x, uint32_t y,
+ uint32_t src_w, uint32_t src_h);
+ void (*disable_plane)(struct drm_plane *plane);
+};
+
#define to_intel_crtc(x) container_of(x, struct intel_crtc, base)
#define to_intel_connector(x) container_of(x, struct intel_connector, base)
#define to_intel_encoder(x) container_of(x, struct intel_encoder, base)
#define to_intel_framebuffer(x) container_of(x, struct intel_framebuffer, base)
+#define to_intel_plane(x) container_of(x, struct intel_plane, base)
#define DIP_HEADER_SIZE 5
@@ -289,6 +305,7 @@ intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode,
extern bool intel_dpd_is_edp(struct drm_device *dev);
extern void intel_edp_link_config(struct intel_encoder *, int *, int *);
extern bool intel_encoder_is_pch_edp(struct drm_encoder *encoder);
+extern int intel_plane_init(struct drm_device *dev, enum pipe pipe);
/* intel_panel.c */
extern void intel_fixed_panel_mode(struct drm_display_mode *fixed_mode,
@@ -379,6 +396,11 @@ extern int intel_overlay_attrs(struct drm_device *dev, void *data,
extern void intel_fb_output_poll_changed(struct drm_device *dev);
extern void intel_fb_restore_mode(struct drm_device *dev);
+extern void assert_pipe(struct drm_i915_private *dev_priv, enum pipe pipe,
+ bool state);
+#define assert_pipe_enabled(d, p) assert_pipe(d, p, true)
+#define assert_pipe_disabled(d, p) assert_pipe(d, p, false)
+
extern void intel_init_clock_gating(struct drm_device *dev);
extern void intel_write_eld(struct drm_encoder *encoder,
struct drm_display_mode *mode);
diff --git a/drivers/gpu/drm/i915/intel_fb.c b/drivers/gpu/drm/i915/intel_fb.c
index dc1db4f..068b086 100644
--- a/drivers/gpu/drm/i915/intel_fb.c
+++ b/drivers/gpu/drm/i915/intel_fb.c
@@ -270,8 +270,14 @@ void intel_fb_restore_mode(struct drm_device *dev)
{
int ret;
drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_mode_config *config = &dev->mode_config;
+ struct drm_plane *plane;
ret = drm_fb_helper_restore_fbdev_mode(&dev_priv->fbdev->helper);
if (ret)
DRM_DEBUG("failed to restore crtc mode\n");
+
+ /* Be sure to shut off any planes that may be active */
+ list_for_each_entry(plane, &config->plane_list, head)
+ plane->funcs->disable_plane(plane);
}
diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
new file mode 100644
index 0000000..a4e9721
--- /dev/null
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -0,0 +1,431 @@
+/*
+ * Copyright © 2011 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ * Jesse Barnes <jbarnes@virtuousgeek.org>
+ *
+ * New plane/sprite handling.
+ *
+ * The older chips had a separate interface for programming plane related
+ * registers; newer ones are much simpler and we can use the new DRM plane
+ * support.
+ */
+#include "drmP.h"
+#include "drm_crtc.h"
+#include "intel_drv.h"
+#include "i915_drm.h"
+#include "i915_drv.h"
+
+/*
+ * Note on refcounting:
+ * When the user creates an fb for the GEM object to be used for the plane,
+ * a ref is taken on the object. However, if the application exits before
+ * disabling the plane, the DRM close handling will free all the fbs and
+ * unless we take a ref on the object, it will be destroyed before the
+ * plane disable hook is called, causing obvious trouble with our efforts
+ * to look up and unpin the object. So we take a ref after we move the
+ * object to the display plane so it won't be destroyed until our disable
+ * hook is called and we drop our private reference.
+ */
+
+static void
+ivb_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb,
+ unsigned long start, int crtc_x, int crtc_y,
+ unsigned int crtc_w, unsigned int crtc_h,
+ uint32_t x, uint32_t y,
+ uint32_t src_w, uint32_t src_h)
+{
+ struct drm_device *dev = plane->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_plane *intel_plane = to_intel_plane(plane);
+ int pipe = intel_plane->pipe;
+ u32 sprctl, sprscale = 0;
+ u32 reg = SPRCTL(pipe);
+
+ sprctl = I915_READ(reg);
+
+ /* Mask out pixel format bits in case we change it */
+ sprctl &= ~(SPRITE_DEST_KEY | SPRITE_SOURCE_KEY);
+ sprctl &= ~SPRITE_PIXFORMAT_MASK;
+ sprctl &= ~SPRITE_RGB_ORDER_RGBX;
+ sprctl &= ~SPRITE_YUV_BYTE_ORDER_MASK;
+
+ switch (fb->pixel_format) {
+ case V4L2_PIX_FMT_BGR32:
+ sprctl |= SPRITE_FORMAT_RGBX888;
+ break;
+ case V4L2_PIX_FMT_RGB32:
+ sprctl |= SPRITE_FORMAT_RGBX888 | SPRITE_RGB_ORDER_RGBX;
+ break;
+ case V4L2_PIX_FMT_YUYV:
+ sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_YUYV;
+ break;
+ case V4L2_PIX_FMT_YVYU:
+ sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_YVYU;
+ break;
+ case V4L2_PIX_FMT_UYVY:
+ sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_UYVY;
+ break;
+ case V4L2_PIX_FMT_VYUY:
+ sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_VYUY;
+ break;
+ default:
+ DRM_DEBUG_DRIVER("bad pixel format, assuming RGBX888\n");
+ sprctl |= DVS_FORMAT_RGBX888;
+ break;
+ }
+
+ sprctl |= SPRITE_TILED;
+
+ /* must disable */
+ sprctl |= SPRITE_TRICKLE_FEED_DISABLE;
+ sprctl |= SPRITE_ENABLE;
+
+ /* Sizes are 0 based */
+ src_w--;
+ src_h--;
+ crtc_w--;
+ crtc_h--;
+
+ /* Adjust watermarks as needed */
+ I915_WRITE(WM1S_LP_ILK, 0x100);
+ I915_WRITE(WM2S_LP_IVB, 0x100);
+ I915_WRITE(WM3S_LP_IVB, 0x100);
+
+ if (crtc_w != src_w || crtc_h != src_h)
+ sprscale = SPRITE_SCALE_ENABLE | (src_h << 16) | src_w;
+
+ I915_WRITE(SPRSTRIDE(pipe), fb->pitch);
+ I915_WRITE(SPRPOS(pipe), (crtc_y << 16) | crtc_x);
+ I915_WRITE(SPRTILEOFF(pipe), (y << 16) | x);
+ I915_WRITE(SPRSIZE(pipe), (crtc_h << 16) | crtc_w);
+ I915_WRITE(SPRSCALE(pipe), sprscale);
+ I915_WRITE(reg, sprctl);
+ I915_WRITE(SPRSURF(pipe), start);
+ POSTING_READ(SPRSURF(pipe));
+}
+
+static void
+ivb_disable_plane(struct drm_plane *plane)
+{
+ struct drm_device *dev = plane->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_plane *intel_plane = to_intel_plane(plane);
+ int pipe = intel_plane->pipe;
+
+ I915_WRITE(SPRCTL(pipe), I915_READ(SPRCTL(pipe)) & ~SPRITE_ENABLE);
+ I915_WRITE(SPRSCALE(pipe), 0);
+ I915_WRITE(SPRSURF(pipe), 0);
+ POSTING_READ(SPRSURF(pipe));
+ intel_wait_for_vblank(dev, pipe);
+}
+
+static void
+snb_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb,
+ unsigned long start, int crtc_x, int crtc_y,
+ unsigned int crtc_w, unsigned int crtc_h,
+ uint32_t x, uint32_t y,
+ uint32_t src_w, uint32_t src_h)
+{
+ struct drm_device *dev = plane->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_plane *intel_plane = to_intel_plane(plane);
+ int pipe = intel_plane->pipe;
+ u32 dvscntr, dvsscale = 0;
+ u32 reg = DVSCNTR(pipe);
+
+ dvscntr = I915_READ(reg);
+
+ /* Mask out pixel format bits in case we change it */
+ dvscntr &= ~(DVS_DEST_KEY | DVS_SOURCE_KEY);
+ dvscntr &= ~DVS_PIXFORMAT_MASK;
+ dvscntr &= ~DVS_RGB_ORDER_RGBX;
+ dvscntr &= ~DVS_YUV_BYTE_ORDER_MASK;
+
+ switch (fb->pixel_format) {
+ case V4L2_PIX_FMT_BGR32:
+ dvscntr |= DVS_FORMAT_RGBX888;
+ break;
+ case V4L2_PIX_FMT_RGB32:
+ dvscntr |= DVS_FORMAT_RGBX888 | DVS_RGB_ORDER_RGBX;
+ break;
+ case V4L2_PIX_FMT_YUYV:
+ dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_YUYV;
+ break;
+ case V4L2_PIX_FMT_YVYU:
+ dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_YVYU;
+ break;
+ case V4L2_PIX_FMT_UYVY:
+ dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_UYVY;
+ break;
+ case V4L2_PIX_FMT_VYUY:
+ dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_VYUY;
+ break;
+ default:
+ DRM_DEBUG_DRIVER("bad pixel format, assuming RGBX888\n");
+ dvscntr |= DVS_FORMAT_RGBX888;
+ break;
+ }
+
+ dvscntr |= DVS_TILED;
+
+ /* must disable */
+ dvscntr |= DVS_TRICKLE_FEED_DISABLE;
+ dvscntr |= DVS_ENABLE;
+
+ /* Sizes are 0 based */
+ src_w--;
+ src_h--;
+ crtc_w--;
+ crtc_h--;
+
+ if (crtc_w != src_w || crtc_h != src_h)
+ dvsscale = DVS_SCALE_ENABLE | (src_h << 16) | src_w;
+
+ I915_WRITE(DVSSTRIDE(pipe), fb->pitch);
+ I915_WRITE(DVSPOS(pipe), (crtc_y << 16) | crtc_x);
+ I915_WRITE(DVSTILEOFF(pipe), (y << 16) | x);
+ I915_WRITE(DVSSIZE(pipe), (crtc_h << 16) | crtc_w);
+ I915_WRITE(DVSSCALE(pipe), dvsscale);
+ I915_WRITE(reg, dvscntr);
+ I915_WRITE(DVSSURF(pipe), start);
+ POSTING_READ(DVSSURF(pipe));
+}
+
+static void
+snb_disable_plane(struct drm_plane *plane)
+{
+ struct drm_device *dev = plane->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_plane *intel_plane = to_intel_plane(plane);
+ int pipe = intel_plane->pipe;
+
+ I915_WRITE(DVSCNTR(pipe), I915_READ(DVSCNTR(pipe)) & ~DVS_ENABLE);
+ I915_WRITE(DVSSCALE(pipe), 0);
+ I915_WRITE(DVSSURF(pipe), 0);
+ POSTING_READ(DVSSURF(pipe));
+ intel_wait_for_vblank(dev, pipe);
+}
+
+static int
+intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
+ struct drm_framebuffer *fb, int crtc_x, int crtc_y,
+ unsigned int crtc_w, unsigned int crtc_h,
+ uint32_t src_x, uint32_t src_y,
+ uint32_t src_w, uint32_t src_h)
+{
+ struct drm_device *dev = plane->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+ struct intel_plane *intel_plane = to_intel_plane(plane);
+ struct intel_framebuffer *intel_fb;
+ struct drm_i915_gem_object *obj, *old_obj;
+ int pipe = intel_plane->pipe;
+ unsigned long start;
+ int ret = 0;
+ int x = src_x >> 16, y = src_y >> 16;
+ int primary_w = crtc->mode.hdisplay, primary_h = crtc->mode.vdisplay;
+ bool disable_primary = false;
+
+ intel_fb = to_intel_framebuffer(fb);
+ obj = intel_fb->obj;
+
+ old_obj = intel_plane->obj;
+
+ /* Pipe must be running... */
+ if (!(I915_READ(PIPECONF(pipe)) & PIPECONF_ENABLE))
+ return -EINVAL;
+
+ if (crtc_x >= primary_w || crtc_y >= primary_h)
+ return -EINVAL;
+
+ /* Don't modify another pipe's plane */
+ if (intel_plane->pipe != intel_crtc->pipe)
+ return -EINVAL;
+
+ /*
+ * Clamp the width & height into the visible area. Note we don't
+ * try to scale the source if part of the visible region is offscreen.
+ * The caller must handle that by adjusting source offset and size.
+ */
+ if (crtc_x < 0) {
+ crtc_w += crtc_x;
+ crtc_x = 0;
+ }
+ if (crtc_x + crtc_w > primary_w)
+ crtc_w = primary_w - crtc_x;
+
+ if (crtc_y < 0) {
+ crtc_h += crtc_y;
+ crtc_y = 0;
+ }
+ if (crtc_y + crtc_h > primary_h)
+ crtc_h = primary_h - crtc_y;
+
+ /*
+ * We can take a larger source and scale it down, but
+ * only so much... 16x is the max on SNB.
+ */
+ if (((src_w * src_h) / (crtc_w * crtc_h)) > intel_plane->max_downscale)
+ return -EINVAL;
+
+ /*
+ * If the sprite is completely covering the primary plane,
+ * we can disable the primary and save power.
+ */
+ if ((crtc_x == 0) && (crtc_y == 0) &&
+ (crtc_w == primary_w) && (crtc_h == primary_h))
+ disable_primary = true;
+
+ mutex_lock(&dev->struct_mutex);
+
+ if (obj->tiling_mode != I915_TILING_X) {
+ DRM_ERROR("plane surfaces must be X tiled\n");
+ ret = -EINVAL;
+ goto out_unlock;
+ }
+
+ ret = intel_pin_and_fence_fb_obj(dev, obj, NULL);
+ if (ret) {
+ DRM_ERROR("failed to pin object\n");
+ goto out_unlock;
+ }
+
+ drm_gem_object_reference(&obj->base);
+
+ intel_plane->obj = obj;
+
+ start = obj->gtt_offset;
+
+ intel_plane->update_plane(plane, fb, start, crtc_x, crtc_y,
+ crtc_w, crtc_h, x, y, src_w, src_h);
+
+ /* Unpin old obj after new one is active to avoid ugliness */
+ if (old_obj) {
+ /*
+ * It's fairly common to simply update the position of
+ * an existing object. In that case, we don't need to
+ * wait for vblank to avoid ugliness, we only need to
+ * do the pin & ref bookkeeping.
+ */
+ if (old_obj != obj)
+ intel_wait_for_vblank(dev, to_intel_crtc(crtc)->pipe);
+ i915_gem_object_unpin(old_obj);
+ drm_gem_object_unreference(&old_obj->base);
+ }
+
+out_unlock:
+ mutex_unlock(&dev->struct_mutex);
+
+ return ret;
+}
+
+static int
+intel_disable_plane(struct drm_plane *plane)
+{
+ struct drm_device *dev = plane->dev;
+ struct intel_plane *intel_plane = to_intel_plane(plane);
+ int ret = 0;
+
+ mutex_lock(&dev->struct_mutex);
+
+ intel_plane->disable_plane(plane);
+
+ if (!intel_plane->obj)
+ goto out_unlock;
+
+ ret = i915_gem_object_finish_gpu(intel_plane->obj);
+ if (ret)
+ goto out_unlock;
+
+ i915_gem_object_unpin(intel_plane->obj);
+
+ drm_gem_object_unreference(&intel_plane->obj->base);
+
+out_unlock:
+ intel_plane->obj = NULL;
+
+ mutex_unlock(&dev->struct_mutex);
+
+ return ret;
+}
+
+static void intel_destroy_plane(struct drm_plane *plane)
+{
+ struct intel_plane *intel_plane = to_intel_plane(plane);
+ intel_disable_plane(plane);
+ drm_plane_cleanup(plane);
+ kfree(intel_plane);
+}
+
+static const struct drm_plane_funcs intel_plane_funcs = {
+ .update_plane = intel_update_plane,
+ .disable_plane = intel_disable_plane,
+ .destroy = intel_destroy_plane,
+};
+
+static uint32_t snb_plane_formats[] = {
+ V4L2_PIX_FMT_BGR32,
+ V4L2_PIX_FMT_RGB32,
+ V4L2_PIX_FMT_YUYV,
+ V4L2_PIX_FMT_YVYU,
+ V4L2_PIX_FMT_UYVY,
+ V4L2_PIX_FMT_VYUY,
+};
+
+int
+intel_plane_init(struct drm_device *dev, enum pipe pipe)
+{
+ struct intel_plane *intel_plane;
+ unsigned long possible_crtcs;
+ int ret;
+
+ if (!(IS_GEN6(dev) || IS_GEN7(dev))) {
+ DRM_ERROR("new plane code only for SNB+\n");
+ return -ENODEV;
+ }
+
+ intel_plane = kzalloc(sizeof(struct intel_plane), GFP_KERNEL);
+ if (!intel_plane)
+ return -ENOMEM;
+
+ if (IS_GEN6(dev)) {
+ intel_plane->max_downscale = 16;
+ intel_plane->update_plane = snb_update_plane;
+ intel_plane->disable_plane = snb_disable_plane;
+ } else if (IS_GEN7(dev)) {
+ intel_plane->max_downscale = 2;
+ intel_plane->update_plane = ivb_update_plane;
+ intel_plane->disable_plane = ivb_disable_plane;
+ }
+
+ intel_plane->pipe = pipe;
+ possible_crtcs = (1 << pipe);
+ ret = drm_plane_init(dev, &intel_plane->base, possible_crtcs,
+ &intel_plane_funcs, snb_plane_formats,
+ ARRAY_SIZE(snb_plane_formats));
+ if (ret)
+ kfree(intel_plane);
+
+ return ret;
+}
+
--
1.7.4.1
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 2/3] drm/i915: add destination color key support
2011-11-08 21:19 [PATCH 1/3] drm/i915: add SNB and IVB video sprite support Jesse Barnes
@ 2011-11-08 21:19 ` Jesse Barnes
2011-11-08 21:19 ` [PATCH 3/3] drm/i915: track sprite coverage and disable primary plane if possible Jesse Barnes
1 sibling, 0 replies; 9+ messages in thread
From: Jesse Barnes @ 2011-11-08 21:19 UTC (permalink / raw)
To: intel-gfx
Add new ioctls for getting and setting the current destination color
key. This allows for simple overlay display control by matching a color
key value in the primary plane before blending the overlay on top.
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
---
drivers/gpu/drm/i915/i915_dma.c | 2 +
drivers/gpu/drm/i915/i915_reg.h | 2 +
drivers/gpu/drm/i915/intel_drv.h | 8 ++
drivers/gpu/drm/i915/intel_sprite.c | 146 +++++++++++++++++++++++++++++++++++
include/drm/i915_drm.h | 16 ++++
5 files changed, 174 insertions(+), 0 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index 2eac955..0385a27 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -2294,6 +2294,8 @@ struct drm_ioctl_desc i915_ioctls[] = {
DRM_IOCTL_DEF_DRV(I915_GEM_MADVISE, i915_gem_madvise_ioctl, DRM_UNLOCKED),
DRM_IOCTL_DEF_DRV(I915_OVERLAY_PUT_IMAGE, intel_overlay_put_image, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
DRM_IOCTL_DEF_DRV(I915_OVERLAY_ATTRS, intel_overlay_attrs, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+ DRM_IOCTL_DEF_DRV(I915_SET_SPRITE_DESTKEY, intel_sprite_set_destkey, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+ DRM_IOCTL_DEF_DRV(I915_GET_SPRITE_DESTKEY, intel_sprite_get_destkey, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
};
int i915_max_ioctl = DRM_ARRAY_SIZE(i915_ioctls);
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index b2270fa..8bed5d8 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -2724,6 +2724,8 @@
#define DVSSIZE(pipe) _PIPE(pipe, _DVSASIZE, _DVSBSIZE)
#define DVSSCALE(pipe) _PIPE(pipe, _DVSASCALE, _DVSBSCALE)
#define DVSTILEOFF(pipe) _PIPE(pipe, _DVSATILEOFF, _DVSBTILEOFF)
+#define DVSKEYVAL(pipe) _PIPE(pipe, _DVSAKEYVAL, _DVSBKEYVAL)
+#define DVSKEYMSK(pipe) _PIPE(pipe, _DVSAKEYMSK, _DVSBKEYMSK)
#define _SPRA_CTL 0x70280
#define SPRITE_ENABLE (1<<31)
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 6284562..b0081d2 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -189,6 +189,8 @@ struct intel_plane {
uint32_t x, uint32_t y,
uint32_t src_w, uint32_t src_h);
void (*disable_plane)(struct drm_plane *plane);
+ int (*update_destkey)(struct drm_plane *plane, u32 value);
+ u32 (*get_destkey)(struct drm_plane *plane);
};
#define to_intel_crtc(x) container_of(x, struct intel_crtc, base)
@@ -406,4 +408,10 @@ extern void intel_write_eld(struct drm_encoder *encoder,
struct drm_display_mode *mode);
extern void intel_cpt_verify_modeset(struct drm_device *dev, int pipe);
+extern int intel_sprite_set_destkey(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+extern int intel_sprite_get_destkey(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+
+
#endif /* __INTEL_DRV_H__ */
diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
index a4e9721..7c6c6c7 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -99,6 +99,7 @@ ivb_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb,
/* must disable */
sprctl |= SPRITE_TRICKLE_FEED_DISABLE;
sprctl |= SPRITE_ENABLE;
+ sprctl |= SPRITE_DEST_KEY;
/* Sizes are 0 based */
src_w--;
@@ -139,6 +140,45 @@ ivb_disable_plane(struct drm_plane *plane)
intel_wait_for_vblank(dev, pipe);
}
+static int
+ivb_update_destkey(struct drm_plane *plane, u32 value)
+{
+ struct drm_device *dev = plane->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_plane *intel_plane;
+ int ret = 0;
+
+ if (value > 0xffffff)
+ return -EINVAL;
+
+ intel_plane = to_intel_plane(plane);
+
+ mutex_lock(&dev->struct_mutex);
+ I915_WRITE(SPRKEYVAL(intel_plane->pipe), value);
+ I915_WRITE(SPRKEYMSK(intel_plane->pipe), 0xffffff);
+ POSTING_READ(SPRKEYMSK(intel_plane->pipe));
+ mutex_unlock(&dev->struct_mutex);
+
+ return ret;
+}
+
+static u32
+ivb_get_destkey(struct drm_plane *plane)
+{
+ struct drm_device *dev = plane->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_plane *intel_plane;
+ u32 value;
+
+ intel_plane = to_intel_plane(plane);
+
+ mutex_lock(&dev->struct_mutex);
+ value = I915_READ(SPRKEYVAL(intel_plane->pipe));
+ mutex_unlock(&dev->struct_mutex);
+
+ return value;
+}
+
static void
snb_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb,
unsigned long start, int crtc_x, int crtc_y,
@@ -227,6 +267,45 @@ snb_disable_plane(struct drm_plane *plane)
}
static int
+snb_update_destkey(struct drm_plane *plane, u32 value)
+{
+ struct drm_device *dev = plane->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_plane *intel_plane;
+ int ret = 0;
+
+ if (value > 0xffffff)
+ return -EINVAL;
+
+ intel_plane = to_intel_plane(plane);
+
+ mutex_lock(&dev->struct_mutex);
+ I915_WRITE(DVSKEYVAL(intel_plane->pipe), value);
+ I915_WRITE(DVSKEYMSK(intel_plane->pipe), 0xffffff);
+ POSTING_READ(DVSKEYMSK(intel_plane->pipe));
+ mutex_unlock(&dev->struct_mutex);
+
+ return ret;
+}
+
+static u32
+snb_get_destkey(struct drm_plane *plane)
+{
+ struct drm_device *dev = plane->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_plane *intel_plane;
+ u32 value;
+
+ intel_plane = to_intel_plane(plane);
+
+ mutex_lock(&dev->struct_mutex);
+ value = I915_READ(DVSKEYVAL(intel_plane->pipe));
+ mutex_unlock(&dev->struct_mutex);
+
+ return value;
+}
+
+static int
intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
struct drm_framebuffer *fb, int crtc_x, int crtc_y,
unsigned int crtc_w, unsigned int crtc_h,
@@ -377,6 +456,69 @@ static void intel_destroy_plane(struct drm_plane *plane)
kfree(intel_plane);
}
+int intel_sprite_set_destkey(struct drm_device *dev, void *data,
+ struct drm_file *file_priv)
+{
+ struct drm_intel_set_sprite_destkey *set = data;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct drm_mode_object *obj;
+ struct drm_plane *plane;
+ struct intel_plane *intel_plane;
+ int ret = 0;
+
+ if (!dev_priv)
+ return -EINVAL;
+
+ if (set->value > 0xffffff)
+ return -EINVAL;
+
+ mutex_lock(&dev->mode_config.mutex);
+
+ obj = drm_mode_object_find(dev, set->plane_id, DRM_MODE_OBJECT_PLANE);
+ if (!obj) {
+ ret = -EINVAL;
+ goto out_unlock;
+ }
+
+ plane = obj_to_plane(obj);
+ intel_plane = to_intel_plane(plane);
+ ret = intel_plane->update_destkey(plane, set->value);
+
+out_unlock:
+ mutex_unlock(&dev->mode_config.mutex);
+ return ret;
+}
+
+int intel_sprite_get_destkey(struct drm_device *dev, void *data,
+ struct drm_file *file_priv)
+{
+ struct drm_intel_get_sprite_destkey *get = data;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct drm_mode_object *obj;
+ struct drm_plane *plane;
+ struct intel_plane *intel_plane;
+ int ret = 0;
+
+ if (!dev_priv)
+ return -EINVAL;
+
+ mutex_lock(&dev->mode_config.mutex);
+
+ obj = drm_mode_object_find(dev, get->plane_id, DRM_MODE_OBJECT_PLANE);
+ if (!obj) {
+ ret = -EINVAL;
+ goto out_unlock;
+ }
+
+ plane = obj_to_plane(obj);
+ intel_plane = to_intel_plane(plane);
+ get->value = intel_plane->get_destkey(plane);
+
+out_unlock:
+ mutex_unlock(&dev->mode_config.mutex);
+ return ret;
+}
+
static const struct drm_plane_funcs intel_plane_funcs = {
.update_plane = intel_update_plane,
.disable_plane = intel_disable_plane,
@@ -412,10 +554,14 @@ intel_plane_init(struct drm_device *dev, enum pipe pipe)
intel_plane->max_downscale = 16;
intel_plane->update_plane = snb_update_plane;
intel_plane->disable_plane = snb_disable_plane;
+ intel_plane->update_destkey = snb_update_destkey;
+ intel_plane->get_destkey = snb_get_destkey;
} else if (IS_GEN7(dev)) {
intel_plane->max_downscale = 2;
intel_plane->update_plane = ivb_update_plane;
intel_plane->disable_plane = ivb_disable_plane;
+ intel_plane->update_destkey = ivb_update_destkey;
+ intel_plane->get_destkey = ivb_get_destkey;
}
intel_plane->pipe = pipe;
diff --git a/include/drm/i915_drm.h b/include/drm/i915_drm.h
index 28c0d11..71674b3 100644
--- a/include/drm/i915_drm.h
+++ b/include/drm/i915_drm.h
@@ -198,6 +198,8 @@ typedef struct _drm_i915_sarea {
#define DRM_I915_OVERLAY_PUT_IMAGE 0x27
#define DRM_I915_OVERLAY_ATTRS 0x28
#define DRM_I915_GEM_EXECBUFFER2 0x29
+#define DRM_I915_GET_SPRITE_DESTKEY 0x2a
+#define DRM_I915_SET_SPRITE_DESTKEY 0x2b
#define DRM_IOCTL_I915_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT, drm_i915_init_t)
#define DRM_IOCTL_I915_FLUSH DRM_IO ( DRM_COMMAND_BASE + DRM_I915_FLUSH)
@@ -239,6 +241,8 @@ typedef struct _drm_i915_sarea {
#define DRM_IOCTL_I915_GEM_MADVISE DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_MADVISE, struct drm_i915_gem_madvise)
#define DRM_IOCTL_I915_OVERLAY_PUT_IMAGE DRM_IOW(DRM_COMMAND_BASE + DRM_I915_OVERLAY_PUT_IMAGE, struct drm_intel_overlay_put_image)
#define DRM_IOCTL_I915_OVERLAY_ATTRS DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_OVERLAY_ATTRS, struct drm_intel_overlay_attrs)
+#define DRM_IOCTL_I915_SET_SPRITE_DESTKEY DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_SET_SPRITE_DESTKEY, struct drm_intel_set_sprite_destkey)
+#define DRM_IOCTL_I915_GET_SPRITE_DESTKEY DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_SET_SPRITE_DESTKEY, struct drm_intel_get_sprite_destkey)
/* Allow drivers to submit batchbuffers directly to hardware, relying
* on the security mechanisms provided by hardware.
@@ -844,4 +848,16 @@ struct drm_intel_overlay_attrs {
__u32 gamma5;
};
+/* Set the destination color key on a given sprite */
+struct drm_intel_set_sprite_destkey {
+ __u32 plane_id;
+ __u32 value;
+};
+
+/* Get the current destination color key on a given sprite */
+struct drm_intel_get_sprite_destkey {
+ __u32 plane_id;
+ __u32 value;
+};
+
#endif /* _I915_DRM_H_ */
--
1.7.4.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 3/3] drm/i915: track sprite coverage and disable primary plane if possible
2011-11-08 21:19 [PATCH 1/3] drm/i915: add SNB and IVB video sprite support Jesse Barnes
2011-11-08 21:19 ` [PATCH 2/3] drm/i915: add destination color key support Jesse Barnes
@ 2011-11-08 21:19 ` Jesse Barnes
1 sibling, 0 replies; 9+ messages in thread
From: Jesse Barnes @ 2011-11-08 21:19 UTC (permalink / raw)
To: intel-gfx
To save power when the sprite is full screen, we can disable the primary
plane on the same pipe. Track the sprite status and enable/disable the
primary opportunistically.
Signed-off-by: Jesse Barnes
---
drivers/gpu/drm/i915/intel_drv.h | 3 ++
drivers/gpu/drm/i915/intel_sprite.c | 67 +++++++++++++++++++++++++++++++++++
2 files changed, 70 insertions(+), 0 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index b0081d2..d534e1e 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -180,6 +180,7 @@ struct intel_plane {
struct drm_plane base;
enum pipe pipe;
struct drm_i915_gem_object *obj;
+ bool primary_disabled;
int max_downscale;
u32 lut_r[1024], lut_g[1024], lut_b[1024];
void (*update_plane)(struct drm_plane *plane,
@@ -191,6 +192,8 @@ struct intel_plane {
void (*disable_plane)(struct drm_plane *plane);
int (*update_destkey)(struct drm_plane *plane, u32 value);
u32 (*get_destkey)(struct drm_plane *plane);
+ void (*enable_primary)(struct drm_crtc *crtc);
+ void (*disable_primary)(struct drm_crtc *crtc);
};
#define to_intel_crtc(x) container_of(x, struct intel_crtc, base)
diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
index 7c6c6c7..384a4a7 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -48,6 +48,28 @@
*/
static void
+ivb_enable_primary(struct drm_crtc *crtc)
+{
+ struct drm_device *dev = crtc->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+ int reg = DSPCNTR(intel_crtc->plane);
+
+ I915_WRITE(reg, I915_READ(reg) | DISPLAY_PLANE_ENABLE);
+}
+
+static void
+ivb_disable_primary(struct drm_crtc *crtc)
+{
+ struct drm_device *dev = crtc->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+ int reg = DSPCNTR(intel_crtc->plane);
+
+ I915_WRITE(reg, I915_READ(reg) & ~DISPLAY_PLANE_ENABLE);
+}
+
+static void
ivb_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb,
unsigned long start, int crtc_x, int crtc_y,
unsigned int crtc_w, unsigned int crtc_h,
@@ -180,6 +202,28 @@ ivb_get_destkey(struct drm_plane *plane)
}
static void
+snb_enable_primary(struct drm_crtc *crtc)
+{
+ struct drm_device *dev = crtc->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+ int reg = DSPCNTR(intel_crtc->plane);
+
+ I915_WRITE(reg, I915_READ(reg) | DISPLAY_PLANE_ENABLE);
+}
+
+static void
+snb_disable_primary(struct drm_crtc *crtc)
+{
+ struct drm_device *dev = crtc->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+ int reg = DSPCNTR(intel_crtc->plane);
+
+ I915_WRITE(reg, I915_READ(reg) & ~DISPLAY_PLANE_ENABLE);
+}
+
+static void
snb_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb,
unsigned long start, int crtc_x, int crtc_y,
unsigned int crtc_w, unsigned int crtc_h,
@@ -395,9 +439,23 @@ intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
start = obj->gtt_offset;
+ /*
+ * Be sure to re-enable the primary before the sprite is no longer
+ * covering it fully.
+ */
+ if (!disable_primary && intel_plane->primary_disabled) {
+ intel_plane->enable_primary(crtc);
+ intel_plane->primary_disabled = false;
+ }
+
intel_plane->update_plane(plane, fb, start, crtc_x, crtc_y,
crtc_w, crtc_h, x, y, src_w, src_h);
+ if (disable_primary) {
+ intel_plane->disable_primary(crtc);
+ intel_plane->primary_disabled = true;
+ }
+
/* Unpin old obj after new one is active to avoid ugliness */
if (old_obj) {
/*
@@ -427,6 +485,11 @@ intel_disable_plane(struct drm_plane *plane)
mutex_lock(&dev->struct_mutex);
+ if (intel_plane->primary_disabled) {
+ intel_plane->enable_primary(plane->crtc);
+ intel_plane->primary_disabled = false;
+ }
+
intel_plane->disable_plane(plane);
if (!intel_plane->obj)
@@ -556,12 +619,16 @@ intel_plane_init(struct drm_device *dev, enum pipe pipe)
intel_plane->disable_plane = snb_disable_plane;
intel_plane->update_destkey = snb_update_destkey;
intel_plane->get_destkey = snb_get_destkey;
+ intel_plane->enable_primary = ivb_enable_primary;
+ intel_plane->disable_primary = ivb_disable_primary;
} else if (IS_GEN7(dev)) {
intel_plane->max_downscale = 2;
intel_plane->update_plane = ivb_update_plane;
intel_plane->disable_plane = ivb_disable_plane;
intel_plane->update_destkey = ivb_update_destkey;
intel_plane->get_destkey = ivb_get_destkey;
+ intel_plane->enable_primary = snb_enable_primary;
+ intel_plane->disable_primary = snb_disable_primary;
}
intel_plane->pipe = pipe;
--
1.7.4.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH 2/3] drm/i915: add destination color key support
2011-12-07 20:29 ` [PATCH 2/3] drm/i915: add destination color key support Jesse Barnes
@ 2011-12-12 22:14 ` Daniel Vetter
0 siblings, 0 replies; 9+ messages in thread
From: Daniel Vetter @ 2011-12-12 22:14 UTC (permalink / raw)
To: Jesse Barnes; +Cc: intel-gfx
On Wed, Dec 07, 2011 at 12:29:22PM -0800, Jesse Barnes wrote:
> Add new ioctls for getting and setting the current destination color
> key. This allows for simple overlay display control by matching a color
> key value in the primary plane before blending the overlay on top.
>
> v2: remove unnecessary mutex acquire/release around reg accesses
>
> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
[snip]
> +/* Set the destination color key on a given sprite */
> +struct drm_intel_set_sprite_destkey {
> + __u32 plane_id;
> + __u32 value;
> +};
> +
> +/* Get the current destination color key on a given sprite */
> +struct drm_intel_get_sprite_destkey {
> + __u32 plane_id;
> + __u32 value;
> +};
As explained in my top-reply, I think we want a __u32 flags here to
enable the colorkey (and maybe switch between dst/src color key). Nothing
else to complain about here.
-Daniel
--
Daniel Vetter
Mail: daniel@ffwll.ch
Mobile: +41 (0)79 365 57 48
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 2/3] drm/i915: add destination color key support
2011-12-07 20:29 Plane support for SNB and IVB Jesse Barnes
@ 2011-12-07 20:29 ` Jesse Barnes
2011-12-12 22:14 ` Daniel Vetter
0 siblings, 1 reply; 9+ messages in thread
From: Jesse Barnes @ 2011-12-07 20:29 UTC (permalink / raw)
To: intel-gfx
Add new ioctls for getting and setting the current destination color
key. This allows for simple overlay display control by matching a color
key value in the primary plane before blending the overlay on top.
v2: remove unnecessary mutex acquire/release around reg accesses
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
---
drivers/gpu/drm/i915/i915_dma.c | 2 +
drivers/gpu/drm/i915/i915_reg.h | 2 +
drivers/gpu/drm/i915/intel_drv.h | 8 ++
drivers/gpu/drm/i915/intel_sprite.c | 138 +++++++++++++++++++++++++++++++++++
include/drm/i915_drm.h | 16 ++++
5 files changed, 166 insertions(+), 0 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index a9533c5..bc7ee4f 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -2295,6 +2295,8 @@ struct drm_ioctl_desc i915_ioctls[] = {
DRM_IOCTL_DEF_DRV(I915_GEM_MADVISE, i915_gem_madvise_ioctl, DRM_UNLOCKED),
DRM_IOCTL_DEF_DRV(I915_OVERLAY_PUT_IMAGE, intel_overlay_put_image, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
DRM_IOCTL_DEF_DRV(I915_OVERLAY_ATTRS, intel_overlay_attrs, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+ DRM_IOCTL_DEF_DRV(I915_SET_SPRITE_DESTKEY, intel_sprite_set_destkey, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+ DRM_IOCTL_DEF_DRV(I915_GET_SPRITE_DESTKEY, intel_sprite_get_destkey, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
};
int i915_max_ioctl = DRM_ARRAY_SIZE(i915_ioctls);
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index a2ce411..860b250 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -2738,6 +2738,8 @@
#define DVSSIZE(pipe) _PIPE(pipe, _DVSASIZE, _DVSBSIZE)
#define DVSSCALE(pipe) _PIPE(pipe, _DVSASCALE, _DVSBSCALE)
#define DVSTILEOFF(pipe) _PIPE(pipe, _DVSATILEOFF, _DVSBTILEOFF)
+#define DVSKEYVAL(pipe) _PIPE(pipe, _DVSAKEYVAL, _DVSBKEYVAL)
+#define DVSKEYMSK(pipe) _PIPE(pipe, _DVSAKEYMSK, _DVSBKEYMSK)
#define _SPRA_CTL 0x70280
#define SPRITE_ENABLE (1<<31)
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 089cdde..e0407cd 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -190,6 +190,8 @@ struct intel_plane {
uint32_t x, uint32_t y,
uint32_t src_w, uint32_t src_h);
void (*disable_plane)(struct drm_plane *plane);
+ int (*update_destkey)(struct drm_plane *plane, u32 value);
+ u32 (*get_destkey)(struct drm_plane *plane);
};
#define to_intel_crtc(x) container_of(x, struct intel_crtc, base)
@@ -412,4 +414,10 @@ extern void sandybridge_update_wm(struct drm_device *dev);
extern void intel_update_sprite_watermarks(struct drm_device *dev, int pipe,
uint32_t sprite_width,
int pixel_size);
+
+extern int intel_sprite_set_destkey(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+extern int intel_sprite_get_destkey(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+
#endif /* __INTEL_DRV_H__ */
diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
index 18eb7b8..a51edc9 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -96,6 +96,7 @@ ivb_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb,
/* must disable */
sprctl |= SPRITE_TRICKLE_FEED_DISABLE;
sprctl |= SPRITE_ENABLE;
+ sprctl |= SPRITE_DEST_KEY;
/* Sizes are 0 based */
src_w--;
@@ -154,6 +155,41 @@ ivb_disable_plane(struct drm_plane *plane)
POSTING_READ(SPRSURF(pipe));
}
+static int
+ivb_update_destkey(struct drm_plane *plane, u32 value)
+{
+ struct drm_device *dev = plane->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_plane *intel_plane;
+ int ret = 0;
+
+ if (value > 0xffffff)
+ return -EINVAL;
+
+ intel_plane = to_intel_plane(plane);
+
+ I915_WRITE(SPRKEYVAL(intel_plane->pipe), value);
+ I915_WRITE(SPRKEYMSK(intel_plane->pipe), 0xffffff);
+ POSTING_READ(SPRKEYMSK(intel_plane->pipe));
+
+ return ret;
+}
+
+static u32
+ivb_get_destkey(struct drm_plane *plane)
+{
+ struct drm_device *dev = plane->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_plane *intel_plane;
+ u32 value;
+
+ intel_plane = to_intel_plane(plane);
+
+ value = I915_READ(SPRKEYVAL(intel_plane->pipe));
+
+ return value;
+}
+
static void
snb_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb,
struct drm_i915_gem_object *obj, int crtc_x, int crtc_y,
@@ -259,6 +295,41 @@ snb_disable_plane(struct drm_plane *plane)
}
static int
+snb_update_destkey(struct drm_plane *plane, u32 value)
+{
+ struct drm_device *dev = plane->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_plane *intel_plane;
+ int ret = 0;
+
+ if (value > 0xffffff)
+ return -EINVAL;
+
+ intel_plane = to_intel_plane(plane);
+
+ I915_WRITE(DVSKEYVAL(intel_plane->pipe), value);
+ I915_WRITE(DVSKEYMSK(intel_plane->pipe), 0xffffff);
+ POSTING_READ(DVSKEYMSK(intel_plane->pipe));
+
+ return ret;
+}
+
+static u32
+snb_get_destkey(struct drm_plane *plane)
+{
+ struct drm_device *dev = plane->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_plane *intel_plane;
+ u32 value;
+
+ intel_plane = to_intel_plane(plane);
+
+ value = I915_READ(DVSKEYVAL(intel_plane->pipe));
+
+ return value;
+}
+
+static int
intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
struct drm_framebuffer *fb, int crtc_x, int crtc_y,
unsigned int crtc_w, unsigned int crtc_h,
@@ -398,6 +469,69 @@ static void intel_destroy_plane(struct drm_plane *plane)
kfree(intel_plane);
}
+int intel_sprite_set_destkey(struct drm_device *dev, void *data,
+ struct drm_file *file_priv)
+{
+ struct drm_intel_set_sprite_destkey *set = data;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct drm_mode_object *obj;
+ struct drm_plane *plane;
+ struct intel_plane *intel_plane;
+ int ret = 0;
+
+ if (!dev_priv)
+ return -EINVAL;
+
+ if (set->value > 0xffffff)
+ return -EINVAL;
+
+ mutex_lock(&dev->mode_config.mutex);
+
+ obj = drm_mode_object_find(dev, set->plane_id, DRM_MODE_OBJECT_PLANE);
+ if (!obj) {
+ ret = -EINVAL;
+ goto out_unlock;
+ }
+
+ plane = obj_to_plane(obj);
+ intel_plane = to_intel_plane(plane);
+ ret = intel_plane->update_destkey(plane, set->value);
+
+out_unlock:
+ mutex_unlock(&dev->mode_config.mutex);
+ return ret;
+}
+
+int intel_sprite_get_destkey(struct drm_device *dev, void *data,
+ struct drm_file *file_priv)
+{
+ struct drm_intel_get_sprite_destkey *get = data;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct drm_mode_object *obj;
+ struct drm_plane *plane;
+ struct intel_plane *intel_plane;
+ int ret = 0;
+
+ if (!dev_priv)
+ return -EINVAL;
+
+ mutex_lock(&dev->mode_config.mutex);
+
+ obj = drm_mode_object_find(dev, get->plane_id, DRM_MODE_OBJECT_PLANE);
+ if (!obj) {
+ ret = -EINVAL;
+ goto out_unlock;
+ }
+
+ plane = obj_to_plane(obj);
+ intel_plane = to_intel_plane(plane);
+ get->value = intel_plane->get_destkey(plane);
+
+out_unlock:
+ mutex_unlock(&dev->mode_config.mutex);
+ return ret;
+}
+
static const struct drm_plane_funcs intel_plane_funcs = {
.update_plane = intel_update_plane,
.disable_plane = intel_disable_plane,
@@ -433,10 +567,14 @@ intel_plane_init(struct drm_device *dev, enum pipe pipe)
intel_plane->max_downscale = 16;
intel_plane->update_plane = snb_update_plane;
intel_plane->disable_plane = snb_disable_plane;
+ intel_plane->update_destkey = snb_update_destkey;
+ intel_plane->get_destkey = snb_get_destkey;
} else if (IS_GEN7(dev)) {
intel_plane->max_downscale = 2;
intel_plane->update_plane = ivb_update_plane;
intel_plane->disable_plane = ivb_disable_plane;
+ intel_plane->update_destkey = ivb_update_destkey;
+ intel_plane->get_destkey = ivb_get_destkey;
}
intel_plane->pipe = pipe;
diff --git a/include/drm/i915_drm.h b/include/drm/i915_drm.h
index 28c0d11..71674b3 100644
--- a/include/drm/i915_drm.h
+++ b/include/drm/i915_drm.h
@@ -198,6 +198,8 @@ typedef struct _drm_i915_sarea {
#define DRM_I915_OVERLAY_PUT_IMAGE 0x27
#define DRM_I915_OVERLAY_ATTRS 0x28
#define DRM_I915_GEM_EXECBUFFER2 0x29
+#define DRM_I915_GET_SPRITE_DESTKEY 0x2a
+#define DRM_I915_SET_SPRITE_DESTKEY 0x2b
#define DRM_IOCTL_I915_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT, drm_i915_init_t)
#define DRM_IOCTL_I915_FLUSH DRM_IO ( DRM_COMMAND_BASE + DRM_I915_FLUSH)
@@ -239,6 +241,8 @@ typedef struct _drm_i915_sarea {
#define DRM_IOCTL_I915_GEM_MADVISE DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_MADVISE, struct drm_i915_gem_madvise)
#define DRM_IOCTL_I915_OVERLAY_PUT_IMAGE DRM_IOW(DRM_COMMAND_BASE + DRM_I915_OVERLAY_PUT_IMAGE, struct drm_intel_overlay_put_image)
#define DRM_IOCTL_I915_OVERLAY_ATTRS DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_OVERLAY_ATTRS, struct drm_intel_overlay_attrs)
+#define DRM_IOCTL_I915_SET_SPRITE_DESTKEY DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_SET_SPRITE_DESTKEY, struct drm_intel_set_sprite_destkey)
+#define DRM_IOCTL_I915_GET_SPRITE_DESTKEY DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_SET_SPRITE_DESTKEY, struct drm_intel_get_sprite_destkey)
/* Allow drivers to submit batchbuffers directly to hardware, relying
* on the security mechanisms provided by hardware.
@@ -844,4 +848,16 @@ struct drm_intel_overlay_attrs {
__u32 gamma5;
};
+/* Set the destination color key on a given sprite */
+struct drm_intel_set_sprite_destkey {
+ __u32 plane_id;
+ __u32 value;
+};
+
+/* Get the current destination color key on a given sprite */
+struct drm_intel_get_sprite_destkey {
+ __u32 plane_id;
+ __u32 value;
+};
+
#endif /* _I915_DRM_H_ */
--
1.7.4.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH 2/3] drm/i915: add destination color key support
2011-11-16 16:10 ` Daniel Vetter
@ 2011-11-16 16:48 ` Jesse Barnes
0 siblings, 0 replies; 9+ messages in thread
From: Jesse Barnes @ 2011-11-16 16:48 UTC (permalink / raw)
To: Daniel Vetter; +Cc: intel-gfx
On Wed, 16 Nov 2011 17:10:53 +0100
Daniel Vetter <daniel@ffwll.ch> wrote:
> On Mon, Nov 14, 2011 at 21:22, Jesse Barnes <jbarnes@virtuousgeek.org> wrote:
> > Add new ioctls for getting and setting the current destination color
> > key. This allows for simple overlay display control by matching a color
> > key value in the primary plane before blending the overlay on top.
> >
> > Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
>
> Just a few comments because reviewing patches here is a royal pain:
> - Is taking dev->struct_mutex really required around the register access?
Oh did I leave them in place for these paths? I'll drop them too.
> - You unconditionally enable the color key. Do we anticipate any other
> uses (like no color key or dst color key) or is this just the
> make-Xv-work ioctl?
I was thinking of that... W/o a src or dest key, the overlay will
always be on top. That's probably reasonable for simple cases, so
having a "key present" flag makes sense.
Which means setting a 0 dest key would mean "disable dest key" and go
back to the default behavior. So the interface would stay the same
even if we added other key types in the future.
--
Jesse Barnes, Intel Open Source Technology Center
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 2/3] drm/i915: add destination color key support
2011-11-14 20:22 ` [PATCH 2/3] drm/i915: add destination color key support Jesse Barnes
@ 2011-11-16 16:10 ` Daniel Vetter
2011-11-16 16:48 ` Jesse Barnes
0 siblings, 1 reply; 9+ messages in thread
From: Daniel Vetter @ 2011-11-16 16:10 UTC (permalink / raw)
To: Jesse Barnes; +Cc: intel-gfx
On Mon, Nov 14, 2011 at 21:22, Jesse Barnes <jbarnes@virtuousgeek.org> wrote:
> Add new ioctls for getting and setting the current destination color
> key. This allows for simple overlay display control by matching a color
> key value in the primary plane before blending the overlay on top.
>
> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Just a few comments because reviewing patches here is a royal pain:
- Is taking dev->struct_mutex really required around the register access?
- You unconditionally enable the color key. Do we anticipate any other
uses (like no color key or dst color key) or is this just the
make-Xv-work ioctl?
- Same for the mask ....
Cheers, Daniel
--
Daniel Vetter
daniel.vetter@ffwll.ch - +41 (0) 79 364 57 48 - http://blog.ffwll.ch
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 2/3] drm/i915: add destination color key support
2011-11-14 20:22 [PATCH 1/3] drm/i915: add SNB and IVB video sprite support v2 Jesse Barnes
@ 2011-11-14 20:22 ` Jesse Barnes
2011-11-16 16:10 ` Daniel Vetter
0 siblings, 1 reply; 9+ messages in thread
From: Jesse Barnes @ 2011-11-14 20:22 UTC (permalink / raw)
To: intel-gfx
Add new ioctls for getting and setting the current destination color
key. This allows for simple overlay display control by matching a color
key value in the primary plane before blending the overlay on top.
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
---
drivers/gpu/drm/i915/i915_dma.c | 2 +
drivers/gpu/drm/i915/i915_reg.h | 2 +
drivers/gpu/drm/i915/intel_drv.h | 8 ++
drivers/gpu/drm/i915/intel_sprite.c | 146 +++++++++++++++++++++++++++++++++++
include/drm/i915_drm.h | 16 ++++
5 files changed, 174 insertions(+), 0 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index 2eac955..0385a27 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -2294,6 +2294,8 @@ struct drm_ioctl_desc i915_ioctls[] = {
DRM_IOCTL_DEF_DRV(I915_GEM_MADVISE, i915_gem_madvise_ioctl, DRM_UNLOCKED),
DRM_IOCTL_DEF_DRV(I915_OVERLAY_PUT_IMAGE, intel_overlay_put_image, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
DRM_IOCTL_DEF_DRV(I915_OVERLAY_ATTRS, intel_overlay_attrs, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+ DRM_IOCTL_DEF_DRV(I915_SET_SPRITE_DESTKEY, intel_sprite_set_destkey, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+ DRM_IOCTL_DEF_DRV(I915_GET_SPRITE_DESTKEY, intel_sprite_get_destkey, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
};
int i915_max_ioctl = DRM_ARRAY_SIZE(i915_ioctls);
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 7929a55..d486bab 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -2726,6 +2726,8 @@
#define DVSSIZE(pipe) _PIPE(pipe, _DVSASIZE, _DVSBSIZE)
#define DVSSCALE(pipe) _PIPE(pipe, _DVSASCALE, _DVSBSCALE)
#define DVSTILEOFF(pipe) _PIPE(pipe, _DVSATILEOFF, _DVSBTILEOFF)
+#define DVSKEYVAL(pipe) _PIPE(pipe, _DVSAKEYVAL, _DVSBKEYVAL)
+#define DVSKEYMSK(pipe) _PIPE(pipe, _DVSAKEYMSK, _DVSBKEYMSK)
#define _SPRA_CTL 0x70280
#define SPRITE_ENABLE (1<<31)
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index f91de00..68ef060 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -190,6 +190,8 @@ struct intel_plane {
uint32_t x, uint32_t y,
uint32_t src_w, uint32_t src_h);
void (*disable_plane)(struct drm_plane *plane);
+ int (*update_destkey)(struct drm_plane *plane, u32 value);
+ u32 (*get_destkey)(struct drm_plane *plane);
};
#define to_intel_crtc(x) container_of(x, struct intel_crtc, base)
@@ -407,4 +409,10 @@ extern void intel_write_eld(struct drm_encoder *encoder,
struct drm_display_mode *mode);
extern void intel_cpt_verify_modeset(struct drm_device *dev, int pipe);
+extern int intel_sprite_set_destkey(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+extern int intel_sprite_get_destkey(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+
+
#endif /* __INTEL_DRV_H__ */
diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
index d8ae3e4..b470e9b 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -99,6 +99,7 @@ ivb_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb,
/* must disable */
sprctl |= SPRITE_TRICKLE_FEED_DISABLE;
sprctl |= SPRITE_ENABLE;
+ sprctl |= SPRITE_DEST_KEY;
/* Sizes are 0 based */
src_w--;
@@ -140,6 +141,45 @@ ivb_disable_plane(struct drm_plane *plane)
POSTING_READ(SPRSURF(pipe));
}
+static int
+ivb_update_destkey(struct drm_plane *plane, u32 value)
+{
+ struct drm_device *dev = plane->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_plane *intel_plane;
+ int ret = 0;
+
+ if (value > 0xffffff)
+ return -EINVAL;
+
+ intel_plane = to_intel_plane(plane);
+
+ mutex_lock(&dev->struct_mutex);
+ I915_WRITE(SPRKEYVAL(intel_plane->pipe), value);
+ I915_WRITE(SPRKEYMSK(intel_plane->pipe), 0xffffff);
+ POSTING_READ(SPRKEYMSK(intel_plane->pipe));
+ mutex_unlock(&dev->struct_mutex);
+
+ return ret;
+}
+
+static u32
+ivb_get_destkey(struct drm_plane *plane)
+{
+ struct drm_device *dev = plane->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_plane *intel_plane;
+ u32 value;
+
+ intel_plane = to_intel_plane(plane);
+
+ mutex_lock(&dev->struct_mutex);
+ value = I915_READ(SPRKEYVAL(intel_plane->pipe));
+ mutex_unlock(&dev->struct_mutex);
+
+ return value;
+}
+
static void
snb_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb,
struct drm_i915_gem_object *obj, int crtc_x, int crtc_y,
@@ -228,6 +268,45 @@ snb_disable_plane(struct drm_plane *plane)
}
static int
+snb_update_destkey(struct drm_plane *plane, u32 value)
+{
+ struct drm_device *dev = plane->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_plane *intel_plane;
+ int ret = 0;
+
+ if (value > 0xffffff)
+ return -EINVAL;
+
+ intel_plane = to_intel_plane(plane);
+
+ mutex_lock(&dev->struct_mutex);
+ I915_WRITE(DVSKEYVAL(intel_plane->pipe), value);
+ I915_WRITE(DVSKEYMSK(intel_plane->pipe), 0xffffff);
+ POSTING_READ(DVSKEYMSK(intel_plane->pipe));
+ mutex_unlock(&dev->struct_mutex);
+
+ return ret;
+}
+
+static u32
+snb_get_destkey(struct drm_plane *plane)
+{
+ struct drm_device *dev = plane->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_plane *intel_plane;
+ u32 value;
+
+ intel_plane = to_intel_plane(plane);
+
+ mutex_lock(&dev->struct_mutex);
+ value = I915_READ(DVSKEYVAL(intel_plane->pipe));
+ mutex_unlock(&dev->struct_mutex);
+
+ return value;
+}
+
+static int
intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
struct drm_framebuffer *fb, int crtc_x, int crtc_y,
unsigned int crtc_w, unsigned int crtc_h,
@@ -371,6 +450,69 @@ static void intel_destroy_plane(struct drm_plane *plane)
kfree(intel_plane);
}
+int intel_sprite_set_destkey(struct drm_device *dev, void *data,
+ struct drm_file *file_priv)
+{
+ struct drm_intel_set_sprite_destkey *set = data;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct drm_mode_object *obj;
+ struct drm_plane *plane;
+ struct intel_plane *intel_plane;
+ int ret = 0;
+
+ if (!dev_priv)
+ return -EINVAL;
+
+ if (set->value > 0xffffff)
+ return -EINVAL;
+
+ mutex_lock(&dev->mode_config.mutex);
+
+ obj = drm_mode_object_find(dev, set->plane_id, DRM_MODE_OBJECT_PLANE);
+ if (!obj) {
+ ret = -EINVAL;
+ goto out_unlock;
+ }
+
+ plane = obj_to_plane(obj);
+ intel_plane = to_intel_plane(plane);
+ ret = intel_plane->update_destkey(plane, set->value);
+
+out_unlock:
+ mutex_unlock(&dev->mode_config.mutex);
+ return ret;
+}
+
+int intel_sprite_get_destkey(struct drm_device *dev, void *data,
+ struct drm_file *file_priv)
+{
+ struct drm_intel_get_sprite_destkey *get = data;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct drm_mode_object *obj;
+ struct drm_plane *plane;
+ struct intel_plane *intel_plane;
+ int ret = 0;
+
+ if (!dev_priv)
+ return -EINVAL;
+
+ mutex_lock(&dev->mode_config.mutex);
+
+ obj = drm_mode_object_find(dev, get->plane_id, DRM_MODE_OBJECT_PLANE);
+ if (!obj) {
+ ret = -EINVAL;
+ goto out_unlock;
+ }
+
+ plane = obj_to_plane(obj);
+ intel_plane = to_intel_plane(plane);
+ get->value = intel_plane->get_destkey(plane);
+
+out_unlock:
+ mutex_unlock(&dev->mode_config.mutex);
+ return ret;
+}
+
static const struct drm_plane_funcs intel_plane_funcs = {
.update_plane = intel_update_plane,
.disable_plane = intel_disable_plane,
@@ -406,10 +548,14 @@ intel_plane_init(struct drm_device *dev, enum pipe pipe)
intel_plane->max_downscale = 16;
intel_plane->update_plane = snb_update_plane;
intel_plane->disable_plane = snb_disable_plane;
+ intel_plane->update_destkey = snb_update_destkey;
+ intel_plane->get_destkey = snb_get_destkey;
} else if (IS_GEN7(dev)) {
intel_plane->max_downscale = 2;
intel_plane->update_plane = ivb_update_plane;
intel_plane->disable_plane = ivb_disable_plane;
+ intel_plane->update_destkey = ivb_update_destkey;
+ intel_plane->get_destkey = ivb_get_destkey;
}
intel_plane->pipe = pipe;
diff --git a/include/drm/i915_drm.h b/include/drm/i915_drm.h
index 28c0d11..71674b3 100644
--- a/include/drm/i915_drm.h
+++ b/include/drm/i915_drm.h
@@ -198,6 +198,8 @@ typedef struct _drm_i915_sarea {
#define DRM_I915_OVERLAY_PUT_IMAGE 0x27
#define DRM_I915_OVERLAY_ATTRS 0x28
#define DRM_I915_GEM_EXECBUFFER2 0x29
+#define DRM_I915_GET_SPRITE_DESTKEY 0x2a
+#define DRM_I915_SET_SPRITE_DESTKEY 0x2b
#define DRM_IOCTL_I915_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT, drm_i915_init_t)
#define DRM_IOCTL_I915_FLUSH DRM_IO ( DRM_COMMAND_BASE + DRM_I915_FLUSH)
@@ -239,6 +241,8 @@ typedef struct _drm_i915_sarea {
#define DRM_IOCTL_I915_GEM_MADVISE DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_MADVISE, struct drm_i915_gem_madvise)
#define DRM_IOCTL_I915_OVERLAY_PUT_IMAGE DRM_IOW(DRM_COMMAND_BASE + DRM_I915_OVERLAY_PUT_IMAGE, struct drm_intel_overlay_put_image)
#define DRM_IOCTL_I915_OVERLAY_ATTRS DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_OVERLAY_ATTRS, struct drm_intel_overlay_attrs)
+#define DRM_IOCTL_I915_SET_SPRITE_DESTKEY DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_SET_SPRITE_DESTKEY, struct drm_intel_set_sprite_destkey)
+#define DRM_IOCTL_I915_GET_SPRITE_DESTKEY DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_SET_SPRITE_DESTKEY, struct drm_intel_get_sprite_destkey)
/* Allow drivers to submit batchbuffers directly to hardware, relying
* on the security mechanisms provided by hardware.
@@ -844,4 +848,16 @@ struct drm_intel_overlay_attrs {
__u32 gamma5;
};
+/* Set the destination color key on a given sprite */
+struct drm_intel_set_sprite_destkey {
+ __u32 plane_id;
+ __u32 value;
+};
+
+/* Get the current destination color key on a given sprite */
+struct drm_intel_get_sprite_destkey {
+ __u32 plane_id;
+ __u32 value;
+};
+
#endif /* _I915_DRM_H_ */
--
1.7.4.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 2/3] drm/i915: add destination color key support
2011-11-14 19:47 [PATCH 1/3] drm/i915: add SNB and IVB video sprite support v2 Jesse Barnes
@ 2011-11-14 19:47 ` Jesse Barnes
0 siblings, 0 replies; 9+ messages in thread
From: Jesse Barnes @ 2011-11-14 19:47 UTC (permalink / raw)
To: intel-gfx
Add new ioctls for getting and setting the current destination color
key. This allows for simple overlay display control by matching a color
key value in the primary plane before blending the overlay on top.
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
---
drivers/gpu/drm/i915/i915_dma.c | 2 +
drivers/gpu/drm/i915/i915_reg.h | 2 +
drivers/gpu/drm/i915/intel_drv.h | 8 ++
drivers/gpu/drm/i915/intel_sprite.c | 146 +++++++++++++++++++++++++++++++++++
include/drm/i915_drm.h | 16 ++++
5 files changed, 174 insertions(+), 0 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index 2eac955..0385a27 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -2294,6 +2294,8 @@ struct drm_ioctl_desc i915_ioctls[] = {
DRM_IOCTL_DEF_DRV(I915_GEM_MADVISE, i915_gem_madvise_ioctl, DRM_UNLOCKED),
DRM_IOCTL_DEF_DRV(I915_OVERLAY_PUT_IMAGE, intel_overlay_put_image, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
DRM_IOCTL_DEF_DRV(I915_OVERLAY_ATTRS, intel_overlay_attrs, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+ DRM_IOCTL_DEF_DRV(I915_SET_SPRITE_DESTKEY, intel_sprite_set_destkey, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+ DRM_IOCTL_DEF_DRV(I915_GET_SPRITE_DESTKEY, intel_sprite_get_destkey, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
};
int i915_max_ioctl = DRM_ARRAY_SIZE(i915_ioctls);
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 7929a55..d486bab 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -2726,6 +2726,8 @@
#define DVSSIZE(pipe) _PIPE(pipe, _DVSASIZE, _DVSBSIZE)
#define DVSSCALE(pipe) _PIPE(pipe, _DVSASCALE, _DVSBSCALE)
#define DVSTILEOFF(pipe) _PIPE(pipe, _DVSATILEOFF, _DVSBTILEOFF)
+#define DVSKEYVAL(pipe) _PIPE(pipe, _DVSAKEYVAL, _DVSBKEYVAL)
+#define DVSKEYMSK(pipe) _PIPE(pipe, _DVSAKEYMSK, _DVSBKEYMSK)
#define _SPRA_CTL 0x70280
#define SPRITE_ENABLE (1<<31)
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index f91de00..68ef060 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -190,6 +190,8 @@ struct intel_plane {
uint32_t x, uint32_t y,
uint32_t src_w, uint32_t src_h);
void (*disable_plane)(struct drm_plane *plane);
+ int (*update_destkey)(struct drm_plane *plane, u32 value);
+ u32 (*get_destkey)(struct drm_plane *plane);
};
#define to_intel_crtc(x) container_of(x, struct intel_crtc, base)
@@ -407,4 +409,10 @@ extern void intel_write_eld(struct drm_encoder *encoder,
struct drm_display_mode *mode);
extern void intel_cpt_verify_modeset(struct drm_device *dev, int pipe);
+extern int intel_sprite_set_destkey(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+extern int intel_sprite_get_destkey(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+
+
#endif /* __INTEL_DRV_H__ */
diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
index d8ae3e4..b470e9b 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -99,6 +99,7 @@ ivb_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb,
/* must disable */
sprctl |= SPRITE_TRICKLE_FEED_DISABLE;
sprctl |= SPRITE_ENABLE;
+ sprctl |= SPRITE_DEST_KEY;
/* Sizes are 0 based */
src_w--;
@@ -140,6 +141,45 @@ ivb_disable_plane(struct drm_plane *plane)
POSTING_READ(SPRSURF(pipe));
}
+static int
+ivb_update_destkey(struct drm_plane *plane, u32 value)
+{
+ struct drm_device *dev = plane->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_plane *intel_plane;
+ int ret = 0;
+
+ if (value > 0xffffff)
+ return -EINVAL;
+
+ intel_plane = to_intel_plane(plane);
+
+ mutex_lock(&dev->struct_mutex);
+ I915_WRITE(SPRKEYVAL(intel_plane->pipe), value);
+ I915_WRITE(SPRKEYMSK(intel_plane->pipe), 0xffffff);
+ POSTING_READ(SPRKEYMSK(intel_plane->pipe));
+ mutex_unlock(&dev->struct_mutex);
+
+ return ret;
+}
+
+static u32
+ivb_get_destkey(struct drm_plane *plane)
+{
+ struct drm_device *dev = plane->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_plane *intel_plane;
+ u32 value;
+
+ intel_plane = to_intel_plane(plane);
+
+ mutex_lock(&dev->struct_mutex);
+ value = I915_READ(SPRKEYVAL(intel_plane->pipe));
+ mutex_unlock(&dev->struct_mutex);
+
+ return value;
+}
+
static void
snb_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb,
struct drm_i915_gem_object *obj, int crtc_x, int crtc_y,
@@ -228,6 +268,45 @@ snb_disable_plane(struct drm_plane *plane)
}
static int
+snb_update_destkey(struct drm_plane *plane, u32 value)
+{
+ struct drm_device *dev = plane->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_plane *intel_plane;
+ int ret = 0;
+
+ if (value > 0xffffff)
+ return -EINVAL;
+
+ intel_plane = to_intel_plane(plane);
+
+ mutex_lock(&dev->struct_mutex);
+ I915_WRITE(DVSKEYVAL(intel_plane->pipe), value);
+ I915_WRITE(DVSKEYMSK(intel_plane->pipe), 0xffffff);
+ POSTING_READ(DVSKEYMSK(intel_plane->pipe));
+ mutex_unlock(&dev->struct_mutex);
+
+ return ret;
+}
+
+static u32
+snb_get_destkey(struct drm_plane *plane)
+{
+ struct drm_device *dev = plane->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_plane *intel_plane;
+ u32 value;
+
+ intel_plane = to_intel_plane(plane);
+
+ mutex_lock(&dev->struct_mutex);
+ value = I915_READ(DVSKEYVAL(intel_plane->pipe));
+ mutex_unlock(&dev->struct_mutex);
+
+ return value;
+}
+
+static int
intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
struct drm_framebuffer *fb, int crtc_x, int crtc_y,
unsigned int crtc_w, unsigned int crtc_h,
@@ -371,6 +450,69 @@ static void intel_destroy_plane(struct drm_plane *plane)
kfree(intel_plane);
}
+int intel_sprite_set_destkey(struct drm_device *dev, void *data,
+ struct drm_file *file_priv)
+{
+ struct drm_intel_set_sprite_destkey *set = data;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct drm_mode_object *obj;
+ struct drm_plane *plane;
+ struct intel_plane *intel_plane;
+ int ret = 0;
+
+ if (!dev_priv)
+ return -EINVAL;
+
+ if (set->value > 0xffffff)
+ return -EINVAL;
+
+ mutex_lock(&dev->mode_config.mutex);
+
+ obj = drm_mode_object_find(dev, set->plane_id, DRM_MODE_OBJECT_PLANE);
+ if (!obj) {
+ ret = -EINVAL;
+ goto out_unlock;
+ }
+
+ plane = obj_to_plane(obj);
+ intel_plane = to_intel_plane(plane);
+ ret = intel_plane->update_destkey(plane, set->value);
+
+out_unlock:
+ mutex_unlock(&dev->mode_config.mutex);
+ return ret;
+}
+
+int intel_sprite_get_destkey(struct drm_device *dev, void *data,
+ struct drm_file *file_priv)
+{
+ struct drm_intel_get_sprite_destkey *get = data;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct drm_mode_object *obj;
+ struct drm_plane *plane;
+ struct intel_plane *intel_plane;
+ int ret = 0;
+
+ if (!dev_priv)
+ return -EINVAL;
+
+ mutex_lock(&dev->mode_config.mutex);
+
+ obj = drm_mode_object_find(dev, get->plane_id, DRM_MODE_OBJECT_PLANE);
+ if (!obj) {
+ ret = -EINVAL;
+ goto out_unlock;
+ }
+
+ plane = obj_to_plane(obj);
+ intel_plane = to_intel_plane(plane);
+ get->value = intel_plane->get_destkey(plane);
+
+out_unlock:
+ mutex_unlock(&dev->mode_config.mutex);
+ return ret;
+}
+
static const struct drm_plane_funcs intel_plane_funcs = {
.update_plane = intel_update_plane,
.disable_plane = intel_disable_plane,
@@ -406,10 +548,14 @@ intel_plane_init(struct drm_device *dev, enum pipe pipe)
intel_plane->max_downscale = 16;
intel_plane->update_plane = snb_update_plane;
intel_plane->disable_plane = snb_disable_plane;
+ intel_plane->update_destkey = snb_update_destkey;
+ intel_plane->get_destkey = snb_get_destkey;
} else if (IS_GEN7(dev)) {
intel_plane->max_downscale = 2;
intel_plane->update_plane = ivb_update_plane;
intel_plane->disable_plane = ivb_disable_plane;
+ intel_plane->update_destkey = ivb_update_destkey;
+ intel_plane->get_destkey = ivb_get_destkey;
}
intel_plane->pipe = pipe;
diff --git a/include/drm/i915_drm.h b/include/drm/i915_drm.h
index 28c0d11..71674b3 100644
--- a/include/drm/i915_drm.h
+++ b/include/drm/i915_drm.h
@@ -198,6 +198,8 @@ typedef struct _drm_i915_sarea {
#define DRM_I915_OVERLAY_PUT_IMAGE 0x27
#define DRM_I915_OVERLAY_ATTRS 0x28
#define DRM_I915_GEM_EXECBUFFER2 0x29
+#define DRM_I915_GET_SPRITE_DESTKEY 0x2a
+#define DRM_I915_SET_SPRITE_DESTKEY 0x2b
#define DRM_IOCTL_I915_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT, drm_i915_init_t)
#define DRM_IOCTL_I915_FLUSH DRM_IO ( DRM_COMMAND_BASE + DRM_I915_FLUSH)
@@ -239,6 +241,8 @@ typedef struct _drm_i915_sarea {
#define DRM_IOCTL_I915_GEM_MADVISE DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_MADVISE, struct drm_i915_gem_madvise)
#define DRM_IOCTL_I915_OVERLAY_PUT_IMAGE DRM_IOW(DRM_COMMAND_BASE + DRM_I915_OVERLAY_PUT_IMAGE, struct drm_intel_overlay_put_image)
#define DRM_IOCTL_I915_OVERLAY_ATTRS DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_OVERLAY_ATTRS, struct drm_intel_overlay_attrs)
+#define DRM_IOCTL_I915_SET_SPRITE_DESTKEY DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_SET_SPRITE_DESTKEY, struct drm_intel_set_sprite_destkey)
+#define DRM_IOCTL_I915_GET_SPRITE_DESTKEY DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_SET_SPRITE_DESTKEY, struct drm_intel_get_sprite_destkey)
/* Allow drivers to submit batchbuffers directly to hardware, relying
* on the security mechanisms provided by hardware.
@@ -844,4 +848,16 @@ struct drm_intel_overlay_attrs {
__u32 gamma5;
};
+/* Set the destination color key on a given sprite */
+struct drm_intel_set_sprite_destkey {
+ __u32 plane_id;
+ __u32 value;
+};
+
+/* Get the current destination color key on a given sprite */
+struct drm_intel_get_sprite_destkey {
+ __u32 plane_id;
+ __u32 value;
+};
+
#endif /* _I915_DRM_H_ */
--
1.7.4.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
end of thread, other threads:[~2011-12-12 22:13 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-11-08 21:19 [PATCH 1/3] drm/i915: add SNB and IVB video sprite support Jesse Barnes
2011-11-08 21:19 ` [PATCH 2/3] drm/i915: add destination color key support Jesse Barnes
2011-11-08 21:19 ` [PATCH 3/3] drm/i915: track sprite coverage and disable primary plane if possible Jesse Barnes
2011-11-14 19:47 [PATCH 1/3] drm/i915: add SNB and IVB video sprite support v2 Jesse Barnes
2011-11-14 19:47 ` [PATCH 2/3] drm/i915: add destination color key support Jesse Barnes
2011-11-14 20:22 [PATCH 1/3] drm/i915: add SNB and IVB video sprite support v2 Jesse Barnes
2011-11-14 20:22 ` [PATCH 2/3] drm/i915: add destination color key support Jesse Barnes
2011-11-16 16:10 ` Daniel Vetter
2011-11-16 16:48 ` Jesse Barnes
2011-12-07 20:29 Plane support for SNB and IVB Jesse Barnes
2011-12-07 20:29 ` [PATCH 2/3] drm/i915: add destination color key support Jesse Barnes
2011-12-12 22:14 ` Daniel Vetter
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.