Commit 560b85bb authored by Chris Wilson's avatar Chris Wilson Committed by Eric Anholt

drm/i915: Only update i845/i865 CURBASE when disabled (v2)

The i845 and i865 have a peculiarlity in that CURBASE is not the trigger
for the vsync update of the cursor registers but instead the
modification of that register is prohibited whilst the cursor is
enabled. Reorder the write sequence for CURPOS, CURCNTR and CURBASE on
i845 to i865 to match.

v2: Remove the checks for i845/i865 from within i9xx_cursor_update()
Signed-off-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: default avatarEric Anholt <eric@anholt.net>
parent c27ba48e
...@@ -4204,6 +4204,62 @@ void intel_crtc_load_lut(struct drm_crtc *crtc) ...@@ -4204,6 +4204,62 @@ void intel_crtc_load_lut(struct drm_crtc *crtc)
} }
} }
static void i845_update_cursor(struct drm_crtc *crtc, u32 base)
{
struct drm_device *dev = crtc->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
bool visible = base != 0;
u32 cntl;
if (intel_crtc->cursor_visible == visible)
return;
cntl = I915_READ(CURACNTR);
if (visible) {
/* On these chipsets we can only modify the base whilst
* the cursor is disabled.
*/
I915_WRITE(CURABASE, base);
cntl &= ~(CURSOR_FORMAT_MASK);
/* XXX width must be 64, stride 256 => 0x00 << 28 */
cntl |= CURSOR_ENABLE |
CURSOR_GAMMA_ENABLE |
CURSOR_FORMAT_ARGB;
} else
cntl &= ~(CURSOR_ENABLE | CURSOR_GAMMA_ENABLE);
I915_WRITE(CURACNTR, cntl);
intel_crtc->cursor_visible = visible;
}
static void i9xx_update_cursor(struct drm_crtc *crtc, u32 base)
{
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;
bool visible = base != 0;
if (intel_crtc->cursor_visible != visible) {
uint32_t cntl = I915_READ(pipe == 0 ? CURACNTR : CURBCNTR);
if (base) {
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_MODE | MCURSOR_GAMMA_ENABLE);
cntl |= CURSOR_MODE_DISABLE;
}
I915_WRITE(pipe == 0 ? CURACNTR : CURBCNTR, cntl);
intel_crtc->cursor_visible = visible;
}
/* and commit changes on next vblank */
I915_WRITE(pipe == 0 ? CURABASE : CURBBASE, base);
}
/* If no-part of the cursor is visible on the framebuffer, then the GPU may hang... */ /* 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) static void intel_crtc_update_cursor(struct drm_crtc *crtc)
{ {
...@@ -4213,7 +4269,7 @@ static void intel_crtc_update_cursor(struct drm_crtc *crtc) ...@@ -4213,7 +4269,7 @@ static void intel_crtc_update_cursor(struct drm_crtc *crtc)
int pipe = intel_crtc->pipe; int pipe = intel_crtc->pipe;
int x = intel_crtc->cursor_x; int x = intel_crtc->cursor_x;
int y = intel_crtc->cursor_y; int y = intel_crtc->cursor_y;
uint32_t base, pos; u32 base, pos;
bool visible; bool visible;
pos = 0; pos = 0;
...@@ -4247,37 +4303,14 @@ static void intel_crtc_update_cursor(struct drm_crtc *crtc) ...@@ -4247,37 +4303,14 @@ static void intel_crtc_update_cursor(struct drm_crtc *crtc)
pos |= y << CURSOR_Y_SHIFT; pos |= y << CURSOR_Y_SHIFT;
visible = base != 0; visible = base != 0;
if (!visible && !intel_crtc->cursor_visble) if (!visible && !intel_crtc->cursor_visible)
return; return;
I915_WRITE(pipe == 0 ? CURAPOS : CURBPOS, pos); I915_WRITE(pipe == 0 ? CURAPOS : CURBPOS, pos);
if (intel_crtc->cursor_visble != visible) { if (IS_845G(dev) || IS_I865G(dev))
uint32_t cntl = I915_READ(pipe == 0 ? CURACNTR : CURBCNTR); i845_update_cursor(crtc, base);
if (base) { else
/* Hooray for CUR*CNTR differences */ i9xx_update_cursor(crtc, base);
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) if (visible)
intel_mark_busy(dev, to_intel_framebuffer(crtc->fb)->obj); intel_mark_busy(dev, to_intel_framebuffer(crtc->fb)->obj);
......
...@@ -168,7 +168,7 @@ struct intel_crtc { ...@@ -168,7 +168,7 @@ struct intel_crtc {
uint32_t cursor_addr; uint32_t cursor_addr;
int16_t cursor_x, cursor_y; int16_t cursor_x, cursor_y;
int16_t cursor_width, cursor_height; int16_t cursor_width, cursor_height;
bool cursor_visble, cursor_on; bool cursor_visible, cursor_on;
}; };
#define to_intel_crtc(x) container_of(x, struct intel_crtc, base) #define to_intel_crtc(x) container_of(x, struct intel_crtc, base)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment