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:
 "Travelling slowed down getting these out.

  Two vmwgfx fixes, a radeon revert to avoid a regression, i915 fixes,
  and some ioctl sizing issues fixed with 32 on 64"

* 'drm-fixes' of git://people.freedesktop.org/~airlied/linux:
  drm/radeon/audio: don't set speaker allocation on DCE4+
  drm/radeon: rework audio option
  drm/radeon/audio: don't set speaker allocation on DCE3.2
  drm/radeon: make missing smc ucode non-fatal (CI)
  drm/radeon: make missing smc ucode non-fatal (r7xx-SI)
  drm/radeon/uvd: revert lower msg&fb buffer requirements on UVD3
  drm/radeon: stop the leaks in cik_ib_test
  drm/radeon/atom: workaround vbios bug in transmitter table on rs780
  drm/i915: Disable GGTT PTEs on GEN6+ suspend
  drm/i915: Make PTE valid encoding optional
  drm: Pad drm_mode_get_connector to 64-bit boundary
  drm: Prevent overwriting from userspace underallocating core ioctl structs
  drm/vmwgfx: Don't kill clients on VT switch
  drm/vmwgfx: Don't put resources with invalid id's on lru list
  drm/i915: disable LVDS clock gating on CPT v2
  • Loading branch information
Linus Torvalds committed Oct 22, 2013
2 parents 1c24113 + 579123f commit b403b73
Show file tree
Hide file tree
Showing 22 changed files with 207 additions and 72 deletions.
9 changes: 8 additions & 1 deletion drivers/gpu/drm/drm_drv.c
Original file line number Diff line number Diff line change
Expand Up @@ -402,9 +402,16 @@ long drm_ioctl(struct file *filp,
cmd = ioctl->cmd_drv;
}
else if ((nr >= DRM_COMMAND_END) || (nr < DRM_COMMAND_BASE)) {
u32 drv_size;

ioctl = &drm_ioctls[nr];
cmd = ioctl->cmd;

drv_size = _IOC_SIZE(ioctl->cmd);
usize = asize = _IOC_SIZE(cmd);
if (drv_size > asize)
asize = drv_size;

cmd = ioctl->cmd;
} else
goto err_i1;

Expand Down
5 changes: 4 additions & 1 deletion drivers/gpu/drm/i915/i915_drv.c
Original file line number Diff line number Diff line change
Expand Up @@ -505,6 +505,8 @@ static int i915_drm_freeze(struct drm_device *dev)
intel_modeset_suspend_hw(dev);
}

i915_gem_suspend_gtt_mappings(dev);

i915_save_state(dev);

intel_opregion_fini(dev);
Expand Down Expand Up @@ -648,7 +650,8 @@ static int i915_drm_thaw(struct drm_device *dev)
mutex_lock(&dev->struct_mutex);
i915_gem_restore_gtt_mappings(dev);
mutex_unlock(&dev->struct_mutex);
}
} else if (drm_core_check_feature(dev, DRIVER_MODESET))
i915_check_and_clear_faults(dev);

__i915_drm_thaw(dev);

Expand Down
8 changes: 6 additions & 2 deletions drivers/gpu/drm/i915/i915_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -497,10 +497,12 @@ struct i915_address_space {

/* FIXME: Need a more generic return type */
gen6_gtt_pte_t (*pte_encode)(dma_addr_t addr,
enum i915_cache_level level);
enum i915_cache_level level,
bool valid); /* Create a valid PTE */
void (*clear_range)(struct i915_address_space *vm,
unsigned int first_entry,
unsigned int num_entries);
unsigned int num_entries,
bool use_scratch);
void (*insert_entries)(struct i915_address_space *vm,
struct sg_table *st,
unsigned int first_entry,
Expand Down Expand Up @@ -2065,6 +2067,8 @@ void i915_ppgtt_bind_object(struct i915_hw_ppgtt *ppgtt,
void i915_ppgtt_unbind_object(struct i915_hw_ppgtt *ppgtt,
struct drm_i915_gem_object *obj);

void i915_check_and_clear_faults(struct drm_device *dev);
void i915_gem_suspend_gtt_mappings(struct drm_device *dev);
void i915_gem_restore_gtt_mappings(struct drm_device *dev);
int __must_check i915_gem_gtt_prepare_object(struct drm_i915_gem_object *obj);
void i915_gem_gtt_bind_object(struct drm_i915_gem_object *obj,
Expand Down
109 changes: 85 additions & 24 deletions drivers/gpu/drm/i915/i915_gem_gtt.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,10 @@
#define HSW_WT_ELLC_LLC_AGE0 HSW_CACHEABILITY_CONTROL(0x6)

static gen6_gtt_pte_t snb_pte_encode(dma_addr_t addr,
enum i915_cache_level level)
enum i915_cache_level level,
bool valid)
{
gen6_gtt_pte_t pte = GEN6_PTE_VALID;
gen6_gtt_pte_t pte = valid ? GEN6_PTE_VALID : 0;
pte |= GEN6_PTE_ADDR_ENCODE(addr);

switch (level) {
Expand All @@ -79,9 +80,10 @@ static gen6_gtt_pte_t snb_pte_encode(dma_addr_t addr,
}

static gen6_gtt_pte_t ivb_pte_encode(dma_addr_t addr,
enum i915_cache_level level)
enum i915_cache_level level,
bool valid)
{
gen6_gtt_pte_t pte = GEN6_PTE_VALID;
gen6_gtt_pte_t pte = valid ? GEN6_PTE_VALID : 0;
pte |= GEN6_PTE_ADDR_ENCODE(addr);

switch (level) {
Expand All @@ -105,9 +107,10 @@ static gen6_gtt_pte_t ivb_pte_encode(dma_addr_t addr,
#define BYT_PTE_SNOOPED_BY_CPU_CACHES (1 << 2)

static gen6_gtt_pte_t byt_pte_encode(dma_addr_t addr,
enum i915_cache_level level)
enum i915_cache_level level,
bool valid)
{
gen6_gtt_pte_t pte = GEN6_PTE_VALID;
gen6_gtt_pte_t pte = valid ? GEN6_PTE_VALID : 0;
pte |= GEN6_PTE_ADDR_ENCODE(addr);

/* Mark the page as writeable. Other platforms don't have a
Expand All @@ -122,9 +125,10 @@ static gen6_gtt_pte_t byt_pte_encode(dma_addr_t addr,
}

static gen6_gtt_pte_t hsw_pte_encode(dma_addr_t addr,
enum i915_cache_level level)
enum i915_cache_level level,
bool valid)
{
gen6_gtt_pte_t pte = GEN6_PTE_VALID;
gen6_gtt_pte_t pte = valid ? GEN6_PTE_VALID : 0;
pte |= HSW_PTE_ADDR_ENCODE(addr);

if (level != I915_CACHE_NONE)
Expand All @@ -134,9 +138,10 @@ static gen6_gtt_pte_t hsw_pte_encode(dma_addr_t addr,
}

static gen6_gtt_pte_t iris_pte_encode(dma_addr_t addr,
enum i915_cache_level level)
enum i915_cache_level level,
bool valid)
{
gen6_gtt_pte_t pte = GEN6_PTE_VALID;
gen6_gtt_pte_t pte = valid ? GEN6_PTE_VALID : 0;
pte |= HSW_PTE_ADDR_ENCODE(addr);

switch (level) {
Expand Down Expand Up @@ -236,7 +241,8 @@ static int gen6_ppgtt_enable(struct drm_device *dev)
/* PPGTT support for Sandybdrige/Gen6 and later */
static void gen6_ppgtt_clear_range(struct i915_address_space *vm,
unsigned first_entry,
unsigned num_entries)
unsigned num_entries,
bool use_scratch)
{
struct i915_hw_ppgtt *ppgtt =
container_of(vm, struct i915_hw_ppgtt, base);
Expand All @@ -245,7 +251,7 @@ static void gen6_ppgtt_clear_range(struct i915_address_space *vm,
unsigned first_pte = first_entry % I915_PPGTT_PT_ENTRIES;
unsigned last_pte, i;

scratch_pte = vm->pte_encode(vm->scratch.addr, I915_CACHE_LLC);
scratch_pte = vm->pte_encode(vm->scratch.addr, I915_CACHE_LLC, true);

while (num_entries) {
last_pte = first_pte + num_entries;
Expand Down Expand Up @@ -282,7 +288,7 @@ static void gen6_ppgtt_insert_entries(struct i915_address_space *vm,
dma_addr_t page_addr;

page_addr = sg_page_iter_dma_address(&sg_iter);
pt_vaddr[act_pte] = vm->pte_encode(page_addr, cache_level);
pt_vaddr[act_pte] = vm->pte_encode(page_addr, cache_level, true);
if (++act_pte == I915_PPGTT_PT_ENTRIES) {
kunmap_atomic(pt_vaddr);
act_pt++;
Expand Down Expand Up @@ -367,7 +373,7 @@ static int gen6_ppgtt_init(struct i915_hw_ppgtt *ppgtt)
}

ppgtt->base.clear_range(&ppgtt->base, 0,
ppgtt->num_pd_entries * I915_PPGTT_PT_ENTRIES);
ppgtt->num_pd_entries * I915_PPGTT_PT_ENTRIES, true);

ppgtt->pd_offset = first_pd_entry_in_global_pt * sizeof(gen6_gtt_pte_t);

Expand Down Expand Up @@ -444,7 +450,8 @@ void i915_ppgtt_unbind_object(struct i915_hw_ppgtt *ppgtt,
{
ppgtt->base.clear_range(&ppgtt->base,
i915_gem_obj_ggtt_offset(obj) >> PAGE_SHIFT,
obj->base.size >> PAGE_SHIFT);
obj->base.size >> PAGE_SHIFT,
true);
}

extern int intel_iommu_gfx_mapped;
Expand Down Expand Up @@ -485,15 +492,65 @@ static void undo_idling(struct drm_i915_private *dev_priv, bool interruptible)
dev_priv->mm.interruptible = interruptible;
}

void i915_check_and_clear_faults(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_ring_buffer *ring;
int i;

if (INTEL_INFO(dev)->gen < 6)
return;

for_each_ring(ring, dev_priv, i) {
u32 fault_reg;
fault_reg = I915_READ(RING_FAULT_REG(ring));
if (fault_reg & RING_FAULT_VALID) {
DRM_DEBUG_DRIVER("Unexpected fault\n"
"\tAddr: 0x%08lx\\n"
"\tAddress space: %s\n"
"\tSource ID: %d\n"
"\tType: %d\n",
fault_reg & PAGE_MASK,
fault_reg & RING_FAULT_GTTSEL_MASK ? "GGTT" : "PPGTT",
RING_FAULT_SRCID(fault_reg),
RING_FAULT_FAULT_TYPE(fault_reg));
I915_WRITE(RING_FAULT_REG(ring),
fault_reg & ~RING_FAULT_VALID);
}
}
POSTING_READ(RING_FAULT_REG(&dev_priv->ring[RCS]));
}

void i915_gem_suspend_gtt_mappings(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;

/* Don't bother messing with faults pre GEN6 as we have little
* documentation supporting that it's a good idea.
*/
if (INTEL_INFO(dev)->gen < 6)
return;

i915_check_and_clear_faults(dev);

dev_priv->gtt.base.clear_range(&dev_priv->gtt.base,
dev_priv->gtt.base.start / PAGE_SIZE,
dev_priv->gtt.base.total / PAGE_SIZE,
false);
}

void i915_gem_restore_gtt_mappings(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_i915_gem_object *obj;

i915_check_and_clear_faults(dev);

/* First fill our portion of the GTT with scratch pages */
dev_priv->gtt.base.clear_range(&dev_priv->gtt.base,
dev_priv->gtt.base.start / PAGE_SIZE,
dev_priv->gtt.base.total / PAGE_SIZE);
dev_priv->gtt.base.total / PAGE_SIZE,
true);

list_for_each_entry(obj, &dev_priv->mm.bound_list, global_list) {
i915_gem_clflush_object(obj, obj->pin_display);
Expand Down Expand Up @@ -536,7 +593,7 @@ static void gen6_ggtt_insert_entries(struct i915_address_space *vm,

for_each_sg_page(st->sgl, &sg_iter, st->nents, 0) {
addr = sg_page_iter_dma_address(&sg_iter);
iowrite32(vm->pte_encode(addr, level), &gtt_entries[i]);
iowrite32(vm->pte_encode(addr, level, true), &gtt_entries[i]);
i++;
}

Expand All @@ -548,7 +605,7 @@ static void gen6_ggtt_insert_entries(struct i915_address_space *vm,
*/
if (i != 0)
WARN_ON(readl(&gtt_entries[i-1]) !=
vm->pte_encode(addr, level));
vm->pte_encode(addr, level, true));

/* This next bit makes the above posting read even more important. We
* want to flush the TLBs only after we're certain all the PTE updates
Expand All @@ -560,7 +617,8 @@ static void gen6_ggtt_insert_entries(struct i915_address_space *vm,

static void gen6_ggtt_clear_range(struct i915_address_space *vm,
unsigned int first_entry,
unsigned int num_entries)
unsigned int num_entries,
bool use_scratch)
{
struct drm_i915_private *dev_priv = vm->dev->dev_private;
gen6_gtt_pte_t scratch_pte, __iomem *gtt_base =
Expand All @@ -573,7 +631,8 @@ static void gen6_ggtt_clear_range(struct i915_address_space *vm,
first_entry, num_entries, max_entries))
num_entries = max_entries;

scratch_pte = vm->pte_encode(vm->scratch.addr, I915_CACHE_LLC);
scratch_pte = vm->pte_encode(vm->scratch.addr, I915_CACHE_LLC, use_scratch);

for (i = 0; i < num_entries; i++)
iowrite32(scratch_pte, &gtt_base[i]);
readl(gtt_base);
Expand All @@ -594,7 +653,8 @@ static void i915_ggtt_insert_entries(struct i915_address_space *vm,

static void i915_ggtt_clear_range(struct i915_address_space *vm,
unsigned int first_entry,
unsigned int num_entries)
unsigned int num_entries,
bool unused)
{
intel_gtt_clear_range(first_entry, num_entries);
}
Expand Down Expand Up @@ -622,7 +682,8 @@ void i915_gem_gtt_unbind_object(struct drm_i915_gem_object *obj)

dev_priv->gtt.base.clear_range(&dev_priv->gtt.base,
entry,
obj->base.size >> PAGE_SHIFT);
obj->base.size >> PAGE_SHIFT,
true);

obj->has_global_gtt_mapping = 0;
}
Expand Down Expand Up @@ -709,11 +770,11 @@ void i915_gem_setup_global_gtt(struct drm_device *dev,
const unsigned long count = (hole_end - hole_start) / PAGE_SIZE;
DRM_DEBUG_KMS("clearing unused GTT space: [%lx, %lx]\n",
hole_start, hole_end);
ggtt_vm->clear_range(ggtt_vm, hole_start / PAGE_SIZE, count);
ggtt_vm->clear_range(ggtt_vm, hole_start / PAGE_SIZE, count, true);
}

/* And finally clear the reserved guard page */
ggtt_vm->clear_range(ggtt_vm, end / PAGE_SIZE - 1, 1);
ggtt_vm->clear_range(ggtt_vm, end / PAGE_SIZE - 1, 1, true);
}

static bool
Expand Down
6 changes: 6 additions & 0 deletions drivers/gpu/drm/i915/i915_reg.h
Original file line number Diff line number Diff line change
Expand Up @@ -604,6 +604,10 @@
#define ARB_MODE_SWIZZLE_IVB (1<<5)
#define RENDER_HWS_PGA_GEN7 (0x04080)
#define RING_FAULT_REG(ring) (0x4094 + 0x100*(ring)->id)
#define RING_FAULT_GTTSEL_MASK (1<<11)
#define RING_FAULT_SRCID(x) ((x >> 3) & 0xff)
#define RING_FAULT_FAULT_TYPE(x) ((x >> 1) & 0x3)
#define RING_FAULT_VALID (1<<0)
#define DONE_REG 0x40b0
#define BSD_HWS_PGA_GEN7 (0x04180)
#define BLT_HWS_PGA_GEN7 (0x04280)
Expand Down Expand Up @@ -4279,7 +4283,9 @@
#define FDI_RX_CHICKEN(pipe) _PIPE(pipe, _FDI_RXA_CHICKEN, _FDI_RXB_CHICKEN)

#define SOUTH_DSPCLK_GATE_D 0xc2020
#define PCH_DPLUNIT_CLOCK_GATE_DISABLE (1<<30)
#define PCH_DPLSUNIT_CLOCK_GATE_DISABLE (1<<29)
#define PCH_CPUNIT_CLOCK_GATE_DISABLE (1<<14)
#define PCH_LP_PARTITION_LEVEL_DISABLE (1<<12)

/* CPU: FDI_TX */
Expand Down
4 changes: 3 additions & 1 deletion drivers/gpu/drm/i915/intel_pm.c
Original file line number Diff line number Diff line change
Expand Up @@ -4759,7 +4759,9 @@ static void cpt_init_clock_gating(struct drm_device *dev)
* gating for the panel power sequencer or it will fail to
* start up when no ports are active.
*/
I915_WRITE(SOUTH_DSPCLK_GATE_D, PCH_DPLSUNIT_CLOCK_GATE_DISABLE);
I915_WRITE(SOUTH_DSPCLK_GATE_D, PCH_DPLSUNIT_CLOCK_GATE_DISABLE |
PCH_DPLUNIT_CLOCK_GATE_DISABLE |
PCH_CPUNIT_CLOCK_GATE_DISABLE);
I915_WRITE(SOUTH_CHICKEN2, I915_READ(SOUTH_CHICKEN2) |
DPLS_EDP_PPS_FIX_DIS);
/* The below fixes the weird display corruption, a few pixels shifted
Expand Down
Loading

0 comments on commit b403b73

Please sign in to comment.