Skip to content

Commit

Permalink
Merge branch 'for-airlied' of git://people.freedesktop.org/~danvet/dr…
Browse files Browse the repository at this point in the history
…m-intel into drm-next

Daniel writes:
Besides the big item of lifting the "preliminary hw support" tag from the
 Haswell code, just small bits&pieces all over:
 - Leftover Haswell patches and some fixes from Paulo
 - LyncPoint PCH support (for hsw)
 - OOM handling improvements from Chris Wilson
 - connector property and send_vblank_event refactorings from Rob Clark
 - random pile of small fixes

 Note that the send_vblank refactorings will cause some locking WARNs to
 show up. Imre has fixed that up, but since all the driver changes outside
 of the drm core have been for exonys, those four patches are merged
 through the exonys-next tree.

Meh, I've forgotten to cherry-pick an important fix from Ben for a
regression in the 3.8 gen6+ gtt code. New pull request below. While I'm at
it, the hdmi VIC patch for the drm edid code is still in my queue, I'll
send you that in the next 3.8-fixes pull.

* 'for-airlied' of git://people.freedesktop.org/~danvet/drm-intel: (33 commits)
  drm/i915: Fix pte updates in ggtt clear range
  drm/i915: promote Haswell to full support
  drm/i915: Report the origin of the LVDS fixed panel mode
  drm/i915: LVDS fallback to fixed-mode if EDID not present
  drm/i915/sdvo: kfree the intel_sdvo_connector, not drm_connector, on destroy
  drm/i915: drm_connector_property -> drm_object_property
  drm/i915: use drm_send_vblank_event() helper
  drm/i915: Use pci_resource functions for BARs.
  drm/i915: Borrow our struct_mutex for the direct reclaim
  drm/i915: Defer assignment of obj->gtt_space until after all possible mallocs
  drm/i915: Apply the IBX transcoder A w/a for HDMI to SDVO as well
  drm/i915: implement WaMbcDriverBootEnable on Haswell
  drm/i915: fix intel_ddi_get_cdclk_freq for ULT machines
  drm/i915: make the panel fitter work on pipes B and C on Haswell
  drm/i915: make the panel fitter work on pipes B and C on IVB
  drm/i915: don't intel_crt_init if DDI A has 4 lanes
  drm/i915: make DP work on LPT-LP machines
  drm/i915: fix false positive "Unclaimed write" messages
  drm/i915: use cpu/pch transcoder on intel_enable_pipe
  drm/i915: don't limit Haswell CRT encoder to pipe A
  ...
  • Loading branch information
Dave Airlie committed Nov 29, 2012
2 parents bd3b49f + 2ff4aea commit 7136470
Show file tree
Hide file tree
Showing 21 changed files with 264 additions and 179 deletions.
26 changes: 15 additions & 11 deletions drivers/gpu/drm/i915/i915_drv.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,11 @@ MODULE_PARM_DESC(modeset,
unsigned int i915_fbpercrtc __always_unused = 0;
module_param_named(fbpercrtc, i915_fbpercrtc, int, 0400);

int i915_panel_ignore_lid __read_mostly = 0;
int i915_panel_ignore_lid __read_mostly = 1;
module_param_named(panel_ignore_lid, i915_panel_ignore_lid, int, 0600);
MODULE_PARM_DESC(panel_ignore_lid,
"Override lid status (0=autodetect [default], 1=lid open, "
"-1=lid closed)");
"Override lid status (0=autodetect, 1=autodetect disabled [default], "
"-1=force lid closed, -2=force lid open)");

unsigned int i915_powersave __read_mostly = 1;
module_param_named(powersave, i915_powersave, int, 0600);
Expand Down Expand Up @@ -396,12 +396,6 @@ static const struct pci_device_id pciidlist[] = { /* aka */
MODULE_DEVICE_TABLE(pci, pciidlist);
#endif

#define INTEL_PCH_DEVICE_ID_MASK 0xff00
#define INTEL_PCH_IBX_DEVICE_ID_TYPE 0x3b00
#define INTEL_PCH_CPT_DEVICE_ID_TYPE 0x1c00
#define INTEL_PCH_PPT_DEVICE_ID_TYPE 0x1e00
#define INTEL_PCH_LPT_DEVICE_ID_TYPE 0x8c00

void intel_detect_pch(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
Expand All @@ -416,8 +410,9 @@ void intel_detect_pch(struct drm_device *dev)
pch = pci_get_class(PCI_CLASS_BRIDGE_ISA << 8, NULL);
if (pch) {
if (pch->vendor == PCI_VENDOR_ID_INTEL) {
int id;
unsigned short id;
id = pch->device & INTEL_PCH_DEVICE_ID_MASK;
dev_priv->pch_id = id;

if (id == INTEL_PCH_IBX_DEVICE_ID_TYPE) {
dev_priv->pch_type = PCH_IBX;
Expand All @@ -440,6 +435,11 @@ void intel_detect_pch(struct drm_device *dev)
dev_priv->num_pch_pll = 0;
DRM_DEBUG_KMS("Found LynxPoint PCH\n");
WARN_ON(!IS_HASWELL(dev));
} else if (id == INTEL_PCH_LPT_LP_DEVICE_ID_TYPE) {
dev_priv->pch_type = PCH_LPT;
dev_priv->num_pch_pll = 0;
DRM_DEBUG_KMS("Found LynxPoint LP PCH\n");
WARN_ON(!IS_HASWELL(dev));
}
BUG_ON(dev_priv->num_pch_pll > I915_NUM_PLLS);
}
Expand Down Expand Up @@ -884,7 +884,7 @@ i915_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
struct intel_device_info *intel_info =
(struct intel_device_info *) ent->driver_data;

if (intel_info->is_haswell || intel_info->is_valleyview)
if (intel_info->is_valleyview)
if(!i915_preliminary_hw_support) {
DRM_ERROR("Preliminary hardware support disabled\n");
return -ENODEV;
Expand Down Expand Up @@ -1258,6 +1258,10 @@ void i915_write##x(struct drm_i915_private *dev_priv, u32 reg, u##x val) { \
} \
if (IS_GEN5(dev_priv->dev)) \
ilk_dummy_write(dev_priv); \
if (IS_HASWELL(dev_priv->dev) && (I915_READ_NOTRACE(GEN7_ERR_INT) & ERR_INT_MMIO_UNCLAIMED)) { \
DRM_ERROR("Unknown unclaimed register before writing to %x\n", reg); \
I915_WRITE_NOTRACE(GEN7_ERR_INT, ERR_INT_MMIO_UNCLAIMED); \
} \
if (IS_VALLEYVIEW(dev_priv->dev) && IS_DISPLAYREG(reg)) { \
write##y(val, dev_priv->regs + reg + 0x180000); \
} else { \
Expand Down
13 changes: 11 additions & 2 deletions drivers/gpu/drm/i915/i915_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -402,7 +402,6 @@ struct i915_suspend_saved_registers {
u32 saveDSPACNTR;
u32 saveDSPBCNTR;
u32 saveDSPARB;
u32 saveHWS;
u32 savePIPEACONF;
u32 savePIPEBCONF;
u32 savePIPEASRC;
Expand Down Expand Up @@ -738,6 +737,7 @@ typedef struct drm_i915_private {

/* PCH chipset type */
enum intel_pch pch_type;
unsigned short pch_id;

unsigned long quirks;

Expand Down Expand Up @@ -1161,6 +1161,8 @@ struct drm_i915_file_private {
#define IS_VALLEYVIEW(dev) (INTEL_INFO(dev)->is_valleyview)
#define IS_HASWELL(dev) (INTEL_INFO(dev)->is_haswell)
#define IS_MOBILE(dev) (INTEL_INFO(dev)->is_mobile)
#define IS_ULT(dev) (IS_HASWELL(dev) && \
((dev)->pci_device & 0xFF00) == 0x0A00)

/*
* The genX designation typically refers to the render engine, so render
Expand Down Expand Up @@ -1206,6 +1208,13 @@ struct drm_i915_file_private {

#define HAS_PIPE_CONTROL(dev) (INTEL_INFO(dev)->gen >= 5)

#define INTEL_PCH_DEVICE_ID_MASK 0xff00
#define INTEL_PCH_IBX_DEVICE_ID_TYPE 0x3b00
#define INTEL_PCH_CPT_DEVICE_ID_TYPE 0x1c00
#define INTEL_PCH_PPT_DEVICE_ID_TYPE 0x1e00
#define INTEL_PCH_LPT_DEVICE_ID_TYPE 0x8c00
#define INTEL_PCH_LPT_LP_DEVICE_ID_TYPE 0x9c00

#define INTEL_PCH_TYPE(dev) (((struct drm_i915_private *)(dev)->dev_private)->pch_type)
#define HAS_PCH_LPT(dev) (INTEL_PCH_TYPE(dev) == PCH_LPT)
#define HAS_PCH_CPT(dev) (INTEL_PCH_TYPE(dev) == PCH_CPT)
Expand Down Expand Up @@ -1541,7 +1550,7 @@ void i915_gem_init_global_gtt(struct drm_device *dev,
unsigned long end);
int i915_gem_gtt_init(struct drm_device *dev);
void i915_gem_gtt_fini(struct drm_device *dev);
extern inline void i915_gem_chipset_flush(struct drm_device *dev)
static inline void i915_gem_chipset_flush(struct drm_device *dev)
{
if (INTEL_INFO(dev)->gen < 6)
intel_gtt_chipset_flush();
Expand Down
102 changes: 58 additions & 44 deletions drivers/gpu/drm/i915/i915_gem.c
Original file line number Diff line number Diff line change
Expand Up @@ -1345,30 +1345,17 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
trace_i915_gem_object_fault(obj, page_offset, true, write);

/* Now bind it into the GTT if needed */
if (!obj->map_and_fenceable) {
ret = i915_gem_object_unbind(obj);
if (ret)
goto unlock;
}
if (!obj->gtt_space) {
ret = i915_gem_object_bind_to_gtt(obj, 0, true, false);
if (ret)
goto unlock;

ret = i915_gem_object_set_to_gtt_domain(obj, write);
if (ret)
goto unlock;
}
ret = i915_gem_object_pin(obj, 0, true, false);
if (ret)
goto unlock;

if (!obj->has_global_gtt_mapping)
i915_gem_gtt_bind_object(obj, obj->cache_level);
ret = i915_gem_object_set_to_gtt_domain(obj, write);
if (ret)
goto unpin;

ret = i915_gem_object_get_fence(obj);
if (ret)
goto unlock;

if (i915_gem_object_is_inactive(obj))
list_move_tail(&obj->mm_list, &dev_priv->mm.inactive_list);
goto unpin;

obj->fault_mappable = true;

Expand All @@ -1377,6 +1364,8 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)

/* Finally, remap it using the new GTT offset */
ret = vm_insert_pfn(vma, (unsigned long)vmf->virtual_address, pfn);
unpin:
i915_gem_object_unpin(obj);
unlock:
mutex_unlock(&dev->struct_mutex);
out:
Expand Down Expand Up @@ -2925,74 +2914,75 @@ i915_gem_object_bind_to_gtt(struct drm_i915_gem_object *obj,
if (ret)
return ret;

i915_gem_object_pin_pages(obj);

search_free:
if (map_and_fenceable)
free_space =
drm_mm_search_free_in_range_color(&dev_priv->mm.gtt_space,
size, alignment, obj->cache_level,
0, dev_priv->mm.gtt_mappable_end,
false);
free_space = drm_mm_search_free_in_range_color(&dev_priv->mm.gtt_space,
size, alignment, obj->cache_level,
0, dev_priv->mm.gtt_mappable_end,
false);
else
free_space = drm_mm_search_free_color(&dev_priv->mm.gtt_space,
size, alignment, obj->cache_level,
false);

if (free_space != NULL) {
if (map_and_fenceable)
obj->gtt_space =
free_space =
drm_mm_get_block_range_generic(free_space,
size, alignment, obj->cache_level,
0, dev_priv->mm.gtt_mappable_end,
false);
else
obj->gtt_space =
free_space =
drm_mm_get_block_generic(free_space,
size, alignment, obj->cache_level,
false);
}
if (obj->gtt_space == NULL) {
if (free_space == NULL) {
ret = i915_gem_evict_something(dev, size, alignment,
obj->cache_level,
map_and_fenceable,
nonblocking);
if (ret)
if (ret) {
i915_gem_object_unpin_pages(obj);
return ret;
}

goto search_free;
}
if (WARN_ON(!i915_gem_valid_gtt_space(dev,
obj->gtt_space,
free_space,
obj->cache_level))) {
drm_mm_put_block(obj->gtt_space);
obj->gtt_space = NULL;
i915_gem_object_unpin_pages(obj);
drm_mm_put_block(free_space);
return -EINVAL;
}


ret = i915_gem_gtt_prepare_object(obj);
if (ret) {
drm_mm_put_block(obj->gtt_space);
obj->gtt_space = NULL;
i915_gem_object_unpin_pages(obj);
drm_mm_put_block(free_space);
return ret;
}

if (!dev_priv->mm.aliasing_ppgtt)
i915_gem_gtt_bind_object(obj, obj->cache_level);

list_move_tail(&obj->gtt_list, &dev_priv->mm.bound_list);
list_add_tail(&obj->mm_list, &dev_priv->mm.inactive_list);

obj->gtt_offset = obj->gtt_space->start;
obj->gtt_space = free_space;
obj->gtt_offset = free_space->start;

fenceable =
obj->gtt_space->size == fence_size &&
(obj->gtt_space->start & (fence_alignment - 1)) == 0;
free_space->size == fence_size &&
(free_space->start & (fence_alignment - 1)) == 0;

mappable =
obj->gtt_offset + obj->base.size <= dev_priv->mm.gtt_mappable_end;

obj->map_and_fenceable = mappable && fenceable;

i915_gem_object_unpin_pages(obj);
trace_i915_gem_object_bind(obj, map_and_fenceable);
i915_gem_verify_gtt(dev);
return 0;
Expand Down Expand Up @@ -3456,11 +3446,16 @@ i915_gem_object_pin(struct drm_i915_gem_object *obj,
}

if (obj->gtt_space == NULL) {
struct drm_i915_private *dev_priv = obj->base.dev->dev_private;

ret = i915_gem_object_bind_to_gtt(obj, alignment,
map_and_fenceable,
nonblocking);
if (ret)
return ret;

if (!dev_priv->mm.aliasing_ppgtt)
i915_gem_gtt_bind_object(obj, obj->cache_level);
}

if (!obj->has_global_gtt_mapping && map_and_fenceable)
Expand Down Expand Up @@ -4347,6 +4342,19 @@ void i915_gem_release(struct drm_device *dev, struct drm_file *file)
spin_unlock(&file_priv->mm.lock);
}

static bool mutex_is_locked_by(struct mutex *mutex, struct task_struct *task)
{
if (!mutex_is_locked(mutex))
return false;

#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_MUTEXES)
return mutex->owner == task;
#else
/* Since UP may be pre-empted, we cannot assume that we own the lock */
return false;
#endif
}

static int
i915_gem_inactive_shrink(struct shrinker *shrinker, struct shrink_control *sc)
{
Expand All @@ -4357,10 +4365,15 @@ i915_gem_inactive_shrink(struct shrinker *shrinker, struct shrink_control *sc)
struct drm_device *dev = dev_priv->dev;
struct drm_i915_gem_object *obj;
int nr_to_scan = sc->nr_to_scan;
bool unlock = true;
int cnt;

if (!mutex_trylock(&dev->struct_mutex))
return 0;
if (!mutex_trylock(&dev->struct_mutex)) {
if (!mutex_is_locked_by(&dev->struct_mutex, current))
return 0;

unlock = false;
}

if (nr_to_scan) {
nr_to_scan -= i915_gem_purge(dev_priv, nr_to_scan);
Expand All @@ -4376,6 +4389,7 @@ i915_gem_inactive_shrink(struct shrinker *shrinker, struct shrink_control *sc)
if (obj->pin_count == 0 && obj->pages_pin_count == 0)
cnt += obj->base.size >> PAGE_SHIFT;

mutex_unlock(&dev->struct_mutex);
if (unlock)
mutex_unlock(&dev->struct_mutex);
return cnt;
}
9 changes: 0 additions & 9 deletions drivers/gpu/drm/i915/i915_gem_execbuffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -128,15 +128,6 @@ i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj,
target_i915_obj->cache_level);
}

/* The target buffer should have appeared before us in the
* exec_object list, so it should have a GTT space bound by now.
*/
if (unlikely(target_offset == 0)) {
DRM_DEBUG("No GTT space found for object %d\n",
reloc->target_handle);
return ret;
}

/* Validate that the target is in a valid r/w GPU domain */
if (unlikely(reloc->write_domain & (reloc->write_domain - 1))) {
DRM_DEBUG("reloc with multiple write domains: "
Expand Down
14 changes: 6 additions & 8 deletions drivers/gpu/drm/i915/i915_gem_gtt.c
Original file line number Diff line number Diff line change
Expand Up @@ -367,8 +367,9 @@ static void i915_ggtt_clear_range(struct drm_device *dev,
{
struct drm_i915_private *dev_priv = dev->dev_private;
gtt_pte_t scratch_pte;
volatile void __iomem *gtt_base = dev_priv->mm.gtt->gtt + first_entry;
gtt_pte_t __iomem *gtt_base = dev_priv->mm.gtt->gtt + first_entry;
const int max_entries = dev_priv->mm.gtt->gtt_total_entries - first_entry;
int i;

if (INTEL_INFO(dev)->gen < 6) {
intel_gtt_clear_range(first_entry, num_entries);
Expand All @@ -381,7 +382,8 @@ static void i915_ggtt_clear_range(struct drm_device *dev,
num_entries = max_entries;

scratch_pte = pte_encode(dev, dev_priv->mm.gtt->scratch_page_dma, I915_CACHE_LLC);
memset_io(gtt_base, scratch_pte, num_entries * sizeof(scratch_pte));
for (i = 0; i < num_entries; i++)
iowrite32(scratch_pte, &gtt_base[i]);
readl(gtt_base);
}

Expand Down Expand Up @@ -609,7 +611,6 @@ int i915_gem_gtt_init(struct drm_device *dev)
struct drm_i915_private *dev_priv = dev->dev_private;
phys_addr_t gtt_bus_addr;
u16 snb_gmch_ctl;
u32 tmp;
int ret;

/* On modern platforms we need not worry ourself with the legacy
Expand Down Expand Up @@ -638,12 +639,9 @@ int i915_gem_gtt_init(struct drm_device *dev)
if (!pci_set_dma_mask(dev->pdev, DMA_BIT_MASK(40)))
pci_set_consistent_dma_mask(dev->pdev, DMA_BIT_MASK(40));

pci_read_config_dword(dev->pdev, PCI_BASE_ADDRESS_0, &tmp);
/* For GEN6+ the PTEs for the ggtt live at 2MB + BAR0 */
gtt_bus_addr = (tmp & PCI_BASE_ADDRESS_MEM_MASK) + (2<<20);

pci_read_config_dword(dev->pdev, PCI_BASE_ADDRESS_2, &tmp);
dev_priv->mm.gtt->gma_bus_addr = tmp & PCI_BASE_ADDRESS_MEM_MASK;
gtt_bus_addr = pci_resource_start(dev->pdev, 0) + (2<<20);
dev_priv->mm.gtt->gma_bus_addr = pci_resource_start(dev->pdev, 2);

/* i9xx_setup */
pci_read_config_word(dev->pdev, SNB_GMCH_CTRL, &snb_gmch_ctl);
Expand Down
Loading

0 comments on commit 7136470

Please sign in to comment.