drm/i915/overlay: Whitespace

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
This commit is contained in:
Chris Wilson 2010-08-12 09:28:50 +01:00
parent 4fc6ee7646
commit 722506f04d
2 changed files with 244 additions and 232 deletions

View file

@ -291,7 +291,7 @@ extern void intel_setup_overlay(struct drm_device *dev);
extern void intel_cleanup_overlay(struct drm_device *dev); extern void intel_cleanup_overlay(struct drm_device *dev);
extern int intel_overlay_switch_off(struct intel_overlay *overlay); extern int intel_overlay_switch_off(struct intel_overlay *overlay);
extern int intel_overlay_recover_from_interrupt(struct intel_overlay *overlay, extern int intel_overlay_recover_from_interrupt(struct intel_overlay *overlay,
int interruptible); bool interruptible);
extern int intel_overlay_put_image(struct drm_device *dev, void *data, extern int intel_overlay_put_image(struct drm_device *dev, void *data,
struct drm_file *file_priv); struct drm_file *file_priv);
extern int intel_overlay_attrs(struct drm_device *dev, void *data, extern int intel_overlay_attrs(struct drm_device *dev, void *data,

View file

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