diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2011-03-02 00:20:20 +0100 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2011-03-02 00:20:20 +0100 |
commit | 8d3c3ddfa85837e24fad6fa39318617cbb59e843 (patch) | |
tree | f699dcaac2a11f0c9506ad111ae39fd5e3617c2d /drivers/gpu | |
parent | drm/i915: Re-enable GPU semaphores for SandyBridge mobile (diff) | |
parent | drm/i915: fix memory corruption with GM965 and >4GB RAM (diff) | |
download | linux-8d3c3ddfa85837e24fad6fa39318617cbb59e843.tar.xz linux-8d3c3ddfa85837e24fad6fa39318617cbb59e843.zip |
Merge branch 'drm-intel-fixes' into drm-intel-next
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/drm/drm_irq.c | 29 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_dma.c | 11 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem_tiling.c | 16 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_display.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_bo.c | 5 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/r100.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_display.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_fb.c | 5 |
8 files changed, 53 insertions, 21 deletions
diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index 3dadfa2a8528..28d1d3c24d65 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c @@ -164,8 +164,10 @@ static void vblank_disable_and_save(struct drm_device *dev, int crtc) * available. In that case we can't account for this and just * hope for the best. */ - if ((vblrc > 0) && (abs(diff_ns) > 1000000)) + if ((vblrc > 0) && (abs64(diff_ns) > 1000000)) { atomic_inc(&dev->_vblank_count[crtc]); + smp_mb__after_atomic_inc(); + } /* Invalidate all timestamps while vblank irq's are off. */ clear_vblank_timestamps(dev, crtc); @@ -491,6 +493,12 @@ void drm_calc_timestamping_constants(struct drm_crtc *crtc) /* Dot clock in Hz: */ dotclock = (u64) crtc->hwmode.clock * 1000; + /* Fields of interlaced scanout modes are only halve a frame duration. + * Double the dotclock to get halve the frame-/line-/pixelduration. + */ + if (crtc->hwmode.flags & DRM_MODE_FLAG_INTERLACE) + dotclock *= 2; + /* Valid dotclock? */ if (dotclock > 0) { /* Convert scanline length in pixels and video dot clock to @@ -603,14 +611,6 @@ int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, int crtc, return -EAGAIN; } - /* Don't know yet how to handle interlaced or - * double scan modes. Just no-op for now. - */ - if (mode->flags & (DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLSCAN)) { - DRM_DEBUG("crtc %d: Noop due to unsupported mode.\n", crtc); - return -ENOTSUPP; - } - /* Get current scanout position with system timestamp. * Repeat query up to DRM_TIMESTAMP_MAXRETRIES times * if single query takes longer than max_error nanoseconds. @@ -858,10 +858,11 @@ static void drm_update_vblank_count(struct drm_device *dev, int crtc) if (rc) { tslot = atomic_read(&dev->_vblank_count[crtc]) + diff; vblanktimestamp(dev, crtc, tslot) = t_vblank; - smp_wmb(); } + smp_mb__before_atomic_inc(); atomic_add(diff, &dev->_vblank_count[crtc]); + smp_mb__after_atomic_inc(); } /** @@ -1011,7 +1012,8 @@ int drm_modeset_ctl(struct drm_device *dev, void *data, struct drm_file *file_priv) { struct drm_modeset_ctl *modeset = data; - int crtc, ret = 0; + int ret = 0; + unsigned int crtc; /* If drm_vblank_init() hasn't been called yet, just no-op */ if (!dev->num_crtcs) @@ -1293,15 +1295,16 @@ bool drm_handle_vblank(struct drm_device *dev, int crtc) * e.g., due to spurious vblank interrupts. We need to * ignore those for accounting. */ - if (abs(diff_ns) > DRM_REDUNDANT_VBLIRQ_THRESH_NS) { + if (abs64(diff_ns) > DRM_REDUNDANT_VBLIRQ_THRESH_NS) { /* Store new timestamp in ringbuffer. */ vblanktimestamp(dev, crtc, vblcount + 1) = tvblank; - smp_wmb(); /* Increment cooked vblank count. This also atomically commits * the timestamp computed above. */ + smp_mb__before_atomic_inc(); atomic_inc(&dev->_vblank_count[crtc]); + smp_mb__after_atomic_inc(); } else { DRM_DEBUG("crtc %d: Redundant vblirq ignored. diff_ns = %d\n", crtc, (int) diff_ns); diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 51150692af2d..8924b4bc7369 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -1900,6 +1900,17 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) if (IS_GEN2(dev)) dma_set_coherent_mask(&dev->pdev->dev, DMA_BIT_MASK(30)); + /* 965GM sometimes incorrectly writes to hardware status page (HWS) + * using 32bit addressing, overwriting memory if HWS is located + * above 4GB. + * + * The documentation also mentions an issue with undefined + * behaviour if any general state is accessed within a page above 4GB, + * which also needs to be handled carefully. + */ + if (IS_BROADWATER(dev) || IS_CRESTLINE(dev)) + dma_set_coherent_mask(&dev->pdev->dev, DMA_BIT_MASK(32)); + mmio_bar = IS_GEN2(dev) ? 1 : 0; dev_priv->regs = pci_iomap(dev->pdev, mmio_bar, 0); if (!dev_priv->regs) { diff --git a/drivers/gpu/drm/i915/i915_gem_tiling.c b/drivers/gpu/drm/i915/i915_gem_tiling.c index 0a8969392829..1f45019e6da3 100644 --- a/drivers/gpu/drm/i915/i915_gem_tiling.c +++ b/drivers/gpu/drm/i915/i915_gem_tiling.c @@ -184,7 +184,7 @@ i915_gem_detect_bit_6_swizzle(struct drm_device *dev) static bool i915_tiling_ok(struct drm_device *dev, int stride, int size, int tiling_mode) { - int tile_width; + int tile_width, tile_height; /* Linear is always fine */ if (tiling_mode == I915_TILING_NONE) @@ -215,6 +215,20 @@ i915_tiling_ok(struct drm_device *dev, int stride, int size, int tiling_mode) } } + if (IS_GEN2(dev) || + (tiling_mode == I915_TILING_Y && HAS_128_BYTE_Y_TILING(dev))) + tile_height = 32; + else + tile_height = 8; + /* i8xx is strange: It has 2 interleaved rows of tiles, so needs an even + * number of tile rows. */ + if (IS_GEN2(dev)) + tile_height *= 2; + + /* Size needs to be aligned to a full tile row */ + if (size & (tile_height * stride - 1)) + return false; + /* 965+ just needs multiples of tile width */ if (INTEL_INFO(dev)->gen >= 4) { if (stride & (tile_width - 1)) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index c19e974c0019..4a392b4a5ae9 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -7148,7 +7148,7 @@ static void ironlake_disable_rc6(struct drm_device *dev) POSTING_READ(RSTDBYCTL); } - ironlake_disable_rc6(dev); + ironlake_teardown_rc6(dev); } static int ironlake_setup_rc6(struct drm_device *dev) diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index d38a4d9f9b0b..a52184007f5f 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c @@ -49,7 +49,10 @@ nouveau_bo_del_ttm(struct ttm_buffer_object *bo) DRM_ERROR("bo %p still attached to GEM object\n", bo); nv10_mem_put_tile_region(dev, nvbo->tile, NULL); - nouveau_vm_put(&nvbo->vma); + if (nvbo->vma.node) { + nouveau_vm_unmap(&nvbo->vma); + nouveau_vm_put(&nvbo->vma); + } kfree(nvbo); } diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index 56deae5bf02e..93fa735c8c1a 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c @@ -3490,7 +3490,7 @@ void r100_cs_track_clear(struct radeon_device *rdev, struct r100_cs_track *track track->num_texture = 16; track->maxy = 4096; track->separate_cube = 0; - track->aaresolve = true; + track->aaresolve = false; track->aa.robj = NULL; } @@ -3801,8 +3801,6 @@ static int r100_startup(struct radeon_device *rdev) r100_mc_program(rdev); /* Resume clock */ r100_clock_startup(rdev); - /* Initialize GPU configuration (# pipes, ...) */ -// r100_gpu_init(rdev); /* Initialize GART (initialize after TTM so we can allocate * memory through TTM but finalize after TTM) */ r100_enable_bm(rdev); diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c index 0e657095de7c..3e7e7f9eb781 100644 --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c @@ -971,7 +971,7 @@ void radeon_compute_pll_legacy(struct radeon_pll *pll, max_fractional_feed_div = pll->max_frac_feedback_div; } - for (post_div = min_post_div; post_div <= max_post_div; ++post_div) { + for (post_div = max_post_div; post_div >= min_post_div; --post_div) { uint32_t ref_div; if ((pll->flags & RADEON_PLL_NO_ODD_POST_DIV) && (post_div & 1)) diff --git a/drivers/gpu/drm/radeon/radeon_fb.c b/drivers/gpu/drm/radeon/radeon_fb.c index 66324b5bb5ba..cc44bdfec80f 100644 --- a/drivers/gpu/drm/radeon/radeon_fb.c +++ b/drivers/gpu/drm/radeon/radeon_fb.c @@ -113,11 +113,14 @@ static int radeonfb_create_pinned_object(struct radeon_fbdev *rfbdev, u32 tiling_flags = 0; int ret; int aligned_size, size; + int height = mode_cmd->height; /* need to align pitch with crtc limits */ mode_cmd->pitch = radeon_align_pitch(rdev, mode_cmd->width, mode_cmd->bpp, fb_tiled) * ((mode_cmd->bpp + 1) / 8); - size = mode_cmd->pitch * mode_cmd->height; + if (rdev->family >= CHIP_R600) + height = ALIGN(mode_cmd->height, 8); + size = mode_cmd->pitch * height; aligned_size = ALIGN(size, PAGE_SIZE); ret = radeon_gem_object_create(rdev, aligned_size, 0, RADEON_GEM_DOMAIN_VRAM, |