|
@@ -176,7 +176,6 @@ struct overlay_registers {
|
|
|
#define OVERLAY_NONPHYSICAL(dev) (IS_G33(dev) || IS_I965G(dev))
|
|
|
#define OVERLAY_EXISTS(dev) (!IS_G4X(dev) && !IS_IRONLAKE(dev) && !IS_GEN6(dev))
|
|
|
|
|
|
-
|
|
|
static struct overlay_registers *intel_overlay_map_regs_atomic(struct intel_overlay *overlay)
|
|
|
{
|
|
|
drm_i915_private_t *dev_priv = overlay->dev->dev_private;
|
|
@@ -235,7 +234,8 @@ static int intel_overlay_on(struct intel_overlay *overlay)
|
|
|
return -ENOMEM;
|
|
|
|
|
|
ret = i915_do_wait_request(dev,
|
|
|
- overlay->last_flip_req, 1, &dev_priv->render_ring);
|
|
|
+ overlay->last_flip_req, true,
|
|
|
+ &dev_priv->render_ring);
|
|
|
if (ret != 0)
|
|
|
return ret;
|
|
|
|
|
@@ -246,7 +246,7 @@ static int intel_overlay_on(struct intel_overlay *overlay)
|
|
|
|
|
|
/* overlay needs to be enabled in OCMD reg */
|
|
|
static void intel_overlay_continue(struct intel_overlay *overlay,
|
|
|
- bool load_polyphase_filter)
|
|
|
+ bool load_polyphase_filter)
|
|
|
{
|
|
|
struct drm_device *dev = overlay->dev;
|
|
|
drm_i915_private_t *dev_priv = dev->dev_private;
|
|
@@ -275,13 +275,14 @@ static void intel_overlay_continue(struct intel_overlay *overlay,
|
|
|
static int intel_overlay_wait_flip(struct intel_overlay *overlay)
|
|
|
{
|
|
|
struct drm_device *dev = overlay->dev;
|
|
|
- drm_i915_private_t *dev_priv = dev->dev_private;
|
|
|
+ drm_i915_private_t *dev_priv = dev->dev_private;
|
|
|
int ret;
|
|
|
u32 tmp;
|
|
|
|
|
|
if (overlay->last_flip_req != 0) {
|
|
|
- ret = i915_do_wait_request(dev, overlay->last_flip_req,
|
|
|
- 1, &dev_priv->render_ring);
|
|
|
+ ret = i915_do_wait_request(dev,
|
|
|
+ overlay->last_flip_req, true,
|
|
|
+ &dev_priv->render_ring);
|
|
|
if (ret == 0) {
|
|
|
overlay->last_flip_req = 0;
|
|
|
|
|
@@ -296,17 +297,18 @@ static int intel_overlay_wait_flip(struct intel_overlay *overlay)
|
|
|
overlay->hw_wedged = RELEASE_OLD_VID;
|
|
|
|
|
|
BEGIN_LP_RING(2);
|
|
|
- OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
|
|
|
- OUT_RING(MI_NOOP);
|
|
|
- ADVANCE_LP_RING();
|
|
|
+ OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
|
|
|
+ OUT_RING(MI_NOOP);
|
|
|
+ ADVANCE_LP_RING();
|
|
|
|
|
|
overlay->last_flip_req =
|
|
|
i915_add_request(dev, NULL, &dev_priv->render_ring);
|
|
|
if (overlay->last_flip_req == 0)
|
|
|
return -ENOMEM;
|
|
|
|
|
|
- ret = i915_do_wait_request(dev, overlay->last_flip_req,
|
|
|
- 1, &dev_priv->render_ring);
|
|
|
+ ret = i915_do_wait_request(dev,
|
|
|
+ overlay->last_flip_req, true,
|
|
|
+ &dev_priv->render_ring);
|
|
|
if (ret != 0)
|
|
|
return ret;
|
|
|
|
|
@@ -337,17 +339,18 @@ static int intel_overlay_off(struct intel_overlay *overlay)
|
|
|
BEGIN_LP_RING(4);
|
|
|
OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_CONTINUE);
|
|
|
OUT_RING(flip_addr);
|
|
|
- OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
|
|
|
- OUT_RING(MI_NOOP);
|
|
|
- ADVANCE_LP_RING();
|
|
|
+ OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
|
|
|
+ OUT_RING(MI_NOOP);
|
|
|
+ ADVANCE_LP_RING();
|
|
|
|
|
|
overlay->last_flip_req =
|
|
|
i915_add_request(dev, NULL, &dev_priv->render_ring);
|
|
|
if (overlay->last_flip_req == 0)
|
|
|
return -ENOMEM;
|
|
|
|
|
|
- ret = i915_do_wait_request(dev, overlay->last_flip_req,
|
|
|
- 1, &dev_priv->render_ring);
|
|
|
+ ret = i915_do_wait_request(dev,
|
|
|
+ overlay->last_flip_req, true,
|
|
|
+ &dev_priv->render_ring);
|
|
|
if (ret != 0)
|
|
|
return ret;
|
|
|
|
|
@@ -355,10 +358,10 @@ static int intel_overlay_off(struct intel_overlay *overlay)
|
|
|
overlay->hw_wedged = SWITCH_OFF_STAGE_2;
|
|
|
|
|
|
BEGIN_LP_RING(4);
|
|
|
- OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_OFF);
|
|
|
+ OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_OFF);
|
|
|
OUT_RING(flip_addr);
|
|
|
- OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
|
|
|
- OUT_RING(MI_NOOP);
|
|
|
+ OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
|
|
|
+ OUT_RING(MI_NOOP);
|
|
|
ADVANCE_LP_RING();
|
|
|
|
|
|
overlay->last_flip_req =
|
|
@@ -366,8 +369,9 @@ static int intel_overlay_off(struct intel_overlay *overlay)
|
|
|
if (overlay->last_flip_req == 0)
|
|
|
return -ENOMEM;
|
|
|
|
|
|
- ret = i915_do_wait_request(dev, overlay->last_flip_req,
|
|
|
- 1, &dev_priv->render_ring);
|
|
|
+ ret = i915_do_wait_request(dev,
|
|
|
+ overlay->last_flip_req, true,
|
|
|
+ &dev_priv->render_ring);
|
|
|
if (ret != 0)
|
|
|
return ret;
|
|
|
|
|
@@ -396,7 +400,7 @@ static void intel_overlay_off_tail(struct intel_overlay *overlay)
|
|
|
/* recover from an interruption due to a signal
|
|
|
* We have to be careful not to repeat work forever an make forward progess. */
|
|
|
int intel_overlay_recover_from_interrupt(struct intel_overlay *overlay,
|
|
|
- int interruptible)
|
|
|
+ bool interruptible)
|
|
|
{
|
|
|
struct drm_device *dev = overlay->dev;
|
|
|
struct drm_gem_object *obj;
|
|
@@ -415,46 +419,47 @@ int intel_overlay_recover_from_interrupt(struct intel_overlay *overlay,
|
|
|
}
|
|
|
|
|
|
ret = i915_do_wait_request(dev, overlay->last_flip_req,
|
|
|
- interruptible, &dev_priv->render_ring);
|
|
|
+ interruptible, &dev_priv->render_ring);
|
|
|
if (ret != 0)
|
|
|
return ret;
|
|
|
|
|
|
switch (overlay->hw_wedged) {
|
|
|
- case RELEASE_OLD_VID:
|
|
|
- obj = &overlay->old_vid_bo->base;
|
|
|
- i915_gem_object_unpin(obj);
|
|
|
- drm_gem_object_unreference(obj);
|
|
|
- overlay->old_vid_bo = NULL;
|
|
|
- break;
|
|
|
- case SWITCH_OFF_STAGE_1:
|
|
|
- flip_addr = overlay->flip_addr;
|
|
|
- flip_addr |= OFC_UPDATE;
|
|
|
-
|
|
|
- overlay->hw_wedged = SWITCH_OFF_STAGE_2;
|
|
|
-
|
|
|
- BEGIN_LP_RING(4);
|
|
|
- OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_OFF);
|
|
|
- OUT_RING(flip_addr);
|
|
|
- OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
|
|
|
- OUT_RING(MI_NOOP);
|
|
|
- ADVANCE_LP_RING();
|
|
|
-
|
|
|
- overlay->last_flip_req =
|
|
|
- i915_add_request(dev, NULL,
|
|
|
- &dev_priv->render_ring);
|
|
|
- if (overlay->last_flip_req == 0)
|
|
|
- return -ENOMEM;
|
|
|
-
|
|
|
- ret = i915_do_wait_request(dev, overlay->last_flip_req,
|
|
|
- interruptible, &dev_priv->render_ring);
|
|
|
- if (ret != 0)
|
|
|
- return ret;
|
|
|
+ case RELEASE_OLD_VID:
|
|
|
+ obj = &overlay->old_vid_bo->base;
|
|
|
+ i915_gem_object_unpin(obj);
|
|
|
+ drm_gem_object_unreference(obj);
|
|
|
+ overlay->old_vid_bo = NULL;
|
|
|
+ break;
|
|
|
+ case SWITCH_OFF_STAGE_1:
|
|
|
+ flip_addr = overlay->flip_addr;
|
|
|
+ flip_addr |= OFC_UPDATE;
|
|
|
|
|
|
- case SWITCH_OFF_STAGE_2:
|
|
|
- intel_overlay_off_tail(overlay);
|
|
|
- break;
|
|
|
- default:
|
|
|
- BUG_ON(overlay->hw_wedged != NEEDS_WAIT_FOR_FLIP);
|
|
|
+ overlay->hw_wedged = SWITCH_OFF_STAGE_2;
|
|
|
+
|
|
|
+ BEGIN_LP_RING(4);
|
|
|
+ OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_OFF);
|
|
|
+ OUT_RING(flip_addr);
|
|
|
+ OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
|
|
|
+ OUT_RING(MI_NOOP);
|
|
|
+ ADVANCE_LP_RING();
|
|
|
+
|
|
|
+ overlay->last_flip_req =
|
|
|
+ i915_add_request(dev, NULL,
|
|
|
+ &dev_priv->render_ring);
|
|
|
+ if (overlay->last_flip_req == 0)
|
|
|
+ return -ENOMEM;
|
|
|
+
|
|
|
+ ret = i915_do_wait_request(dev, overlay->last_flip_req,
|
|
|
+ interruptible,
|
|
|
+ &dev_priv->render_ring);
|
|
|
+ if (ret != 0)
|
|
|
+ return ret;
|
|
|
+
|
|
|
+ case SWITCH_OFF_STAGE_2:
|
|
|
+ intel_overlay_off_tail(overlay);
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ BUG_ON(overlay->hw_wedged != NEEDS_WAIT_FOR_FLIP);
|
|
|
}
|
|
|
|
|
|
overlay->hw_wedged = 0;
|
|
@@ -507,50 +512,50 @@ struct put_image_params {
|
|
|
static int packed_depth_bytes(u32 format)
|
|
|
{
|
|
|
switch (format & I915_OVERLAY_DEPTH_MASK) {
|
|
|
- case I915_OVERLAY_YUV422:
|
|
|
- return 4;
|
|
|
- case I915_OVERLAY_YUV411:
|
|
|
- /* return 6; not implemented */
|
|
|
- default:
|
|
|
- return -EINVAL;
|
|
|
+ case I915_OVERLAY_YUV422:
|
|
|
+ return 4;
|
|
|
+ case I915_OVERLAY_YUV411:
|
|
|
+ /* return 6; not implemented */
|
|
|
+ default:
|
|
|
+ return -EINVAL;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
static int packed_width_bytes(u32 format, short width)
|
|
|
{
|
|
|
switch (format & I915_OVERLAY_DEPTH_MASK) {
|
|
|
- case I915_OVERLAY_YUV422:
|
|
|
- return width << 1;
|
|
|
- default:
|
|
|
- return -EINVAL;
|
|
|
+ case I915_OVERLAY_YUV422:
|
|
|
+ return width << 1;
|
|
|
+ default:
|
|
|
+ return -EINVAL;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
static int uv_hsubsampling(u32 format)
|
|
|
{
|
|
|
switch (format & I915_OVERLAY_DEPTH_MASK) {
|
|
|
- case I915_OVERLAY_YUV422:
|
|
|
- case I915_OVERLAY_YUV420:
|
|
|
- return 2;
|
|
|
- case I915_OVERLAY_YUV411:
|
|
|
- case I915_OVERLAY_YUV410:
|
|
|
- return 4;
|
|
|
- default:
|
|
|
- return -EINVAL;
|
|
|
+ case I915_OVERLAY_YUV422:
|
|
|
+ case I915_OVERLAY_YUV420:
|
|
|
+ return 2;
|
|
|
+ case I915_OVERLAY_YUV411:
|
|
|
+ case I915_OVERLAY_YUV410:
|
|
|
+ return 4;
|
|
|
+ default:
|
|
|
+ return -EINVAL;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
static int uv_vsubsampling(u32 format)
|
|
|
{
|
|
|
switch (format & I915_OVERLAY_DEPTH_MASK) {
|
|
|
- case I915_OVERLAY_YUV420:
|
|
|
- case I915_OVERLAY_YUV410:
|
|
|
- return 2;
|
|
|
- case I915_OVERLAY_YUV422:
|
|
|
- case I915_OVERLAY_YUV411:
|
|
|
- return 1;
|
|
|
- default:
|
|
|
- return -EINVAL;
|
|
|
+ case I915_OVERLAY_YUV420:
|
|
|
+ case I915_OVERLAY_YUV410:
|
|
|
+ return 2;
|
|
|
+ case I915_OVERLAY_YUV422:
|
|
|
+ case I915_OVERLAY_YUV411:
|
|
|
+ return 1;
|
|
|
+ default:
|
|
|
+ return -EINVAL;
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -588,7 +593,9 @@ static const u16 y_static_hcoeffs[N_HORIZ_Y_TAPS * N_PHASES] = {
|
|
|
0x3020, 0xb340, 0x1fb8, 0x34a0, 0xb060,
|
|
|
0x3020, 0xb240, 0x1fe0, 0x32e0, 0xb040,
|
|
|
0x3020, 0xb140, 0x1ff8, 0x3160, 0xb020,
|
|
|
- 0xb000, 0x3000, 0x0800, 0x3000, 0xb000};
|
|
|
+ 0xb000, 0x3000, 0x0800, 0x3000, 0xb000
|
|
|
+};
|
|
|
+
|
|
|
static const u16 uv_static_hcoeffs[N_HORIZ_UV_TAPS * N_PHASES] = {
|
|
|
0x3000, 0x1800, 0x1800, 0xb000, 0x18d0, 0x2e60,
|
|
|
0xb000, 0x1990, 0x2ce0, 0xb020, 0x1a68, 0x2b40,
|
|
@@ -598,7 +605,8 @@ static const u16 uv_static_hcoeffs[N_HORIZ_UV_TAPS * N_PHASES] = {
|
|
|
0xb100, 0x1eb8, 0x3620, 0xb100, 0x1f18, 0x34a0,
|
|
|
0xb100, 0x1f68, 0x3360, 0xb0e0, 0x1fa8, 0x3240,
|
|
|
0xb0c0, 0x1fe0, 0x3140, 0xb060, 0x1ff0, 0x30a0,
|
|
|
- 0x3000, 0x0800, 0x3000};
|
|
|
+ 0x3000, 0x0800, 0x3000
|
|
|
+};
|
|
|
|
|
|
static void update_polyphase_filter(struct overlay_registers *regs)
|
|
|
{
|
|
@@ -631,29 +639,31 @@ static bool update_scaling_factors(struct intel_overlay *overlay,
|
|
|
yscale = 1 << FP_SHIFT;
|
|
|
|
|
|
/*if (params->format & I915_OVERLAY_YUV_PLANAR) {*/
|
|
|
- xscale_UV = xscale/uv_hscale;
|
|
|
- yscale_UV = yscale/uv_vscale;
|
|
|
- /* make the Y scale to UV scale ratio an exact multiply */
|
|
|
- xscale = xscale_UV * uv_hscale;
|
|
|
- yscale = yscale_UV * uv_vscale;
|
|
|
+ xscale_UV = xscale/uv_hscale;
|
|
|
+ yscale_UV = yscale/uv_vscale;
|
|
|
+ /* make the Y scale to UV scale ratio an exact multiply */
|
|
|
+ xscale = xscale_UV * uv_hscale;
|
|
|
+ yscale = yscale_UV * uv_vscale;
|
|
|
/*} else {
|
|
|
- xscale_UV = 0;
|
|
|
- yscale_UV = 0;
|
|
|
- }*/
|
|
|
+ xscale_UV = 0;
|
|
|
+ yscale_UV = 0;
|
|
|
+ }*/
|
|
|
|
|
|
if (xscale != overlay->old_xscale || yscale != overlay->old_yscale)
|
|
|
scale_changed = true;
|
|
|
overlay->old_xscale = xscale;
|
|
|
overlay->old_yscale = yscale;
|
|
|
|
|
|
- regs->YRGBSCALE = ((yscale & FRACT_MASK) << 20)
|
|
|
- | ((xscale >> FP_SHIFT) << 16)
|
|
|
- | ((xscale & FRACT_MASK) << 3);
|
|
|
- regs->UVSCALE = ((yscale_UV & FRACT_MASK) << 20)
|
|
|
- | ((xscale_UV >> FP_SHIFT) << 16)
|
|
|
- | ((xscale_UV & FRACT_MASK) << 3);
|
|
|
- regs->UVSCALEV = ((yscale >> FP_SHIFT) << 16)
|
|
|
- | ((yscale_UV >> FP_SHIFT) << 0);
|
|
|
+ regs->YRGBSCALE = (((yscale & FRACT_MASK) << 20) |
|
|
|
+ ((xscale >> FP_SHIFT) << 16) |
|
|
|
+ ((xscale & FRACT_MASK) << 3));
|
|
|
+
|
|
|
+ regs->UVSCALE = (((yscale_UV & FRACT_MASK) << 20) |
|
|
|
+ ((xscale_UV >> FP_SHIFT) << 16) |
|
|
|
+ ((xscale_UV & FRACT_MASK) << 3));
|
|
|
+
|
|
|
+ regs->UVSCALEV = ((((yscale >> FP_SHIFT) << 16) |
|
|
|
+ ((yscale_UV >> FP_SHIFT) << 0)));
|
|
|
|
|
|
if (scale_changed)
|
|
|
update_polyphase_filter(regs);
|
|
@@ -666,21 +676,21 @@ static void update_colorkey(struct intel_overlay *overlay,
|
|
|
{
|
|
|
u32 key = overlay->color_key;
|
|
|
switch (overlay->crtc->base.fb->bits_per_pixel) {
|
|
|
- case 8:
|
|
|
- regs->DCLRKV = 0;
|
|
|
- regs->DCLRKM = CLK_RGB8I_MASK | DST_KEY_ENABLE;
|
|
|
- case 16:
|
|
|
- if (overlay->crtc->base.fb->depth == 15) {
|
|
|
- regs->DCLRKV = RGB15_TO_COLORKEY(key);
|
|
|
- regs->DCLRKM = CLK_RGB15_MASK | DST_KEY_ENABLE;
|
|
|
- } else {
|
|
|
- regs->DCLRKV = RGB16_TO_COLORKEY(key);
|
|
|
- regs->DCLRKM = CLK_RGB16_MASK | DST_KEY_ENABLE;
|
|
|
- }
|
|
|
- case 24:
|
|
|
- case 32:
|
|
|
- regs->DCLRKV = key;
|
|
|
- regs->DCLRKM = CLK_RGB24_MASK | DST_KEY_ENABLE;
|
|
|
+ case 8:
|
|
|
+ regs->DCLRKV = 0;
|
|
|
+ regs->DCLRKM = CLK_RGB8I_MASK | DST_KEY_ENABLE;
|
|
|
+ case 16:
|
|
|
+ if (overlay->crtc->base.fb->depth == 15) {
|
|
|
+ regs->DCLRKV = RGB15_TO_COLORKEY(key);
|
|
|
+ regs->DCLRKM = CLK_RGB15_MASK | DST_KEY_ENABLE;
|
|
|
+ } else {
|
|
|
+ regs->DCLRKV = RGB16_TO_COLORKEY(key);
|
|
|
+ regs->DCLRKM = CLK_RGB16_MASK | DST_KEY_ENABLE;
|
|
|
+ }
|
|
|
+ case 24:
|
|
|
+ case 32:
|
|
|
+ regs->DCLRKV = key;
|
|
|
+ regs->DCLRKM = CLK_RGB24_MASK | DST_KEY_ENABLE;
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -690,39 +700,39 @@ static u32 overlay_cmd_reg(struct put_image_params *params)
|
|
|
|
|
|
if (params->format & I915_OVERLAY_YUV_PLANAR) {
|
|
|
switch (params->format & I915_OVERLAY_DEPTH_MASK) {
|
|
|
- case I915_OVERLAY_YUV422:
|
|
|
- cmd |= OCMD_YUV_422_PLANAR;
|
|
|
- break;
|
|
|
- case I915_OVERLAY_YUV420:
|
|
|
- cmd |= OCMD_YUV_420_PLANAR;
|
|
|
- break;
|
|
|
- case I915_OVERLAY_YUV411:
|
|
|
- case I915_OVERLAY_YUV410:
|
|
|
- cmd |= OCMD_YUV_410_PLANAR;
|
|
|
- break;
|
|
|
+ case I915_OVERLAY_YUV422:
|
|
|
+ cmd |= OCMD_YUV_422_PLANAR;
|
|
|
+ break;
|
|
|
+ case I915_OVERLAY_YUV420:
|
|
|
+ cmd |= OCMD_YUV_420_PLANAR;
|
|
|
+ break;
|
|
|
+ case I915_OVERLAY_YUV411:
|
|
|
+ case I915_OVERLAY_YUV410:
|
|
|
+ cmd |= OCMD_YUV_410_PLANAR;
|
|
|
+ break;
|
|
|
}
|
|
|
} else { /* YUV packed */
|
|
|
switch (params->format & I915_OVERLAY_DEPTH_MASK) {
|
|
|
- case I915_OVERLAY_YUV422:
|
|
|
- cmd |= OCMD_YUV_422_PACKED;
|
|
|
- break;
|
|
|
- case I915_OVERLAY_YUV411:
|
|
|
- cmd |= OCMD_YUV_411_PACKED;
|
|
|
- break;
|
|
|
+ case I915_OVERLAY_YUV422:
|
|
|
+ cmd |= OCMD_YUV_422_PACKED;
|
|
|
+ break;
|
|
|
+ case I915_OVERLAY_YUV411:
|
|
|
+ cmd |= OCMD_YUV_411_PACKED;
|
|
|
+ break;
|
|
|
}
|
|
|
|
|
|
switch (params->format & I915_OVERLAY_SWAP_MASK) {
|
|
|
- case I915_OVERLAY_NO_SWAP:
|
|
|
- break;
|
|
|
- case I915_OVERLAY_UV_SWAP:
|
|
|
- cmd |= OCMD_UV_SWAP;
|
|
|
- break;
|
|
|
- case I915_OVERLAY_Y_SWAP:
|
|
|
- cmd |= OCMD_Y_SWAP;
|
|
|
- break;
|
|
|
- case I915_OVERLAY_Y_AND_UV_SWAP:
|
|
|
- cmd |= OCMD_Y_AND_UV_SWAP;
|
|
|
- break;
|
|
|
+ case I915_OVERLAY_NO_SWAP:
|
|
|
+ break;
|
|
|
+ case I915_OVERLAY_UV_SWAP:
|
|
|
+ cmd |= OCMD_UV_SWAP;
|
|
|
+ break;
|
|
|
+ case I915_OVERLAY_Y_SWAP:
|
|
|
+ cmd |= OCMD_Y_SWAP;
|
|
|
+ break;
|
|
|
+ case I915_OVERLAY_Y_AND_UV_SWAP:
|
|
|
+ cmd |= OCMD_Y_AND_UV_SWAP;
|
|
|
+ break;
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -789,7 +799,7 @@ int intel_overlay_do_put_image(struct intel_overlay *overlay,
|
|
|
|
|
|
regs->SWIDTH = params->src_w;
|
|
|
regs->SWIDTHSW = calc_swidthsw(overlay->dev,
|
|
|
- params->offset_Y, tmp_width);
|
|
|
+ params->offset_Y, tmp_width);
|
|
|
regs->SHEIGHT = params->src_h;
|
|
|
regs->OBUF_0Y = bo_priv->gtt_offset + params-> offset_Y;
|
|
|
regs->OSTRIDE = params->stride_Y;
|
|
@@ -800,9 +810,9 @@ int intel_overlay_do_put_image(struct intel_overlay *overlay,
|
|
|
u32 tmp_U, tmp_V;
|
|
|
regs->SWIDTH |= (params->src_w/uv_hscale) << 16;
|
|
|
tmp_U = calc_swidthsw(overlay->dev, params->offset_U,
|
|
|
- params->src_w/uv_hscale);
|
|
|
+ params->src_w/uv_hscale);
|
|
|
tmp_V = calc_swidthsw(overlay->dev, params->offset_V,
|
|
|
- params->src_w/uv_hscale);
|
|
|
+ params->src_w/uv_hscale);
|
|
|
regs->SWIDTHSW |= max_t(u32, tmp_U, tmp_V) << 16;
|
|
|
regs->SHEIGHT |= (params->src_h/uv_vscale) << 16;
|
|
|
regs->OBUF_0U = bo_priv->gtt_offset + params->offset_U;
|
|
@@ -868,7 +878,7 @@ int intel_overlay_switch_off(struct intel_overlay *overlay)
|
|
|
static int check_overlay_possible_on_crtc(struct intel_overlay *overlay,
|
|
|
struct intel_crtc *crtc)
|
|
|
{
|
|
|
- drm_i915_private_t *dev_priv = overlay->dev->dev_private;
|
|
|
+ drm_i915_private_t *dev_priv = overlay->dev->dev_private;
|
|
|
u32 pipeconf;
|
|
|
int pipeconf_reg = (crtc->pipe == 0) ? PIPEACONF : PIPEBCONF;
|
|
|
|
|
@@ -887,7 +897,7 @@ static int check_overlay_possible_on_crtc(struct intel_overlay *overlay,
|
|
|
static void update_pfit_vscale_ratio(struct intel_overlay *overlay)
|
|
|
{
|
|
|
struct drm_device *dev = overlay->dev;
|
|
|
- drm_i915_private_t *dev_priv = dev->dev_private;
|
|
|
+ drm_i915_private_t *dev_priv = dev->dev_private;
|
|
|
u32 ratio;
|
|
|
u32 pfit_control = I915_READ(PFIT_CONTROL);
|
|
|
|
|
@@ -911,12 +921,10 @@ static int check_overlay_dst(struct intel_overlay *overlay,
|
|
|
{
|
|
|
struct drm_display_mode *mode = &overlay->crtc->base.mode;
|
|
|
|
|
|
- if ((rec->dst_x < mode->crtc_hdisplay)
|
|
|
- && (rec->dst_x + rec->dst_width
|
|
|
- <= mode->crtc_hdisplay)
|
|
|
- && (rec->dst_y < mode->crtc_vdisplay)
|
|
|
- && (rec->dst_y + rec->dst_height
|
|
|
- <= mode->crtc_vdisplay))
|
|
|
+ if (rec->dst_x < mode->crtc_hdisplay &&
|
|
|
+ rec->dst_x + rec->dst_width <= mode->crtc_hdisplay &&
|
|
|
+ rec->dst_y < mode->crtc_vdisplay &&
|
|
|
+ rec->dst_y + rec->dst_height <= mode->crtc_vdisplay)
|
|
|
return 0;
|
|
|
else
|
|
|
return -EINVAL;
|
|
@@ -949,45 +957,45 @@ static int check_overlay_src(struct drm_device *dev,
|
|
|
|
|
|
/* check src dimensions */
|
|
|
if (IS_845G(dev) || IS_I830(dev)) {
|
|
|
- if (rec->src_height > IMAGE_MAX_HEIGHT_LEGACY
|
|
|
- || rec->src_width > IMAGE_MAX_WIDTH_LEGACY)
|
|
|
+ if (rec->src_height > IMAGE_MAX_HEIGHT_LEGACY ||
|
|
|
+ rec->src_width > IMAGE_MAX_WIDTH_LEGACY)
|
|
|
return -EINVAL;
|
|
|
} else {
|
|
|
- if (rec->src_height > IMAGE_MAX_HEIGHT
|
|
|
- || rec->src_width > IMAGE_MAX_WIDTH)
|
|
|
+ if (rec->src_height > IMAGE_MAX_HEIGHT ||
|
|
|
+ rec->src_width > IMAGE_MAX_WIDTH)
|
|
|
return -EINVAL;
|
|
|
}
|
|
|
/* better safe than sorry, use 4 as the maximal subsampling ratio */
|
|
|
- if (rec->src_height < N_VERT_Y_TAPS*4
|
|
|
- || rec->src_width < N_HORIZ_Y_TAPS*4)
|
|
|
+ if (rec->src_height < N_VERT_Y_TAPS*4 ||
|
|
|
+ rec->src_width < N_HORIZ_Y_TAPS*4)
|
|
|
return -EINVAL;
|
|
|
|
|
|
/* check alignment constraints */
|
|
|
switch (rec->flags & I915_OVERLAY_TYPE_MASK) {
|
|
|
- case I915_OVERLAY_RGB:
|
|
|
- /* not implemented */
|
|
|
+ case I915_OVERLAY_RGB:
|
|
|
+ /* not implemented */
|
|
|
+ return -EINVAL;
|
|
|
+ case I915_OVERLAY_YUV_PACKED:
|
|
|
+ depth = packed_depth_bytes(rec->flags);
|
|
|
+ if (uv_vscale != 1)
|
|
|
return -EINVAL;
|
|
|
- case I915_OVERLAY_YUV_PACKED:
|
|
|
- depth = packed_depth_bytes(rec->flags);
|
|
|
- if (uv_vscale != 1)
|
|
|
- return -EINVAL;
|
|
|
- if (depth < 0)
|
|
|
- return depth;
|
|
|
- /* ignore UV planes */
|
|
|
- rec->stride_UV = 0;
|
|
|
- rec->offset_U = 0;
|
|
|
- rec->offset_V = 0;
|
|
|
- /* check pixel alignment */
|
|
|
- if (rec->offset_Y % depth)
|
|
|
- return -EINVAL;
|
|
|
- break;
|
|
|
- case I915_OVERLAY_YUV_PLANAR:
|
|
|
- if (uv_vscale < 0 || uv_hscale < 0)
|
|
|
- return -EINVAL;
|
|
|
- /* no offset restrictions for planar formats */
|
|
|
- break;
|
|
|
- default:
|
|
|
+ if (depth < 0)
|
|
|
+ return depth;
|
|
|
+ /* ignore UV planes */
|
|
|
+ rec->stride_UV = 0;
|
|
|
+ rec->offset_U = 0;
|
|
|
+ rec->offset_V = 0;
|
|
|
+ /* check pixel alignment */
|
|
|
+ if (rec->offset_Y % depth)
|
|
|
+ return -EINVAL;
|
|
|
+ break;
|
|
|
+ case I915_OVERLAY_YUV_PLANAR:
|
|
|
+ if (uv_vscale < 0 || uv_hscale < 0)
|
|
|
return -EINVAL;
|
|
|
+ /* no offset restrictions for planar formats */
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ return -EINVAL;
|
|
|
}
|
|
|
|
|
|
if (rec->src_width % uv_hscale)
|
|
@@ -1011,32 +1019,32 @@ static int check_overlay_src(struct drm_device *dev,
|
|
|
|
|
|
/* check buffer dimensions */
|
|
|
switch (rec->flags & I915_OVERLAY_TYPE_MASK) {
|
|
|
- case I915_OVERLAY_RGB:
|
|
|
- case I915_OVERLAY_YUV_PACKED:
|
|
|
- /* always 4 Y values per depth pixels */
|
|
|
- if (packed_width_bytes(rec->flags, rec->src_width)
|
|
|
- > rec->stride_Y)
|
|
|
- return -EINVAL;
|
|
|
-
|
|
|
- tmp = rec->stride_Y*rec->src_height;
|
|
|
- if (rec->offset_Y + tmp > new_bo->size)
|
|
|
- return -EINVAL;
|
|
|
- break;
|
|
|
- case I915_OVERLAY_YUV_PLANAR:
|
|
|
- if (rec->src_width > rec->stride_Y)
|
|
|
- return -EINVAL;
|
|
|
- if (rec->src_width/uv_hscale > rec->stride_UV)
|
|
|
- return -EINVAL;
|
|
|
-
|
|
|
- tmp = rec->stride_Y*rec->src_height;
|
|
|
- if (rec->offset_Y + tmp > new_bo->size)
|
|
|
- return -EINVAL;
|
|
|
- tmp = rec->stride_UV*rec->src_height;
|
|
|
- tmp /= uv_vscale;
|
|
|
- if (rec->offset_U + tmp > new_bo->size
|
|
|
- || rec->offset_V + tmp > new_bo->size)
|
|
|
- return -EINVAL;
|
|
|
- break;
|
|
|
+ case I915_OVERLAY_RGB:
|
|
|
+ case I915_OVERLAY_YUV_PACKED:
|
|
|
+ /* always 4 Y values per depth pixels */
|
|
|
+ if (packed_width_bytes(rec->flags, rec->src_width) > rec->stride_Y)
|
|
|
+ return -EINVAL;
|
|
|
+
|
|
|
+ tmp = rec->stride_Y*rec->src_height;
|
|
|
+ if (rec->offset_Y + tmp > new_bo->size)
|
|
|
+ return -EINVAL;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case I915_OVERLAY_YUV_PLANAR:
|
|
|
+ if (rec->src_width > rec->stride_Y)
|
|
|
+ return -EINVAL;
|
|
|
+ if (rec->src_width/uv_hscale > rec->stride_UV)
|
|
|
+ return -EINVAL;
|
|
|
+
|
|
|
+ tmp = rec->stride_Y*rec->src_height;
|
|
|
+ if (rec->offset_Y + tmp > new_bo->size)
|
|
|
+ return -EINVAL;
|
|
|
+ tmp = rec->stride_UV*rec->src_height;
|
|
|
+ tmp /= uv_vscale;
|
|
|
+ if (rec->offset_U + tmp > new_bo->size ||
|
|
|
+ rec->offset_V + tmp > new_bo->size)
|
|
|
+ return -EINVAL;
|
|
|
+ break;
|
|
|
}
|
|
|
|
|
|
return 0;
|
|
@@ -1082,7 +1090,7 @@ int intel_overlay_put_image(struct drm_device *dev, void *data,
|
|
|
return -ENOMEM;
|
|
|
|
|
|
drmmode_obj = drm_mode_object_find(dev, put_image_rec->crtc_id,
|
|
|
- DRM_MODE_OBJECT_CRTC);
|
|
|
+ DRM_MODE_OBJECT_CRTC);
|
|
|
if (!drmmode_obj) {
|
|
|
ret = -ENOENT;
|
|
|
goto out_free;
|
|
@@ -1090,7 +1098,7 @@ int intel_overlay_put_image(struct drm_device *dev, void *data,
|
|
|
crtc = to_intel_crtc(obj_to_crtc(drmmode_obj));
|
|
|
|
|
|
new_bo = drm_gem_object_lookup(dev, file_priv,
|
|
|
- put_image_rec->bo_handle);
|
|
|
+ put_image_rec->bo_handle);
|
|
|
if (!new_bo) {
|
|
|
ret = -ENOENT;
|
|
|
goto out_free;
|
|
@@ -1133,10 +1141,10 @@ int intel_overlay_put_image(struct drm_device *dev, void *data,
|
|
|
|
|
|
if (overlay->pfit_active) {
|
|
|
params->dst_y = ((((u32)put_image_rec->dst_y) << 12) /
|
|
|
- overlay->pfit_vscale_ratio);
|
|
|
+ overlay->pfit_vscale_ratio);
|
|
|
/* shifting right rounds downwards, so add 1 */
|
|
|
params->dst_h = ((((u32)put_image_rec->dst_height) << 12) /
|
|
|
- overlay->pfit_vscale_ratio) + 1;
|
|
|
+ overlay->pfit_vscale_ratio) + 1;
|
|
|
} else {
|
|
|
params->dst_y = put_image_rec->dst_y;
|
|
|
params->dst_h = put_image_rec->dst_height;
|
|
@@ -1148,8 +1156,8 @@ int intel_overlay_put_image(struct drm_device *dev, void *data,
|
|
|
params->src_h = put_image_rec->src_height;
|
|
|
params->src_scan_w = put_image_rec->src_scan_width;
|
|
|
params->src_scan_h = put_image_rec->src_scan_height;
|
|
|
- if (params->src_scan_h > params->src_h
|
|
|
- || params->src_scan_w > params->src_w) {
|
|
|
+ if (params->src_scan_h > params->src_h ||
|
|
|
+ params->src_scan_w > params->src_w) {
|
|
|
ret = -EINVAL;
|
|
|
goto out_unlock;
|
|
|
}
|
|
@@ -1205,7 +1213,7 @@ static bool check_gamma_bounds(u32 gamma1, u32 gamma2)
|
|
|
return false;
|
|
|
|
|
|
for (i = 0; i < 3; i++) {
|
|
|
- if (((gamma1 >> i * 8) & 0xff) >= ((gamma2 >> i*8) & 0xff))
|
|
|
+ if (((gamma1 >> i*8) & 0xff) >= ((gamma2 >> i*8) & 0xff))
|
|
|
return false;
|
|
|
}
|
|
|
|
|
@@ -1226,16 +1234,18 @@ static bool check_gamma5_errata(u32 gamma5)
|
|
|
|
|
|
static int check_gamma(struct drm_intel_overlay_attrs *attrs)
|
|
|
{
|
|
|
- if (!check_gamma_bounds(0, attrs->gamma0)
|
|
|
- || !check_gamma_bounds(attrs->gamma0, attrs->gamma1)
|
|
|
- || !check_gamma_bounds(attrs->gamma1, attrs->gamma2)
|
|
|
- || !check_gamma_bounds(attrs->gamma2, attrs->gamma3)
|
|
|
- || !check_gamma_bounds(attrs->gamma3, attrs->gamma4)
|
|
|
- || !check_gamma_bounds(attrs->gamma4, attrs->gamma5)
|
|
|
- || !check_gamma_bounds(attrs->gamma5, 0x00ffffff))
|
|
|
+ if (!check_gamma_bounds(0, attrs->gamma0) ||
|
|
|
+ !check_gamma_bounds(attrs->gamma0, attrs->gamma1) ||
|
|
|
+ !check_gamma_bounds(attrs->gamma1, attrs->gamma2) ||
|
|
|
+ !check_gamma_bounds(attrs->gamma2, attrs->gamma3) ||
|
|
|
+ !check_gamma_bounds(attrs->gamma3, attrs->gamma4) ||
|
|
|
+ !check_gamma_bounds(attrs->gamma4, attrs->gamma5) ||
|
|
|
+ !check_gamma_bounds(attrs->gamma5, 0x00ffffff))
|
|
|
return -EINVAL;
|
|
|
+
|
|
|
if (!check_gamma5_errata(attrs->gamma5))
|
|
|
return -EINVAL;
|
|
|
+
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
@@ -1285,12 +1295,14 @@ int intel_overlay_attrs(struct drm_device *dev, void *data,
|
|
|
ret = -EINVAL;
|
|
|
goto out_unlock;
|
|
|
}
|
|
|
+
|
|
|
if (attrs->contrast <= 255) {
|
|
|
overlay->contrast = attrs->contrast;
|
|
|
} else {
|
|
|
ret = -EINVAL;
|
|
|
goto out_unlock;
|
|
|
}
|
|
|
+
|
|
|
if (attrs->saturation <= 1023) {
|
|
|
overlay->saturation = attrs->saturation;
|
|
|
} else {
|
|
@@ -1409,7 +1421,7 @@ out_free:
|
|
|
|
|
|
void intel_cleanup_overlay(struct drm_device *dev)
|
|
|
{
|
|
|
- drm_i915_private_t *dev_priv = dev->dev_private;
|
|
|
+ drm_i915_private_t *dev_priv = dev->dev_private;
|
|
|
|
|
|
if (dev_priv->overlay) {
|
|
|
/* The bo's should be free'd by the generic code already.
|