Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 205174
b: refs/heads/master
c: cda4b7d
h: refs/heads/master
v: v3
  • Loading branch information
Chris Wilson authored and Eric Anholt committed Aug 2, 2010
1 parent c972ea1 commit 844bf5e
Show file tree
Hide file tree
Showing 3 changed files with 100 additions and 54 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 86f100b136626e91f4f66f3776303475e2e58998
refs/heads/master: cda4b7d3a5b1dcbc0d8e7bad52134347798e9047
144 changes: 93 additions & 51 deletions trunk/drivers/gpu/drm/i915/intel_display.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
bool intel_pipe_has_type (struct drm_crtc *crtc, int type);
static void intel_update_watermarks(struct drm_device *dev);
static void intel_increase_pllclock(struct drm_crtc *crtc, bool schedule);
static void intel_crtc_update_cursor(struct drm_crtc *crtc);

typedef struct {
/* given values */
Expand Down Expand Up @@ -3575,6 +3576,9 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
return -EINVAL;
}

/* Ensure that the cursor is valid for the new mode before changing... */
intel_crtc_update_cursor(crtc);

if (is_lvds && dev_priv->lvds_downclock_avail) {
has_reduced_clock = limit->find_pll(limit, crtc,
dev_priv->lvds_downclock,
Expand Down Expand Up @@ -4111,6 +4115,85 @@ void intel_crtc_load_lut(struct drm_crtc *crtc)
}
}

/* If no-part of the cursor is visible on the framebuffer, then the GPU may hang... */
static void intel_crtc_update_cursor(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 pipe = intel_crtc->pipe;
int x = intel_crtc->cursor_x;
int y = intel_crtc->cursor_y;
uint32_t base, pos;
bool visible;

pos = 0;

if (crtc->fb) {
base = intel_crtc->cursor_addr;
if (x > (int) crtc->fb->width)
base = 0;

if (y > (int) crtc->fb->height)
base = 0;
} else
base = 0;

if (x < 0) {
if (x + intel_crtc->cursor_width < 0)
base = 0;

pos |= CURSOR_POS_SIGN << CURSOR_X_SHIFT;
x = -x;
}
pos |= x << CURSOR_X_SHIFT;

if (y < 0) {
if (y + intel_crtc->cursor_height < 0)
base = 0;

pos |= CURSOR_POS_SIGN << CURSOR_Y_SHIFT;
y = -y;
}
pos |= y << CURSOR_Y_SHIFT;

visible = base != 0;
if (!visible && !intel_crtc->cursor_visble)
return;

I915_WRITE(pipe == 0 ? CURAPOS : CURBPOS, pos);
if (intel_crtc->cursor_visble != visible) {
uint32_t cntl = I915_READ(pipe == 0 ? CURACNTR : CURBCNTR);
if (base) {
/* Hooray for CUR*CNTR differences */
if (IS_MOBILE(dev) || IS_I9XX(dev)) {
cntl &= ~(CURSOR_MODE | MCURSOR_PIPE_SELECT);
cntl |= CURSOR_MODE_64_ARGB_AX | MCURSOR_GAMMA_ENABLE;
cntl |= pipe << 28; /* Connect to correct pipe */
} else {
cntl &= ~(CURSOR_FORMAT_MASK);
cntl |= CURSOR_ENABLE;
cntl |= CURSOR_FORMAT_ARGB | CURSOR_GAMMA_ENABLE;
}
} else {
if (IS_MOBILE(dev) || IS_I9XX(dev)) {
cntl &= ~(CURSOR_MODE | MCURSOR_GAMMA_ENABLE);
cntl |= CURSOR_MODE_DISABLE;
} else {
cntl &= ~(CURSOR_ENABLE | CURSOR_GAMMA_ENABLE);
}
}
I915_WRITE(pipe == 0 ? CURACNTR : CURBCNTR, cntl);

intel_crtc->cursor_visble = visible;
}
/* and commit changes on next vblank */
I915_WRITE(pipe == 0 ? CURABASE : CURBBASE, base);

if (visible)
intel_mark_busy(dev, to_intel_framebuffer(crtc->fb)->obj);
}

static int intel_crtc_cursor_set(struct drm_crtc *crtc,
struct drm_file *file_priv,
uint32_t handle,
Expand All @@ -4121,24 +4204,14 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc,
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
struct drm_gem_object *bo;
struct drm_i915_gem_object *obj_priv;
int pipe = intel_crtc->pipe;
uint32_t control = (pipe == 0) ? CURACNTR : CURBCNTR;
uint32_t base = (pipe == 0) ? CURABASE : CURBBASE;
uint32_t temp = I915_READ(control);
size_t addr;
uint32_t addr;
int ret;

DRM_DEBUG_KMS("\n");

/* if we want to turn off the cursor ignore width and height */
if (!handle) {
DRM_DEBUG_KMS("cursor off\n");
if (IS_MOBILE(dev) || IS_I9XX(dev)) {
temp &= ~(CURSOR_MODE | MCURSOR_GAMMA_ENABLE);
temp |= CURSOR_MODE_DISABLE;
} else {
temp &= ~(CURSOR_ENABLE | CURSOR_GAMMA_ENABLE);
}
addr = 0;
bo = NULL;
mutex_lock(&dev->struct_mutex);
Expand Down Expand Up @@ -4180,7 +4253,8 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc,

addr = obj_priv->gtt_offset;
} else {
ret = i915_gem_attach_phys_object(dev, bo, (pipe == 0) ? I915_GEM_PHYS_CURSOR_0 : I915_GEM_PHYS_CURSOR_1);
ret = i915_gem_attach_phys_object(dev, bo,
(intel_crtc->pipe == 0) ? I915_GEM_PHYS_CURSOR_0 : I915_GEM_PHYS_CURSOR_1);
if (ret) {
DRM_ERROR("failed to attach phys object\n");
goto fail_locked;
Expand All @@ -4191,21 +4265,7 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc,
if (!IS_I9XX(dev))
I915_WRITE(CURSIZE, (height << 12) | width);

/* Hooray for CUR*CNTR differences */
if (IS_MOBILE(dev) || IS_I9XX(dev)) {
temp &= ~(CURSOR_MODE | MCURSOR_PIPE_SELECT);
temp |= CURSOR_MODE_64_ARGB_AX | MCURSOR_GAMMA_ENABLE;
temp |= (pipe << 28); /* Connect to correct pipe */
} else {
temp &= ~(CURSOR_FORMAT_MASK);
temp |= CURSOR_ENABLE;
temp |= CURSOR_FORMAT_ARGB | CURSOR_GAMMA_ENABLE;
}

finish:
I915_WRITE(control, temp);
I915_WRITE(base, addr);

if (intel_crtc->cursor_bo) {
if (dev_priv->info->cursor_needs_physical) {
if (intel_crtc->cursor_bo != bo)
Expand All @@ -4219,6 +4279,10 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc,

intel_crtc->cursor_addr = addr;
intel_crtc->cursor_bo = bo;
intel_crtc->cursor_width = width;
intel_crtc->cursor_height = height;

intel_crtc_update_cursor(crtc);

return 0;
fail_unpin:
Expand All @@ -4232,34 +4296,12 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc,

static int intel_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
{
struct drm_device *dev = crtc->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
struct intel_framebuffer *intel_fb;
int pipe = intel_crtc->pipe;
uint32_t temp = 0;
uint32_t adder;

if (crtc->fb) {
intel_fb = to_intel_framebuffer(crtc->fb);
intel_mark_busy(dev, intel_fb->obj);
}

if (x < 0) {
temp |= CURSOR_POS_SIGN << CURSOR_X_SHIFT;
x = -x;
}
if (y < 0) {
temp |= CURSOR_POS_SIGN << CURSOR_Y_SHIFT;
y = -y;
}

temp |= x << CURSOR_X_SHIFT;
temp |= y << CURSOR_Y_SHIFT;
intel_crtc->cursor_x = x;
intel_crtc->cursor_y = y;

adder = intel_crtc->cursor_addr;
I915_WRITE((pipe == 0) ? CURAPOS : CURBPOS, temp);
I915_WRITE((pipe == 0) ? CURABASE : CURBBASE, adder);
intel_crtc_update_cursor(crtc);

return 0;
}
Expand Down
8 changes: 6 additions & 2 deletions trunk/drivers/gpu/drm/i915/intel_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -143,8 +143,6 @@ struct intel_crtc {
struct drm_crtc base;
enum pipe pipe;
enum plane plane;
struct drm_gem_object *cursor_bo;
uint32_t cursor_addr;
u8 lut_r[256], lut_g[256], lut_b[256];
int dpms_mode;
bool busy; /* is scanout buffer being updated frequently? */
Expand All @@ -153,6 +151,12 @@ struct intel_crtc {
struct intel_overlay *overlay;
struct intel_unpin_work *unpin_work;
int fdi_lanes;

struct drm_gem_object *cursor_bo;
uint32_t cursor_addr;
int16_t cursor_x, cursor_y;
int16_t cursor_width, cursor_height;
bool cursor_visble;
};

#define to_intel_crtc(x) container_of(x, struct intel_crtc, base)
Expand Down

0 comments on commit 844bf5e

Please sign in to comment.