Skip to content

Commit

Permalink
Merge branch 'drm-intel-fixes' of git://git.kernel.org/pub/scm/linux/…
Browse files Browse the repository at this point in the history
…kernel/git/ickle/drm-intel

* 'drm-intel-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/ickle/drm-intel:
  drm/i915: Fix LVDS fixed-mode regression from 219adae
  drm/i915/ringbuffer: Use the HEAD auto-reporting mechanism
  drm/i915: Avoid might_fault during pwrite whilst holding our mutex
  agp/intel: fix cache control for sandybridge
  agp/intel: restore cache behavior on sandybridge
  drm/i915; Don't apply Ironlake FDI clock workaround to Sandybridge
  drm/i915: Fix KMS regression on Sandybridge/CPT
  i915: reprogram power monitoring registers on resume
  drm/i915: SNB BLT workaround
  drm/i915: Fix the graphics frequency clamping at init and when IPS is active.
  drm/i915: Allow powersave modparam to be adjusted at runtime.
  drm/i915: Apply big hammer to serialise buffer access between rings
  drm/i915: opregion_setup: iounmap correct address
  drm/i915: Flush read-only buffers from the active list upon idle as well
  i915: signedness bug in check_overlay_src()
  drm/i915: Fix typo from "Enable DisplayPort Audio"
  • Loading branch information
Dave Airlie committed Nov 9, 2010
2 parents a7bcf21 + 3f8ff0e commit 91839fd
Show file tree
Hide file tree
Showing 14 changed files with 267 additions and 96 deletions.
6 changes: 3 additions & 3 deletions drivers/char/agp/intel-gtt.c
Original file line number Diff line number Diff line change
Expand Up @@ -1210,14 +1210,14 @@ static void gen6_write_entry(dma_addr_t addr, unsigned int entry,
unsigned int gfdt = flags & AGP_USER_CACHED_MEMORY_GFDT;
u32 pte_flags;

if (type_mask == AGP_USER_UNCACHED_MEMORY)
if (type_mask == AGP_USER_MEMORY)
pte_flags = GEN6_PTE_UNCACHED | I810_PTE_VALID;
else if (type_mask == AGP_USER_CACHED_MEMORY_LLC_MLC) {
pte_flags = GEN6_PTE_LLC | I810_PTE_VALID;
pte_flags = GEN6_PTE_LLC_MLC | I810_PTE_VALID;
if (gfdt)
pte_flags |= GEN6_PTE_GFDT;
} else { /* set 'normal'/'cached' to LLC by default */
pte_flags = GEN6_PTE_LLC_MLC | I810_PTE_VALID;
pte_flags = GEN6_PTE_LLC | I810_PTE_VALID;
if (gfdt)
pte_flags |= GEN6_PTE_GFDT;
}
Expand Down
2 changes: 1 addition & 1 deletion drivers/gpu/drm/i915/i915_drv.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ unsigned int i915_fbpercrtc = 0;
module_param_named(fbpercrtc, i915_fbpercrtc, int, 0400);

unsigned int i915_powersave = 1;
module_param_named(powersave, i915_powersave, int, 0400);
module_param_named(powersave, i915_powersave, int, 0600);

unsigned int i915_lvds_downclock = 0;
module_param_named(lvds_downclock, i915_lvds_downclock, int, 0400);
Expand Down
1 change: 1 addition & 0 deletions drivers/gpu/drm/i915/i915_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -1321,6 +1321,7 @@ static inline void i915_write(struct drm_i915_private *dev_priv, u32 reg,

#define INTEL_PCH_TYPE(dev) (((struct drm_i915_private *)(dev)->dev_private)->pch_type)
#define HAS_PCH_CPT(dev) (INTEL_PCH_TYPE(dev) == PCH_CPT)
#define HAS_PCH_IBX(dev) (INTEL_PCH_TYPE(dev) == PCH_IBX)

#define PRIMARY_RINGBUFFER_SIZE (128*1024)

Expand Down
115 changes: 71 additions & 44 deletions drivers/gpu/drm/i915/i915_gem.c
Original file line number Diff line number Diff line change
Expand Up @@ -2172,7 +2172,7 @@ i915_gem_object_unbind(struct drm_gem_object *obj)
static int i915_ring_idle(struct drm_device *dev,
struct intel_ring_buffer *ring)
{
if (list_empty(&ring->gpu_write_list))
if (list_empty(&ring->gpu_write_list) && list_empty(&ring->active_list))
return 0;

i915_gem_flush_ring(dev, NULL, ring,
Expand All @@ -2190,9 +2190,7 @@ i915_gpu_idle(struct drm_device *dev)
int ret;

lists_empty = (list_empty(&dev_priv->mm.flushing_list) &&
list_empty(&dev_priv->render_ring.active_list) &&
list_empty(&dev_priv->bsd_ring.active_list) &&
list_empty(&dev_priv->blt_ring.active_list));
list_empty(&dev_priv->mm.active_list));
if (lists_empty)
return 0;

Expand Down Expand Up @@ -3108,7 +3106,8 @@ i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj,
* write domain
*/
if (obj->write_domain &&
obj->write_domain != obj->pending_read_domains) {
(obj->write_domain != obj->pending_read_domains ||
obj_priv->ring != ring)) {
flush_domains |= obj->write_domain;
invalidate_domains |=
obj->pending_read_domains & ~obj->write_domain;
Expand Down Expand Up @@ -3497,6 +3496,52 @@ i915_gem_execbuffer_pin(struct drm_device *dev,
return 0;
}

static int
i915_gem_execbuffer_move_to_gpu(struct drm_device *dev,
struct drm_file *file,
struct intel_ring_buffer *ring,
struct drm_gem_object **objects,
int count)
{
struct drm_i915_private *dev_priv = dev->dev_private;
int ret, i;

/* Zero the global flush/invalidate flags. These
* will be modified as new domains are computed
* for each object
*/
dev->invalidate_domains = 0;
dev->flush_domains = 0;
dev_priv->mm.flush_rings = 0;
for (i = 0; i < count; i++)
i915_gem_object_set_to_gpu_domain(objects[i], ring);

if (dev->invalidate_domains | dev->flush_domains) {
#if WATCH_EXEC
DRM_INFO("%s: invalidate_domains %08x flush_domains %08x\n",
__func__,
dev->invalidate_domains,
dev->flush_domains);
#endif
i915_gem_flush(dev, file,
dev->invalidate_domains,
dev->flush_domains,
dev_priv->mm.flush_rings);
}

for (i = 0; i < count; i++) {
struct drm_i915_gem_object *obj = to_intel_bo(objects[i]);
/* XXX replace with semaphores */
if (obj->ring && ring != obj->ring) {
ret = i915_gem_object_wait_rendering(&obj->base, true);
if (ret)
return ret;
}
}

return 0;
}

/* Throttle our rendering by waiting until the ring has completed our requests
* emitted over 20 msec ago.
*
Expand Down Expand Up @@ -3757,33 +3802,10 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
goto err;
}

/* Zero the global flush/invalidate flags. These
* will be modified as new domains are computed
* for each object
*/
dev->invalidate_domains = 0;
dev->flush_domains = 0;
dev_priv->mm.flush_rings = 0;

for (i = 0; i < args->buffer_count; i++) {
struct drm_gem_object *obj = object_list[i];

/* Compute new gpu domains and update invalidate/flush */
i915_gem_object_set_to_gpu_domain(obj, ring);
}

if (dev->invalidate_domains | dev->flush_domains) {
#if WATCH_EXEC
DRM_INFO("%s: invalidate_domains %08x flush_domains %08x\n",
__func__,
dev->invalidate_domains,
dev->flush_domains);
#endif
i915_gem_flush(dev, file,
dev->invalidate_domains,
dev->flush_domains,
dev_priv->mm.flush_rings);
}
ret = i915_gem_execbuffer_move_to_gpu(dev, file, ring,
object_list, args->buffer_count);
if (ret)
goto err;

for (i = 0; i < args->buffer_count; i++) {
struct drm_gem_object *obj = object_list[i];
Expand Down Expand Up @@ -4856,17 +4878,24 @@ i915_gem_phys_pwrite(struct drm_device *dev, struct drm_gem_object *obj,
struct drm_file *file_priv)
{
struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
void *obj_addr;
int ret;
char __user *user_data;
void *vaddr = obj_priv->phys_obj->handle->vaddr + args->offset;
char __user *user_data = (char __user *) (uintptr_t) args->data_ptr;

user_data = (char __user *) (uintptr_t) args->data_ptr;
obj_addr = obj_priv->phys_obj->handle->vaddr + args->offset;
DRM_DEBUG_DRIVER("vaddr %p, %lld\n", vaddr, args->size);

DRM_DEBUG_DRIVER("obj_addr %p, %lld\n", obj_addr, args->size);
ret = copy_from_user(obj_addr, user_data, args->size);
if (ret)
return -EFAULT;
if (__copy_from_user_inatomic_nocache(vaddr, user_data, args->size)) {
unsigned long unwritten;

/* The physical object once assigned is fixed for the lifetime
* of the obj, so we can safely drop the lock and continue
* to access vaddr.
*/
mutex_unlock(&dev->struct_mutex);
unwritten = copy_from_user(vaddr, user_data, args->size);
mutex_lock(&dev->struct_mutex);
if (unwritten)
return -EFAULT;
}

drm_agp_chipset_flush(dev);
return 0;
Expand Down Expand Up @@ -4900,9 +4929,7 @@ i915_gpu_is_active(struct drm_device *dev)
int lists_empty;

lists_empty = list_empty(&dev_priv->mm.flushing_list) &&
list_empty(&dev_priv->render_ring.active_list) &&
list_empty(&dev_priv->bsd_ring.active_list) &&
list_empty(&dev_priv->blt_ring.active_list);
list_empty(&dev_priv->mm.active_list);

return !lists_empty;
}
Expand Down
8 changes: 2 additions & 6 deletions drivers/gpu/drm/i915/i915_gem_evict.c
Original file line number Diff line number Diff line change
Expand Up @@ -165,9 +165,7 @@ i915_gem_evict_everything(struct drm_device *dev)

lists_empty = (list_empty(&dev_priv->mm.inactive_list) &&
list_empty(&dev_priv->mm.flushing_list) &&
list_empty(&dev_priv->render_ring.active_list) &&
list_empty(&dev_priv->bsd_ring.active_list) &&
list_empty(&dev_priv->blt_ring.active_list));
list_empty(&dev_priv->mm.active_list));
if (lists_empty)
return -ENOSPC;

Expand All @@ -184,9 +182,7 @@ i915_gem_evict_everything(struct drm_device *dev)

lists_empty = (list_empty(&dev_priv->mm.inactive_list) &&
list_empty(&dev_priv->mm.flushing_list) &&
list_empty(&dev_priv->render_ring.active_list) &&
list_empty(&dev_priv->bsd_ring.active_list) &&
list_empty(&dev_priv->blt_ring.active_list));
list_empty(&dev_priv->mm.active_list));
BUG_ON(!lists_empty);

return 0;
Expand Down
4 changes: 3 additions & 1 deletion drivers/gpu/drm/i915/i915_suspend.c
Original file line number Diff line number Diff line change
Expand Up @@ -862,8 +862,10 @@ int i915_restore_state(struct drm_device *dev)
/* Clock gating state */
intel_init_clock_gating(dev);

if (HAS_PCH_SPLIT(dev))
if (HAS_PCH_SPLIT(dev)) {
ironlake_enable_drps(dev);
intel_init_emon(dev);
}

/* Cache mode state */
I915_WRITE (CACHE_MODE_0, dev_priv->saveCACHE_MODE_0 | 0xffff0000);
Expand Down
70 changes: 41 additions & 29 deletions drivers/gpu/drm/i915/intel_display.c
Original file line number Diff line number Diff line change
Expand Up @@ -1681,6 +1681,37 @@ static void ironlake_set_pll_edp(struct drm_crtc *crtc, int clock)
udelay(500);
}

static void intel_fdi_normal_train(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;
u32 reg, temp;

/* enable normal train */
reg = FDI_TX_CTL(pipe);
temp = I915_READ(reg);
temp &= ~FDI_LINK_TRAIN_NONE;
temp |= FDI_LINK_TRAIN_NONE | FDI_TX_ENHANCE_FRAME_ENABLE;
I915_WRITE(reg, temp);

reg = FDI_RX_CTL(pipe);
temp = I915_READ(reg);
if (HAS_PCH_CPT(dev)) {
temp &= ~FDI_LINK_TRAIN_PATTERN_MASK_CPT;
temp |= FDI_LINK_TRAIN_NORMAL_CPT;
} else {
temp &= ~FDI_LINK_TRAIN_NONE;
temp |= FDI_LINK_TRAIN_NONE;
}
I915_WRITE(reg, temp | FDI_RX_ENHANCE_FRAME_ENABLE);

/* wait one idle pattern time */
POSTING_READ(reg);
udelay(1000);
}

/* The FDI link training functions for ILK/Ibexpeak. */
static void ironlake_fdi_link_train(struct drm_crtc *crtc)
{
Expand Down Expand Up @@ -1767,27 +1798,6 @@ static void ironlake_fdi_link_train(struct drm_crtc *crtc)

DRM_DEBUG_KMS("FDI train done\n");

/* enable normal train */
reg = FDI_TX_CTL(pipe);
temp = I915_READ(reg);
temp &= ~FDI_LINK_TRAIN_NONE;
temp |= FDI_LINK_TRAIN_NONE | FDI_TX_ENHANCE_FRAME_ENABLE;
I915_WRITE(reg, temp);

reg = FDI_RX_CTL(pipe);
temp = I915_READ(reg);
if (HAS_PCH_CPT(dev)) {
temp &= ~FDI_LINK_TRAIN_PATTERN_MASK_CPT;
temp |= FDI_LINK_TRAIN_NORMAL_CPT;
} else {
temp &= ~FDI_LINK_TRAIN_NONE;
temp |= FDI_LINK_TRAIN_NONE;
}
I915_WRITE(reg, temp | FDI_RX_ENHANCE_FRAME_ENABLE);

/* wait one idle pattern time */
POSTING_READ(reg);
udelay(1000);
}

static const int const snb_b_fdi_train_param [] = {
Expand Down Expand Up @@ -2090,6 +2100,8 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc)
I915_WRITE(TRANS_VBLANK(pipe), I915_READ(VBLANK(pipe)));
I915_WRITE(TRANS_VSYNC(pipe), I915_READ(VSYNC(pipe)));

intel_fdi_normal_train(crtc);

/* For PCH DP, enable TRANS_DP_CTL */
if (HAS_PCH_CPT(dev) &&
intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT)) {
Expand Down Expand Up @@ -2200,9 +2212,10 @@ static void ironlake_crtc_disable(struct drm_crtc *crtc)
udelay(100);

/* Ironlake workaround, disable clock pointer after downing FDI */
I915_WRITE(FDI_RX_CHICKEN(pipe),
I915_READ(FDI_RX_CHICKEN(pipe) &
~FDI_RX_PHASE_SYNC_POINTER_ENABLE));
if (HAS_PCH_IBX(dev))
I915_WRITE(FDI_RX_CHICKEN(pipe),
I915_READ(FDI_RX_CHICKEN(pipe) &
~FDI_RX_PHASE_SYNC_POINTER_ENABLE));

/* still set train pattern 1 */
reg = FDI_TX_CTL(pipe);
Expand Down Expand Up @@ -5581,20 +5594,19 @@ void ironlake_enable_drps(struct drm_device *dev)
fmin = (rgvmodectl & MEMMODE_FMIN_MASK);
fstart = (rgvmodectl & MEMMODE_FSTART_MASK) >>
MEMMODE_FSTART_SHIFT;
fstart = fmax;

vstart = (I915_READ(PXVFREQ_BASE + (fstart * 4)) & PXVFREQ_PX_MASK) >>
PXVFREQ_PX_SHIFT;

dev_priv->fmax = fstart; /* IPS callback will increase this */
dev_priv->fmax = fmax; /* IPS callback will increase this */
dev_priv->fstart = fstart;

dev_priv->max_delay = fmax;
dev_priv->max_delay = fstart;
dev_priv->min_delay = fmin;
dev_priv->cur_delay = fstart;

DRM_DEBUG_DRIVER("fmax: %d, fmin: %d, fstart: %d\n", fmax, fmin,
fstart);
DRM_DEBUG_DRIVER("fmax: %d, fmin: %d, fstart: %d\n",
fmax, fmin, fstart);

I915_WRITE(MEMINTREN, MEMINT_CX_SUPR_EN | MEMINT_EVAL_CHG_EN);

Expand Down
2 changes: 1 addition & 1 deletion drivers/gpu/drm/i915/intel_dp.c
Original file line number Diff line number Diff line change
Expand Up @@ -1517,7 +1517,7 @@ g4x_dp_detect(struct intel_dp *intel_dp)
status = connector_status_connected;
}

return bit;
return status;
}

/**
Expand Down
1 change: 1 addition & 0 deletions drivers/gpu/drm/i915/intel_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,7 @@ extern void intel_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green,
extern void intel_init_clock_gating(struct drm_device *dev);
extern void ironlake_enable_drps(struct drm_device *dev);
extern void ironlake_disable_drps(struct drm_device *dev);
extern void intel_init_emon(struct drm_device *dev);

extern int intel_pin_and_fence_fb_obj(struct drm_device *dev,
struct drm_gem_object *obj,
Expand Down
16 changes: 11 additions & 5 deletions drivers/gpu/drm/i915/intel_lvds.c
Original file line number Diff line number Diff line change
Expand Up @@ -481,11 +481,8 @@ static int intel_lvds_get_modes(struct drm_connector *connector)
struct drm_device *dev = connector->dev;
struct drm_display_mode *mode;

if (intel_lvds->edid) {
drm_mode_connector_update_edid_property(connector,
intel_lvds->edid);
if (intel_lvds->edid)
return drm_add_edid_modes(connector, intel_lvds->edid);
}

mode = drm_mode_duplicate(dev, intel_lvds->fixed_mode);
if (mode == 0)
Expand Down Expand Up @@ -939,7 +936,16 @@ void intel_lvds_init(struct drm_device *dev)
*/
intel_lvds->edid = drm_get_edid(connector,
&dev_priv->gmbus[pin].adapter);

if (intel_lvds->edid) {
if (drm_add_edid_modes(connector,
intel_lvds->edid)) {
drm_mode_connector_update_edid_property(connector,
intel_lvds->edid);
} else {
kfree(intel_lvds->edid);
intel_lvds->edid = NULL;
}
}
if (!intel_lvds->edid) {
/* Didn't get an EDID, so
* Set wide sync ranges so we get all modes
Expand Down
Loading

0 comments on commit 91839fd

Please sign in to comment.