drm/i915: use new fb debug hooks

Implement atomic kernel mode settings using the fb layer's debug hook
system for supporting debugger interaction.

Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Jason Wessel <jason.wessel@windriver.com>
This commit is contained in:
Jesse Barnes 2010-08-02 12:07:50 -07:00 committed by Jason Wessel
parent 1a7aba7f4e
commit 81255565db
2 changed files with 99 additions and 1 deletions

View File

@ -975,7 +975,10 @@ void
intel_wait_for_vblank(struct drm_device *dev)
{
/* Wait for 20ms, i.e. one cycle at 50hz. */
msleep(20);
if (in_dbg_master())
mdelay(20); /* The kernel debugger cannot call msleep() */
else
msleep(20);
}
/* Parameters have changed, update FBC info */
@ -1314,6 +1317,98 @@ intel_pin_and_fence_fb_obj(struct drm_device *dev, struct drm_gem_object *obj)
return 0;
}
/* Assume fb object is pinned & idle & fenced and just update base pointers */
static int
intel_pipe_set_base_atomic(struct drm_crtc *crtc, struct drm_framebuffer *fb,
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;
struct drm_i915_gem_object *obj_priv;
struct drm_gem_object *obj;
int plane = intel_crtc->plane;
unsigned long Start, Offset;
int dspbase = (plane == 0 ? DSPAADDR : DSPBADDR);
int dspsurf = (plane == 0 ? DSPASURF : DSPBSURF);
int dspstride = (plane == 0) ? DSPASTRIDE : DSPBSTRIDE;
int dsptileoff = (plane == 0 ? DSPATILEOFF : DSPBTILEOFF);
int dspcntr_reg = (plane == 0) ? DSPACNTR : DSPBCNTR;
u32 dspcntr;
switch (plane) {
case 0:
case 1:
break;
default:
DRM_ERROR("Can't update plane %d in SAREA\n", plane);
return -EINVAL;
}
intel_fb = to_intel_framebuffer(fb);
obj = intel_fb->obj;
obj_priv = to_intel_bo(obj);
dspcntr = I915_READ(dspcntr_reg);
/* Mask out pixel format bits in case we change it */
dspcntr &= ~DISPPLANE_PIXFORMAT_MASK;
switch (fb->bits_per_pixel) {
case 8:
dspcntr |= DISPPLANE_8BPP;
break;
case 16:
if (fb->depth == 15)
dspcntr |= DISPPLANE_15_16BPP;
else
dspcntr |= DISPPLANE_16BPP;
break;
case 24:
case 32:
dspcntr |= DISPPLANE_32BPP_NO_ALPHA;
break;
default:
DRM_ERROR("Unknown color depth\n");
return -EINVAL;
}
if (IS_I965G(dev)) {
if (obj_priv->tiling_mode != I915_TILING_NONE)
dspcntr |= DISPPLANE_TILED;
else
dspcntr &= ~DISPPLANE_TILED;
}
if (IS_IRONLAKE(dev))
/* must disable */
dspcntr |= DISPPLANE_TRICKLE_FEED_DISABLE;
I915_WRITE(dspcntr_reg, dspcntr);
Start = obj_priv->gtt_offset;
Offset = y * fb->pitch + x * (fb->bits_per_pixel / 8);
DRM_DEBUG("Writing base %08lX %08lX %d %d\n", Start, Offset, x, y);
I915_WRITE(dspstride, fb->pitch);
if (IS_I965G(dev)) {
I915_WRITE(dspbase, Offset);
I915_READ(dspbase);
I915_WRITE(dspsurf, Start);
I915_READ(dspsurf);
I915_WRITE(dsptileoff, (y << 16) | x);
} else {
I915_WRITE(dspbase, Start + Offset);
I915_READ(dspbase);
}
if ((IS_I965G(dev) || plane == 0))
intel_update_fbc(crtc, &crtc->mode);
intel_wait_for_vblank(dev);
intel_increase_pllclock(crtc, true);
return 0;
}
static int
intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
struct drm_framebuffer *old_fb)
@ -4814,6 +4909,7 @@ static const struct drm_crtc_helper_funcs intel_helper_funcs = {
.mode_fixup = intel_crtc_mode_fixup,
.mode_set = intel_crtc_mode_set,
.mode_set_base = intel_pipe_set_base,
.mode_set_base_atomic = intel_pipe_set_base_atomic,
.prepare = intel_crtc_prepare,
.commit = intel_crtc_commit,
.load_lut = intel_crtc_load_lut,

View File

@ -61,6 +61,8 @@ static struct fb_ops intelfb_ops = {
.fb_pan_display = drm_fb_helper_pan_display,
.fb_blank = drm_fb_helper_blank,
.fb_setcmap = drm_fb_helper_setcmap,
.fb_debug_enter = drm_fb_helper_debug_enter,
.fb_debug_leave = drm_fb_helper_debug_leave,
};
static int intelfb_create(struct intel_fbdev *ifbdev,