Skip to content

Commit

Permalink
Merge branch 'drm-fixes' of git://people.freedesktop.org/~airlied/linux
Browse files Browse the repository at this point in the history
Pull drm fixes from Dave Airlie:
 "Fixes for i915, nouveau and radeon:

   - i915: haswell stability, modeset rework fallout, ums fix
   - nouveau: misc fixes from code rework
   - radeon: pll rework fixes, more 2 level PTE cleanups.
   - core: warning fixes on 32-bit."

* 'drm-fixes' of git://people.freedesktop.org/~airlied/linux: (31 commits)
  nouveau: fix warning on 32-bit build.
  drm/nouveau/bios: fix typo in error message
  drm/nouveau: only call ttm_agp_tt_create when __OS_HAS_AGP
  drm/nv50/fb: fix double free of vram mm
  drm/nouveau/pm: do not stop reclocking if failing to set the fan speed
  drm/nouveau/pm: fix a typo related to the move to the therm subdev
  drm/nouveau/hwmon: fix the initialization condition
  drm: fix warning on 32-bit.
  drm: radeon: fix printk format warning
  drm/radeon: fix spelling typos in debugging output
  drm/radeon: Don't destroy I2C Bus Rec in radeon_ext_tmds_enc_destroy().
  drm/radeon: check if pcie gen 2 is already enabled (v2)
  drm/radeon/cayman: set VM max pfn at MC init
  drm/radeon: separate pt alloc from lru add
  drm/radeon: don't add the IB pool to all VMs v2
  drm/radeon: allocate page tables on demand v4
  drm/radeon: update comments to clarify VM setup (v2)
  drm/radeon: allocate PPLLs from low to high
  drm/radeon: fix compilation with backlight disabled
  drm/radeon: use %zu for formatting size_t
  ...
  • Loading branch information
Linus Torvalds committed Oct 17, 2012
2 parents 5d5c5dc + 8a00b6a commit 75fa29c
Show file tree
Hide file tree
Showing 29 changed files with 443 additions and 249 deletions.
2 changes: 1 addition & 1 deletion drivers/char/agp/intel-gtt.c
Original file line number Diff line number Diff line change
Expand Up @@ -667,7 +667,7 @@ static int intel_gtt_init(void)
gtt_map_size = intel_private.base.gtt_total_entries * 4;

intel_private.gtt = NULL;
if (INTEL_GTT_GEN < 6)
if (INTEL_GTT_GEN < 6 && INTEL_GTT_GEN > 2)
intel_private.gtt = ioremap_wc(intel_private.gtt_bus_addr,
gtt_map_size);
if (intel_private.gtt == NULL)
Expand Down
2 changes: 1 addition & 1 deletion drivers/gpu/drm/drm_info.c
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ int drm_vma_info(struct seq_file *m, void *data)
mutex_lock(&dev->struct_mutex);
seq_printf(m, "vma use count: %d, high_memory = %pK, 0x%pK\n",
atomic_read(&dev->vma_count),
high_memory, (void *)virt_to_phys(high_memory));
high_memory, (void *)(unsigned long)virt_to_phys(high_memory));

list_for_each_entry(pt, &dev->vmalist, head) {
vma = pt->vma;
Expand Down
6 changes: 3 additions & 3 deletions drivers/gpu/drm/i915/dvo_ch7xxx.c
Original file line number Diff line number Diff line change
Expand Up @@ -303,10 +303,10 @@ static bool ch7xxx_get_hw_state(struct intel_dvo_device *dvo)

ch7xxx_readb(dvo, CH7xxx_PM, &val);

if (val & CH7xxx_PM_FPD)
return false;
else
if (val & (CH7xxx_PM_DVIL | CH7xxx_PM_DVIP))
return true;
else
return false;
}

static void ch7xxx_dump_regs(struct intel_dvo_device *dvo)
Expand Down
9 changes: 7 additions & 2 deletions drivers/gpu/drm/i915/i915_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -1341,9 +1341,14 @@ int __must_check i915_gem_object_get_pages(struct drm_i915_gem_object *obj);
static inline struct page *i915_gem_object_get_page(struct drm_i915_gem_object *obj, int n)
{
struct scatterlist *sg = obj->pages->sgl;
while (n >= SG_MAX_SINGLE_ALLOC) {
int nents = obj->pages->nents;
while (nents > SG_MAX_SINGLE_ALLOC) {
if (n < SG_MAX_SINGLE_ALLOC - 1)
break;

sg = sg_chain_ptr(sg + SG_MAX_SINGLE_ALLOC - 1);
n -= SG_MAX_SINGLE_ALLOC - 1;
nents -= SG_MAX_SINGLE_ALLOC - 1;
}
return sg_page(sg+n);
}
Expand Down Expand Up @@ -1427,7 +1432,7 @@ int __must_check i915_gpu_idle(struct drm_device *dev);
int __must_check i915_gem_idle(struct drm_device *dev);
int i915_add_request(struct intel_ring_buffer *ring,
struct drm_file *file,
struct drm_i915_gem_request *request);
u32 *seqno);
int __must_check i915_wait_seqno(struct intel_ring_buffer *ring,
uint32_t seqno);
int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf);
Expand Down
19 changes: 11 additions & 8 deletions drivers/gpu/drm/i915/i915_gem.c
Original file line number Diff line number Diff line change
Expand Up @@ -1955,11 +1955,12 @@ i915_gem_next_request_seqno(struct intel_ring_buffer *ring)
int
i915_add_request(struct intel_ring_buffer *ring,
struct drm_file *file,
struct drm_i915_gem_request *request)
u32 *out_seqno)
{
drm_i915_private_t *dev_priv = ring->dev->dev_private;
uint32_t seqno;
struct drm_i915_gem_request *request;
u32 request_ring_position;
u32 seqno;
int was_empty;
int ret;

Expand All @@ -1974,11 +1975,9 @@ i915_add_request(struct intel_ring_buffer *ring,
if (ret)
return ret;

if (request == NULL) {
request = kmalloc(sizeof(*request), GFP_KERNEL);
if (request == NULL)
return -ENOMEM;
}
request = kmalloc(sizeof(*request), GFP_KERNEL);
if (request == NULL)
return -ENOMEM;

seqno = i915_gem_next_request_seqno(ring);

Expand Down Expand Up @@ -2030,6 +2029,8 @@ i915_add_request(struct intel_ring_buffer *ring,
}
}

if (out_seqno)
*out_seqno = seqno;
return 0;
}

Expand Down Expand Up @@ -3959,6 +3960,9 @@ i915_gem_init_hw(struct drm_device *dev)
if (!intel_enable_gtt())
return -EIO;

if (IS_HASWELL(dev) && (I915_READ(0x120010) == 1))
I915_WRITE(0x9008, I915_READ(0x9008) | 0xf0000);

i915_gem_l3_remap(dev);

i915_gem_init_swizzling(dev);
Expand Down Expand Up @@ -4098,7 +4102,6 @@ i915_gem_entervt_ioctl(struct drm_device *dev, void *data,
}

BUG_ON(!list_empty(&dev_priv->mm.active_list));
BUG_ON(!list_empty(&dev_priv->mm.inactive_list));
mutex_unlock(&dev->struct_mutex);

ret = drm_irq_install(dev);
Expand Down
2 changes: 1 addition & 1 deletion drivers/gpu/drm/i915/i915_reg.h
Original file line number Diff line number Diff line change
Expand Up @@ -521,7 +521,7 @@
*/
# define _3D_CHICKEN2_WM_READ_PIPELINED (1 << 14)
#define _3D_CHICKEN3 0x02090
#define _3D_CHICKEN_SF_DISABLE_FASTCLIP_CULL (1 << 5)
#define _3D_CHICKEN3_SF_DISABLE_FASTCLIP_CULL (1 << 5)

#define MI_MODE 0x0209c
# define VS_TIMER_DISPATCH (1 << 6)
Expand Down
47 changes: 34 additions & 13 deletions drivers/gpu/drm/i915/intel_display.c
Original file line number Diff line number Diff line change
Expand Up @@ -3253,6 +3253,16 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc)

if (HAS_PCH_CPT(dev))
intel_cpt_verify_modeset(dev, intel_crtc->pipe);

/*
* There seems to be a race in PCH platform hw (at least on some
* outputs) where an enabled pipe still completes any pageflip right
* away (as if the pipe is off) instead of waiting for vblank. As soon
* as the first vblank happend, everything works as expected. Hence just
* wait for one vblank before returning to avoid strange things
* happening.
*/
intel_wait_for_vblank(dev, intel_crtc->pipe);
}

static void ironlake_crtc_disable(struct drm_crtc *crtc)
Expand Down Expand Up @@ -7892,8 +7902,7 @@ static struct intel_quirk intel_quirks[] = {
/* ThinkPad T60 needs pipe A force quirk (bug #16494) */
{ 0x2782, 0x17aa, 0x201a, quirk_pipea_force },

/* 855 & before need to leave pipe A & dpll A up */
{ 0x3582, PCI_ANY_ID, PCI_ANY_ID, quirk_pipea_force },
/* 830/845 need to leave pipe A & dpll A up */
{ 0x2562, PCI_ANY_ID, PCI_ANY_ID, quirk_pipea_force },
{ 0x3577, PCI_ANY_ID, PCI_ANY_ID, quirk_pipea_force },

Expand Down Expand Up @@ -8049,29 +8058,42 @@ static void intel_enable_pipe_a(struct drm_device *dev)

}

static bool
intel_check_plane_mapping(struct intel_crtc *crtc)
{
struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
u32 reg, val;

if (dev_priv->num_pipe == 1)
return true;

reg = DSPCNTR(!crtc->plane);
val = I915_READ(reg);

if ((val & DISPLAY_PLANE_ENABLE) &&
(!!(val & DISPPLANE_SEL_PIPE_MASK) == crtc->pipe))
return false;

return true;
}

static void intel_sanitize_crtc(struct intel_crtc *crtc)
{
struct drm_device *dev = crtc->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
u32 reg, val;
u32 reg;

/* Clear any frame start delays used for debugging left by the BIOS */
reg = PIPECONF(crtc->pipe);
I915_WRITE(reg, I915_READ(reg) & ~PIPECONF_FRAME_START_DELAY_MASK);

/* We need to sanitize the plane -> pipe mapping first because this will
* disable the crtc (and hence change the state) if it is wrong. */
if (!HAS_PCH_SPLIT(dev)) {
* disable the crtc (and hence change the state) if it is wrong. Note
* that gen4+ has a fixed plane -> pipe mapping. */
if (INTEL_INFO(dev)->gen < 4 && !intel_check_plane_mapping(crtc)) {
struct intel_connector *connector;
bool plane;

reg = DSPCNTR(crtc->plane);
val = I915_READ(reg);

if ((val & DISPLAY_PLANE_ENABLE) == 0 &&
(!!(val & DISPPLANE_SEL_PIPE_MASK) == crtc->pipe))
goto ok;

DRM_DEBUG_KMS("[CRTC:%d] wrong plane connection detected!\n",
crtc->base.base.id);

Expand All @@ -8095,7 +8117,6 @@ static void intel_sanitize_crtc(struct intel_crtc *crtc)
WARN_ON(crtc->active);
crtc->base.enabled = false;
}
ok:

if (dev_priv->quirks & QUIRK_PIPEA_FORCE &&
crtc->pipe == PIPE_A && !crtc->active) {
Expand Down
3 changes: 2 additions & 1 deletion drivers/gpu/drm/i915/intel_dp.c
Original file line number Diff line number Diff line change
Expand Up @@ -2369,8 +2369,9 @@ static void
intel_dp_destroy(struct drm_connector *connector)
{
struct drm_device *dev = connector->dev;
struct intel_dp *intel_dp = intel_attached_dp(connector);

if (intel_dpd_is_edp(dev))
if (is_edp(intel_dp))
intel_panel_destroy_backlight(dev);

drm_sysfs_connector_remove(connector);
Expand Down
72 changes: 15 additions & 57 deletions drivers/gpu/drm/i915/intel_overlay.c
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,6 @@ static void intel_overlay_unmap_regs(struct intel_overlay *overlay,
}

static int intel_overlay_do_wait_request(struct intel_overlay *overlay,
struct drm_i915_gem_request *request,
void (*tail)(struct intel_overlay *))
{
struct drm_device *dev = overlay->dev;
Expand All @@ -218,12 +217,10 @@ static int intel_overlay_do_wait_request(struct intel_overlay *overlay,
int ret;

BUG_ON(overlay->last_flip_req);
ret = i915_add_request(ring, NULL, request);
if (ret) {
kfree(request);
return ret;
}
overlay->last_flip_req = request->seqno;
ret = i915_add_request(ring, NULL, &overlay->last_flip_req);
if (ret)
return ret;

overlay->flip_tail = tail;
ret = i915_wait_seqno(ring, overlay->last_flip_req);
if (ret)
Expand All @@ -240,35 +237,24 @@ static int intel_overlay_on(struct intel_overlay *overlay)
struct drm_device *dev = overlay->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_ring_buffer *ring = &dev_priv->ring[RCS];
struct drm_i915_gem_request *request;
int ret;

BUG_ON(overlay->active);
overlay->active = 1;

WARN_ON(IS_I830(dev) && !(dev_priv->quirks & QUIRK_PIPEA_FORCE));

request = kzalloc(sizeof(*request), GFP_KERNEL);
if (request == NULL) {
ret = -ENOMEM;
goto out;
}

ret = intel_ring_begin(ring, 4);
if (ret) {
kfree(request);
goto out;
}
if (ret)
return ret;

intel_ring_emit(ring, MI_OVERLAY_FLIP | MI_OVERLAY_ON);
intel_ring_emit(ring, overlay->flip_addr | OFC_UPDATE);
intel_ring_emit(ring, MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
intel_ring_emit(ring, MI_NOOP);
intel_ring_advance(ring);

ret = intel_overlay_do_wait_request(overlay, request, NULL);
out:
return ret;
return intel_overlay_do_wait_request(overlay, NULL);
}

/* overlay needs to be enabled in OCMD reg */
Expand All @@ -278,17 +264,12 @@ static int intel_overlay_continue(struct intel_overlay *overlay,
struct drm_device *dev = overlay->dev;
drm_i915_private_t *dev_priv = dev->dev_private;
struct intel_ring_buffer *ring = &dev_priv->ring[RCS];
struct drm_i915_gem_request *request;
u32 flip_addr = overlay->flip_addr;
u32 tmp;
int ret;

BUG_ON(!overlay->active);

request = kzalloc(sizeof(*request), GFP_KERNEL);
if (request == NULL)
return -ENOMEM;

if (load_polyphase_filter)
flip_addr |= OFC_UPDATE;

Expand All @@ -298,22 +279,14 @@ static int intel_overlay_continue(struct intel_overlay *overlay,
DRM_DEBUG("overlay underrun, DOVSTA: %x\n", tmp);

ret = intel_ring_begin(ring, 2);
if (ret) {
kfree(request);
if (ret)
return ret;
}

intel_ring_emit(ring, MI_OVERLAY_FLIP | MI_OVERLAY_CONTINUE);
intel_ring_emit(ring, flip_addr);
intel_ring_advance(ring);

ret = i915_add_request(ring, NULL, request);
if (ret) {
kfree(request);
return ret;
}

overlay->last_flip_req = request->seqno;
return 0;
return i915_add_request(ring, NULL, &overlay->last_flip_req);
}

static void intel_overlay_release_old_vid_tail(struct intel_overlay *overlay)
Expand Down Expand Up @@ -349,26 +322,20 @@ static int intel_overlay_off(struct intel_overlay *overlay)
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_ring_buffer *ring = &dev_priv->ring[RCS];
u32 flip_addr = overlay->flip_addr;
struct drm_i915_gem_request *request;
int ret;

BUG_ON(!overlay->active);

request = kzalloc(sizeof(*request), GFP_KERNEL);
if (request == NULL)
return -ENOMEM;

/* According to intel docs the overlay hw may hang (when switching
* off) without loading the filter coeffs. It is however unclear whether
* this applies to the disabling of the overlay or to the switching off
* of the hw. Do it in both cases */
flip_addr |= OFC_UPDATE;

ret = intel_ring_begin(ring, 6);
if (ret) {
kfree(request);
if (ret)
return ret;
}

/* wait for overlay to go idle */
intel_ring_emit(ring, MI_OVERLAY_FLIP | MI_OVERLAY_CONTINUE);
intel_ring_emit(ring, flip_addr);
Expand All @@ -379,8 +346,7 @@ static int intel_overlay_off(struct intel_overlay *overlay)
intel_ring_emit(ring, MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
intel_ring_advance(ring);

return intel_overlay_do_wait_request(overlay, request,
intel_overlay_off_tail);
return intel_overlay_do_wait_request(overlay, intel_overlay_off_tail);
}

/* recover from an interruption due to a signal
Expand Down Expand Up @@ -425,24 +391,16 @@ static int intel_overlay_release_old_vid(struct intel_overlay *overlay)
return 0;

if (I915_READ(ISR) & I915_OVERLAY_PLANE_FLIP_PENDING_INTERRUPT) {
struct drm_i915_gem_request *request;

/* synchronous slowpath */
request = kzalloc(sizeof(*request), GFP_KERNEL);
if (request == NULL)
return -ENOMEM;

ret = intel_ring_begin(ring, 2);
if (ret) {
kfree(request);
if (ret)
return ret;
}

intel_ring_emit(ring, MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
intel_ring_emit(ring, MI_NOOP);
intel_ring_advance(ring);

ret = intel_overlay_do_wait_request(overlay, request,
ret = intel_overlay_do_wait_request(overlay,
intel_overlay_release_old_vid_tail);
if (ret)
return ret;
Expand Down
Loading

0 comments on commit 75fa29c

Please sign in to comment.