Skip to content

Commit

Permalink
drm/i915/overlay: Use non-atomic mappings for the common case.
Browse files Browse the repository at this point in the history
The only time where an atomic mapping is required is during
error-capture and there we cannot use the default slot, but need to
specifically use one of the IRQ slots. So separate out the two
conditions and use the atomic mapping only when appropriate.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
  • Loading branch information
Chris Wilson committed Sep 8, 2010
1 parent 3157814 commit 8d74f65
Showing 1 changed file with 55 additions and 17 deletions.
72 changes: 55 additions & 17 deletions drivers/gpu/drm/i915/intel_overlay.c
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,9 @@ struct overlay_registers {
/* overlay flip addr flag */
#define OFC_UPDATE 0x1

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,
int slot)
{
drm_i915_private_t *dev_priv = overlay->dev->dev_private;
struct overlay_registers *regs;
Expand All @@ -186,7 +188,7 @@ static struct overlay_registers *intel_overlay_map_regs_atomic(struct intel_over
} else {
regs = io_mapping_map_atomic_wc(dev_priv->mm.gtt_mapping,
overlay->reg_bo->gtt_offset,
KM_USER0);
slot);

if (!regs) {
DRM_ERROR("failed to map overlay regs in GTT\n");
Expand All @@ -197,10 +199,45 @@ static struct overlay_registers *intel_overlay_map_regs_atomic(struct intel_over
return overlay->virt_addr = regs;
}

static void intel_overlay_unmap_regs_atomic(struct intel_overlay *overlay)
static void intel_overlay_unmap_regs_atomic(struct intel_overlay *overlay,
int slot)
{
if (!OVERLAY_NEEDS_PHYSICAL(overlay->dev))
io_mapping_unmap_atomic(overlay->virt_addr, KM_USER0);
io_mapping_unmap_atomic(overlay->virt_addr, slot);

overlay->virt_addr = NULL;

return;
}

static struct overlay_registers *
intel_overlay_map_regs(struct intel_overlay *overlay)
{
drm_i915_private_t *dev_priv = overlay->dev->dev_private;
struct overlay_registers *regs;

/* no recursive mappings */
BUG_ON(overlay->virt_addr);

if (OVERLAY_NEEDS_PHYSICAL(overlay->dev)) {
regs = overlay->reg_bo->phys_obj->handle->vaddr;
} else {
regs = io_mapping_map_wc(dev_priv->mm.gtt_mapping,
overlay->reg_bo->gtt_offset);

if (!regs) {
DRM_ERROR("failed to map overlay regs in GTT\n");
return NULL;
}
}

return overlay->virt_addr = regs;
}

static void intel_overlay_unmap_regs(struct intel_overlay *overlay)
{
if (!OVERLAY_NEEDS_PHYSICAL(overlay->dev))
io_mapping_unmap(overlay->virt_addr);

overlay->virt_addr = NULL;

Expand Down Expand Up @@ -467,7 +504,8 @@ int intel_overlay_recover_from_interrupt(struct intel_overlay *overlay,

/* Wait for pending overlay flip and release old frame.
* Needs to be called before the overlay register are changed
* via intel_overlay_(un)map_regs_atomic */
* via intel_overlay_(un)map_regs
*/
static int intel_overlay_release_old_vid(struct intel_overlay *overlay)
{
int ret;
Expand Down Expand Up @@ -770,7 +808,7 @@ int intel_overlay_do_put_image(struct intel_overlay *overlay,
goto out_unpin;

if (!overlay->active) {
regs = intel_overlay_map_regs_atomic(overlay);
regs = intel_overlay_map_regs(overlay);
if (!regs) {
ret = -ENOMEM;
goto out_unpin;
Expand All @@ -780,14 +818,14 @@ int intel_overlay_do_put_image(struct intel_overlay *overlay,
regs->OCONFIG |= OCONF_CSC_MODE_BT709;
regs->OCONFIG |= overlay->crtc->pipe == 0 ?
OCONF_PIPE_A : OCONF_PIPE_B;
intel_overlay_unmap_regs_atomic(overlay);
intel_overlay_unmap_regs(overlay);

ret = intel_overlay_on(overlay);
if (ret != 0)
goto out_unpin;
}

regs = intel_overlay_map_regs_atomic(overlay);
regs = intel_overlay_map_regs(overlay);
if (!regs) {
ret = -ENOMEM;
goto out_unpin;
Expand Down Expand Up @@ -830,7 +868,7 @@ int intel_overlay_do_put_image(struct intel_overlay *overlay,

regs->OCMD = overlay_cmd_reg(params);

intel_overlay_unmap_regs_atomic(overlay);
intel_overlay_unmap_regs(overlay);

intel_overlay_continue(overlay, scale_changed);

Expand Down Expand Up @@ -866,9 +904,9 @@ int intel_overlay_switch_off(struct intel_overlay *overlay)
if (ret != 0)
return ret;

regs = intel_overlay_map_regs_atomic(overlay);
regs = intel_overlay_map_regs(overlay);
regs->OCMD = 0;
intel_overlay_unmap_regs_atomic(overlay);
intel_overlay_unmap_regs(overlay);

ret = intel_overlay_off(overlay);
if (ret != 0)
Expand Down Expand Up @@ -1314,15 +1352,15 @@ int intel_overlay_attrs(struct drm_device *dev, void *data,
goto out_unlock;
}

regs = intel_overlay_map_regs_atomic(overlay);
regs = intel_overlay_map_regs(overlay);
if (!regs) {
ret = -ENOMEM;
goto out_unlock;
}

update_reg_attrs(overlay, regs);

intel_overlay_unmap_regs_atomic(overlay);
intel_overlay_unmap_regs(overlay);

if (attrs->flags & I915_OVERLAY_UPDATE_GAMMA) {
if (!IS_I9XX(dev)) {
Expand Down Expand Up @@ -1407,7 +1445,7 @@ void intel_setup_overlay(struct drm_device *dev)
overlay->contrast = 75;
overlay->saturation = 146;

regs = intel_overlay_map_regs_atomic(overlay);
regs = intel_overlay_map_regs(overlay);
if (!regs)
goto out_free_bo;

Expand All @@ -1416,7 +1454,7 @@ void intel_setup_overlay(struct drm_device *dev)

update_reg_attrs(overlay, regs);

intel_overlay_unmap_regs_atomic(overlay);
intel_overlay_unmap_regs(overlay);

dev_priv->overlay = overlay;
DRM_INFO("initialized overlay support\n");
Expand Down Expand Up @@ -1474,12 +1512,12 @@ intel_overlay_capture_error_state(struct drm_device *dev)
else
error->base = (long) overlay->reg_bo->gtt_offset;

regs = intel_overlay_map_regs_atomic(overlay);
regs = intel_overlay_map_regs_atomic(overlay, KM_IRQ0);
if (!regs)
goto err;

memcpy_fromio(&error->regs, regs, sizeof(struct overlay_registers));
intel_overlay_unmap_regs_atomic(overlay);
intel_overlay_unmap_regs_atomic(overlay, KM_IRQ0);

return error;

Expand Down

0 comments on commit 8d74f65

Please sign in to comment.