[Intel-gfx] [PATCH 23/26] drm/i915: Force pd restore when PDEs change, gen6-7

2014-03-17 Thread Ben Widawsky
The docs say you cannot change the PDEs of a currently running context. If you
are changing the PDEs of the currently running context then. We never
map new PDEs of a running context, and expect them to be present - so I
think this is okay. (We can unmap, but this should also be okay since we
only unmap unreferenced objects that the GPU shouldn't be tryingto
va->pa xlate.) The MI_SET_CONTEXT command does have a flag to signal
that even if the context is the same, force a reload. It's unclear
exactly what this does, but I have a hunch it's the right thing to do.

The logic assumes that we always emit a context switch after mapping new
PDEs, and before we submit a batch. This is the case today, and has been
the case since the inception of hardware contexts. A note in the comment
let's the user know.

NOTE: I have no evidence to suggest this is actually needed other than a
few tidbits which lead me to believe there are some corner cases that
will require it. I'm mostly depending on the reload of DCLV to
invalidate the old TLBs. We can try to remove this patch and see what
happens.

Signed-off-by: Ben Widawsky 
---
 drivers/gpu/drm/i915/i915_gem_context.c| 15 ---
 drivers/gpu/drm/i915/i915_gem_execbuffer.c |  5 +
 drivers/gpu/drm/i915/i915_gem_gtt.c| 17 -
 drivers/gpu/drm/i915/i915_gem_gtt.h|  2 ++
 4 files changed, 35 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_context.c 
b/drivers/gpu/drm/i915/i915_gem_context.c
index a899e11..6ad5380 100644
--- a/drivers/gpu/drm/i915/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/i915_gem_context.c
@@ -636,9 +636,18 @@ mi_set_context(struct intel_ring_buffer *ring,
 
 static inline bool should_skip_switch(struct intel_ring_buffer *ring,
  struct i915_hw_context *from,
- struct i915_hw_context *to)
+ struct i915_hw_context *to,
+ u32 *flags)
 {
-   if (from == to && from->last_ring == ring && !to->remap_slice)
+   if (test_and_clear_bit(ring->id, &to->vm->pd_reload_mask)) {
+   *flags |= MI_FORCE_RESTORE;
+   return false;
+   }
+
+   if (to->remap_slice)
+   return false;
+
+   if (from == to && from->last_ring == ring)
return true;
 
return false;
@@ -658,7 +667,7 @@ static int do_switch(struct intel_ring_buffer *ring,
BUG_ON(!i915_gem_obj_is_pinned(from->obj));
}
 
-   if (should_skip_switch(ring, from, to))
+   if (should_skip_switch(ring, from, to, &hw_flags))
return 0;
 
/* Trying to pin first makes error handling easier. */
diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c 
b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
index 856fa9d..bb901e8 100644
--- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
@@ -1162,6 +1162,10 @@ i915_gem_do_execbuffer(struct drm_device *dev, void 
*data,
if (ret)
goto err;
 
+   /* XXX: Reserve has possibly change PDEs which means we must do a
+* context switch before we can coherently read some of the reserved
+* VMAs. */
+
/* The objects are in their final locations, apply the relocations. */
if (need_relocs)
ret = i915_gem_execbuffer_relocate(eb);
@@ -1263,6 +1267,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
goto err;
}
} else {
+   WARN_ON(vm->pd_reload_mask & (1dispatch_execbuffer(ring,
exec_start, exec_len,
flags);
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/i915_gem_gtt.c
index d3c77d1..6d904c9 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -1228,6 +1228,16 @@ int i915_gem_init_ppgtt(struct drm_device *dev, struct 
i915_hw_ppgtt *ppgtt)
return 0;
 }
 
+/* PDE TLBs are a pain invalidate pre GEN8. It requires a context reload. If we
+ * are switching between contexts with the same LRCA, we also must do a force
+ * restore.
+ */
+#define ppgtt_invalidate_tlbs(vm) do {\
+   if (INTEL_INFO(vm->dev)->gen < 8) { \
+   vm->pd_reload_mask = INTEL_INFO(vm->dev)->ring_mask; \
+   } \
+} while(0)
+
 static int
 ppgtt_bind_vma(struct i915_vma *vma,
   enum i915_cache_level cache_level,
@@ -1242,10 +1252,13 @@ ppgtt_bind_vma(struct i915_vma *vma,
 vma->node.size);
if (ret)
return ret;
+
+   ppgtt_invalidate_tlbs(vma->vm);
}
 
vma->vm->insert_entries(vma->vm, vma->obj->pages, vma->node.start,
cache

[Intel-gfx] [PATCH 24/26] drm/i915: Finish gen6/7 dynamic page table allocation

2014-03-17 Thread Ben Widawsky
This patch continues on the idea from the previous patch. From here on,
in the steady state, PDEs are all pointing to the scratch page table (as
recommended in the spec). When an object is allocated in the VA range,
the code will determine if we need to allocate a page for the page
table. Similarly when the object is destroyed, we will remove, and free
the page table pointing the PDE back to the scratch page.

Following patches will work to unify the code a bit as we bring in GEN8
support. GEN6 and GEN8 are different enough that I had a hard time to
get to this point with as much common code as I do.

The aliasing PPGTT must pre-allocate all of the page tables. There are a
few reasons for this. Two trivial ones: aliasing ppgtt goes through the
ggtt paths, so it's hard to maintain, we currently do not restore the
default context (assuming the previous force reload is indeed
necessary). Most importantly though, the only way (it seems from
empirical evidence) to invalidate the CS TLBs on non-render ring is to
either use ring sync (which requires actually stopping the rings in
order to synchronize when the sync completes vs. where you are in
execution), or to reload DCLV.  Since without full PPGTT we do not ever
reload the DCLV register, there is no good way to achieve this. The
simplest solution is just to not support dynamic page table
creation/destruction in the aliasing PPGTT.

We could always reload DCLV, but this seems like quite a bit of excess
overhead only to save at most 2MB-4k of memory for the aliasing PPGTT
page tables.

Signed-off-by: Ben Widawsky 
---
 drivers/gpu/drm/i915/i915_drv.h |   2 +-
 drivers/gpu/drm/i915/i915_gem_context.c |   2 +-
 drivers/gpu/drm/i915/i915_gem_gtt.c | 123 +---
 drivers/gpu/drm/i915/i915_trace.h   | 108 
 4 files changed, 224 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index b19442c..eeef032 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2373,7 +2373,7 @@ static inline void i915_gem_chipset_flush(struct 
drm_device *dev)
if (INTEL_INFO(dev)->gen < 6)
intel_gtt_chipset_flush();
 }
-int i915_gem_init_ppgtt(struct drm_device *dev, struct i915_hw_ppgtt *ppgtt);
+int i915_gem_init_ppgtt(struct drm_device *dev, struct i915_hw_ppgtt *ppgtt, 
bool aliasing);
 bool intel_enable_ppgtt(struct drm_device *dev, bool full);
 
 /* i915_gem_stolen.c */
diff --git a/drivers/gpu/drm/i915/i915_gem_context.c 
b/drivers/gpu/drm/i915/i915_gem_context.c
index 6ad5380..185c926 100644
--- a/drivers/gpu/drm/i915/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/i915_gem_context.c
@@ -209,7 +209,7 @@ create_vm_for_ctx(struct drm_device *dev, struct 
i915_hw_context *ctx)
if (!ppgtt)
return ERR_PTR(-ENOMEM);
 
-   ret = i915_gem_init_ppgtt(dev, ppgtt);
+   ret = i915_gem_init_ppgtt(dev, ppgtt, ctx->file_priv == NULL);
if (ret) {
kfree(ppgtt);
return ERR_PTR(ret);
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 6d904c9..846a5b5 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -1016,13 +1016,54 @@ static void gen6_ppgtt_insert_entries(struct 
i915_address_space *vm,
kunmap_atomic(pt_vaddr);
 }
 
+static DECLARE_BITMAP(new_page_tables, I915_PDES_PER_PD);
 static int gen6_alloc_va_range(struct i915_address_space *vm,
   uint64_t start, uint64_t length)
 {
+   struct drm_device *dev = vm->dev;
+   struct drm_i915_private *dev_priv = dev->dev_private;
struct i915_hw_ppgtt *ppgtt =
container_of(vm, struct i915_hw_ppgtt, base);
struct i915_pagetab *pt;
+   const uint32_t start_save = start, length_save = length;
uint32_t pde, temp;
+   int ret;
+
+   BUG_ON(upper_32_bits(start));
+
+   bitmap_zero(new_page_tables, I915_PDES_PER_PD);
+
+   trace_i915_va_alloc(vm, start, length);
+
+   /* The allocation is done in two stages so that we can bail out with
+* minimal amount of pain. The first stage finds new page tables that
+* need allocation. The second stage marks use ptes within the page
+* tables.
+*/
+   gen6_for_each_pde(pt, &ppgtt->pd, start, length, temp, pde) {
+   if (pt != ppgtt->scratch_pt) {
+   WARN_ON(bitmap_empty(pt->used_ptes, GEN6_PTES_PER_PT));
+   continue;
+   }
+
+   /* We've already allocated a page table */
+   WARN_ON(!bitmap_empty(pt->used_ptes, GEN6_PTES_PER_PT));
+
+   pt = alloc_pt_single(dev);
+   if (IS_ERR(pt)) {
+   ret = PTR_ERR(pt);
+   goto unwind_out;
+   }
+
+   ppgtt->pd.page_tables[p

[Intel-gfx] [PATCH 16/26] drm/i915: Generalize GEN6 mapping

2014-03-17 Thread Ben Widawsky
Having a more general way of doing mappings will allow the ability to
easy map and unmap a specific page table. Specifically in this case, we
pass down the page directory + entry, and the page table to map. This
works similarly to the x86 code.

The same work will need to happen for GEN8. At that point I will try to
combine functionality.

Signed-off-by: Ben Widawsky 
---
 drivers/gpu/drm/i915/i915_gem_gtt.c | 61 +++--
 drivers/gpu/drm/i915/i915_gem_gtt.h |  2 ++
 2 files changed, 34 insertions(+), 29 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 5c08cf9..35acccb 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -663,18 +663,13 @@ bail:
 
 static void gen6_dump_ppgtt(struct i915_hw_ppgtt *ppgtt, struct seq_file *m)
 {
-   struct drm_i915_private *dev_priv = ppgtt->base.dev->dev_private;
struct i915_address_space *vm = &ppgtt->base;
-   gen6_gtt_pte_t __iomem *pd_addr;
gen6_gtt_pte_t scratch_pte;
uint32_t pd_entry;
int pte, pde;
 
scratch_pte = vm->pte_encode(vm->scratch.addr, I915_CACHE_LLC, true);
 
-   pd_addr = (gen6_gtt_pte_t __iomem *)dev_priv->gtt.gsm +
-   ppgtt->pd.pd_offset / sizeof(gen6_gtt_pte_t);
-
seq_printf(m, "  VM %p (pd_offset %x-%x):\n", vm,
   ppgtt->pd.pd_offset,
   ppgtt->pd.pd_offset + ppgtt->num_pd_entries);
@@ -682,7 +677,7 @@ static void gen6_dump_ppgtt(struct i915_hw_ppgtt *ppgtt, 
struct seq_file *m)
u32 expected;
gen6_gtt_pte_t *pt_vaddr;
dma_addr_t pt_addr = ppgtt->pd.page_tables[pde]->daddr;
-   pd_entry = readl(pd_addr + pde);
+   pd_entry = readl(ppgtt->pd_addr + pde);
expected = (GEN6_PDE_ADDR_ENCODE(pt_addr) | GEN6_PDE_VALID);
 
if (pd_entry != expected)
@@ -718,39 +713,43 @@ static void gen6_dump_ppgtt(struct i915_hw_ppgtt *ppgtt, 
struct seq_file *m)
}
 }
 
-static void gen6_map_single(struct i915_hw_ppgtt *ppgtt,
-   const unsigned pde_index,
-   dma_addr_t daddr)
+/* Map pde (index) from the page directory @pd to the page table @pt */
+static void gen6_map_single(struct i915_pagedir *pd,
+   const int pde, struct i915_pagetab *pt)
 {
-   struct drm_i915_private *dev_priv = ppgtt->base.dev->dev_private;
-   uint32_t pd_entry;
-   gen6_gtt_pte_t __iomem *pd_addr = (gen6_gtt_pte_t 
__iomem*)dev_priv->gtt.gsm;
-   pd_addr += ppgtt->pd.pd_offset / sizeof(gen6_gtt_pte_t);
+   struct i915_hw_ppgtt *ppgtt =
+   container_of(pd, struct i915_hw_ppgtt, pd);
+   u32 pd_entry;
 
-   pd_entry = GEN6_PDE_ADDR_ENCODE(daddr);
+   pd_entry = GEN6_PDE_ADDR_ENCODE(pt->daddr);
pd_entry |= GEN6_PDE_VALID;
 
-   writel(pd_entry, pd_addr + pde_index);
+   writel(pd_entry, ppgtt->pd_addr + pde);
+
+   /* XXX: Caller needs to make sure the write completes if necessary */
 }
 
 /* Map all the page tables found in the ppgtt structure to incrementing page
  * directories. */
-static void gen6_map_page_tables(struct i915_hw_ppgtt *ppgtt)
+static void gen6_map_page_range(struct drm_i915_private *dev_priv,
+   struct i915_pagedir *pd, unsigned pde, size_t n)
 {
-   struct drm_i915_private *dev_priv = ppgtt->base.dev->dev_private;
-   int i;
+   if (WARN_ON(pde + n > I915_PDES_PER_PD))
+   n = I915_PDES_PER_PD - pde;
 
-   WARN_ON(ppgtt->pd.pd_offset & 0x3f);
-   for (i = 0; i < ppgtt->num_pd_entries; i++)
-   gen6_map_single(ppgtt, i, ppgtt->pd.page_tables[i]->daddr);
+   n += pde;
+
+   for (; pde < n; pde++)
+   gen6_map_single(pd, pde, pd->page_tables[pde]);
 
+   /* Make sure write is complete before other code can use this page
+* table. Also require for WC mapped PTEs */
readl(dev_priv->gtt.gsm);
 }
 
 static uint32_t get_pd_offset(struct i915_hw_ppgtt *ppgtt)
 {
BUG_ON(ppgtt->pd.pd_offset & 0x3f);
-
return (ppgtt->pd.pd_offset / 64) << 16;
 }
 
@@ -1184,7 +1183,10 @@ static int gen6_ppgtt_init(struct i915_hw_ppgtt *ppgtt)
ppgtt->pd.pd_offset =
ppgtt->node.start / PAGE_SIZE * sizeof(gen6_gtt_pte_t);
 
-   gen6_map_page_tables(ppgtt);
+   ppgtt->pd_addr = (gen6_gtt_pte_t __iomem*)dev_priv->gtt.gsm +
+   ppgtt->pd.pd_offset / sizeof(gen6_gtt_pte_t);
+
+   gen6_map_page_range(dev_priv, &ppgtt->pd, 0, ppgtt->num_pd_entries);
 
DRM_DEBUG_DRIVER("Allocated pde space (%ldM) at GTT entry: %lx\n",
 ppgtt->node.size >> 20,
@@ -1355,13 +1357,14 @@ void i915_gem_restore_gtt_mappings(struct drm_device 
*dev)
 
list_for_each_entry(vm, &dev_priv->vm_list, global_link) {
/* TODO: Perhaps it shouldn't b

[Intel-gfx] [PATCH 22/26] drm/i915: Extract context switch skip logic

2014-03-17 Thread Ben Widawsky
We have some fanciness coming up. This patch just breaks out the logic.

Signed-off-by: Ben Widawsky 
---
 drivers/gpu/drm/i915/i915_gem_context.c | 12 +++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_context.c 
b/drivers/gpu/drm/i915/i915_gem_context.c
index f918f2c..a899e11 100644
--- a/drivers/gpu/drm/i915/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/i915_gem_context.c
@@ -634,6 +634,16 @@ mi_set_context(struct intel_ring_buffer *ring,
return ret;
 }
 
+static inline bool should_skip_switch(struct intel_ring_buffer *ring,
+ struct i915_hw_context *from,
+ struct i915_hw_context *to)
+{
+   if (from == to && from->last_ring == ring && !to->remap_slice)
+   return true;
+
+   return false;
+}
+
 static int do_switch(struct intel_ring_buffer *ring,
 struct i915_hw_context *to)
 {
@@ -648,7 +658,7 @@ static int do_switch(struct intel_ring_buffer *ring,
BUG_ON(!i915_gem_obj_is_pinned(from->obj));
}
 
-   if (from == to && from->last_ring == ring && !to->remap_slice)
+   if (should_skip_switch(ring, from, to))
return 0;
 
/* Trying to pin first makes error handling easier. */
-- 
1.9.0

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 26/26] FOR REFERENCE ONLY

2014-03-17 Thread Ben Widawsky
Start using size/length through the GEN8 code. The same approach was
taken for gen7. The difference with gen8 to this point is we need to
take care to the do the page directory allocations, as well as the page
tables.

This patch is meant to show how things will look (more or less) if I
keep up in the same direction.
---
 drivers/gpu/drm/i915/i915_gem_gtt.c | 104 +++-
 drivers/gpu/drm/i915/i915_gem_gtt.h |  37 +
 2 files changed, 115 insertions(+), 26 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 846a5b5..1348d48 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -488,29 +488,50 @@ static void gen8_ppgtt_insert_entries(struct 
i915_address_space *vm,
kunmap_atomic(pt_vaddr);
 }
 
-static void gen8_free_page_tables(struct i915_pagedir *pd, struct drm_device 
*dev)
+static void gen8_free_page_tables(struct i915_pagedir *pd,
+ uint64_t start, uint64_t length,
+ struct drm_device *dev)
 {
int i;
 
if (!pd->page)
return;
 
-   for (i = 0; i < I915_PDES_PER_PD; i++) {
+   for (i = gen8_pte_index(start);
+length && i < GEN8_PTES_PER_PT; i++, length -= PAGE_SIZE) {
+   if (!pd->page_tables[i])
+   continue;
+
free_pt_single(pd->page_tables[i], dev);
pd->page_tables[i] = NULL;
}
 }
 
-static void gen8_ppgtt_free(struct i915_hw_ppgtt *ppgtt)
+static void gen8_teardown_va_range(struct i915_hw_ppgtt *ppgtt,
+  uint64_t start, uint64_t length)
 {
-   int i;
+   struct drm_device *dev = ppgtt->base.dev;
+   struct i915_pagedir *pd;
+   struct i915_pagetab *pt;
+   uint64_t temp, temp2;
+   uint32_t pdpe, pde;
+
+   gen8_for_each_pdpe(pd, &ppgtt->pdp, start, length, temp, pdpe) {
+   uint64_t pd_start = start;
+   uint64_t pd_len = gen8_bound_pt(start, length);
+   gen8_for_each_pde(pt, pd, pd_start, pd_len, temp2, pde) {
+   gen8_free_page_tables(pd, pd_start, pd_len, dev);
+   }
 
-   for (i = 0; i < ppgtt->num_pd_pages; i++) {
-   gen8_free_page_tables(ppgtt->pdp.pagedir[i], ppgtt->base.dev);
-   free_pd_single(ppgtt->pdp.pagedir[i], ppgtt->base.dev);
+   free_pd_single(pd, dev);
}
 }
 
+static void gen8_ppgtt_free(struct i915_hw_ppgtt *ppgtt)
+{
+   gen8_teardown_va_range(ppgtt, ppgtt->base.start, ppgtt->base.total);
+}
+
 static void gen8_ppgtt_cleanup(struct i915_address_space *vm)
 {
struct i915_hw_ppgtt *ppgtt =
@@ -537,41 +558,75 @@ static int gen8_ppgtt_allocate_page_tables(struct 
i915_hw_ppgtt *ppgtt)
 
 unwind_out:
while (i--)
-   gen8_free_page_tables(ppgtt->pdp.pagedir[i], ppgtt->base.dev);
+   gen8_free_page_tables(ppgtt->pdp.pagedir[i],
+ i * I915_PDES_PER_PD * GEN8_PTES_PER_PT,
+ (i + 1)* I915_PDES_PER_PD * 
GEN8_PTES_PER_PT,
+ ppgtt->base.dev);
 
return -ENOMEM;
 }
 
 static int gen8_ppgtt_allocate_page_directories(struct i915_hw_ppgtt *ppgtt,
-   const int max_pdp)
+   uint64_t start, uint64_t length)
 {
-   int i;
+   struct i915_pagedir *unused;
+   uint64_t temp;
+   uint32_t pdpe;
 
-   for (i = 0; i < max_pdp; i++) {
-   ppgtt->pdp.pagedir[i] = alloc_pd_single(ppgtt->base.dev);
-   if (IS_ERR(ppgtt->pdp.pagedir[i]))
-   goto unwind_out;
+   gen8_for_each_pdpe(unused, &ppgtt->pdp, start, length, temp, pdpe) {
+   struct i915_pagedir *pd;
+
+   BUG_ON(unused);
+   pd = alloc_pd_single(ppgtt->base.dev);
+   if (!pd)
+   goto pd_fail;
+
+   ppgtt->pdp.pagedir[pdpe] = pd;
+   ppgtt->num_pd_pages++;
}
 
-   ppgtt->num_pd_pages = max_pdp;
BUG_ON(ppgtt->num_pd_pages > GEN8_LEGACY_PDPS);
 
return 0;
 
-unwind_out:
-   while (i--)
-   free_pd_single(ppgtt->pdp.pagedir[i],
-  ppgtt->base.dev);
+pd_fail:
+   while (pdpe--)
+   free_pd_single(ppgtt->pdp.pagedir[pdpe], ppgtt->base.dev);
 
return -ENOMEM;
 }
 
+static void gen8_alloc_va_range(struct i915_hw_ppgtt *ppgtt,
+   uint64_t start, uint64_t length)
+{
+   struct i915_pagedir *pd;
+   struct i915_pagetab *pt;
+   uint64_t temp, temp2;
+   uint32_t pdpe, pde;
+
+   gen8_for_each_pdpe(pd, &ppgtt->pdp, start, length, temp, pdpe) {
+   uint64_t pd_start = start;
+   uint64_

[Intel-gfx] [PATCH 14/26] drm/i915: Complete page table structures

2014-03-17 Thread Ben Widawsky
Move the remaining members over to the new page table structures.

This can be squashed with the previous commit if desire. The reasoning
is the same as that patch. I simply felt it is easier to review if split.

Signed-off-by: Ben Widawsky 

Conflicts:
drivers/gpu/drm/i915/i915_drv.h
drivers/gpu/drm/i915/i915_gem_gtt.c
---
 drivers/gpu/drm/i915/i915_debugfs.c   |  2 +-
 drivers/gpu/drm/i915/i915_gem_gtt.c   | 85 +--
 drivers/gpu/drm/i915/i915_gem_gtt.h   | 15 +++
 drivers/gpu/drm/i915/i915_gpu_error.c |  1 -
 4 files changed, 38 insertions(+), 65 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c 
b/drivers/gpu/drm/i915/i915_debugfs.c
index b226788..5f3666a 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -1788,7 +1788,7 @@ static void gen8_ppgtt_info(struct seq_file *m, struct 
drm_device *dev, int verb
 static void print_ppgtt(struct seq_file *m, struct i915_hw_ppgtt *ppgtt, const 
char *name)
 {
seq_printf(m, "%s:\n", name);
-   seq_printf(m, "pd gtt offset: 0x%08x\n", ppgtt->pd_offset);
+   seq_printf(m, "pd gtt offset: 0x%08x\n", ppgtt->pd.pd_offset);
 }
 
 static void gen6_ppgtt_info(struct seq_file *m, struct drm_device *dev, bool 
verbose)
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 5b283f2..d91a545 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -223,7 +223,7 @@ static int gen8_mm_switch(struct i915_hw_ppgtt *ppgtt,
int used_pd = ppgtt->num_pd_entries / I915_PDES_PER_PD;
 
for (i = used_pd - 1; i >= 0; i--) {
-   dma_addr_t addr = ppgtt->pd_dma_addr[i];
+   dma_addr_t addr = ppgtt->pdp.pagedir[i].daddr;
ret = gen8_write_pdp(ring, i, addr, synchronous);
if (ret)
return ret;
@@ -341,7 +341,6 @@ static void gen8_ppgtt_free(struct i915_hw_ppgtt *ppgtt)
for (i = 0; i < ppgtt->num_pd_pages; i++) {
gen8_free_page_tables(&ppgtt->pdp.pagedir[i]);
gen8_free_page_directories(&ppgtt->pdp.pagedir[i]);
-   kfree(ppgtt->gen8_pt_dma_addr[i]);
}
 }
 
@@ -353,14 +352,14 @@ static void gen8_ppgtt_dma_unmap_pages(struct 
i915_hw_ppgtt *ppgtt)
for (i = 0; i < ppgtt->num_pd_pages; i++) {
/* TODO: In the future we'll support sparse mappings, so this
 * will have to change. */
-   if (!ppgtt->pd_dma_addr[i])
+   if (!ppgtt->pdp.pagedir[i].daddr)
continue;
 
-   pci_unmap_page(hwdev, ppgtt->pd_dma_addr[i], PAGE_SIZE,
+   pci_unmap_page(hwdev, ppgtt->pdp.pagedir[i].daddr, PAGE_SIZE,
   PCI_DMA_BIDIRECTIONAL);
 
for (j = 0; j < I915_PDES_PER_PD; j++) {
-   dma_addr_t addr = ppgtt->gen8_pt_dma_addr[i][j];
+   dma_addr_t addr = 
ppgtt->pdp.pagedir[i].page_tables[j].daddr;
if (addr)
pci_unmap_page(hwdev, addr, PAGE_SIZE,
   PCI_DMA_BIDIRECTIONAL);
@@ -380,31 +379,18 @@ static void gen8_ppgtt_cleanup(struct i915_address_space 
*vm)
gen8_ppgtt_free(ppgtt);
 }
 
-static int gen8_ppgtt_allocate_dma(struct i915_hw_ppgtt *ppgtt)
-{
-   int i;
-
-   for (i = 0; i < ppgtt->num_pd_pages; i++) {
-   ppgtt->gen8_pt_dma_addr[i] = kcalloc(I915_PDES_PER_PD,
-sizeof(dma_addr_t),
-GFP_KERNEL);
-   if (!ppgtt->gen8_pt_dma_addr[i])
-   return -ENOMEM;
-   }
-
-   return 0;
-}
-
 static int gen8_ppgtt_allocate_page_tables(struct i915_hw_ppgtt *ppgtt)
 {
int i, j;
 
for (i = 0; i < ppgtt->num_pd_pages; i++) {
+   struct i915_pagedir *pd = &ppgtt->pdp.pagedir[i];
for (j = 0; j < I915_PDES_PER_PD; j++) {
-   struct i915_pagetab *pt = 
&ppgtt->pdp.pagedir[i].page_tables[j];
+   struct i915_pagetab *pt = &pd->page_tables[j];
pt->page = alloc_page(GFP_KERNEL | __GFP_ZERO);
if (!pt->page)
goto unwind_out;
+
}
}
 
@@ -464,9 +450,7 @@ static int gen8_ppgtt_alloc(struct i915_hw_ppgtt *ppgtt,
 
ppgtt->num_pd_entries = max_pdp * I915_PDES_PER_PD;
 
-   ret = gen8_ppgtt_allocate_dma(ppgtt);
-   if (!ret)
-   return ret;
+   return 0;
 
/* TODO: Check this for all cases */
 err_out:
@@ -488,7 +472,7 @@ static int gen8_ppgtt_setup_page_directories(struct 
i915_hw_ppgtt *ppgtt,
if (ret)
return ret;
 
-   ppgtt->pd_dma_addr[pdpe] = pd_addr;
+   ppgtt->pdp.pagedir[pdpe].daddr = 

[Intel-gfx] [PATCH 18/26] drm/i915: Always dma map page table allocations

2014-03-17 Thread Ben Widawsky
There is never a case where we don't want to do it. Since we've broken
up the allocations into nice clean helper functions, it's both easy and
obvious to do the dma mapping at the same time.

Signed-off-by: Ben Widawsky 
---
 drivers/gpu/drm/i915/i915_gem_gtt.c | 78 -
 1 file changed, 17 insertions(+), 61 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 92e03dd..9630109 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -187,20 +187,6 @@ static gen6_gtt_pte_t iris_pte_encode(dma_addr_t addr,
pci_unmap_page((dev)->pdev, (pt)->daddr, 4096, PCI_DMA_BIDIRECTIONAL); \
 } while (0);
 
-
-static void dma_unmap_pt_range(struct i915_pagedir *pd,
-  unsigned pde, size_t n,
-  struct drm_device *dev)
-{
-   if (WARN_ON(pde + n > I915_PDES_PER_PD))
-   n = I915_PDES_PER_PD - pde;
-
-   n += pde;
-
-   for (; pde < n; pde++)
-   dma_unmap_pt_single(pd->page_tables[pde], dev);
-}
-
 /**
  * dma_map_pt_single() - Create a dma mapping for a page table
  * @pt:Page table to get a DMA map for
@@ -230,33 +216,12 @@ static int dma_map_pt_single(struct i915_pagetab *pt, 
struct drm_device *dev)
return 0;
 }
 
-static int dma_map_pt_range(struct i915_pagedir *pd,
-   unsigned pde, size_t n,
-   struct drm_device *dev)
-{
-   const int first = pde;
-
-   if (WARN_ON(pde + n > I915_PDES_PER_PD))
-   n = I915_PDES_PER_PD - pde;
-
-   n += pde;
-
-   for (; pde < n; pde++) {
-   int ret;
-   ret = dma_map_pt_single(pd->page_tables[pde], dev);
-   if (ret) {
-   dma_unmap_pt_range(pd, first, pde, dev);
-   return ret;
-   }
-   }
-
-   return 0;
-}
-
-static void free_pt_single(struct i915_pagetab *pt)
+static void free_pt_single(struct i915_pagetab *pt, struct drm_device *dev)
 {
if (WARN_ON(!pt->page))
return;
+
+   dma_unmap_pt_single(pt, dev);
__free_page(pt->page);
kfree(pt);
 }
@@ -264,6 +229,7 @@ static void free_pt_single(struct i915_pagetab *pt)
 static struct i915_pagetab *alloc_pt_single(struct drm_device *dev)
 {
struct i915_pagetab *pt;
+   int ret;
 
pt = kzalloc(sizeof(*pt), GFP_KERNEL);
if (!pt)
@@ -275,6 +241,13 @@ static struct i915_pagetab *alloc_pt_single(struct 
drm_device *dev)
return ERR_PTR(-ENOMEM);
}
 
+   ret = dma_map_pt_single(pt, dev);
+   if (ret) {
+   __free_page(pt->page);
+   kfree(pt);
+   return ERR_PTR(ret);
+   }
+
return pt;
 }
 
@@ -318,7 +291,7 @@ static int alloc_pt_range(struct i915_pagedir *pd, uint16_t 
pde, size_t count,
 
 err_out:
while (i--)
-   free_pt_single(pd->page_tables[i]);
+   free_pt_single(pd->page_tables[i], dev);
return ret;
 }
 
@@ -486,7 +459,7 @@ static void gen8_ppgtt_insert_entries(struct 
i915_address_space *vm,
kunmap_atomic(pt_vaddr);
 }
 
-static void gen8_free_page_tables(struct i915_pagedir *pd)
+static void gen8_free_page_tables(struct i915_pagedir *pd, struct drm_device 
*dev)
 {
int i;
 
@@ -494,7 +467,7 @@ static void gen8_free_page_tables(struct i915_pagedir *pd)
return;
 
for (i = 0; i < I915_PDES_PER_PD; i++) {
-   free_pt_single(pd->page_tables[i]);
+   free_pt_single(pd->page_tables[i], dev);
pd->page_tables[i] = NULL;
}
 }
@@ -504,7 +477,7 @@ static void gen8_ppgtt_free(struct i915_hw_ppgtt *ppgtt)
int i;
 
for (i = 0; i < ppgtt->num_pd_pages; i++) {
-   gen8_free_page_tables(ppgtt->pdp.pagedir[i]);
+   gen8_free_page_tables(ppgtt->pdp.pagedir[i], ppgtt->base.dev);
free_pd_single(ppgtt->pdp.pagedir[i]);
}
 }
@@ -561,7 +534,7 @@ static int gen8_ppgtt_allocate_page_tables(struct 
i915_hw_ppgtt *ppgtt)
 
 unwind_out:
while (i--)
-   gen8_free_page_tables(ppgtt->pdp.pagedir[i]);
+   gen8_free_page_tables(ppgtt->pdp.pagedir[i], ppgtt->base.dev);
 
return -ENOMEM;
 }
@@ -659,18 +632,9 @@ static int gen8_ppgtt_init(struct i915_hw_ppgtt *ppgtt, 
uint64_t size)
 * 2. Create DMA mappings for the page directories and page tables.
 */
for (i = 0; i < max_pdp; i++) {
-   struct i915_pagedir *pd;
ret = gen8_ppgtt_setup_page_directories(ppgtt, i);
if (ret)
goto bail;
-
-   pd = ppgtt->pdp.pagedir[i];
-
-   for (j = 0; j < I915_PDES_PER_PD; j++) {
-   ret = dma_map_pt_single(pd->page_tables[j], 
ppgtt->base.dev);
- 

[Intel-gfx] [PATCH 21/26] drm/i915: Track GEN6 page table usage

2014-03-17 Thread Ben Widawsky
Instead of implementing the full tracking + dynamic allocation, this
patch does a bit less than half of the work, by tracking and warning on
unexpected conditions. The tracking itself follows which PTEs within a
page table are currently being used for objects. The next patch will
modify this to actually allocate the page tables only when necessary.

With the current patch there isn't much in the way of making a gen
agnostic range allocation function. However, in the next patch we'll add
more specificity which makes having separate functions a bit easier to
manage.

Notice that aliasing PPGTT is not managed here. The patch which actually
begins dynamic allocation/teardown explains the reasoning forthis.

Signed-off-by: Ben Widawsky 
---
 drivers/gpu/drm/i915/i915_gem_gtt.c | 170 +---
 drivers/gpu/drm/i915/i915_gem_gtt.h | 117 +++--
 2 files changed, 212 insertions(+), 75 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/i915_gem_gtt.c
index ad2f2c5..d3c77d1 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -53,9 +53,9 @@ bool intel_enable_ppgtt(struct drm_device *dev, bool full)
return HAS_ALIASING_PPGTT(dev);
 }
 
-static void ppgtt_bind_vma(struct i915_vma *vma,
-  enum i915_cache_level cache_level,
-  u32 flags);
+static int ppgtt_bind_vma(struct i915_vma *vma,
+ enum i915_cache_level cache_level,
+ u32 flags);
 static void ppgtt_unbind_vma(struct i915_vma *vma);
 static int gen8_ppgtt_enable(struct i915_hw_ppgtt *ppgtt);
 
@@ -204,39 +204,71 @@ static gen6_gtt_pte_t iris_pte_encode(dma_addr_t addr,
 (px)->page, 0, 4096, \
 PCI_DMA_BIDIRECTIONAL))
 
-static void free_pt_single(struct i915_pagetab *pt, struct drm_device *dev)
+static void __free_pt_single(struct i915_pagetab *pt, struct drm_device *dev,
+int scratch)
 {
+   if (WARN(scratch ^ pt->scratch,
+"Tried to free scratch = %d. Is scratch = %d\n",
+scratch, pt->scratch))
+   return;
+
if (WARN_ON(!pt->page))
return;
 
+   if (!scratch) {
+   const size_t count = INTEL_INFO(dev)->gen >= 8 ?
+   GEN8_PTES_PER_PT : GEN6_PTES_PER_PT;
+   WARN(!bitmap_empty(pt->used_ptes, count),
+"Free page table with %d used pages\n",
+bitmap_weight(pt->used_ptes, count));
+   }
+
i915_dma_unmap_single(pt, dev);
__free_page(pt->page);
+   kfree(pt->used_ptes);
kfree(pt);
 }
 
+#define free_pt_single(pt, dev) \
+   __free_pt_single(pt, dev, false)
+#define free_pt_scratch(pt, dev) \
+   __free_pt_single(pt, dev, true)
+
 static struct i915_pagetab *alloc_pt_single(struct drm_device *dev)
 {
struct i915_pagetab *pt;
-   int ret;
+   const size_t count = INTEL_INFO(dev)->gen >= 8 ?
+   GEN8_PTES_PER_PT : GEN6_PTES_PER_PT;
+   int ret = -ENOMEM;
 
pt = kzalloc(sizeof(*pt), GFP_KERNEL);
if (!pt)
return ERR_PTR(-ENOMEM);
 
+   pt->used_ptes = kcalloc(BITS_TO_LONGS(count), sizeof(*pt->used_ptes),
+   GFP_KERNEL);
+
+   if (!pt->used_ptes)
+   goto fail_bitmap;
+
pt->page = alloc_page(GFP_KERNEL | __GFP_ZERO);
-   if (!pt->page) {
-   kfree(pt);
-   return ERR_PTR(-ENOMEM);
-   }
+   if (!pt->page)
+   goto fail_page;
 
ret = i915_dma_map_px_single(pt, dev);
-   if (ret) {
-   __free_page(pt->page);
-   kfree(pt);
-   return ERR_PTR(ret);
-   }
+   if (ret)
+   goto fail_dma;
 
return pt;
+
+fail_dma:
+   __free_page(pt->page);
+fail_page:
+   kfree(pt->used_ptes);
+fail_bitmap:
+   kfree(pt);
+
+   return ERR_PTR(ret);
 }
 
 /**
@@ -689,15 +721,13 @@ static void gen6_map_single(struct i915_pagedir *pd,
 /* Map all the page tables found in the ppgtt structure to incrementing page
  * directories. */
 static void gen6_map_page_range(struct drm_i915_private *dev_priv,
-   struct i915_pagedir *pd, unsigned pde, size_t n)
+   struct i915_pagedir *pd, uint32_t start, 
uint32_t length)
 {
-   if (WARN_ON(pde + n > I915_PDES_PER_PD))
-   n = I915_PDES_PER_PD - pde;
-
-   n += pde;
+   struct i915_pagetab *pt;
+   uint32_t pde, temp;
 
-   for (; pde < n; pde++)
-   gen6_map_single(pd, pde, pd->page_tables[pde]);
+   gen6_for_each_pde(pt, pd, start, length, temp, pde)
+   gen6_map_single(pd, pde, pt);
 
/* Make sure write is complete

[Intel-gfx] [PATCH 17/26] drm/i915: Clean up pagetable DMA map & unmap

2014-03-17 Thread Ben Widawsky
Map and unmap are common operations across all generations for
pagetables. With a simple helper, we can get a nice net code reduction
as well as simplified complexity.

There is some room for optimization here, for instance with the multiple
page mapping, that can be done in one pci_map operation. In that case
however, the max value we'll ever see there is 512, and so I believe the
simpler code makes this a worthwhile trade-off. Also, the range mapping
functions are place holders to help transition the code. Eventually,
mapping will only occur during a page allocation which will always be a
discrete operation.

Signed-off-by: Ben Widawsky 
---
 drivers/gpu/drm/i915/i915_gem_gtt.c | 147 +---
 1 file changed, 85 insertions(+), 62 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 35acccb..92e03dd 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -183,6 +183,76 @@ static gen6_gtt_pte_t iris_pte_encode(dma_addr_t addr,
return pte;
 }
 
+#define dma_unmap_pt_single(pt, dev) do { \
+   pci_unmap_page((dev)->pdev, (pt)->daddr, 4096, PCI_DMA_BIDIRECTIONAL); \
+} while (0);
+
+
+static void dma_unmap_pt_range(struct i915_pagedir *pd,
+  unsigned pde, size_t n,
+  struct drm_device *dev)
+{
+   if (WARN_ON(pde + n > I915_PDES_PER_PD))
+   n = I915_PDES_PER_PD - pde;
+
+   n += pde;
+
+   for (; pde < n; pde++)
+   dma_unmap_pt_single(pd->page_tables[pde], dev);
+}
+
+/**
+ * dma_map_pt_single() - Create a dma mapping for a page table
+ * @pt:Page table to get a DMA map for
+ * @dev:   drm device
+ *
+ * Page table allocations are unified across all gens. They always require a
+ * single 4k allocation, as well as a DMA mapping.
+ *
+ * Return: 0 if success.
+ */
+static int dma_map_pt_single(struct i915_pagetab *pt, struct drm_device *dev)
+{
+   struct page *page;
+   dma_addr_t pt_addr;
+   int ret;
+
+   page = pt->page;
+   pt_addr = pci_map_page(dev->pdev, page, 0, 4096,
+  PCI_DMA_BIDIRECTIONAL);
+
+   ret = pci_dma_mapping_error(dev->pdev, pt_addr);
+   if (ret)
+   return ret;
+
+   pt->daddr = pt_addr;
+
+   return 0;
+}
+
+static int dma_map_pt_range(struct i915_pagedir *pd,
+   unsigned pde, size_t n,
+   struct drm_device *dev)
+{
+   const int first = pde;
+
+   if (WARN_ON(pde + n > I915_PDES_PER_PD))
+   n = I915_PDES_PER_PD - pde;
+
+   n += pde;
+
+   for (; pde < n; pde++) {
+   int ret;
+   ret = dma_map_pt_single(pd->page_tables[pde], dev);
+   if (ret) {
+   dma_unmap_pt_range(pd, first, pde, dev);
+   return ret;
+   }
+   }
+
+   return 0;
+}
+
 static void free_pt_single(struct i915_pagetab *pt)
 {
if (WARN_ON(!pt->page))
@@ -191,7 +261,7 @@ static void free_pt_single(struct i915_pagetab *pt)
kfree(pt);
 }
 
-static struct i915_pagetab *alloc_pt_single(void)
+static struct i915_pagetab *alloc_pt_single(struct drm_device *dev)
 {
struct i915_pagetab *pt;
 
@@ -214,6 +284,7 @@ static struct i915_pagetab *alloc_pt_single(void)
  * available to point to the allocated page tables.
  * @pde:   First page directory entry for which we are allocating.
  * @count: Number of pages to allocate.
+ * @devDRM device used for DMA mapping.
  *
  * Allocates multiple page table pages and sets the appropriate entries in the
  * page table structure within the page directory. Function cleans up after
@@ -221,7 +292,8 @@ static struct i915_pagetab *alloc_pt_single(void)
  *
  * Return: 0 if allocation succeeded.
  */
-static int alloc_pt_range(struct i915_pagedir *pd, uint16_t pde, size_t count)
+static int alloc_pt_range(struct i915_pagedir *pd, uint16_t pde, size_t count,
+ struct drm_device *dev)
 {
int i, ret;
 
@@ -231,7 +303,7 @@ static int alloc_pt_range(struct i915_pagedir *pd, uint16_t 
pde, size_t count)
BUG_ON(pde + count > I915_PDES_PER_PD);
 
for (i = pde; i < pde + count; i++) {
-   struct i915_pagetab *pt = alloc_pt_single();
+   struct i915_pagetab *pt = alloc_pt_single(dev);
if (IS_ERR(pt)) {
ret = PTR_ERR(pt);
goto err_out;
@@ -480,7 +552,7 @@ static int gen8_ppgtt_allocate_page_tables(struct 
i915_hw_ppgtt *ppgtt)
 
for (i = 0; i < ppgtt->num_pd_pages; i++) {
ret = alloc_pt_range(ppgtt->pdp.pagedir[i],
-0, I915_PDES_PER_PD);
+0, I915_PDES_PER_PD, ppgtt->base.dev);
if (ret)
g

[Intel-gfx] [PATCH 25/26] drm/i915: Print used ppgtt pages for gen6 in debugfs

2014-03-17 Thread Ben Widawsky
Signed-off-by: Ben Widawsky 
---
 drivers/gpu/drm/i915/i915_debugfs.c | 19 ++-
 1 file changed, 18 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c 
b/drivers/gpu/drm/i915/i915_debugfs.c
index 5f3666a..04d40fa 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -1785,10 +1785,26 @@ static void gen8_ppgtt_info(struct seq_file *m, struct 
drm_device *dev, int verb
}
 }
 
+static size_t gen6_ppgtt_count_pt_pages(struct i915_hw_ppgtt *ppgtt)
+{
+   struct i915_pagedir *pd = &ppgtt->pd;
+   struct i915_pagetab **pt = &pd->page_tables[0];
+   size_t cnt = 0;
+   int i;
+
+   for (i = 0; i < ppgtt->num_pd_entries; i++) {
+   if (pt[i] != ppgtt->scratch_pt)
+   cnt++;
+   }
+
+   return cnt;
+}
+
 static void print_ppgtt(struct seq_file *m, struct i915_hw_ppgtt *ppgtt, const 
char *name)
 {
seq_printf(m, "%s:\n", name);
seq_printf(m, "pd gtt offset: 0x%08x\n", ppgtt->pd.pd_offset);
+   seq_printf(m, "\tpd pages: %zu\n", gen6_ppgtt_count_pt_pages(ppgtt));
 }
 
 static void gen6_ppgtt_info(struct seq_file *m, struct drm_device *dev, bool 
verbose)
@@ -1809,6 +1825,8 @@ static void gen6_ppgtt_info(struct seq_file *m, struct 
drm_device *dev, bool ver
seq_printf(m, "PP_DIR_BASE_READ: 0x%08x\n", 
I915_READ(RING_PP_DIR_BASE_READ(ring)));
seq_printf(m, "PP_DIR_DCLV: 0x%08x\n", 
I915_READ(RING_PP_DIR_DCLV(ring)));
}
+   seq_printf(m, "ECOCHK: 0x%08x\n\n", I915_READ(GAM_ECOCHK));
+
if (dev_priv->mm.aliasing_ppgtt) {
struct i915_hw_ppgtt *ppgtt = dev_priv->mm.aliasing_ppgtt;
 
@@ -1829,7 +1847,6 @@ static void gen6_ppgtt_info(struct seq_file *m, struct 
drm_device *dev, bool ver
if (verbose)
idr_for_each(&file_priv->context_idr, per_file_ctx, m);
}
-   seq_printf(m, "ECOCHK: 0x%08x\n", I915_READ(GAM_ECOCHK));
 }
 
 static int i915_ppgtt_info(struct seq_file *m, void *data)
-- 
1.9.0

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 19/26] drm/i915: Consolidate dma mappings

2014-03-17 Thread Ben Widawsky
With a little bit of macro magic, and the fact that every page
table/dir/etc. we wish to map will have a page, and daddr member, we can
greatly simplify and reduce code.

The patch introduces an i915_dma_map/unmap which has the same semantics
as pci_map_page, but is 1 line, and doesn't require newlines, or local
variables to make it fit cleanly.

Notice that even the page allocation shares this same attribute. For
now, I am leaving that code untouched because the macro version would be
a bit on the big side - but it's a nice cleanup as well (IMO)

Signed-off-by: Ben Widawsky 
---
 drivers/gpu/drm/i915/i915_gem_gtt.c | 56 -
 1 file changed, 18 insertions(+), 38 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 9630109..abef33dd 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -183,45 +183,33 @@ static gen6_gtt_pte_t iris_pte_encode(dma_addr_t addr,
return pte;
 }
 
-#define dma_unmap_pt_single(pt, dev) do { \
-   pci_unmap_page((dev)->pdev, (pt)->daddr, 4096, PCI_DMA_BIDIRECTIONAL); \
+#define i915_dma_unmap_single(px, dev) do { \
+   pci_unmap_page((dev)->pdev, (px)->daddr, 4096, PCI_DMA_BIDIRECTIONAL); \
 } while (0);
 
 /**
- * dma_map_pt_single() - Create a dma mapping for a page table
- * @pt:Page table to get a DMA map for
+ * i915_dma_map_px_single() - Create a dma mapping for a page table/dir/etc.
+ * @px:Page table/dir/etc to get a DMA map for
  * @dev:   drm device
  *
  * Page table allocations are unified across all gens. They always require a
- * single 4k allocation, as well as a DMA mapping.
+ * single 4k allocation, as well as a DMA mapping. If we keep the structs
+ * symmetric here, the simple macro covers us for every page table type.
  *
  * Return: 0 if success.
  */
-static int dma_map_pt_single(struct i915_pagetab *pt, struct drm_device *dev)
-{
-   struct page *page;
-   dma_addr_t pt_addr;
-   int ret;
-
-   page = pt->page;
-   pt_addr = pci_map_page(dev->pdev, page, 0, 4096,
-  PCI_DMA_BIDIRECTIONAL);
-
-   ret = pci_dma_mapping_error(dev->pdev, pt_addr);
-   if (ret)
-   return ret;
-
-   pt->daddr = pt_addr;
-
-   return 0;
-}
+#define i915_dma_map_px_single(px, dev) \
+   pci_dma_mapping_error((dev)->pdev, \
+ (px)->daddr = pci_map_page((dev)->pdev, \
+(px)->page, 0, 4096, \
+PCI_DMA_BIDIRECTIONAL))
 
 static void free_pt_single(struct i915_pagetab *pt, struct drm_device *dev)
 {
if (WARN_ON(!pt->page))
return;
 
-   dma_unmap_pt_single(pt, dev);
+   i915_dma_unmap_single(pt, dev);
__free_page(pt->page);
kfree(pt);
 }
@@ -241,7 +229,7 @@ static struct i915_pagetab *alloc_pt_single(struct 
drm_device *dev)
return ERR_PTR(-ENOMEM);
}
 
-   ret = dma_map_pt_single(pt, dev);
+   ret = i915_dma_map_px_single(pt, dev);
if (ret) {
__free_page(pt->page);
kfree(pt);
@@ -484,7 +472,7 @@ static void gen8_ppgtt_free(struct i915_hw_ppgtt *ppgtt)
 
 static void gen8_ppgtt_dma_unmap_pages(struct i915_hw_ppgtt *ppgtt)
 {
-   struct pci_dev *hwdev = ppgtt->base.dev->pdev;
+   struct drm_device *dev = ppgtt->base.dev;
int i, j;
 
for (i = 0; i < ppgtt->num_pd_pages; i++) {
@@ -493,16 +481,14 @@ static void gen8_ppgtt_dma_unmap_pages(struct 
i915_hw_ppgtt *ppgtt)
if (!ppgtt->pdp.pagedir[i]->daddr)
continue;
 
-   pci_unmap_page(hwdev, ppgtt->pdp.pagedir[i]->daddr, PAGE_SIZE,
-  PCI_DMA_BIDIRECTIONAL);
+   i915_dma_unmap_single(ppgtt->pdp.pagedir[i], dev);
 
for (j = 0; j < I915_PDES_PER_PD; j++) {
struct i915_pagedir *pd = ppgtt->pdp.pagedir[i];
struct i915_pagetab *pt =  pd->page_tables[j];
dma_addr_t addr = pt->daddr;
if (addr)
-   pci_unmap_page(hwdev, addr, PAGE_SIZE,
-  PCI_DMA_BIDIRECTIONAL);
+   i915_dma_unmap_single(pt, dev);
}
}
 }
@@ -588,19 +574,13 @@ err_out:
 static int gen8_ppgtt_setup_page_directories(struct i915_hw_ppgtt *ppgtt,
 const int pdpe)
 {
-   dma_addr_t pd_addr;
int ret;
 
-   pd_addr = pci_map_page(ppgtt->base.dev->pdev,
-  ppgtt->pdp.pagedir[pdpe]->page, 0,
-  PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
-
-   ret = pci_dma_mapping_error(ppgtt->base.dev->pdev, pd_addr);
+   ret = i915_dma_map

[Intel-gfx] [PATCH 05/26] drm/i915: Setup less PPGTT on failed pagedir

2014-03-17 Thread Ben Widawsky
The current code will both potentially print a WARN, and setup part of
the PPGTT structure. Neither of these harm the current code, it is
simply for clarity, and to perhaps prevent later bugs, or weird
debug messages.

Signed-off-by: Ben Widawsky 
---
 drivers/gpu/drm/i915/i915_gem_gtt.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 08a1e1c..09556d1 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -1085,11 +1085,14 @@ alloc:
goto alloc;
}
 
+   if (ret)
+   return ret;
+
if (ppgtt->node.start < dev_priv->gtt.mappable_end)
DRM_DEBUG("Forced to use aperture for PDEs\n");
 
ppgtt->num_pd_entries = GEN6_PPGTT_PD_ENTRIES;
-   return ret;
+   return 0;
 }
 
 static int gen6_ppgtt_allocate_page_tables(struct i915_hw_ppgtt *ppgtt)
-- 
1.9.0

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 09/26] drm/i915: Split out gtt specific header file

2014-03-17 Thread Ben Widawsky
TODO: Do header files need a copyright?

Signed-off-by: Ben Widawsky 
---
 drivers/gpu/drm/i915/i915_drv.h | 162 +-
 drivers/gpu/drm/i915/i915_gem_gtt.c |  57 -
 drivers/gpu/drm/i915/i915_gem_gtt.h | 225 
 3 files changed, 227 insertions(+), 217 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/i915_gem_gtt.h

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 084e82f..b19442c 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -44,6 +44,8 @@
 #include 
 #include 
 
+#include "i915_gem_gtt.h"
+
 /* General customization:
  */
 
@@ -572,166 +574,6 @@ enum i915_cache_level {
I915_CACHE_WT, /* hsw:gt3e WriteThrough for scanouts */
 };
 
-typedef uint32_t gen6_gtt_pte_t;
-
-/**
- * A VMA represents a GEM BO that is bound into an address space. Therefore, a
- * VMA's presence cannot be guaranteed before binding, or after unbinding the
- * object into/from the address space.
- *
- * To make things as simple as possible (ie. no refcounting), a VMA's lifetime
- * will always be <= an objects lifetime. So object refcounting should cover 
us.
- */
-struct i915_vma {
-   struct drm_mm_node node;
-   struct drm_i915_gem_object *obj;
-   struct i915_address_space *vm;
-
-   /** This object's place on the active/inactive lists */
-   struct list_head mm_list;
-
-   struct list_head vma_link; /* Link in the object's VMA list */
-
-   /** This vma's place in the batchbuffer or on the eviction list */
-   struct list_head exec_list;
-
-   /**
-* Used for performing relocations during execbuffer insertion.
-*/
-   struct hlist_node exec_node;
-   unsigned long exec_handle;
-   struct drm_i915_gem_exec_object2 *exec_entry;
-
-   /**
-* How many users have pinned this object in GTT space. The following
-* users can each hold at most one reference: pwrite/pread, pin_ioctl
-* (via user_pin_count), execbuffer (objects are not allowed multiple
-* times for the same batchbuffer), and the framebuffer code. When
-* switching/pageflipping, the framebuffer code has at most two buffers
-* pinned per crtc.
-*
-* In the worst case this is 1 + 1 + 1 + 2*2 = 7. That would fit into 3
-* bits with absolutely no headroom. So use 4 bits. */
-   unsigned int pin_count:4;
-#define DRM_I915_GEM_OBJECT_MAX_PIN_COUNT 0xf
-
-   /** Unmap an object from an address space. This usually consists of
-* setting the valid PTE entries to a reserved scratch page. */
-   void (*unbind_vma)(struct i915_vma *vma);
-   /* Map an object into an address space with the given cache flags. */
-#define GLOBAL_BIND (1<<0)
-   void (*bind_vma)(struct i915_vma *vma,
-enum i915_cache_level cache_level,
-u32 flags);
-};
-
-struct i915_address_space {
-   struct drm_mm mm;
-   struct drm_device *dev;
-   struct list_head global_link;
-   unsigned long start;/* Start offset always 0 for dri2 */
-   size_t total;   /* size addr space maps (ex. 2GB for ggtt) */
-
-   struct {
-   dma_addr_t addr;
-   struct page *page;
-   } scratch;
-
-   /**
-* List of objects currently involved in rendering.
-*
-* Includes buffers having the contents of their GPU caches
-* flushed, not necessarily primitives.  last_rendering_seqno
-* represents when the rendering involved will be completed.
-*
-* A reference is held on the buffer while on this list.
-*/
-   struct list_head active_list;
-
-   /**
-* LRU list of objects which are not in the ringbuffer and
-* are ready to unbind, but are still in the GTT.
-*
-* last_rendering_seqno is 0 while an object is in this list.
-*
-* A reference is not held on the buffer while on this list,
-* as merely being GTT-bound shouldn't prevent its being
-* freed, and we'll pull it off the list in the free path.
-*/
-   struct list_head inactive_list;
-
-   /* FIXME: Need a more generic return type */
-   gen6_gtt_pte_t (*pte_encode)(dma_addr_t addr,
-enum i915_cache_level level,
-bool valid); /* Create a valid PTE */
-   void (*clear_range)(struct i915_address_space *vm,
-   uint64_t start,
-   uint64_t length,
-   bool use_scratch);
-   void (*insert_entries)(struct i915_address_space *vm,
-  struct sg_table *st,
-  uint64_t start,
-  enum i915_cache_level cache_level);
-   void (*cleanup)(struct i915_address_space *vm);
-};
-
-/* Th

[Intel-gfx] [PATCH 10/26] drm/i915: Make gen6_write_pdes gen6_map_page_tables

2014-03-17 Thread Ben Widawsky
Split out single mappings which will help with upcoming work. Also while
here, rename the function because it is a better description - but this
function is going away soon.

Signed-off-by: Ben Widawsky 
---
 drivers/gpu/drm/i915/i915_gem_gtt.c | 39 ++---
 1 file changed, 23 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/i915_gem_gtt.c
index a239196..d89054d 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -655,26 +655,33 @@ static void gen6_dump_ppgtt(struct i915_hw_ppgtt *ppgtt, 
struct seq_file *m)
}
 }
 
-static void gen6_write_pdes(struct i915_hw_ppgtt *ppgtt)
+static void gen6_map_single(struct i915_hw_ppgtt *ppgtt,
+   const unsigned pde_index,
+   dma_addr_t daddr)
 {
struct drm_i915_private *dev_priv = ppgtt->base.dev->dev_private;
-   gen6_gtt_pte_t __iomem *pd_addr;
uint32_t pd_entry;
+   gen6_gtt_pte_t __iomem *pd_addr =
+   (gen6_gtt_pte_t __iomem*)dev_priv->gtt.gsm + ppgtt->pd_offset / 
sizeof(gen6_gtt_pte_t);
+
+   pd_entry = GEN6_PDE_ADDR_ENCODE(daddr);
+   pd_entry |= GEN6_PDE_VALID;
+
+   writel(pd_entry, pd_addr + pde_index);
+}
+
+/* Map all the page tables found in the ppgtt structure to incrementing page
+ * directories. */
+static void gen6_map_page_tables(struct i915_hw_ppgtt *ppgtt)
+{
+   struct drm_i915_private *dev_priv = ppgtt->base.dev->dev_private;
int i;
 
WARN_ON(ppgtt->pd_offset & 0x3f);
-   pd_addr = (gen6_gtt_pte_t __iomem*)dev_priv->gtt.gsm +
-   ppgtt->pd_offset / sizeof(gen6_gtt_pte_t);
-   for (i = 0; i < ppgtt->num_pd_entries; i++) {
-   dma_addr_t pt_addr;
-
-   pt_addr = ppgtt->pt_dma_addr[i];
-   pd_entry = GEN6_PDE_ADDR_ENCODE(pt_addr);
-   pd_entry |= GEN6_PDE_VALID;
+   for (i = 0; i < ppgtt->num_pd_entries; i++)
+   gen6_map_single(ppgtt, i, ppgtt->pt_dma_addr[i]);
 
-   writel(pd_entry, pd_addr + i);
-   }
-   readl(pd_addr);
+   readl(dev_priv->gtt.gsm);
 }
 
 static uint32_t get_pd_offset(struct i915_hw_ppgtt *ppgtt)
@@ -1145,7 +1152,7 @@ static int gen6_ppgtt_init(struct i915_hw_ppgtt *ppgtt)
ppgtt->pd_offset =
ppgtt->node.start / PAGE_SIZE * sizeof(gen6_gtt_pte_t);
 
-   gen6_write_pdes(ppgtt);
+   gen6_map_page_tables(ppgtt);
 
ppgtt->base.clear_range(&ppgtt->base, 0, ppgtt->base.total, true);
 
@@ -1319,11 +1326,11 @@ void i915_gem_restore_gtt_mappings(struct drm_device 
*dev)
/* TODO: Perhaps it shouldn't be gen6 specific */
if (i915_is_ggtt(vm)) {
if (dev_priv->mm.aliasing_ppgtt)
-   gen6_write_pdes(dev_priv->mm.aliasing_ppgtt);
+   
gen6_map_page_tables(dev_priv->mm.aliasing_ppgtt);
continue;
}
 
-   gen6_write_pdes(container_of(vm, struct i915_hw_ppgtt, base));
+   gen6_map_page_tables(container_of(vm, struct i915_hw_ppgtt, 
base));
}
 
i915_gem_chipset_flush(dev);
-- 
1.9.0

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 04/26] drm/i915: rename map/unmap to dma_map/unmap

2014-03-17 Thread Ben Widawsky
Upcoming patches will use the terms map and unmap in references to the
page table entries. Having this distinction will really help with code
clarity at that point.

Signed-off-by: Ben Widawsky 
---
 drivers/gpu/drm/i915/i915_gem_gtt.c | 12 ++--
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/i915_gem_gtt.c
index b26b186..08a1e1c 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -394,7 +394,7 @@ static void gen8_ppgtt_free(const struct i915_hw_ppgtt 
*ppgtt)
__free_pages(ppgtt->pd_pages, get_order(ppgtt->num_pd_pages << 
PAGE_SHIFT));
 }
 
-static void gen8_ppgtt_unmap_pages(struct i915_hw_ppgtt *ppgtt)
+static void gen8_ppgtt_dma_unmap_pages(struct i915_hw_ppgtt *ppgtt)
 {
struct pci_dev *hwdev = ppgtt->base.dev->pdev;
int i, j;
@@ -425,7 +425,7 @@ static void gen8_ppgtt_cleanup(struct i915_address_space 
*vm)
list_del(&vm->global_link);
drm_mm_takedown(&vm->mm);
 
-   gen8_ppgtt_unmap_pages(ppgtt);
+   gen8_ppgtt_dma_unmap_pages(ppgtt);
gen8_ppgtt_free(ppgtt);
 }
 
@@ -651,7 +651,7 @@ static int gen8_ppgtt_init(struct i915_hw_ppgtt *ppgtt, 
uint64_t size)
return 0;
 
 bail:
-   gen8_ppgtt_unmap_pages(ppgtt);
+   gen8_ppgtt_dma_unmap_pages(ppgtt);
gen8_ppgtt_free(ppgtt);
return ret;
 }
@@ -1019,7 +1019,7 @@ static void gen6_ppgtt_insert_entries(struct 
i915_address_space *vm,
kunmap_atomic(pt_vaddr);
 }
 
-static void gen6_ppgtt_unmap_pages(struct i915_hw_ppgtt *ppgtt)
+static void gen6_ppgtt_dma_unmap_pages(struct i915_hw_ppgtt *ppgtt)
 {
int i;
 
@@ -1050,7 +1050,7 @@ static void gen6_ppgtt_cleanup(struct i915_address_space 
*vm)
drm_mm_takedown(&ppgtt->base.mm);
drm_mm_remove_node(&ppgtt->node);
 
-   gen6_ppgtt_unmap_pages(ppgtt);
+   gen6_ppgtt_dma_unmap_pages(ppgtt);
gen6_ppgtt_free(ppgtt);
 }
 
@@ -1150,7 +1150,7 @@ static int gen6_ppgtt_setup_page_tables(struct 
i915_hw_ppgtt *ppgtt)
   PCI_DMA_BIDIRECTIONAL);
 
if (pci_dma_mapping_error(dev->pdev, pt_addr)) {
-   gen6_ppgtt_unmap_pages(ppgtt);
+   gen6_ppgtt_dma_unmap_pages(ppgtt);
return -EIO;
}
 
-- 
1.9.0

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 03/26] drm/i915: s/pd/pdpe, s/pt/pde

2014-03-17 Thread Ben Widawsky
The actual correct way to think about this with the new style of page
table data structures is as the actual entry that is being indexed into
the array. "pd", and "pt" aren't representative of what the operation is
doing.

The clarity here will improve the readability of future patches.

Signed-off-by: Ben Widawsky 
---
 drivers/gpu/drm/i915/i915_gem_gtt.c | 14 +++---
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/i915_gem_gtt.c
index bd016e2..b26b186 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -537,40 +537,40 @@ static int gen8_ppgtt_alloc(struct i915_hw_ppgtt *ppgtt,
 }
 
 static int gen8_ppgtt_setup_page_directories(struct i915_hw_ppgtt *ppgtt,
-const int pd)
+const int pdpe)
 {
dma_addr_t pd_addr;
int ret;
 
pd_addr = pci_map_page(ppgtt->base.dev->pdev,
-  &ppgtt->pd_pages[pd], 0,
+  &ppgtt->pd_pages[pdpe], 0,
   PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
 
ret = pci_dma_mapping_error(ppgtt->base.dev->pdev, pd_addr);
if (ret)
return ret;
 
-   ppgtt->pd_dma_addr[pd] = pd_addr;
+   ppgtt->pd_dma_addr[pdpe] = pd_addr;
 
return 0;
 }
 
 static int gen8_ppgtt_setup_page_tables(struct i915_hw_ppgtt *ppgtt,
-   const int pd,
-   const int pt)
+   const int pdpe,
+   const int pde)
 {
dma_addr_t pt_addr;
struct page *p;
int ret;
 
-   p = ppgtt->gen8_pt_pages[pd][pt];
+   p = ppgtt->gen8_pt_pages[pdpe][pde];
pt_addr = pci_map_page(ppgtt->base.dev->pdev,
   p, 0, PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
ret = pci_dma_mapping_error(ppgtt->base.dev->pdev, pt_addr);
if (ret)
return ret;
 
-   ppgtt->gen8_pt_dma_addr[pd][pt] = pt_addr;
+   ppgtt->gen8_pt_dma_addr[pdpe][pde] = pt_addr;
 
return 0;
 }
-- 
1.9.0

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 20/26] drm/i915: Always dma map page directory allocations

2014-03-17 Thread Ben Widawsky
Similar to the patch a few back in the series, we can always map and
unmap page directories when we do their allocation and teardown. Page
directory pages only exist on gen8+, so this should only effect behavior
on those platforms.

Signed-off-by: Ben Widawsky 
---
 drivers/gpu/drm/i915/i915_gem_gtt.c | 79 +
 1 file changed, 19 insertions(+), 60 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/i915_gem_gtt.c
index abef33dd..ad2f2c5 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -283,21 +283,23 @@ err_out:
return ret;
 }
 
-static void __free_pd_single(struct i915_pagedir *pd)
+static void __free_pd_single(struct i915_pagedir *pd, struct drm_device *dev)
 {
+   i915_dma_unmap_single(pd, dev);
__free_page(pd->page);
kfree(pd);
 }
 
-#define free_pd_single(pd) do { \
+#define free_pd_single(pd, dev) do { \
if ((pd)->page) { \
-   __free_pd_single(pd); \
+   __free_pd_single(pd, dev); \
} \
 } while (0)
 
-static struct i915_pagedir *alloc_pd_single(void)
+static struct i915_pagedir *alloc_pd_single(struct drm_device *dev)
 {
struct i915_pagedir *pd;
+   int ret;
 
pd = kzalloc(sizeof(*pd), GFP_KERNEL);
if (!pd)
@@ -309,6 +311,13 @@ static struct i915_pagedir *alloc_pd_single(void)
return ERR_PTR(-ENOMEM);
}
 
+   ret = i915_dma_map_px_single(pd, dev);
+   if (ret) {
+   __free_page(pd->page);
+   kfree(pd);
+   return ERR_PTR(ret);
+   }
+
return pd;
 }
 
@@ -466,30 +475,7 @@ static void gen8_ppgtt_free(struct i915_hw_ppgtt *ppgtt)
 
for (i = 0; i < ppgtt->num_pd_pages; i++) {
gen8_free_page_tables(ppgtt->pdp.pagedir[i], ppgtt->base.dev);
-   free_pd_single(ppgtt->pdp.pagedir[i]);
-   }
-}
-
-static void gen8_ppgtt_dma_unmap_pages(struct i915_hw_ppgtt *ppgtt)
-{
-   struct drm_device *dev = ppgtt->base.dev;
-   int i, j;
-
-   for (i = 0; i < ppgtt->num_pd_pages; i++) {
-   /* TODO: In the future we'll support sparse mappings, so this
-* will have to change. */
-   if (!ppgtt->pdp.pagedir[i]->daddr)
-   continue;
-
-   i915_dma_unmap_single(ppgtt->pdp.pagedir[i], dev);
-
-   for (j = 0; j < I915_PDES_PER_PD; j++) {
-   struct i915_pagedir *pd = ppgtt->pdp.pagedir[i];
-   struct i915_pagetab *pt =  pd->page_tables[j];
-   dma_addr_t addr = pt->daddr;
-   if (addr)
-   i915_dma_unmap_single(pt, dev);
-   }
+   free_pd_single(ppgtt->pdp.pagedir[i], ppgtt->base.dev);
}
 }
 
@@ -501,7 +487,6 @@ static void gen8_ppgtt_cleanup(struct i915_address_space 
*vm)
list_del(&vm->global_link);
drm_mm_takedown(&vm->mm);
 
-   gen8_ppgtt_dma_unmap_pages(ppgtt);
gen8_ppgtt_free(ppgtt);
 }
 
@@ -531,7 +516,7 @@ static int gen8_ppgtt_allocate_page_directories(struct 
i915_hw_ppgtt *ppgtt,
int i;
 
for (i = 0; i < max_pdp; i++) {
-   ppgtt->pdp.pagedir[i] = alloc_pd_single();
+   ppgtt->pdp.pagedir[i] = alloc_pd_single(ppgtt->base.dev);
if (IS_ERR(ppgtt->pdp.pagedir[i]))
goto unwind_out;
}
@@ -543,7 +528,8 @@ static int gen8_ppgtt_allocate_page_directories(struct 
i915_hw_ppgtt *ppgtt,
 
 unwind_out:
while (i--)
-   free_pd_single(ppgtt->pdp.pagedir[i]);
+   free_pd_single(ppgtt->pdp.pagedir[i],
+  ppgtt->base.dev);
 
return -ENOMEM;
 }
@@ -571,19 +557,6 @@ err_out:
return ret;
 }
 
-static int gen8_ppgtt_setup_page_directories(struct i915_hw_ppgtt *ppgtt,
-const int pdpe)
-{
-   int ret;
-
-   ret = i915_dma_map_px_single(ppgtt->pdp.pagedir[pdpe],
-ppgtt->base.dev);
-   if (ret)
-   return ret;
-
-   return 0;
-}
-
 /**
  * GEN8 legacy ppgtt programming is accomplished through a max 4 PDP registers
  * with a net effect resembling a 2-level page table in normal x86 terms. Each
@@ -609,16 +582,7 @@ static int gen8_ppgtt_init(struct i915_hw_ppgtt *ppgtt, 
uint64_t size)
return ret;
 
/*
-* 2. Create DMA mappings for the page directories and page tables.
-*/
-   for (i = 0; i < max_pdp; i++) {
-   ret = gen8_ppgtt_setup_page_directories(ppgtt, i);
-   if (ret)
-   goto bail;
-   }
-
-   /*
-* 3. Map all the page directory entires to point to the page tables
+* 2. Map all the page directory entires to point to the page tables
 * we've allocated.
 *
  

[Intel-gfx] [PATCH 00/26] [RFCish] GEN7 dynamic page tables

2014-03-17 Thread Ben Widawsky
These patches live here, based on my temporary Broadwell branch:
http://cgit.freedesktop.org/~bwidawsk/drm-intel/log/?h=dynamic_pt_alloc

First, and most importantly, this work should have no impact on current
drm-intel code because PPGTT is currently shut off there. To actually
test this patch series, one must re-enable PPGTT. On a single run of IGT
on IVB, it seem this doesn't introduce any regressions, but y'know, it's
PPGTT, so there's some instability, and it's hard to claim for certain
this doesn't break anything on top. Also, as stated below, the gen8 work
is only partially done.

Before I go too much further with this, I wanted to get eyes on it. I am
really open to any feedback. Before you do request a change though,
please realize that I've gone through several iterations of the
functions/interfaces. So please, spare me some pain and try to think
through what your request is before rattling it off. Daniel has
expressed to me already that he is unwilling to merge certain things
until PPGTT problems are fixed, and that can be enabled by default.
That's okay. In my opinion, many of the patches don't really have any
major behavioral changes, and only make the code so much more readable
and easy to deal with, that I believe merging it would only improve
PPGTT debugging in the future. There are several cleanups in the series
which could also go in relatively harmlessly.

Okay, so what does this do?
The patch series /dynamicizes/ page table allocation and teardown for
GEN7. It also starts to introduce GEN8, but the tricky stuff is still
not done. Up until now, all our page tables are pre-allocated when the
address space is created. That's actually okay for current GENs since we
don't use many address spaces, and the page tables occupy only 2MB each.
However, on GEN8 we can use a deeper page table, and to preallocate such
an address space would be very costly. This work was done for GEN7 first
because this is the most well tested with full PPGTT, and stable
platforms are readily available.

In this patch series, I've demonstrated how we will manage tracking used
page tables (bitmaps), and broken things out into much more discrete
functions. I'm hoping I'll get feedback on the way I've implemented
things (primarily if it seems fundamentally flawed in any way). The real
goal was to prove out the dynamic allocation so we can begin to enable
GEN8 in the same way. I'll emphasize now that I put in a lot of effort
limit risk with each patch, and this does result in some excess churn.

My next step is bring GEN8 up to par with GEN7. Once GEN8 is working,
and clean we can find where GEN7, and GEN8 overlap, and then recombine
where I haven't done so already. It's possible this plan will not work
out, and the above 2 steps will end up as one. After that, I plan to
merge the VA range allocation, and teardown into the insert/clear
entries (currently it's two steps). I think both of those steps should
be distinct.

On x86 code overlap:
I spent more time that I would have liked trying to conjoin our
pagetable management with x86 code. In the end I decided not to depend
on any of the x86 definitions (other than PAGE_SIZE) because I found the
maze of conditional compiles and defines a bit too cumbersome.  I also
didn't feel the abstract pagetable topology used in x86 code was
worthwhile given that with about 6 #defines, we achieve the same thing.
We just don't support nearly as many configurations, and our page table
format differs in too many places. One thing I had really considered,
and toyed around with was not having data structures to track the page
tables we've allocated and simply use the one that's in memory (which is
what x86 does). I was not able to make this work because of IOMMU. The
address we write into our page tables is an IOMMU address.  This means
we need to know, or be able to easily derive both the physical address
(or pfn, or struct page), and the DMA address. I failed to accomplish
this. I think using the bitmaps should be a fast way than having to kmap
the pagetables to determine their status anyway. And, one thing to keep
in mind is currently we don't have any GPU faulting capability. This
will greatly limit the ability to map things sparsely, which also will
greatly limit the effective virtual address space we can use.

Ben Widawsky (26):
  drm/i915: Split out verbose PPGTT dumping
  drm/i915: Extract switch to default context
  drm/i915: s/pd/pdpe, s/pt/pde
  drm/i915: rename map/unmap to dma_map/unmap
  drm/i915: Setup less PPGTT on failed pagedir
  drm/i915: Wrap VMA binding
  drm/i915: clean up PPGTT init error path
  drm/i915: Un-hardcode number of page directories
  drm/i915: Split out gtt specific header file
  drm/i915: Make gen6_write_pdes gen6_map_page_tables
  drm/i915: Range clearing is PPGTT agnostic
  drm/i915: Page table helpers, and define renames
  drm/i915: construct page table abstractions
  drm/i915: Complete page table structures
  drm/i915: Create page table allocators
  dr

[Intel-gfx] [PATCH 07/26] drm/i915: clean up PPGTT init error path

2014-03-17 Thread Ben Widawsky
The old code (I'm having trouble finding the commit) had a reason for
doing things when there was an error, and would continue on, thus the
!ret. For the newer code however, this looks completely silly.

Follow the normal idiom of if (ret) return ret.

Also, put the pde wiring in the gen specific init, now that GEN8 exists.

Signed-off-by: Ben Widawsky 
---
 drivers/gpu/drm/i915/i915_gem_gtt.c | 22 +-
 1 file changed, 9 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 1620211..5f73284 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -1202,6 +1202,8 @@ static int gen6_ppgtt_init(struct i915_hw_ppgtt *ppgtt)
ppgtt->pd_offset =
ppgtt->node.start / PAGE_SIZE * sizeof(gen6_gtt_pte_t);
 
+   gen6_write_pdes(ppgtt);
+
ppgtt->base.clear_range(&ppgtt->base, 0, ppgtt->base.total, true);
 
DRM_DEBUG_DRIVER("Allocated pde space (%ldM) at GTT entry: %lx\n",
@@ -1226,20 +1228,14 @@ int i915_gem_init_ppgtt(struct drm_device *dev, struct 
i915_hw_ppgtt *ppgtt)
else
BUG();
 
-   if (!ret) {
-   struct drm_i915_private *dev_priv = dev->dev_private;
-   kref_init(&ppgtt->ref);
-   drm_mm_init(&ppgtt->base.mm, ppgtt->base.start,
-   ppgtt->base.total);
-   i915_init_vm(dev_priv, &ppgtt->base);
-   if (INTEL_INFO(dev)->gen < 8) {
-   gen6_write_pdes(ppgtt);
-   DRM_DEBUG("Adding PPGTT at offset %x\n",
- ppgtt->pd_offset << 10);
-   }
-   }
+   if (ret)
+   return ret;
 
-   return ret;
+   kref_init(&ppgtt->ref);
+   drm_mm_init(&ppgtt->base.mm, ppgtt->base.start, ppgtt->base.total);
+   i915_init_vm(dev_priv, &ppgtt->base);
+
+   return 0;
 }
 
 static void
-- 
1.9.0

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 15/26] drm/i915: Create page table allocators

2014-03-17 Thread Ben Widawsky
As we move toward dynamic page table allocation, it becomes much easier
to manage our data structures if break do things less coarsely by
breaking up all of our actions into individual tasks.  This makes the
code easier to write, read, and verify.

Aside from the dissection of the allocation functions, the patch
statically allocates the page table structures without a page directory.
This remains the same for all platforms,

The patch itself should not have much functional difference. The primary
noticeable difference is the fact that page tables are no longer
allocated, but rather statically declared as part of the page directory.
This has non-zero overhead, but things gain non-trivial complexity as a
result.

Signed-off-by: Ben Widawsky 
---
 drivers/gpu/drm/i915/i915_gem_gtt.c | 226 +++-
 drivers/gpu/drm/i915/i915_gem_gtt.h |   4 +-
 2 files changed, 147 insertions(+), 83 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/i915_gem_gtt.c
index d91a545..5c08cf9 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -183,6 +183,102 @@ static gen6_gtt_pte_t iris_pte_encode(dma_addr_t addr,
return pte;
 }
 
+static void free_pt_single(struct i915_pagetab *pt)
+{
+   if (WARN_ON(!pt->page))
+   return;
+   __free_page(pt->page);
+   kfree(pt);
+}
+
+static struct i915_pagetab *alloc_pt_single(void)
+{
+   struct i915_pagetab *pt;
+
+   pt = kzalloc(sizeof(*pt), GFP_KERNEL);
+   if (!pt)
+   return ERR_PTR(-ENOMEM);
+
+   pt->page = alloc_page(GFP_KERNEL | __GFP_ZERO);
+   if (!pt->page) {
+   kfree(pt);
+   return ERR_PTR(-ENOMEM);
+   }
+
+   return pt;
+}
+
+/**
+ * alloc_pt_range() - Allocate a multiple page tables
+ * @pd:The page directory which will have at least @count 
entries
+ * available to point to the allocated page tables.
+ * @pde:   First page directory entry for which we are allocating.
+ * @count: Number of pages to allocate.
+ *
+ * Allocates multiple page table pages and sets the appropriate entries in the
+ * page table structure within the page directory. Function cleans up after
+ * itself on any failures.
+ *
+ * Return: 0 if allocation succeeded.
+ */
+static int alloc_pt_range(struct i915_pagedir *pd, uint16_t pde, size_t count)
+{
+   int i, ret;
+
+   /* 512 is the max page tables per pagedir on any platform.
+* TODO: make WARN after patch series is done
+*/
+   BUG_ON(pde + count > I915_PDES_PER_PD);
+
+   for (i = pde; i < pde + count; i++) {
+   struct i915_pagetab *pt = alloc_pt_single();
+   if (IS_ERR(pt)) {
+   ret = PTR_ERR(pt);
+   goto err_out;
+   }
+   WARN(pd->page_tables[i],
+"Leaking page directory entry %d (%pa)\n",
+i, pd->page_tables[i]);
+   pd->page_tables[i] = pt;
+   }
+
+   return 0;
+
+err_out:
+   while (i--)
+   free_pt_single(pd->page_tables[i]);
+   return ret;
+}
+
+static void __free_pd_single(struct i915_pagedir *pd)
+{
+   __free_page(pd->page);
+   kfree(pd);
+}
+
+#define free_pd_single(pd) do { \
+   if ((pd)->page) { \
+   __free_pd_single(pd); \
+   } \
+} while (0)
+
+static struct i915_pagedir *alloc_pd_single(void)
+{
+   struct i915_pagedir *pd;
+
+   pd = kzalloc(sizeof(*pd), GFP_KERNEL);
+   if (!pd)
+   return ERR_PTR(-ENOMEM);
+
+   pd->page = alloc_page(GFP_KERNEL | __GFP_ZERO);
+   if (!pd->page) {
+   kfree(pd);
+   return ERR_PTR(-ENOMEM);
+   }
+
+   return pd;
+}
+
 /* Broadwell Page Directory Pointer Descriptors */
 static int gen8_write_pdp(struct intel_ring_buffer *ring, unsigned entry,
   uint64_t val, bool synchronous)
@@ -223,7 +319,7 @@ static int gen8_mm_switch(struct i915_hw_ppgtt *ppgtt,
int used_pd = ppgtt->num_pd_entries / I915_PDES_PER_PD;
 
for (i = used_pd - 1; i >= 0; i--) {
-   dma_addr_t addr = ppgtt->pdp.pagedir[i].daddr;
+   dma_addr_t addr = ppgtt->pdp.pagedir[i]->daddr;
ret = gen8_write_pdp(ring, i, addr, synchronous);
if (ret)
return ret;
@@ -250,8 +346,9 @@ static void gen8_ppgtt_clear_range(struct 
i915_address_space *vm,
  I915_CACHE_LLC, use_scratch);
 
while (num_entries) {
-   struct i915_pagedir *pd = &ppgtt->pdp.pagedir[pdpe];
-   struct page *page_table = pd->page_tables[pde].page;
+   struct i915_pagedir *pd = ppgtt->pdp.pagedir[pdpe];
+   struct i915_pagetab *pt = pd->page_tables[pde];
+   struct page *page_table = pt->page;
 
last_pte = pte 

[Intel-gfx] [PATCH 12/26] drm/i915: Page table helpers, and define renames

2014-03-17 Thread Ben Widawsky
These page table helpers make the code much cleaner. There is some
room to use the arch/x86 header files. The reason I've opted not to is
in several cases, the definitions are dictated by the CONFIG_ options
which do not always indicate the restrictions in the GPU. While here,
clean up the defines to have more concise names, and consolidate between
gen6 and gen8 where appropriate.

I've made a lot of tiny errors in these helpers. Often I'd correct an
error only to introduce another one. While IGT was capable of catching
them, the tests often took a while to catch, and where hard/slow to
debug in the kernel. As a result, to test this, I compiled
i915_gem_gtt.h in userspace, and ran tests from userspace. What follows
isn't by any means complete, but it was able to catch lot of bugs. Gen8
is also untested, but since the current code is almost identical, I feel
pretty comfortable with that.

void test_pte(uint32_t base) {
uint32_t ret;
assert_pte_index((base + 0), 0);
assert_pte_index((base + 1), 0);
assert_pte_index((base + 0x1000), 1);
assert_pte_index((base + (1<<22)), 0);
assert_pte_index((base + ((1<<22) - 1)), 1023);
assert_pte_index((base + (1<<21)), 512);

assert_pte_count(base + 0, 0, 0);
assert_pte_count(base + 0, 1, 1);
assert_pte_count(base + 0, 0x1000, 1);
assert_pte_count(base + 0, 0x1001, 2);
assert_pte_count(base + 0, 1<<21, 512);

assert_pte_count(base + 0, 1<<22, 1024);
assert_pte_count(base + 0, (1<<22) - 1, 1024);
assert_pte_count(base + (1<<21), 1<<22, 512);
assert_pte_count(base + (1<<21), (1<<22)+1, 512);
assert_pte_count(base + (1<<21), 10<<22, 512);
}

void test_pde(uint32_t base) {
assert(gen6_pde_index(base + 0) == 0);
assert(gen6_pde_index(base + 1) == 0);
assert(gen6_pde_index(base + (1<<21)) == 0);
assert(gen6_pde_index(base + (1<<22)) == 1);
assert(gen6_pde_index(base + ((256<<22)))== 256);
assert(gen6_pde_index(base + ((512<<22))) == 0);
assert(gen6_pde_index(base + ((513<<22))) == 1); /* This is
actually not possible on gen6 */

assert(gen6_pde_count(base + 0, 0) == 0);
assert(gen6_pde_count(base + 0, 1) == 1);
assert(gen6_pde_count(base + 0, 1<<21) == 1);
assert(gen6_pde_count(base + 0, 1<<22) == 1);
assert(gen6_pde_count(base + 0, (1<<22) + 0x1000) == 2);
assert(gen6_pde_count(base + 0x1000, 1<<22) == 2);
assert(gen6_pde_count(base + 0, 511<<22) == 511);
assert(gen6_pde_count(base + 0, 512<<22) == 512);
assert(gen6_pde_count(base + 0x1000, 512<<22) == 512);
assert(gen6_pde_count(base + (1<<22), 512<<22) == 511);
}

int main()
{
test_pde(0);
while (1)
test_pte(rand() & ~((1<<22) - 1));

return 0;
}

Signed-off-by: Ben Widawsky 
---
 drivers/gpu/drm/i915/i915_gem_gtt.c |  90 +-
 drivers/gpu/drm/i915/i915_gem_gtt.h | 125 ++--
 2 files changed, 162 insertions(+), 53 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 77556ac..7afa5f4 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -220,7 +220,7 @@ static int gen8_mm_switch(struct i915_hw_ppgtt *ppgtt,
int i, ret;
 
/* bit of a hack to find the actual last used pd */
-   int used_pd = ppgtt->num_pd_entries / GEN8_PDES_PER_PAGE;
+   int used_pd = ppgtt->num_pd_entries / I915_PDES_PER_PD;
 
for (i = used_pd - 1; i >= 0; i--) {
dma_addr_t addr = ppgtt->pd_dma_addr[i];
@@ -240,9 +240,9 @@ static void gen8_ppgtt_clear_range(struct 
i915_address_space *vm,
struct i915_hw_ppgtt *ppgtt =
container_of(vm, struct i915_hw_ppgtt, base);
gen8_gtt_pte_t *pt_vaddr, scratch_pte;
-   unsigned pdpe = start >> GEN8_PDPE_SHIFT & GEN8_PDPE_MASK;
-   unsigned pde = start >> GEN8_PDE_SHIFT & GEN8_PDE_MASK;
-   unsigned pte = start >> GEN8_PTE_SHIFT & GEN8_PTE_MASK;
+   unsigned pdpe = gen8_pdpe_index(start);
+   unsigned pde = gen8_pde_index(start);
+   unsigned pte = gen8_pte_index(start);
unsigned num_entries = length >> PAGE_SHIFT;
unsigned last_pte, i;
 
@@ -253,8 +253,8 @@ static void gen8_ppgtt_clear_range(struct 
i915_address_space *vm,
struct page *page_table = ppgtt->gen8_pt_pages[pdpe][pde];
 
last_pte = pte + num_entries;
-   if (last_pte > GEN8_PTES_PER_PAGE)
-   last_pte = GEN8_PTES_PER_PAGE;
+   if (last_pte > GEN8_PTES_PER_PT)
+   last_pte = GEN8_PTES_PER_PT;
 
pt_vaddr = kmap_atomic(page_table);
 
@@ -266,7 +266,7 @@ static void gen8_ppgtt_clear_range(struct 
i915_address_space *vm,
kunmap_atomic(pt_vaddr);
 
pte = 0;

[Intel-gfx] [PATCH 13/26] drm/i915: construct page table abstractions

2014-03-17 Thread Ben Widawsky
Thus far we've opted to make complex code requiring difficult review. In
the future, the code is only going to become more complex, and as such
we'll take the hit now and start to encapsulate things.

To help transition the code nicely there is some wasted space in gen6/7.
This will be ameliorated shortly.

NOTE: The pun in the subject was intentional.

Signed-off-by: Ben Widawsky 

Conflicts:
drivers/gpu/drm/i915/i915_drv.h
---
 drivers/gpu/drm/i915/i915_gem_gtt.c | 175 ++--
 drivers/gpu/drm/i915/i915_gem_gtt.h |  24 +++--
 2 files changed, 104 insertions(+), 95 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 7afa5f4..5b283f2 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -250,7 +250,8 @@ static void gen8_ppgtt_clear_range(struct 
i915_address_space *vm,
  I915_CACHE_LLC, use_scratch);
 
while (num_entries) {
-   struct page *page_table = ppgtt->gen8_pt_pages[pdpe][pde];
+   struct i915_pagedir *pd = &ppgtt->pdp.pagedir[pdpe];
+   struct page *page_table = pd->page_tables[pde].page;
 
last_pte = pte + num_entries;
if (last_pte > GEN8_PTES_PER_PT)
@@ -292,8 +293,11 @@ static void gen8_ppgtt_insert_entries(struct 
i915_address_space *vm,
if (WARN_ON(pdpe >= GEN8_LEGACY_PDPS))
break;
 
-   if (pt_vaddr == NULL)
-   pt_vaddr = kmap_atomic(ppgtt->gen8_pt_pages[pdpe][pde]);
+   if (pt_vaddr == NULL) {
+   struct i915_pagedir *pd = &ppgtt->pdp.pagedir[pdpe];
+   struct page *page_table = pd->page_tables[pde].page;
+   pt_vaddr = kmap_atomic(page_table);
+   }
 
pt_vaddr[pte] =
gen8_pte_encode(sg_page_iter_dma_address(&sg_iter),
@@ -312,29 +316,33 @@ static void gen8_ppgtt_insert_entries(struct 
i915_address_space *vm,
kunmap_atomic(pt_vaddr);
 }
 
-static void gen8_free_page_tables(struct page **pt_pages)
+static void gen8_free_page_tables(struct i915_pagedir *pd)
 {
int i;
 
-   if (pt_pages == NULL)
+   if (pd->page_tables == NULL)
return;
 
for (i = 0; i < I915_PDES_PER_PD; i++)
-   if (pt_pages[i])
-   __free_pages(pt_pages[i], 0);
+   if (pd->page_tables[i].page)
+   __free_page(pd->page_tables[i].page);
+}
+
+static void gen8_free_page_directories(struct i915_pagedir *pd)
+{
+   kfree(pd->page_tables);
+   __free_page(pd->page);
 }
 
-static void gen8_ppgtt_free(const struct i915_hw_ppgtt *ppgtt)
+static void gen8_ppgtt_free(struct i915_hw_ppgtt *ppgtt)
 {
int i;
 
for (i = 0; i < ppgtt->num_pd_pages; i++) {
-   gen8_free_page_tables(ppgtt->gen8_pt_pages[i]);
-   kfree(ppgtt->gen8_pt_pages[i]);
+   gen8_free_page_tables(&ppgtt->pdp.pagedir[i]);
+   gen8_free_page_directories(&ppgtt->pdp.pagedir[i]);
kfree(ppgtt->gen8_pt_dma_addr[i]);
}
-
-   __free_pages(ppgtt->pd_pages, get_order(ppgtt->num_pd_pages << 
PAGE_SHIFT));
 }
 
 static void gen8_ppgtt_dma_unmap_pages(struct i915_hw_ppgtt *ppgtt)
@@ -372,87 +380,73 @@ static void gen8_ppgtt_cleanup(struct i915_address_space 
*vm)
gen8_ppgtt_free(ppgtt);
 }
 
-static struct page **__gen8_alloc_page_tables(void)
+static int gen8_ppgtt_allocate_dma(struct i915_hw_ppgtt *ppgtt)
 {
-   struct page **pt_pages;
int i;
 
-   pt_pages = kcalloc(I915_PDES_PER_PD, sizeof(struct page *), GFP_KERNEL);
-   if (!pt_pages)
-   return ERR_PTR(-ENOMEM);
-
-   for (i = 0; i < I915_PDES_PER_PD; i++) {
-   pt_pages[i] = alloc_page(GFP_KERNEL | __GFP_ZERO);
-   if (!pt_pages[i])
-   goto bail;
+   for (i = 0; i < ppgtt->num_pd_pages; i++) {
+   ppgtt->gen8_pt_dma_addr[i] = kcalloc(I915_PDES_PER_PD,
+sizeof(dma_addr_t),
+GFP_KERNEL);
+   if (!ppgtt->gen8_pt_dma_addr[i])
+   return -ENOMEM;
}
 
-   return pt_pages;
-
-bail:
-   gen8_free_page_tables(pt_pages);
-   kfree(pt_pages);
-   return ERR_PTR(-ENOMEM);
+   return 0;
 }
 
-static int gen8_ppgtt_allocate_page_tables(struct i915_hw_ppgtt *ppgtt,
-  const int max_pdp)
+static int gen8_ppgtt_allocate_page_tables(struct i915_hw_ppgtt *ppgtt)
 {
-   struct page **pt_pages[GEN8_LEGACY_PDPS];
-   int i, ret;
+   int i, j;
 
-   for (i = 0; i < max_pdp; i++) {
-   pt_pages[i] = __gen8_alloc_page_tables();
-   if (IS_ERR(pt_pages[i])) {

[Intel-gfx] [PATCH 06/26] drm/i915: Wrap VMA binding

2014-03-17 Thread Ben Widawsky
This will be useful for some upcoming patches which do more platform
specific work. Having it in one central place just makes things a bit
cleaner and easier.

There is a small functional change here. There are more calls to the
tracepoints.

NOTE: I didn't actually end up using this patch for the intended purpose, but I
thought it was a nice patch to keep around.

Signed-off-by: Ben Widawsky 
---
 drivers/gpu/drm/i915/i915_drv.h|  3 +++
 drivers/gpu/drm/i915/i915_gem.c|  8 
 drivers/gpu/drm/i915/i915_gem_context.c|  2 +-
 drivers/gpu/drm/i915/i915_gem_execbuffer.c |  5 +++--
 drivers/gpu/drm/i915/i915_gem_gtt.c| 16 ++--
 5 files changed, 25 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index c59b707..b3e31fd 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2408,6 +2408,9 @@ bool i915_gem_obj_bound(struct drm_i915_gem_object *o,
struct i915_address_space *vm);
 unsigned long i915_gem_obj_size(struct drm_i915_gem_object *o,
struct i915_address_space *vm);
+void i915_gem_bind_vma(struct i915_vma *vma, enum i915_cache_level,
+  unsigned flags);
+void i915_gem_unbind_vma(struct i915_vma *vma);
 struct i915_vma *i915_gem_obj_to_vma(struct drm_i915_gem_object *obj,
 struct i915_address_space *vm);
 struct i915_vma *
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index ed09dda..0a3f4ac 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -2765,7 +2765,7 @@ int i915_vma_unbind(struct i915_vma *vma)
 
trace_i915_vma_unbind(vma);
 
-   vma->unbind_vma(vma);
+   i915_gem_unbind_vma(vma);
 
i915_gem_gtt_finish_object(obj);
 
@@ -3514,8 +3514,8 @@ int i915_gem_object_set_cache_level(struct 
drm_i915_gem_object *obj,
 
list_for_each_entry(vma, &obj->vma_list, vma_link)
if (drm_mm_node_allocated(&vma->node))
-   vma->bind_vma(vma, cache_level,
- obj->has_global_gtt_mapping ? 
GLOBAL_BIND : 0);
+   i915_gem_bind_vma(vma, cache_level,
+ obj->has_global_gtt_mapping ? 
GLOBAL_BIND : 0);
}
 
list_for_each_entry(vma, &obj->vma_list, vma_link)
@@ -3878,7 +3878,7 @@ i915_gem_object_pin(struct drm_i915_gem_object *obj,
}
 
if (flags & PIN_GLOBAL && !obj->has_global_gtt_mapping)
-   vma->bind_vma(vma, obj->cache_level, GLOBAL_BIND);
+   i915_gem_bind_vma(vma, obj->cache_level, GLOBAL_BIND);
 
vma->pin_count++;
if (flags & PIN_MAPPABLE)
diff --git a/drivers/gpu/drm/i915/i915_gem_context.c 
b/drivers/gpu/drm/i915/i915_gem_context.c
index 7dfdc02..f918f2c 100644
--- a/drivers/gpu/drm/i915/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/i915_gem_context.c
@@ -693,7 +693,7 @@ static int do_switch(struct intel_ring_buffer *ring,
if (!to->obj->has_global_gtt_mapping) {
struct i915_vma *vma = i915_gem_obj_to_vma(to->obj,
   &dev_priv->gtt.base);
-   vma->bind_vma(vma, to->obj->cache_level, GLOBAL_BIND);
+   i915_gem_bind_vma(vma, to->obj->cache_level, GLOBAL_BIND);
}
 
if (!to->is_initialized || i915_gem_context_is_default(to))
diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c 
b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
index 3851a1b..856fa9d 100644
--- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
@@ -369,7 +369,8 @@ i915_gem_execbuffer_relocate_entry(struct 
drm_i915_gem_object *obj,
struct i915_vma *vma =
list_first_entry(&target_i915_obj->vma_list,
 typeof(*vma), vma_link);
-   vma->bind_vma(vma, target_i915_obj->cache_level, GLOBAL_BIND);
+   i915_gem_bind_vma(vma, target_i915_obj->cache_level,
+ GLOBAL_BIND);
}
 
/* Validate that the target is in a valid r/w GPU domain */
@@ -1209,7 +1210,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
 * allocate space first */
struct i915_vma *vma = i915_gem_obj_to_ggtt(batch_obj);
BUG_ON(!vma);
-   vma->bind_vma(vma, batch_obj->cache_level, GLOBAL_BIND);
+   i915_gem_bind_vma(vma, batch_obj->cache_level, GLOBAL_BIND);
}
 
if (flags & I915_DISPATCH_SECURE)
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 09556d1..1620211 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -1370,10 +1

[Intel-gfx] [PATCH 02/26] drm/i915: Extract switch to default context

2014-03-17 Thread Ben Widawsky
This patch existed for another reason which no longer exists. I liked
it, so I kept it in the series. It can skipped if undesirable.

Signed-off-by: Ben Widawsky 
---
 drivers/gpu/drm/i915/i915_drv.h | 2 ++
 drivers/gpu/drm/i915/i915_gem.c | 2 +-
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 35f9a37..c59b707 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2476,6 +2476,8 @@ int i915_gem_context_enable(struct drm_i915_private 
*dev_priv);
 void i915_gem_context_close(struct drm_device *dev, struct drm_file *file);
 int i915_switch_context(struct intel_ring_buffer *ring,
struct drm_file *file, struct i915_hw_context *to);
+#define i915_switch_to_default(ring) \
+   i915_switch_context(ring, NULL, ring->default_context)
 struct i915_hw_context *
 i915_gem_context_get(struct drm_i915_file_private *file_priv, u32 id);
 void i915_gem_context_free(struct kref *ctx_ref);
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index b2565d2..ed09dda 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -2799,7 +2799,7 @@ int i915_gpu_idle(struct drm_device *dev)
 
/* Flush everything onto the inactive list. */
for_each_ring(ring, dev_priv, i) {
-   ret = i915_switch_context(ring, NULL, ring->default_context);
+   ret = i915_switch_to_default(ring);
if (ret)
return ret;
 
-- 
1.9.0

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 08/26] drm/i915: Un-hardcode number of page directories

2014-03-17 Thread Ben Widawsky
trivial.

Signed-off-by: Ben Widawsky 
---
 drivers/gpu/drm/i915/i915_drv.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index b3e31fd..084e82f 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -722,7 +722,7 @@ struct i915_hw_ppgtt {
};
union {
dma_addr_t *pt_dma_addr;
-   dma_addr_t *gen8_pt_dma_addr[4];
+   dma_addr_t *gen8_pt_dma_addr[GEN8_LEGACY_PDPS];
};
 
int (*enable)(struct i915_hw_ppgtt *ppgtt);
-- 
1.9.0

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 01/26] drm/i915: Split out verbose PPGTT dumping

2014-03-17 Thread Ben Widawsky
There often is not enough memory to dump the full contents of the PPGTT.
As a temporary bandage, to continue getting valuable basic PPGTT info,
wrap the dangerous, memory hungry part inside of a new verbose version
of the debugfs file.

Also while here we can split out the ppgtt print function so it's more
reusable.

I'd really like to get ppgtt info into our error state, but I found it too
difficult to make work in the limited time I have. Maybe Mika can find a way.

Cc: Mika Kuoppala 
Signed-off-by: Ben Widawsky 
---
 drivers/gpu/drm/i915/i915_debugfs.c | 28 ++--
 1 file changed, 18 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c 
b/drivers/gpu/drm/i915/i915_debugfs.c
index 1031c43..b226788 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -1760,7 +1760,7 @@ static int per_file_ctx(int id, void *ptr, void *data)
return 0;
 }
 
-static void gen8_ppgtt_info(struct seq_file *m, struct drm_device *dev)
+static void gen8_ppgtt_info(struct seq_file *m, struct drm_device *dev, int 
verbose)
 {
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_ring_buffer *ring;
@@ -1785,7 +1785,13 @@ static void gen8_ppgtt_info(struct seq_file *m, struct 
drm_device *dev)
}
 }
 
-static void gen6_ppgtt_info(struct seq_file *m, struct drm_device *dev)
+static void print_ppgtt(struct seq_file *m, struct i915_hw_ppgtt *ppgtt, const 
char *name)
+{
+   seq_printf(m, "%s:\n", name);
+   seq_printf(m, "pd gtt offset: 0x%08x\n", ppgtt->pd_offset);
+}
+
+static void gen6_ppgtt_info(struct seq_file *m, struct drm_device *dev, bool 
verbose)
 {
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_ring_buffer *ring;
@@ -1806,10 +1812,9 @@ static void gen6_ppgtt_info(struct seq_file *m, struct 
drm_device *dev)
if (dev_priv->mm.aliasing_ppgtt) {
struct i915_hw_ppgtt *ppgtt = dev_priv->mm.aliasing_ppgtt;
 
-   seq_puts(m, "aliasing PPGTT:\n");
-   seq_printf(m, "pd gtt offset: 0x%08x\n", ppgtt->pd_offset);
-
-   ppgtt->debug_dump(ppgtt, m);
+   print_ppgtt(m, ppgtt, "Aliasing PPGTT");
+   if (verbose)
+   ppgtt->debug_dump(ppgtt, m);
} else
return;
 
@@ -1820,8 +1825,9 @@ static void gen6_ppgtt_info(struct seq_file *m, struct 
drm_device *dev)
pvt_ppgtt = ctx_to_ppgtt(file_priv->private_default_ctx);
seq_printf(m, "proc: %s\n",
   get_pid_task(file->pid, PIDTYPE_PID)->comm);
-   seq_puts(m, "  default context:\n");
-   idr_for_each(&file_priv->context_idr, per_file_ctx, m);
+   print_ppgtt(m, pvt_ppgtt, "Default context");
+   if (verbose)
+   idr_for_each(&file_priv->context_idr, per_file_ctx, m);
}
seq_printf(m, "ECOCHK: 0x%08x\n", I915_READ(GAM_ECOCHK));
 }
@@ -1831,6 +1837,7 @@ static int i915_ppgtt_info(struct seq_file *m, void *data)
struct drm_info_node *node = (struct drm_info_node *) m->private;
struct drm_device *dev = node->minor->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
+   bool verbose = node->info_ent->data ? true : false;
 
int ret = mutex_lock_interruptible(&dev->struct_mutex);
if (ret)
@@ -1838,9 +1845,9 @@ static int i915_ppgtt_info(struct seq_file *m, void *data)
intel_runtime_pm_get(dev_priv);
 
if (INTEL_INFO(dev)->gen >= 8)
-   gen8_ppgtt_info(m, dev);
+   gen8_ppgtt_info(m, dev, verbose);
else if (INTEL_INFO(dev)->gen >= 6)
-   gen6_ppgtt_info(m, dev);
+   gen6_ppgtt_info(m, dev, verbose);
 
intel_runtime_pm_put(dev_priv);
mutex_unlock(&dev->struct_mutex);
@@ -3826,6 +3833,7 @@ static const struct drm_info_list i915_debugfs_list[] = {
{"i915_gen6_forcewake_count", i915_gen6_forcewake_count_info, 0},
{"i915_swizzle_info", i915_swizzle_info, 0},
{"i915_ppgtt_info", i915_ppgtt_info, 0},
+   {"i915_ppgtt_verbose_info", i915_ppgtt_info, 0, (void *)1},
{"i915_dpio", i915_dpio_info, 0},
{"i915_llc", i915_llc, 0},
{"i915_edp_psr_status", i915_edp_psr_status, 0},
-- 
1.9.0

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 11/26] drm/i915: Range clearing is PPGTT agnostic

2014-03-17 Thread Ben Widawsky
Therefore we can do it from our general init function. Eventually, I
hope to have a lot more commonality like this. It won't arrive yet, but
this was a nice easy one.

Signed-off-by: Ben Widawsky 
---
 drivers/gpu/drm/i915/i915_gem_gtt.c | 5 +
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/i915_gem_gtt.c
index d89054d..77556ac 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -584,8 +584,6 @@ static int gen8_ppgtt_init(struct i915_hw_ppgtt *ppgtt, 
uint64_t size)
ppgtt->base.start = 0;
ppgtt->base.total = ppgtt->num_pd_entries * GEN8_PTES_PER_PAGE * 
PAGE_SIZE;
 
-   ppgtt->base.clear_range(&ppgtt->base, 0, ppgtt->base.total, true);
-
DRM_DEBUG_DRIVER("Allocated %d pages for page directories (%d 
wasted)\n",
 ppgtt->num_pd_pages, ppgtt->num_pd_pages - max_pdp);
DRM_DEBUG_DRIVER("Allocated %d pages for page tables (%lld wasted)\n",
@@ -1154,8 +1152,6 @@ static int gen6_ppgtt_init(struct i915_hw_ppgtt *ppgtt)
 
gen6_map_page_tables(ppgtt);
 
-   ppgtt->base.clear_range(&ppgtt->base, 0, ppgtt->base.total, true);
-
DRM_DEBUG_DRIVER("Allocated pde space (%ldM) at GTT entry: %lx\n",
 ppgtt->node.size >> 20,
 ppgtt->node.start / PAGE_SIZE);
@@ -1183,6 +1179,7 @@ int i915_gem_init_ppgtt(struct drm_device *dev, struct 
i915_hw_ppgtt *ppgtt)
 
kref_init(&ppgtt->ref);
drm_mm_init(&ppgtt->base.mm, ppgtt->base.start, ppgtt->base.total);
+   ppgtt->base.clear_range(&ppgtt->base, 0, ppgtt->base.total, true);
i915_init_vm(dev_priv, &ppgtt->base);
 
return 0;
-- 
1.9.0

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH] prime_mmap: Add new test for calling mmap() on dma-buf fds

2014-03-17 Thread Rob Bradford
From: Rob Bradford 

This test has the following subtests:
- test_correct for correctness of the data
- test_map_unmap checks for mapping idempotency
- test_reprime checks for dma-buf creation idempotency
- test_forked checks for multiprocess access
- test_refcounting checks for buffer reference counting
- test_dup chats that dup()ing the fd works
- test_errors checks the error return values for failures
- test_aperture_limit tests multiple buffer creation at the gtt aperture
  limit

Signed-off-by: Rob Bradford 
---
 tests/Makefile.sources |   1 +
 tests/prime_mmap.c | 384 +
 2 files changed, 385 insertions(+)
 create mode 100644 tests/prime_mmap.c

diff --git a/tests/Makefile.sources b/tests/Makefile.sources
index 88866ac..d666381 100644
--- a/tests/Makefile.sources
+++ b/tests/Makefile.sources
@@ -65,6 +65,7 @@ TESTS_progs_M = \
pm_lpsp \
pm_pc8 \
pm_rps \
+   prime_mmap \
prime_self_import \
template \
$(NULL)
diff --git a/tests/prime_mmap.c b/tests/prime_mmap.c
new file mode 100644
index 000..94ba191
--- /dev/null
+++ b/tests/prime_mmap.c
@@ -0,0 +1,384 @@
+
+/*
+ * Copyright © 2014 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ *Rob Bradford 
+ *
+ */
+
+/*
+ * Testcase: Check whether mmap()ing dma-buf works
+ */
+#define _GNU_SOURCE
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "drm.h"
+#include "i915_drm.h"
+#include "drmtest.h"
+#include "igt_debugfs.h"
+#include "ioctl_wrappers.h"
+
+#define BO_SIZE (16*1024)
+
+static int fd;
+
+char pattern[] = {0xff, 0x00, 0x00, 0x00,
+ 0x00, 0xff, 0x00, 0x00,
+ 0x00, 0x00, 0xff, 0x00,
+ 0x00, 0x00, 0x00, 0xff};
+
+static void
+fill_bo(uint32_t handle, size_t size)
+{
+   off_t i;
+   for (i = 0; i < size; i+=sizeof(pattern))
+   {
+   gem_write(fd, handle, i, pattern, sizeof(pattern));
+   }
+}
+
+static int
+pattern_check(char *ptr, size_t size)
+{
+   off_t i;
+   for (i = 0; i < size; i+=sizeof(pattern))
+   {
+   if (memcmp(ptr, pattern, sizeof(pattern)) != 0)
+   return 1;
+   }
+
+   return 0;
+}
+
+static void
+test_correct(void)
+{
+   int dma_buf_fd;
+   char *ptr1, *ptr2;
+   uint32_t handle;
+
+   handle = gem_create(fd, BO_SIZE);
+   fill_bo(handle, BO_SIZE);
+
+   dma_buf_fd = prime_handle_to_fd(fd, handle);
+   igt_assert(errno == 0);
+
+   /* Check correctness vs GEM_MMAP_GTT */
+   ptr1 = gem_mmap(fd, handle, BO_SIZE, PROT_READ | PROT_WRITE);
+   ptr2 = mmap(NULL, BO_SIZE, PROT_READ, MAP_SHARED, dma_buf_fd, 0);
+   igt_assert(ptr1 != MAP_FAILED);
+   igt_assert(ptr2 != MAP_FAILED);
+   igt_assert(memcmp(ptr1, ptr2, BO_SIZE) == 0);
+
+   /* Check pattern correctness */
+   igt_assert(pattern_check(ptr2, BO_SIZE) == 0);
+
+   munmap(ptr1, BO_SIZE);
+   munmap(ptr2, BO_SIZE);
+   close(dma_buf_fd);
+   gem_close(fd, handle);
+}
+
+static void
+test_map_unmap(void)
+{
+   int dma_buf_fd;
+   char *ptr;
+   uint32_t handle;
+
+   handle = gem_create(fd, BO_SIZE);
+   fill_bo(handle, BO_SIZE);
+
+   dma_buf_fd = prime_handle_to_fd(fd, handle);
+   igt_assert(errno == 0);
+
+   ptr = mmap(NULL, BO_SIZE, PROT_READ, MAP_SHARED, dma_buf_fd, 0);
+   igt_assert(ptr != MAP_FAILED);
+   igt_assert(pattern_check(ptr, BO_SIZE) == 0);
+
+   /* Unmap and remap */
+   munmap(ptr, BO_SIZE);
+   ptr = mmap(NULL, BO_SIZE, PROT_READ, MAP_SHARED, dma_buf_fd, 0);
+   igt_assert(ptr != MAP_FAILED);
+   igt_assert(pattern_check(ptr, BO_SIZE) == 0);
+
+   munmap(ptr, BO_SIZE);
+   close(dma_buf_fd);
+   gem_close(fd, h

[Intel-gfx] [PATCH] drm/i915: Rename intel_setup_wm_latency() to ilk_setup_wm_latency()

2014-03-17 Thread Damien Lespiau
This function is only used on ILK+, so rename it accordingly.

Signed-off-by: Damien Lespiau 
---
 drivers/gpu/drm/i915/intel_pm.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 6dbaf66..47bf433 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -2085,7 +2085,7 @@ static void intel_print_wm_latency(struct drm_device *dev,
}
 }
 
-static void intel_setup_wm_latency(struct drm_device *dev)
+static void ilk_setup_wm_latency(struct drm_device *dev)
 {
struct drm_i915_private *dev_priv = dev->dev_private;
 
@@ -5990,7 +5990,7 @@ void intel_init_pm(struct drm_device *dev)
 
/* For FIFO watermark updates */
if (HAS_PCH_SPLIT(dev)) {
-   intel_setup_wm_latency(dev);
+   ilk_setup_wm_latency(dev);
 
if ((IS_GEN5(dev) && dev_priv->wm.pri_latency[1] &&
 dev_priv->wm.spr_latency[1] && 
dev_priv->wm.cur_latency[1]) ||
-- 
1.8.3.1

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH] drm/i915: Remove spurious '()' in WARN macros

2014-03-17 Thread Damien Lespiau
No need of any here.

Signed-off-by: Damien Lespiau 
---
 drivers/gpu/drm/i915/intel_display.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index d34add5..c6743f0 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -1166,7 +1166,7 @@ static void assert_planes_disabled(struct 
drm_i915_private *dev_priv,
if (INTEL_INFO(dev)->gen >= 4) {
reg = DSPCNTR(pipe);
val = I915_READ(reg);
-   WARN((val & DISPLAY_PLANE_ENABLE),
+   WARN(val & DISPLAY_PLANE_ENABLE,
 "plane %c assertion failure, should be disabled but not\n",
 plane_name(pipe));
return;
@@ -1195,20 +1195,20 @@ static void assert_sprites_disabled(struct 
drm_i915_private *dev_priv,
for_each_sprite(pipe, sprite) {
reg = SPCNTR(pipe, sprite);
val = I915_READ(reg);
-   WARN((val & SP_ENABLE),
+   WARN(val & SP_ENABLE,
 "sprite %c assertion failure, should be off on 
pipe %c but is still active\n",
 sprite_name(pipe, sprite), pipe_name(pipe));
}
} else if (INTEL_INFO(dev)->gen >= 7) {
reg = SPRCTL(pipe);
val = I915_READ(reg);
-   WARN((val & SPRITE_ENABLE),
+   WARN(val & SPRITE_ENABLE,
 "sprite %c assertion failure, should be off on pipe %c but 
is still active\n",
 plane_name(pipe), pipe_name(pipe));
} else if (INTEL_INFO(dev)->gen >= 5) {
reg = DVSCNTR(pipe);
val = I915_READ(reg);
-   WARN((val & DVS_ENABLE),
+   WARN(val & DVS_ENABLE,
 "sprite %c assertion failure, should be off on pipe %c but 
is still active\n",
 plane_name(pipe), pipe_name(pipe));
}
-- 
1.8.3.1

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH] drm/i915: Give the sprite width to the WM computation

2014-03-17 Thread Damien Lespiau
In the future, we'll need the height of the fb we're fetching from
memory for WM computation.

At some point in the future, it'd be nice to give a pointer to a
mystical plane_config structure instead of chaplet of parameters.

Signed-off-by: Damien Lespiau 
---
 drivers/gpu/drm/i915/i915_drv.h |  4 ++--
 drivers/gpu/drm/i915/intel_drv.h|  5 -
 drivers/gpu/drm/i915/intel_pm.c | 17 +++--
 drivers/gpu/drm/i915/intel_sprite.c | 15 +--
 4 files changed, 26 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 70fbe90..057873e 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -438,8 +438,8 @@ struct drm_i915_display_funcs {
void (*update_wm)(struct drm_crtc *crtc);
void (*update_sprite_wm)(struct drm_plane *plane,
 struct drm_crtc *crtc,
-uint32_t sprite_width, int pixel_size,
-bool enable, bool scaled);
+uint32_t sprite_width, uint32_t sprite_height,
+int pixel_size, bool enable, bool scaled);
void (*modeset_global_resources)(struct drm_device *dev);
/* Returns the active state of the crtc, and if the crtc is active,
 * fills out the pipe-config with the hw state. */
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index e0064a1..8e6f971 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -392,6 +392,7 @@ struct intel_crtc {
 
 struct intel_plane_wm_parameters {
uint32_t horiz_pixels;
+   uint32_t vert_pixels;
uint8_t bytes_per_pixel;
bool enabled;
bool scaled;
@@ -873,7 +874,9 @@ void intel_suspend_hw(struct drm_device *dev);
 void intel_update_watermarks(struct drm_crtc *crtc);
 void intel_update_sprite_watermarks(struct drm_plane *plane,
struct drm_crtc *crtc,
-   uint32_t sprite_width, int pixel_size,
+   uint32_t sprite_width,
+   uint32_t sprite_height,
+   int pixel_size,
bool enabled, bool scaled);
 void intel_init_pm(struct drm_device *dev);
 void intel_pm_setup(struct drm_device *dev);
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index ad58ce3..6dbaf66 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -2579,10 +2579,11 @@ static void ilk_update_wm(struct drm_crtc *crtc)
ilk_write_wm_values(dev_priv, &results);
 }
 
-static void ilk_update_sprite_wm(struct drm_plane *plane,
-struct drm_crtc *crtc,
-uint32_t sprite_width, int pixel_size,
-bool enabled, bool scaled)
+static void
+ilk_update_sprite_wm(struct drm_plane *plane,
+struct drm_crtc *crtc,
+uint32_t sprite_width, uint32_t sprite_height,
+int pixel_size, bool enabled, bool scaled)
 {
struct drm_device *dev = plane->dev;
struct intel_plane *intel_plane = to_intel_plane(plane);
@@ -2590,6 +2591,7 @@ static void ilk_update_sprite_wm(struct drm_plane *plane,
intel_plane->wm.enabled = enabled;
intel_plane->wm.scaled = scaled;
intel_plane->wm.horiz_pixels = sprite_width;
+   intel_plane->wm.vert_pixels = sprite_width;
intel_plane->wm.bytes_per_pixel = pixel_size;
 
/*
@@ -2720,13 +2722,16 @@ void intel_update_watermarks(struct drm_crtc *crtc)
 
 void intel_update_sprite_watermarks(struct drm_plane *plane,
struct drm_crtc *crtc,
-   uint32_t sprite_width, int pixel_size,
+   uint32_t sprite_width,
+   uint32_t sprite_height,
+   int pixel_size,
bool enabled, bool scaled)
 {
struct drm_i915_private *dev_priv = plane->dev->dev_private;
 
if (dev_priv->display.update_sprite_wm)
-   dev_priv->display.update_sprite_wm(plane, crtc, sprite_width,
+   dev_priv->display.update_sprite_wm(plane, crtc,
+  sprite_width, sprite_height,
   pixel_size, enabled, scaled);
 }
 
diff --git a/drivers/gpu/drm/i915/intel_sprite.c 
b/drivers/gpu/drm/i915/intel_sprite.c
index 336ae6c..844bccd 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -115,7 +115,8 @@ vlv_update_plane(struct drm_plane *dplane, struct drm_crtc 
*crtc,
 
sprctl |= SP_ENABLE;
 
-   intel_upda

Re: [Intel-gfx] v3.14-rc7: Backlight control broken on Dell XPS13

2014-03-17 Thread Romain Francoise
Jani Nikula  writes:

> Here's two patches to try, separately, *without* the quirk: [...]

Okay, I've tried both and neither works. However, I've noticed that
while the backlight level never changes even though I'm changing it with
Fn+F4/Fn+F5, it *does* get registered somewhere because if I bring it
all the day down and reboot, the brightness is reduced in the next BIOS
POST (loading i915 gets it back to 100%).

Thanks,
-r
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH] tests/gem_reset_stats: run non hw context tests also on older gens

2014-03-17 Thread Mika Kuoppala
To gain more coverage on interface, default context and banning.
As there is no proper reset support for gen <= 3, we only
do limited interface testing on those.

Signed-off-by: Mika Kuoppala 
---
 tests/gem_reset_stats.c |   91 ++-
 1 file changed, 75 insertions(+), 16 deletions(-)

diff --git a/tests/gem_reset_stats.c b/tests/gem_reset_stats.c
index 3719f40..2bb4681 100644
--- a/tests/gem_reset_stats.c
+++ b/tests/gem_reset_stats.c
@@ -51,6 +51,9 @@
 #define RS_BATCH_PENDING (1 << 1)
 #define RS_UNKNOWN   (1 << 2)
 
+static uint32_t devid;
+static bool hw_contexts;
+
 struct local_drm_i915_reset_stats {
__u32 ctx_id;
__u32 flags;
@@ -101,6 +104,9 @@ static const struct target_ring {
 
 static bool has_context(const struct target_ring *ring)
 {
+   if (!hw_contexts)
+   return false;
+
if(ring->exec == I915_EXEC_RENDER)
return true;
 
@@ -277,7 +283,7 @@ static int inject_hang_ring(int fd, int ctx, int ring)
 
srandom(time(NULL));
 
-   if (intel_gen(intel_get_drm_devid(fd)) >= 8)
+   if (intel_gen(devid) >= 8)
cmd_len = 3;
 
buf = malloc(BUFSIZE);
@@ -960,7 +966,7 @@ static int _test_params(int fd, int ctx, uint32_t flags, 
uint32_t pad)
 
 typedef enum { root = 0, user } cap_t;
 
-static void test_param_ctx(const int fd, const int ctx, const cap_t cap)
+static void _check_param_ctx(const int fd, const int ctx, const cap_t cap)
 {
const uint32_t bad = rand() + 1;
 
@@ -981,8 +987,7 @@ static void check_params(const int fd, const int ctx, cap_t 
cap)
igt_assert(ioctl(fd, GET_RESET_STATS_IOCTL, 0) == -1);
igt_assert(_test_params(fd, 0xbadbad, 0, 0) == -ENOENT);
 
-   test_param_ctx(fd, 0, cap);
-   test_param_ctx(fd, ctx, cap);
+   _check_param_ctx(fd, ctx, cap);
 }
 
 static void _test_param(const int fd, const int ctx)
@@ -1002,7 +1007,7 @@ static void _test_param(const int fd, const int ctx)
igt_waitchildren();
 }
 
-static void test_params(void)
+static void test_params_ctx(void)
 {
int fd, ctx;
 
@@ -1015,29 +1020,76 @@ static void test_params(void)
close(fd);
 }
 
-#define RING_HAS_CONTEXTS current_ring->contexts(current_ring)
-#define RUN_CTX_TEST(...) do { igt_skip_on(RING_HAS_CONTEXTS == false); 
__VA_ARGS__; } while (0)
+static void test_params(void)
+{
+   int fd;
 
-int fd;
+   fd = drm_open_any();
+   igt_assert(fd >= 0);
 
-igt_main
+   _test_param(fd, 0);
+
+   close(fd);
+
+}
+
+static bool gem_has_hw_contexts(int fd)
 {
struct local_drm_i915_gem_context_create create;
-   uint32_t devid;
int ret;
 
+   memset(&create, 0, sizeof(create));
+   ret = drmIoctl(fd, CONTEXT_CREATE_IOCTL, &create);
+
+   if (ret == 0) {
+   drmIoctl(fd, CONTEXT_DESTROY_IOCTL, &create);
+   return true;
+   }
+
+   return false;
+}
+
+static bool gem_has_reset_stats(int fd)
+{
+   struct local_drm_i915_reset_stats rs;
+   int ret;
+
+   /* Carefully set flags and pad to zero, otherwise
+  we get -EINVAL
+   */
+   memset(&rs, 0, sizeof(rs));
+
+   ret = drmIoctl(fd, GET_RESET_STATS_IOCTL, &rs);
+   if (ret == 0)
+   return true;
+
+   /* If we get EPERM, we have support but did not
+  have CAP_SYSADM */
+   if (ret == -1 && errno == EPERM)
+   return true;
+
+   return false;
+}
+
+#define RING_HAS_CONTEXTS (current_ring->contexts(current_ring))
+#define RUN_CTX_TEST(...) do { igt_skip_on(RING_HAS_CONTEXTS == false); 
__VA_ARGS__; } while (0)
+
+static int fd;
+
+igt_main
+{
igt_skip_on_simulation();
 
igt_fixture {
+   bool has_reset_stats;
fd = drm_open_any();
devid = intel_get_drm_devid(fd);
-   igt_require_f(intel_gen(devid) >= 4,
- "Architecture %d too old\n", intel_gen(devid));
 
-   ret = drmIoctl(fd, CONTEXT_CREATE_IOCTL, &create);
-   igt_skip_on_f(ret != 0 && (errno == ENODEV || errno == EINVAL),
- "Kernel is too old, or contexts not supported: 
%s\n",
- strerror(errno));
+   hw_contexts = gem_has_hw_contexts(fd);
+   has_reset_stats = gem_has_reset_stats(fd);
+
+   igt_require_f(has_reset_stats,
+ "No reset stats ioctl support. Too old 
kernel?\n");
}
 
igt_subtest("params")
@@ -1052,6 +1104,13 @@ igt_main
igt_fixture
gem_require_ring(fd, current_ring->exec);
 
+   igt_fixture
+   igt_require_f(intel_gen(devid) >= 4,
+ "gen %d doesn't support reset\n", 
intel_gen(devid));
+
+   igt_subtest_f("params-ctx-%s", name)
+   RUN_CTX_TEST(test_params_ctx());

Re: [Intel-gfx] v3.14-rc7: Backlight control broken on Dell XPS13

2014-03-17 Thread Romain Francoise
Jani Nikula  writes:

> Please file a new bug on DRM/Intel component at [1]. Please attach
> intel_reg_dumper output (tool from intel-gpu-tools [2]) with and without
> the revert. Please also attach dmesg with drm.debug=0xe from early
> boot.

Done, https://bugs.freedesktop.org/show_bug.cgi?id=76276

Let me know if you need more info.

> Do you have the snb or ivb model?

IVB.

> The register dump from *before* i915 gets loaded is also interesting.

That's more difficult to procure, is it really necessary?

Thanks,
-r
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] v3.14-rc7: Backlight control broken on Dell XPS13

2014-03-17 Thread Romain Francoise
Hi Daniel,

Daniel Vetter  writes:

> Please never just send a mail to maintainers, always cc mailing lists.

Yes, sorry, I sent this privately because it wasn't a fully-formed bug
report; I just wanted Jani to confirm that it wasn't intentionally
broken as of -rc7.

> Have you tested with the patch reverted to confirm that it's indeed
> this commit and not something else (e.g. in the acpi code)?

I hadn't, but I've now reverted the revert and things work again as in
v3.13. So as far as I can tell the quirk is still definitely needed.

Thanks!
-r
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH] drm/i915: finish off reverting eDP VDD changes

2014-03-17 Thread Daniel Vetter
On Mon, Mar 17, 2014 at 04:43:36PM +0200, Jani Nikula wrote:
> This is a small follow-up fix to the series of eDP VDD back and forth
> we've had recently. This is effectively a combined revert of three
> commits:
> 
> commit 2c2894f698fffd8ff53e1e1d3834f9e1035b1f39
> Author: Paulo Zanoni 
> Date:   Fri Mar 7 20:05:20 2014 -0300
> 
> drm/i915: properly disable the VDD when disabling the panel
> 
> commit b3064154dfd37deb386b1e459c54e1ca2460b3d5
> Author: Patrik Jakobsson 
> Date:   Tue Mar 4 00:42:44 2014 +0100
> 
> drm/i915: Don't just say it, actually force edp vdd
> 
> commit dff392dbd258381a6c3164f38420593f2d291e3b
> Author: Paulo Zanoni 
> Date:   Fri Dec 6 17:32:41 2013 -0200
> 
> drm/i915: don't touch the VDD when disabling the panel
> 
> which shows that we're pretty close back to where we started
> already. The first two were basically reverting the last, but missing
> the WARN. Add that back. We also OCD the intel_ prefix back to
> intel_edp_panel_vdd_on() which was lost somewhere in between. The circle
> closes.
> 
> For future reference, "drm/i915: don't touch the VDD when disabling the
> panel" failed to take into account
> 
> commit 6cb49835da0426f69a2931bc2a0a8156344b0e41
> Author: Daniel Vetter 
> Date:   Sun May 20 17:14:50 2012 +0200
> 
> drm/i915: enable vdd when switching off the eDP panel
> 
> and
> 
> commit 35a38556d900b9cb5dfa2529c93944b847f8a8a4
> Author: Daniel Vetter 
> Date:   Sun Aug 12 22:17:14 2012 +0200
> 
> drm/i915: reorder edp disabling to fix ivb MacBook Air
> 
> Cc: Patrik Jakobsson 
> Cc: Paulo Zanoni 
> Signed-off-by: Jani Nikula 

5 commit citations and we still need more. I think that's a new highscore
;-)

Thanks for doing this detailed revert, queued for -next, thanks for the patch.

And an ack on the relevant revert for -fixes ofc.
-Daniel
> ---
>  drivers/gpu/drm/i915/intel_ddi.c |2 +-
>  drivers/gpu/drm/i915/intel_dp.c  |   14 --
>  drivers/gpu/drm/i915/intel_drv.h |2 +-
>  3 files changed, 10 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_ddi.c 
> b/drivers/gpu/drm/i915/intel_ddi.c
> index fe1f5f012c4f..070bf2e78d61 100644
> --- a/drivers/gpu/drm/i915/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/intel_ddi.c
> @@ -1340,7 +1340,7 @@ static void intel_ddi_post_disable(struct intel_encoder 
> *intel_encoder)
>   if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) {
>   struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
>   intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF);
> - edp_panel_vdd_on(intel_dp);
> + intel_edp_panel_vdd_on(intel_dp);
>   intel_edp_panel_off(intel_dp);
>   }
>  
> diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
> index 7854cdbb462a..071d44fe2fc8 100644
> --- a/drivers/gpu/drm/i915/intel_dp.c
> +++ b/drivers/gpu/drm/i915/intel_dp.c
> @@ -676,7 +676,7 @@ intel_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode,
>   int reply_bytes;
>   int ret;
>  
> - edp_panel_vdd_on(intel_dp);
> + intel_edp_panel_vdd_on(intel_dp);
>   intel_dp_check_edp(intel_dp);
>   /* Set up the command byte */
>   if (mode & MODE_I2C_READ)
> @@ -1161,7 +1161,7 @@ static  u32 ironlake_get_pp_control(struct intel_dp 
> *intel_dp)
>   return control;
>  }
>  
> -void edp_panel_vdd_on(struct intel_dp *intel_dp)
> +void intel_edp_panel_vdd_on(struct intel_dp *intel_dp)
>  {
>   struct drm_device *dev = intel_dp_to_dev(intel_dp);
>   struct drm_i915_private *dev_priv = dev->dev_private;
> @@ -1329,6 +1329,8 @@ void intel_edp_panel_off(struct intel_dp *intel_dp)
>  
>   edp_wait_backlight_off(intel_dp);
>  
> + WARN(!intel_dp->want_panel_vdd, "Need VDD to turn off panel\n");
> +
>   pp = ironlake_get_pp_control(intel_dp);
>   /* We need to switch off panel power _and_ force vdd, for otherwise some
>* panels get very unhappy and cease to work. */
> @@ -1880,7 +1882,7 @@ static void intel_disable_dp(struct intel_encoder 
> *encoder)
>  
>   /* Make sure the panel is off before trying to change the mode. But also
>* ensure that we have vdd while we switch off the panel. */
> - edp_panel_vdd_on(intel_dp);
> + intel_edp_panel_vdd_on(intel_dp);
>   intel_edp_backlight_off(intel_dp);
>   intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF);
>   intel_edp_panel_off(intel_dp);
> @@ -1913,7 +1915,7 @@ static void intel_enable_dp(struct intel_encoder 
> *encoder)
>   if (WARN_ON(dp_reg & DP_PORT_EN))
>   return;
>  
> - edp_panel_vdd_on(intel_dp);
> + intel_edp_panel_vdd_on(intel_dp);
>   intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
>   intel_dp_start_link_train(intel_dp);
>   intel_edp_panel_on(intel_dp);
> @@ -2951,7 +2953,7 @@ intel_dp_probe_oui(struct intel_dp *intel_dp)
>   if (!(intel_dp->dpcd[DP_DOWN_STREAM_PORT_COUNT] & DP_OUI_SUPPORT))
>   return;
>  
> - 

Re: [Intel-gfx] [PATCH] drm/i915/bdw: Fix GEN8 GTT size calculation

2014-03-17 Thread Daniel Vetter
On Mon, Mar 17, 2014 at 5:17 PM, Woodhouse, David
 wrote:
> I think I have found this problem on the IOMMU side. We usually assume
> that RMRRs are for boot-time only, such as USB controllers for the
> legacy keyboard/mouse emulation. And a patch sneaked in which
> effectively *unmaps* the RMRR regions when you do the first "real"
> mapping for the driver. Having fixed that, I think I should no longer
> see these DMA faults.

Which commit is this? I've a patch+bug report that stolen + dmar is busted.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] v3.14-rc7: Backlight control broken on Dell XPS13

2014-03-17 Thread Jani Nikula
On Mon, 17 Mar 2014, Romain Francoise  wrote:
> Hi Daniel,
>
> Daniel Vetter  writes:
>
>> Please never just send a mail to maintainers, always cc mailing lists.
>
> Yes, sorry, I sent this privately because it wasn't a fully-formed bug
> report; I just wanted Jani to confirm that it wasn't intentionally
> broken as of -rc7.
>
>> Have you tested with the patch reverted to confirm that it's indeed
>> this commit and not something else (e.g. in the acpi code)?
>
> I hadn't, but I've now reverted the revert and things work again as in
> v3.13. So as far as I can tell the quirk is still definitely needed.

Here's two patches to try, separately, *without* the quirk:

Patch #1:

diff --git a/drivers/gpu/drm/i915/intel_panel.c 
b/drivers/gpu/drm/i915/intel_panel.c
index cb058408c70e..ef26115dbe68 100644
--- a/drivers/gpu/drm/i915/intel_panel.c
+++ b/drivers/gpu/drm/i915/intel_panel.c
@@ -659,7 +659,7 @@ static void pch_enable_backlight(struct intel_connector 
*connector)
/* This won't stick until the above enable. */
intel_panel_actually_set_backlight(connector, panel->backlight.level);
 
-   pch_ctl2 = panel->backlight.max << 16;
+   pch_ctl2 = panel->backlight.max << 16 | panel->backlight.level;
I915_WRITE(BLC_PWM_PCH_CTL2, pch_ctl2);
 
pch_ctl1 = 0;

Patch #2:

diff --git a/drivers/gpu/drm/i915/intel_panel.c 
b/drivers/gpu/drm/i915/intel_panel.c
index cb058408c70e..10849104fa1e 100644
--- a/drivers/gpu/drm/i915/intel_panel.c
+++ b/drivers/gpu/drm/i915/intel_panel.c
@@ -669,6 +669,8 @@ static void pch_enable_backlight(struct intel_connector 
*connector)
I915_WRITE(BLC_PWM_PCH_CTL1, pch_ctl1);
POSTING_READ(BLC_PWM_PCH_CTL1);
I915_WRITE(BLC_PWM_PCH_CTL1, pch_ctl1 | BLM_PCH_PWM_ENABLE);
+
+   intel_panel_actually_set_backlight(connector, panel->backlight.level);
 }
 
 static void i9xx_enable_backlight(struct intel_connector *connector)



-- 
Jani Nikula, Intel Open Source Technology Center
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH] uxa: Support BLT ring flushes on Broadwell, but not render ring flushes.

2014-03-17 Thread Kenneth Graunke
Several places (such as intel_cache_expire) call intel_emit_batch_flush,
so it needs to work on Broadwell.  Sometimes the batch is empty, in
which case current_batch may not yet be BLT_RING.

The PIPE_CONTROL code has not been ported to work on Broadwell, so
trying to do a render ring flush will hang the GPU.  It also doesn't
make any sense to do a render ring flush, given that we never use the
render ring for UXA on Broadwell.

Signed-off-by: Kenneth Graunke 
---
 src/uxa/intel_batchbuffer.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

This is an alternative to my old "uxa: Don't emit PIPE_CONTROLs in an
empty batch." patch, which Chris pointed out was broken.

Chris,

In the future, if you're going to rewrite significant portions of my
patches, could you please at least put your Signed-off-by or something
on it?  In the version of "uxa: Enable BLT acceleration on Broadwell.",
you committed, at least half the patch was not actually written by me,
and the resulting code either hit assertion failures or GPU hangs if
run at all.

It's pretty disconcerting to see code committed under my name, with my
Signed-off-by, that doesn't work and which I've never even seen before.

diff --git a/src/uxa/intel_batchbuffer.c b/src/uxa/intel_batchbuffer.c
index 4aabe48..ec71ce2 100644
--- a/src/uxa/intel_batchbuffer.c
+++ b/src/uxa/intel_batchbuffer.c
@@ -183,11 +183,11 @@ void intel_batch_emit_flush(ScrnInfoPtr scrn)
int flags;
 
assert (!intel->in_batch_atomic);
-   assert (INTEL_INFO(intel)->gen < 0100);
 
/* Big hammer, look to the pipelined flushes in future. */
if ((INTEL_INFO(intel)->gen >= 060)) {
-   if (intel->current_batch == BLT_BATCH) {
+   if (intel->current_batch == BLT_BATCH ||
+   INTEL_INFO(intel)->gen >= 0100) {
BEGIN_BATCH_BLT(4);
OUT_BATCH(MI_FLUSH_DW | 2);
OUT_BATCH(0);
-- 
1.8.4.2

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH] drm/i915/bdw: Fix GEN8 GTT size calculation

2014-03-17 Thread David Woodhouse
On Mon, 2014-03-17 at 16:17 +, David Woodhouse wrote:
> 
> Can't tell though, because my machine is still dying in an endless
> stream of
> [  199.647850] [drm:intel_set_cpu_fifo_underrun_reporting] *ERROR*
> Interrupt arrived before CRTCs were setup up

Except when the failure mode is different...

[   24.143180] [ cut here ]
[   24.150433] WARNING: CPU: 1 PID: 161 at kernel/watchdog.c:245 
watchdog_overflow_callback+0x9c/0xd0()
[   24.162945] Watchdog detected hard LOCKUP on cpu 1
[   24.168206] Modules linked in: i915(+) i2c_algo_bit drm_kms_helper drm 
i2c_core video
[   24.181743] CPU: 1 PID: 161 Comm: systemd-udevd Not tainted 3.14.0-rc5+ #54
[   24.191833] Hardware name: Intel Corporation Broadwell Client 
platform/WhiteTip Mountain 1, BIOS BDW-E2R1.86C.0053.R02.131213
[   24.208364]  0009 88014e446c20 816b5c48 
88014e446c68
[   24.219026]  88014e446c58 81085e9d 880147cf 

[   24.229676]  88014e446d88  88014e446ef8 
88014e446cb8
[   24.240298] Call Trace:
[   24.245251][] dump_stack+0x45/0x56
[   24.254028]  [] warn_slowpath_common+0x7d/0xa0
[   24.263071]  [] warn_slowpath_fmt+0x4c/0x50
[   24.271802]  [] ? restart_watchdog_hrtimer+0x50/0x50
[   24.281352]  [] watchdog_overflow_callback+0x9c/0xd0
[   24.290979]  [] __perf_event_overflow+0x8e/0x240
[   24.300211]  [] ? x86_perf_event_set_period+0xe8/0x150
[   24.310053]  [] perf_event_overflow+0x14/0x20
[   24.319014]  [] intel_pmu_handle_irq+0x1cd/0x3c0
[   24.328264]  [] perf_event_nmi_handler+0x2b/0x50
[   24.337519]  [] nmi_handle.isra.3+0x88/0x180
[   24.346369]  [] do_nmi+0x169/0x310
[   24.354215]  [] end_repeat_nmi+0x1e/0x2e
[   24.362660]  [] ? alloc_vmap_area+0x6f/0x310
[   24.371525]  [] ? __gen6_gt_force_wake_mt_get+0x7b/0x150 
[i915]
[   24.382215]  [] ? __gen6_gt_force_wake_mt_get+0x7b/0x150 
[i915]
[   24.392935]  [] ? __gen6_gt_force_wake_mt_get+0x7b/0x150 
[i915]
[   24.403590]  <>  [] gen8_write32+0x10c/0x120 [i915]
[   24.413655]  [] gen8_gmch_probe+0xe7/0x190 [i915]
[   24.422984]  [] i915_gem_gtt_init+0x62/0x200 [i915]
[   24.432504]  [] i915_driver_load+0x43d/0xe10 [i915]
[   24.442000]  [] ? drm_get_minor+0x1a5/0x200 [drm]
[   24.451322]  [] drm_dev_register+0x7b/0x160 [drm]
[   24.460620]  [] drm_get_pci_dev+0xa0/0x220 [drm]
[   24.469827]  [] i915_pci_probe+0x3b/0x60 [i915]
[   24.478917]  [] local_pci_probe+0x45/0xa0
[   24.487382]  [] pci_device_probe+0xd1/0x130
[   24.496072]  [] driver_probe_device+0x125/0x3a0
[   24.505141]  [] __driver_attach+0x93/0xa0
[   24.513631]  [] ? __device_attach+0x40/0x40
[   24.522301]  [] bus_for_each_dev+0x63/0xa0
[   24.530871]  [] driver_attach+0x1e/0x20
[   24.539114]  [] bus_add_driver+0x180/0x250
[   24.547625]  [] ? 0xa0146fff
[   24.54]  [] driver_register+0x64/0xf0
[   24.563824]  [] ? 0xa0146fff
[   24.571716]  [] __pci_register_driver+0x4b/0x50
[   24.580701]  [] drm_pci_init+0x11a/0x130 [drm]
[   24.589447]  [] ? 0xa0146fff
[   24.597330]  [] i915_init+0x6a/0x6c [i915]
[   24.605806]  [] do_one_initcall+0xd2/0x180
[   24.614278]  [] ? set_memory_nx+0x43/0x50
[   24.622651]  [] load_module+0x1e0b/0x25a0
[   24.631014]  [] ? store_uevent+0x40/0x40
[   24.639285]  [] ? copy_module_from_fd.isra.47+0x12a/0x190
[   24.649242]  [] SyS_finit_module+0x86/0xb0
[   24.657721]  [] system_call_fastpath+0x16/0x1b
[   24.666590] ---[ end trace d4228967fcb7ae4a ]---


-- 
dwmw2


smime.p7s
Description: S/MIME cryptographic signature
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH] drm/i915/bdw: Fix GEN8 GTT size calculation

2014-03-17 Thread Woodhouse, David
On Fri, 2014-03-14 at 23:10 +0100, Daniel Vetter wrote:
> 
> I've asked you on private irc whether this range matches/overlaps with
> stolen - we know of things blowing up at least on earlier generations
> in combination with dmar. Please boot with drm.debug=0xe and scan for
> the stolen mem reporting:

Surely it *has* to be stolen? That's the whole *point* in the RMRR that
the BIOS provides, telling us that the gfx unit is expecting to do DMA
to this range of memory.

If it isn't stolen, it's just being wantonly "borrowed".

Have you *ever* known an RMRR point at memory other than the stolen
range?

I think I have found this problem on the IOMMU side. We usually assume
that RMRRs are for boot-time only, such as USB controllers for the
legacy keyboard/mouse emulation. And a patch sneaked in which
effectively *unmaps* the RMRR regions when you do the first "real"
mapping for the driver. Having fixed that, I think I should no longer
see these DMA faults.

Can't tell though, because my machine is still dying in an endless
stream of
[  199.647850] [drm:intel_set_cpu_fifo_underrun_reporting] *ERROR* Interrupt 
arrived before CRTCs were setup up

-- 
   Sent with MeeGo's ActiveSync support.

David WoodhouseOpen Source Technology Centre
david.woodho...@intel.com  Intel Corporation


smime.p7s
Description: S/MIME cryptographic signature
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] v3.14-rc7: Backlight control broken on Dell XPS13

2014-03-17 Thread Jani Nikula
On Mon, 17 Mar 2014, Jani Nikula  wrote:
> On Mon, 17 Mar 2014, Romain Francoise  wrote:
>> Hi Daniel,
>>
>> Daniel Vetter  writes:
>>
>>> Please never just send a mail to maintainers, always cc mailing lists.
>>
>> Yes, sorry, I sent this privately because it wasn't a fully-formed bug
>> report; I just wanted Jani to confirm that it wasn't intentionally
>> broken as of -rc7.
>>
>>> Have you tested with the patch reverted to confirm that it's indeed
>>> this commit and not something else (e.g. in the acpi code)?
>>
>> I hadn't, but I've now reverted the revert and things work again as in
>> v3.13. So as far as I can tell the quirk is still definitely needed.
>
> I still don't think having the quirk is the way to go. Let's fix this
> properly, shall we?
>
> Please file a new bug on DRM/Intel component at [1]. Please attach
> intel_reg_dumper output (tool from intel-gpu-tools [2]) with and without
> the revert. Please also attach dmesg with drm.debug=0xe from early boot.

The register dump from *before* i915 gets loaded is also interesting.

BR,
Jani.

>
> Do you have the snb or ivb model?
>
> BR,
> Jani.
>
>
> [1] https://bugs.freedesktop.org/enter_bug.cgi?product=DRI
> [2] http://cgit.freedesktop.org/xorg/app/intel-gpu-tools/
>
>>
>> Thanks!
>> -r
>
> -- 
> Jani Nikula, Intel Open Source Technology Center
> ___
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Jani Nikula, Intel Open Source Technology Center
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] v3.14-rc7: Backlight control broken on Dell XPS13

2014-03-17 Thread Jani Nikula
On Mon, 17 Mar 2014, Romain Francoise  wrote:
> Hi Daniel,
>
> Daniel Vetter  writes:
>
>> Please never just send a mail to maintainers, always cc mailing lists.
>
> Yes, sorry, I sent this privately because it wasn't a fully-formed bug
> report; I just wanted Jani to confirm that it wasn't intentionally
> broken as of -rc7.
>
>> Have you tested with the patch reverted to confirm that it's indeed
>> this commit and not something else (e.g. in the acpi code)?
>
> I hadn't, but I've now reverted the revert and things work again as in
> v3.13. So as far as I can tell the quirk is still definitely needed.

I still don't think having the quirk is the way to go. Let's fix this
properly, shall we?

Please file a new bug on DRM/Intel component at [1]. Please attach
intel_reg_dumper output (tool from intel-gpu-tools [2]) with and without
the revert. Please also attach dmesg with drm.debug=0xe from early boot.

Do you have the snb or ivb model?

BR,
Jani.


[1] https://bugs.freedesktop.org/enter_bug.cgi?product=DRI
[2] http://cgit.freedesktop.org/xorg/app/intel-gpu-tools/

>
> Thanks!
> -r

-- 
Jani Nikula, Intel Open Source Technology Center
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH 4/6] drm/i915/dp: use the new drm helpers for dp aux

2014-03-17 Thread Jani Nikula
On Mon, 17 Mar 2014, Rodrigo Vivi  wrote:
> On Mon, Mar 17, 2014 at 11:08 AM, Rodrigo Vivi  wrote:
>> On Fri, Mar 14, 2014 at 11:51 AM, Jani Nikula  wrote:
>>> -   if (!intel_dp_aux_native_read(intel_dp, DP_TEST_SINK_MISC, buf, 1))
>>> +   if (drm_dp_dpcd_readb(&intel_dp->aux, DP_TEST_SINK_MISC, buf) < 0);
>
> wrong ";" here..

Yikes, good catch. I've been rebasing this way too many times...

Jani.


-- 
Jani Nikula, Intel Open Source Technology Center
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH 4/6] drm/i915/dp: use the new drm helpers for dp aux

2014-03-17 Thread Rodrigo Vivi
On Mon, Mar 17, 2014 at 11:08 AM, Rodrigo Vivi  wrote:
> On Fri, Mar 14, 2014 at 11:51 AM, Jani Nikula  wrote:
>> Functionality remains largely the same as before.
>>
>> Signed-off-by: Jani Nikula 
>> ---
>>  drivers/gpu/drm/i915/intel_dp.c  |  257 
>> +-
>>  drivers/gpu/drm/i915/intel_drv.h |1 +
>>  2 files changed, 116 insertions(+), 142 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i915/intel_dp.c 
>> b/drivers/gpu/drm/i915/intel_dp.c
>> index 22134edc03dd..24cbf4bd36c4 100644
>> --- a/drivers/gpu/drm/i915/intel_dp.c
>> +++ b/drivers/gpu/drm/i915/intel_dp.c
>> @@ -575,97 +575,77 @@ out:
>> return ret;
>>  }
>>
>> -/* Write data to the aux channel in native mode */
>> -static int
>> -intel_dp_aux_native_write(struct intel_dp *intel_dp,
>> - uint16_t address, uint8_t *send, int send_bytes)
>> +#define HEADER_SIZE4
>> +static ssize_t
>> +intel_dp_aux_transfer(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg)
>>  {
>> +   struct intel_dp *intel_dp = container_of(aux, struct intel_dp, aux);
>> +   uint8_t txbuf[20], rxbuf[20];
>> +   size_t txsize, rxsize;
>> int ret;
>> -   uint8_t msg[20];
>> -   int msg_bytes;
>> -   uint8_t ack;
>> -   int retry;
>>
>> -   if (WARN_ON(send_bytes > 16))
>> -   return -E2BIG;
>> +   txbuf[0] = msg->request << 4;
>> +   txbuf[1] = msg->address >> 8;
>> +   txbuf[2] = msg->address & 0xff;
>> +   txbuf[3] = msg->size - 1;
>>
>> -   intel_dp_check_edp(intel_dp);
>> -   msg[0] = DP_AUX_NATIVE_WRITE << 4;
>> -   msg[1] = address >> 8;
>> -   msg[2] = address & 0xff;
>> -   msg[3] = send_bytes - 1;
>> -   memcpy(&msg[4], send, send_bytes);
>> -   msg_bytes = send_bytes + 4;
>> -   for (retry = 0; retry < 7; retry++) {
>
> we were retrying 7 times always, but now we are now retrying only 3
> times or even none.
> Couldn't it trigger some new bug or regression?
>
>> -   ret = intel_dp_aux_ch(intel_dp, msg, msg_bytes, &ack, 1);
>> -   if (ret < 0)
>> -   return ret;
>> -   ack >>= 4;
>> -   if ((ack & DP_AUX_NATIVE_REPLY_MASK) == 
>> DP_AUX_NATIVE_REPLY_ACK)
>> -   return send_bytes;
>> -   else if ((ack & DP_AUX_NATIVE_REPLY_MASK) == 
>> DP_AUX_NATIVE_REPLY_DEFER)
>> -   usleep_range(400, 500);
>
> we are also not checking this ack x defer (here nor in native_write)
> replies anymore.
> Don't we need it anymore? why?
>
>> -   else
>> -   return -EIO;
>> -   }
>> +   switch (msg->request & ~DP_AUX_I2C_MOT) {
>> +   case DP_AUX_NATIVE_WRITE:
>> +   case DP_AUX_I2C_WRITE:
>> +   txsize = HEADER_SIZE + msg->size;
>> +   rxsize = 1;
>>
>> -   DRM_ERROR("too many retries, giving up\n");
>> -   return -EIO;
>> -}
>> +   if (WARN_ON(txsize > 20))
>> +   return -E2BIG;
>>
>> -/* Write a single byte to the aux channel in native mode */
>> -static int
>> -intel_dp_aux_native_write_1(struct intel_dp *intel_dp,
>> -   uint16_t address, uint8_t byte)
>> -{
>> -   return intel_dp_aux_native_write(intel_dp, address, &byte, 1);
>> -}
>> +   memcpy(txbuf + HEADER_SIZE, msg->buffer, msg->size);
>>
>> -/* read bytes from a native aux channel */
>> -static int
>> -intel_dp_aux_native_read(struct intel_dp *intel_dp,
>> -uint16_t address, uint8_t *recv, int recv_bytes)
>> -{
>> -   uint8_t msg[4];
>> -   int msg_bytes;
>> -   uint8_t reply[20];
>> -   int reply_bytes;
>> -   uint8_t ack;
>> -   int ret;
>> -   int retry;
>> +   ret = intel_dp_aux_ch(intel_dp, txbuf, txsize, rxbuf, 
>> rxsize);
>> +   if (ret > 0) {
>> +   msg->reply = rxbuf[0] >> 4;
>>
>> -   if (WARN_ON(recv_bytes > 19))
>> -   return -E2BIG;
>> +   /* Return payload size. */
>> +   ret = msg->size;
>> +   }
>> +   break;
>>
>> -   intel_dp_check_edp(intel_dp);
>> -   msg[0] = DP_AUX_NATIVE_READ << 4;
>> -   msg[1] = address >> 8;
>> -   msg[2] = address & 0xff;
>> -   msg[3] = recv_bytes - 1;
>> +   case DP_AUX_NATIVE_READ:
>> +   case DP_AUX_I2C_READ:
>> +   txsize = HEADER_SIZE;
>> +   rxsize = msg->size + 1;
>>
>> -   msg_bytes = 4;
>> -   reply_bytes = recv_bytes + 1;
>> +   if (WARN_ON(rxsize > 20))
>> +   return -E2BIG;
>>
>> -   for (retry = 0; retry < 7; retry++) {
>> -   ret = intel_dp_aux_ch(intel_dp, msg, msg_bytes,
>> - reply, reply_bytes);
>> -   if (ret == 0)
>> -   return -EPROTO;
>> -   if (ret < 0)
>> -

Re: [Intel-gfx] [PATCH 5/6] drm/i915/dp: move dp aux ch register init to aux init

2014-03-17 Thread Jani Nikula
On Mon, 17 Mar 2014, Rodrigo Vivi  wrote:
> I would prefer an else instead of unecessary comparisons and
> assignment that will be override..

In general I agree, but see next patch. ;)

BR,
Jani.


>
> But anyway it works, so feel free to use:
> Reviewed-by: Rodrigo Vivi 
>
> On Fri, Mar 14, 2014 at 11:51 AM, Jani Nikula  wrote:
>> Do a slight rearrangement of the switch to prep for follow-up.
>>
>> Signed-off-by: Jani Nikula 
>> ---
>>  drivers/gpu/drm/i915/intel_dp.c |   42 
>> ---
>>  1 file changed, 22 insertions(+), 20 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i915/intel_dp.c 
>> b/drivers/gpu/drm/i915/intel_dp.c
>> index 24cbf4bd36c4..71a76d00d634 100644
>> --- a/drivers/gpu/drm/i915/intel_dp.c
>> +++ b/drivers/gpu/drm/i915/intel_dp.c
>> @@ -643,6 +643,28 @@ static void
>>  intel_dp_aux_init(struct intel_dp *intel_dp, struct intel_connector 
>> *connector)
>>  {
>> struct drm_device *dev = intel_dp_to_dev(intel_dp);
>> +   struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
>> +   enum port port = intel_dig_port->port;
>> +
>> +   switch (port) {
>> +   case PORT_A:
>> +   intel_dp->aux_ch_ctl_reg = DPA_AUX_CH_CTL;
>> +   break;
>> +   case PORT_B:
>> +   intel_dp->aux_ch_ctl_reg = PCH_DPB_AUX_CH_CTL;
>> +   break;
>> +   case PORT_C:
>> +   intel_dp->aux_ch_ctl_reg = PCH_DPC_AUX_CH_CTL;
>> +   break;
>> +   case PORT_D:
>> +   intel_dp->aux_ch_ctl_reg = PCH_DPD_AUX_CH_CTL;
>> +   break;
>> +   default:
>> +   BUG();
>> +   }
>> +
>> +   if (!HAS_DDI(dev))
>> +   intel_dp->aux_ch_ctl_reg = intel_dp->output_reg + 0x10;
>>
>> intel_dp->aux.dev = dev->dev;
>> intel_dp->aux.transfer = intel_dp_aux_transfer;
>> @@ -3849,26 +3871,6 @@ intel_dp_init_connector(struct intel_digital_port 
>> *intel_dig_port,
>> intel_connector->get_hw_state = intel_connector_get_hw_state;
>> intel_connector->unregister = intel_dp_connector_unregister;
>>
>> -   intel_dp->aux_ch_ctl_reg = intel_dp->output_reg + 0x10;
>> -   if (HAS_DDI(dev)) {
>> -   switch (intel_dig_port->port) {
>> -   case PORT_A:
>> -   intel_dp->aux_ch_ctl_reg = DPA_AUX_CH_CTL;
>> -   break;
>> -   case PORT_B:
>> -   intel_dp->aux_ch_ctl_reg = PCH_DPB_AUX_CH_CTL;
>> -   break;
>> -   case PORT_C:
>> -   intel_dp->aux_ch_ctl_reg = PCH_DPC_AUX_CH_CTL;
>> -   break;
>> -   case PORT_D:
>> -   intel_dp->aux_ch_ctl_reg = PCH_DPD_AUX_CH_CTL;
>> -   break;
>> -   default:
>> -   BUG();
>> -   }
>> -   }
>> -
>> /* Set up the DDC bus. */
>> switch (port) {
>> case PORT_A:
>> --
>> 1.7.9.5
>>
>> ___
>> Intel-gfx mailing list
>> Intel-gfx@lists.freedesktop.org
>> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
>
>
>
> -- 
> Rodrigo Vivi
> Blog: http://blog.vivi.eng.br

-- 
Jani Nikula, Intel Open Source Technology Center
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH 2/6] drm/i915/dp: split edp_panel_vdd_on() for reuse

2014-03-17 Thread Rodrigo Vivi
forgot to say that this patch needs a rebase on -nightly

On Mon, Mar 17, 2014 at 11:09 AM, Rodrigo Vivi  wrote:
> Reviewed-by: Rodrigo Vivi 
>
> On Fri, Mar 14, 2014 at 11:51 AM, Jani Nikula  wrote:
>> Introduce _edp_panel_vdd_on() that returns true if the call enabled vdd,
>> and a matching disable is needed. Keep edp_panel_vdd_on() as a helper
>> for when it is expected the vdd is off.
>>
>> Signed-off-by: Jani Nikula 
>> ---
>>  drivers/gpu/drm/i915/intel_dp.c |   22 --
>>  1 file changed, 16 insertions(+), 6 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i915/intel_dp.c 
>> b/drivers/gpu/drm/i915/intel_dp.c
>> index bb66f9301cd9..94e7577da484 100644
>> --- a/drivers/gpu/drm/i915/intel_dp.c
>> +++ b/drivers/gpu/drm/i915/intel_dp.c
>> @@ -91,6 +91,7 @@ static struct intel_dp *intel_attached_dp(struct 
>> drm_connector *connector)
>>  }
>>
>>  static void intel_dp_link_down(struct intel_dp *intel_dp);
>> +static bool _edp_panel_vdd_on(struct intel_dp *intel_dp);
>>  static void edp_panel_vdd_on(struct intel_dp *intel_dp);
>>  static void edp_panel_vdd_off(struct intel_dp *intel_dp, bool sync);
>>
>> @@ -1162,23 +1163,21 @@ static  u32 ironlake_get_pp_control(struct intel_dp 
>> *intel_dp)
>> return control;
>>  }
>>
>> -static void edp_panel_vdd_on(struct intel_dp *intel_dp)
>> +static bool _edp_panel_vdd_on(struct intel_dp *intel_dp)
>>  {
>> struct drm_device *dev = intel_dp_to_dev(intel_dp);
>> struct drm_i915_private *dev_priv = dev->dev_private;
>> u32 pp;
>> u32 pp_stat_reg, pp_ctrl_reg;
>> +   bool need_to_disable = !intel_dp->want_panel_vdd;
>>
>> if (!is_edp(intel_dp))
>> -   return;
>> -
>> -   WARN(intel_dp->want_panel_vdd,
>> -"eDP VDD already requested on\n");
>> +   return false;
>>
>> intel_dp->want_panel_vdd = true;
>>
>> if (edp_have_panel_vdd(intel_dp))
>> -   return;
>> +   return need_to_disable;
>>
>> intel_runtime_pm_get(dev_priv);
>>
>> @@ -1204,6 +1203,17 @@ static void edp_panel_vdd_on(struct intel_dp 
>> *intel_dp)
>> DRM_DEBUG_KMS("eDP was not running\n");
>> msleep(intel_dp->panel_power_up_delay);
>> }
>> +
>> +   return need_to_disable;
>> +}
>> +
>> +static void edp_panel_vdd_on(struct intel_dp *intel_dp)
>> +{
>> +   if (is_edp(intel_dp)) {
>> +   bool vdd = _edp_panel_vdd_on(intel_dp);
>> +
>> +   WARN(!vdd, "eDP VDD already requested on\n");
>> +   }
>>  }
>>
>>  static void edp_panel_vdd_off_sync(struct intel_dp *intel_dp)
>> --
>> 1.7.9.5
>>
>> ___
>> Intel-gfx mailing list
>> Intel-gfx@lists.freedesktop.org
>> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
>
>
>
> --
> Rodrigo Vivi
> Blog: http://blog.vivi.eng.br



-- 
Rodrigo Vivi
Blog: http://blog.vivi.eng.br
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH 6/6] drm/i915/dp: use the new drm helpers for dp i2c-over-aux

2014-03-17 Thread Rodrigo Vivi
On Fri, Mar 14, 2014 at 11:51 AM, Jani Nikula  wrote:
> The functionality remains largerly the same. The main difference is that
> i2c-over-aux defer timeouts are increased to be safe for all use cases
> instead of depending on DP device type and properties.

I was going to ask about different timeouts but you had already answered here ;)

>
> Signed-off-by: Jani Nikula 
> ---
>  drivers/gpu/drm/i915/intel_dp.c  |  197 
> ++
>  drivers/gpu/drm/i915/intel_drv.h |2 -
>  2 files changed, 30 insertions(+), 169 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
> index 71a76d00d634..208fdf075140 100644
> --- a/drivers/gpu/drm/i915/intel_dp.c
> +++ b/drivers/gpu/drm/i915/intel_dp.c
> @@ -645,19 +645,25 @@ intel_dp_aux_init(struct intel_dp *intel_dp, struct 
> intel_connector *connector)
> struct drm_device *dev = intel_dp_to_dev(intel_dp);
> struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
> enum port port = intel_dig_port->port;
> +   const char *name = NULL;
> +   int ret;
>
> switch (port) {
> case PORT_A:
> intel_dp->aux_ch_ctl_reg = DPA_AUX_CH_CTL;
> +   name = "DPDDC-A";
> break;
> case PORT_B:
> intel_dp->aux_ch_ctl_reg = PCH_DPB_AUX_CH_CTL;
> +   name = "DPDDC-B";
> break;
> case PORT_C:
> intel_dp->aux_ch_ctl_reg = PCH_DPC_AUX_CH_CTL;
> +   name = "DPDDC-C";
> break;
> case PORT_D:
> intel_dp->aux_ch_ctl_reg = PCH_DPD_AUX_CH_CTL;
> +   name = "DPDDC-D";
> break;
> default:
> BUG();
> @@ -666,128 +672,27 @@ intel_dp_aux_init(struct intel_dp *intel_dp, struct 
> intel_connector *connector)
> if (!HAS_DDI(dev))
> intel_dp->aux_ch_ctl_reg = intel_dp->output_reg + 0x10;
>
> +   intel_dp->aux.name = name;
> intel_dp->aux.dev = dev->dev;
> intel_dp->aux.transfer = intel_dp_aux_transfer;
> -}
>
> -static int
> -intel_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode,
> -   uint8_t write_byte, uint8_t *read_byte)
> -{
> -   struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data;
> -   struct intel_dp *intel_dp = container_of(adapter,
> -   struct intel_dp,
> -   adapter);
> -   uint16_t address = algo_data->address;
> -   uint8_t msg[5];
> -   uint8_t reply[2];
> -   unsigned retry;
> -   int msg_bytes;
> -   int reply_bytes;
> -   int ret;
> -
> -   /* Set up the command byte */
> -   if (mode & MODE_I2C_READ)
> -   msg[0] = DP_AUX_I2C_READ << 4;
> -   else
> -   msg[0] = DP_AUX_I2C_WRITE << 4;
> +   DRM_DEBUG_KMS("registering %s bus for %s\n", name,
> + connector->base.kdev->kobj.name);
>
> -   if (!(mode & MODE_I2C_STOP))
> -   msg[0] |= DP_AUX_I2C_MOT << 4;
> -
> -   msg[1] = address >> 8;
> -   msg[2] = address;
> -
> -   switch (mode) {
> -   case MODE_I2C_WRITE:
> -   msg[3] = 0;
> -   msg[4] = write_byte;
> -   msg_bytes = 5;
> -   reply_bytes = 1;
> -   break;
> -   case MODE_I2C_READ:
> -   msg[3] = 0;
> -   msg_bytes = 4;
> -   reply_bytes = 2;
> -   break;
> -   default:
> -   msg_bytes = 3;
> -   reply_bytes = 1;
> -   break;
> +   ret = drm_dp_aux_register_i2c_bus(&intel_dp->aux);
> +   if (ret < 0) {
> +   DRM_ERROR("drm_dp_aux_register_i2c_bus() for %s failed 
> (%d)\n",
> + name, ret);
> +   return;
> }
>
> -   /*
> -* DP1.2 sections 2.7.7.1.5.6.1 and 2.7.7.1.6.6.1: A DP Source device 
> is
> -* required to retry at least seven times upon receiving AUX_DEFER
> -* before giving up the AUX transaction.
> -*/
> -   for (retry = 0; retry < 7; retry++) {
> -   ret = intel_dp_aux_ch(intel_dp,
> - msg, msg_bytes,
> - reply, reply_bytes);
> -   if (ret < 0) {
> -   DRM_DEBUG_KMS("aux_ch failed %d\n", ret);
> -   goto out;
> -   }
> -
> -   switch ((reply[0] >> 4) & DP_AUX_NATIVE_REPLY_MASK) {
> -   case DP_AUX_NATIVE_REPLY_ACK:
> -   /* I2C-over-AUX Reply field is only valid
> -* when paired with AUX ACK.
> -*/
> -   break;
> -   case DP_AUX_NATIVE_REPLY_NACK:
> -   DRM_DEBUG_KMS("aux_ch native nack\n");
> -  

[Intel-gfx] [PATCH] drm/i915: finish off reverting eDP VDD changes

2014-03-17 Thread Jani Nikula
This is a small follow-up fix to the series of eDP VDD back and forth
we've had recently. This is effectively a combined revert of three
commits:

commit 2c2894f698fffd8ff53e1e1d3834f9e1035b1f39
Author: Paulo Zanoni 
Date:   Fri Mar 7 20:05:20 2014 -0300

drm/i915: properly disable the VDD when disabling the panel

commit b3064154dfd37deb386b1e459c54e1ca2460b3d5
Author: Patrik Jakobsson 
Date:   Tue Mar 4 00:42:44 2014 +0100

drm/i915: Don't just say it, actually force edp vdd

commit dff392dbd258381a6c3164f38420593f2d291e3b
Author: Paulo Zanoni 
Date:   Fri Dec 6 17:32:41 2013 -0200

drm/i915: don't touch the VDD when disabling the panel

which shows that we're pretty close back to where we started
already. The first two were basically reverting the last, but missing
the WARN. Add that back. We also OCD the intel_ prefix back to
intel_edp_panel_vdd_on() which was lost somewhere in between. The circle
closes.

For future reference, "drm/i915: don't touch the VDD when disabling the
panel" failed to take into account

commit 6cb49835da0426f69a2931bc2a0a8156344b0e41
Author: Daniel Vetter 
Date:   Sun May 20 17:14:50 2012 +0200

drm/i915: enable vdd when switching off the eDP panel

and

commit 35a38556d900b9cb5dfa2529c93944b847f8a8a4
Author: Daniel Vetter 
Date:   Sun Aug 12 22:17:14 2012 +0200

drm/i915: reorder edp disabling to fix ivb MacBook Air

Cc: Patrik Jakobsson 
Cc: Paulo Zanoni 
Signed-off-by: Jani Nikula 
---
 drivers/gpu/drm/i915/intel_ddi.c |2 +-
 drivers/gpu/drm/i915/intel_dp.c  |   14 --
 drivers/gpu/drm/i915/intel_drv.h |2 +-
 3 files changed, 10 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index fe1f5f012c4f..070bf2e78d61 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -1340,7 +1340,7 @@ static void intel_ddi_post_disable(struct intel_encoder 
*intel_encoder)
if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) {
struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF);
-   edp_panel_vdd_on(intel_dp);
+   intel_edp_panel_vdd_on(intel_dp);
intel_edp_panel_off(intel_dp);
}
 
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 7854cdbb462a..071d44fe2fc8 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -676,7 +676,7 @@ intel_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode,
int reply_bytes;
int ret;
 
-   edp_panel_vdd_on(intel_dp);
+   intel_edp_panel_vdd_on(intel_dp);
intel_dp_check_edp(intel_dp);
/* Set up the command byte */
if (mode & MODE_I2C_READ)
@@ -1161,7 +1161,7 @@ static  u32 ironlake_get_pp_control(struct intel_dp 
*intel_dp)
return control;
 }
 
-void edp_panel_vdd_on(struct intel_dp *intel_dp)
+void intel_edp_panel_vdd_on(struct intel_dp *intel_dp)
 {
struct drm_device *dev = intel_dp_to_dev(intel_dp);
struct drm_i915_private *dev_priv = dev->dev_private;
@@ -1329,6 +1329,8 @@ void intel_edp_panel_off(struct intel_dp *intel_dp)
 
edp_wait_backlight_off(intel_dp);
 
+   WARN(!intel_dp->want_panel_vdd, "Need VDD to turn off panel\n");
+
pp = ironlake_get_pp_control(intel_dp);
/* We need to switch off panel power _and_ force vdd, for otherwise some
 * panels get very unhappy and cease to work. */
@@ -1880,7 +1882,7 @@ static void intel_disable_dp(struct intel_encoder 
*encoder)
 
/* Make sure the panel is off before trying to change the mode. But also
 * ensure that we have vdd while we switch off the panel. */
-   edp_panel_vdd_on(intel_dp);
+   intel_edp_panel_vdd_on(intel_dp);
intel_edp_backlight_off(intel_dp);
intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF);
intel_edp_panel_off(intel_dp);
@@ -1913,7 +1915,7 @@ static void intel_enable_dp(struct intel_encoder *encoder)
if (WARN_ON(dp_reg & DP_PORT_EN))
return;
 
-   edp_panel_vdd_on(intel_dp);
+   intel_edp_panel_vdd_on(intel_dp);
intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
intel_dp_start_link_train(intel_dp);
intel_edp_panel_on(intel_dp);
@@ -2951,7 +2953,7 @@ intel_dp_probe_oui(struct intel_dp *intel_dp)
if (!(intel_dp->dpcd[DP_DOWN_STREAM_PORT_COUNT] & DP_OUI_SUPPORT))
return;
 
-   edp_panel_vdd_on(intel_dp);
+   intel_edp_panel_vdd_on(intel_dp);
 
if (intel_dp_aux_native_read_retry(intel_dp, DP_SINK_OUI, buf, 3))
DRM_DEBUG_KMS("Sink OUI: %02hx%02hx%02hx\n",
@@ -3748,7 +3750,7 @@ static bool intel_edp_init_connector(struct intel_dp 
*intel_dp,
return true;
 
/* Cache DPCD and EDID for edp. */
-   edp_panel_vdd_on(intel_dp);
+   intel_edp_panel_vdd_on(intel_dp);

[Intel-gfx] [PATCH for -fixes] Revert "drm/i915: don't touch the VDD when disabling the panel"

2014-03-17 Thread Jani Nikula
This reverts
commit dff392dbd258381a6c3164f38420593f2d291e3b
Author: Paulo Zanoni 
Date:   Fri Dec 6 17:32:41 2013 -0200

drm/i915: don't touch the VDD when disabling the panel

which didn't take into account

commit 6cb49835da0426f69a2931bc2a0a8156344b0e41
Author: Daniel Vetter 
Date:   Sun May 20 17:14:50 2012 +0200

drm/i915: enable vdd when switching off the eDP panel

and

commit 35a38556d900b9cb5dfa2529c93944b847f8a8a4
Author: Daniel Vetter 
Date:   Sun Aug 12 22:17:14 2012 +0200

drm/i915: reorder edp disabling to fix ivb MacBook Air

Unsurprisingly, various MacBooks failed.

Effectively the same has already been done in drm-intel-next-queued.

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=74628
Cc: Patrik Jakobsson 
Cc: Paulo Zanoni 
Signed-off-by: Jani Nikula 
---
 drivers/gpu/drm/i915/intel_ddi.c |1 +
 drivers/gpu/drm/i915/intel_dp.c  |   10 +-
 2 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index e06b9e017d6b..234ac5f7bc5a 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -1244,6 +1244,7 @@ static void intel_ddi_post_disable(struct intel_encoder 
*intel_encoder)
if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) {
struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF);
+   ironlake_edp_panel_vdd_on(intel_dp);
ironlake_edp_panel_off(intel_dp);
}
 
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 41bdac44dfc1..2688f6d64bb9 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -1249,17 +1249,24 @@ void ironlake_edp_panel_off(struct intel_dp *intel_dp)
 
DRM_DEBUG_KMS("Turn eDP power off\n");
 
+   WARN(!intel_dp->want_panel_vdd, "Need VDD to turn off panel\n");
+
pp = ironlake_get_pp_control(intel_dp);
/* We need to switch off panel power _and_ force vdd, for otherwise some
 * panels get very unhappy and cease to work. */
-   pp &= ~(POWER_TARGET_ON | PANEL_POWER_RESET | EDP_BLC_ENABLE);
+   pp &= ~(POWER_TARGET_ON | EDP_FORCE_VDD | PANEL_POWER_RESET | 
EDP_BLC_ENABLE);
 
pp_ctrl_reg = _pp_ctrl_reg(intel_dp);
 
I915_WRITE(pp_ctrl_reg, pp);
POSTING_READ(pp_ctrl_reg);
 
+   intel_dp->want_panel_vdd = false;
+
ironlake_wait_panel_off(intel_dp);
+
+   /* We got a reference when we enabled the VDD. */
+   intel_runtime_pm_put(dev_priv);
 }
 
 void ironlake_edp_backlight_on(struct intel_dp *intel_dp)
@@ -1784,6 +1791,7 @@ static void intel_disable_dp(struct intel_encoder 
*encoder)
 
/* Make sure the panel is off before trying to change the mode. But also
 * ensure that we have vdd while we switch off the panel. */
+   ironlake_edp_panel_vdd_on(intel_dp);
ironlake_edp_backlight_off(intel_dp);
intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF);
ironlake_edp_panel_off(intel_dp);
-- 
1.7.9.5

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH 5/6] drm/i915/dp: move dp aux ch register init to aux init

2014-03-17 Thread Rodrigo Vivi
I would prefer an else instead of unecessary comparisons and
assignment that will be override..

But anyway it works, so feel free to use:
Reviewed-by: Rodrigo Vivi 

On Fri, Mar 14, 2014 at 11:51 AM, Jani Nikula  wrote:
> Do a slight rearrangement of the switch to prep for follow-up.
>
> Signed-off-by: Jani Nikula 
> ---
>  drivers/gpu/drm/i915/intel_dp.c |   42 
> ---
>  1 file changed, 22 insertions(+), 20 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
> index 24cbf4bd36c4..71a76d00d634 100644
> --- a/drivers/gpu/drm/i915/intel_dp.c
> +++ b/drivers/gpu/drm/i915/intel_dp.c
> @@ -643,6 +643,28 @@ static void
>  intel_dp_aux_init(struct intel_dp *intel_dp, struct intel_connector 
> *connector)
>  {
> struct drm_device *dev = intel_dp_to_dev(intel_dp);
> +   struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
> +   enum port port = intel_dig_port->port;
> +
> +   switch (port) {
> +   case PORT_A:
> +   intel_dp->aux_ch_ctl_reg = DPA_AUX_CH_CTL;
> +   break;
> +   case PORT_B:
> +   intel_dp->aux_ch_ctl_reg = PCH_DPB_AUX_CH_CTL;
> +   break;
> +   case PORT_C:
> +   intel_dp->aux_ch_ctl_reg = PCH_DPC_AUX_CH_CTL;
> +   break;
> +   case PORT_D:
> +   intel_dp->aux_ch_ctl_reg = PCH_DPD_AUX_CH_CTL;
> +   break;
> +   default:
> +   BUG();
> +   }
> +
> +   if (!HAS_DDI(dev))
> +   intel_dp->aux_ch_ctl_reg = intel_dp->output_reg + 0x10;
>
> intel_dp->aux.dev = dev->dev;
> intel_dp->aux.transfer = intel_dp_aux_transfer;
> @@ -3849,26 +3871,6 @@ intel_dp_init_connector(struct intel_digital_port 
> *intel_dig_port,
> intel_connector->get_hw_state = intel_connector_get_hw_state;
> intel_connector->unregister = intel_dp_connector_unregister;
>
> -   intel_dp->aux_ch_ctl_reg = intel_dp->output_reg + 0x10;
> -   if (HAS_DDI(dev)) {
> -   switch (intel_dig_port->port) {
> -   case PORT_A:
> -   intel_dp->aux_ch_ctl_reg = DPA_AUX_CH_CTL;
> -   break;
> -   case PORT_B:
> -   intel_dp->aux_ch_ctl_reg = PCH_DPB_AUX_CH_CTL;
> -   break;
> -   case PORT_C:
> -   intel_dp->aux_ch_ctl_reg = PCH_DPC_AUX_CH_CTL;
> -   break;
> -   case PORT_D:
> -   intel_dp->aux_ch_ctl_reg = PCH_DPD_AUX_CH_CTL;
> -   break;
> -   default:
> -   BUG();
> -   }
> -   }
> -
> /* Set up the DDC bus. */
> switch (port) {
> case PORT_A:
> --
> 1.7.9.5
>
> ___
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx



-- 
Rodrigo Vivi
Blog: http://blog.vivi.eng.br
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH 2/6] drm/i915/dp: split edp_panel_vdd_on() for reuse

2014-03-17 Thread Rodrigo Vivi
Reviewed-by: Rodrigo Vivi 

On Fri, Mar 14, 2014 at 11:51 AM, Jani Nikula  wrote:
> Introduce _edp_panel_vdd_on() that returns true if the call enabled vdd,
> and a matching disable is needed. Keep edp_panel_vdd_on() as a helper
> for when it is expected the vdd is off.
>
> Signed-off-by: Jani Nikula 
> ---
>  drivers/gpu/drm/i915/intel_dp.c |   22 --
>  1 file changed, 16 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
> index bb66f9301cd9..94e7577da484 100644
> --- a/drivers/gpu/drm/i915/intel_dp.c
> +++ b/drivers/gpu/drm/i915/intel_dp.c
> @@ -91,6 +91,7 @@ static struct intel_dp *intel_attached_dp(struct 
> drm_connector *connector)
>  }
>
>  static void intel_dp_link_down(struct intel_dp *intel_dp);
> +static bool _edp_panel_vdd_on(struct intel_dp *intel_dp);
>  static void edp_panel_vdd_on(struct intel_dp *intel_dp);
>  static void edp_panel_vdd_off(struct intel_dp *intel_dp, bool sync);
>
> @@ -1162,23 +1163,21 @@ static  u32 ironlake_get_pp_control(struct intel_dp 
> *intel_dp)
> return control;
>  }
>
> -static void edp_panel_vdd_on(struct intel_dp *intel_dp)
> +static bool _edp_panel_vdd_on(struct intel_dp *intel_dp)
>  {
> struct drm_device *dev = intel_dp_to_dev(intel_dp);
> struct drm_i915_private *dev_priv = dev->dev_private;
> u32 pp;
> u32 pp_stat_reg, pp_ctrl_reg;
> +   bool need_to_disable = !intel_dp->want_panel_vdd;
>
> if (!is_edp(intel_dp))
> -   return;
> -
> -   WARN(intel_dp->want_panel_vdd,
> -"eDP VDD already requested on\n");
> +   return false;
>
> intel_dp->want_panel_vdd = true;
>
> if (edp_have_panel_vdd(intel_dp))
> -   return;
> +   return need_to_disable;
>
> intel_runtime_pm_get(dev_priv);
>
> @@ -1204,6 +1203,17 @@ static void edp_panel_vdd_on(struct intel_dp *intel_dp)
> DRM_DEBUG_KMS("eDP was not running\n");
> msleep(intel_dp->panel_power_up_delay);
> }
> +
> +   return need_to_disable;
> +}
> +
> +static void edp_panel_vdd_on(struct intel_dp *intel_dp)
> +{
> +   if (is_edp(intel_dp)) {
> +   bool vdd = _edp_panel_vdd_on(intel_dp);
> +
> +   WARN(!vdd, "eDP VDD already requested on\n");
> +   }
>  }
>
>  static void edp_panel_vdd_off_sync(struct intel_dp *intel_dp)
> --
> 1.7.9.5
>
> ___
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx



-- 
Rodrigo Vivi
Blog: http://blog.vivi.eng.br
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH 3/6] drm/i915/dp: move edp vdd enable/disable at a lower level in i2c-over-aux

2014-03-17 Thread Rodrigo Vivi
Reviewed-by: Rodrigo Vivi 

On Fri, Mar 14, 2014 at 11:51 AM, Jani Nikula  wrote:
> This is prep work for conversion to generic drm i2c-over-aux helpers
> where we won't have the function to do this at.
>
> Signed-off-by: Jani Nikula 
> ---
>  drivers/gpu/drm/i915/intel_dp.c |9 ++---
>  1 file changed, 6 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
> index 94e7577da484..22134edc03dd 100644
> --- a/drivers/gpu/drm/i915/intel_dp.c
> +++ b/drivers/gpu/drm/i915/intel_dp.c
> @@ -461,6 +461,9 @@ intel_dp_aux_ch(struct intel_dp *intel_dp,
> uint32_t status;
> int try, clock = 0;
> bool has_aux_irq = HAS_AUX_IRQ(dev);
> +   bool vdd;
> +
> +   vdd = _edp_panel_vdd_on(intel_dp);
>
> /* dp aux is extremely sensitive to irq latency, hence request the
>  * lowest possible wakeup latency and so prevent the cpu from going 
> into
> @@ -566,6 +569,9 @@ out:
> pm_qos_update_request(&dev_priv->pm_qos, PM_QOS_DEFAULT_VALUE);
> intel_aux_display_runtime_put(dev_priv);
>
> +   if (vdd)
> +   edp_panel_vdd_off(intel_dp, false);
> +
> return ret;
>  }
>
> @@ -678,8 +684,6 @@ intel_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode,
> int reply_bytes;
> int ret;
>
> -   edp_panel_vdd_on(intel_dp);
> -   intel_dp_check_edp(intel_dp);
> /* Set up the command byte */
> if (mode & MODE_I2C_READ)
> msg[0] = DP_AUX_I2C_READ << 4;
> @@ -781,7 +785,6 @@ intel_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode,
> ret = -EREMOTEIO;
>
>  out:
> -   edp_panel_vdd_off(intel_dp, false);
> return ret;
>  }
>
> --
> 1.7.9.5
>
> ___
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx



-- 
Rodrigo Vivi
Blog: http://blog.vivi.eng.br
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH 1/6] drm/dp: let drivers specify the name of the I2C-over-AUX adapter

2014-03-17 Thread Rodrigo Vivi
Reviewed-by: Rodrigo Vivi 

//Although I know it has been already reviewed ;)

On Fri, Mar 14, 2014 at 11:51 AM, Jani Nikula  wrote:
> Let the drivers specify the name of the I2C-over-AUX adapter to maintain
> backwards compatibility in the sysfs when converting to the new
> I2C-over-AUX helper infrastructure.
>
> The i915 driver currently uses DPDDC-A to DPDDC-D as names for the DP
> i2c adapters. These names show up in the i2c sysfs name attribute. We'd
> like to be able to maintain that when switching over to the new helpers.
>
> Due to i2c device and connector cleanup ordering issues we also recently
> made the drm device (instead of connector) the parent of the i2c
> adapters:
>
> commit 80f65de3c9b8101c1613fa82df500ba6a099a11c
> Author: Imre Deak 
> Date:   Tue Feb 11 17:12:49 2014 +0200
>
> drm/i915: dp: fix order of dp aux i2c device cleanup
>
> With the name picked up from the adapter parent using dev_name(), it
> would be the same for all i2c adapters with the current I2C-over-AUX
> helpers.
>
> Signed-off-by: Jani Nikula 
> Reviewed-by: Thierry Reding 
> ---
>  drivers/gpu/drm/drm_dp_helper.c |3 ++-
>  include/drm/drm_dp_helper.h |4 
>  2 files changed, 6 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c
> index 35251af3b14e..17832d048147 100644
> --- a/drivers/gpu/drm/drm_dp_helper.c
> +++ b/drivers/gpu/drm/drm_dp_helper.c
> @@ -726,7 +726,8 @@ int drm_dp_aux_register_i2c_bus(struct drm_dp_aux *aux)
> aux->ddc.dev.parent = aux->dev;
> aux->ddc.dev.of_node = aux->dev->of_node;
>
> -   strncpy(aux->ddc.name, dev_name(aux->dev), sizeof(aux->ddc.name));
> +   strlcpy(aux->ddc.name, aux->name ? aux->name : dev_name(aux->dev),
> +   sizeof(aux->ddc.name));
>
> return i2c_add_adapter(&aux->ddc);
>  }
> diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h
> index 42947566e755..b4f58914bf7d 100644
> --- a/include/drm/drm_dp_helper.h
> +++ b/include/drm/drm_dp_helper.h
> @@ -438,6 +438,9 @@ struct drm_dp_aux_msg {
>   * The .dev field should be set to a pointer to the device that implements
>   * the AUX channel.
>   *
> + * The .name field may be used to specify the name of the I2C adapter. If 
> set to
> + * NULL, dev_name() of .dev will be used.
> + *
>   * Drivers provide a hardware-specific implementation of how transactions
>   * are executed via the .transfer() function. A pointer to a drm_dp_aux_msg
>   * structure describing the transaction is passed into this function. Upon
> @@ -455,6 +458,7 @@ struct drm_dp_aux_msg {
>   * should call drm_dp_aux_unregister_i2c_bus() to remove the I2C adapter.
>   */
>  struct drm_dp_aux {
> +   const char *name;
> struct i2c_adapter ddc;
> struct device *dev;
>
> --
> 1.7.9.5
>
> ___
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx



-- 
Rodrigo Vivi
Blog: http://blog.vivi.eng.br
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH 4/6] drm/i915/dp: use the new drm helpers for dp aux

2014-03-17 Thread Rodrigo Vivi
On Fri, Mar 14, 2014 at 11:51 AM, Jani Nikula  wrote:
> Functionality remains largely the same as before.
>
> Signed-off-by: Jani Nikula 
> ---
>  drivers/gpu/drm/i915/intel_dp.c  |  257 
> +-
>  drivers/gpu/drm/i915/intel_drv.h |1 +
>  2 files changed, 116 insertions(+), 142 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
> index 22134edc03dd..24cbf4bd36c4 100644
> --- a/drivers/gpu/drm/i915/intel_dp.c
> +++ b/drivers/gpu/drm/i915/intel_dp.c
> @@ -575,97 +575,77 @@ out:
> return ret;
>  }
>
> -/* Write data to the aux channel in native mode */
> -static int
> -intel_dp_aux_native_write(struct intel_dp *intel_dp,
> - uint16_t address, uint8_t *send, int send_bytes)
> +#define HEADER_SIZE4
> +static ssize_t
> +intel_dp_aux_transfer(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg)
>  {
> +   struct intel_dp *intel_dp = container_of(aux, struct intel_dp, aux);
> +   uint8_t txbuf[20], rxbuf[20];
> +   size_t txsize, rxsize;
> int ret;
> -   uint8_t msg[20];
> -   int msg_bytes;
> -   uint8_t ack;
> -   int retry;
>
> -   if (WARN_ON(send_bytes > 16))
> -   return -E2BIG;
> +   txbuf[0] = msg->request << 4;
> +   txbuf[1] = msg->address >> 8;
> +   txbuf[2] = msg->address & 0xff;
> +   txbuf[3] = msg->size - 1;
>
> -   intel_dp_check_edp(intel_dp);
> -   msg[0] = DP_AUX_NATIVE_WRITE << 4;
> -   msg[1] = address >> 8;
> -   msg[2] = address & 0xff;
> -   msg[3] = send_bytes - 1;
> -   memcpy(&msg[4], send, send_bytes);
> -   msg_bytes = send_bytes + 4;
> -   for (retry = 0; retry < 7; retry++) {

we were retrying 7 times always, but now we are now retrying only 3
times or even none.
Couldn't it trigger some new bug or regression?

> -   ret = intel_dp_aux_ch(intel_dp, msg, msg_bytes, &ack, 1);
> -   if (ret < 0)
> -   return ret;
> -   ack >>= 4;
> -   if ((ack & DP_AUX_NATIVE_REPLY_MASK) == 
> DP_AUX_NATIVE_REPLY_ACK)
> -   return send_bytes;
> -   else if ((ack & DP_AUX_NATIVE_REPLY_MASK) == 
> DP_AUX_NATIVE_REPLY_DEFER)
> -   usleep_range(400, 500);

we are also not checking this ack x defer (here nor in native_write)
replies anymore.
Don't we need it anymore? why?

> -   else
> -   return -EIO;
> -   }
> +   switch (msg->request & ~DP_AUX_I2C_MOT) {
> +   case DP_AUX_NATIVE_WRITE:
> +   case DP_AUX_I2C_WRITE:
> +   txsize = HEADER_SIZE + msg->size;
> +   rxsize = 1;
>
> -   DRM_ERROR("too many retries, giving up\n");
> -   return -EIO;
> -}
> +   if (WARN_ON(txsize > 20))
> +   return -E2BIG;
>
> -/* Write a single byte to the aux channel in native mode */
> -static int
> -intel_dp_aux_native_write_1(struct intel_dp *intel_dp,
> -   uint16_t address, uint8_t byte)
> -{
> -   return intel_dp_aux_native_write(intel_dp, address, &byte, 1);
> -}
> +   memcpy(txbuf + HEADER_SIZE, msg->buffer, msg->size);
>
> -/* read bytes from a native aux channel */
> -static int
> -intel_dp_aux_native_read(struct intel_dp *intel_dp,
> -uint16_t address, uint8_t *recv, int recv_bytes)
> -{
> -   uint8_t msg[4];
> -   int msg_bytes;
> -   uint8_t reply[20];
> -   int reply_bytes;
> -   uint8_t ack;
> -   int ret;
> -   int retry;
> +   ret = intel_dp_aux_ch(intel_dp, txbuf, txsize, rxbuf, rxsize);
> +   if (ret > 0) {
> +   msg->reply = rxbuf[0] >> 4;
>
> -   if (WARN_ON(recv_bytes > 19))
> -   return -E2BIG;
> +   /* Return payload size. */
> +   ret = msg->size;
> +   }
> +   break;
>
> -   intel_dp_check_edp(intel_dp);
> -   msg[0] = DP_AUX_NATIVE_READ << 4;
> -   msg[1] = address >> 8;
> -   msg[2] = address & 0xff;
> -   msg[3] = recv_bytes - 1;
> +   case DP_AUX_NATIVE_READ:
> +   case DP_AUX_I2C_READ:
> +   txsize = HEADER_SIZE;
> +   rxsize = msg->size + 1;
>
> -   msg_bytes = 4;
> -   reply_bytes = recv_bytes + 1;
> +   if (WARN_ON(rxsize > 20))
> +   return -E2BIG;
>
> -   for (retry = 0; retry < 7; retry++) {
> -   ret = intel_dp_aux_ch(intel_dp, msg, msg_bytes,
> - reply, reply_bytes);
> -   if (ret == 0)
> -   return -EPROTO;
> -   if (ret < 0)
> -   return ret;
> -   ack = reply[0] >> 4;
> -   if ((ack & DP_AUX_NATIVE_REPLY_MASK) == 
> DP_AUX_NATIVE_REPLY_ACK) {
> -   memcpy(recv, reply + 1, ret - 1);
> -

Re: [Intel-gfx] [PATCH] drm/i915: Don't del_timer_sync uninitialized timer

2014-03-17 Thread Daniel Vetter
On Mon, Mar 17, 2014 at 01:17:32PM +, Chris Wilson wrote:
> On Sat, Mar 15, 2014 at 11:30:18AM -0700, Ben Widawsky wrote:
> > On Sat, Mar 15, 2014 at 03:20:23PM +, Chris Wilson wrote:
> > > On Sat, Mar 15, 2014 at 12:47:22PM +0100, Daniel Vetter wrote:
> > > > On Fri, Mar 14, 2014 at 05:21:36PM -0700, Ben Widawsky wrote:
> > > > > Broken by:
> > > > > commit 0294ae7b44bba7ab0d4cef9a8736287f38bdb4fd
> > > > > Author: Chris Wilson 
> > > > > Date:   Thu Mar 13 12:00:29 2014 +
> > > > > 
> > > > > drm/i915: Consolidate forcewake resetting to a single function
> > > > > 
> > > > > Cc: Chris Wilson 
> > > > > Cc: Mika Kuoppala 
> > > > > Signed-off-by: Ben Widawsky 
> > > > > ---
> > > > >  drivers/gpu/drm/i915/intel_uncore.c | 6 +++---
> > > > >  1 file changed, 3 insertions(+), 3 deletions(-)
> > > > > 
> > > > > diff --git a/drivers/gpu/drm/i915/intel_uncore.c 
> > > > > b/drivers/gpu/drm/i915/intel_uncore.c
> > > > > index e6bb421..7e55ceb 100644
> > > > > --- a/drivers/gpu/drm/i915/intel_uncore.c
> > > > > +++ b/drivers/gpu/drm/i915/intel_uncore.c
> > > > > @@ -362,6 +362,9 @@ void intel_uncore_early_sanitize(struct 
> > > > > drm_device *dev)
> > > > >  {
> > > > >   struct drm_i915_private *dev_priv = dev->dev_private;
> > > > >  
> > > > > + setup_timer(&dev_priv->uncore.force_wake_timer,
> > > > > + gen6_force_wake_timer, (unsigned long)dev_priv);
> > > > 
> > > > We call early_sanitize also from our resume code, so this will now
> > > > re-setup the timer again. We generally don't do that since if we ever 
> > > > leak
> > > > the timer to here in an enabled state it causes havoc.
> > > 
> > > Gah, really? intel_uncore_early_init()! There must be a clean way to
> > > break this up.
> > > -Chris
> > 
> > At least in the code base I was looking at, we currently do this also,
> > so I didn't think this was any worse.
> > 
> > With lockdep turned on, the module will not even load, so please either
> > revert the original, or merge this.
> 
> I think we can just:
> 
> diff --git a/drivers/gpu/drm/i915/intel_uncore.c 
> b/drivers/gpu/drm/i915/intel_uncore.c
> index a62ff21..c9fcc20 100644
> --- a/drivers/gpu/drm/i915/intel_uncore.c
> +++ b/drivers/gpu/drm/i915/intel_uncore.c
> @@ -317,9 +317,10 @@ static void intel_uncore_forcewake_reset(struct 
> drm_device *dev, bool restore)
>  {
> struct drm_i915_private *dev_priv = dev->dev_private;
> unsigned long irqflags;
> -   int pending;
> +   int pending = 0;
>  
> -   pending = del_timer_sync(&dev_priv->uncore.force_wake_timer);
> +   if (dev_priv->uncore.force_wake_timer.function)
> +   pending = del_timer_sync(&dev_priv->uncore.force_wake_timer);
>  
> /* Hold uncore.lock across reset to prevent any register access
>  * with forcewake not set correctly
> 
> i.e.
> 
> -   del_timer_sync(&dev_priv->uncore.force_wake_timer);
> +   if (dev_priv->uncore.force_wake_timer.function)
> +   del_timer_sync(&dev_priv->uncore.force_wake_timer);

I've thought of this:

diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index e4d2b9f15ae2..9faee49f210d 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -1608,8 +1608,6 @@ int i915_driver_load(struct drm_device *dev, unsigned 
long flags)
goto put_bridge;
}
 
-   intel_uncore_early_sanitize(dev);
-
/* This must be called before any calls to HAS_PCH_* */
intel_detect_pch(dev);
 
diff --git a/drivers/gpu/drm/i915/intel_uncore.c 
b/drivers/gpu/drm/i915/intel_uncore.c
index e2e328d86aff..c3832d9270a6 100644
--- a/drivers/gpu/drm/i915/intel_uncore.c
+++ b/drivers/gpu/drm/i915/intel_uncore.c
@@ -736,6 +736,8 @@ void intel_uncore_init(struct drm_device *dev)
setup_timer(&dev_priv->uncore.force_wake_timer,
gen6_force_wake_timer, (unsigned long)dev_priv);
 
+   intel_uncore_early_sanitize(dev);
+
if (IS_VALLEYVIEW(dev)) {
dev_priv->uncore.funcs.force_wake_get = __vlv_force_wake_get;
dev_priv->uncore.funcs.force_wake_put = __vlv_force_wake_put;

-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] v3.14-rc7: Backlight control broken on Dell XPS13

2014-03-17 Thread Daniel Vetter
Please never just send a mail to maintainers, always cc mailing lists.

On Mon, Mar 17, 2014 at 2:33 PM, Romain Francoise  wrote:
> Moving from v3.13 to v3.14-rc7 breaks backlight control on my Dell
> XPS13, which I assume is because of this change:
>
> http://git.kernel.org/linus/bc0bb9fd1c7810407ab810d204bbaecb255fddde
>
> Is this right? Is backlight supposed to work correctly without the quirk
> now?

Yeah, it should work without the quirk. Have you tested with the patch
reverted to confirm that it's indeed this commit and not something
else (e.g. in the acpi code)?
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH] drm/i915: Don't del_timer_sync uninitialized timer

2014-03-17 Thread Chris Wilson
On Sat, Mar 15, 2014 at 11:30:18AM -0700, Ben Widawsky wrote:
> On Sat, Mar 15, 2014 at 03:20:23PM +, Chris Wilson wrote:
> > On Sat, Mar 15, 2014 at 12:47:22PM +0100, Daniel Vetter wrote:
> > > On Fri, Mar 14, 2014 at 05:21:36PM -0700, Ben Widawsky wrote:
> > > > Broken by:
> > > > commit 0294ae7b44bba7ab0d4cef9a8736287f38bdb4fd
> > > > Author: Chris Wilson 
> > > > Date:   Thu Mar 13 12:00:29 2014 +
> > > > 
> > > > drm/i915: Consolidate forcewake resetting to a single function
> > > > 
> > > > Cc: Chris Wilson 
> > > > Cc: Mika Kuoppala 
> > > > Signed-off-by: Ben Widawsky 
> > > > ---
> > > >  drivers/gpu/drm/i915/intel_uncore.c | 6 +++---
> > > >  1 file changed, 3 insertions(+), 3 deletions(-)
> > > > 
> > > > diff --git a/drivers/gpu/drm/i915/intel_uncore.c 
> > > > b/drivers/gpu/drm/i915/intel_uncore.c
> > > > index e6bb421..7e55ceb 100644
> > > > --- a/drivers/gpu/drm/i915/intel_uncore.c
> > > > +++ b/drivers/gpu/drm/i915/intel_uncore.c
> > > > @@ -362,6 +362,9 @@ void intel_uncore_early_sanitize(struct drm_device 
> > > > *dev)
> > > >  {
> > > > struct drm_i915_private *dev_priv = dev->dev_private;
> > > >  
> > > > +   setup_timer(&dev_priv->uncore.force_wake_timer,
> > > > +   gen6_force_wake_timer, (unsigned long)dev_priv);
> > > 
> > > We call early_sanitize also from our resume code, so this will now
> > > re-setup the timer again. We generally don't do that since if we ever leak
> > > the timer to here in an enabled state it causes havoc.
> > 
> > Gah, really? intel_uncore_early_init()! There must be a clean way to
> > break this up.
> > -Chris
> 
> At least in the code base I was looking at, we currently do this also,
> so I didn't think this was any worse.
> 
> With lockdep turned on, the module will not even load, so please either
> revert the original, or merge this.

I think we can just:

diff --git a/drivers/gpu/drm/i915/intel_uncore.c 
b/drivers/gpu/drm/i915/intel_uncore.c
index a62ff21..c9fcc20 100644
--- a/drivers/gpu/drm/i915/intel_uncore.c
+++ b/drivers/gpu/drm/i915/intel_uncore.c
@@ -317,9 +317,10 @@ static void intel_uncore_forcewake_reset(struct drm_device 
*dev, bool restore)
 {
struct drm_i915_private *dev_priv = dev->dev_private;
unsigned long irqflags;
-   int pending;
+   int pending = 0;
 
-   pending = del_timer_sync(&dev_priv->uncore.force_wake_timer);
+   if (dev_priv->uncore.force_wake_timer.function)
+   pending = del_timer_sync(&dev_priv->uncore.force_wake_timer);
 
/* Hold uncore.lock across reset to prevent any register access
 * with forcewake not set correctly

i.e.

-   del_timer_sync(&dev_priv->uncore.force_wake_timer);
+   if (dev_priv->uncore.force_wake_timer.function)
+   del_timer_sync(&dev_priv->uncore.force_wake_timer);

-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH 1/3] lib: Export interval_tree

2014-03-17 Thread David Woodhouse
On Mon, 2014-03-17 at 12:21 +, Chris Wilson wrote:
> +EXPORT_SYMBOL(interval_tree_insert);
> +EXPORT_SYMBOL(interval_tree_remove);
> +EXPORT_SYMBOL(interval_tree_iter_first);
> +EXPORT_SYMBOL(interval_tree_iter_next);

I'd prefer to see EXPORT_SYMBOL_GPL for this.


-- 
dwmw2



smime.p7s
Description: S/MIME cryptographic signature
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 1/3] lib: Export interval_tree

2014-03-17 Thread Chris Wilson
lib/interval_tree.c provides a simple interface for an interval-tree
(an augmented red-black tree) but is only built when testing the generic
macros for building interval-trees. For drivers with modest needs,
export the simple interval-tree library as is.

v2: Lots of help from Michel Lespinasse to only compile the code
as required:
- make INTERVAL_TREE a config option
- make INTERVAL_TREE_TEST select the library functions
  and sanitize the filenames & Makefile
- prepare interval_tree for being built as a module if required

Signed-off-by: Chris Wilson 
Cc: Michel Lespinasse 
Cc: Rik van Riel 
Cc: Peter Zijlstra 
Cc: Andrea Arcangeli 
Cc: David Woodhouse 
Cc: Andrew Morton 
Reviewed-by: Michel Lespinasse 
[Acked for inclusion via drm/i915 by Andrew Morton.]
---
 lib/Kconfig   |  14 ++
 lib/Kconfig.debug |   1 +
 lib/Makefile  |   3 +-
 lib/interval_tree.c   |   6 +++
 lib/interval_tree_test.c  | 106 ++
 lib/interval_tree_test_main.c | 106 --
 6 files changed, 128 insertions(+), 108 deletions(-)
 create mode 100644 lib/interval_tree_test.c
 delete mode 100644 lib/interval_tree_test_main.c

diff --git a/lib/Kconfig b/lib/Kconfig
index 991c98bc4a3f..04270aae4b60 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -322,6 +322,20 @@ config TEXTSEARCH_FSM
 config BTREE
boolean
 
+config INTERVAL_TREE
+   boolean
+   help
+ Simple, embeddable, interval-tree. Can find the start of an
+ overlapping range in log(n) time and then iterate over all
+ overlapping nodes. The algorithm is implemented as an
+ augmented rbtree.
+
+ See:
+
+   Documentation/rbtree.txt
+
+ for more information.
+
 config ASSOCIATIVE_ARRAY
bool
help
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index a48abeac753f..135a6a0588c9 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -1487,6 +1487,7 @@ config RBTREE_TEST
 config INTERVAL_TREE_TEST
tristate "Interval tree test"
depends on m && DEBUG_KERNEL
+   select INTERVAL_TREE
help
  A benchmark measuring the performance of the interval tree library
 
diff --git a/lib/Makefile b/lib/Makefile
index 48140e3ba73f..0969494f20d1 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -50,6 +50,7 @@ CFLAGS_hweight.o = $(subst 
$(quote),,$(CONFIG_ARCH_HWEIGHT_CFLAGS))
 obj-$(CONFIG_GENERIC_HWEIGHT) += hweight.o
 
 obj-$(CONFIG_BTREE) += btree.o
+obj-$(CONFIG_INTERVAL_TREE) += interval_tree.o
 obj-$(CONFIG_ASSOCIATIVE_ARRAY) += assoc_array.o
 obj-$(CONFIG_DEBUG_PREEMPT) += smp_processor_id.o
 obj-$(CONFIG_DEBUG_LIST) += list_debug.o
@@ -155,8 +156,6 @@ lib-$(CONFIG_LIBFDT) += $(libfdt_files)
 obj-$(CONFIG_RBTREE_TEST) += rbtree_test.o
 obj-$(CONFIG_INTERVAL_TREE_TEST) += interval_tree_test.o
 
-interval_tree_test-objs := interval_tree_test_main.o interval_tree.o
-
 obj-$(CONFIG_PERCPU_TEST) += percpu_test.o
 
 obj-$(CONFIG_ASN1) += asn1_decoder.o
diff --git a/lib/interval_tree.c b/lib/interval_tree.c
index e6eb406f2d65..e4109f624e51 100644
--- a/lib/interval_tree.c
+++ b/lib/interval_tree.c
@@ -1,6 +1,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #define START(node) ((node)->start)
 #define LAST(node)  ((node)->last)
@@ -8,3 +9,8 @@
 INTERVAL_TREE_DEFINE(struct interval_tree_node, rb,
 unsigned long, __subtree_last,
 START, LAST,, interval_tree)
+
+EXPORT_SYMBOL(interval_tree_insert);
+EXPORT_SYMBOL(interval_tree_remove);
+EXPORT_SYMBOL(interval_tree_iter_first);
+EXPORT_SYMBOL(interval_tree_iter_next);
diff --git a/lib/interval_tree_test.c b/lib/interval_tree_test.c
new file mode 100644
index ..245900b98c8e
--- /dev/null
+++ b/lib/interval_tree_test.c
@@ -0,0 +1,106 @@
+#include 
+#include 
+#include 
+#include 
+
+#define NODES100
+#define PERF_LOOPS   10
+#define SEARCHES 100
+#define SEARCH_LOOPS 1
+
+static struct rb_root root = RB_ROOT;
+static struct interval_tree_node nodes[NODES];
+static u32 queries[SEARCHES];
+
+static struct rnd_state rnd;
+
+static inline unsigned long
+search(unsigned long query, struct rb_root *root)
+{
+   struct interval_tree_node *node;
+   unsigned long results = 0;
+
+   for (node = interval_tree_iter_first(root, query, query); node;
+node = interval_tree_iter_next(node, query, query))
+   results++;
+   return results;
+}
+
+static void init(void)
+{
+   int i;
+   for (i = 0; i < NODES; i++) {
+   u32 a = prandom_u32_state(&rnd);
+   u32 b = prandom_u32_state(&rnd);
+   if (a <= b) {
+   nodes[i].start = a;
+   nodes[i].last = b;
+   } else {
+   nodes[i].start = b;
+   nodes[i].last = a;
+   }
+   }
+   for (i = 0; 

[Intel-gfx] [PATCH 2/3] drm/i915: Do not call retire_requests from wait_for_rendering

2014-03-17 Thread Chris Wilson
A common issue we have is that retiring requests causes recursion
through GTT manipulation or page table manipulation which we can only
handle at very specific points. However, to maintain internal
consistency (enforced through our sanity checks on write_domain at
various points in the GEM object lifecycle) we do need to retire the
object prior to marking it with a new write_domain, and also clear the
write_domain for the implicit flush following a batch.

Note that this then allows the unbound objects to still be on the active
lists, and so care must be taken when removing objects from unbound lists
(similar to the caveats we face processing the bound lists).

v2: Fix i915_gem_shrink_all() to handle updated object lifetime rules,
by refactoring it to call into __i915_gem_shrink().

v3: Missed an object-retire prior to changing cache domains in
i915_gem_object_set_cache_leve()

v4: Rebase

Signed-off-by: Chris Wilson 
Tested-by: Ville Syrjälä 
---
 drivers/gpu/drm/i915/i915_gem.c| 112 -
 drivers/gpu/drm/i915/i915_gem_execbuffer.c |   3 +
 2 files changed, 66 insertions(+), 49 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 58704ce62e3e..5cf4d80de867 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -44,6 +44,9 @@ static void i915_gem_object_flush_cpu_write_domain(struct 
drm_i915_gem_object *o
 static __must_check int
 i915_gem_object_wait_rendering(struct drm_i915_gem_object *obj,
   bool readonly);
+static void
+i915_gem_object_retire(struct drm_i915_gem_object *obj);
+
 static int i915_gem_phys_pwrite(struct drm_device *dev,
struct drm_i915_gem_object *obj,
struct drm_i915_gem_pwrite *args,
@@ -502,6 +505,8 @@ int i915_gem_obj_prepare_shmem_read(struct 
drm_i915_gem_object *obj,
ret = i915_gem_object_wait_rendering(obj, true);
if (ret)
return ret;
+
+   i915_gem_object_retire(obj);
}
 
ret = i915_gem_object_get_pages(obj);
@@ -917,6 +922,8 @@ i915_gem_shmem_pwrite(struct drm_device *dev,
ret = i915_gem_object_wait_rendering(obj, false);
if (ret)
return ret;
+
+   i915_gem_object_retire(obj);
}
/* Same trick applies to invalidate partially written cachelines read
 * before writing. */
@@ -1304,7 +1311,8 @@ static int
 i915_gem_object_wait_rendering__tail(struct drm_i915_gem_object *obj,
 struct intel_ring_buffer *ring)
 {
-   i915_gem_retire_requests_ring(ring);
+   if (!obj->active)
+   return 0;
 
/* Manually manage the write flush as we may have not yet
 * retired the buffer.
@@ -1314,7 +1322,6 @@ i915_gem_object_wait_rendering__tail(struct 
drm_i915_gem_object *obj,
 * we know we have passed the last write.
 */
obj->last_write_seqno = 0;
-   obj->base.write_domain &= ~I915_GEM_GPU_DOMAINS;
 
return 0;
 }
@@ -1949,58 +1956,58 @@ static unsigned long
 __i915_gem_shrink(struct drm_i915_private *dev_priv, long target,
  bool purgeable_only)
 {
-   struct list_head still_bound_list;
-   struct drm_i915_gem_object *obj, *next;
+   struct list_head still_in_list;
+   struct drm_i915_gem_object *obj;
unsigned long count = 0;
 
-   list_for_each_entry_safe(obj, next,
-&dev_priv->mm.unbound_list,
-global_list) {
-   if ((i915_gem_object_is_purgeable(obj) || !purgeable_only) &&
-   i915_gem_object_put_pages(obj) == 0) {
-   count += obj->base.size >> PAGE_SHIFT;
-   if (count >= target)
-   return count;
-   }
-   }
-
/*
-* As we may completely rewrite the bound list whilst unbinding
+* As we may completely rewrite the (un)bound list whilst unbinding
 * (due to retiring requests) we have to strictly process only
 * one element of the list at the time, and recheck the list
 * on every iteration.
+*
+* In particular, we must hold a reference whilst removing the
+* object as we may end up waiting for and/or retiring the objects.
+* This might release the final reference (held by the active list)
+* and result in the object being freed from under us. This is
+* similar to the precautions the eviction code must take whilst
+* removing objects.
+*
+* Also note that although these lists do not hold a reference to
+* the object we can safely grab one here: The final object
+* unreferencing and the bound_list are both protected by the
+* dev->struct_mutex and so we won'

[Intel-gfx] [PATCH 3/3] drm/i915: Introduce mapping of user pages into video memory (userptr) ioctl

2014-03-17 Thread Chris Wilson
By exporting the ability to map user address and inserting PTEs
representing their backing pages into the GTT, we can exploit UMA in order
to utilize normal application data as a texture source or even as a
render target (depending upon the capabilities of the chipset). This has
a number of uses, with zero-copy downloads to the GPU and efficient
readback making the intermixed streaming of CPU and GPU operations
fairly efficient. This ability has many widespread implications from
faster rendering of client-side software rasterisers (chromium),
mitigation of stalls due to read back (firefox) and to faster pipelining
of texture data (such as pixel buffer objects in GL or data blobs in CL).

v2: Compile with CONFIG_MMU_NOTIFIER
v3: We can sleep while performing invalidate-range, which we can utilise
to drop our page references prior to the kernel manipulating the vma
(for either discard or cloning) and so protect normal users.
v4: Only run the invalidate notifier if the range intercepts the bo.
v5: Prevent userspace from attempting to GTT mmap non-page aligned buffers
v6: Recheck after reacquire mutex for lost mmu.
v7: Fix implicit padding of ioctl struct by rounding to next 64bit boundary.
v8: Fix rebasing error after forwarding porting the back port.
v9: Limit the userptr to page aligned entries. We now expect userspace
to handle all the offset-in-page adjustments itself.
v10: Prevent vma from being copied across fork to avoid issues with cow.
v11: Drop vma behaviour changes -- locking is nigh on impossible.
 Use a worker to load user pages to avoid lock inversions.
v12: Use get_task_mm()/mmput() for correct refcounting of mm.
v13: Use a worker to release the mmu_notifier to avoid lock inversion
v14: Decouple mmu_notifier from struct_mutex using a custom mmu_notifer
 with its own locking and tree of objects for each mm/mmu_notifier.
v15: Prevent overlapping userptr objects, and invalidate all objects
 within the mmu_notifier range
v16: Fix a typo for iterating over multiple objects in the range and
 rearrange error path to destroy the mmu_notifier locklessly.
 Also close a race between invalidate_range and the get_pages_worker.
v17: Close a race between get_pages_worker/invalidate_range and fresh
 allocations of the same userptr range - and notice that
 struct_mutex was presumed to be held when during creation it wasn't.
v18: Sigh. Fix the refactor of st_set_pages() to allocate enough memory
 for the struct sg_table and to clear it before reporting an error.
v19: Always error out on read-only userptr requests as we don't have the
 hardware infrastructure to support them at the moment.
v20: Refuse to implement read-only support until we have the required
 infrastructure - but reserve the bit in flags for future use.
v21: use_mm() is not required for get_user_pages(). It is only meant to
 be used to fix up the kernel thread's current->mm for use with
 copy_user().

Signed-off-by: Chris Wilson 
Cc: Tvrtko Ursulin 
Cc: "Gong, Zhipeng" 
Cc: Akash Goel 
Cc: "Volkin, Bradley D" 
Reviewed-by: Tvrtko Ursulin 
---
 drivers/gpu/drm/i915/Kconfig|   1 +
 drivers/gpu/drm/i915/Makefile   |   1 +
 drivers/gpu/drm/i915/i915_dma.c |   1 +
 drivers/gpu/drm/i915/i915_drv.h |  24 +-
 drivers/gpu/drm/i915/i915_gem.c |   4 +
 drivers/gpu/drm/i915/i915_gem_dmabuf.c  |   5 +
 drivers/gpu/drm/i915/i915_gem_userptr.c | 679 
 drivers/gpu/drm/i915/i915_gpu_error.c   |   2 +
 include/uapi/drm/i915_drm.h |  16 +
 9 files changed, 732 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/drm/i915/i915_gem_userptr.c

diff --git a/drivers/gpu/drm/i915/Kconfig b/drivers/gpu/drm/i915/Kconfig
index 73ed59eff139..9940baee10c2 100644
--- a/drivers/gpu/drm/i915/Kconfig
+++ b/drivers/gpu/drm/i915/Kconfig
@@ -5,6 +5,7 @@ config DRM_I915
depends on (AGP || AGP=n)
select INTEL_GTT
select AGP_INTEL if AGP
+   select INTERVAL_TREE
# we need shmfs for the swappable backing store, and in particular
# the shmem_readpage() which depends upon tmpfs
select SHMEM
diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index 2e02137a0d6e..1856494439e9 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -27,6 +27,7 @@ i915-y += i915_cmd_parser.o \
  i915_gem.o \
  i915_gem_stolen.o \
  i915_gem_tiling.o \
+ i915_gem_userptr.o \
  i915_gpu_error.o \
  i915_irq.o \
  i915_trace_points.o \
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index a98d66fb0302..4f7b93e2cb4f 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -1979,6 +1979,7 @@ const struct drm_ioctl_desc i915_ioctls[] = {
DRM_IOCTL_DEF_DRV(I915_REG_READ, i915_reg_read_ioctl, 
DRM_UNLOCKED|DRM_RENDER_ALLOW),
DRM_IOCTL_DEF_DRV(

[Intel-gfx] [PULL] drm-intel-next

2014-03-17 Thread Daniel Vetter
Hi Dave,

drm-intel-next-2014-03-07:
- fine-grained display power domains for byt (Imre)
- runtime pm prep patches for !hsw from Paulo
- WiZ hashing flag updates from Ville
- ppgtt setup cleanup and enabling of full 4G range on bdw (Ben)
- fixes from Jesse for the inherited intial config code
- gpu reset code improvements from Mika
- per-pipe num_planes refactoring from Damien
- stability fixes around bdw forcewake handling and other bdw w/a from Mika and
  Ken
- and as usual a pile of smaller fixes all over

The big thing here is the disabling of the full ppgtt code. I've figured
I'll need to pull the plug a bit earlier to have enough time to test thing
throughroughly before the 3.15 merge window opens.

Cheers, Daniel


The following changes since commit 4c0e552882114d1edb588242d45035246ab078a0:

  drm/i915: fix NULL deref in the load detect code (2014-02-14 17:23:12 +0100)

are available in the git repository at:

  git://anongit.freedesktop.org/drm-intel tags/drm-intel-next-2014-03-07

for you to fetch changes up to 2fae6a860ca9adb0c881f6dcd633df775c2520e9:

  drm/i915: Go OCD on the Makefile (2014-03-07 22:37:00 +0100)


- fine-grained display power domains for byt (Imre)
- runtime pm prep patches for !hsw from Paulo
- WiZ hashing flag updates from Ville
- ppgtt setup cleanup and enabling of full 4G range on bdw (Ben)
- fixes from Jesse for the inherited intial config code
- gpu reset code improvements from Mika
- per-pipe num_planes refactoring from Damien
- stability fixes around bdw forcewake handling and other bdw w/a from Mika and
  Ken
- and as usual a pile of smaller fixes all over


Ben Widawsky (12):
  drm/i915: Move ppgtt_release out of the header
  drm/i915/bdw: Free PPGTT struct
  drm/i915/bdw: Reorganize PPGTT init
  drm/i915/bdw: Split ppgtt initialization up
  drm/i915: Make clear/insert vfuncs args absolute
  drm/i915/bdw: Reorganize PT allocations
  Revert "drm/i915/bdw: Limit GTT to 2GB"
  drm/i915: Update i915_gem_gtt.c copyright
  drm/i915: Split GEN6 PPGTT cleanup
  drm/i915: Split GEN6 PPGTT initialization up
  drm/i915/bdw: Kill ppgtt->num_pt_pages
  drm/i915/bdw: Add FBC support

Brad Volkin (2):
  drm/i915: Refactor shmem pread setup
  drm/i915: Implement command buffer parsing logic

Chris Wilson (9):
  drm/i915: Revert workaround for disabling L3 cache aging on IVB
  Revert "drm/i915: enable HiZ Raw Stall Optimization on IVB"
  drm/i915: Reject changes of fb base when we have a flip pending
  drm/i915: Accurately track when we mark the hardware as idle/busy
  drm/i915: Convert the forcewake worker into a timer func
  drm/i915: Perform pageflip using mmio if the GPU is terminally wedged
  drm/i915: Reset vma->mm_list after unbinding
  drm/i915: Rely on accurate request tracking for finding hung batches
  drm/i915: Record pid/comm of hanging task

Damien Lespiau (8):
  drm/i915: Use a pipe variable to cycle through the pipes
  drm/i915: Don't declare unnecessary shadowing variable
  drm/i915: Replace a few for_each_pipe(i) by for_each_pipe(pipe)
  drm/i915: Add a for_each_sprite() macro
  drm/i915: Make num_sprites a per-pipe value
  drm/i915: Make i915_gem_retire_requests_ring() static
  drm/i915: Remove unused to_gem_object() macro
  drm/i915: Fix i915_switch_context() argument name in kerneldoc

Daniel Vetter (7):
  drm/i915: tune down user-triggerable dmesg noise in the cursor/overlay 
code
  drm/i915: sprinkle static
  drm/i915: s/any_enabled/!fallback/ in fbdev_initial_config
  drm/i915: ignore bios output config if not all outputs are on
  drm/i915: reverse dp link param selection, prefer fast over wide again
  drm/i915: Disable full ppgtt by default
  drm/i915: Go OCD on the Makefile

Imre Deak (21):
  drm/i915: use drm_i915_private everywhere in the power domain api
  drm/i915: switch order of power domain init wrt. irq install
  drm/i915: use power domain api to check vga power state
  drm/i915: move hsw power domain comment to its right place
  drm/i915: fold in __intel_power_well_get/put functions
  drm/i915: move modeset_update_power_wells earlier
  drm/i915: move power domain macros to intel_pm.c
  drm/i915: add init power domain to always-on power wells
  drm/i915: split power well 'set' handler to separate 
enable/disable/sync_hw
  drm/i915: add noop power well handlers instead of NULL checking them
  drm/i915: add port power domains
  drm/i915: get port power domain in connector detect handlers
  drm/i915: check port power domain when reading the encoder hw state
  drm/i915: check pipe power domain when reading its hw state
  drm/i915: vlv: keep first level vblank IRQs masked
  drm/i915: sanitize PUNIT register macro defin

[Intel-gfx] [PULL] drm-intel-fixes

2014-03-17 Thread Jani Nikula

Hi Dave,

Two 3.14 specific fixes, two cc: stable.

I'm afraid I've accumulated a slight backlog of fixes. This pull is to
get the tested stuff out of the way first. I'll be pushing more patches
soon, and will send another pull once our QA has had some time to run
them.

BR,
Jani.


The following changes since commit 6375b768a9850b6154478993e5fb566fa4614a9c:

  drm/i915: Reject >165MHz modes w/ DVI monitors (2014-03-03 19:08:08 +0200)

are available in the git repository at:

  git://anongit.freedesktop.org/drm-intel tags/drm-intel-fixes-2014-03-17

for you to fetch changes up to 5c673b60a9b3b23486f4eda75c72e91d31d26a2b:

  drm/i915: Don't enable display error interrupts from the start (2014-03-12 
17:20:34 +0200)


Ben Widawsky (1):
  drm/i915: Fix PSR programming

Daniel Vetter (1):
  drm/i915: Don't enable display error interrupts from the start

Ville Syrjälä (2):
  drm/i915: Add a workaround for HSW scanline counter weirdness
  drm/i915: Fix scanline counter fixup on BDW

 drivers/gpu/drm/i915/i915_irq.c |   71 ++-
 drivers/gpu/drm/i915/intel_dp.c |2 +-
 2 files changed, 42 insertions(+), 31 deletions(-)

-- 
Jani Nikula, Intel Open Source Technology Center


pgpHlgXBjRz8n.pgp
Description: PGP signature
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH] drm/i915: Don't del_timer_sync uninitialized timer

2014-03-17 Thread Daniel Vetter
On Mon, Mar 17, 2014 at 11:14:25AM +0200, Jani Nikula wrote:
> On Mon, 17 Mar 2014, Jani Nikula  wrote:
> > On Sat, 15 Mar 2014, Ben Widawsky  wrote:
> >> Broken by:
> >> commit 0294ae7b44bba7ab0d4cef9a8736287f38bdb4fd
> >> Author: Chris Wilson 
> >> Date:   Thu Mar 13 12:00:29 2014 +
> >>
> >> drm/i915: Consolidate forcewake resetting to a single function
> >>
> >
> > Does this result in https://bugs.freedesktop.org/show_bug.cgi?id=76242 ?
> 
> QA confirms this patch fixes the bug.

Also the commit message seriously lacks details. Apparantly this only
blows up with lockdep (since most my machines here are still happy), which
is a rather crucial detail.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH 1/3] drm/i915: Added a new 'I915_CPU_MAP_NOT_NEEDED' flag to gem_create ioctl.

2014-03-17 Thread Gupta, Sourab
On Mon, 2014-03-10 at 22:07 +, 'Chris Wilson' wrote:
> On Mon, Mar 10, 2014 at 04:12:23PM +, Gupta, Sourab wrote:
> > 
> > Hi Chris,
> > 
> > For the issue mentioned by you ( regarding botching up ioctls), we 
> > understand that this is related to the 
> > compatibility between the older/newer versions of driver/userspace.
> > In our old implementation, the 'pad' field was replaced with 'flags' in the 
> > ioctl structure. This would have 
> > led to the erroneous behavior when the new userspace is communicating with 
> > old driver.
> 
> You missed the important point that there is no guarrantee that current
> userspace is not stuffing garbage into the pad field. It is.
> 
> You have to go with a new ioctl. So you may as well design one that
> tries to fulfil today's varied needs for a constructor.  For example,
> here's one I prepared earlier,
> http://cgit.freedesktop.org/~ickle/linux-2.6/commit/?h=create2&id=401fa740adcaf252d0149cdd63d5fdf5e3969907
> -Chris
> 

Hi Chris,

We went through this patch and this fulfills the requirements from the
stolen mem perspective, and this looks like a replacement of the first
patch we have submitted.
This patch seems to be in your private branch. When do you plan to merge
this patch with drm-intel branch?
Have you also prepared the corresponding libdrm side patches? If so, can
you share those also. Actually, the igt patch which we submitted earlier
would also need to be modified according to the libdrm changes.

Also,
When do you plan to merge the second and third patch in the series
(truncation of stolen mem objs) as they seem to be fine to us.

Regards,
Sourab

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH] drm/i915: Don't del_timer_sync uninitialized timer

2014-03-17 Thread Jani Nikula
On Mon, 17 Mar 2014, Jani Nikula  wrote:
> On Sat, 15 Mar 2014, Ben Widawsky  wrote:
>> Broken by:
>> commit 0294ae7b44bba7ab0d4cef9a8736287f38bdb4fd
>> Author: Chris Wilson 
>> Date:   Thu Mar 13 12:00:29 2014 +
>>
>> drm/i915: Consolidate forcewake resetting to a single function
>>
>
> Does this result in https://bugs.freedesktop.org/show_bug.cgi?id=76242 ?

QA confirms this patch fixes the bug.

Jani.


-- 
Jani Nikula, Intel Open Source Technology Center
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] yet another modesetting backtrace.

2014-03-17 Thread Daniel Vetter
On Mon, Mar 17, 2014 at 12:51:24PM +1000, Dave Airlie wrote:
>  Booted drm-next merged into Linus 3.14-rc7 this morning,
> 
> got splatted.
> 
> Ivybridge, one DP one DVI monitor.

Oh, the infamous. We have a report of these for pretty much all our our hw
platforms up to ivb (I think hsw is fine actually). Played around with
piles of things to no avail thus far. For 3.15 there's two patches from
Imre which might improve this mess (since in general if the pipe stops
running when we don't expect it to our code will hang all over the place
since we don't have a hangcheck for the display hardware):

2e82a7203182d0883d0f9450d40ad6e1c6578ad9 drm/i915: don't disable DP port after 
a failed link training
5d6a1116c6475404e6505b708320f9579ae19acd drm/i915: don't disable the DP port if 
the link is lost

Cheers, Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH v2 1/1] kms_cursor_crc: Enabling this test for 128x128 and 256x256 cursors

2014-03-17 Thread Daniel Vetter
On Sat, Mar 8, 2014 at 7:49 PM,   wrote:
> From: Sagar Kamble 
>
> v1: Added 128x128 and 256x256 cursor size support.
>
> v2: Refined the test to use igt_subtest_f and automate enumeration.
>
> Signed-off-by: Sagar Kamble 

Hm, do you have an update of this patch to use the drm ioctl to query
the max cursor size and correctly skip 128x128 and higher?

Also adding the additional modes into an enum looks a bit strange. I'm
it would be simpler to explicit pass the cursor size and have an outer
loop over all of them, i.e.

for (cursor_size = 64 ; cursor_size <= 256; cursor_size *= 2) {

igt_require(cusror_max >= cursor_size);

/* lists of all the existing subtests with a
igt_subtest_f("subtest-%s", cursor_size) */
}

Adding all the indirections with the enum switches makes the code imo
harder to read, and for testcases we want to aim for simple
straightforward code.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH] drm/i915: Don't del_timer_sync uninitialized timer

2014-03-17 Thread Jani Nikula
On Sat, 15 Mar 2014, Ben Widawsky  wrote:
> Broken by:
> commit 0294ae7b44bba7ab0d4cef9a8736287f38bdb4fd
> Author: Chris Wilson 
> Date:   Thu Mar 13 12:00:29 2014 +
>
> drm/i915: Consolidate forcewake resetting to a single function
>

Does this result in https://bugs.freedesktop.org/show_bug.cgi?id=76242 ?

Backtrace in the commit message would help a lot in pattern matching...

BR,
Jani.



> Cc: Chris Wilson 
> Cc: Mika Kuoppala 
> Signed-off-by: Ben Widawsky 
> ---
>  drivers/gpu/drm/i915/intel_uncore.c | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_uncore.c 
> b/drivers/gpu/drm/i915/intel_uncore.c
> index e6bb421..7e55ceb 100644
> --- a/drivers/gpu/drm/i915/intel_uncore.c
> +++ b/drivers/gpu/drm/i915/intel_uncore.c
> @@ -362,6 +362,9 @@ void intel_uncore_early_sanitize(struct drm_device *dev)
>  {
>   struct drm_i915_private *dev_priv = dev->dev_private;
>  
> + setup_timer(&dev_priv->uncore.force_wake_timer,
> + gen6_force_wake_timer, (unsigned long)dev_priv);
> +
>   if (HAS_FPGA_DBG_UNCLAIMED(dev))
>   __raw_i915_write32(dev_priv, FPGA_DBG, FPGA_DBG_RM_NOCLAIM);
>  
> @@ -724,9 +727,6 @@ void intel_uncore_init(struct drm_device *dev)
>  {
>   struct drm_i915_private *dev_priv = dev->dev_private;
>  
> - setup_timer(&dev_priv->uncore.force_wake_timer,
> - gen6_force_wake_timer, (unsigned long)dev_priv);
> -
>   if (IS_VALLEYVIEW(dev)) {
>   dev_priv->uncore.funcs.force_wake_get = __vlv_force_wake_get;
>   dev_priv->uncore.funcs.force_wake_put = __vlv_force_wake_put;
> -- 
> 1.9.0
>
> ___
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Jani Nikula, Intel Open Source Technology Center
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx