Re: [Intel-gfx] [PATCH 2/2] drm/i915: Protect engine request list with spinlock

2015-02-24 Thread Chris Wilson
On Tue, Feb 24, 2015 at 12:58:19AM +0100, Daniel Vetter wrote:
> On Thu, Feb 19, 2015 at 04:41:12PM +, Chris Wilson wrote:
> > On Thu, Feb 19, 2015 at 06:18:55PM +0200, Mika Kuoppala wrote:
> > > There are multiple players interested in the ring->request_list
> > > state. Request submission can happen in kernel or user context,
> > > idle worker is going through request list to free items. And then there
> > > is hangcheck worker which tries to figure out if particular ring is
> > > healthy by peeking at the request list among other things. And if
> > > judged stuck by hangcheck, error state is colleted. Which in turns
> > > needs access to ring->request_list.
> > 
> > We have discussed this before. Hangcheck does not need the lock so long
> > as it is serialised with deletion. List processing with hangcheck during
> > concurrent addition is safe.
> > 
> > For example, I expect the request locking to look like
> > 
> > http://cgit.freedesktop.org/~ickle/linux-2.6/tree/drivers/gpu/drm/i915/i915_gem_request.c#n691
> 
> I think longer-term with per-engine reset and fun stuff like that we
> probably want the spinlock, just to avoid too many headaches with locking
> auditing. For the execbuf fastpath it should just be one more spinlock per
> ioctl, so hopefully bearable.

But it is not even the locking bug that breaks capture, so what's the
point?
-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


[Intel-gfx] [PATCH v4] drm/i915: avoid processing spurious/shared interrupts in low-power states

2015-02-24 Thread Imre Deak
Atm, it's possible that the interrupt handler is called when the device
is in D3 or some other low-power state. It can be due to another device
that is still in D0 state and shares the interrupt line with i915, or on
some platforms there could be spurious interrupts even without sharing
the interrupt line. The latter case was reported by Klaus Ethgen using a
Lenovo x61p machine (gen 4). He noticed this issue via a system
suspend/resume hang and bisected it to the following commit:

commit e11aa362308f5de467ce355a2a2471321b15a35c
Author: Jesse Barnes 
Date:   Wed Jun 18 09:52:55 2014 -0700

drm/i915: use runtime irq suspend/resume in freeze/thaw

This is a problem, since in low-power states IIR will always read
0x resulting in an endless IRQ servicing loop.

Fix this by handling interrupts only when the driver explicitly enables
them and so it's guaranteed that the interrupt registers return a valid
value.

Note that this issue existed even before the above commit, since during
runtime suspend/resume we never unregistered the handler.

v2:
- clarify the purpose of smp_mb() vs. synchronize_irq() in the
  code comment (Chris)

v3:
- no need for an explicit smp_mb(), we can assume that synchronize_irq()
  and the mmio read/writes in the install hooks provide for this (Daniel)
- remove code comment as the remaining synchronize_irq() is self
  explanatory (Daniel)

v4:
- drm_irq_uninstall() implies synchronize_irq(), so no need to call it
  explicitly (Daniel)

Reference: https://lkml.org/lkml/2015/2/11/205
Reported-and-bisected-by: Klaus Ethgen 
Signed-off-by: Imre Deak 
Reviewed-by: Daniel Vetter 
---
 drivers/gpu/drm/i915/i915_irq.c | 22 ++
 1 file changed, 22 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 9073119..1561248 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -1889,6 +1889,9 @@ static irqreturn_t valleyview_irq_handler(int irq, void 
*arg)
u32 iir, gt_iir, pm_iir;
irqreturn_t ret = IRQ_NONE;
 
+   if (!intel_irqs_enabled(dev_priv))
+   return IRQ_NONE;
+
while (true) {
/* Find, clear, then process each source of interrupt */
 
@@ -1933,6 +1936,9 @@ static irqreturn_t cherryview_irq_handler(int irq, void 
*arg)
u32 master_ctl, iir;
irqreturn_t ret = IRQ_NONE;
 
+   if (!intel_irqs_enabled(dev_priv))
+   return IRQ_NONE;
+
for (;;) {
master_ctl = I915_READ(GEN8_MASTER_IRQ) & 
~GEN8_MASTER_IRQ_CONTROL;
iir = I915_READ(VLV_IIR);
@@ -2205,6 +2211,9 @@ static irqreturn_t ironlake_irq_handler(int irq, void 
*arg)
u32 de_iir, gt_iir, de_ier, sde_ier = 0;
irqreturn_t ret = IRQ_NONE;
 
+   if (!intel_irqs_enabled(dev_priv))
+   return IRQ_NONE;
+
/* We get interrupts on unclaimed registers, so check for this before we
 * do any I915_{READ,WRITE}. */
intel_uncore_check_errors(dev);
@@ -2276,6 +2285,9 @@ static irqreturn_t gen8_irq_handler(int irq, void *arg)
enum pipe pipe;
u32 aux_mask = GEN8_AUX_CHANNEL_A;
 
+   if (!intel_irqs_enabled(dev_priv))
+   return IRQ_NONE;
+
if (IS_GEN9(dev))
aux_mask |=  GEN9_AUX_CHANNEL_B | GEN9_AUX_CHANNEL_C |
GEN9_AUX_CHANNEL_D;
@@ -3768,6 +3780,9 @@ static irqreturn_t i8xx_irq_handler(int irq, void *arg)
I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT |
I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT;
 
+   if (!intel_irqs_enabled(dev_priv))
+   return IRQ_NONE;
+
iir = I915_READ16(IIR);
if (iir == 0)
return IRQ_NONE;
@@ -3948,6 +3963,9 @@ static irqreturn_t i915_irq_handler(int irq, void *arg)
I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT;
int pipe, ret = IRQ_NONE;
 
+   if (!intel_irqs_enabled(dev_priv))
+   return IRQ_NONE;
+
iir = I915_READ(IIR);
do {
bool irq_received = (iir & ~flip_mask) != 0;
@@ -4168,6 +4186,9 @@ static irqreturn_t i965_irq_handler(int irq, void *arg)
I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT |
I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT;
 
+   if (!intel_irqs_enabled(dev_priv))
+   return IRQ_NONE;
+
iir = I915_READ(IIR);
 
for (;;) {
@@ -4517,6 +4538,7 @@ void intel_runtime_pm_disable_interrupts(struct 
drm_i915_private *dev_priv)
 {
dev_priv->dev->driver->irq_uninstall(dev_priv->dev);
dev_priv->pm.irqs_enabled = false;
+   synchronize_irq(dev_priv->dev->irq);
 }
 
 /**
-- 
2.1.0

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


Re: [Intel-gfx] [PATCH i-g-t 2/4] lib: use defines for igt_simple_init and igt_subtest_init

2015-02-24 Thread Thomas Wood
On 23 February 2015 at 23:49, Daniel Vetter  wrote:
> What's the benifit here? Would be nice to add that to the commit message
> with a short sentence. Series lgtm otherwise, imo you could push it as-is.

It is partly as preparation for the next patch and partly just a
simplification to remove an extra function call. I'll add a suitable
comment to the commit message.

> -Daniel
>
> On Wed, Feb 18, 2015 at 05:06:14PM +, Thomas Wood wrote:
>> Signed-off-by: Thomas Wood 
>> ---
>>  lib/igt_core.c | 34 --
>>  lib/igt_core.h | 36 
>>  2 files changed, 32 insertions(+), 38 deletions(-)
>>
>> diff --git a/lib/igt_core.c b/lib/igt_core.c
>> index eef338b..afecdf1 100644
>> --- a/lib/igt_core.c
>> +++ b/lib/igt_core.c
>> @@ -696,40 +696,6 @@ int igt_subtest_init_parse_opts(int argc, char **argv,
>>  enum igt_log_level igt_log_level = IGT_LOG_INFO;
>>
>>  /**
>> - * igt_subtest_init:
>> - * @argc: argc from the test's main()
>> - * @argv: argv from the test's main()
>> - *
>> - * This initializes the for tests with subtests without the need for 
>> additional
>> - * cmdline options. It is just a simplified version of
>> - * igt_subtest_init_parse_opts().
>> - *
>> - * If there's not a reason to the contrary it's less error prone to just 
>> use an
>> - * #igt_main block instead of stitching the tests's main() function together
>> - * manually.
>> - */
>> -void igt_subtest_init(int argc, char **argv)
>> -{
>> - igt_subtest_init_parse_opts(argc, argv, NULL, NULL, NULL, NULL);
>> -}
>> -
>> -/**
>> - * igt_simple_init:
>> - * @argc: argc from the test's main()
>> - * @argv: argv from the test's main()
>> - *
>> - * This initializes a simple test without any support for subtests.
>> - *
>> - * If there's not a reason to the contrary it's less error prone to just 
>> use an
>> - * #igt_simple_main block instead of stitching the tests's main() function 
>> together
>> - * manually.
>> - */
>> -void igt_simple_init(int argc, char **argv)
>> -{
>> - common_init(argc, argv, NULL, NULL, NULL, NULL);
>> -}
>> -
>> -/**
>>   * igt_simple_init_parse_opts:
>>   * @argc: argc from the test's main()
>>   * @argv: argv from the test's main()
>> diff --git a/lib/igt_core.h b/lib/igt_core.h
>> index 0086945..88b47bf 100644
>> --- a/lib/igt_core.h
>> +++ b/lib/igt_core.h
>> @@ -106,7 +106,6 @@ void __igt_fixture_end(void) __attribute__((noreturn));
>>
>>  /* subtest infrastructure */
>>  jmp_buf igt_subtest_jmpbuf;
>> -void igt_subtest_init(int argc, char **argv);
>>  typedef int (*igt_opt_handler_t)(int opt, int opt_index);
>>  #ifndef __GTK_DOC_IGNORE__ /* gtkdoc wants to document this forward decl */
>>  struct option;
>> @@ -117,6 +116,22 @@ int igt_subtest_init_parse_opts(int argc, char **argv,
>>   const char *help_str,
>>   igt_opt_handler_t extra_opt_handler);
>>
>> +
>> +/**
>> + * igt_subtest_init:
>> + * @argc: argc from the test's main()
>> + * @argv: argv from the test's main()
>> + *
>> + * This initializes the for tests with subtests without the need for 
>> additional
>> + * cmdline options. It is just a simplified version of
>> + * igt_subtest_init_parse_opts().
>> + *
>> + * If there's not a reason to the contrary it's less error prone to just 
>> use an
>> + * #igt_main block instead of stitching the test's main() function together
>> + * manually.
>> + */
>> +#define igt_subtest_init(argc, argv) igt_subtest_init_parse_opts(argc, 
>> argv, NULL, NULL, NULL, NULL);
>> +
>>  bool __igt_run_subtest(const char *subtest_name);
>>  #define __igt_tokencat2(x, y) x ## y
>>
>> @@ -180,13 +195,13 @@ bool igt_only_list_subtests(void);
>>  #define igt_main \
>>   static void igt_tokencat(__real_main, __LINE__)(void); \
>>   int main(int argc, char **argv) { \
>> - igt_subtest_init(argc, argv); \
>> + igt_subtest_init_parse_opts(argc, argv, NULL, NULL, NULL, 
>> NULL); \
>>   igt_tokencat(__real_main, __LINE__)(); \
>>   igt_exit(); \
>>   } \
>>   static void igt_tokencat(__real_main, __LINE__)(void) \
>>
>> -void igt_simple_init(int argc, char **argv);
>> +
>>  void igt_simple_init_parse_opts(int argc, char **argv,
>>   const char *extra_short_opts,
>>   struct option *extra_long_opts,
>> @@ -194,6 +209,19 @@ void igt_simple_init_parse_opts(int argc, char **argv,
>>   igt_opt_handler_t extra_opt_handler);
>>
>>  /**
>> + * igt_simple_init:
>> + * @argc: argc from the test's main()
>> + * @argv: argv from the test's main()
>> + *
>> + * This initializes a simple test without any support for subtests.
>> + *
>> + * If there's not a reason to the contrary it's less error prone to just 
>> use an
>> + * #igt_simple_main block instead of stitching the test's main() function 
>> together
>> + * manually.
>> + */
>> +#define igt_simple_init(argc, argv) igt

Re: [Intel-gfx] [PATCH] drm/i915: Shift driver's HWSP usage out of reserved range

2015-02-24 Thread Daniel, Thomas
> -Original Message-
> From: Daniel Vetter [mailto:daniel.vet...@ffwll.ch] On Behalf Of Daniel Vetter
> Sent: Monday, February 23, 2015 11:28 PM
> To: Gordon, David S
> Cc: Daniel, Thomas; intel-gfx@lists.freedesktop.org
> Subject: Re: [Intel-gfx] [PATCH] drm/i915: Shift driver's HWSP usage out of
> reserved range
> 
> On Thu, Feb 19, 2015 at 02:58:48PM +, Dave Gordon wrote:
> > On 18/02/15 11:48, Thomas Daniel wrote:
> > > As of Gen6, the general purpose area of the hardware status page has 
> > > shrunk
> and
> > > now begins at dword 0x30.  i915 driver uses dword 0x20 to store the seqno
> which
> > > is now reserved.  So shift our HWSP dwords up into the general purpose
> range
> > > before this bites us.
> 
> It would be really interesting to know what exactly the hw does with
> offsets below 0x30 ... it might explain some of the bugs we've seen. Can
> you please digg that out so that I can amend the commit message?

All documentation I've seen just says "Reserved" for current hardware including 
SKL so we can't rely on any particular usage.  That's why I just put "Reserved" 
for these dwords in the comment.

Thomas.


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


Re: [Intel-gfx] [PATCH 2/2] drm/i915: Protect engine request list with spinlock

2015-02-24 Thread Chris Wilson
On Tue, Feb 24, 2015 at 11:39:08AM +0100, Daniel Vetter wrote:
> On Tue, Feb 24, 2015 at 08:31:18AM +, Chris Wilson wrote:
> > On Tue, Feb 24, 2015 at 12:58:19AM +0100, Daniel Vetter wrote:
> > > On Thu, Feb 19, 2015 at 04:41:12PM +, Chris Wilson wrote:
> > > > On Thu, Feb 19, 2015 at 06:18:55PM +0200, Mika Kuoppala wrote:
> > > > > There are multiple players interested in the ring->request_list
> > > > > state. Request submission can happen in kernel or user context,
> > > > > idle worker is going through request list to free items. And then 
> > > > > there
> > > > > is hangcheck worker which tries to figure out if particular ring is
> > > > > healthy by peeking at the request list among other things. And if
> > > > > judged stuck by hangcheck, error state is colleted. Which in turns
> > > > > needs access to ring->request_list.
> > > > 
> > > > We have discussed this before. Hangcheck does not need the lock so long
> > > > as it is serialised with deletion. List processing with hangcheck during
> > > > concurrent addition is safe.
> > > > 
> > > > For example, I expect the request locking to look like
> > > > 
> > > > http://cgit.freedesktop.org/~ickle/linux-2.6/tree/drivers/gpu/drm/i915/i915_gem_request.c#n691
> > > 
> > > I think longer-term with per-engine reset and fun stuff like that we
> > > probably want the spinlock, just to avoid too many headaches with locking
> > > auditing. For the execbuf fastpath it should just be one more spinlock per
> > > ioctl, so hopefully bearable.
> > 
> > But it is not even the locking bug that breaks capture, so what's the
> > point?
> 
> Oh I've read the patch as general prep work for more finegrained reset
> support not as a fix for the referenced bug. I guess the bug is just the
> usual incoherent seqno/irq thing that's been plagueing us ever since gen6?

I presumed Mika wants to fix that hangcheck and capture may explode as
requests are completed concurrently. The bug that I expect will remain
is that we peek at the bo without locks during capture.
-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 v4] drm/i915: avoid processing spurious/shared interrupts in low-power states

2015-02-24 Thread Chris Wilson
On Tue, Feb 24, 2015 at 11:42:20AM +0100, Daniel Vetter wrote:
> On Tue, Feb 24, 2015 at 09:29:15AM +, Chris Wilson wrote:
> > On Tue, Feb 24, 2015 at 11:14:30AM +0200, Imre Deak wrote:
> > > Atm, it's possible that the interrupt handler is called when the device
> > > is in D3 or some other low-power state. It can be due to another device
> > > that is still in D0 state and shares the interrupt line with i915, or on
> > > some platforms there could be spurious interrupts even without sharing
> > > the interrupt line. The latter case was reported by Klaus Ethgen using a
> > > Lenovo x61p machine (gen 4). He noticed this issue via a system
> > > suspend/resume hang and bisected it to the following commit:
> > > 
> > > commit e11aa362308f5de467ce355a2a2471321b15a35c
> > > Author: Jesse Barnes 
> > > Date:   Wed Jun 18 09:52:55 2014 -0700
> > > 
> > > drm/i915: use runtime irq suspend/resume in freeze/thaw
> > > 
> > > This is a problem, since in low-power states IIR will always read
> > > 0x resulting in an endless IRQ servicing loop.
> > > 
> > > Fix this by handling interrupts only when the driver explicitly enables
> > > them and so it's guaranteed that the interrupt registers return a valid
> > > value.
> > > 
> > > Note that this issue existed even before the above commit, since during
> > > runtime suspend/resume we never unregistered the handler.
> > > 
> > > v2:
> > > - clarify the purpose of smp_mb() vs. synchronize_irq() in the
> > >   code comment (Chris)
> > > 
> > > v3:
> > > - no need for an explicit smp_mb(), we can assume that synchronize_irq()
> > >   and the mmio read/writes in the install hooks provide for this (Daniel)
> > > - remove code comment as the remaining synchronize_irq() is self
> > >   explanatory (Daniel)
> > 
> > Why make the assumption though? I thought the comments documenting the
> > interaction between the irq enablements, the irq handler and shared
> > interrupts was beneficial. At the very least the assumption should be
> > made explicit through comments in the code - because I am not convinced
> > that a cached write will be flushed by an uncached write to another area
> > of memory. In particular, note that on the gen most troubled by rogue
> > irqs (gen4), we do not have any memory barriers in the mmio paths.
> 
> The synchronize_irq is a fairly massive barrier and I've figured the name
> is descriptive enough to make clear what's going on. At least I've felt
> any comment on top would be redundant.
> 
> Also the hard rule for adding comments to explicit barriers is mostly a
> reminder that you always need barriers on both sides, and the comment
> then must explain where the other side is in the code. Imo with
> synchronize_irq it's clear that the other side is the irq handler already.
> 
> What do you want to clarify on top of that in the comment?

The smp_mb() was being applied to the enable path, not the disable +
sync_irq path. Also we now have a large body of lore regarding interrupt
issues on gen4 but we haven't been documenting any of it.  At the bare
minimum we need to explain why we call sync_irq and how that interacts
with the intel_irqs_enabled() checks and shared interrupts.

Even perhaps adding intel_runtime_pm_enabled_irq() as a wrapper for the
irq handlers to cross-reference against the runtime_pm tricks -
otherwise, there is a good likelihood that in the years to come, we
might forget how we end up inside a disabled interrupt handler and why
we are not allowed to touch the hardware at that point.
-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


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

2015-02-24 Thread Michel Thierry
From: Ben Widawsky 

When we move to dynamic page allocation, keeping page_directory and pagetabs as
separate structures will help to break actions into simpler tasks.

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

Following the x86 pagetable terminology:
PDPE = struct i915_page_directory_pointer_entry.
PDE = struct i915_page_directory_entry [page_directory].
PTE = struct i915_page_table_entry [page_tables].

v2: fixed mismatches after clean-up/rebase.

v3: Clarify the names of the multiple levels of page tables (Daniel)

v4: Addressing Mika's review comments.
s/gen8_free_page_directories/gen8_free_page_directory and free the
page tables for the directory there.
In gen8_ppgtt_allocate_page_directories, do not leak previously allocated
pt in case the page_directory alloc fails.
Update error return handling in gen8_ppgtt_alloc.

v5: Do not leak pt on error in gen6_ppgtt_allocate_page_tables. (Mika)

Cc: Mika Kuoppala 
Signed-off-by: Ben Widawsky 
Signed-off-by: Michel Thierry  (v2+)
---
 drivers/gpu/drm/i915/i915_gem_gtt.c | 180 +++-
 drivers/gpu/drm/i915/i915_gem_gtt.h |  23 -
 2 files changed, 111 insertions(+), 92 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/i915_gem_gtt.c
index e54b2a0..b4dee34 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -338,7 +338,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_page_directory_entry *pd = 
&ppgtt->pdp.page_directory[pdpe];
+   struct page *page_table = pd->page_tables[pde].page;
 
last_pte = pte + num_entries;
if (last_pte > GEN8_PTES_PER_PAGE)
@@ -382,8 +383,12 @@ static void gen8_ppgtt_insert_entries(struct 
i915_address_space *vm,
if (WARN_ON(pdpe >= GEN8_LEGACY_PDPES))
break;
 
-   if (pt_vaddr == NULL)
-   pt_vaddr = kmap_atomic(ppgtt->gen8_pt_pages[pdpe][pde]);
+   if (pt_vaddr == NULL) {
+   struct i915_page_directory_entry *pd = 
&ppgtt->pdp.page_directory[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),
@@ -407,29 +412,33 @@ static void gen8_ppgtt_insert_entries(struct 
i915_address_space *vm,
}
 }
 
-static void gen8_free_page_tables(struct page **pt_pages)
+static void gen8_free_page_tables(struct i915_page_directory_entry *pd)
 {
int i;
 
-   if (pt_pages == NULL)
+   if (pd->page_tables == NULL)
return;
 
for (i = 0; i < GEN8_PDES_PER_PAGE; 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_ppgtt_free(const struct i915_hw_ppgtt *ppgtt)
+static void gen8_free_page_directory(struct i915_page_directory_entry *pd)
+{
+   gen8_free_page_tables(pd);
+   kfree(pd->page_tables);
+   __free_page(pd->page);
+}
+
+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_directory(&ppgtt->pdp.page_directory[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_unmap_pages(struct i915_hw_ppgtt *ppgtt)
@@ -464,86 +473,77 @@ 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(GEN8_PDES_PER_PAGE, sizeof(struct page *), 
GFP_KERNEL);
-   if (!pt_pages)
-   return ERR_PTR(-ENOMEM);
-
-   for (i = 0; i < GEN8_PDES_PER_PAGE; i++) {
-   pt_pages[i] = alloc_page(GFP_KERNEL);
-   if (!pt_pages[i])
-   goto bail;
+   for (i = 0; i < ppgtt->num_pd_pages; i++) {
+   ppgtt->gen8_pt_dma_addr[i] = kcalloc(GEN8_PDES_PER_PAGE,
+sizeof(dma_addr_t),
+GFP_KERNEL);
+   if (!ppgtt->gen8_pt_dma_addr[i])
+  

Re: [Intel-gfx] [PATCH 2/2] drm/i915: Protect engine request list with spinlock

2015-02-24 Thread Mika Kuoppala
Chris Wilson  writes:

> On Tue, Feb 24, 2015 at 11:39:08AM +0100, Daniel Vetter wrote:
>> On Tue, Feb 24, 2015 at 08:31:18AM +, Chris Wilson wrote:
>> > On Tue, Feb 24, 2015 at 12:58:19AM +0100, Daniel Vetter wrote:
>> > > On Thu, Feb 19, 2015 at 04:41:12PM +, Chris Wilson wrote:
>> > > > On Thu, Feb 19, 2015 at 06:18:55PM +0200, Mika Kuoppala wrote:
>> > > > > There are multiple players interested in the ring->request_list
>> > > > > state. Request submission can happen in kernel or user context,
>> > > > > idle worker is going through request list to free items. And then 
>> > > > > there
>> > > > > is hangcheck worker which tries to figure out if particular ring is
>> > > > > healthy by peeking at the request list among other things. And if
>> > > > > judged stuck by hangcheck, error state is colleted. Which in turns
>> > > > > needs access to ring->request_list.
>> > > > 
>> > > > We have discussed this before. Hangcheck does not need the lock so long
>> > > > as it is serialised with deletion. List processing with hangcheck 
>> > > > during
>> > > > concurrent addition is safe.
>> > > > 
>> > > > For example, I expect the request locking to look like
>> > > > 
>> > > > http://cgit.freedesktop.org/~ickle/linux-2.6/tree/drivers/gpu/drm/i915/i915_gem_request.c#n691
>> > > 
>> > > I think longer-term with per-engine reset and fun stuff like that we
>> > > probably want the spinlock, just to avoid too many headaches with locking
>> > > auditing. For the execbuf fastpath it should just be one more spinlock 
>> > > per
>> > > ioctl, so hopefully bearable.
>> > 
>> > But it is not even the locking bug that breaks capture, so what's the
>> > point?
>> 
>> Oh I've read the patch as general prep work for more finegrained reset
>> support not as a fix for the referenced bug. I guess the bug is just the
>> usual incoherent seqno/irq thing that's been plagueing us ever since gen6?
>
> I presumed Mika wants to fix that hangcheck and capture may explode as
> requests are completed concurrently. The bug that I expect will remain
> is that we peek at the bo without locks during capture.
> -Chris
>

What I think is the failure mode on [1] is:

Request gets added to the ring but not yet
into the ring->request_list, gpu finishes it and updates
the hw status page. Hangcheck runs and sees that request_list
does not contain the supposed request and complains
that the hangcheck was activated on idle ring.

https://bugs.freedesktop.org/show_bug.cgi?id=88651

-Mika

> -- 
> 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] drm/i915/skl: handle all pixel formats in skylake_update_primary_plane()

2015-02-24 Thread Ville Syrjälä
On Mon, Feb 23, 2015 at 03:15:58PM +0200, Jani Nikula wrote:
> On Mon, 16 Feb 2015, Damien Lespiau  wrote:
> > On Tue, Feb 10, 2015 at 01:15:49PM +0200, Jani Nikula wrote:
> >> skylake_update_primary_plane() did not handle all pixel formats returned
> >> by skl_format_to_fourcc(). Handle alpha similar to skl_update_plane().
> >> 
> >> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=89052
> >> Signed-off-by: Jani Nikula 
> >
> > Given the discussion with Ville, it's quite likely we'll default to
> > alpha blending for pre-multiplied fbs (for plane supporting alpha), even
> > with the blending properties added. In that context, we can provide a
> > single, fixed, (but useful) blending mode before we get to implement the
> > full thing. So:
> >
> > Reviewed-by: Damien Lespiau 
> 
> Pushed to drm-intel-fixes, thanks for the review.

Well, the patch still isn't quite right. intel_primary_formats_gen4[]
defines which formats the core will let slip through into the driver,
and even with this patch we're not handling them all.

-- 
Ville Syrjälä
Intel OTC
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH] drm/i915: Fix a use after free, and unbalanced refcounting

2015-02-24 Thread Jani Nikula
On Mon, 23 Feb 2015, "Daniel, Thomas"  wrote:
>> -Original Message-
>> From: Intel-gfx [mailto:intel-gfx-boun...@lists.freedesktop.org] On Behalf Of
>> Nick Hoath
>> Sent: Thursday, February 19, 2015 4:31 PM
>> To: intel-gfx@lists.freedesktop.org
>> Subject: [Intel-gfx] [PATCH] drm/i915: Fix a use after free, and unbalanced
>> refcounting
>> 
>> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=88652
>> 
>> When converting from implicitly tracked execlist queue items to ref counted
>> requests, not all frees of requests were replaced with unrefs, and extraneous
>> refs/unrefs of contexts were added.
>> Correct the unbalanced refcount & replace the frees.
>> Remove a noisy warning when hitting the request creation path.
>> 
>> drm_i915_gem_request and intel_context are both kref reference counted
>> structures. Upon allocation, drm_i915_gem_request's ref count should be
>> bumped using kref_init. When a context is assigned to the request,
>> the context's reference count should be bumped using
>> i915_gem_context_reference.
>> i915_gem_request_reference will reduce the context reference count when
>> the request is freed.
>> 
>> Problem introduced in
>> commit 6d3d8274bc45de4babb62d64562d92af984dd238
>> Author: Nick Hoath 
>> AuthorDate: Thu Jan 15 13:10:39 2015 +
>> 
>>  drm/i915: Subsume intel_ctx_submit_request in to drm_i915_gem_request
>> 
>> v2: Added comments explaining how the ctx pointer and the request object
>> should
>> be ref-counted. Removed noisy warning.
>> 
>> v3: Cleaned up the language used in the commit & the header
>> description (Thanks David Gordon)
>> 
>> Signed-off-by: Nick Hoath 
>> ---
>>  drivers/gpu/drm/i915/i915_drv.h  | 11 ++-
>>  drivers/gpu/drm/i915/i915_gem.c  |  3 +--
>>  drivers/gpu/drm/i915/intel_lrc.c |  8 
>>  4 files changed, 16 insertions(+), 8 deletions(-)
>> 
>> diff --git a/drivers/gpu/drm/i915/i915_drv.h 
>> b/drivers/gpu/drm/i915/i915_drv.h
>> index 2dedd43..956fe26 100644
>> --- a/drivers/gpu/drm/i915/i915_drv.h
>> +++ b/drivers/gpu/drm/i915/i915_drv.h
>> @@ -2121,6 +2121,9 @@ void i915_gem_track_fb(struct drm_i915_gem_object
>> *old,
>>   * number comparisons on buffer last_read|write_seqno. It also allows an
>>   * emission time to be associated with the request for tracking how far 
>> ahead
>>   * of the GPU the submission is.
>> + *
>> + * The requests are reference counted, so upon creation they should have an
>> + * initial reference taken using kref_init
>>   */
>>  struct drm_i915_gem_request {
>>  struct kref ref;
>> @@ -2144,7 +2147,16 @@ struct drm_i915_gem_request {
>>  /** Position in the ringbuffer of the end of the whole request */
>>  u32 tail;
>> 
>> -/** Context related to this request */
>> +/**
>> + * Context related to this request
>> + * Contexts are refcounted, so when this request is associated with a
>> + * context, we must increment the context's refcount, to guarantee that
>> + * it persists while any request is linked to it. Requests themselves
>> + * are also refcounted, so the request will only be freed when the last
>> + * reference to it is dismissed, and the code in
>> + * i915_gem_request_free() will then decrement the refcount on the
>> + * context.
>> + */
>>  struct intel_context *ctx;
>> 
>>  /** Batch buffer related to this request if any */
>> diff --git a/drivers/gpu/drm/i915/i915_gem.c
>> b/drivers/gpu/drm/i915/i915_gem.c
>> index 61134ab..996f60f 100644
>> --- a/drivers/gpu/drm/i915/i915_gem.c
>> +++ b/drivers/gpu/drm/i915/i915_gem.c
>> @@ -2664,8 +2664,7 @@ static void i915_gem_reset_ring_cleanup(struct
>> drm_i915_private *dev_priv,
>>  if (submit_req->ctx != ring->default_context)
>>  intel_lr_context_unpin(ring, submit_req->ctx);
>> 
>> -i915_gem_context_unreference(submit_req->ctx);
>> -kfree(submit_req);
>> +i915_gem_request_unreference(submit_req);
>>  }
>> 
>>  /*
>> diff --git a/drivers/gpu/drm/i915/intel_lrc.c 
>> b/drivers/gpu/drm/i915/intel_lrc.c
>> index aafcef3..62a2b2a 100644
>> --- a/drivers/gpu/drm/i915/intel_lrc.c
>> +++ b/drivers/gpu/drm/i915/intel_lrc.c
>> @@ -512,18 +512,19 @@ static int execlists_context_queue(struct
>> intel_engine_cs *ring,
>>   * If there isn't a request associated with this submission,
>>   * create one as a temporary holder.
>>   */
>> -WARN(1, "execlist context submission without request");
>>  request = kzalloc(sizeof(*request), GFP_KERNEL);
>>  if (request == NULL)
>>  return -ENOMEM;
>>  request->ring = ring;
>>  request->ctx = to;
>> +kref_init(&request->ref);
>> +request->uniq = dev_priv->request_uniq++;
>> +i915_gem_context_reference(request->ctx);
>>  } else {
>> +i915_gem_request_reference(request);
>>  WARN_ON(

Re: [Intel-gfx] [PATCH] drm/i915: Do not invalidate obj->pages under mempressure

2015-02-24 Thread Jani Nikula
On Tue, 10 Feb 2015, Jani Nikula  wrote:
> On Mon, 09 Feb 2015, Daniel Vetter  wrote:
>> From: Chris Wilson 
>>
>> This (partially) reverts
>>
>> commit 5537252b6b6d71fb1a8ed7395a8e5babf91953fd
>> Author: Chris Wilson 
>> Date:   Tue Mar 25 13:23:06 2014 +
>>
>> drm/i915: Invalidate our pages under memory pressure
>>
>> It appears given the right workload, that pages which are swapped out
>> more than once are incorrectly invalidated and discarded. I had presumed
>> that the swapin would mark the pages dirty again and so preserve them
>> against the next cycle of invalidation - that appears to be false, and
>> leads to memory corruption (even leak of stale pages to userspace).
>>
>> v2: Do a more throughrought revert and als get rid of the hunk in
>> gem_free_objects which we've tried to patch up already in
>>
>> commit 340fbd8ca1c7d6006a6b6afe716c10007bbfde85
>> Author: Chris Wilson 
>> Date:   Thu May 22 09:16:52 2014 +0100
>>
>> drm/i915: Only discard backing storage on releasing the last ref
>>
>> This means this patch also fully reverts this fixup. Apparently this
>> is just too tricky.
>>
>> Reported-by: Sean V Kelley 
>> Signed-off-by: Chris Wilson 
>> Cc: Sean V Kelley 
>> Cc: sta...@vger.kernel.org
>> Cc: Chris Wilson 
>> Cc: Jani Nikula 
>> Signed-off-by: Daniel Vetter  (v2)
>
> Pushed this one to drm-intel-next-fixes, thanks for the patch, and v2 of
> the patch.

For completeness, this one was dropped again on Feb 11.

Jani.


>
> BR,
> Jani.
>
>> ---
>>  drivers/gpu/drm/i915/i915_gem.c | 49 
>> ++---
>>  1 file changed, 2 insertions(+), 47 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i915/i915_gem.c 
>> b/drivers/gpu/drm/i915/i915_gem.c
>> index 36f1093e3c63..39e2af9b5fef 100644
>> --- a/drivers/gpu/drm/i915/i915_gem.c
>> +++ b/drivers/gpu/drm/i915/i915_gem.c
>> @@ -1946,26 +1946,6 @@ i915_gem_object_truncate(struct drm_i915_gem_object 
>> *obj)
>>  obj->madv = __I915_MADV_PURGED;
>>  }
>>  
>> -/* Try to discard unwanted pages */
>> -static void
>> -i915_gem_object_invalidate(struct drm_i915_gem_object *obj)
>> -{
>> -struct address_space *mapping;
>> -
>> -switch (obj->madv) {
>> -case I915_MADV_DONTNEED:
>> -i915_gem_object_truncate(obj);
>> -case __I915_MADV_PURGED:
>> -return;
>> -}
>> -
>> -if (obj->base.filp == NULL)
>> -return;
>> -
>> -mapping = file_inode(obj->base.filp)->i_mapping,
>> -invalidate_mapping_pages(mapping, 0, (loff_t)-1);
>> -}
>> -
>>  static void
>>  i915_gem_object_put_pages_gtt(struct drm_i915_gem_object *obj)
>>  {
>> @@ -2028,7 +2008,8 @@ i915_gem_object_put_pages(struct drm_i915_gem_object 
>> *obj)
>>  ops->put_pages(obj);
>>  obj->pages = NULL;
>>  
>> -i915_gem_object_invalidate(obj);
>> +if (i915_gem_object_is_purgeable(obj))
>> +i915_gem_object_truncate(obj);
>>  
>>  return 0;
>>  }
>> @@ -4458,30 +4439,6 @@ struct drm_i915_gem_object 
>> *i915_gem_alloc_object(struct drm_device *dev,
>>  return obj;
>>  }
>>  
>> -static bool discard_backing_storage(struct drm_i915_gem_object *obj)
>> -{
>> -/* If we are the last user of the backing storage (be it shmemfs
>> - * pages or stolen etc), we know that the pages are going to be
>> - * immediately released. In this case, we can then skip copying
>> - * back the contents from the GPU.
>> - */
>> -
>> -if (obj->madv != I915_MADV_WILLNEED)
>> -return false;
>> -
>> -if (obj->base.filp == NULL)
>> -return true;
>> -
>> -/* At first glance, this looks racy, but then again so would be
>> - * userspace racing mmap against close. However, the first external
>> - * reference to the filp can only be obtained through the
>> - * i915_gem_mmap_ioctl() which safeguards us against the user
>> - * acquiring such a reference whilst we are in the middle of
>> - * freeing the object.
>> - */
>> -return atomic_long_read(&obj->base.filp->f_count) == 1;
>> -}
>> -
>>  void i915_gem_free_object(struct drm_gem_object *gem_obj)
>>  {
>>  struct drm_i915_gem_object *obj = to_intel_bo(gem_obj);
>> @@ -4524,8 +4481,6 @@ void i915_gem_free_object(struct drm_gem_object 
>> *gem_obj)
>>  
>>  if (WARN_ON(obj->pages_pin_count))
>>  obj->pages_pin_count = 0;
>> -if (discard_backing_storage(obj))
>> -obj->madv = I915_MADV_DONTNEED;
>>  i915_gem_object_put_pages(obj);
>>  i915_gem_object_free_mmap_offset(obj);
>>  
>> -- 
>> 2.1.4
>>
>
> -- 
> Jani Nikula, Intel Open Source Technology Center

-- 
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 17/53] drm/i915: Split i915_ppgtt_init_hw() in half - generic and per ring

2015-02-24 Thread Daniel, Thomas
> -Original Message-
> From: Intel-gfx [mailto:intel-gfx-boun...@lists.freedesktop.org] On Behalf Of
> john.c.harri...@intel.com
> Sent: Thursday, February 19, 2015 5:17 PM
> To: Intel-GFX@Lists.FreeDesktop.Org
> Subject: [Intel-gfx] [PATCH 17/53] drm/i915: Split i915_ppgtt_init_hw() in 
> half -
> generic and per ring
> 
> From: John Harrison 
> 
> The i915_gem_init_hw() function calls a bunch of smaller initialisation
> functions. Multiple of which have generic sections and per ring sections. This
> means multiple passes are done over the rings. Each pass writes data to the 
> ring
> which floats around in that ring's OLR until some random point in the future
> when an add_request() is done by some random other piece of code.
> 
> This patch breaks i915_ppgtt_init_hw() in two with the per ring initialisation
> now being done in i915_ppgtt_init_ring(). The ring looping is now done at the
> top level in i915_gem_init_hw().
> 
> For: VIZ-5115
> Signed-off-by: John Harrison 
> ---
>  drivers/gpu/drm/i915/i915_gem.c |   25 +++--
>  drivers/gpu/drm/i915/i915_gem_gtt.c |   25 -
>  drivers/gpu/drm/i915/i915_gem_gtt.h |1 +
>  3 files changed, 32 insertions(+), 19 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_gem.c
> b/drivers/gpu/drm/i915/i915_gem.c
> index 51f719c..9bc60d7 100644
> --- a/drivers/gpu/drm/i915/i915_gem.c
> +++ b/drivers/gpu/drm/i915/i915_gem.c
> @@ -4844,19 +4844,32 @@ i915_gem_init_hw(struct drm_device *dev)
>*/
>   init_unused_rings(dev);
> 
> + ret = i915_ppgtt_init_hw(dev);
> + if (ret) {
> + DRM_ERROR("PPGTT enable HW failed %d\n", ret);
> + return ret;
> + }
> +
> + /* Need to do basic initialisation of all rings first: */
>   for_each_ring(ring, dev_priv, i) {
>   ret = ring->init_hw(ring);
>   if (ret)
>   return ret;
>   }
> 
> - for (i = 0; i < NUM_L3_SLICES(dev); i++)
> - i915_gem_l3_remap(&dev_priv->ring[RCS], i);
> + /* Now it is safe to go back round and do everything else: */
> + for_each_ring(ring, dev_priv, i) {
> + if (ring->id == RCS) {
> + for (i = 0; i < NUM_L3_SLICES(dev); i++)
> + i915_gem_l3_remap(ring, i);
> + }
> 
> - ret = i915_ppgtt_init_hw(dev);
> - if (ret && ret != -EIO) {
> - DRM_ERROR("PPGTT enable failed %d\n", ret);
> - i915_gem_cleanup_ringbuffer(dev);
> + ret = i915_ppgtt_init_ring(ring);
> + if (ret && ret != -EIO) {
> + DRM_ERROR("PPGTT enable ring #%d failed %d\n", i,
> ret);
> + i915_gem_cleanup_ringbuffer(dev);
> + return ret;
> + }
>   }
> 
>   ret = i915_gem_context_enable(dev_priv);
> diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c
> b/drivers/gpu/drm/i915/i915_gem_gtt.c
> index e54b2a0..428d2f6 100644
> --- a/drivers/gpu/drm/i915/i915_gem_gtt.c
> +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
> @@ -1206,11 +1206,6 @@ int i915_ppgtt_init(struct drm_device *dev, struct
> i915_hw_ppgtt *ppgtt)
> 
>  int i915_ppgtt_init_hw(struct drm_device *dev)
>  {
> - struct drm_i915_private *dev_priv = dev->dev_private;
> - struct intel_engine_cs *ring;
> - struct i915_hw_ppgtt *ppgtt = dev_priv->mm.aliasing_ppgtt;
> - int i, ret = 0;
> -
>   /* In the case of execlists, PPGTT is enabled by the context descriptor
>* and the PDPs are contained within the context itself.  We don't
>* need to do anything here. */
> @@ -1229,16 +1224,20 @@ int i915_ppgtt_init_hw(struct drm_device *dev)
>   else
>   MISSING_CASE(INTEL_INFO(dev)->gen);
> 
> - if (ppgtt) {
> - for_each_ring(ring, dev_priv, i) {
> - ret = ppgtt->switch_mm(ppgtt, ring);
> - if (ret != 0)
> - return ret;
> - }
> - }
> + return 0;
> +}
> 
> - return ret;
> +int i915_ppgtt_init_ring(struct intel_engine_cs *ring)
> +{
> + struct drm_i915_private *dev_priv = ring->dev->dev_private;
> + struct i915_hw_ppgtt *ppgtt = dev_priv->mm.aliasing_ppgtt;
> +
> + if (!ppgtt)
> + return 0;
> +
> + return ppgtt->switch_mm(ppgtt, ring);
>  }
This breaks alias PPGTT for execlists.
I915_ppgtt_init_hw() is a noop for execlists mode, but the new 
i915_ppgtt_init_ring() will try to do a switch_mm() which should not be done 
for execlists.

Thomas.

> +
>  struct i915_hw_ppgtt *
>  i915_ppgtt_create(struct drm_device *dev, struct drm_i915_file_private 
> *fpriv)
>  {
> diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h
> b/drivers/gpu/drm/i915/i915_gem_gtt.h
> index 8f76990..5a6cef9 100644
> --- a/drivers/gpu/drm/i915/i915_gem_gtt.h
> +++ b/drivers/gpu/drm/i915/i915_gem_gtt.h
> @@ -300,6 +300,7 @@ void i915_global_gtt_cleanup(struct drm_device *dev);
> 
>  i

Re: [Intel-gfx] [PATCH v4] drm/i915: avoid processing spurious/shared interrupts in low-power states

2015-02-24 Thread Jani Nikula
On Tue, 24 Feb 2015, Imre Deak  wrote:
> Atm, it's possible that the interrupt handler is called when the device
> is in D3 or some other low-power state. It can be due to another device
> that is still in D0 state and shares the interrupt line with i915, or on
> some platforms there could be spurious interrupts even without sharing
> the interrupt line. The latter case was reported by Klaus Ethgen using a
> Lenovo x61p machine (gen 4). He noticed this issue via a system
> suspend/resume hang and bisected it to the following commit:
>
> commit e11aa362308f5de467ce355a2a2471321b15a35c
> Author: Jesse Barnes 
> Date:   Wed Jun 18 09:52:55 2014 -0700
>
> drm/i915: use runtime irq suspend/resume in freeze/thaw
>
> This is a problem, since in low-power states IIR will always read
> 0x resulting in an endless IRQ servicing loop.
>
> Fix this by handling interrupts only when the driver explicitly enables
> them and so it's guaranteed that the interrupt registers return a valid
> value.
>
> Note that this issue existed even before the above commit, since during
> runtime suspend/resume we never unregistered the handler.
>
> v2:
> - clarify the purpose of smp_mb() vs. synchronize_irq() in the
>   code comment (Chris)
>
> v3:
> - no need for an explicit smp_mb(), we can assume that synchronize_irq()
>   and the mmio read/writes in the install hooks provide for this (Daniel)
> - remove code comment as the remaining synchronize_irq() is self
>   explanatory (Daniel)
>
> v4:
> - drm_irq_uninstall() implies synchronize_irq(), so no need to call it
>   explicitly (Daniel)
>
> Reference: https://lkml.org/lkml/2015/2/11/205
> Reported-and-bisected-by: Klaus Ethgen 
> Signed-off-by: Imre Deak 
> Reviewed-by: Daniel Vetter 

Pushed to drm-intel-fixes, cc: stable, thanks for the patch and review.

BR,
Jani.


> ---
>  drivers/gpu/drm/i915/i915_irq.c | 22 ++
>  1 file changed, 22 insertions(+)
>
> diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
> index 9073119..1561248 100644
> --- a/drivers/gpu/drm/i915/i915_irq.c
> +++ b/drivers/gpu/drm/i915/i915_irq.c
> @@ -1889,6 +1889,9 @@ static irqreturn_t valleyview_irq_handler(int irq, void 
> *arg)
>   u32 iir, gt_iir, pm_iir;
>   irqreturn_t ret = IRQ_NONE;
>  
> + if (!intel_irqs_enabled(dev_priv))
> + return IRQ_NONE;
> +
>   while (true) {
>   /* Find, clear, then process each source of interrupt */
>  
> @@ -1933,6 +1936,9 @@ static irqreturn_t cherryview_irq_handler(int irq, void 
> *arg)
>   u32 master_ctl, iir;
>   irqreturn_t ret = IRQ_NONE;
>  
> + if (!intel_irqs_enabled(dev_priv))
> + return IRQ_NONE;
> +
>   for (;;) {
>   master_ctl = I915_READ(GEN8_MASTER_IRQ) & 
> ~GEN8_MASTER_IRQ_CONTROL;
>   iir = I915_READ(VLV_IIR);
> @@ -2205,6 +2211,9 @@ static irqreturn_t ironlake_irq_handler(int irq, void 
> *arg)
>   u32 de_iir, gt_iir, de_ier, sde_ier = 0;
>   irqreturn_t ret = IRQ_NONE;
>  
> + if (!intel_irqs_enabled(dev_priv))
> + return IRQ_NONE;
> +
>   /* We get interrupts on unclaimed registers, so check for this before we
>* do any I915_{READ,WRITE}. */
>   intel_uncore_check_errors(dev);
> @@ -2276,6 +2285,9 @@ static irqreturn_t gen8_irq_handler(int irq, void *arg)
>   enum pipe pipe;
>   u32 aux_mask = GEN8_AUX_CHANNEL_A;
>  
> + if (!intel_irqs_enabled(dev_priv))
> + return IRQ_NONE;
> +
>   if (IS_GEN9(dev))
>   aux_mask |=  GEN9_AUX_CHANNEL_B | GEN9_AUX_CHANNEL_C |
>   GEN9_AUX_CHANNEL_D;
> @@ -3768,6 +3780,9 @@ static irqreturn_t i8xx_irq_handler(int irq, void *arg)
>   I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT |
>   I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT;
>  
> + if (!intel_irqs_enabled(dev_priv))
> + return IRQ_NONE;
> +
>   iir = I915_READ16(IIR);
>   if (iir == 0)
>   return IRQ_NONE;
> @@ -3948,6 +3963,9 @@ static irqreturn_t i915_irq_handler(int irq, void *arg)
>   I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT;
>   int pipe, ret = IRQ_NONE;
>  
> + if (!intel_irqs_enabled(dev_priv))
> + return IRQ_NONE;
> +
>   iir = I915_READ(IIR);
>   do {
>   bool irq_received = (iir & ~flip_mask) != 0;
> @@ -4168,6 +4186,9 @@ static irqreturn_t i965_irq_handler(int irq, void *arg)
>   I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT |
>   I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT;
>  
> + if (!intel_irqs_enabled(dev_priv))
> + return IRQ_NONE;
> +
>   iir = I915_READ(IIR);
>  
>   for (;;) {
> @@ -4517,6 +4538,7 @@ void intel_runtime_pm_disable_interrupts(struct 
> drm_i915_private *dev_priv)
>  {
>   dev_priv->dev->driver->irq_uninstall(dev_priv->dev);
>   dev_priv->pm.irqs_enabled = false;
> + synchronize_irq(dev_priv->dev->irq);
>  }
>  
>  /**

Re: [Intel-gfx] [PATCH] drm/i915: Check obj->vma_list under the struct_mutex

2015-02-24 Thread Jani Nikula
On Thu, 12 Feb 2015, Daniel Vetter  wrote:
> On Thu, Feb 12, 2015 at 07:53:18AM +, Chris Wilson wrote:
>> When we walk the list of vma, or even for protecting against concurrent
>> framebuffer creation, we must hold the struct_mutex or else a second
>> thread can corrupt the list as we walk it.
>> 
>> Fixes regression from
>> commit d7f46fc4e7323887494db13f063a8e59861fefb0
>> Author: Ben Widawsky 
>> Date:   Fri Dec 6 14:10:55 2013 -0800
>> 
>> drm/i915: Make pin count per VMA
>> 
>> References: https://bugs.freedesktop.org/show_bug.cgi?id=89085
>> Signed-off-by: Chris Wilson 
>> ---
>>  drivers/gpu/drm/i915/i915_gem_tiling.c | 7 ---
>>  1 file changed, 4 insertions(+), 3 deletions(-)
>> 
>> diff --git a/drivers/gpu/drm/i915/i915_gem_tiling.c 
>> b/drivers/gpu/drm/i915/i915_gem_tiling.c
>> index 7a24bd1a51f6..6377b22269ad 100644
>> --- a/drivers/gpu/drm/i915/i915_gem_tiling.c
>> +++ b/drivers/gpu/drm/i915/i915_gem_tiling.c
>> @@ -335,9 +335,10 @@ i915_gem_set_tiling(struct drm_device *dev, void *data,
>>  return -EINVAL;
>>  }
>>  
>> +mutex_lock(&dev->struct_mutex);
>>  if (i915_gem_obj_is_pinned(obj) || obj->framebuffer_references) {
>
> Since the removal of userspace pinning we shouldn't be able to see pinned
> objects here which are _not_ framebuffers too. But we still need the lock
> for synchronization and to avoid races, but perhaps we could drop the list
> walk?
>
> Either way this is
>
> Reviewed-by: Daniel Vetter 
> Cc: sta...@vger.kernel.org (we have some vague evidence that it blows up
> at last)

Pushed to drm-intel-fixes, thanks for the patch and review.

BR,
Jani.

>
> I've also audited all the other callers of is_pinned, the only other
> suspicious one is the one in capture_bo. Perhaps we should also move that
> over to obj->framebuffer_references?
>
> Cheers, Daniel
>> -drm_gem_object_unreference_unlocked(&obj->base);
>> -return -EBUSY;
>> +ret = -EBUSY;
>> +goto err;
>>  }
>>  
>>  if (args->tiling_mode == I915_TILING_NONE) {
>> @@ -369,7 +370,6 @@ i915_gem_set_tiling(struct drm_device *dev, void *data,
>>  }
>>  }
>>  
>> -mutex_lock(&dev->struct_mutex);
>>  if (args->tiling_mode != obj->tiling_mode ||
>>  args->stride != obj->stride) {
>>  /* We need to rebind the object if its current allocation
>> @@ -424,6 +424,7 @@ i915_gem_set_tiling(struct drm_device *dev, void *data,
>>  obj->bit_17 = NULL;
>>  }
>>  
>> +err:
>>  drm_gem_object_unreference(&obj->base);
>>  mutex_unlock(&dev->struct_mutex);
>>  
>> -- 
>> 2.1.4
>> 
>> ___
>> Intel-gfx mailing list
>> Intel-gfx@lists.freedesktop.org
>> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
>
> -- 
> Daniel Vetter
> Software Engineer, Intel Corporation
> +41 (0) 79 365 57 48 - http://blog.ffwll.ch

-- 
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 v5 03/32] drm/i915: Create page table allocators

2015-02-24 Thread Mika Kuoppala
Michel Thierry  writes:

> From: 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.
>

I don't quite understand the last sentence here. We gain overhead and
complexity.

s/non-trivial/trivial?

> This patch exists for a few reasons:
> 1. Splitting out the functions allows easily combining GEN6 and GEN8
> code. Page tables have no difference based on GEN8. As we'll see in a
> future patch when we add the DMA mappings to the allocations, it
> requires only one small change to make work, and error handling should
> just fall into place.
>
> 2. Unless we always want to allocate all page tables under a given PDE,
> we'll have to eventually break this up into an array of pointers (or
> pointer to pointer).
>
> 3. Having the discrete functions is easier to review, and understand.
> All allocations and frees now take place in just a couple of locations.
> Reviewing, and catching leaks should be easy.
>
> 4. Less important: the GFP flags are confined to one location, which
> makes playing around with such things trivial.
>
> v2: Updated commit message to explain why this patch exists
>
> v3: For lrc, s/pdp.page_directory[i].daddr/pdp.page_directory[i]->daddr/
>
> v4: Renamed free_pt/pd_single functions to unmap_and_free_pt/pd (Daniel)
>
> v5: Added additional safety checks in gen8 clear/free/unmap.
>
> v6: Use WARN_ON and return -EINVAL in alloc_pt_range (Mika).
>
> Cc: Mika Kuoppala 
> Signed-off-by: Ben Widawsky 
> Signed-off-by: Michel Thierry  (v3+)
> ---
>  drivers/gpu/drm/i915/i915_gem_gtt.c | 252 
> 
>  drivers/gpu/drm/i915/i915_gem_gtt.h |   4 +-
>  drivers/gpu/drm/i915/intel_lrc.c|  16 +--
>  3 files changed, 178 insertions(+), 94 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
> b/drivers/gpu/drm/i915/i915_gem_gtt.c
> index eb0714c..65c77e5 100644
> --- a/drivers/gpu/drm/i915/i915_gem_gtt.c
> +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
> @@ -279,6 +279,98 @@ static gen6_gtt_pte_t iris_pte_encode(dma_addr_t addr,
>   return pte;
>  }
>  
> +static void unmap_and_free_pt(struct i915_page_table_entry *pt)
> +{
> + if (WARN_ON(!pt->page))
> + return;
> + __free_page(pt->page);
> + kfree(pt);
> +}
> +
> +static struct i915_page_table_entry *alloc_pt_single(void)
> +{
> + struct i915_page_table_entry *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_page_directory_entry *pd, uint16_t 
> pde, size_t count)
> +{
> + int i, ret;
> +
> + /* 512 is the max page tables per page_directory on any platform. */
> + if (WARN_ON(pde + count > GEN6_PPGTT_PD_ENTRIES))
> + return -EINVAL;
> +
> + for (i = pde; i < pde + count; i++) {
> + struct i915_page_table_entry *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--)
> + unmap_and_free_pt(pd->page_tables[i]);

This is suspicious as it is non symmetrical of how we allocate. If the
plan is to free everything below pde, that should be mentioned in the
comment above.

On this patch we call this with pde == 0, but 

Re: [Intel-gfx] [RFC 09/12] drm/i915/config: Add VBT settings configuration.

2015-02-24 Thread Daniel Vetter
On Thu, Feb 12, 2015 at 03:41:35PM -0800, Bob Paauwe wrote:
> Add a new section with subsections to the ACPI configuration table
> that mimics much of the information typically stored in the VBT/option
> ROM. This allows for a way to override incorrect VBT data or to provide
> the configuration if VBT is not present.  Lack of VBT is common in
> embedded systems.
> 
> Any data found in the configuration tables will replace the driver's
> vbt structure.
> 
> MIPI DSI configuration is not implmemnted at this time.
> 
> Signed-off-by: Bob Paauwe 

I'm not too happy with the duplicate of standards this creates. Is there
no way to just load a vbt blob into the acpi table somewhere and require
that it perfectly matches the vbt "standard" for the given platforms,
warts and all included?

As Jani points out we already have vbt headaches, it would be good if we
only have those once ;-)
-Daniel

> ---
>  drivers/gpu/drm/i915/i915_dma.c |   2 +
>  drivers/gpu/drm/i915/i915_drv.h |   1 +
>  drivers/gpu/drm/i915/intel_config.c | 334 
> 
>  drivers/gpu/drm/i915/intel_drv.h|   4 +-
>  4 files changed, 340 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
> index 9501360..9119e9b 100644
> --- a/drivers/gpu/drm/i915/i915_dma.c
> +++ b/drivers/gpu/drm/i915/i915_dma.c
> @@ -852,6 +852,8 @@ int i915_driver_load(struct drm_device *dev, unsigned 
> long flags)
>   if (intel_vgpu_active(dev))
>   I915_WRITE(vgtif_reg(display_ready), VGT_DRV_DISPLAY_READY);
>  
> + intel_config_vbt(dev_priv);
> +
>   i915_setup_sysfs(dev);
>  
>   if (INTEL_INFO(dev)->num_pipes) {
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 1580702..a60511e 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -1657,6 +1657,7 @@ struct intel_config_info {
>   struct list_head connector_list;
>   struct list_head plane_list;
>   struct list_head wa_list;
> + struct list_head vbt_list;
>  };
>  
>  
> diff --git a/drivers/gpu/drm/i915/intel_config.c 
> b/drivers/gpu/drm/i915/intel_config.c
> index ab14928..c1b06b7 100644
> --- a/drivers/gpu/drm/i915/intel_config.c
> +++ b/drivers/gpu/drm/i915/intel_config.c
> @@ -215,6 +215,7 @@ void intel_config_init(struct drm_device *dev)
>   INIT_LIST_HEAD(&info->connector_list);
>   INIT_LIST_HEAD(&info->plane_list);
>   INIT_LIST_HEAD(&info->wa_list);
> + INIT_LIST_HEAD(&info->vbt_list);
>  
>   handle = ACPI_HANDLE(dev->dev);
>   if (!handle) {
> @@ -241,6 +242,7 @@ void intel_config_init(struct drm_device *dev)
>  #define i915_COMPONENT_CONNECTOR "CNCT"
>  #define i915_COMPONENT_PLANE "PLNS"
>  #define i915_COMPONENT_WORKAROUND "WRKS"
> +#define i915_COMPONENT_VBIOSTABLE "VBT"
>  
>   /* Build lists */
>   list_for_each_entry(component, &info->base.adev->children, node) {
> @@ -267,6 +269,18 @@ void intel_config_init(struct drm_device *dev)
>   } else if (strcmp(cname, i915_COMPONENT_WORKAROUND) == 0) {
>   if (!alloc_new_node(cl, &info->wa_list))
>   goto bail;
> + } else if (strcmp(cname, i915_COMPONENT_VBIOSTABLE) == 0) {
> + /* Add the main VBT node */
> + if (!alloc_new_node(cl, &info->vbt_list))
> + goto bail;
> +
> + /* This adds all the sub device nodes */
> + list_for_each_entry(cl, &component->children, node) {
> + if (!alloc_new_node(cl, &info->vbt_list))
> + goto bail;
> + }
> + } else {
> + DRM_DEBUG_DRIVER("i915/config: Unknown component : 
> %s\n", cname);
>   }
>   }
>  
> @@ -284,6 +298,8 @@ bail:
>   kfree(new_node);
>   list_for_each_entry_safe(new_node, tmp, &info->wa_list, node)
>   kfree(new_node);
> + list_for_each_entry_safe(new_node, tmp, &info->vbt_list, node)
> + kfree(new_node);
>  
>   kfree(info);
>   dev_priv->config_info = NULL;
> @@ -318,6 +334,8 @@ void intel_config_shutdown(struct drm_device *dev)
>   kfree(n);
>   list_for_each_entry_safe(n, tmp, &info->wa_list, node)
>   kfree(n);
> + list_for_each_entry_safe(n, tmp, &info->vbt_list, node)
> + kfree(n);
>  
>   /* Unload any dynamically loaded ACPI property table */
>   handle = ACPI_HANDLE(dev->dev);
> @@ -395,6 +413,8 @@ static struct list_head *cfg_type_to_list(struct 
> intel_config_info *info,
>   return &info->plane_list;
>   case CFG_WORKAROUND:
>   return &info->wa_list;
> + case CFG_VBT:
> + return &info->vbt_list;
>   }
>   return NULL;
>  }
> @@ -433,6 +453,320 @@ bool intel_config_get_integer(struct drm

Re: [Intel-gfx] [PATCH v2 0/7] Added missing changes for Turbo feature on SKL

2015-02-24 Thread Damien Lespiau
On Wed, Feb 18, 2015 at 07:31:13PM +0530, akash.g...@intel.com wrote:
> From: Akash Goel 
> 
> This patch series add missing changes, required for proper functioning of the
> Turbo feature on SKL.
> Addressed review comments from Damien & Chris. 

Another item on the TODO list (for whoever is going to fix this), it
seems it'd be advisable to change gen9_enable_rc6() to use the new
GT_INTERVAL_FROM_US() macro.

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


Re: [Intel-gfx] [PATCH 2/7] drm/i915/skl: Updated the gen6_set_rps function

2015-02-24 Thread Damien Lespiau
On Wed, Feb 18, 2015 at 07:31:11PM +0530, akash.g...@intel.com wrote:
> From: Akash Goel 
> 
> On SKL, the frequency programmed in RPNSWREQ (A008) register
> has to be in units of 16.66 MHZ. So updated the gen6_set_rps
> function, as per this change.
> 
> Signed-off-by: Akash Goel 
> Reviewed-by: Lespiau, Damien 

Please don't use the Outlook way "lastname, firstname" here :)

-- 
Damien

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


Re: [Intel-gfx] [PATCH v2 6/7] drm/i915/skl: Updated the 'i915_frequency_info' debugs function

2015-02-24 Thread Ville Syrjälä
On Wed, Feb 18, 2015 at 07:31:18PM +0530, akash.g...@intel.com wrote:
> From: Akash Goel 
> 
> Added support for SKL in the 'i915_frequency_info' debugfs function
> 
> v2: Added missing conversion to 50MHZ for reqf & cagf (Damien)
> 
> Signed-off-by: Akash Goel 
> ---
>  drivers/gpu/drm/i915/i915_debugfs.c | 25 +
>  1 file changed, 17 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_debugfs.c 
> b/drivers/gpu/drm/i915/i915_debugfs.c
> index 9af17fb..5fb0121 100644
> --- a/drivers/gpu/drm/i915/i915_debugfs.c
> +++ b/drivers/gpu/drm/i915/i915_debugfs.c
> @@ -1089,7 +1089,7 @@ static int i915_frequency_info(struct seq_file *m, void 
> *unused)
>   seq_printf(m, "Current P-state: %d\n",
>  (rgvstat & MEMSTAT_PSTATE_MASK) >> 
> MEMSTAT_PSTATE_SHIFT);
>   } else if (IS_GEN6(dev) || (IS_GEN7(dev) && !IS_VALLEYVIEW(dev)) ||
> -IS_BROADWELL(dev)) {
> +IS_BROADWELL(dev) || IS_GEN9(dev)) {
>   u32 gt_perf_status = I915_READ(GEN6_GT_PERF_STATUS);
>   u32 rp_state_limits = I915_READ(GEN6_RP_STATE_LIMITS);
>   u32 rp_state_cap = I915_READ(GEN6_RP_STATE_CAP);
> @@ -1108,11 +1108,17 @@ static int i915_frequency_info(struct seq_file *m, 
> void *unused)
>   intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL);
>  
>   reqf = I915_READ(GEN6_RPNSWREQ);
> - reqf &= ~GEN6_TURBO_DISABLE;
> - if (IS_HASWELL(dev) || IS_BROADWELL(dev))
> - reqf >>= 24;
> - else
> - reqf >>= 25;
> + if (IS_GEN9(dev)) {
> + reqf >>= 23;
> + /* Convert to 50 MHZ units from 16.667 MHZ */
> + reqf /= GEN9_FREQ_SCALER;
> + } else {
> + reqf &= ~GEN6_TURBO_DISABLE;
> + if (IS_HASWELL(dev) || IS_BROADWELL(dev))
> + reqf >>= 24;
> + else
> + reqf >>= 25;
> + }
>   reqf = intel_gpu_freq(dev_priv, reqf);
>  
>   rpmodectl = I915_READ(GEN6_RP_CONTROL);
> @@ -1128,7 +1134,10 @@ static int i915_frequency_info(struct seq_file *m, 
> void *unused)
>   rpprevdown = I915_READ(GEN6_RP_PREV_DOWN);
>   if (IS_HASWELL(dev) || IS_BROADWELL(dev))
>   cagf = (rpstat & HSW_CAGF_MASK) >> HSW_CAGF_SHIFT;
> - else
> + else if (IS_GEN9(dev)) {
> + cagf = (rpstat & GEN9_CAGF_MASK) >> GEN9_CAGF_SHIFT;
> + cagf /= GEN9_FREQ_SCALER;
> + } else
>   cagf = (rpstat & GEN6_CAGF_MASK) >> GEN6_CAGF_SHIFT;


I would put gen9 first, then hsw/bsw, then gen6.

Also there's now a gt_act_freq_mhz_show() that needs some love too.

>   cagf = intel_gpu_freq(dev_priv, cagf);
>  
> @@ -1152,7 +1161,7 @@ static int i915_frequency_info(struct seq_file *m, void 
> *unused)
>  pm_ier, pm_imr, pm_isr, pm_iir, pm_mask);
>   seq_printf(m, "GT_PERF_STATUS: 0x%08x\n", gt_perf_status);
>   seq_printf(m, "Render p-state ratio: %d\n",
> -(gt_perf_status & 0xff00) >> 8);
> +(gt_perf_status & (IS_GEN9(dev) ? 0x1ff00 : 0xff00)) 
> >> 8);
>   seq_printf(m, "Render p-state VID: %d\n",
>  gt_perf_status & 0xff);
>   seq_printf(m, "Render p-state limit: %d\n",
> -- 
> 1.9.2
> 
> ___
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Ville Syrjälä
Intel OTC
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH] drm/i915: fix failure to power off after hibernate

2015-02-24 Thread Imre Deak
On ti, 2015-02-24 at 15:58 +0100, Bjørn Mork wrote:
> This fixes a bug where hibernation completes, but the system
> fails to power off after the image has been saved.
> 
> Bisection lead to commit da2bc1b9db33 ("drm/i915: add poweroff_late
> handler") which added a .poweroff_late hook pointing to the same
> function as the .freeze_late hook, without any justification or
> explanation why this would be correct, except "for consistency".
> 
> The assumption that this "makes the power off handling identical to
> the S3 suspend and S4 freeze handling" is completely bogus. As clearly
> documented in Documentation/power/devices.txt, the poweroff* hooks
> are part of the hibernation API along with the freeze* hooks.  The
> phases involved in hibernation are:
> 
>prepare, freeze, freeze_late, freeze_noirq, thaw_noirq, thaw_early,
>thaw, complete, prepare, poweroff, poweroff_late, poweroff_noirq
> 
> With the above sequence in mind, it should be fairly obvious that you
> cannot save registers and disable the device in both the freeze_late
> and poweroff_late phases.  Or as Documentation/power/devices.txt
> explains it:
> 
>  The poweroff, poweroff_late and poweroff_noirq callbacks should do 
> essentially
>  the same things as the suspend, suspend_late and suspend_noirq callbacks,
>  respectively.  The only notable difference is that they need not store the
>  device register values, because the registers should already have been stored
>  during the freeze, freeze_late or freeze_noirq phases.
> 
> The "consistency" between suspend and hibernate was already in
> place, with freeze_late pointing to the same function as suspend_late.
> There is no need for any poweroff_late hook in this driver.

The poweroff handlers undo the actions of the thaw handlers. As the
original commit stated saving the registers is not needed there, but
it's also not a big overhead and there should be no problem doing it. We
are planning to optimize the hibernation sequence by for example not
shutting down the display between freeze and thaw, and also getting rid
of unnecessary steps at the power off phase. But before that we want to
actually unify things rather than having special cases, as maintaining
the special code paths caused already quite a lot of problems for us so
far.

Reverting the commit may hide some other issue, so before doing that
could you try the following patch:
http://lists.freedesktop.org/archives/intel-gfx/2015-February/060529.html

If with that you still get the hang could you try on top of that the
patch below, first having only pci_set_power_state uncommented, then
both pci_set_power_state and pci_disable_device uncommented?

Thanks,
Imre

diff --git a/drivers/gpu/drm/i915/i915_drv.c
b/drivers/gpu/drm/i915/i915_drv.c
index 4badb23..dc91d4b 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -968,6 +968,23 @@ static int i915_pm_suspend_late(struct device *dev)
return i915_drm_suspend_late(drm_dev);
 }
 
+static int i915_pm_poweroff_late(struct device *dev)
+{
+   struct drm_device *drm_dev = dev_to_i915(dev)->dev;
+   struct drm_i915_private *dev_priv = drm_dev->dev_private;
+   int ret;
+
+   ret = intel_suspend_complete(dev_priv);
+
+   if (ret)
+   return ret;
+
+   pci_disable_device(drm_dev->pdev);
+// pci_set_power_state(drm_dev->pdev, PCI_D3hot);
+
+   return 0;
+}
+
 static int i915_pm_resume_early(struct device *dev)
 {
struct drm_device *drm_dev = dev_to_i915(dev)->dev;
@@ -1535,7 +1552,7 @@ static const struct dev_pm_ops i915_pm_ops = {
.thaw_early = i915_pm_resume_early,
.thaw = i915_pm_resume,
.poweroff = i915_pm_suspend,
-   .poweroff_late = i915_pm_suspend_late,
+   .poweroff_late = i915_pm_poweroff_late,
.restore_early = i915_pm_resume_early,
.restore = i915_pm_resume,
 


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


Re: [Intel-gfx] [RFC 01/12] drm/i915/config: Initial framework

2015-02-24 Thread Daniel Vetter
On Thu, Feb 12, 2015 at 03:41:27PM -0800, Bob Paauwe wrote:
> This adds an init-time configuration framework that parses configuration
> data from an ACPI property table. The table is assumed to have well
> defined sub-device property tables that correspond to the various
> driver components.  Initially the following sub-device tables are
> defined:
> 
> CRTC (CRTC)
>The CRTC sub-device table contains additional sub-device tables
>where each one corresponds to a CRTC.  Each CRTC sub-device must
>include a property called "id" whose value matches the driver's
>crtc id. Additional properties for the CRTC are used to configure
>the crtc.
> 
> Connector (CNCT)
>The CNCT sub-device table contains additional sub-device tables
>where each one corresponds to a connector. Each of the connector
>sub-device tables must include a property called "name" whose value
>matches a connector name assigned by the driver (see later patch
>for output name function). Additional connector properties can
>be set through these tables.
> 
> Plane (PLNS)
>The PLNS sub-device table contains additional sub-device tables
>where each one corresponds to a plane.  [this needs additional work]
> 
> In addition, the main device property table for the device may
> contain configuration information that applies to general driver
> configuration.
> 
> The framework includes a couple of helper functions to access the
> configuration data.
> 
>intel_config_get_integer() will look up a configuration property
>and return the integer value associated with it.
> 
>intel_config_init__property() will look up a
>configuration property and assign the value to a drm
>property of the same name.  These functions are used to
>initialize drm property instances to specific values.
> 
> Signed-off-by: Bob Paauwe 

Like Jani I'm mostly concerned about maintaining yet another slightly
different definition of paramters and settings here - we already have (or
will soon grow) per crtc/plane/connector properties for atomic.

My high-level idea for this was that we reuse the atomic support (once we
have it) and just take the acpi tables as a slightly different source for
an atomic update. Since the design of a name/value pair for objects is
very similar to what we do with the atomic ioctl this hopefully should map
fairly well.

Internally in the driver the only work needed to do would be to add any
missing properties. All the acpi atomic update code should be fully i915
agnostic and only use generic atomic update interfaces.

Would this work or do I overlook something important here.
-Daniel

> ---
>  drivers/gpu/drm/i915/Makefile   |   3 +-
>  drivers/gpu/drm/i915/i915_dma.c |   4 +
>  drivers/gpu/drm/i915/i915_drv.h |  16 ++
>  drivers/gpu/drm/i915/i915_params.c  |   6 +
>  drivers/gpu/drm/i915/intel_config.c | 542 
> 
>  drivers/gpu/drm/i915/intel_drv.h|  28 ++
>  6 files changed, 598 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/gpu/drm/i915/intel_config.c
> 
> diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
> index f025e7f..462de19 100644
> --- a/drivers/gpu/drm/i915/Makefile
> +++ b/drivers/gpu/drm/i915/Makefile
> @@ -12,7 +12,8 @@ i915-y := i915_drv.o \
>i915_suspend.o \
> i915_sysfs.o \
> intel_pm.o \
> -   intel_runtime_pm.o
> +   intel_runtime_pm.o \
> +   intel_config.o
>  
>  i915-$(CONFIG_COMPAT)   += i915_ioc32.o
>  i915-$(CONFIG_DEBUG_FS) += i915_debugfs.o
> diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
> index 5804aa5..9501360 100644
> --- a/drivers/gpu/drm/i915/i915_dma.c
> +++ b/drivers/gpu/drm/i915/i915_dma.c
> @@ -656,6 +656,8 @@ int i915_driver_load(struct drm_device *dev, unsigned 
> long flags)
>   dev->dev_private = dev_priv;
>   dev_priv->dev = dev;
>  
> + intel_config_init(dev);
> +
>   /* Setup the write-once "constant" device info */
>   device_info = (struct intel_device_info *)&dev_priv->info;
>   memcpy(device_info, info, sizeof(dev_priv->info));
> @@ -929,6 +931,8 @@ int i915_driver_unload(struct drm_device *dev)
>  
>   acpi_video_unregister();
>  
> + intel_config_shutdown(dev);
> +
>   if (drm_core_check_feature(dev, DRIVER_MODESET))
>   intel_fbdev_fini(dev);
>  
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 2dedd43..165091c 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -1645,6 +1645,20 @@ struct i915_virtual_gpu {
>   bool active;
>  };
>  
> +struct intel_config_node {
> + struct acpi_device *adev;
> + struct list_head node;
> + struct list_head list;
> +};
> +
> +struct intel_config_info {
> + struct intel_config_node base;
> + struct list_head crtc_list;
> + struct list_head connector_list;
> + struct list_head plane_list;
> 

[Intel-gfx] [PATCH v6 09/32] drm/i915: Finish gen6/7 dynamic page table allocation

2015-02-24 Thread Michel Thierry
From: 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.

v2: Make the page table bitmap declared inside the function (Chris)
Simplify the way scratching address space works.
Move the alloc/teardown tracepoints up a level in the call stack so that
both all implementations get the trace.

v3: Updated trace event to spit out a name

v4: Aliasing ppgtt is now initialized differently (in setup global gtt)

v5: Rebase to latest code. Also removed unnecessary aliasing ppgtt check
for trace, as it is no longer possible after the PPGTT cleanup patch series
of a couple of months ago (Daniel).

v6: Implement changes from code review (Daniel):
 - allocate/teardown_va_range calls added.
 - Add a scratch page allocation helper (only need the address).
 - Move trace events to a new patch.
 - Use updated mark_tlbs_dirty.
 - Moved pt preallocation for aliasing ppgtt into gen6_ppgtt_init.

v7: teardown_va_range removed (Daniel).
In init, gen6_ppgtt_clear_range call is only needed for aliasing ppgtt.

v8: Rebase after s/page_tables/page_table/.

Cc: Daniel Vetter 
Signed-off-by: Ben Widawsky 
Signed-off-by: Michel Thierry  (v4+)
---
 drivers/gpu/drm/i915/i915_debugfs.c |   3 +-
 drivers/gpu/drm/i915/i915_gem.c |   9 +++
 drivers/gpu/drm/i915/i915_gem_gtt.c | 125 +++-
 drivers/gpu/drm/i915/i915_gem_gtt.h |   3 +
 4 files changed, 123 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c 
b/drivers/gpu/drm/i915/i915_debugfs.c
index 4d07030..e8ad450 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -2181,6 +2181,8 @@ static void gen6_ppgtt_info(struct seq_file *m, struct 
drm_device *dev)
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;
 
@@ -2197,7 +2199,6 @@ static void gen6_ppgtt_info(struct seq_file *m, struct 
drm_device *dev)
   get_pid_task(file->pid, PIDTYPE_PID)->comm);
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)
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 61134ab..312b7d2 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -3599,6 +3599,15 @@ search_free:
if (ret)
goto err_remove_node;
 
+   /*  allocate before insert / bind */
+   if (vma->vm->allocate_va_range) {
+   ret = vma->vm->allocate_va_range(vma->vm,
+   vma->node.start,
+   vma->node.size);
+   if (ret)
+   goto err_remove_node;
+   }
+
trace_i915_vma_bind(vma, flags);
ret = i915_vma_bind(vma, obj->cache_level,
flags & PIN_GLOBAL ? GLOBAL_BIND : 0);
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/i915_gem_gtt.c
index bd8e876..29cda58 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ 

[Intel-gfx] [PATCH v6 07/32] drm/i915: Track page table reload need

2015-02-24 Thread Michel Thierry
From: Ben Widawsky 

This patch was formerly known as, "Force pd restore when PDEs change,
gen6-7." I had to change the name because it is needed for GEN8 too.

The real issue this is trying to solve is when a new object is mapped
into the current address space. The GPU does not snoop the new mapping
so we must do the gen specific action to reload the page tables.

GEN8 and GEN7 do differ in the way they load page tables for the RCS.
GEN8 does so with the context restore, while GEN7 requires the proper
load commands in the command streamer. Non-render is similar for both.

Caveat for GEN7
The docs say you cannot change the PDEs of a currently running context.
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.

It's not just for gen8. If the current context has mappings change, we
need a context reload to switch

v2: Rebased after ppgtt clean up patches. Split the warning for aliasing
and true ppgtt options. And do not break aliasing ppgtt, where to->ppgtt
is always null.

v3: Invalidate PPGTT TLBs inside alloc_va_range.

v4: Rename ppgtt_invalidate_tlbs to mark_tlbs_dirty and move
pd_dirty_rings from i915_address_space to i915_hw_ppgtt. Fixes when
neither ctx->ppgtt and aliasing_ppgtt exist.

v5: Removed references to teardown_va_range.

Signed-off-by: Ben Widawsky 
Signed-off-by: Michel Thierry  (v2+)
---
 drivers/gpu/drm/i915/i915_gem_context.c| 29 -
 drivers/gpu/drm/i915/i915_gem_execbuffer.c | 11 +++
 drivers/gpu/drm/i915/i915_gem_gtt.c| 11 +++
 drivers/gpu/drm/i915/i915_gem_gtt.h|  1 +
 4 files changed, 47 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_context.c 
b/drivers/gpu/drm/i915/i915_gem_context.c
index 6206d27..437cdcc 100644
--- a/drivers/gpu/drm/i915/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/i915_gem_context.c
@@ -569,8 +569,20 @@ static inline bool should_skip_switch(struct 
intel_engine_cs *ring,
  struct intel_context *from,
  struct intel_context *to)
 {
-   if (from == to && !to->remap_slice)
-   return true;
+   struct drm_i915_private *dev_priv = ring->dev->dev_private;
+
+   if (to->remap_slice)
+   return false;
+
+   if (to->ppgtt) {
+   if (from == to && !test_bit(ring->id,
+   &to->ppgtt->pd_dirty_rings))
+   return true;
+   } else if (dev_priv->mm.aliasing_ppgtt) {
+   if (from == to && !test_bit(ring->id,
+   &dev_priv->mm.aliasing_ppgtt->pd_dirty_rings))
+   return true;
+   }
 
return false;
 }
@@ -587,9 +599,8 @@ needs_pd_load_pre(struct intel_engine_cs *ring, struct 
intel_context *to)
 static bool
 needs_pd_load_post(struct intel_engine_cs *ring, struct intel_context *to)
 {
-   return (!to->legacy_hw_ctx.initialized ||
-   i915_gem_context_is_default(to)) &&
-   to->ppgtt && IS_GEN8(ring->dev);
+   return IS_GEN8(ring->dev) &&
+   (to->ppgtt || &to->ppgtt->pd_dirty_rings);
 }
 
 static int do_switch(struct intel_engine_cs *ring,
@@ -634,6 +645,12 @@ static int do_switch(struct intel_engine_cs *ring,
ret = to->ppgtt->switch_mm(to->ppgtt, ring);
if (ret)
goto unpin_out;
+
+   /* Doing a PD load always reloads the page dirs */
+   if (to->ppgtt)
+   clear_bit(ring->id, &to->ppgtt->pd_dirty_rings);
+   else
+   clear_bit(ring->id, 
&dev_priv->mm.aliasing_ppgtt->pd_dirty_rings);
}
 
if (ring != &dev_priv->ring[RCS]) {
@@ -672,6 +689,8 @@ static int do_switch(struct intel_engine_cs *ring,
 */
if (!to->legacy_hw_ctx.initialized || i915_gem_context_is_default(to))
hw_flags |= MI_RESTORE_INHIBIT;
+   else if (to->ppgtt && test_and_clear_bit(ring->id, 
&to->ppgtt->pd_dirty_rings))
+   hw_flags |= MI_FORCE_RESTORE;
 
ret = mi_set_context(ring, to, hw_flags);
if (ret)
diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c 
b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
index 82636aa..24757ee 100644
--- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c
+++ b/drivers/gpu/dr

[Intel-gfx] [PATCH v6 05/32] drm/i915: Track GEN6 page table usage

2015-02-24 Thread Michel Thierry
From: 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.

One important change introduced here is that DMA mappings are
created/destroyed at the same page directories/tables are
allocated/deallocated.

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

v2: s/pdp.page_directory/pdp.page_directorys
Make a scratch page allocation helper

v3: Rebase and expand commit message.

v4: Allocate required pagetables only when it is needed, _bind_to_vm
instead of bind_vma (Daniel).

v5: Rebased to remove the unnecessary noise in the diff, also:
 - PDE mask is GEN agnostic, renamed GEN6_PDE_MASK to I915_PDE_MASK.
 - Removed unnecessary checks in gen6_alloc_va_range.
 - Changed map/unmap_px_single macros to use dma functions directly and
   be part of a static inline function instead.
 - Moved drm_device plumbing through page tables operation to its own
   patch.
 - Moved allocate/teardown_va_range calls until they are fully
   implemented (in subsequent patch).
 - Merged pt and scratch_pt unmap_and_free path.
 - Moved scratch page allocator helper to the patch that will use it.

v6: Reduce complexity by not tearing down pagetables dynamically, the
same can be achieved while freeing empty vms. (Daniel)

v7: s/i915_dma_map_px_single/i915_dma_map_single
s/gen6_write_pdes/gen6_write_pde
Prevent a NULL case when only GGTT is available. (Mika)

v8: Rebased after s/page_tables/page_table/.

Cc: Daniel Vetter 
Cc: Mika Kuoppala 
Signed-off-by: Ben Widawsky 
Signed-off-by: Michel Thierry  (v3+)
---
 drivers/gpu/drm/i915/i915_gem_gtt.c | 198 +---
 drivers/gpu/drm/i915/i915_gem_gtt.h |  75 ++
 2 files changed, 211 insertions(+), 62 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/i915_gem_gtt.c
index e05488e..f9354c7 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -278,29 +278,88 @@ static gen6_gtt_pte_t iris_pte_encode(dma_addr_t addr,
return pte;
 }
 
-static void unmap_and_free_pt(struct i915_page_table_entry *pt, struct 
drm_device *dev)
+#define i915_dma_unmap_single(px, dev) \
+   __i915_dma_unmap_single((px)->daddr, dev)
+
+static inline void __i915_dma_unmap_single(dma_addr_t daddr,
+   struct drm_device *dev)
+{
+   struct device *device = &dev->pdev->dev;
+
+   dma_unmap_page(device, daddr, 4096, PCI_DMA_BIDIRECTIONAL);
+}
+
+/**
+ * i915_dma_map_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. If we keep the structs
+ * symmetric here, the simple macro covers us for every page table type.
+ *
+ * Return: 0 if success.
+ */
+#define i915_dma_map_single(px, dev) \
+   i915_dma_map_page_single((px)->page, (dev), &(px)->daddr)
+
+static inline int i915_dma_map_page_single(struct page *page,
+  struct drm_device *dev,
+  dma_addr_t *daddr)
+{
+   struct device *device = &dev->pdev->dev;
+
+   *daddr = dma_map_page(device, page, 0, 4096, PCI_DMA_BIDIRECTIONAL);
+   return dma_mapping_error(device, *daddr);
+}
+
+static void unmap_and_free_pt(struct i915_page_table_entry *pt,
+  struct drm_device *dev)
 {
if (WARN_ON(!pt->page))
return;
+
+   i915_dma_unmap_single(pt, dev);
__free_page(pt->page);
+   kfree(pt->used_ptes);
kfree(pt);
 }
 
 static struct i915_page_table_entry *alloc_pt_single(struct drm_device *dev)
 {
struct i915_page_table_entry *pt;
+   const size_t count = INTEL_INFO(dev)->gen >= 8 ?
+   GEN8_PTES_PER_PAGE : I915_PPGTT_PT_ENTRIES;
+   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);
-  

[Intel-gfx] [PATCH v6 08/32] drm/i915: Initialize all contexts

2015-02-24 Thread Michel Thierry
From: Ben Widawsky 

The problem is we're going to switch to a new context, which could be
the default context. The plan was to use restore inhibit, which would be
fine, except if we are using dynamic page tables (which we will). If we
use dynamic page tables and we don't load new page tables, the previous
page tables might go away, and future operations will fault.

CTXA runs.
switch to default, restore inhibit
CTXA dies and has its address space taken away.
Run CTXB, tries to save using the context A's address space - this
fails.

The general solution is to make sure every context has it's own state,
and its own address space. For cases when we must restore inhibit, first
thing we do is load a valid address space. I thought this would be
enough, but apparently there are references within the context itself
which will refer to the old address space - therefore, we also must
reinitialize.

It was tricky to track this down as we don't have much insight into what
happens in a context save.

This is required for the next patch which enables dynamic page tables.

v2: to->ppgtt is only valid in full ppgtt.

Signed-off-by: Ben Widawsky 
Signed-off-by: Michel Thierry  (v2)
---
 drivers/gpu/drm/i915/i915_gem_context.c | 25 +++--
 1 file changed, 11 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_context.c 
b/drivers/gpu/drm/i915/i915_gem_context.c
index 437cdcc..6a583c3 100644
--- a/drivers/gpu/drm/i915/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/i915_gem_context.c
@@ -596,13 +596,6 @@ needs_pd_load_pre(struct intel_engine_cs *ring, struct 
intel_context *to)
(ring != &dev_priv->ring[RCS])) && to->ppgtt;
 }
 
-static bool
-needs_pd_load_post(struct intel_engine_cs *ring, struct intel_context *to)
-{
-   return IS_GEN8(ring->dev) &&
-   (to->ppgtt || &to->ppgtt->pd_dirty_rings);
-}
-
 static int do_switch(struct intel_engine_cs *ring,
 struct intel_context *to)
 {
@@ -683,20 +676,24 @@ static int do_switch(struct intel_engine_cs *ring,
 
/* GEN8 does *not* require an explicit reload if the PDPs have been
 * setup, and we do not wish to move them.
-*
-* XXX: If we implemented page directory eviction code, this
-* optimization needs to be removed.
 */
-   if (!to->legacy_hw_ctx.initialized || i915_gem_context_is_default(to))
+   if (!to->legacy_hw_ctx.initialized) {
hw_flags |= MI_RESTORE_INHIBIT;
-   else if (to->ppgtt && test_and_clear_bit(ring->id, 
&to->ppgtt->pd_dirty_rings))
+   /* NB: If we inhibit the restore, the context is not allowed to
+* die because future work may end up depending on valid address
+* space. This means we must enforce that a page table load
+* occur when this occurs. */
+   } else if (to->ppgtt && test_and_clear_bit(ring->id, 
&to->ppgtt->pd_dirty_rings))
hw_flags |= MI_FORCE_RESTORE;
 
ret = mi_set_context(ring, to, hw_flags);
if (ret)
goto unpin_out;
 
-   if (needs_pd_load_post(ring, to)) {
+   if (IS_GEN8(ring->dev) && to->ppgtt && (hw_flags & MI_RESTORE_INHIBIT)) 
{
+   /* We have a valid page directory (scratch) to switch to. This
+* allows the old VM to be freed. Note that if anything occurs
+* between the set context, and here, we are f*cked */
ret = to->ppgtt->switch_mm(to->ppgtt, ring);
/* The hardware context switch is emitted, but we haven't
 * actually changed the state - so it's probably safe to bail
@@ -746,7 +743,7 @@ static int do_switch(struct intel_engine_cs *ring,
i915_gem_context_unreference(from);
}
 
-   uninitialized = !to->legacy_hw_ctx.initialized && from == NULL;
+   uninitialized = !to->legacy_hw_ctx.initialized;
to->legacy_hw_ctx.initialized = true;
 
 done:
-- 
2.1.1

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


[Intel-gfx] [PATCH v6 24/32] drm/i915/bdw: Add ppgtt info for dynamic pages

2015-02-24 Thread Michel Thierry
From: Ben Widawsky 

Note that there is no gen8 ppgtt debug_dump function yet.

Signed-off-by: Ben Widawsky 
Signed-off-by: Michel Thierry 
---
 drivers/gpu/drm/i915/i915_debugfs.c | 19 ++-
 drivers/gpu/drm/i915/i915_gem_gtt.c | 32 
 drivers/gpu/drm/i915/i915_gem_gtt.h |  9 +
 3 files changed, 51 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c 
b/drivers/gpu/drm/i915/i915_debugfs.c
index e85da9d..c877957 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -2165,7 +2165,6 @@ static void gen6_ppgtt_info(struct seq_file *m, struct 
drm_device *dev)
 {
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_engine_cs *ring;
-   struct drm_file *file;
int i;
 
if (INTEL_INFO(dev)->gen == 6)
@@ -2189,14 +2188,6 @@ static void gen6_ppgtt_info(struct seq_file *m, struct 
drm_device *dev)
 
ppgtt->debug_dump(ppgtt, m);
}
-
-   list_for_each_entry_reverse(file, &dev->filelist, lhead) {
-   struct drm_i915_file_private *file_priv = file->driver_priv;
-
-   seq_printf(m, "proc: %s\n",
-  get_pid_task(file->pid, PIDTYPE_PID)->comm);
-   idr_for_each(&file_priv->context_idr, per_file_ctx, m);
-   }
 }
 
 static int i915_ppgtt_info(struct seq_file *m, void *data)
@@ -2204,6 +2195,7 @@ static int i915_ppgtt_info(struct seq_file *m, void *data)
struct drm_info_node *node = m->private;
struct drm_device *dev = node->minor->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
+   struct drm_file *file;
 
int ret = mutex_lock_interruptible(&dev->struct_mutex);
if (ret)
@@ -2215,6 +2207,15 @@ static int i915_ppgtt_info(struct seq_file *m, void 
*data)
else if (INTEL_INFO(dev)->gen >= 6)
gen6_ppgtt_info(m, dev);
 
+   list_for_each_entry_reverse(file, &dev->filelist, lhead) {
+   struct drm_i915_file_private *file_priv = file->driver_priv;
+
+   seq_printf(m, "\nproc: %s\n",
+  get_pid_task(file->pid, PIDTYPE_PID)->comm);
+   idr_for_each(&file_priv->context_idr, per_file_ctx,
+(void *)(unsigned long)m);
+   }
+
intel_runtime_pm_put(dev_priv);
mutex_unlock(&dev->struct_mutex);
 
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/i915_gem_gtt.c
index f613377..9f16db7 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -2128,6 +2128,38 @@ static void gen8_ggtt_clear_range(struct 
i915_address_space *vm,
readl(gtt_base);
 }
 
+void gen8_for_every_pdpe_pde(struct i915_hw_ppgtt *ppgtt,
+void (*callback)(struct 
i915_page_directory_pointer_entry *pdp,
+ struct i915_page_directory_entry 
*pd,
+ struct i915_page_table_entry *pt,
+ unsigned pdpe,
+ unsigned pde,
+ void *data),
+void *data)
+{
+   uint64_t start = ppgtt->base.start;
+   uint64_t length = ppgtt->base.total;
+   uint64_t pdpe, pde, temp;
+
+   struct i915_page_directory_entry *pd;
+   struct i915_page_table_entry *pt;
+
+   gen8_for_each_pdpe(pd, &ppgtt->pdp, start, length, temp, pdpe) {
+   uint64_t pd_start = start, pd_length = length;
+   int i;
+
+   if (pd == NULL) {
+   for (i = 0; i < GEN8_PDES_PER_PAGE; i++)
+   callback(&ppgtt->pdp, NULL, NULL, pdpe, i, 
data);
+   continue;
+   }
+
+   gen8_for_each_pde(pt, pd, pd_start, pd_length, temp, pde) {
+   callback(&ppgtt->pdp, pd, pt, pdpe, pde, data);
+   }
+   }
+}
+
 static void gen6_ggtt_clear_range(struct i915_address_space *vm,
  uint64_t start,
  uint64_t length,
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h 
b/drivers/gpu/drm/i915/i915_gem_gtt.h
index 1004e0f..f74afa6 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.h
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.h
@@ -483,6 +483,15 @@ static inline size_t gen8_pde_count(uint64_t addr, 
uint64_t length)
return i915_pde_index(end, GEN8_PDE_SHIFT) - i915_pde_index(addr, 
GEN8_PDE_SHIFT);
 }
 
+void gen8_for_every_pdpe_pde(struct i915_hw_ppgtt *ppgtt,
+void (*callback)(struct 
i915_page_directory_pointer_entry *pdp,
+ struct i915_page_directory_entry 
*pd,
+ struct i915_page_table_entry *pt,
+ 

[Intel-gfx] [PATCH v6 06/32] drm/i915: Extract context switch skip and pd load logic

2015-02-24 Thread Michel Thierry
From: Ben Widawsky 

We have some fanciness coming up. This patch just breaks out the logic
of context switch skip, pd load pre, and pd load post.

v2: Use new functions to replace the logic right away (Daniel)

Cc: Daniel Vetter 
Signed-off-by: Ben Widawsky 
Signed-off-by: Michel Thierry  (v2)
---
 drivers/gpu/drm/i915/i915_gem_context.c | 40 +
 1 file changed, 31 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_context.c 
b/drivers/gpu/drm/i915/i915_gem_context.c
index 755b415..6206d27 100644
--- a/drivers/gpu/drm/i915/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/i915_gem_context.c
@@ -565,6 +565,33 @@ mi_set_context(struct intel_engine_cs *ring,
return ret;
 }
 
+static inline bool should_skip_switch(struct intel_engine_cs *ring,
+ struct intel_context *from,
+ struct intel_context *to)
+{
+   if (from == to && !to->remap_slice)
+   return true;
+
+   return false;
+}
+
+static bool
+needs_pd_load_pre(struct intel_engine_cs *ring, struct intel_context *to)
+{
+   struct drm_i915_private *dev_priv = ring->dev->dev_private;
+
+   return ((INTEL_INFO(ring->dev)->gen < 8) ||
+   (ring != &dev_priv->ring[RCS])) && to->ppgtt;
+}
+
+static bool
+needs_pd_load_post(struct intel_engine_cs *ring, struct intel_context *to)
+{
+   return (!to->legacy_hw_ctx.initialized ||
+   i915_gem_context_is_default(to)) &&
+   to->ppgtt && IS_GEN8(ring->dev);
+}
+
 static int do_switch(struct intel_engine_cs *ring,
 struct intel_context *to)
 {
@@ -573,9 +600,6 @@ static int do_switch(struct intel_engine_cs *ring,
u32 hw_flags = 0;
bool uninitialized = false;
struct i915_vma *vma;
-   bool needs_pd_load_pre = ((INTEL_INFO(ring->dev)->gen < 8) ||
-   (ring != &dev_priv->ring[RCS])) && to->ppgtt;
-   bool needs_pd_load_post = false;
int ret, i;
 
if (from != NULL && ring == &dev_priv->ring[RCS]) {
@@ -583,7 +607,7 @@ static int do_switch(struct intel_engine_cs *ring,
BUG_ON(!i915_gem_obj_is_pinned(from->legacy_hw_ctx.rcs_state));
}
 
-   if (from == to && !to->remap_slice)
+   if (should_skip_switch(ring, from, to))
return 0;
 
/* Trying to pin first makes error handling easier. */
@@ -601,7 +625,7 @@ static int do_switch(struct intel_engine_cs *ring,
 */
from = ring->last_context;
 
-   if (needs_pd_load_pre) {
+   if (needs_pd_load_pre(ring, to)) {
/* Older GENs and non render rings still want the load first,
 * "PP_DCLV followed by PP_DIR_BASE register through Load
 * Register Immediate commands in Ring Buffer before submitting
@@ -646,16 +670,14 @@ static int do_switch(struct intel_engine_cs *ring,
 * XXX: If we implemented page directory eviction code, this
 * optimization needs to be removed.
 */
-   if (!to->legacy_hw_ctx.initialized || i915_gem_context_is_default(to)) {
+   if (!to->legacy_hw_ctx.initialized || i915_gem_context_is_default(to))
hw_flags |= MI_RESTORE_INHIBIT;
-   needs_pd_load_post = to->ppgtt && IS_GEN8(ring->dev);
-   }
 
ret = mi_set_context(ring, to, hw_flags);
if (ret)
goto unpin_out;
 
-   if (needs_pd_load_post) {
+   if (needs_pd_load_post(ring, to)) {
ret = to->ppgtt->switch_mm(to->ppgtt, ring);
/* The hardware context switch is emitted, but we haven't
 * actually changed the state - so it's probably safe to bail
-- 
2.1.1

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


[Intel-gfx] [PATCH v6 22/32] drm/i915/bdw: Abstract PDP usage

2015-02-24 Thread Michel Thierry
From: Ben Widawsky 

Up until now, ppgtt->pdp has always been the root of our page tables.
Legacy 32b addresses acted like it had 1 PDP with 4 PDPEs.

In preparation for 4 level page tables, we need to stop use ppgtt->pdp
directly unless we know it's what we want. The future structure will use
ppgtt->pml4 for the top level, and the pdp is just one of the entries
being pointed to by a pml4e.

This patch addresses some carelessness done throughout development wrt
assumptions made of the root page tables.

v2: Updated after dynamic page allocation changes.
v3: Rebase after s/page_tables/page_table/.

Signed-off-by: Ben Widawsky 
Signed-off-by: Michel Thierry  (v2+)
---
 drivers/gpu/drm/i915/i915_gem_gtt.c | 123 
 1 file changed, 70 insertions(+), 53 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 2a453fd..50583a4 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -560,6 +560,7 @@ static void gen8_ppgtt_clear_range(struct 
i915_address_space *vm,
 {
struct i915_hw_ppgtt *ppgtt =
container_of(vm, struct i915_hw_ppgtt, base);
+   struct i915_page_directory_pointer_entry *pdp = &ppgtt->pdp; /* FIXME: 
48b */
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;
@@ -575,10 +576,10 @@ static void gen8_ppgtt_clear_range(struct 
i915_address_space *vm,
struct i915_page_table_entry *pt;
struct page *page_table;
 
-   if (WARN_ON(!ppgtt->pdp.page_directory[pdpe]))
+   if (WARN_ON(!pdp->page_directory[pdpe]))
continue;
 
-   pd = ppgtt->pdp.page_directory[pdpe];
+   pd = pdp->page_directory[pdpe];
 
if (WARN_ON(!pd->page_table[pde]))
continue;
@@ -620,6 +621,7 @@ static void gen8_ppgtt_insert_entries(struct 
i915_address_space *vm,
 {
struct i915_hw_ppgtt *ppgtt =
container_of(vm, struct i915_hw_ppgtt, base);
+   struct i915_page_directory_pointer_entry *pdp = &ppgtt->pdp; /* FIXME: 
48b */
gen8_gtt_pte_t *pt_vaddr;
unsigned pdpe = start >> GEN8_PDPE_SHIFT & GEN8_PDPE_MASK;
unsigned pde = start >> GEN8_PDE_SHIFT & GEN8_PDE_MASK;
@@ -630,7 +632,7 @@ static void gen8_ppgtt_insert_entries(struct 
i915_address_space *vm,
 
for_each_sg_page(pages->sgl, &sg_iter, pages->nents, 0) {
if (pt_vaddr == NULL) {
-   struct i915_page_directory_entry *pd = 
ppgtt->pdp.page_directory[pdpe];
+   struct i915_page_directory_entry *pd = 
pdp->page_directory[pdpe];
struct i915_page_table_entry *pt = pd->page_table[pde];
struct page *page_table = pt->page;
 
@@ -708,16 +710,17 @@ static void gen8_free_page_tables(struct 
i915_page_directory_entry *pd, struct d
 static void gen8_ppgtt_unmap_pages(struct i915_hw_ppgtt *ppgtt)
 {
struct pci_dev *hwdev = ppgtt->base.dev->pdev;
+   struct i915_page_directory_pointer_entry *pdp = &ppgtt->pdp; /* FIXME: 
48b */
int i, j;
 
-   for_each_set_bit(i, ppgtt->pdp.used_pdpes,
+   for_each_set_bit(i, pdp->used_pdpes,
I915_PDPES_PER_PDP(ppgtt->base.dev)) {
struct i915_page_directory_entry *pd;
 
-   if (WARN_ON(!ppgtt->pdp.page_directory[i]))
+   if (WARN_ON(!pdp->page_directory[i]))
continue;
 
-   pd = ppgtt->pdp.page_directory[i];
+   pd = pdp->page_directory[i];
if (!pd->daddr)
pci_unmap_page(hwdev, pd->daddr, PAGE_SIZE,
PCI_DMA_BIDIRECTIONAL);
@@ -743,15 +746,21 @@ static void gen8_ppgtt_free(struct i915_hw_ppgtt *ppgtt)
 {
int i;
 
-   for_each_set_bit(i, ppgtt->pdp.used_pdpes,
-   I915_PDPES_PER_PDP(ppgtt->base.dev)) {
-   if (WARN_ON(!ppgtt->pdp.page_directory[i]))
-   continue;
+   if (!USES_FULL_48BIT_PPGTT(ppgtt->base.dev)) {
+   for_each_set_bit(i, ppgtt->pdp.used_pdpes,
+I915_PDPES_PER_PDP(ppgtt->base.dev)) {
+   if (WARN_ON(!ppgtt->pdp.page_directory[i]))
+   continue;
 
-   gen8_free_page_tables(ppgtt->pdp.page_directory[i], 
ppgtt->base.dev);
-   unmap_and_free_pd(ppgtt->pdp.page_directory[i], 
ppgtt->base.dev);
+   gen8_free_page_tables(ppgtt->pdp.page_directory[i],
+ ppgtt->base.dev);
+   unmap_and_free_pd(ppgtt->pdp.page_directory[i],
+ ppgtt->base.dev);
+   }
+  

[Intel-gfx] [PATCH v6 11/32] drm/i915/bdw: Use dynamic allocation idioms on free

2015-02-24 Thread Michel Thierry
From: Ben Widawsky 

The page directory freer is left here for now as it's still useful given
that GEN8 still preallocates. Once the allocation functions are broken
up into more discrete chunks, we'll follow suit and destroy this
leftover piece.

v2: Match trace_i915_va_teardown params
v3: Multiple rebases.
v4: Updated to use unmap_and_free_pt.
v5: teardown_va_range logic no longer needed.
v6: Rebase after s/page_tables/page_table/.

Signed-off-by: Ben Widawsky 
Signed-off-by: Michel Thierry  (v2+)
---
 drivers/gpu/drm/i915/i915_gem_gtt.c | 26 ++--
 drivers/gpu/drm/i915/i915_gem_gtt.h | 47 +
 2 files changed, 60 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 94cdd99..e03b2c8 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -607,19 +607,6 @@ static void gen8_free_page_tables(struct 
i915_page_directory_entry *pd, struct d
}
 }
 
-static void gen8_ppgtt_free(struct i915_hw_ppgtt *ppgtt)
-{
-   int i;
-
-   for (i = 0; i < ppgtt->num_pd_pages; i++) {
-   if (WARN_ON(!ppgtt->pdp.page_directory[i]))
-   continue;
-
-   gen8_free_page_tables(ppgtt->pdp.page_directory[i], 
ppgtt->base.dev);
-   unmap_and_free_pd(ppgtt->pdp.page_directory[i]);
-   }
-}
-
 static void gen8_ppgtt_unmap_pages(struct i915_hw_ppgtt *ppgtt)
 {
struct pci_dev *hwdev = ppgtt->base.dev->pdev;
@@ -652,6 +639,19 @@ static void gen8_ppgtt_unmap_pages(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++) {
+   if (WARN_ON(!ppgtt->pdp.page_directory[i]))
+   continue;
+
+   gen8_free_page_tables(ppgtt->pdp.page_directory[i], 
ppgtt->base.dev);
+   unmap_and_free_pd(ppgtt->pdp.page_directory[i]);
+   }
+}
+
 static void gen8_ppgtt_cleanup(struct i915_address_space *vm)
 {
struct i915_hw_ppgtt *ppgtt =
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h 
b/drivers/gpu/drm/i915/i915_gem_gtt.h
index 5918131..1f5c136 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.h
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.h
@@ -383,6 +383,53 @@ static inline uint32_t gen6_pde_index(uint32_t addr)
return i915_pde_index(addr, GEN6_PDE_SHIFT);
 }
 
+#define gen8_for_each_pde(pt, pd, start, length, temp, iter)   \
+   for (iter = gen8_pde_index(start), pt = (pd)->page_table[iter]; \
+length > 0 && iter < GEN8_PDES_PER_PAGE;   \
+pt = (pd)->page_table[++iter], \
+temp = ALIGN(start+1, 1 << GEN8_PDE_SHIFT) - start,\
+temp = min(temp, length),  \
+start += temp, length -= temp)
+
+#define gen8_for_each_pdpe(pd, pdp, start, length, temp, iter) \
+   for (iter = gen8_pdpe_index(start), pd = (pdp)->page_directory[iter];   
\
+length > 0 && iter < GEN8_LEGACY_PDPES;\
+pd = (pdp)->page_directory[++iter],
\
+temp = ALIGN(start+1, 1 << GEN8_PDPE_SHIFT) - start,   \
+temp = min(temp, length),  \
+start += temp, length -= temp)
+
+/* Clamp length to the next page_directory boundary */
+static inline uint64_t gen8_clamp_pd(uint64_t start, uint64_t length)
+{
+   uint64_t next_pd = ALIGN(start + 1, 1 << GEN8_PDPE_SHIFT);
+
+   if (next_pd > (start + length))
+   return length;
+
+   return next_pd - start;
+}
+
+static inline uint32_t gen8_pte_index(uint64_t address)
+{
+   return i915_pte_index(address, GEN8_PDE_SHIFT);
+}
+
+static inline uint32_t gen8_pde_index(uint64_t address)
+{
+   return i915_pde_index(address, GEN8_PDE_SHIFT);
+}
+
+static inline uint32_t gen8_pdpe_index(uint64_t address)
+{
+   return (address >> GEN8_PDPE_SHIFT) & GEN8_PDPE_MASK;
+}
+
+static inline uint32_t gen8_pml4e_index(uint64_t address)
+{
+   BUG(); /* For 64B */
+}
+
 int i915_gem_gtt_init(struct drm_device *dev);
 void i915_gem_init_global_gtt(struct drm_device *dev);
 void i915_global_gtt_cleanup(struct drm_device *dev);
-- 
2.1.1

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


[Intel-gfx] [PATCH v6 15/32] drm/i915: num_pd_pages/num_pd_entries isn't useful

2015-02-24 Thread Michel Thierry
From: Ben Widawsky 

These values are never quite useful for dynamic allocations of the page
tables. Getting rid of them will help prevent later confusion.

v2: Updated to use unmap_and_free_pd functions.
v3: Updated gen8_ppgtt_free after teardown logic was removed.
v4: Rebase after s/page_tables/page_table/.

Signed-off-by: Ben Widawsky 
Signed-off-by: Michel Thierry  (v2+)
---
 drivers/gpu/drm/i915/i915_debugfs.c |  2 --
 drivers/gpu/drm/i915/i915_gem_gtt.c | 72 -
 drivers/gpu/drm/i915/i915_gem_gtt.h |  7 ++--
 3 files changed, 28 insertions(+), 53 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c 
b/drivers/gpu/drm/i915/i915_debugfs.c
index e8ad450..e85da9d 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -2149,8 +2149,6 @@ static void gen8_ppgtt_info(struct seq_file *m, struct 
drm_device *dev)
if (!ppgtt)
return;
 
-   seq_printf(m, "Page directories: %d\n", ppgtt->num_pd_pages);
-   seq_printf(m, "Page tables: %d\n", ppgtt->num_pd_entries);
for_each_ring(ring, dev_priv, unused) {
seq_printf(m, "%s\n", ring->name);
for (i = 0; i < 4; i++) {
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 2e4db77..bddfcc2 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -613,9 +613,7 @@ static void gen8_ppgtt_unmap_pages(struct i915_hw_ppgtt 
*ppgtt)
struct pci_dev *hwdev = ppgtt->base.dev->pdev;
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. */
+   for (i = 0; i < GEN8_LEGACY_PDPES; i++) {
if (!ppgtt->pdp.page_directory[i]->daddr)
continue;
 
@@ -644,7 +642,7 @@ static void gen8_ppgtt_free(struct i915_hw_ppgtt *ppgtt)
 {
int i;
 
-   for (i = 0; i < ppgtt->num_pd_pages; i++) {
+   for (i = 0; i < GEN8_LEGACY_PDPES; i++) {
if (WARN_ON(!ppgtt->pdp.page_directory[i]))
continue;
 
@@ -705,21 +703,13 @@ static int gen8_ppgtt_alloc_page_directories(struct 
i915_page_directory_pointer_
pdp->page_directory[pdpe] = alloc_pd_single();
if (IS_ERR(ppgtt->pdp.page_directory[pdpe]))
goto unwind_out;
-
-   ppgtt->num_pd_pages++;
}
 
-   BUG_ON(ppgtt->num_pd_pages > GEN8_LEGACY_PDPES);
-
return 0;
 
 unwind_out:
-   while (pdpe--) {
+   while (pdpe--)
unmap_and_free_pd(ppgtt->pdp.page_directory[pdpe]);
-   ppgtt->num_pd_pages--;
-   }
-
-   WARN_ON(ppgtt->num_pd_pages);
 
return -ENOMEM;
 }
@@ -742,12 +732,8 @@ static int gen8_ppgtt_alloc(struct i915_hw_ppgtt *ppgtt,
ppgtt->base.dev);
if (ret)
goto err_out;
-
-   ppgtt->num_pd_entries += GEN8_PDES_PER_PAGE;
}
 
-   BUG_ON(pdpe > ppgtt->num_pd_pages);
-
return 0;
 
 err_out:
@@ -808,7 +794,6 @@ static int gen8_ppgtt_setup_page_tables(struct 
i915_hw_ppgtt *ppgtt,
 static int gen8_ppgtt_init(struct i915_hw_ppgtt *ppgtt, uint64_t size)
 {
const int max_pdp = DIV_ROUND_UP(size, 1 << 30);
-   const int min_pt_pages = GEN8_PDES_PER_PAGE * max_pdp;
int i, j, ret;
 
if (size % (1<<30))
@@ -872,12 +857,6 @@ static int gen8_ppgtt_init(struct i915_hw_ppgtt *ppgtt, 
uint64_t size)
ppgtt->base.cleanup = gen8_ppgtt_cleanup;
 
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",
-ppgtt->num_pd_entries,
-(ppgtt->num_pd_entries - min_pt_pages) + size % 
(1<<30));
return 0;
 
 bail:
@@ -888,26 +867,20 @@ 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;
+   struct i915_page_table_entry *unused;
gen6_gtt_pte_t scratch_pte;
uint32_t pd_entry;
-   int pte, pde;
+   uint32_t  pte, pde, temp;
+   uint32_t start = ppgtt->base.start, length = ppgtt->base.total;
 
scratch_pte = vm->pte_encode(vm->scratch.addr, I915_CACHE_LLC, true, 0);
 
-   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,
-   

[Intel-gfx] [PATCH v6 30/32] drm/i915/bdw: Add 4 level support in insert_entries and clear_range

2015-02-24 Thread Michel Thierry
When 48b is enabled, gen8_ppgtt_insert_entries needs to read the Page Map
Level 4 (PML4), before it selects which Page Directory Pointer (PDP)
it will write to.

Similarly, gen8_ppgtt_clear_range needs to get the correct PDP/PD range.

Also add a scratch page for PML4.

This patch was inspired by Ben's "Depend exclusively on map and
unmap_vma".

v2: Rebase after s/page_tables/page_table/.

Signed-off-by: Michel Thierry 
---
 drivers/gpu/drm/i915/i915_gem_gtt.c | 66 ++---
 drivers/gpu/drm/i915/i915_gem_gtt.h | 12 +++
 2 files changed, 67 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 166daf4..842ce93 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -676,24 +676,52 @@ static void gen8_ppgtt_clear_pte_range(struct 
i915_page_directory_pointer_entry
}
 }
 
+static void gen8_ppgtt_clear_range_4lvl(struct i915_hw_ppgtt *ppgtt,
+   gen8_gtt_pte_t scratch_pte,
+   uint64_t start,
+   uint64_t length)
+{
+   struct i915_page_directory_pointer_entry *pdp;
+   uint64_t templ4, templ3, pml4e, pdpe;
+
+   gen8_for_each_pml4e(pdp, &ppgtt->pml4, start, length, templ4, pml4e) {
+   struct i915_page_directory_entry *pd;
+   uint64_t pdp_len = gen8_clamp_pdp(start, length);
+   uint64_t pdp_start = start;
+
+   gen8_for_each_pdpe(pd, pdp, pdp_start, pdp_len, templ3, pdpe) {
+   uint64_t pd_len = gen8_clamp_pd(pdp_start, pdp_len);
+   uint64_t pd_start = pdp_start;
+
+   gen8_ppgtt_clear_pte_range(pdp, pd_start, pd_len,
+  scratch_pte, 
!HAS_LLC(ppgtt->base.dev));
+   }
+   }
+}
+
 static void gen8_ppgtt_clear_range(struct i915_address_space *vm,
-  uint64_t start,
-  uint64_t length,
+  uint64_t start, uint64_t length,
   bool use_scratch)
 {
struct i915_hw_ppgtt *ppgtt =
-   container_of(vm, struct i915_hw_ppgtt, base);
-   struct i915_page_directory_pointer_entry *pdp = &ppgtt->pdp; /* FIXME: 
48b */
-
+   container_of(vm, struct i915_hw_ppgtt, base);
gen8_gtt_pte_t scratch_pte = gen8_pte_encode(ppgtt->base.scratch.addr,
 I915_CACHE_LLC, 
use_scratch);
 
-   gen8_ppgtt_clear_pte_range(pdp, start, length, scratch_pte, 
!HAS_LLC(vm->dev));
+   if (!USES_FULL_48BIT_PPGTT(vm->dev)) {
+   struct i915_page_directory_pointer_entry *pdp = &ppgtt->pdp;
+
+   gen8_ppgtt_clear_pte_range(pdp, start, length, scratch_pte,
+  !HAS_LLC(ppgtt->base.dev));
+   } else {
+   gen8_ppgtt_clear_range_4lvl(ppgtt, scratch_pte, start, length);
+   }
 }
 
 static void gen8_ppgtt_insert_pte_entries(struct 
i915_page_directory_pointer_entry *pdp,
  struct sg_page_iter *sg_iter,
  uint64_t start,
+ size_t pages,
  enum i915_cache_level cache_level,
  const bool flush)
 {
@@ -704,7 +732,7 @@ static void gen8_ppgtt_insert_pte_entries(struct 
i915_page_directory_pointer_ent
 
pt_vaddr = NULL;
 
-   while (__sg_page_iter_next(sg_iter)) {
+   while (pages-- && __sg_page_iter_next(sg_iter)) {
if (pt_vaddr == NULL) {
struct i915_page_directory_entry *pd = 
pdp->page_directory[pdpe];
struct i915_page_table_entry *pt = pd->page_table[pde];
@@ -742,11 +770,26 @@ static void gen8_ppgtt_insert_entries(struct 
i915_address_space *vm,
  u32 unused)
 {
struct i915_hw_ppgtt *ppgtt = container_of(vm, struct i915_hw_ppgtt, 
base);
-   struct i915_page_directory_pointer_entry *pdp = &ppgtt->pdp; /* FIXME: 
48b */
+   struct i915_page_directory_pointer_entry *pdp;
struct sg_page_iter sg_iter;
 
__sg_page_iter_start(&sg_iter, pages->sgl, sg_nents(pages->sgl), 0);
-   gen8_ppgtt_insert_pte_entries(pdp, &sg_iter, start, cache_level, 
!HAS_LLC(vm->dev));
+
+   if (!USES_FULL_48BIT_PPGTT(vm->dev)) {
+   pdp = &ppgtt->pdp;
+   gen8_ppgtt_insert_pte_entries(pdp, &sg_iter, start,
+   sg_nents(pages->sgl),
+   cache_level, !HAS_LLC(vm->dev));
+   } else {
+   struct i915_pml4 *pml4;
+   unsigned pml4e = gen8_pml4e_index(start);
+
+   pml4 = &pp

[Intel-gfx] [PATCH v6 10/32] drm/i915: Add dynamic page trace events

2015-02-24 Thread Michel Thierry
Traces for page directories and tables allocation and map.

v2: Removed references to teardown.
v3: bitmap_scnprintf has been deprecated.

Signed-off-by: Michel Thierry 
---
 drivers/gpu/drm/i915/i915_gem.c |  2 +
 drivers/gpu/drm/i915/i915_gem_gtt.c |  5 ++
 drivers/gpu/drm/i915/i915_trace.h   | 95 +
 3 files changed, 102 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 312b7d2..4e51275 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -3601,6 +3601,8 @@ search_free:
 
/*  allocate before insert / bind */
if (vma->vm->allocate_va_range) {
+   trace_i915_va_alloc(vma->vm, vma->node.start, vma->node.size,
+   VM_TO_TRACE_NAME(vma->vm));
ret = vma->vm->allocate_va_range(vma->vm,
vma->node.start,
vma->node.size);
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 29cda58..94cdd99 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -1210,6 +1210,7 @@ static int gen6_alloc_va_range(struct i915_address_space 
*vm,
 
ppgtt->pd.page_table[pde] = pt;
set_bit(pde, new_page_tables);
+   trace_i915_page_table_entry_alloc(vm, pde, start, 
GEN6_PDE_SHIFT);
}
 
start = start_save;
@@ -1225,6 +1226,10 @@ static int gen6_alloc_va_range(struct i915_address_space 
*vm,
if (test_and_clear_bit(pde, new_page_tables))
gen6_write_pde(&ppgtt->pd, pde, pt);
 
+   trace_i915_page_table_entry_map(vm, pde, pt,
+gen6_pte_index(start),
+gen6_pte_count(start, length),
+I915_PPGTT_PT_ENTRIES);
bitmap_or(pt->used_ptes, tmp_bitmap, pt->used_ptes,
I915_PPGTT_PT_ENTRIES);
}
diff --git a/drivers/gpu/drm/i915/i915_trace.h 
b/drivers/gpu/drm/i915/i915_trace.h
index f004d3d..0038dc2 100644
--- a/drivers/gpu/drm/i915/i915_trace.h
+++ b/drivers/gpu/drm/i915/i915_trace.h
@@ -156,6 +156,101 @@ TRACE_EVENT(i915_vma_unbind,
  __entry->obj, __entry->offset, __entry->size, __entry->vm)
 );
 
+#define VM_TO_TRACE_NAME(vm) \
+   (i915_is_ggtt(vm) ? "GGTT" : \
+ "Private VM")
+
+DECLARE_EVENT_CLASS(i915_va,
+   TP_PROTO(struct i915_address_space *vm, u64 start, u64 length, const 
char *name),
+   TP_ARGS(vm, start, length, name),
+
+   TP_STRUCT__entry(
+   __field(struct i915_address_space *, vm)
+   __field(u64, start)
+   __field(u64, end)
+   __string(name, name)
+   ),
+
+   TP_fast_assign(
+   __entry->vm = vm;
+   __entry->start = start;
+   __entry->end = start + length;
+   __assign_str(name, name);
+   ),
+
+   TP_printk("vm=%p (%s), 0x%llx-0x%llx",
+ __entry->vm, __get_str(name),  __entry->start, __entry->end)
+);
+
+DEFINE_EVENT(i915_va, i915_va_alloc,
+TP_PROTO(struct i915_address_space *vm, u64 start, u64 length, 
const char *name),
+TP_ARGS(vm, start, length, name)
+);
+
+DECLARE_EVENT_CLASS(i915_page_table_entry,
+   TP_PROTO(struct i915_address_space *vm, u32 pde, u64 start, u64 
pde_shift),
+   TP_ARGS(vm, pde, start, pde_shift),
+
+   TP_STRUCT__entry(
+   __field(struct i915_address_space *, vm)
+   __field(u32, pde)
+   __field(u64, start)
+   __field(u64, end)
+   ),
+
+   TP_fast_assign(
+   __entry->vm = vm;
+   __entry->pde = pde;
+   __entry->start = start;
+   __entry->end = (start + (1ULL << pde_shift)) & ~((1ULL << 
pde_shift)-1);
+   ),
+
+   TP_printk("vm=%p, pde=%d (0x%llx-0x%llx)",
+ __entry->vm, __entry->pde, __entry->start, __entry->end)
+);
+
+DEFINE_EVENT(i915_page_table_entry, i915_page_table_entry_alloc,
+TP_PROTO(struct i915_address_space *vm, u32 pde, u64 start, u64 
pde_shift),
+TP_ARGS(vm, pde, start, pde_shift)
+);
+
+/* Avoid extra math because we only support two sizes. The format is defined by
+ * bitmap_scnprintf. Each 32 bits is 8 HEX digits followed by comma */
+#define TRACE_PT_SIZE(bits) \
+   bits) == 1024) ? 288 : 144) + 1)
+
+DECLARE_EVENT_CLASS(i915_page_table_entry_update,
+   TP_PROTO(struct i915_address_space *vm, u32 pde,
+struct i915_page_table_entry *pt, u32 first, u32 len, size_t 
bits),
+   TP_ARGS(vm, pde, pt, first, len, bits),
+
+   TP_STRUCT__entry(
+   __field(struct i915_address_space *, vm)
+   __field(u32, p

[Intel-gfx] [PATCH v6 13/32] drm/i915/bdw: pagetable allocation rework

2015-02-24 Thread Michel Thierry
From: Ben Widawsky 

Start using gen8_for_each_pde macro to allocate page tables.

v2: teardown_va_range references removed.
v3: Rebase after s/page_tables/page_table/.

Signed-off-by: Ben Widawsky 
Signed-off-by: Michel Thierry  (v2+)
---
 drivers/gpu/drm/i915/i915_gem_gtt.c | 46 +++--
 1 file changed, 29 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/i915_gem_gtt.c
index ade8edd..762c535 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -661,22 +661,27 @@ static void gen8_ppgtt_cleanup(struct i915_address_space 
*vm)
gen8_ppgtt_free(ppgtt);
 }
 
-static int gen8_ppgtt_allocate_page_tables(struct i915_hw_ppgtt *ppgtt)
+static int gen8_ppgtt_alloc_pagetabs(struct i915_page_directory_entry *pd,
+uint64_t start,
+uint64_t length,
+struct drm_device *dev)
 {
-   int i, ret;
+   struct i915_page_table_entry *unused;
+   uint64_t temp;
+   uint32_t pde;
 
-   for (i = 0; i < ppgtt->num_pd_pages; i++) {
-   ret = alloc_pt_range(ppgtt->pdp.page_directory[i],
-0, GEN8_PDES_PER_PAGE, ppgtt->base.dev);
-   if (ret)
+   gen8_for_each_pde(unused, pd, start, length, temp, pde) {
+   BUG_ON(unused);
+   pd->page_table[pde] = alloc_pt_single(dev);
+   if (IS_ERR(pd->page_table[pde]))
goto unwind_out;
}
 
return 0;
 
 unwind_out:
-   while (i--)
-   gen8_free_page_tables(ppgtt->pdp.page_directory[i], 
ppgtt->base.dev);
+   while (pde--)
+   unmap_and_free_pt(pd->page_table[pde], dev);
 
return -ENOMEM;
 }
@@ -719,20 +724,28 @@ unwind_out:
 }
 
 static int gen8_ppgtt_alloc(struct i915_hw_ppgtt *ppgtt,
-   const int max_pdp)
+   uint64_t start,
+   uint64_t length)
 {
+   struct i915_page_directory_entry *pd;
+   uint64_t temp;
+   uint32_t pdpe;
int ret;
 
-   ret = gen8_ppgtt_alloc_page_directories(&ppgtt->pdp, ppgtt->base.start,
-   ppgtt->base.total);
+   ret = gen8_ppgtt_alloc_page_directories(&ppgtt->pdp, start, length);
if (ret)
return ret;
 
-   ret = gen8_ppgtt_allocate_page_tables(ppgtt);
-   if (ret)
-   goto err_out;
+   gen8_for_each_pdpe(pd, &ppgtt->pdp, start, length, temp, pdpe) {
+   ret = gen8_ppgtt_alloc_pagetabs(pd, start, length,
+   ppgtt->base.dev);
+   if (ret)
+   goto err_out;
+
+   ppgtt->num_pd_entries += GEN8_PDES_PER_PAGE;
+   }
 
-   ppgtt->num_pd_entries = max_pdp * GEN8_PDES_PER_PAGE;
+   BUG_ON(pdpe > ppgtt->num_pd_pages);
 
return 0;
 
@@ -802,10 +815,9 @@ static int gen8_ppgtt_init(struct i915_hw_ppgtt *ppgtt, 
uint64_t size)
 
ppgtt->base.start = 0;
ppgtt->base.total = size;
-   BUG_ON(ppgtt->base.total == 0);
 
/* 1. Do all our allocations for page directories and page tables. */
-   ret = gen8_ppgtt_alloc(ppgtt, max_pdp);
+   ret = gen8_ppgtt_alloc(ppgtt, ppgtt->base.start, ppgtt->base.total);
if (ret)
return ret;
 
-- 
2.1.1

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


[Intel-gfx] [PATCH v6 04/32] drm/i915: Plumb drm_device through page tables operations

2015-02-24 Thread Michel Thierry
The next patch in the series will require it for alloc_pt_single.

v2: Rebased after s/page_tables/page_table/.

Signed-off-by: Michel Thierry 
---
 drivers/gpu/drm/i915/i915_gem_gtt.c | 29 -
 1 file changed, 16 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 81c1dba..e05488e 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -142,7 +142,6 @@ static int sanitize_enable_ppgtt(struct drm_device *dev, 
int enable_ppgtt)
return has_aliasing_ppgtt ? 1 : 0;
 }
 
-
 static void ppgtt_bind_vma(struct i915_vma *vma,
   enum i915_cache_level cache_level,
   u32 flags);
@@ -279,7 +278,7 @@ static gen6_gtt_pte_t iris_pte_encode(dma_addr_t addr,
return pte;
 }
 
-static void unmap_and_free_pt(struct i915_page_table_entry *pt)
+static void unmap_and_free_pt(struct i915_page_table_entry *pt, struct 
drm_device *dev)
 {
if (WARN_ON(!pt->page))
return;
@@ -287,7 +286,7 @@ static void unmap_and_free_pt(struct i915_page_table_entry 
*pt)
kfree(pt);
 }
 
-static struct i915_page_table_entry *alloc_pt_single(void)
+static struct i915_page_table_entry *alloc_pt_single(struct drm_device *dev)
 {
struct i915_page_table_entry *pt;
 
@@ -317,7 +316,9 @@ static struct i915_page_table_entry *alloc_pt_single(void)
  *
  * Return: 0 if allocation succeeded.
  */
-static int alloc_pt_range(struct i915_page_directory_entry *pd, uint16_t pde, 
size_t count)
+static int alloc_pt_range(struct i915_page_directory_entry *pd, uint16_t pde, 
size_t count,
+ struct drm_device *dev)
+
 {
int i, ret;
 
@@ -326,7 +327,7 @@ static int alloc_pt_range(struct i915_page_directory_entry 
*pd, uint16_t pde, si
return -EINVAL;
 
for (i = pde; i < pde + count; i++) {
-   struct i915_page_table_entry *pt = alloc_pt_single();
+   struct i915_page_table_entry *pt = alloc_pt_single(dev);
 
if (IS_ERR(pt)) {
ret = PTR_ERR(pt);
@@ -342,7 +343,7 @@ static int alloc_pt_range(struct i915_page_directory_entry 
*pd, uint16_t pde, si
 
 err_out:
while (i-- > pde)
-   unmap_and_free_pt(pd->page_table[i]);
+   unmap_and_free_pt(pd->page_table[i], dev);
return ret;
 }
 
@@ -521,7 +522,7 @@ static void gen8_ppgtt_insert_entries(struct 
i915_address_space *vm,
}
 }
 
-static void gen8_free_page_tables(struct i915_page_directory_entry *pd)
+static void gen8_free_page_tables(struct i915_page_directory_entry *pd, struct 
drm_device *dev)
 {
int i;
 
@@ -532,7 +533,7 @@ static void gen8_free_page_tables(struct 
i915_page_directory_entry *pd)
if (WARN_ON(!pd->page_table[i]))
continue;
 
-   unmap_and_free_pt(pd->page_table[i]);
+   unmap_and_free_pt(pd->page_table[i], dev);
pd->page_table[i] = NULL;
}
 }
@@ -545,7 +546,7 @@ static void gen8_ppgtt_free(struct i915_hw_ppgtt *ppgtt)
if (WARN_ON(!ppgtt->pdp.page_directory[i]))
continue;
 
-   gen8_free_page_tables(ppgtt->pdp.page_directory[i]);
+   gen8_free_page_tables(ppgtt->pdp.page_directory[i], 
ppgtt->base.dev);
unmap_and_free_pd(ppgtt->pdp.page_directory[i]);
}
 }
@@ -597,7 +598,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.page_directory[i],
-0, GEN8_PDES_PER_PAGE);
+0, GEN8_PDES_PER_PAGE, ppgtt->base.dev);
if (ret)
goto unwind_out;
}
@@ -606,7 +607,7 @@ static int gen8_ppgtt_allocate_page_tables(struct 
i915_hw_ppgtt *ppgtt)
 
 unwind_out:
while (i--)
-   gen8_free_page_tables(ppgtt->pdp.page_directory[i]);
+   gen8_free_page_tables(ppgtt->pdp.page_directory[i], 
ppgtt->base.dev);
 
return -ENOMEM;
 }
@@ -1087,7 +1088,7 @@ static void gen6_ppgtt_free(struct i915_hw_ppgtt *ppgtt)
int i;
 
for (i = 0; i < ppgtt->num_pd_entries; i++)
-   unmap_and_free_pt(ppgtt->pd.page_table[i]);
+   unmap_and_free_pt(ppgtt->pd.page_table[i], ppgtt->base.dev);
 
unmap_and_free_pd(&ppgtt->pd);
 }
@@ -1152,7 +1153,9 @@ static int gen6_ppgtt_alloc(struct i915_hw_ppgtt *ppgtt)
if (ret)
return ret;
 
-   ret = alloc_pt_range(&ppgtt->pd, 0, ppgtt->num_pd_entries);
+   ret = alloc_pt_range(&ppgtt->pd, 0, ppgtt->num_pd_entries,
+   ppgtt->base.dev);
+
if (ret) {
drm_mm_remove_node(&ppgtt->node);
return ret;
-- 
2.1.1

_

[Intel-gfx] [PATCH v6 14/32] drm/i915/bdw: Update pdp switch and point unused PDPs to scratch page

2015-02-24 Thread Michel Thierry
From: Ben Widawsky 

One important part of this patch is we now write a scratch page
directory into any unused PDP descriptors. This matters for 2 reasons,
first, we're not allowed to just use 0, or an invalid pointer, and second,
we must wipe out any previous contents from the last context.

The latter point only matters with full PPGTT. The former point only
effect platforms with less than 4GB memory.

v2: Updated commit message to point that we must set unused PDPs to the
scratch page.

Signed-off-by: Ben Widawsky 
Signed-off-by: Michel Thierry  (v2)
---
 drivers/gpu/drm/i915/i915_gem_gtt.c | 29 ++---
 drivers/gpu/drm/i915/i915_gem_gtt.h |  5 -
 2 files changed, 22 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 762c535..2e4db77 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -442,8 +442,9 @@ static struct i915_page_directory_entry 
*alloc_pd_single(void)
 }
 
 /* Broadwell Page Directory Pointer Descriptors */
-static int gen8_write_pdp(struct intel_engine_cs *ring, unsigned entry,
-  uint64_t val)
+static int gen8_write_pdp(struct intel_engine_cs *ring,
+ unsigned entry,
+ dma_addr_t addr)
 {
int ret;
 
@@ -455,10 +456,10 @@ static int gen8_write_pdp(struct intel_engine_cs *ring, 
unsigned entry,
 
intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(1));
intel_ring_emit(ring, GEN8_RING_PDP_UDW(ring, entry));
-   intel_ring_emit(ring, (u32)(val >> 32));
+   intel_ring_emit(ring, upper_32_bits(addr));
intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(1));
intel_ring_emit(ring, GEN8_RING_PDP_LDW(ring, entry));
-   intel_ring_emit(ring, (u32)(val));
+   intel_ring_emit(ring, lower_32_bits(addr));
intel_ring_advance(ring);
 
return 0;
@@ -469,12 +470,12 @@ 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;
-
-   for (i = used_pd - 1; i >= 0; i--) {
-   dma_addr_t addr = ppgtt->pdp.page_directory[i]->daddr;
-   ret = gen8_write_pdp(ring, i, addr);
+   for (i = GEN8_LEGACY_PDPES - 1; i >= 0; i--) {
+   struct i915_page_directory_entry *pd = 
ppgtt->pdp.page_directory[i];
+   dma_addr_t pd_daddr = pd ? pd->daddr : ppgtt->scratch_pd->daddr;
+   /* The page directory might be NULL, but we need to clear out
+* whatever the previous context might have used. */
+   ret = gen8_write_pdp(ring, i, pd_daddr);
if (ret)
return ret;
}
@@ -816,10 +817,16 @@ static int gen8_ppgtt_init(struct i915_hw_ppgtt *ppgtt, 
uint64_t size)
ppgtt->base.start = 0;
ppgtt->base.total = size;
 
+   ppgtt->scratch_pd = alloc_pt_scratch(ppgtt->base.dev);
+   if (IS_ERR(ppgtt->scratch_pd))
+   return PTR_ERR(ppgtt->scratch_pd);
+
/* 1. Do all our allocations for page directories and page tables. */
ret = gen8_ppgtt_alloc(ppgtt, ppgtt->base.start, ppgtt->base.total);
-   if (ret)
+   if (ret) {
+   unmap_and_free_pt(ppgtt->scratch_pd, ppgtt->base.dev);
return ret;
+   }
 
/*
 * 2. Create DMA mappings for the page directories and page tables.
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h 
b/drivers/gpu/drm/i915/i915_gem_gtt.h
index 1f5c136..7a16627 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.h
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.h
@@ -306,7 +306,10 @@ struct i915_hw_ppgtt {
struct i915_page_directory_entry pd;
};
 
-   struct i915_page_table_entry *scratch_pt;
+   union {
+   struct i915_page_table_entry *scratch_pt;
+   struct i915_page_table_entry *scratch_pd; /* Just need the 
daddr */
+   };
 
struct drm_i915_file_private *file_priv;
 
-- 
2.1.1

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


[Intel-gfx] [PATCH v6 26/32] drm/i915/bdw: Add 4 level switching infrastructure

2015-02-24 Thread Michel Thierry
From: Ben Widawsky 

Map is easy, it's the same register as the PDP descriptor 0, but it only
has one entry.

v2: PML4 update in legacy context switch is left for historic reasons,
the preferred mode of operation is with lrc context based submission.

Signed-off-by: Ben Widawsky 
Signed-off-by: Michel Thierry 
---
 drivers/gpu/drm/i915/i915_gem_gtt.c | 56 +
 drivers/gpu/drm/i915/i915_gem_gtt.h |  4 ++-
 drivers/gpu/drm/i915/i915_reg.h |  1 +
 3 files changed, 55 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 4c921d0..88a3c49 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -193,6 +193,9 @@ static inline gen8_ppgtt_pde_t gen8_pde_encode(struct 
drm_device *dev,
return pde;
 }
 
+#define gen8_pdpe_encode gen8_pde_encode
+#define gen8_pml4e_encode gen8_pde_encode
+
 static gen6_gtt_pte_t snb_pte_encode(dma_addr_t addr,
 enum i915_cache_level level,
 bool valid, u32 unused)
@@ -592,8 +595,8 @@ static int gen8_write_pdp(struct intel_engine_cs *ring,
return 0;
 }
 
-static int gen8_mm_switch(struct i915_hw_ppgtt *ppgtt,
- struct intel_engine_cs *ring)
+static int gen8_legacy_mm_switch(struct i915_hw_ppgtt *ppgtt,
+struct intel_engine_cs *ring)
 {
int i, ret;
 
@@ -610,6 +613,12 @@ static int gen8_mm_switch(struct i915_hw_ppgtt *ppgtt,
return 0;
 }
 
+static int gen8_48b_mm_switch(struct i915_hw_ppgtt *ppgtt,
+ struct intel_engine_cs *ring)
+{
+   return gen8_write_pdp(ring, 0, ppgtt->pml4.daddr);
+}
+
 static void gen8_ppgtt_clear_range(struct i915_address_space *vm,
   uint64_t start,
   uint64_t length,
@@ -753,6 +762,37 @@ static void gen8_map_pagetable_range(struct 
i915_address_space *vm,
kunmap_atomic(page_directory);
 }
 
+static void gen8_map_page_directory(struct i915_page_directory_pointer_entry 
*pdp,
+   struct i915_page_directory_entry *pd,
+   int index,
+   struct drm_device *dev)
+{
+   gen8_ppgtt_pdpe_t *page_directorypo;
+   gen8_ppgtt_pdpe_t pdpe;
+
+   /* We do not need to clflush because no platform requiring flush
+* supports 64b pagetables. */
+   if (!USES_FULL_48BIT_PPGTT(dev))
+   return;
+
+   page_directorypo = kmap_atomic(pdp->page);
+   pdpe = gen8_pdpe_encode(dev, pd->daddr, I915_CACHE_LLC);
+   page_directorypo[index] = pdpe;
+   kunmap_atomic(page_directorypo);
+}
+
+static void gen8_map_page_directory_pointer(struct i915_pml4 *pml4,
+   struct 
i915_page_directory_pointer_entry *pdp,
+   int index,
+   struct drm_device *dev)
+{
+   gen8_ppgtt_pml4e_t *pagemap = kmap_atomic(pml4->page);
+   gen8_ppgtt_pml4e_t pml4e = gen8_pml4e_encode(dev, pdp->daddr, 
I915_CACHE_LLC);
+   BUG_ON(!USES_FULL_48BIT_PPGTT(dev));
+   pagemap[index] = pml4e;
+   kunmap_atomic(pagemap);
+}
+
 static void gen8_free_page_tables(struct i915_page_directory_entry *pd, struct 
drm_device *dev)
 {
int i;
@@ -1124,6 +1164,7 @@ static int gen8_alloc_va_range_3lvl(struct 
i915_address_space *vm,
 
set_bit(pdpe, pdp->used_pdpes);
gen8_map_pagetable_range(vm, pd, start, length);
+   gen8_map_page_directory(pdp, pd, pdpe, dev);
}
 
free_gen8_temp_bitmaps(new_page_dirs, new_page_tables, pdpes);
@@ -1192,6 +1233,8 @@ static int gen8_alloc_va_range_4lvl(struct 
i915_address_space *vm,
ret = gen8_alloc_va_range_3lvl(vm, pdp, start, length);
if (ret)
goto err_out;
+
+   gen8_map_page_directory_pointer(pml4, pdp, pml4e, vm->dev);
}
 
bitmap_or(pml4->used_pml4es, new_pdps, pml4->used_pml4es,
@@ -1251,14 +1294,14 @@ static int gen8_ppgtt_init_common(struct i915_hw_ppgtt 
*ppgtt, uint64_t size)
ppgtt->base.cleanup = gen8_ppgtt_cleanup;
ppgtt->base.insert_entries = gen8_ppgtt_insert_entries;
 
-   ppgtt->switch_mm = gen8_mm_switch;
-
if (USES_FULL_48BIT_PPGTT(ppgtt->base.dev)) {
int ret = pml4_init(ppgtt);
if (ret) {
unmap_and_free_pt(ppgtt->scratch_pd, ppgtt->base.dev);
return ret;
}
+
+   ppgtt->switch_mm = gen8_48b_mm_switch;
} else {
int ret = __pdp_init(&ppgtt->pdp, false);
if (ret) {
@@ -1266,6 +1309,7 @@ static int gen8_ppgtt_init_common(struct i915_hw_ppgtt 
*ppgtt, uint64_t size)

[Intel-gfx] [PATCH v6 01/32] drm/i915: page table abstractions

2015-02-24 Thread Michel Thierry
From: Ben Widawsky 

When we move to dynamic page allocation, keeping page_directory and pagetabs as
separate structures will help to break actions into simpler tasks.

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

Following the x86 pagetable terminology:
PDPE = struct i915_page_directory_pointer_entry.
PDE = struct i915_page_directory_entry [page_directory].
PTE = struct i915_page_table_entry [page_tables].

v2: fixed mismatches after clean-up/rebase.

v3: Clarify the names of the multiple levels of page tables (Daniel)

v4: Addressing Mika's review comments.
s/gen8_free_page_directories/gen8_free_page_directory and free the
page tables for the directory there.
In gen8_ppgtt_allocate_page_directories, do not leak previously allocated
pt in case the page_directory alloc fails.
Update error return handling in gen8_ppgtt_alloc.

v5: Do not leak pt on error in gen6_ppgtt_allocate_page_tables. (Mika)

v6: s/page_tables/page_table/. (Mika)

Cc: Mika Kuoppala 
Signed-off-by: Ben Widawsky 
Signed-off-by: Michel Thierry  (v2+)
Reviewed-by: Mika Kuoppala 
---
 drivers/gpu/drm/i915/i915_gem_gtt.c | 180 +++-
 drivers/gpu/drm/i915/i915_gem_gtt.h |  23 -
 2 files changed, 111 insertions(+), 92 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/i915_gem_gtt.c
index e54b2a0..874d9cc 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -338,7 +338,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_page_directory_entry *pd = 
&ppgtt->pdp.page_directory[pdpe];
+   struct page *page_table = pd->page_table[pde].page;
 
last_pte = pte + num_entries;
if (last_pte > GEN8_PTES_PER_PAGE)
@@ -382,8 +383,12 @@ static void gen8_ppgtt_insert_entries(struct 
i915_address_space *vm,
if (WARN_ON(pdpe >= GEN8_LEGACY_PDPES))
break;
 
-   if (pt_vaddr == NULL)
-   pt_vaddr = kmap_atomic(ppgtt->gen8_pt_pages[pdpe][pde]);
+   if (pt_vaddr == NULL) {
+   struct i915_page_directory_entry *pd = 
&ppgtt->pdp.page_directory[pdpe];
+   struct page *page_table = pd->page_table[pde].page;
+
+   pt_vaddr = kmap_atomic(page_table);
+   }
 
pt_vaddr[pte] =
gen8_pte_encode(sg_page_iter_dma_address(&sg_iter),
@@ -407,29 +412,33 @@ static void gen8_ppgtt_insert_entries(struct 
i915_address_space *vm,
}
 }
 
-static void gen8_free_page_tables(struct page **pt_pages)
+static void gen8_free_page_tables(struct i915_page_directory_entry *pd)
 {
int i;
 
-   if (pt_pages == NULL)
+   if (pd->page_table == NULL)
return;
 
for (i = 0; i < GEN8_PDES_PER_PAGE; i++)
-   if (pt_pages[i])
-   __free_pages(pt_pages[i], 0);
+   if (pd->page_table[i].page)
+   __free_page(pd->page_table[i].page);
 }
 
-static void gen8_ppgtt_free(const struct i915_hw_ppgtt *ppgtt)
+static void gen8_free_page_directory(struct i915_page_directory_entry *pd)
+{
+   gen8_free_page_tables(pd);
+   kfree(pd->page_table);
+   __free_page(pd->page);
+}
+
+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_directory(&ppgtt->pdp.page_directory[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_unmap_pages(struct i915_hw_ppgtt *ppgtt)
@@ -464,86 +473,77 @@ 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(GEN8_PDES_PER_PAGE, sizeof(struct page *), 
GFP_KERNEL);
-   if (!pt_pages)
-   return ERR_PTR(-ENOMEM);
-
-   for (i = 0; i < GEN8_PDES_PER_PAGE; i++) {
-   pt_pages[i] = alloc_page(GFP_KERNEL);
-   if (!pt_pages[i])
-   goto bail;
+   for (i = 0; i < ppgtt->num_pd_pages; i++) {
+   ppgtt->gen8_pt_dma_addr[i] = kcalloc(GEN8_PDES_PER_PAGE,
+sizeof(dma_addr_t),
+GFP_KERNEL);
+  

[Intel-gfx] [PATCH v6 21/32] drm/i915/bdw: Make pdp allocation more dynamic

2015-02-24 Thread Michel Thierry
From: Ben Widawsky 

This transitional patch doesn't do much for the existing code. However,
it should make upcoming patches to use the full 48b address space a bit
easier to swallow. The patch also introduces the PML4, ie. the new top
level structure of the page tables.

v2: Renamed  pdp_free to be similar to  pd/pt (unmap_and_free_pdp).

v3: To facilitate testing, 48b mode will be available on Broadwell and
GEN9+, when i915.enable_ppgtt = 3.

v4: Rebase after s/page_tables/page_table/.

Signed-off-by: Ben Widawsky 
Signed-off-by: Michel Thierry  (v2)
---
 drivers/gpu/drm/i915/i915_drv.h |   7 ++-
 drivers/gpu/drm/i915/i915_gem_gtt.c | 109 +---
 drivers/gpu/drm/i915/i915_gem_gtt.h |  41 +++---
 3 files changed, 127 insertions(+), 30 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 3cc0196..662d6c1 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2433,7 +2433,12 @@ struct drm_i915_cmd_table {
 #define HAS_HW_CONTEXTS(dev)   (INTEL_INFO(dev)->gen >= 6)
 #define HAS_LOGICAL_RING_CONTEXTS(dev) (INTEL_INFO(dev)->gen >= 8)
 #define USES_PPGTT(dev)(i915.enable_ppgtt)
-#define USES_FULL_PPGTT(dev)   (i915.enable_ppgtt == 2)
+#define USES_FULL_PPGTT(dev)   (i915.enable_ppgtt >= 2)
+#ifdef CONFIG_64BIT
+# define USES_FULL_48BIT_PPGTT(dev)(i915.enable_ppgtt == 3)
+#else
+# define USES_FULL_48BIT_PPGTT(dev)false
+#endif
 
 #define HAS_OVERLAY(dev)   (INTEL_INFO(dev)->has_overlay)
 #define OVERLAY_NEEDS_PHYSICAL(dev)
(INTEL_INFO(dev)->overlay_needs_physical)
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/i915_gem_gtt.c
index b9dfc56..2a453fd 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -100,10 +100,18 @@ static int sanitize_enable_ppgtt(struct drm_device *dev, 
int enable_ppgtt)
 {
bool has_aliasing_ppgtt;
bool has_full_ppgtt;
+   bool has_full_64bit_ppgtt;
 
has_aliasing_ppgtt = INTEL_INFO(dev)->gen >= 6;
has_full_ppgtt = INTEL_INFO(dev)->gen >= 7;
 
+#ifdef CONFIG_64BIT
+   has_full_64bit_ppgtt = IS_BROADWELL(dev) ||
+   INTEL_INFO(dev)->gen >= 9 && false; /* FIXME: 
64b */
+#else
+   has_full_64bit_ppgtt = false;
+#endif
+
if (intel_vgpu_active(dev))
has_full_ppgtt = false; /* emulation is too hard */
 
@@ -121,6 +129,9 @@ static int sanitize_enable_ppgtt(struct drm_device *dev, 
int enable_ppgtt)
if (enable_ppgtt == 2 && has_full_ppgtt)
return 2;
 
+   if (enable_ppgtt == 3 && has_full_64bit_ppgtt)
+   return 3;
+
 #ifdef CONFIG_INTEL_IOMMU
/* Disable ppgtt on SNB if VT-d is on. */
if (INTEL_INFO(dev)->gen == 6 && intel_iommu_gfx_mapped) {
@@ -461,6 +472,45 @@ free_pd:
return ERR_PTR(ret);
 }
 
+static void __pdp_fini(struct i915_page_directory_pointer_entry *pdp)
+{
+   kfree(pdp->used_pdpes);
+   kfree(pdp->page_directory);
+   /* HACK */
+   pdp->page_directory = NULL;
+}
+
+static void unmap_and_free_pdp(struct i915_page_directory_pointer_entry *pdp,
+   struct drm_device *dev)
+{
+   __pdp_fini(pdp);
+   if (USES_FULL_48BIT_PPGTT(dev))
+   kfree(pdp);
+}
+
+static int __pdp_init(struct i915_page_directory_pointer_entry *pdp,
+ struct drm_device *dev)
+{
+   size_t pdpes = I915_PDPES_PER_PDP(dev);
+
+   pdp->used_pdpes = kcalloc(BITS_TO_LONGS(pdpes),
+ sizeof(unsigned long),
+ GFP_KERNEL);
+   if (!pdp->used_pdpes)
+   return -ENOMEM;
+
+   pdp->page_directory = kcalloc(pdpes, sizeof(*pdp->page_directory), 
GFP_KERNEL);
+   if (!pdp->page_directory) {
+   kfree(pdp->used_pdpes);
+   /* the PDP might be the statically allocated top level. Keep it
+* as clean as possible */
+   pdp->used_pdpes = NULL;
+   return -ENOMEM;
+   }
+
+   return 0;
+}
+
 /* Broadwell Page Directory Pointer Descriptors */
 static int gen8_write_pdp(struct intel_engine_cs *ring,
  unsigned entry,
@@ -490,7 +540,7 @@ static int gen8_mm_switch(struct i915_hw_ppgtt *ppgtt,
 {
int i, ret;
 
-   for (i = GEN8_LEGACY_PDPES - 1; i >= 0; i--) {
+   for (i = 3; i >= 0; i--) {
struct i915_page_directory_entry *pd = 
ppgtt->pdp.page_directory[i];
dma_addr_t pd_daddr = pd ? pd->daddr : ppgtt->scratch_pd->daddr;
/* The page directory might be NULL, but we need to clear out
@@ -579,9 +629,6 @@ static void gen8_ppgtt_insert_entries(struct 
i915_address_space *vm,
pt_vaddr = NULL;
 
for_each_sg_page(pages->sgl, &sg_iter, pages->nents, 0) {
-   if (WARN_ON(pdpe >= GEN8_LEGACY_PDPES))
-

[Intel-gfx] [PATCH v6 32/32] drm/i915/bdw: Flip the 48b switch

2015-02-24 Thread Michel Thierry
Use 48b addresses if hw supports it and i915.enable_ppgtt=3.

Aliasing PPGTT remains 32b only.

Signed-off-by: Michel Thierry 
---
 drivers/gpu/drm/i915/i915_gem_gtt.c | 7 ++-
 drivers/gpu/drm/i915/i915_params.c  | 2 +-
 2 files changed, 3 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 842ce93..fda5907 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -107,7 +107,7 @@ static int sanitize_enable_ppgtt(struct drm_device *dev, 
int enable_ppgtt)
 
 #ifdef CONFIG_64BIT
has_full_64bit_ppgtt = IS_BROADWELL(dev) ||
-   INTEL_INFO(dev)->gen >= 9 && false; /* FIXME: 
64b */
+   INTEL_INFO(dev)->gen >= 9;
 #else
has_full_64bit_ppgtt = false;
 #endif
@@ -1076,9 +1076,6 @@ static int gen8_ppgtt_alloc_page_directories(struct 
i915_address_space *vm,
 
BUG_ON(!bitmap_empty(new_pds, pdpes));
 
-   /* FIXME: PPGTT container_of won't work for 64b */
-   BUG_ON((start + length) > 0x8ULL);
-
gen8_for_each_pdpe(pd, pdp, start, length, temp, pdpe) {
if (pd)
continue;
@@ -1397,7 +1394,7 @@ static int gen8_aliasing_ppgtt_init(struct i915_hw_ppgtt 
*ppgtt)
 {
struct drm_device *dev = ppgtt->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
-   struct i915_page_directory_pointer_entry *pdp = &ppgtt->pdp; /* FIXME: 
48b */
+   struct i915_page_directory_pointer_entry *pdp = &ppgtt->pdp; /* FIXME: 
48b? */
struct i915_page_directory_entry *pd;
uint64_t temp, start = 0, size = dev_priv->gtt.base.total;
uint32_t pdpe;
diff --git a/drivers/gpu/drm/i915/i915_params.c 
b/drivers/gpu/drm/i915/i915_params.c
index 44f2262..1cd43b0 100644
--- a/drivers/gpu/drm/i915/i915_params.c
+++ b/drivers/gpu/drm/i915/i915_params.c
@@ -119,7 +119,7 @@ MODULE_PARM_DESC(enable_hangcheck,
 module_param_named_unsafe(enable_ppgtt, i915.enable_ppgtt, int, 0400);
 MODULE_PARM_DESC(enable_ppgtt,
"Override PPGTT usage. "
-   "(-1=auto [default], 0=disabled, 1=aliasing, 2=full)");
+   "(-1=auto [default], 0=disabled, 1=aliasing, 2=full, 3=full_64b)");
 
 module_param_named(enable_execlists, i915.enable_execlists, int, 0400);
 MODULE_PARM_DESC(enable_execlists,
-- 
2.1.1

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


Re: [Intel-gfx] [PATCH 2/7] drm/i915/skl: Allow scanning out Y and Yf fbs

2015-02-24 Thread Damien Lespiau
On Mon, Feb 23, 2015 at 03:55:56PM +, Tvrtko Ursulin wrote:
> From: Damien Lespiau 
> 
> Skylake is able to scannout those tiling formats. We need to allow them
> in the ADDFB ioctl and tell the harware about it.
> 
> v2: Rebased for addfb2 interface. (Tvrtko Ursulin)
> v3: Rebased for fb modifier changes. (Tvrtko Ursulin)
> v4: Don't allow Y tiled fbs just yet. (Tvrtko Ursulin)
> v5: Check for stride alignment and max pitch. (Tvrtko Ursulin)
> v6: Simplify maximum pitch check. (Ville Syrjälä)
> v7: Drop the gen9 check since requirements are no different. (Ville Syrjälä)
> 
> Signed-off-by: Damien Lespiau 
> Signed-off-by: Tvrtko Ursulin 
> Cc: Ville Syrjälä 

While Tvrtko had the courtesy of keeping me as the original author, it's
really two authors, so the r-b has some meaning. Anyway:

Reviewed-by: Damien Lespiau 

-- 
Damien

> ---
>  drivers/gpu/drm/i915/intel_display.c | 115 
> ---
>  drivers/gpu/drm/i915/intel_drv.h |   2 +
>  drivers/gpu/drm/i915/intel_sprite.c  |  18 --
>  3 files changed, 95 insertions(+), 40 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_display.c 
> b/drivers/gpu/drm/i915/intel_display.c
> index 6e70748..a523d84 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -2728,6 +2728,34 @@ static void ironlake_update_primary_plane(struct 
> drm_crtc *crtc,
>   POSTING_READ(reg);
>  }
>  
> +u32 intel_fb_stride_alignment(struct drm_device *dev, uint64_t fb_modifier,
> +   uint32_t pixel_format)
> +{
> + u32 bits_per_pixel = drm_format_plane_cpp(pixel_format, 0) * 8;
> +
> + /*
> +  * The stride is either expressed as a multiple of 64 bytes
> +  * chunks for linear buffers or in number of tiles for tiled
> +  * buffers.
> +  */
> + switch (fb_modifier) {
> + case DRM_FORMAT_MOD_NONE:
> + return 64;
> + case I915_FORMAT_MOD_X_TILED:
> + return 512;
> + case I915_FORMAT_MOD_Y_TILED:
> + return 128;
> + case I915_FORMAT_MOD_Yf_TILED:
> + if (bits_per_pixel == 8)
> + return 64;
> + else
> + return 128;
> + default:
> + MISSING_CASE(fb_modifier);
> + return 64;
> + }
> +}
> +
>  static void skylake_update_primary_plane(struct drm_crtc *crtc,
>struct drm_framebuffer *fb,
>int x, int y)
> @@ -2735,10 +2763,9 @@ static void skylake_update_primary_plane(struct 
> drm_crtc *crtc,
>   struct drm_device *dev = crtc->dev;
>   struct drm_i915_private *dev_priv = dev->dev_private;
>   struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> - struct intel_framebuffer *intel_fb;
>   struct drm_i915_gem_object *obj;
>   int pipe = intel_crtc->pipe;
> - u32 plane_ctl, stride;
> + u32 plane_ctl, stride_div;
>  
>   if (!intel_crtc->primary_enabled) {
>   I915_WRITE(PLANE_CTL(pipe, 0), 0);
> @@ -2782,29 +2809,30 @@ static void skylake_update_primary_plane(struct 
> drm_crtc *crtc,
>   BUG();
>   }
>  
> - intel_fb = to_intel_framebuffer(fb);
> - obj = intel_fb->obj;
> -
> - /*
> -  * The stride is either expressed as a multiple of 64 bytes chunks for
> -  * linear buffers or in number of tiles for tiled buffers.
> -  */
>   switch (fb->modifier[0]) {
>   case DRM_FORMAT_MOD_NONE:
> - stride = fb->pitches[0] >> 6;
>   break;
>   case I915_FORMAT_MOD_X_TILED:
>   plane_ctl |= PLANE_CTL_TILED_X;
> - stride = fb->pitches[0] >> 9;
> + break;
> + case I915_FORMAT_MOD_Y_TILED:
> + plane_ctl |= PLANE_CTL_TILED_Y;
> + break;
> + case I915_FORMAT_MOD_Yf_TILED:
> + plane_ctl |= PLANE_CTL_TILED_YF;
>   break;
>   default:
> - BUG();
> + MISSING_CASE(fb->modifier[0]);
>   }
>  
>   plane_ctl |= PLANE_CTL_PLANE_GAMMA_DISABLE;
>   if (crtc->primary->state->rotation == BIT(DRM_ROTATE_180))
>   plane_ctl |= PLANE_CTL_ROTATE_180;
>  
> + obj = intel_fb_obj(fb);
> + stride_div = intel_fb_stride_alignment(dev, fb->modifier[0],
> +fb->pixel_format);
> +
>   I915_WRITE(PLANE_CTL(pipe, 0), plane_ctl);
>  
>   DRM_DEBUG_KMS("Writing base %08lX %d,%d,%d,%d pitch=%d\n",
> @@ -2817,7 +2845,7 @@ static void skylake_update_primary_plane(struct 
> drm_crtc *crtc,
>   I915_WRITE(PLANE_SIZE(pipe, 0),
>  (intel_crtc->config->pipe_src_h - 1) << 16 |
>  (intel_crtc->config->pipe_src_w - 1));
> - I915_WRITE(PLANE_STRIDE(pipe, 0), stride);
> + I915_WRITE(PLANE_STRIDE(pipe, 0), fb->pitches[0] / stride_div);
>   I915_WRITE(PLANE_SURF(pipe, 0), i915_gem_obj_ggtt_offset(obj));
>  
>   POSTING_R

Re: [Intel-gfx] Hibernation test

2015-02-24 Thread Imre Deak
On ke, 2015-02-18 at 18:43 +0200, Imre Deak wrote:
> On ke, 2015-02-11 at 16:46 +0200, David Weinehall wrote:
> > intel-gpu-tools currently has a bunch of tests for suspend,
> > but currently none (that I could find) for hibernate.
> > 
> > Attached is a rudimentary patch to add said test.  It does so
> > by repurposing the drv_suspend driver to handle both suspend
> > and hibernate, since the difference is miniscule.
> > 
> > I decided to split the suspend/autoresume functions in
> > igt_aux.c though, to be able to leave the igt_system_uspend_autoresume()
> > function unchanged (the other option would be to
> > introduce a boolean function argument and have that
> > decide what parameters to pass to rtcwake).
> > 
> > The timeout passed to rtcwake probably needs tuning (it might
> > even need to be dynamically adjusted, since the time hibernation takes
> > varies wildly depending on the amount of non-cache memory in use).
> 
> I think in general we should try to keep the existing subtest names, but
> I couldn't find any concrete problem changing them in this case. The
> patch looks ok to me (please inline the patch next time):
> Reviewed-by: Imre Deak 

Thanks for the patch, I pushed it to igt.

--Imre

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


Re: [Intel-gfx] [PATCH 3/7] drm/i915/skl: Adjust intel_fb_align_height() for Yb/Yf tiling

2015-02-24 Thread Damien Lespiau
On Mon, Feb 23, 2015 at 03:55:57PM +, Tvrtko Ursulin wrote:
> From: Damien Lespiau 
> 
> We now need the bpp of the fb as Yf tiling has different tile widths
> depending on it.
> 
> v2: Rebased for the new addfb2 interface. (Tvrtko Ursulin)
> v3: Rebased for fb modifier changes. (Tvrtko Ursulin)
> 
> Signed-off-by: Damien Lespiau 
> Signed-off-by: Tvrtko Ursulin 
> Reviewed-by: Tvrtko Ursulin 

Might want to add a MISSING_CASE() here as well. For the record, the
vertical alignments for Yf are taken from a dodgy looking document found
by chance.

We don't have a 128bpp format supported by display

Now that I think about it, for the horizontal stride, BSpec says:

  - 8 bpp -> 64 bytes
  - * bpp -> 128 bytes

Given that a tile is a page size this would give for the vertical
alignment:

  - 8 bpp -> 64 byes (that's what we have)
  - * -> 32 bytes

So the 64bpp cases look a bit suspicious. Given that one the goals for
this new tiling format is to have tiles as square as possible (in terms
of pixels, not byte size), it'd make sense to have different strides
constraints for the 64bpp format, so it could be BSpec being wrong on
the horizontal stride constraint for 64bpp?

-- 
Damien

> ---
>  drivers/gpu/drm/i915/intel_display.c | 31 +--
>  1 file changed, 29 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_display.c 
> b/drivers/gpu/drm/i915/intel_display.c
> index a523d84..4f0033a 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -2195,9 +2195,36 @@ intel_fb_align_height(struct drm_device *dev, int 
> height,
> uint64_t fb_format_modifier)
>  {
>   int tile_height;
> + uint32_t bits_per_pixel;
>  
> - tile_height = fb_format_modifier == I915_FORMAT_MOD_X_TILED ?
> - (IS_GEN2(dev) ? 16 : 8) : 1;
> + switch (fb_format_modifier) {
> + case I915_FORMAT_MOD_X_TILED:
> + tile_height = IS_GEN2(dev) ? 16 : 8;
> + break;
> + case I915_FORMAT_MOD_Y_TILED:
> + tile_height = 32;
> + break;
> + case I915_FORMAT_MOD_Yf_TILED:
> + bits_per_pixel = drm_format_plane_cpp(pixel_format, 0) * 8;
> + switch (bits_per_pixel) {
> + default:
> + case 8:
> + tile_height = 64;
> + break;
> + case 16:
> + case 32:
> + tile_height = 32;
> + break;
> + case 64:
> + case 128:
> + tile_height = 16;
> + break;
> + }
> + break;
> + default:
> + tile_height = 1;
> + break;
> + }
>  
>   return ALIGN(height, tile_height);
>  }
> -- 
> 2.3.0
> 
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH 5/7] drm/i915/skl: Adjust get_plane_config() to support Yb/Yf tiling

2015-02-24 Thread Damien Lespiau
On Mon, Feb 23, 2015 at 03:55:59PM +, Tvrtko Ursulin wrote:
> From: Damien Lespiau 
> 
> v2: Rebased for addfb2 interface and consolidated a bit. (Tvrtko Ursulin)
> v3: Rebased for fb modifier changes. (Tvrtko Ursulin)
> 
> Signed-off-by: Damien Lespiau 
> Signed-off-by: Tvrtko Ursulin 
> Reviewed-by: Tvrtko Ursulin 
> ---

This patch looks like it could reuse the newly introduced
intel_fb_stride_alignment(). Otherwise:

Reviewed-by: Damien Lespiau 

>  drivers/gpu/drm/i915/intel_display.c | 45 
> ++--
>  1 file changed, 28 insertions(+), 17 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_display.c 
> b/drivers/gpu/drm/i915/intel_display.c
> index 358a97e..c622b11 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -7718,7 +7718,7 @@ skylake_get_initial_plane_config(struct intel_crtc 
> *crtc,
>  {
>   struct drm_device *dev = crtc->base.dev;
>   struct drm_i915_private *dev_priv = dev->dev_private;
> - u32 val, base, offset, stride_mult;
> + u32 val, base, offset, stride_mult, tiling;
>   int pipe = crtc->pipe;
>   int fourcc, pixel_format;
>   int aligned_height;
> @@ -7737,11 +7737,6 @@ skylake_get_initial_plane_config(struct intel_crtc 
> *crtc,
>   if (!(val & PLANE_CTL_ENABLE))
>   goto error;
>  
> - if (val & PLANE_CTL_TILED_MASK) {
> - plane_config->tiling = I915_TILING_X;
> - fb->modifier[0] = I915_FORMAT_MOD_X_TILED;
> - }
> -
>   pixel_format = val & PLANE_CTL_FORMAT_MASK;
>   fourcc = skl_format_to_fourcc(pixel_format,
> val & PLANE_CTL_ORDER_RGBX,
> @@ -7749,6 +7744,33 @@ skylake_get_initial_plane_config(struct intel_crtc 
> *crtc,
>   fb->pixel_format = fourcc;
>   fb->bits_per_pixel = drm_format_plane_cpp(fourcc, 0) * 8;
>  
> + tiling = val & PLANE_CTL_TILED_MASK;
> + switch (tiling) {
> + case PLANE_CTL_TILED_LINEAR:
> + fb->modifier[0] = DRM_FORMAT_MOD_NONE;
> + stride_mult = 64;
> + break;
> + case PLANE_CTL_TILED_X:
> + plane_config->tiling = I915_TILING_X;
> + fb->modifier[0] = I915_FORMAT_MOD_X_TILED;
> + stride_mult = 512;
> + break;
> + case PLANE_CTL_TILED_Y:
> + fb->modifier[0] = I915_FORMAT_MOD_Y_TILED;
> + stride_mult = 128;
> + break;
> + case PLANE_CTL_TILED_YF:
> + fb->modifier[0] = I915_FORMAT_MOD_Yf_TILED;
> + if (fb->bits_per_pixel == 8)
> + stride_mult = 64;
> + else
> + stride_mult = 128;
> + break;
> + default:
> + MISSING_CASE(tiling);
> + goto error;
> + }
> +
>   base = I915_READ(PLANE_SURF(pipe, 0)) & 0xf000;
>   plane_config->base = base;
>  
> @@ -7759,17 +7781,6 @@ skylake_get_initial_plane_config(struct intel_crtc 
> *crtc,
>   fb->width = ((val >> 0) & 0x1fff) + 1;
>  
>   val = I915_READ(PLANE_STRIDE(pipe, 0));
> - switch (plane_config->tiling) {
> - case I915_TILING_NONE:
> - stride_mult = 64;
> - break;
> - case I915_TILING_X:
> - stride_mult = 512;
> - break;
> - default:
> - MISSING_CASE(plane_config->tiling);
> - goto error;
> - }
>   fb->pitches[0] = (val & 0x3ff) * stride_mult;
>  
>   aligned_height = intel_fb_align_height(dev, fb->height,
> -- 
> 2.3.0
> 
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH] drm/i915: Fix frontbuffer false positve.

2015-02-24 Thread Rodrigo Vivi
On Mon, Feb 23, 2015 at 6:13 PM, Matt Roper  wrote:
> On Mon, Feb 23, 2015 at 05:52:24PM -0800, Rodrigo Vivi wrote:
>> Hi Daniel,
>>
>> It seems that one check with one good commit followed by many zeroed
>> intel_crtc->atomic commits is again in place.
>
> Can you elaborate on what you mean by this?  With atomic it's possible
> to have a check with no commit after it (if the check or prepare fail,
> or if it's a 'test only' operation), but if you're seeing commits
> without corresponding checks, that sounds like a bug.

Ah so yes, this is the bug, when moving a cursor we have many commits
without checks. So it is only one check followed by many commits... so
it commits with intel_crtc->atomic all zeroed by a previous
finish_commit.

>
> Can you provide a dmesg with drm.debug turned on so we can see what's
> going on?  Or add some dump_stack()'s so that we can see the backtrace
> that led us to this situation.

I lost those logs, but if you put one print in check and one in commit
you also should be able to see that since I heard about this false
positive from many people.

>
> Actually, I wonder if the problem is actually the opposite of what you
> say above.  Now that I look at this again, we only zero out
> intel_crtc->atomic in intel_finish_crtc_commit which is part of the
> commit path.

From what I heard and what I saw on the logs I thought it was ok to
have 1 check than as many commits as possible without the check.
If that was the case we would have a fail that is to zero the
structure on finish_commit. But seems this isn't the case. Sorry.

> So if you had a check that never got a corresponding
> commit, there might still be garbage left over in there.

No it is the opposite. Commits with no check. causing commit of
intel_crtc->atomic zeroed.

> Ultimately we
> should be handling all of this with real intel_crtc_state handling which
> we don't quite have yet.  Maybe in the meantime we need to be clearing
> out intel_crtc->atomic at the beginning of a top-level atomic
> transaction?  I'll send a patch that makes this change for you to try
> shortly.

Thanks! I thought about this but got afraid that clearing this on top
of check could cause a race since one plane doing a check could clean
the atomic being commited on cursor movement, unless we hat that for
planes, but then we would have to iterate over all planes on
finish_commit.

We can also put this patch that fix the only known issue so far with a
FIXME comment while we don't have the final fix.

>
>
> Matt
>
>>
>> So I'm getting that annoying false positives on latest -nightly.
>>
>> Shouldn't we just merge this patch while atomic modeset design doesn't
>> get fixed at all?
>>
>> Unfortunately nothing comes to my mind than moving all
>> intel_crtc->atomic set to commit time and let pre_commit just with
>> pm_get...
>> Ohter than that just a full redesign of atomic modeset.
>>
>> Thanks,
>> Rodrigo.
>>
>>
>> On Fri, Feb 13, 2015 at 12:48 AM, Daniel Vetter  wrote:
>> > On Thu, Feb 12, 2015 at 05:17:04PM -0800, Rodrigo Vivi wrote:
>> >> No, we had solved old frontbuffer false positives... some missing
>> >> flush somewhere at that time...
>> >>
>> >> So, I added a bunch of printk and I insist that it is conceptually
>> >> wrong to set intel_crtc_atomic_commit on check times when you do
>> >> memset(&intel_crtc->atomic, 0, sizeof(intel_crtc->atomic));
>> >> on every finish_commit.
>> >>
>> >> With exception of atomic.disabled_planes I believe the rest shouldn't
>> >> work in the way it is implemented because you can have one check
>> >> followed by many commits, but after the first commit all atomic
>> >> variables are zeroed, except the disabled_planes that is set outside
>> >> check...
>> >
>> > Ok here's the trouble: Every commit should have at exactly one check for
>> > the new state objects. Unfortunately in the transition that seems to have
>> > been lost for some cases.
>> >
>> >> For instance: on every cursor movement atomic.fb_bits was 0x000 when
>> >> it should be 0x002. This is why this patch solved the false positive,
>> >> i.e. setting it on commit instead on check time we get it propperly
>> >> set. One of the problems is the false positive but also it breaks
>> >> entirely SW tracking on VLV/CHV
>> >>
>> >> I believe wait_for flips, update_fbc, watermarks, etc should keep the
>> >> value got on check for the commit or the check should be done at
>> >> commit plane instead of on check.
>> >>
>> >> I started doing a patch here to move all atomic sets from check to
>> >> commit functions but gave up on middle when I noticed the
>> >> prepare_commit would almost get empty...
>> >
>> > All state precomputation must be done in check, at commit time you have a
>> > lot less information since the old state is somewhat gone. You can still
>> > get at it, but as soon as we add an async flip queue that will get really
>> > ugly. The current placement is imo the correct one. Instead we need to
>> > figure out where we're doing a ->commit wit

Re: [Intel-gfx] [PATCH 2/7] drm/i915/skl: Allow scanning out Y and Yf fbs

2015-02-24 Thread Ville Syrjälä
On Mon, Feb 23, 2015 at 03:55:56PM +, Tvrtko Ursulin wrote:
> From: Damien Lespiau 
> 
> Skylake is able to scannout those tiling formats. We need to allow them
> in the ADDFB ioctl and tell the harware about it.
> 
> v2: Rebased for addfb2 interface. (Tvrtko Ursulin)
> v3: Rebased for fb modifier changes. (Tvrtko Ursulin)
> v4: Don't allow Y tiled fbs just yet. (Tvrtko Ursulin)
> v5: Check for stride alignment and max pitch. (Tvrtko Ursulin)
> v6: Simplify maximum pitch check. (Ville Syrjälä)
> v7: Drop the gen9 check since requirements are no different. (Ville Syrjälä)
> 
> Signed-off-by: Damien Lespiau 
> Signed-off-by: Tvrtko Ursulin 
> Cc: Ville Syrjälä 
> ---
>  drivers/gpu/drm/i915/intel_display.c | 115 
> ---
>  drivers/gpu/drm/i915/intel_drv.h |   2 +
>  drivers/gpu/drm/i915/intel_sprite.c  |  18 --
>  3 files changed, 95 insertions(+), 40 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_display.c 
> b/drivers/gpu/drm/i915/intel_display.c
> index 6e70748..a523d84 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -2728,6 +2728,34 @@ static void ironlake_update_primary_plane(struct 
> drm_crtc *crtc,
>   POSTING_READ(reg);
>  }
>  
> +u32 intel_fb_stride_alignment(struct drm_device *dev, uint64_t fb_modifier,
> +   uint32_t pixel_format)
> +{
> + u32 bits_per_pixel = drm_format_plane_cpp(pixel_format, 0) * 8;
> +
> + /*
> +  * The stride is either expressed as a multiple of 64 bytes
> +  * chunks for linear buffers or in number of tiles for tiled
> +  * buffers.
> +  */
> + switch (fb_modifier) {
> + case DRM_FORMAT_MOD_NONE:
> + return 64;
> + case I915_FORMAT_MOD_X_TILED:

if (gen2)
return 128;

> + return 512;
> + case I915_FORMAT_MOD_Y_TILED:
> + return 128;

In theory we could check gen2 and HAS_128_BYTE_Y_TILING() here, but
since old platforms didn't do Y tiled scanout anyway that's not really
needed. But maybe toss in a comment about that so that people don't
start wondering why this doesn't care about that stuff?

> + case I915_FORMAT_MOD_Yf_TILED:
> + if (bits_per_pixel == 8)
> + return 64;
> + else
> + return 128;
> + default:
> + MISSING_CASE(fb_modifier);
> + return 64;
> + }
> +}
> +
>  static void skylake_update_primary_plane(struct drm_crtc *crtc,
>struct drm_framebuffer *fb,
>int x, int y)
> @@ -2735,10 +2763,9 @@ static void skylake_update_primary_plane(struct 
> drm_crtc *crtc,
>   struct drm_device *dev = crtc->dev;
>   struct drm_i915_private *dev_priv = dev->dev_private;
>   struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> - struct intel_framebuffer *intel_fb;
>   struct drm_i915_gem_object *obj;
>   int pipe = intel_crtc->pipe;
> - u32 plane_ctl, stride;
> + u32 plane_ctl, stride_div;
>  
>   if (!intel_crtc->primary_enabled) {
>   I915_WRITE(PLANE_CTL(pipe, 0), 0);
> @@ -2782,29 +2809,30 @@ static void skylake_update_primary_plane(struct 
> drm_crtc *crtc,
>   BUG();
>   }
>  
> - intel_fb = to_intel_framebuffer(fb);
> - obj = intel_fb->obj;
> -
> - /*
> -  * The stride is either expressed as a multiple of 64 bytes chunks for
> -  * linear buffers or in number of tiles for tiled buffers.
> -  */
>   switch (fb->modifier[0]) {
>   case DRM_FORMAT_MOD_NONE:
> - stride = fb->pitches[0] >> 6;
>   break;
>   case I915_FORMAT_MOD_X_TILED:
>   plane_ctl |= PLANE_CTL_TILED_X;
> - stride = fb->pitches[0] >> 9;
> + break;
> + case I915_FORMAT_MOD_Y_TILED:
> + plane_ctl |= PLANE_CTL_TILED_Y;
> + break;
> + case I915_FORMAT_MOD_Yf_TILED:
> + plane_ctl |= PLANE_CTL_TILED_YF;
>   break;
>   default:
> - BUG();
> + MISSING_CASE(fb->modifier[0]);
>   }
>  
>   plane_ctl |= PLANE_CTL_PLANE_GAMMA_DISABLE;
>   if (crtc->primary->state->rotation == BIT(DRM_ROTATE_180))
>   plane_ctl |= PLANE_CTL_ROTATE_180;
>  
> + obj = intel_fb_obj(fb);
> + stride_div = intel_fb_stride_alignment(dev, fb->modifier[0],
> +fb->pixel_format);
> +
>   I915_WRITE(PLANE_CTL(pipe, 0), plane_ctl);
>  
>   DRM_DEBUG_KMS("Writing base %08lX %d,%d,%d,%d pitch=%d\n",
> @@ -2817,7 +2845,7 @@ static void skylake_update_primary_plane(struct 
> drm_crtc *crtc,
>   I915_WRITE(PLANE_SIZE(pipe, 0),
>  (intel_crtc->config->pipe_src_h - 1) << 16 |
>  (intel_crtc->config->pipe_src_w - 1));
> - I915_WRITE(PLANE_STRIDE(pipe, 0), stride);
> + I915_WRITE(PLANE_STRIDE(pipe, 0), 

Re: [Intel-gfx] [RFC 01/12] drm/i915/config: Initial framework

2015-02-24 Thread Bob Paauwe
On Tue, 24 Feb 2015 17:17:18 +0100
Daniel Vetter  wrote:

> On Thu, Feb 12, 2015 at 03:41:27PM -0800, Bob Paauwe wrote:
> > This adds an init-time configuration framework that parses configuration
> > data from an ACPI property table. The table is assumed to have well
> > defined sub-device property tables that correspond to the various
> > driver components.  Initially the following sub-device tables are
> > defined:
> > 
> > CRTC (CRTC)
> >The CRTC sub-device table contains additional sub-device tables
> >where each one corresponds to a CRTC.  Each CRTC sub-device must
> >include a property called "id" whose value matches the driver's
> >crtc id. Additional properties for the CRTC are used to configure
> >the crtc.
> > 
> > Connector (CNCT)
> >The CNCT sub-device table contains additional sub-device tables
> >where each one corresponds to a connector. Each of the connector
> >sub-device tables must include a property called "name" whose value
> >matches a connector name assigned by the driver (see later patch
> >for output name function). Additional connector properties can
> >be set through these tables.
> > 
> > Plane (PLNS)
> >The PLNS sub-device table contains additional sub-device tables
> >where each one corresponds to a plane.  [this needs additional work]
> > 
> > In addition, the main device property table for the device may
> > contain configuration information that applies to general driver
> > configuration.
> > 
> > The framework includes a couple of helper functions to access the
> > configuration data.
> > 
> >intel_config_get_integer() will look up a configuration property
> >and return the integer value associated with it.
> > 
> >intel_config_init__property() will look up a
> >configuration property and assign the value to a drm
> >property of the same name.  These functions are used to
> >initialize drm property instances to specific values.
> > 
> > Signed-off-by: Bob Paauwe 
> 
> Like Jani I'm mostly concerned about maintaining yet another slightly
> different definition of paramters and settings here - we already have (or
> will soon grow) per crtc/plane/connector properties for atomic.

For drm properties, the idea was to expand the existing hard coded
default values with configurable defaults.  For the pre-atomic
connector properties, when the property instance was created, they were
created with a specific default value.  

I haven't looked closely at the atomic property sets yet to see if this
interface also makes sense with them, but that is on my near-term todo
list.  Most of this code had been developed prior to the atomic patches.

> 
> My high-level idea for this was that we reuse the atomic support (once we
> have it) and just take the acpi tables as a slightly different source for
> an atomic update. Since the design of a name/value pair for objects is
> very similar to what we do with the atomic ioctl this hopefully should map
> fairly well.

Yes, I believe it will map easily also, and plan to look at this next. 

> 
> Internally in the driver the only work needed to do would be to add any
> missing properties. All the acpi atomic update code should be fully i915
> agnostic and only use generic atomic update interfaces.

ACPI isn't really driver agnostic since it's only available to IA based
drivers. So I'm not sure I follow your thinking here.  Maybe it will
make more sense to me as I look at the atomic properties. 

I needed to get some fresh eyes looking at this which is why I posted
it. I appreciate the feedback and will be incorporating it into the
next version.

> 
> Would this work or do I overlook something important here.
> -Daniel
> 
> > ---
> >  drivers/gpu/drm/i915/Makefile   |   3 +-
> >  drivers/gpu/drm/i915/i915_dma.c |   4 +
> >  drivers/gpu/drm/i915/i915_drv.h |  16 ++
> >  drivers/gpu/drm/i915/i915_params.c  |   6 +
> >  drivers/gpu/drm/i915/intel_config.c | 542 
> > 
> >  drivers/gpu/drm/i915/intel_drv.h|  28 ++
> >  6 files changed, 598 insertions(+), 1 deletion(-)
> >  create mode 100644 drivers/gpu/drm/i915/intel_config.c
> > 
> > diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
> > index f025e7f..462de19 100644
> > --- a/drivers/gpu/drm/i915/Makefile
> > +++ b/drivers/gpu/drm/i915/Makefile
> > @@ -12,7 +12,8 @@ i915-y := i915_drv.o \
> >i915_suspend.o \
> >   i915_sysfs.o \
> >   intel_pm.o \
> > - intel_runtime_pm.o
> > + intel_runtime_pm.o \
> > + intel_config.o
> >  
> >  i915-$(CONFIG_COMPAT)   += i915_ioc32.o
> >  i915-$(CONFIG_DEBUG_FS) += i915_debugfs.o
> > diff --git a/drivers/gpu/drm/i915/i915_dma.c 
> > b/drivers/gpu/drm/i915/i915_dma.c
> > index 5804aa5..9501360 100644
> > --- a/drivers/gpu/drm/i915/i915_dma.c
> > +++ b/drivers/gpu/drm/i915/i915_dma.c
> > @@ -656,6 +656,8 @@ int i915_driver_load(struct drm_device *dev, unsigned 
> > long flags)
> > de

Re: [Intel-gfx] [PATCH] drm/i915: Clear crtc atomic flags at beginning of transaction

2015-02-24 Thread Rodrigo Vivi
It doesn't fix.

Let's me grab some new logs...

On Tue, Feb 24, 2015 at 9:43 AM, Rodrigo Vivi  wrote:
> Hi Matt,
>
> It probably doesn't fix because the issue is to have many commits
> without a check, having many commits with intel_crtc->atomic zeroed
> already.
> imho cleaning it more wouldn't solve it... but anyway, let me try.
>
> Thanks,
> Rodrigo.
>
> On Mon, Feb 23, 2015 at 6:14 PM, Matt Roper  wrote:
>> Once we have full atomic modeset, these kind of flags should be in a
>> real intel_crtc_state that's tracked properly.  In the meantime, make
>> sure we clear out any old flags at the beginning of a transaction so
>> that we don't wind up seeing leftover flags from old transactions that
>> were checked, but never went to the commit step.
>>
>> Cc: Rodrigo Vivi 
>> Signed-off-by: Matt Roper 
>> ---
>> Rodrigo, does this solve the frontbuffer problems you're seeing?  I haven't 
>> had
>> time to test this myself, but I think this will fix at least one problem that
>> may or may not have been the source of your troubles.
>>
>>  drivers/gpu/drm/i915/intel_atomic.c | 2 ++
>>  1 file changed, 2 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/i915/intel_atomic.c 
>> b/drivers/gpu/drm/i915/intel_atomic.c
>> index 011b896..fe51e23 100644
>> --- a/drivers/gpu/drm/i915/intel_atomic.c
>> +++ b/drivers/gpu/drm/i915/intel_atomic.c
>> @@ -76,6 +76,8 @@ int intel_atomic_check(struct drm_device *dev,
>> state->allow_modeset = false;
>> for (i = 0; i < ncrtcs; i++) {
>> struct intel_crtc *crtc = to_intel_crtc(state->crtcs[i]);
>> +   if (crtc)
>> +   memset(&crtc->atomic, 0, sizeof(crtc->atomic));
>> if (crtc && crtc->pipe != nuclear_pipe)
>> not_nuclear = true;
>> }
>> --
>> 1.8.5.1
>>
>
>
>
> --
> 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] [RFC 07/12] drm/i915/config: Get workaround information from configuration.

2015-02-24 Thread Bob Paauwe
On Tue, 24 Feb 2015 14:51:31 +0100
Daniel Vetter  wrote:

> On Thu, Feb 12, 2015 at 03:41:33PM -0800, Bob Paauwe wrote:
> > Add ability to parse a list of workarounds from the ACPI table.
> > Initially, this expects all workarounds listed to be valid and
> > they replace the hard coded list initialized in init_workarounds_ring().
> > 
> > The main benefit of this is the ability to add/remove workarounds
> > at runtime.  It may also be useful to "adjust" the workaround
> > list for a new GPU prior to fixed support being available in the
> > driver.
> > 
> > Signed-off-by: Bob Paauwe 
> 
> This one here freaks me out. We /should/ be fast enough with rolling out
> workarounds through backports to stable kernels and product trees that
> this shouldn't ever matter. And for a lot of workarounds this is too
> limited since we also need to emit some of them to the ring on each engine
> init or sometimes even context load.
> 
> As-is it looks a lot more like a backdoor to the driver to enable some
> features no one wants to talk about in public ;-)
> -Daniel

Yeah, I don't know that we have any valid use-case for this.  It
really is just an idea. Maybe a bad idea. It was something that looked
like it could map into the configuration space so I coded it up. 

I did think it might be useful if we could disable workarounds for early
steppings that may not be applicable for later steppings without the
need to release a new version of the driver.  As it sits, it doesn't
support this use-case so would need a bit more work. For some embedded
appliance type devices, customers are sometimes more willing to take a
configuration change than a new driver.

The patches for this should be easy to drop without effecting anything
else.

> 
> > ---
> >  drivers/gpu/drm/i915/i915_drv.h |   1 +
> >  drivers/gpu/drm/i915/intel_config.c | 101 
> > +++-
> >  drivers/gpu/drm/i915/intel_drv.h|   4 +-
> >  3 files changed, 104 insertions(+), 2 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/i915_drv.h 
> > b/drivers/gpu/drm/i915/i915_drv.h
> > index 165091c..1580702 100644
> > --- a/drivers/gpu/drm/i915/i915_drv.h
> > +++ b/drivers/gpu/drm/i915/i915_drv.h
> > @@ -1656,6 +1656,7 @@ struct intel_config_info {
> > struct list_head crtc_list;
> > struct list_head connector_list;
> > struct list_head plane_list;
> > +   struct list_head wa_list;
> >  };
> >  
> >  
> > diff --git a/drivers/gpu/drm/i915/intel_config.c 
> > b/drivers/gpu/drm/i915/intel_config.c
> > index fb495ed..ab14928 100644
> > --- a/drivers/gpu/drm/i915/intel_config.c
> > +++ b/drivers/gpu/drm/i915/intel_config.c
> > @@ -214,6 +214,7 @@ void intel_config_init(struct drm_device *dev)
> > INIT_LIST_HEAD(&info->crtc_list);
> > INIT_LIST_HEAD(&info->connector_list);
> > INIT_LIST_HEAD(&info->plane_list);
> > +   INIT_LIST_HEAD(&info->wa_list);
> >  
> > handle = ACPI_HANDLE(dev->dev);
> > if (!handle) {
> > @@ -239,6 +240,7 @@ void intel_config_init(struct drm_device *dev)
> >  #define i915_COMPONENT_CRTC "CRTC"
> >  #define i915_COMPONENT_CONNECTOR "CNCT"
> >  #define i915_COMPONENT_PLANE "PLNS"
> > +#define i915_COMPONENT_WORKAROUND "WRKS"
> >  
> > /* Build lists */
> > list_for_each_entry(component, &info->base.adev->children, node) {
> > @@ -262,6 +264,9 @@ void intel_config_init(struct drm_device *dev)
> > if (!alloc_new_node(cl, &info->crtc_list))
> > goto bail;
> > }
> > +   } else if (strcmp(cname, i915_COMPONENT_WORKAROUND) == 0) {
> > +   if (!alloc_new_node(cl, &info->wa_list))
> > +   goto bail;
> > }
> > }
> >  
> > @@ -277,6 +282,8 @@ bail:
> > kfree(new_node);
> > list_for_each_entry_safe(new_node, tmp, &info->plane_list, node)
> > kfree(new_node);
> > +   list_for_each_entry_safe(new_node, tmp, &info->wa_list, node)
> > +   kfree(new_node);
> >  
> > kfree(info);
> > dev_priv->config_info = NULL;
> > @@ -309,6 +316,8 @@ void intel_config_shutdown(struct drm_device *dev)
> > kfree(n);
> > list_for_each_entry_safe(n, tmp, &info->plane_list, node)
> > kfree(n);
> > +   list_for_each_entry_safe(n, tmp, &info->wa_list, node)
> > +   kfree(n);
> >  
> > /* Unload any dynamically loaded ACPI property table */
> > handle = ACPI_HANDLE(dev->dev);
> > @@ -384,6 +393,8 @@ static struct list_head *cfg_type_to_list(struct 
> > intel_config_info *info,
> > return &info->connector_list;
> > case CFG_PLANE:
> > return &info->plane_list;
> > +   case CFG_WORKAROUND:
> > +   return &info->wa_list;
> > }
> > return NULL;
> >  }
> > @@ -404,7 +415,6 @@ bool intel_config_get_integer(struct drm_i915_private 
> > *dev_priv,
> > struct intel_config_info *info = dev_priv->config_info;
> > struct intel_config_node *n;

Re: [Intel-gfx] [PATCH] drm/i915: Fix frontbuffer false positve.

2015-02-24 Thread Matt Roper
On Tue, Feb 24, 2015 at 09:32:25AM -0800, Rodrigo Vivi wrote:
> On Mon, Feb 23, 2015 at 6:13 PM, Matt Roper  wrote:
> > On Mon, Feb 23, 2015 at 05:52:24PM -0800, Rodrigo Vivi wrote:
> >> Hi Daniel,
> >>
> >> It seems that one check with one good commit followed by many zeroed
> >> intel_crtc->atomic commits is again in place.
> >
> > Can you elaborate on what you mean by this?  With atomic it's possible
> > to have a check with no commit after it (if the check or prepare fail,
> > or if it's a 'test only' operation), but if you're seeing commits
> > without corresponding checks, that sounds like a bug.
> 
> Ah so yes, this is the bug, when moving a cursor we have many commits
> without checks. So it is only one check followed by many commits... so
> it commits with intel_crtc->atomic all zeroed by a previous
> finish_commit.
> 
> >
> > Can you provide a dmesg with drm.debug turned on so we can see what's
> > going on?  Or add some dump_stack()'s so that we can see the backtrace
> > that led us to this situation.
> 
> I lost those logs, but if you put one print in check and one in commit
> you also should be able to see that since I heard about this false
> positive from many people.

Hmm.  Are all of these people using a specific platform?  I only have
access to IVB hardware at the moment, so it could be that the problem
lies on codepaths I just don't exercise on my system.  Most of the
atomic stuff is pretty platform-agnostic, but maybe there's something I
overlooked.

> >
> > Actually, I wonder if the problem is actually the opposite of what you
> > say above.  Now that I look at this again, we only zero out
> > intel_crtc->atomic in intel_finish_crtc_commit which is part of the
> > commit path.
> 
> From what I heard and what I saw on the logs I thought it was ok to
> have 1 check than as many commits as possible without the check.
> If that was the case we would have a fail that is to zero the
> structure on finish_commit. But seems this isn't the case. Sorry.

I guess I should clarify terminology a little bit since this gets kind
of confusing...

For atomic, we have a top-level atomic_state structure that contains
everything that we want to update as part of an atomic transaction
(multiple planes, crtc's, etc.).  At the moment, we only support a
subset of atomic, so you'll only ever get one crtc being modified, but
there could be multiple planes (primary, cursor, 1 or more sprite
planes).  There's a sub-state structure (plane_state, crtc_state, etc.)
for each DRM object being updated.

At the top level of atomic handling we do "check" and then "commit" with
the top-level atomic state.  If you trace down through the codeflow, the
top-level check here will actually call a plane-specific check function
on each plane state during the top-level check, and then the top-level
commit function will call the plane-specific commit function on each
plane involved.

So when I say "1 or more checks, followed by exactly one commit" I'm
referring to the top-level check that deals with the top-level atomic
state.  If you're looking at the plane state specifically, you might see
more of an n:n relationship if your transaction is updating multiple
planes together (one check call per plane being updated, possibly
followed by one commit call for each of them), but the clearing of
intel_crtc->atomic should still happen at the end, after all of the
individual planes have been committed.

> > So if you had a check that never got a corresponding
> > commit, there might still be garbage left over in there.
> 
> No it is the opposite. Commits with no check. causing commit of
> intel_crtc->atomic zeroed.
> 
> > Ultimately we
> > should be handling all of this with real intel_crtc_state handling which
> > we don't quite have yet.  Maybe in the meantime we need to be clearing
> > out intel_crtc->atomic at the beginning of a top-level atomic
> > transaction?  I'll send a patch that makes this change for you to try
> > shortly.
> 
> Thanks! I thought about this but got afraid that clearing this on top
> of check could cause a race since one plane doing a check could clean
> the atomic being commited on cursor movement, unless we hat that for
> planes, but then we would have to iterate over all planes on
> finish_commit.
> 
> We can also put this patch that fix the only known issue so far with a
> FIXME comment while we don't have the final fix.

Well, based on what you say above, it sounds like it probably won't
solve your issue, so we'll need to explore some more.  I still haven't
managed to reproduce this myself, so I'm not sure whether I'm working on
a hardware platform that won't trigger the bug, or whether I'm just
unlucky.

Is there a specific igt test you've been using that triggers this
reliably for you?


Matt

> 
> >
> >
> > Matt
> >
> >>
> >> So I'm getting that annoying false positives on latest -nightly.
> >>
> >> Shouldn't we just merge this patch while atomic modeset design doesn't
> >> get fixed at all?
> >>
> >> Unf

Re: [Intel-gfx] [PATCH v2] drm/i915/skl: Make sure to allocate mininum sizes in the DDB

2015-02-24 Thread Ville Syrjälä
On Mon, Feb 09, 2015 at 01:35:10PM +, Damien Lespiau wrote:
> I overlooked the fact that we need to allocate a minimum 8 blocks and
> that just allocating the planes depending on how much they need to fetch
> from the DDB in proportion of how much memory bw is necessary for the
> whole display can lead to cases where we don't respect those minima (and
> thus overrun).
> 
> So, instead, start by allocating 8 blocks to each active display plane
> and then allocate the remaining blocks like before.
> 
> v2: Rebase on top of -nightly
> 
> Cc: Mahesh Kumar 
> Signed-off-by: Damien Lespiau 

OK after reading through the spec the minimum[] thing makes sense, so
Reviewed-by: Ville Syrjälä 

> ---
>  drivers/gpu/drm/i915/intel_pm.c | 22 ++
>  1 file changed, 18 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> index bebefe7..f6c7e53 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -2502,6 +2502,7 @@ skl_allocate_pipe_ddb(struct drm_crtc *crtc,
>   enum pipe pipe = intel_crtc->pipe;
>   struct skl_ddb_entry *alloc = &ddb->pipe[pipe];
>   uint16_t alloc_size, start, cursor_blocks;
> + uint16_t minimum[I915_MAX_PLANES];
>   unsigned int total_data_rate;
>   int plane;
>  
> @@ -2520,9 +2521,21 @@ skl_allocate_pipe_ddb(struct drm_crtc *crtc,
>   alloc_size -= cursor_blocks;
>   alloc->end -= cursor_blocks;
>  
> + /* 1. Allocate the mininum required blocks for each active plane */
> + for_each_plane(pipe, plane) {
> + const struct intel_plane_wm_parameters *p;
> +
> + p = ¶ms->plane[plane];
> + if (!p->enabled)
> + continue;
> +
> + minimum[plane] = 8;
> + alloc_size -= minimum[plane];
> + }
> +
>   /*
> -  * Each active plane get a portion of the remaining space, in
> -  * proportion to the amount of data they need to fetch from memory.
> +  * 2. Distribute the remaining space in proportion to the amount of
> +  * data each plane needs to fetch from memory.
>*
>* FIXME: we may not allocate every single block here.
>*/
> @@ -2544,8 +2557,9 @@ skl_allocate_pipe_ddb(struct drm_crtc *crtc,
>* promote the expression to 64 bits to avoid overflowing, the
>* result is < available as data_rate / total_data_rate < 1
>*/
> - plane_blocks = div_u64((uint64_t)alloc_size * data_rate,
> -total_data_rate);
> + plane_blocks = minimum[plane];
> + plane_blocks += div_u64((uint64_t)alloc_size * data_rate,
> + total_data_rate);
>  
>   ddb->plane[pipe][plane].start = start;
>   ddb->plane[pipe][plane].end = start + plane_blocks;
> -- 
> 1.8.3.1
> 
> ___
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Ville Syrjälä
Intel OTC
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH] drm/i915: Fix frontbuffer false positve.

2015-02-24 Thread Rodrigo Vivi
Atomic bits needs to be set when cursor check function is returning 0
and intel_crtc is active.

v2: When putting more debug prints I notice the solution was simpler
than I thought. AMS design is solid, just this return was wrong.
Sorry for the noise.

Cc: Matt Roper 
Signed-off-by: Rodrigo Vivi 
---
 drivers/gpu/drm/i915/intel_display.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index 8ccf033..5fb83ba 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -12198,7 +12198,7 @@ intel_check_cursor_plane(struct drm_plane *plane,
}
 
if (fb == crtc->cursor->fb)
-   return 0;
+   goto finish;
 
if (fb->modifier[0] != DRM_FORMAT_MOD_NONE) {
DRM_DEBUG_KMS("cursor cannot be tiled\n");
-- 
2.1.0

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


Re: [Intel-gfx] [RFC 09/12] drm/i915/config: Add VBT settings configuration.

2015-02-24 Thread Bob Paauwe
On Tue, 24 Feb 2015 14:57:48 +0100
Daniel Vetter  wrote:

> On Thu, Feb 12, 2015 at 03:41:35PM -0800, Bob Paauwe wrote:
> > Add a new section with subsections to the ACPI configuration table
> > that mimics much of the information typically stored in the VBT/option
> > ROM. This allows for a way to override incorrect VBT data or to provide
> > the configuration if VBT is not present.  Lack of VBT is common in
> > embedded systems.
> > 
> > Any data found in the configuration tables will replace the driver's
> > vbt structure.
> > 
> > MIPI DSI configuration is not implmemnted at this time.
> > 
> > Signed-off-by: Bob Paauwe 
> 
> I'm not too happy with the duplicate of standards this creates. Is there
> no way to just load a vbt blob into the acpi table somewhere and require
> that it perfectly matches the vbt "standard" for the given platforms,
> warts and all included?

That's actually fairly easy to do. I believe that the opregion code is
just that. So the existing vbt code in the driver does that today.  The
acpi property code can't have an opregion embedded as a property, I did
look into that, but you can still create array properties and one of
those could hold a vbt blob. Another alternative would be to have a
property array for each vbt section. 

What I was trying for here was a way to override the driver defaults
for specific settings in the case where the platform did not have an
ACPI opregion or boot firmware with a vbt table.   I wasn't really
trying to create a mechanism to create an entire vbt table.  But the
parsing of the properties does get pretty messy.

> 
> As Jani points out we already have vbt headaches, it would be good if we
> only have those once ;-)
> -Daniel

I've been trying to think of a better way but not really coming up with
something that scales well. EMGD took the approach of create
configuration for only those values that we had customer requests for.
And that was primarily just the panel power up/down timing sequence and
some backlight control. We never tried to replicate everything that
could be set via vbt.

I've also been looking at splitting up the existing vbt structure in
some way so that both the exiting vbt code and the configuration code
could be used to set component configuration.  Something like 

  set_crt_ddc_pin() in the intel_crt code that gets called by either
  (or both) the vbt parsing code or the configuration framework.

But creating set_ functions for all the existing values in
the vbt structure seems like it might be too much overhead.

Bob

> 
> > ---
> >  drivers/gpu/drm/i915/i915_dma.c |   2 +
> >  drivers/gpu/drm/i915/i915_drv.h |   1 +
> >  drivers/gpu/drm/i915/intel_config.c | 334 
> > 
> >  drivers/gpu/drm/i915/intel_drv.h|   4 +-
> >  4 files changed, 340 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/i915_dma.c 
> > b/drivers/gpu/drm/i915/i915_dma.c
> > index 9501360..9119e9b 100644
> > --- a/drivers/gpu/drm/i915/i915_dma.c
> > +++ b/drivers/gpu/drm/i915/i915_dma.c
> > @@ -852,6 +852,8 @@ int i915_driver_load(struct drm_device *dev, unsigned 
> > long flags)
> > if (intel_vgpu_active(dev))
> > I915_WRITE(vgtif_reg(display_ready), VGT_DRV_DISPLAY_READY);
> >  
> > +   intel_config_vbt(dev_priv);
> > +
> > i915_setup_sysfs(dev);
> >  
> > if (INTEL_INFO(dev)->num_pipes) {
> > diff --git a/drivers/gpu/drm/i915/i915_drv.h 
> > b/drivers/gpu/drm/i915/i915_drv.h
> > index 1580702..a60511e 100644
> > --- a/drivers/gpu/drm/i915/i915_drv.h
> > +++ b/drivers/gpu/drm/i915/i915_drv.h
> > @@ -1657,6 +1657,7 @@ struct intel_config_info {
> > struct list_head connector_list;
> > struct list_head plane_list;
> > struct list_head wa_list;
> > +   struct list_head vbt_list;
> >  };
> >  
> >  
> > diff --git a/drivers/gpu/drm/i915/intel_config.c 
> > b/drivers/gpu/drm/i915/intel_config.c
> > index ab14928..c1b06b7 100644
> > --- a/drivers/gpu/drm/i915/intel_config.c
> > +++ b/drivers/gpu/drm/i915/intel_config.c
> > @@ -215,6 +215,7 @@ void intel_config_init(struct drm_device *dev)
> > INIT_LIST_HEAD(&info->connector_list);
> > INIT_LIST_HEAD(&info->plane_list);
> > INIT_LIST_HEAD(&info->wa_list);
> > +   INIT_LIST_HEAD(&info->vbt_list);
> >  
> > handle = ACPI_HANDLE(dev->dev);
> > if (!handle) {
> > @@ -241,6 +242,7 @@ void intel_config_init(struct drm_device *dev)
> >  #define i915_COMPONENT_CONNECTOR "CNCT"
> >  #define i915_COMPONENT_PLANE "PLNS"
> >  #define i915_COMPONENT_WORKAROUND "WRKS"
> > +#define i915_COMPONENT_VBIOSTABLE "VBT"
> >  
> > /* Build lists */
> > list_for_each_entry(component, &info->base.adev->children, node) {
> > @@ -267,6 +269,18 @@ void intel_config_init(struct drm_device *dev)
> > } else if (strcmp(cname, i915_COMPONENT_WORKAROUND) == 0) {
> > if (!alloc_new_node(cl, &info->wa_list))
> > goto bail;
> > +   } else if (strcmp(

Re: [Intel-gfx] [PATCH 6/7] drm/i915/skl: Update watermarks for Y tiling

2015-02-24 Thread Damien Lespiau
On Mon, Feb 23, 2015 at 03:56:00PM +, Tvrtko Ursulin wrote:
> From: Tvrtko Ursulin 
> 
> Display watermarks need different programming for different tiling
> modes.
> 
> Set the relevant flag so this happens during the plane commit and
> add relevant data into a structure made available to the watermark
> computation code.
> 
> v2: Pass in tiling info to sprite plane updates as well.
> v3: Rebased for plane handling changes.
> v4: Handle fb == NULL when plane is disabled.
> v5: Refactored for addfb2 interface.
> v6: Refactored for fb modifier changes.
> v7: Updated for atomic commit by only updating watermarks when tiling changes.
> 
> Signed-off-by: Tvrtko Ursulin 
> Acked-by: Ander Conselvan de Oliveira 
> Acked-by: Matt Roper 
> ---
>  drivers/gpu/drm/i915/intel_display.c |  6 ++
>  drivers/gpu/drm/i915/intel_drv.h |  1 +
>  drivers/gpu/drm/i915/intel_pm.c  | 33 -
>  drivers/gpu/drm/i915/intel_sprite.c  |  6 ++
>  4 files changed, 41 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_display.c 
> b/drivers/gpu/drm/i915/intel_display.c
> index c622b11..74d4923 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -11985,6 +11985,12 @@ intel_check_primary_plane(struct drm_plane *plane,
>   INTEL_FRONTBUFFER_PRIMARY(intel_crtc->pipe);
>  
>   intel_crtc->atomic.update_fbc = true;
> +
> + /* Update watermarks on tiling changes. */
> + if (!plane->state->fb || !state->base.fb ||
> + plane->state->fb->modifier[0] !=
> + state->base.fb->modifier[0])
> + intel_crtc->atomic.update_wm = true;
>   }
>  
>   return 0;
> diff --git a/drivers/gpu/drm/i915/intel_drv.h 
> b/drivers/gpu/drm/i915/intel_drv.h
> index 399d2b2..b124548 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -501,6 +501,7 @@ struct intel_plane_wm_parameters {
>   uint8_t bytes_per_pixel;
>   bool enabled;
>   bool scaled;
> + u64 tiling;
>  };
>  
>  struct intel_plane {
> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> index f7c9938..006e635 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -2662,6 +2662,7 @@ static void skl_compute_wm_pipe_parameters(struct 
> drm_crtc *crtc,
>   struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
>   enum pipe pipe = intel_crtc->pipe;
>   struct drm_plane *plane;
> + struct drm_framebuffer *fb;
>   int i = 1; /* Index for sprite planes start */
>  
>   p->active = intel_crtc_active(crtc);
> @@ -2677,6 +2678,14 @@ static void skl_compute_wm_pipe_parameters(struct 
> drm_crtc *crtc,
>   crtc->primary->fb->bits_per_pixel / 8;
>   p->plane[0].horiz_pixels = intel_crtc->config->pipe_src_w;
>   p->plane[0].vert_pixels = intel_crtc->config->pipe_src_h;
> + p->plane[0].tiling = DRM_FORMAT_MOD_NONE;
> + fb = crtc->primary->fb;
> + /*
> +  * Framebuffer can be NULL on plane disable, but it does not
> +  * matter for watermarks if we assume no tiling in that case.
> +  */
> + if (fb)
> + p->plane[0].tiling = fb->modifier[0];
>  
>   p->cursor.enabled = true;
>   p->cursor.bytes_per_pixel = 4;
> @@ -2702,6 +2711,7 @@ static bool skl_compute_plane_wm(struct 
> skl_pipe_wm_parameters *p,
>  {
>   uint32_t method1, method2, plane_bytes_per_line, res_blocks, res_lines;
>   uint32_t result_bytes;
> + uint32_t y_tile_minimum;
>  
>   if (mem_value == 0 || !p->active || !p_params->enabled)
>   return false;
> @@ -2718,11 +2728,16 @@ static bool skl_compute_plane_wm(struct 
> skl_pipe_wm_parameters *p,
>   plane_bytes_per_line = p_params->horiz_pixels *
>   p_params->bytes_per_pixel;
>  
> - /* For now xtile and linear */
> - if (((ddb_allocation * 512) / plane_bytes_per_line) >= 1)
> - result_bytes = min(method1, method2);
> - else
> - result_bytes = method1;
> + if (p_params->tiling == I915_FORMAT_MOD_Y_TILED ||
> + p_params->tiling == I915_FORMAT_MOD_Yf_TILED) {
> + y_tile_minimum = plane_bytes_per_line * 4;
> + result_bytes = max(method2, y_tile_minimum);
> + } else {
> + if (((ddb_allocation * 512) / plane_bytes_per_line) >= 1)
> + result_bytes = min(method1, method2);
> + else
> + result_bytes = method1;
> + }

While this was what was documented at some point, it's not anymore.
Would need an extra patch before this one to introduce
plane_blocks_per_line and then this one on top.

>  
>   res_blocks = DIV_ROUND_UP(result_bytes, 512) + 1;
>   res_lin

Re: [Intel-gfx] [PATCH 7/7] drm/i915/skl: Allow Y (and Yf) frame buffer creation

2015-02-24 Thread Damien Lespiau
On Mon, Feb 23, 2015 at 03:56:01PM +, Tvrtko Ursulin wrote:
> From: Tvrtko Ursulin 
> 
> By this patch all underlying bits have been implemented and this
> patch actually enables the feature.
> 
> Signed-off-by: Tvrtko Ursulin 
> ---

Ville noticed that it didn't seem we were properly returning -EINVAL
when userspace sets reserved bits in the modifiers field. Otherwise,
what's here seems to progress in the right direction:

Reviewed-by: Damien Lespiau 

-- 
Damien

>  drivers/gpu/drm/i915/intel_display.c | 13 -
>  1 file changed, 8 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_display.c 
> b/drivers/gpu/drm/i915/intel_display.c
> index 74d4923..f100086 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -12781,6 +12781,14 @@ static int intel_framebuffer_init(struct drm_device 
> *dev,
>   DRM_DEBUG("tiling_mode doesn't match fb modifier\n");
>   return -EINVAL;
>   }
> +
> + if (INTEL_INFO(dev)->gen < 9 &&
> + (mode_cmd->modifier[0] == I915_FORMAT_MOD_Y_TILED ||
> +  mode_cmd->modifier[0] == I915_FORMAT_MOD_Yf_TILED)) {
> + DRM_DEBUG("Unsupported tiling 0x%llx!\n",
> +   mode_cmd->modifier[0]);
> + return -EINVAL;
> + }
>   } else {
>   if (obj->tiling_mode == I915_TILING_X)
>   mode_cmd->modifier[0] = I915_FORMAT_MOD_X_TILED;
> @@ -12790,11 +12798,6 @@ static int intel_framebuffer_init(struct drm_device 
> *dev,
>   }
>   }
>  
> - if (mode_cmd->modifier[0] == I915_FORMAT_MOD_Y_TILED) {
> - DRM_DEBUG("hardware does not support tiling Y\n");
> - return -EINVAL;
> - }
> -
>   stride_alignment = intel_fb_stride_alignment(dev, mode_cmd->modifier[0],
>mode_cmd->pixel_format);
>   if (mode_cmd->pitches[0] & (stride_alignment - 1)) {
> -- 
> 2.3.0
> 
> ___
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH v2] lib/igt_kms.c: remove tests dependency on VT /dev/tty0

2015-02-24 Thread Marc Herbert
Required to run on any recent, freon-based and X11-free ChromeOS release.

Signed-off-by: Marc Herbert 
---

Changes from v1:
- igt_debug() instead of igt_warn()
- return KD_GRAPHICS instead of -1UL
- print previous mode in debug statements. Among others this help a tiny
  bit with the now confusing debug output ("cannot change" immediately
  followed by a misleading "mode changed").

Note: a naive "mv /dev/tty0 /dev/tty0.orig" is typically enough to test
this patch.

 lib/igt_kms.c | 22 ++
 1 file changed, 18 insertions(+), 4 deletions(-)

diff --git a/lib/igt_kms.c b/lib/igt_kms.c
index d0c3690..9c131f0 100644
--- a/lib/igt_kms.c
+++ b/lib/igt_kms.c
@@ -299,12 +299,26 @@ int kmstest_get_pipe_from_crtc_id(int fd, int crtc_id)
return pfci.pipe;
 }
 
+/*
+ * Returns: the previous mode, or KD_GRAPHICS if no /dev/tty0 was
+ * found and nothing was done.
+ */
 static signed long set_vt_mode(unsigned long mode)
 {
int fd;
unsigned long prev_mode;
+   static const char TTY0[] = "/dev/tty0";
+
+   if (access(TTY0, F_OK)) {
+   /* errno message should be "No such file". Do not
+  hardcode but ask strerror() in the very unlikely
+  case something else happened. */
+   igt_debug("VT: %s: %s, cannot change its mode\n",
+ TTY0, strerror(errno));
+   return KD_GRAPHICS;
+   }
 
-   fd = open("/dev/tty0", O_RDONLY);
+   fd = open(TTY0, O_RDONLY);
if (fd < 0)
return -errno;
 
@@ -336,10 +350,10 @@ void kmstest_restore_vt_mode(void)
 
if (orig_vt_mode != -1UL) {
ret = set_vt_mode(orig_vt_mode);
-   orig_vt_mode = -1UL;
 
igt_assert(ret >= 0);
-   igt_debug("VT: original mode restored\n");
+   igt_debug("VT: original mode 0x%lx restored\n", orig_vt_mode);
+   orig_vt_mode = -1UL;
}
 }
 
@@ -366,7 +380,7 @@ void kmstest_set_vt_graphics_mode(void)
igt_assert(ret >= 0);
orig_vt_mode = ret;
 
-   igt_debug("VT: graphics mode set\n");
+   igt_debug("VT: graphics mode set (mode was 0x%lx)\n", ret);
 }
 
 
-- 
1.9.3

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


Re: [Intel-gfx] [PATCH v6 00/32] PPGTT dynamic page allocations and 48b addressing

2015-02-24 Thread Daniel Vetter
On Tue, Feb 24, 2015 at 04:22:33PM +, Michel Thierry wrote:
> This patchset addresses comments from v5 by Mika, specially some rename 
> changes
> touched several patches.
> 
> For GEN8, it has also been extended to work in logical ring submission (lrc)
> mode, as it will be the preferred mode of operation.
> I also tried to update the lrc code at the same time the ppgtt refactoring
> occurred, leaving only one patch that is exclusively for lrc.
> 
> I'm also now including the required patches for PPGTT with 48b addressing.
> In order expand the GPU address space, a 4th level translation is added, the
> Page Map Level 4 (PML4). This PML4 has 256 PML4 Entries (PML4E), PML4[0-255],
> each pointing to a PDP.
> 
> For now, this feature will only be available in BDW and GEN9, in LRC 
> submission
> mode (execlists) and when i915.enable_ppgtt=3 is set.
> Also note that this expanded address space is only available for full PPGTT,
> aliasing PPGTT remains 32b.
> 
> This list can be seen in 3 parts:
> [01-10] Add page table allocation for GEN6/GEN7
> [11-20] Enable dynamic allocation in GEN8,for both legacy and
> execlist submission modes.
> [21-32] PML4 support in BDW and GEN9+.
> 
> Ben Widawsky (26):
>   drm/i915: page table abstractions
>   drm/i915: Complete page table structures
>   drm/i915: Create page table allocators
>   drm/i915: Track GEN6 page table usage
>   drm/i915: Extract context switch skip and pd load logic
>   drm/i915: Track page table reload need
>   drm/i915: Initialize all contexts
>   drm/i915: Finish gen6/7 dynamic page table allocation
>   drm/i915/bdw: Use dynamic allocation idioms on free
>   drm/i915/bdw: page directories rework allocation
>   drm/i915/bdw: pagetable allocation rework
>   drm/i915/bdw: Update pdp switch and point unused PDPs to scratch page
>   drm/i915: num_pd_pages/num_pd_entries isn't useful
>   drm/i915: Extract PPGTT param from page_directory alloc
>   drm/i915/bdw: Split out mappings
>   drm/i915/bdw: begin bitmap tracking
>   drm/i915/bdw: Dynamic page table allocations
>   drm/i915/bdw: Make pdp allocation more dynamic
>   drm/i915/bdw: Abstract PDP usage
>   drm/i915/bdw: Add dynamic page trace events
>   drm/i915/bdw: Add ppgtt info for dynamic pages
>   drm/i915/bdw: implement alloc/free for 4lvl
>   drm/i915/bdw: Add 4 level switching infrastructure
>   drm/i915/bdw: Generalize PTE writing for GEN8 PPGTT
>   drm/i915: Plumb sg_iter through va allocation ->maps
>   drm/i915: Expand error state's address width to 64b
> 
> Michel Thierry (6):
>   drm/i915: Plumb drm_device through page tables operations
>   drm/i915: Add dynamic page trace events
>   drm/i915/bdw: Support dynamic pdp updates in lrc mode
>   drm/i915/bdw: Support 64 bit PPGTT in lrc mode
>   drm/i915/bdw: Add 4 level support in insert_entries and clear_range
>   drm/i915/bdw: Flip the 48b switch

When just a few patches changed (which I suspect is the case here) please
don't resend the entire series, but only resend the individual patches
in-reply-to their earlier versions.

Resending the entire series too often tends to split up the discussions
between multiple threads, so should be used cautiously. My approach is
that I don't resend the entire series except when all the patches have
changed. And I only resend when the review round has reached a conclusion.
While the review is ongoing doing incremental updates of the series is imo
much better.

But when resending the entire series, please start a new thread. Otherwise
it again starts to become unclear which versions of which patches go
together.

And a quick aside if you fear that a patch causes subsequent patches to no
longer apply without a rebase: I can deal with a lot of small conflicts
quickly when merging. And if that doesn't cut it I'll just ask for a
resend when needed.

Just a quick reminder of patch resending bkms, intel-gfx is a really busy
place so everyone needs to strive for best signal/noise ratio.

Thanks, 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: Fix frontbuffer false positve.

2015-02-24 Thread Daniel Vetter
On Tue, Feb 24, 2015 at 10:44:19AM -0800, Matt Roper wrote:
> On Tue, Feb 24, 2015 at 10:36:32AM -0800, Rodrigo Vivi wrote:
> > Atomic bits needs to be set when cursor check function is returning 0
> > and intel_crtc is active.
> > 
> > v2: When putting more debug prints I notice the solution was simpler
> > than I thought. AMS design is solid, just this return was wrong.
> > Sorry for the noise.
> > 
> > Cc: Matt Roper 
> > Signed-off-by: Rodrigo Vivi 
> 
> Reviewed-by: Matt Roper 
> 
> > ---
> >  drivers/gpu/drm/i915/intel_display.c | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/intel_display.c 
> > b/drivers/gpu/drm/i915/intel_display.c
> > index 8ccf033..5fb83ba 100644
> > --- a/drivers/gpu/drm/i915/intel_display.c
> > +++ b/drivers/gpu/drm/i915/intel_display.c
> > @@ -12198,7 +12198,7 @@ intel_check_cursor_plane(struct drm_plane *plane,
> > }
> >  
> > if (fb == crtc->cursor->fb)
> > -   return 0;
> > +   goto finish;

Shouldn't we just delete this check entirely? gcc will do it anyway for
us. When you do that you can also append the history I've dug out for
this.

The original regression seems to have been introduced in the original
check/commit split:

commit 757f9a3e5b8a812af0c213099a5b31cb423f4d3c
Author: Gustavo Padovan 
Date:   Wed Sep 24 14:20:24 2014 -0300

drm/i915: move check of intel_crtc_cursor_set_obj() out

Which already cause other trouble, resulting in the check getting moved in

commit e391ea882b1a04fb3f559287ac694652a3cd9da9
Author: Gustavo Padovan 
Date:   Wed Sep 24 14:20:25 2014 -0300

drm/i915: Fix not checking cursor and object sizes

The frontbuffer tracking itself only was broken when we shifted it into
the check/commit logic with:

commit 32b7eeec4d1e861230b09d437e95d76c86ff4a68
Author: Matt Roper 
Date:   Wed Dec 24 07:59:06 2014 -0800

drm/i915: Refactor work that can sleep out of commit (v7)

Cheers, Daniel
> >  
> > if (fb->modifier[0] != DRM_FORMAT_MOD_NONE) {
> > DRM_DEBUG_KMS("cursor cannot be tiled\n");
> > -- 
> > 2.1.0
> > 
> 
> -- 
> Matt Roper
> Graphics Software Engineer
> IoTG Platform Enabling & Development
> Intel Corporation
> (916) 356-2795
> ___
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
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 2/7] drm/i915/skl: Updated the gen6_set_rps function

2015-02-24 Thread Daniel Vetter
On Tue, Feb 24, 2015 at 03:22:54PM +, Damien Lespiau wrote:
> On Wed, Feb 18, 2015 at 07:31:11PM +0530, akash.g...@intel.com wrote:
> > From: Akash Goel 
> > 
> > On SKL, the frequency programmed in RPNSWREQ (A008) register
> > has to be in units of 16.66 MHZ. So updated the gen6_set_rps
> > function, as per this change.
> > 
> > Signed-off-by: Akash Goel 
> > Reviewed-by: Lespiau, Damien 
> 
> Please don't use the Outlook way "lastname, firstname" here :)

Another one: r-b tags should be treated like signatures and only perfectly
copypasted. Writing your own is considered forgery ;-) Just another reason
to use exactly the string provided.

So same strict rules as with sob really.

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


[Intel-gfx] [BISECTED REGRESSION v3.18->v3.19-rc1] drm/i915: failure to poweroff after hibernation

2015-02-24 Thread Bjørn Mork
Hello,

My Lenovo Thinkpad X301 has failed to power off after saving the
hibernation image ever since v3.19-rc1.  This is a regression since
v3.18.  The regression is still present i v4.0-rc1.

The symptoms are: Hibernation proceeds as usual, writing a complete
image. But instead of powering off the laptop stays on in a "dead"
state, with fans running and the "sleep" LED blinking.  The only way out
of this state is by hard poweroff (pressing the power button for 4+
seconds). The system can successfully resume after this, proving that
the hibernation was complete.

I consider the bug somewhat critical as the system will continue to draw
power until it is forcibly powered off, or the battery is completely
dead. This causes unexpected battery usage and unnecessary battery wear
if the power-off failure goes unnoticed.

I finally took the time to bisect the problem, and ended up with this
surprisingly obvious result:

da2bc1b9db3351addd293e5b82757efe1f77ed1d is the first bad commit
commit da2bc1b9db3351addd293e5b82757efe1f77ed1d
Author: Imre Deak 
Date:   Thu Oct 23 19:23:26 2014 +0300

drm/i915: add poweroff_late handler

The suspend_late handler saves some registers and powers off the device,
so it doesn't have a big overhead. Calling it at S4 poweroff_late time
makes the power off handling identical to the S3 suspend and S4 freeze
handling, so do this for consistency.

Signed-off-by: Imre Deak 
Reviewed-by: Ville Syrjälä 
Signed-off-by: Daniel Vetter 

:04 04 367eee899c6c2b2a669e2e46f68529dad0e1f7a3 
78c7571e2b18dc0fb77161b8a3e32288bd4cbee8 M  drivers


The bisect log was:

# bad: [97bf6af1f928216fd6c5a66e8a57bfa95a659672] Linux 3.19-rc1
# good: [b2776bf7149bddd1f4161f14f79520f17fc1d71d] Linux 3.18
git bisect start 'v3.19-rc1' 'v3.18'
# good: [70e71ca0af244f48a5dcf56dc435243792e3a495] Merge 
git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next
git bisect good 70e71ca0af244f48a5dcf56dc435243792e3a495
# bad: [988adfdffdd43cfd841df734664727993076d7cb] Merge branch 'drm-next' of 
git://people.freedesktop.org/~airlied/linux
git bisect bad 988adfdffdd43cfd841df734664727993076d7cb
# good: [e7cf773d431a63a2417902696fcc9e0ebdc83bbe] Merge tag 'usb-3.19-rc1' of 
git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb
git bisect good e7cf773d431a63a2417902696fcc9e0ebdc83bbe
# bad: [1a92b7a241dcf06a92d84219b4124dcf420ae315] Merge branch 'linux-3.19' of 
git://anongit.freedesktop.org/git/nouveau/linux-2.6 into drm-next
git bisect bad 1a92b7a241dcf06a92d84219b4124dcf420ae315
# bad: [fd172d0c47fddff801d998e38c3efdd236ed082f] Merge tag 
'drm-intel-next-2014-11-07-fixups' of git://anongit.freedesktop.org/drm-intel 
into drm-next
git bisect bad fd172d0c47fddff801d998e38c3efdd236ed082f
# bad: [820d2d77482810702758381808bdbb64595298e2] drm/i915/audio: pass 
intel_encoder on to platform specific ELD functions
git bisect bad 820d2d77482810702758381808bdbb64595298e2
# good: [11c9b6c628c646894e6ef53f92cfd33a814ee553] drm/i915: Tighting 
frontbuffer tracking around flips
git bisect good 11c9b6c628c646894e6ef53f92cfd33a814ee553
# good: [0b14cbd2f58199a024acbe2994bb27533c97d756] drm/i915: remove dead code 
from legacy suspend handler
git bisect good 0b14cbd2f58199a024acbe2994bb27533c97d756
# good: [f4a12ead50580c17c3641ac1a453e68b5a5195dd] drm/i915: remove unused 
restore_gtt_mappings optimization during suspend
git bisect good f4a12ead50580c17c3641ac1a453e68b5a5195dd
# bad: [aff437667b93c3d65576b02628885687c72e1b3b] drm/i915: Move flags 
describing VMA mappings into the VMA
git bisect bad aff437667b93c3d65576b02628885687c72e1b3b
# bad: [da2bc1b9db3351addd293e5b82757efe1f77ed1d] drm/i915: add poweroff_late 
handler
git bisect bad da2bc1b9db3351addd293e5b82757efe1f77ed1d
# good: [f2476ae65e6159b41168bc41c630e9fbb1d72dde] drm/i915: disable/re-enable 
PCI device around S4 freeze/thaw
git bisect good f2476ae65e6159b41168bc41c630e9fbb1d72dde
# good: [5e365c391aeffe8b53d6952c28a68bd5fc856390] drm/i915: sanitize 
suspend/resume helper function names
git bisect good 5e365c391aeffe8b53d6952c28a68bd5fc856390


My rather old system has a GM45 chip, but I would expect the bug to
show up on most (all?) i915 systems:


nemi:/tmp# lspci -vvvnns 2
00:02.0 VGA compatible controller [0300]: Intel Corporation Mobile 4 Series 
Chipset Integrated Graphics Controller [8086:2a42] (rev 07) (prog-if 00 [VGA 
controller])
Subsystem: Lenovo Device [17aa:20e4]
Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- 
Stepping- SERR- FastB2B- DisINTx+
Status: Cap+ 66MHz- UDF- FastB2B+ ParErr- DEVSEL=fast >TAbort- SERR-  [disabled]
Capabilities: [90] MSI: Enable+ Count=1/1 Maskable- 64bit-
Address: fee0100c  Data: 41c2
Capabilities: [d0] Power Management version 3
Flags: PMEClk- DSI+ D1- D2- AuxCurrent=0mA 
PME(D0-,D1-,D2-,D3hot-,D3cold-)
Status: D0 NoSoftRst- PME-Enable- DSel=0 DScale=0 PME-
Kernel

Re: [Intel-gfx] [PATCH] drm: Fix deadlock due to getconnector locking changes

2015-02-24 Thread Marc Finet
On Sun, Feb 22, 2015 at 11:38:36AM +0100, Daniel Vetter wrote:
> In
> 
> daniel@phenom:~/linux/src$ git show ccfc08655
> commit ccfc08655d5fd5076828f45fb09194c070f2f63a
> Author: Rob Clark 
> Date:   Thu Dec 18 16:01:48 2014 -0500
> 
> drm: tweak getconnector locking
> 
> We need to extend the locking to cover connector->state reading for
> atomic drivers, but the above commit was a bit too eager and also
> included the fill_modes callback. Which on i915 on old platforms using
> load detection needs to acquire modeset locks, resulting in a deadlock
> on output probing.
> 
> Reported-by: Marc Finet 
> Cc: Marc Finet 
> Cc: robdcl...@gmail.com
> Signed-off-by: Daniel Vetter 

Tested-by: Marc Finet 

Thanks.
> ---
>  drivers/gpu/drm/drm_crtc.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
> index b15d720eda4c..ce5f1193ecd6 100644
> --- a/drivers/gpu/drm/drm_crtc.c
> +++ b/drivers/gpu/drm/drm_crtc.c
> @@ -2180,7 +2180,6 @@ int drm_mode_getconnector(struct drm_device *dev, void 
> *data,
>   DRM_DEBUG_KMS("[CONNECTOR:%d:?]\n", out_resp->connector_id);
>  
>   mutex_lock(&dev->mode_config.mutex);
> - drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
>  
>   connector = drm_connector_find(dev, out_resp->connector_id);
>   if (!connector) {
> @@ -2210,6 +2209,8 @@ int drm_mode_getconnector(struct drm_device *dev, void 
> *data,
>   out_resp->mm_height = connector->display_info.height_mm;
>   out_resp->subpixel = connector->display_info.subpixel_order;
>   out_resp->connection = connector->status;
> +
> + drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
>   encoder = drm_connector_get_encoder(connector);
>   if (encoder)
>   out_resp->encoder_id = encoder->base.id;
> -- 
> 2.1.4
> 
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH] drm/i915: fix failure to power off after hibernate

2015-02-24 Thread Bjørn Mork
Imre Deak  writes:

> The poweroff handlers undo the actions of the thaw handlers. As the
> original commit stated saving the registers is not needed there, but
> it's also not a big overhead and there should be no problem doing it. We
> are planning to optimize the hibernation sequence by for example not
> shutting down the display between freeze and thaw, and also getting rid
> of unnecessary steps at the power off phase. But before that we want to
> actually unify things rather than having special cases, as maintaining
> the special code paths caused already quite a lot of problems for us so
> far.

That sounds like a worthy goal.  I don't understand what you hope to
achieve by having a poweroff_late hook, since there aren't really
anything useful left to do at the point it is called, but if you want a
dummy callback there for code structure reasons then fine.

But you cannot just run around breaking stuff while slowly moving
towards this goal over multiple releases... v3.19 is currently broken
and that seems totally unnecessary.

In any case: You should have noticed this problem while testing your
patches.  The breakage is 100% reproducible. Unfortunately I had to do a
bisect to realize what you had done to the i915 driver, something I
unfortunately didn't find time to do before v3.19 was released.  But I
do find it unnecessary to release with such bugs.  Any attempt to
exercise the code path you modified would have revealed the bug.


> Reverting the commit may hide some other issue, so before doing that
> could you try the following patch:
> http://lists.freedesktop.org/archives/intel-gfx/2015-February/060529.html

Makes no difference.  I assume that patch fixes an unrelated bug? The
age and reported symptoms indicates so.  Note that I am reporting a
regression introduced after v3.18, while that seems to fix a bug
introduced in v3.17. Both v3.17 and v3.18 (including v3.18.6), as
well as earlier releases, work fine for me.

> If with that you still get the hang could you try on top of that the
> patch below, first having only pci_set_power_state uncommented, then
> both pci_set_power_state and pci_disable_device uncommented?

That patch fixes the problem, with only pci_set_power_state commented
out.  Do you still want me to try with pci_disable_device() commented
out as well?



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


Re: [Intel-gfx] [KERNEL] Re: [KERNEL] Regression bug in drm/i915, Wrong assumption in commit e11aa36 breaks suspend on at least lenovo x61

2015-02-24 Thread Klaus Ethgen
-BEGIN PGP SIGNED MESSAGE-
Hash: SHA512

Hi,

Am Mi den 18. Feb 2015 um 16:39 schrieb Jani Nikula:
> On Tue, 17 Feb 2015, Klaus Ethgen  wrote:
> > After solving  the conflicts, I applied the revert (see attachment) to
> > v3.18.7. I think it should also apply to the current head. With that
> > patch, suspend is working again on that version.
> >
> > However, I have not to deep knowledge of that subsystem, so please,
> > someone who have, have a deeper look into it. I especially do not know
> > if the lines in .../intel_pm.c are correct or better leaving them as
> > they are in v3.18.7.
> >
> > I want to have it working on a version that I know is stable before
> > asking to pull it to head.
> 
> Hi Klaus, we fear this patch may hide the actual cause.

That might be. But that might be a second step, to find the actual
cause. I think first the patch that causes the problem should be
fixed/reverted to have a working kernel and the next step would be to
find the real cause.

I would happily help to solve both.

> Would be useful to get a better description of what happens,

Ask.. English is not my mother thong and I am not that good in finding
descriptions. ;-)

> along with a dmesg with drm.debug=14 module parameter set.

Oh, I would be happy to be able to provide that. But if you look at the
first mail in this thread, I asked days before how to debug that cause.
The problem is that it stops in the middle of the suspend right after
switching of screen. There is no way to get it back working after that
and so no dmesg. I have to hard switch off the laptop after that.

> This might clutter the mailing list, would you mind filing a bug at
> [1] and attach the info there?

One another account to just fill one bug? Or is there a way to fill the
bug without creating an account? I would really like to not create
another account. I still have that many from systems that forced me to
create an account for just one bug report.

Am Mi den 18. Feb 2015 um 17:24 schrieb Imre Deak:
> In addition to the above could you also try the following patch and
> provide a dmesg log on the bugzilla ticket - at this point only to try
> to narrow down the issue?:
> 
[PATCH]

Yes, I can do that. But can you tell me how to get dmesg output when the
problem happened? After that the box is unusable and I have to hard
switch off it. There is no way to get any dmesg output after the bug
happened.

Regards
   Klaus

Ps. I can forward the first two messages that I posted on kernel ML.
That should also be available online.
- -- 
Klaus Ethgen  http://www.ethgen.ch/
pub  4096R/4E20AF1C 2011-05-16   Klaus Ethgen 
Fingerprint: 85D4 CA42 952C 949B 1753  62B3 79D0 B06F 4E20 AF1C
-BEGIN PGP SIGNATURE-
Version: GnuPG v1

iQGcBAEBCgAGBQJU5OIMAAoJEKZ8CrGAGfas/MUL/1EYB/BKzdXl2JKyktSqt/TF
ojXfGKXF6RPYukwIU4+ACXUVGWyZ2llWetbNxrP48MBjBHvXfPLUG0FcxagtE8hH
yw61xt3uhO6YPso4fBBZfaCeiU2A5sO3RDb5yQ9kKdpK1GkrCQoG1VsQRKDFZGdl
99dEXQ4mMFMv27HR22YKtVnqW+Iwzdifu3NcdVw7ioqfZrMlRJSPmJQpJ7avfqFO
qQzTOv9tFC2G29j6K1J4IeDRd5uagE/IoMQWMF1hvDJlx9iSr6dHSbq/7hZ6aOKZ
nVWJ8mF5VB8ReqwI6j+akP+SgShCSG1HqdBJ57/Z2ygDys1N4Yr2EzJ1Ee8qyYp/
ibjwTbCfNKR4Ugq95WY8Dhpr9nUXDB+0pyVYjLvUABkkguDchQeQdUkY50IUodVh
82QkGoATJx+CLY7o+xNRj0W8m/e/VuSMPiJwxwNgJbmipPgG0JhlptRCO5Go8VCA
woyPNWdaiLriPIo19mr2NTK8BlV2pT2HD6D7ehlJ7Q==
=CE8V
-END PGP SIGNATURE-
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH] drm/i915: Fix frontbuffer false positve.

2015-02-24 Thread Rodrigo Vivi
This return 0 without setting atomic bits on fb == crtc->cursor->fb
where causing frontbuffer false positives.

According to Daniel:

The original regression seems to have been introduced in the original
check/commit split:

commit 757f9a3e5b8a812af0c213099a5b31cb423f4d3c
Author: Gustavo Padovan 
Date:   Wed Sep 24 14:20:24 2014 -0300

drm/i915: move check of intel_crtc_cursor_set_obj() out

Which already cause other trouble, resulting in the check getting moved in

commit e391ea882b1a04fb3f559287ac694652a3cd9da9
Author: Gustavo Padovan 
Date:   Wed Sep 24 14:20:25 2014 -0300

drm/i915: Fix not checking cursor and object sizes

The frontbuffer tracking itself only was broken when we shifted it into
the check/commit logic with:

commit 32b7eeec4d1e861230b09d437e95d76c86ff4a68
Author: Matt Roper 
Date:   Wed Dec 24 07:59:06 2014 -0800

drm/i915: Refactor work that can sleep out of commit (v7)

v2: When putting more debug prints I notice the solution was simpler
than I thought. AMS design is solid, just this return was wrong.
Sorry for the noise.

v3: Remove the entire chunck that would probably
be removed by gcc anyway. (by Daniel)

Cc: Jani Nikula 
Cc: Gustavo Padovan 
Cc: Matt Roper 
Signed-off-by: Rodrigo Vivi 
---
 drivers/gpu/drm/i915/intel_display.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index 8ccf033..900dcaa 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -12197,9 +12197,6 @@ intel_check_cursor_plane(struct drm_plane *plane,
return -ENOMEM;
}
 
-   if (fb == crtc->cursor->fb)
-   return 0;
-
if (fb->modifier[0] != DRM_FORMAT_MOD_NONE) {
DRM_DEBUG_KMS("cursor cannot be tiled\n");
ret = -EINVAL;
-- 
2.1.0

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


Re: [Intel-gfx] [PATCH 6/7] drm/i915/skl: Update watermarks for Y tiling

2015-02-24 Thread Daniel Vetter
On Mon, Feb 23, 2015 at 03:56:00PM +, Tvrtko Ursulin wrote:
> From: Tvrtko Ursulin 
> 
> Display watermarks need different programming for different tiling
> modes.
> 
> Set the relevant flag so this happens during the plane commit and
> add relevant data into a structure made available to the watermark
> computation code.
> 
> v2: Pass in tiling info to sprite plane updates as well.
> v3: Rebased for plane handling changes.
> v4: Handle fb == NULL when plane is disabled.
> v5: Refactored for addfb2 interface.
> v6: Refactored for fb modifier changes.
> v7: Updated for atomic commit by only updating watermarks when tiling changes.
> 
> Signed-off-by: Tvrtko Ursulin 
> Acked-by: Ander Conselvan de Oliveira 
> Acked-by: Matt Roper 
> ---
>  drivers/gpu/drm/i915/intel_display.c |  6 ++
>  drivers/gpu/drm/i915/intel_drv.h |  1 +
>  drivers/gpu/drm/i915/intel_pm.c  | 33 -
>  drivers/gpu/drm/i915/intel_sprite.c  |  6 ++
>  4 files changed, 41 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_display.c 
> b/drivers/gpu/drm/i915/intel_display.c
> index c622b11..74d4923 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -11985,6 +11985,12 @@ intel_check_primary_plane(struct drm_plane *plane,
>   INTEL_FRONTBUFFER_PRIMARY(intel_crtc->pipe);
>  
>   intel_crtc->atomic.update_fbc = true;
> +
> + /* Update watermarks on tiling changes. */
> + if (!plane->state->fb || !state->base.fb ||
> + plane->state->fb->modifier[0] !=
> + state->base.fb->modifier[0])
> + intel_crtc->atomic.update_wm = true;

Imo this is fragile. We should unconditionally recomupte watermarks imo
and just ellide the hw update if nothing changed. Spending a few cpu
cycles on this per frame shouldn't hurt, and it will avoid duplicated
logic and checks for watermark recomputation splattered all over the code.

I know that it's kinda there already, but still minimal enough to patch
up. But if Matt knows that this will get removed again with the two-stage
wm code then I'm ok with leaving it in, with a FIXME comment added.
-Daniel

>   }
>  
>   return 0;
> diff --git a/drivers/gpu/drm/i915/intel_drv.h 
> b/drivers/gpu/drm/i915/intel_drv.h
> index 399d2b2..b124548 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -501,6 +501,7 @@ struct intel_plane_wm_parameters {
>   uint8_t bytes_per_pixel;
>   bool enabled;
>   bool scaled;
> + u64 tiling;
>  };
>  
>  struct intel_plane {
> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> index f7c9938..006e635 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -2662,6 +2662,7 @@ static void skl_compute_wm_pipe_parameters(struct 
> drm_crtc *crtc,
>   struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
>   enum pipe pipe = intel_crtc->pipe;
>   struct drm_plane *plane;
> + struct drm_framebuffer *fb;
>   int i = 1; /* Index for sprite planes start */
>  
>   p->active = intel_crtc_active(crtc);
> @@ -2677,6 +2678,14 @@ static void skl_compute_wm_pipe_parameters(struct 
> drm_crtc *crtc,
>   crtc->primary->fb->bits_per_pixel / 8;
>   p->plane[0].horiz_pixels = intel_crtc->config->pipe_src_w;
>   p->plane[0].vert_pixels = intel_crtc->config->pipe_src_h;
> + p->plane[0].tiling = DRM_FORMAT_MOD_NONE;
> + fb = crtc->primary->fb;
> + /*
> +  * Framebuffer can be NULL on plane disable, but it does not
> +  * matter for watermarks if we assume no tiling in that case.
> +  */
> + if (fb)
> + p->plane[0].tiling = fb->modifier[0];
>  
>   p->cursor.enabled = true;
>   p->cursor.bytes_per_pixel = 4;
> @@ -2702,6 +2711,7 @@ static bool skl_compute_plane_wm(struct 
> skl_pipe_wm_parameters *p,
>  {
>   uint32_t method1, method2, plane_bytes_per_line, res_blocks, res_lines;
>   uint32_t result_bytes;
> + uint32_t y_tile_minimum;
>  
>   if (mem_value == 0 || !p->active || !p_params->enabled)
>   return false;
> @@ -2718,11 +2728,16 @@ static bool skl_compute_plane_wm(struct 
> skl_pipe_wm_parameters *p,
>   plane_bytes_per_line = p_params->horiz_pixels *
>   p_params->bytes_per_pixel;
>  
> - /* For now xtile and linear */
> - if (((ddb_allocation * 512) / plane_bytes_per_line) >= 1)
> - result_bytes = min(method1, method2);
> - else
> - result_bytes = method1;
> + if (p_params->tiling == I915_FORMAT_MOD_Y_TILED ||
> + p_params->tiling == I915_FORMAT_MOD_Yf_TILED) {
> + y_tile_minimum = plane_bytes_per_line * 4;
> + result_bytes = m

Re: [Intel-gfx] [PATCH] drm/i915: Fix frontbuffer false positve.

2015-02-24 Thread Matt Roper
On Tue, Feb 24, 2015 at 01:37:54PM -0800, Rodrigo Vivi wrote:
> This return 0 without setting atomic bits on fb == crtc->cursor->fb
> where causing frontbuffer false positives.
> 
> According to Daniel:
> 
> The original regression seems to have been introduced in the original
> check/commit split:
> 
> commit 757f9a3e5b8a812af0c213099a5b31cb423f4d3c
> Author: Gustavo Padovan 
> Date:   Wed Sep 24 14:20:24 2014 -0300
> 
> drm/i915: move check of intel_crtc_cursor_set_obj() out
> 
> Which already cause other trouble, resulting in the check getting moved in
> 
> commit e391ea882b1a04fb3f559287ac694652a3cd9da9
> Author: Gustavo Padovan 
> Date:   Wed Sep 24 14:20:25 2014 -0300
> 
> drm/i915: Fix not checking cursor and object sizes
> 
> The frontbuffer tracking itself only was broken when we shifted it into
> the check/commit logic with:
> 
> commit 32b7eeec4d1e861230b09d437e95d76c86ff4a68
> Author: Matt Roper 
> Date:   Wed Dec 24 07:59:06 2014 -0800
> 
> drm/i915: Refactor work that can sleep out of commit (v7)
> 
> v2: When putting more debug prints I notice the solution was simpler
> than I thought. AMS design is solid, just this return was wrong.
> Sorry for the noise.
> 
> v3: Remove the entire chunck that would probably
> be removed by gcc anyway. (by Daniel)
> 
> Cc: Jani Nikula 
> Cc: Gustavo Padovan 
> Cc: Matt Roper 
> Signed-off-by: Rodrigo Vivi 

Not sure I understand Daniel's remark about gcc optimization, but the
change still looks good to me.

Reviewed-by: Matt Roper 

> ---
>  drivers/gpu/drm/i915/intel_display.c | 3 ---
>  1 file changed, 3 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_display.c 
> b/drivers/gpu/drm/i915/intel_display.c
> index 8ccf033..900dcaa 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -12197,9 +12197,6 @@ intel_check_cursor_plane(struct drm_plane *plane,
>   return -ENOMEM;
>   }
>  
> - if (fb == crtc->cursor->fb)
> - return 0;
> -
>   if (fb->modifier[0] != DRM_FORMAT_MOD_NONE) {
>   DRM_DEBUG_KMS("cursor cannot be tiled\n");
>   ret = -EINVAL;
> -- 
> 2.1.0
> 

-- 
Matt Roper
Graphics Software Engineer
IoTG Platform Enabling & Development
Intel Corporation
(916) 356-2795
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH 7/7] drm/i915/skl: Allow Y (and Yf) frame buffer creation

2015-02-24 Thread Daniel Vetter
On Mon, Feb 23, 2015 at 03:56:01PM +, Tvrtko Ursulin wrote:
> From: Tvrtko Ursulin 
> 
> By this patch all underlying bits have been implemented and this
> patch actually enables the feature.
> 
> Signed-off-by: Tvrtko Ursulin 
> ---
>  drivers/gpu/drm/i915/intel_display.c | 13 -
>  1 file changed, 8 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_display.c 
> b/drivers/gpu/drm/i915/intel_display.c
> index 74d4923..f100086 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -12781,6 +12781,14 @@ static int intel_framebuffer_init(struct drm_device 
> *dev,
>   DRM_DEBUG("tiling_mode doesn't match fb modifier\n");
>   return -EINVAL;
>   }
> +
> + if (INTEL_INFO(dev)->gen < 9 &&
> + (mode_cmd->modifier[0] == I915_FORMAT_MOD_Y_TILED ||
> +  mode_cmd->modifier[0] == I915_FORMAT_MOD_Yf_TILED)) {
> + DRM_DEBUG("Unsupported tiling 0x%llx!\n",
> +   mode_cmd->modifier[0]);
> + return -EINVAL;
> + }
>   } else {
>   if (obj->tiling_mode == I915_TILING_X)
>   mode_cmd->modifier[0] = I915_FORMAT_MOD_X_TILED;
> @@ -12790,11 +12798,6 @@ static int intel_framebuffer_init(struct drm_device 
> *dev,
>   }
>   }
>  
> - if (mode_cmd->modifier[0] == I915_FORMAT_MOD_Y_TILED) {
> - DRM_DEBUG("hardware does not support tiling Y\n");
> - return -EINVAL;
> - }

Imo the clearer code would be to add a 

switch (mode_cmd->modifier[0]) {

}

here and then shovel the platform checks into the supgroups. At least
that's how we tend to roll these since it reduces the risks that a case is
forgotten when the enumeration is extended. That would also have caught
that we don't reject random garbage in the default: case.
-Daniel

> -
>   stride_alignment = intel_fb_stride_alignment(dev, mode_cmd->modifier[0],
>mode_cmd->pixel_format);
>   if (mode_cmd->pitches[0] & (stride_alignment - 1)) {
> -- 
> 2.3.0
> 
> ___
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
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 i-g-t 12/12] testdisplay/skl: Add command line options for Yb/Yf tiled fbs

2015-02-24 Thread Daniel Vetter
On Mon, Feb 23, 2015 at 03:57:55PM +, Tvrtko Ursulin wrote:
> From: Damien Lespiau 
> 
> Signed-off-by: Damien Lespiau 

testdisplay is a bit an awkward test, mostly used by QA for manual
testing. I think we also need some basic kms_setmode subtest to use the
new tiling modes on skl in one of the automated testcases. Otherwise I
fear this will bitrot fast.
-Daniel

> ---
>  tests/testdisplay.c | 16 ++--
>  1 file changed, 14 insertions(+), 2 deletions(-)
> 
> diff --git a/tests/testdisplay.c b/tests/testdisplay.c
> index 64ce4d7..dab9e12 100644
> --- a/tests/testdisplay.c
> +++ b/tests/testdisplay.c
> @@ -51,6 +51,7 @@
>  
>  #include 
>  #include 
> +#include 
>  #include 
>  #include 
>  #include 
> @@ -71,8 +72,10 @@
>  #include 
>  #include 
>  
> -#define SUBTEST_OPTS 1
> +#define SUBTEST_OPTS  1
>  #define HELP_DESCRIPTION 2
> +#define Yb_OPT3
> +#define Yf_OPT4
>  
>  static int tio_fd;
>  struct termios saved_tio;
> @@ -544,7 +547,7 @@ int update_display(void)
>   return 1;
>  }
>  
> -static char optstr[] = "3hiaf:s:d:p:mrto:j:";
> +static char optstr[] = "3hiaf:s:d:p:mrto:j:y";
>  
>  static void __attribute__((noreturn)) usage(char *name, char opt)
>  {
> @@ -645,6 +648,8 @@ int main(int argc, char **argv)
>   {"run-subtest", 1, 0, SUBTEST_OPTS},
>   {"help-description", 0, 0, HELP_DESCRIPTION},
>   {"help", 0, 0, 'h'},
> + {"yb", 0, 0, Yb_OPT},
> + {"yf", 0, 0, Yf_OPT},
>   { 0, 0, 0, 0 }
>   };
>  
> @@ -697,6 +702,13 @@ int main(int argc, char **argv)
>   case 't':
>   tiling = LOCAL_I915_FORMAT_MOD_X_TILED;
>   break;
> + case 'y':
> + case Yb_OPT:
> + tiling = LOCAL_I915_FORMAT_MOD_Y_TILED;
> + break;
> + case Yf_OPT:
> + tiling = LOCAL_I915_FORMAT_MOD_Yf_TILED;
> + break;
>   case 'r':
>   qr_code = 1;
>   break;
> -- 
> 2.3.0
> 
> ___
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
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 i-g-t 00/12] Testing the Y tiled display

2015-02-24 Thread Daniel Vetter
On Mon, Feb 23, 2015 at 03:57:43PM +, Tvrtko Ursulin wrote:
> From: Tvrtko Ursulin 
> 
> Starting with Skylake the display engine can scan out Y tiled objects. (Both
> legacy Y tiled, and the new Yf format.)
> 
> This series takes the original work by Damien Lespiau and converts it to use 
> the
> new frame buffer modifiers instead of object set/get tiling. Some patches 
> needed
> to be dropped, some added and some refactored.
> 
> v2: Refactored for fb modifier changes.
> 
> Damien Lespiau (7):
>   lib: Extract igt_buf_write_to_png() from gem_render_copy
>   lib/skl: Add gen9 specific igt_blitter_fast_copy()
>   lib: Don't give a struct igt_buf * to fast_copy_pitch()
>   lib: Split two helpers to build fast copy's dword0 and dword1
>   lib: Provide a raw version of the gen9 fast copy blits
>   lib: Allow the creation of Ys/Yf tiled FBs
>   testdisplay/skl: Add command line options for Yb/Yf tiled fbs
> 
> Tvrtko Ursulin (5):
>   tests/kms_addfb: Add support for fb modifiers
>   tests/kms_addfb: Y tiled testcases
>   tiling: Convert framebuffer helpers to use fb modifiers
>   lib: Add support for new extension to the ADDFB2 ioctl.
>   lib/igt_fb: Use new ADDFB2 extension for new tiling modes

Test coverage looks good to me overall, just two minor things:
- functional automated test (replied to the testdisplay patch)
- catching invalid modifiers and making sure y/yf tiling is reject
  unconditionally on pre-gen9 seem to be missing too.

Detail checking that we have full coverage is imo for the in-depth review.

Kernel patches also look good, just a few minor comments.

Cheers, Daniel
> 
>  lib/igt_fb.c| 163 +
>  lib/igt_fb.h|  10 +-
>  lib/igt_kms.h   |   1 +
>  lib/intel_batchbuffer.c | 281 
> 
>  lib/intel_batchbuffer.h |  37 ++
>  lib/intel_reg.h |  18 +++
>  lib/ioctl_wrappers.c|  49 
>  lib/ioctl_wrappers.h|  41 +++
>  tests/gem_render_copy.c |  24 +---
>  tests/kms_3d.c  |   2 +-
>  tests/kms_addfb.c   | 135 -
>  tests/kms_cursor_crc.c  |   8 +-
>  tests/kms_fbc_crc.c |   4 +-
>  tests/kms_fence_pin_leak.c  |   4 +-
>  tests/kms_flip.c|   6 +-
>  tests/kms_flip_event_leak.c |   4 +-
>  tests/kms_flip_tiling.c |   7 +-
>  tests/kms_mmio_vs_cs_flip.c |  12 +-
>  tests/kms_pipe_crc_basic.c  |   2 +-
>  tests/kms_plane.c   |   8 +-
>  tests/kms_psr_sink_crc.c|   8 +-
>  tests/kms_pwrite_crc.c  |   4 +-
>  tests/kms_render.c  |   8 +-
>  tests/kms_rotation_crc.c|   4 +-
>  tests/kms_setmode.c |   2 +-
>  tests/kms_sink_crc_basic.c  |   6 +-
>  tests/kms_universal_plane.c |  18 +--
>  tests/pm_lpsp.c |   2 +-
>  tests/pm_rpm.c  |  26 ++--
>  tests/testdisplay.c |  20 +++-
>  30 files changed, 795 insertions(+), 119 deletions(-)
> 
> -- 
> 2.3.0
> 
> ___
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
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] [RFC 09/12] drm/i915/config: Add VBT settings configuration.

2015-02-24 Thread Bob Paauwe
On Tue, 24 Feb 2015 21:52:16 +0100
Daniel Vetter  wrote:

> On Tue, Feb 24, 2015 at 10:37:10AM -0800, Bob Paauwe wrote:
> > On Tue, 24 Feb 2015 14:57:48 +0100
> > Daniel Vetter  wrote:
> > > As Jani points out we already have vbt headaches, it would be good if we
> > > only have those once ;-)
> > > -Daniel
> > 
> > I've been trying to think of a better way but not really coming up with
> > something that scales well. EMGD took the approach of create
> > configuration for only those values that we had customer requests for.
> > And that was primarily just the panel power up/down timing sequence and
> > some backlight control. We never tried to replicate everything that
> > could be set via vbt.
> 
> If it's only a very few select things we could just add them as atomic
> properties to connectors. No need for anything special, and we could even
> use that to debug panel issues at runtime.
> 
> We need a lot of the dp things already anyway for the dp validation stuff,
> but since that was debug Dave shot down my idea to just go with props. But
> here we have another user, and this one will have full abi compat
> requirements. So no longer any reasons to not go with props imo.
> 
> Or else we just smash an entire vbt into acpi, for my that's ok (we need
> to deal with vbt anyway).
> -Daniel


Funny... As I was looking at the atomic code I had the same thought to
use atomic properties but dismissed it because I thought it would be
too much overhead to do that for all of the vbt flags/values.   But it
it's limited, at least initially, to what we know we need that would
work and this whole bit magically goes away.

Thanks! Looks like it's time for me to really start digging into atomic.

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


Re: [Intel-gfx] [PATCH v2] lib/igt_kms.c: remove tests dependency on VT /dev/tty0

2015-02-24 Thread Daniel Vetter
On Tue, Feb 24, 2015 at 12:29:22PM -0800, Marc Herbert wrote:
> Required to run on any recent, freon-based and X11-free ChromeOS release.
> 
> Signed-off-by: Marc Herbert 
> ---
> 
> Changes from v1:
> - igt_debug() instead of igt_warn()
> - return KD_GRAPHICS instead of -1UL
> - print previous mode in debug statements. Among others this help a tiny
>   bit with the now confusing debug output ("cannot change" immediately
>   followed by a misleading "mode changed").

Thanks for the patch, merged to igt.
-Daniel

> 
> Note: a naive "mv /dev/tty0 /dev/tty0.orig" is typically enough to test
> this patch.
> 
>  lib/igt_kms.c | 22 ++
>  1 file changed, 18 insertions(+), 4 deletions(-)
> 
> diff --git a/lib/igt_kms.c b/lib/igt_kms.c
> index d0c3690..9c131f0 100644
> --- a/lib/igt_kms.c
> +++ b/lib/igt_kms.c
> @@ -299,12 +299,26 @@ int kmstest_get_pipe_from_crtc_id(int fd, int crtc_id)
>   return pfci.pipe;
>  }
>  
> +/*
> + * Returns: the previous mode, or KD_GRAPHICS if no /dev/tty0 was
> + * found and nothing was done.
> + */
>  static signed long set_vt_mode(unsigned long mode)
>  {
>   int fd;
>   unsigned long prev_mode;
> + static const char TTY0[] = "/dev/tty0";
> +
> + if (access(TTY0, F_OK)) {
> + /* errno message should be "No such file". Do not
> +hardcode but ask strerror() in the very unlikely
> +case something else happened. */
> + igt_debug("VT: %s: %s, cannot change its mode\n",
> +   TTY0, strerror(errno));
> + return KD_GRAPHICS;
> + }
>  
> - fd = open("/dev/tty0", O_RDONLY);
> + fd = open(TTY0, O_RDONLY);
>   if (fd < 0)
>   return -errno;
>  
> @@ -336,10 +350,10 @@ void kmstest_restore_vt_mode(void)
>  
>   if (orig_vt_mode != -1UL) {
>   ret = set_vt_mode(orig_vt_mode);
> - orig_vt_mode = -1UL;
>  
>   igt_assert(ret >= 0);
> - igt_debug("VT: original mode restored\n");
> + igt_debug("VT: original mode 0x%lx restored\n", orig_vt_mode);
> + orig_vt_mode = -1UL;
>   }
>  }
>  
> @@ -366,7 +380,7 @@ void kmstest_set_vt_graphics_mode(void)
>   igt_assert(ret >= 0);
>   orig_vt_mode = ret;
>  
> - igt_debug("VT: graphics mode set\n");
> + igt_debug("VT: graphics mode set (mode was 0x%lx)\n", ret);
>  }
>  
>  
> -- 
> 1.9.3
> 
> ___
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
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


[Intel-gfx] linux-next: manual merge of the drm-intel tree with the drm-intel-fixes tree

2015-02-24 Thread Stephen Rothwell
Hi all,

Today's linux-next merge of the drm-intel tree got a conflict in
drivers/gpu/drm/i915/intel_display.c between commit f37b5c2be897
("drm/i915: Align initial plane backing objects correctly") from the
drm-intel-fixes tree and commit 6bf129df6ffa ("drm/i915: Use an
intermediate variable to avoid repeating ourselves") from the drm-intel
tree.

I fixed it up (see below) and can carry the fix as necessary (no action
is required).

-- 
Cheers,
Stephen Rothwells...@canb.auug.org.au

diff --cc drivers/gpu/drm/i915/intel_display.c
index bf19a5cce4a8,2ac93909cfc5..
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@@ -2371,11 -2376,8 +2376,12 @@@ intel_alloc_plane_obj(struct intel_crt
struct drm_device *dev = crtc->base.dev;
struct drm_i915_gem_object *obj = NULL;
struct drm_mode_fb_cmd2 mode_cmd = { 0 };
+   struct drm_framebuffer *fb = &plane_config->fb->base;
 -  u32 base = plane_config->base;
 +  u32 base_aligned = round_down(plane_config->base, PAGE_SIZE);
 +  u32 size_aligned = round_up(plane_config->base + plane_config->size,
 +  PAGE_SIZE);
 +
 +  size_aligned -= base_aligned;
  
if (plane_config->size == 0)
return false;
@@@ -6640,9 -6678,10 +6693,10 @@@ i9xx_get_initial_plane_config(struct in
fb->pitches[0] = val & 0xffc0;
  
aligned_height = intel_fb_align_height(dev, fb->height,
-  plane_config->tiling);
+  fb->pixel_format,
+  fb->modifier[0]);
  
 -  plane_config->size = PAGE_ALIGN(fb->pitches[0] * aligned_height);
 +  plane_config->size = fb->pitches[0] * aligned_height;
  
DRM_DEBUG_KMS("pipe/plane %c/%d with fb: size=%dx%d@%d, offset=%x, 
pitch %d, size 0x%x\n",
  pipe_name(pipe), plane, fb->width, fb->height,
@@@ -7677,9 -7721,10 +7736,10 @@@ skylake_get_initial_plane_config(struc
fb->pitches[0] = (val & 0x3ff) * stride_mult;
  
aligned_height = intel_fb_align_height(dev, fb->height,
-  plane_config->tiling);
+  fb->pixel_format,
+  fb->modifier[0]);
  
 -  plane_config->size = ALIGN(fb->pitches[0] * aligned_height, PAGE_SIZE);
 +  plane_config->size = fb->pitches[0] * aligned_height;
  
DRM_DEBUG_KMS("pipe %c with fb: size=%dx%d@%d, offset=%x, pitch %d, 
size 0x%x\n",
  pipe_name(pipe), fb->width, fb->height,
@@@ -7768,9 -7818,10 +7833,10 @@@ ironlake_get_initial_plane_config(struc
fb->pitches[0] = val & 0xffc0;
  
aligned_height = intel_fb_align_height(dev, fb->height,
-  plane_config->tiling);
+  fb->pixel_format,
+  fb->modifier[0]);
  
 -  plane_config->size = PAGE_ALIGN(fb->pitches[0] * aligned_height);
 +  plane_config->size = fb->pitches[0] * aligned_height;
  
DRM_DEBUG_KMS("pipe %c with fb: size=%dx%d@%d, offset=%x, pitch %d, 
size 0x%x\n",
  pipe_name(pipe), fb->width, fb->height,


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


[Intel-gfx] [PATCH 2/2] drm/i915/skl: Add support for edp1.4 low vswing

2015-02-24 Thread Sonika Jindal
Based upon vbt's vswing preemph settings value select the appropriate
translations for edp.

v2: Incorporating bspec changes for vswing and preemph levels, adding edp
translation table. Removed HSW from selection 9 which is specific to skl and
correcting the returning of level2 from max pre emph (Damien)

v3: Rebasing on top of renaming patches. Adding level(3,0) since level(2,2) as
mentioned in bspec is invalid as per edp spec. Also changed the determining of
size of the table selected (Satheesh).

v4: Adding level 3 in max voltage selection if low vswing is selected (Satheesh)

v5: Add a comment stating that skl_ddi_translations_edp is for eDP 1.4
low vswing panels.

v6: Updating recommended DDI translation table for edp 1.4

Reviewed-by: Satheeshakrishna M  (v4)
Reviewed-by: Damien Lespiau  (v6)
Signed-off-by: Sonika Jindal 
Signed-off-by: Damien Lespiau 
---
 drivers/gpu/drm/i915/intel_ddi.c |   46 +-
 drivers/gpu/drm/i915/intel_dp.c  |   12 --
 2 files changed, 50 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index f14e8a2..985d531 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -139,6 +139,21 @@ static const struct ddi_buf_trans 
skl_ddi_translations_dp[] = {
{ 0x4014, 0x0087 },
 };
 
+/* eDP 1.4 low vswing translation parameters */
+static const struct ddi_buf_trans skl_ddi_translations_edp[] = {
+   { 0x0018, 0x00a8 },
+   { 0x2016, 0x00ab },
+   { 0x6012, 0x00a2 },
+   { 0x8010, 0x0088 },
+   { 0x0018, 0x00ab },
+   { 0x4014, 0x00a2 },
+   { 0x6012, 0x00a6 },
+   { 0x0018, 0x00a2 },
+   { 0x5013, 0x009c },
+   { 0x0018, 0x0088 },
+};
+
+
 static const struct ddi_buf_trans skl_ddi_translations_hdmi[] = {
/* Idx  NT mV   T mVdb  */
{ 0x0018, 0x00a0 }, /* 0:   400 400 0   */
@@ -187,7 +202,8 @@ static void intel_prepare_ddi_buffers(struct drm_device 
*dev, enum port port)
 {
struct drm_i915_private *dev_priv = dev->dev_private;
u32 reg;
-   int i, n_hdmi_entries, hdmi_800mV_0dB;
+   int i, n_hdmi_entries, n_dp_entries, n_edp_entries, hdmi_800mV_0dB,
+   size;
int hdmi_level = dev_priv->vbt.ddi_port_info[port].hdmi_level_shift;
const struct ddi_buf_trans *ddi_translations_fdi;
const struct ddi_buf_trans *ddi_translations_dp;
@@ -198,7 +214,15 @@ static void intel_prepare_ddi_buffers(struct drm_device 
*dev, enum port port)
if (IS_SKYLAKE(dev)) {
ddi_translations_fdi = NULL;
ddi_translations_dp = skl_ddi_translations_dp;
-   ddi_translations_edp = skl_ddi_translations_dp;
+   n_dp_entries = ARRAY_SIZE(skl_ddi_translations_dp);
+   if (dev_priv->vbt.edp_low_vswing) {
+   ddi_translations_edp = skl_ddi_translations_edp;
+   n_edp_entries = ARRAY_SIZE(skl_ddi_translations_edp);
+   } else {
+   ddi_translations_edp = skl_ddi_translations_dp;
+   n_edp_entries = ARRAY_SIZE(skl_ddi_translations_dp);
+   }
+
ddi_translations_hdmi = skl_ddi_translations_hdmi;
n_hdmi_entries = ARRAY_SIZE(skl_ddi_translations_hdmi);
hdmi_800mV_0dB = 7;
@@ -207,6 +231,8 @@ static void intel_prepare_ddi_buffers(struct drm_device 
*dev, enum port port)
ddi_translations_dp = bdw_ddi_translations_dp;
ddi_translations_edp = bdw_ddi_translations_edp;
ddi_translations_hdmi = bdw_ddi_translations_hdmi;
+   n_edp_entries = ARRAY_SIZE(bdw_ddi_translations_edp);
+   n_dp_entries = ARRAY_SIZE(bdw_ddi_translations_dp);
n_hdmi_entries = ARRAY_SIZE(bdw_ddi_translations_hdmi);
hdmi_800mV_0dB = 7;
} else if (IS_HASWELL(dev)) {
@@ -214,6 +240,7 @@ static void intel_prepare_ddi_buffers(struct drm_device 
*dev, enum port port)
ddi_translations_dp = hsw_ddi_translations_dp;
ddi_translations_edp = hsw_ddi_translations_dp;
ddi_translations_hdmi = hsw_ddi_translations_hdmi;
+   n_dp_entries = n_edp_entries = 
ARRAY_SIZE(hsw_ddi_translations_dp);
n_hdmi_entries = ARRAY_SIZE(hsw_ddi_translations_hdmi);
hdmi_800mV_0dB = 6;
} else {
@@ -222,6 +249,8 @@ static void intel_prepare_ddi_buffers(struct drm_device 
*dev, enum port port)
ddi_translations_fdi = bdw_ddi_translations_fdi;
ddi_translations_dp = bdw_ddi_translations_dp;
ddi_translations_hdmi = bdw_ddi_translations_hdmi;
+   n_edp_entries = ARRAY_SIZE(bdw_ddi_translations_edp);
+   n_dp_entr

[Intel-gfx] [PATCH 0/2] Support for low voltage swing

2015-02-24 Thread Sonika Jindal
Skylake supports low voltage swing in edp 1.4. The translation table is selected
based upon the vbt entry for selecting low vswing
These patches are being pulled from -internal to -nightly.

Sonika Jindal (2):
  drm/i915/skl: Support for edp low_vswing param in vbt
  drm/i915/skl: Add support for edp1.4 low vswing

 drivers/gpu/drm/i915/i915_drv.h   |1 +
 drivers/gpu/drm/i915/intel_bios.c |7 ++
 drivers/gpu/drm/i915/intel_bios.h |1 +
 drivers/gpu/drm/i915/intel_ddi.c  |   46 -
 drivers/gpu/drm/i915/intel_dp.c   |   12 --
 5 files changed, 59 insertions(+), 8 deletions(-)

-- 
1.7.10.4

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


Re: [Intel-gfx] [PATCH 7/7] drm/i915/skl: Allow Y (and Yf) frame buffer creation

2015-02-24 Thread shuang . he
Tested-By: PRC QA PRTS (Patch Regression Test System Contact: 
shuang...@intel.com)
Task id: 5814
-Summary-
Platform  Delta  drm-intel-nightly  Series Applied
PNV  281/281  281/281
ILK  305/305  305/305
SNB -1  326/326  325/326
IVB  380/380  380/380
BYT  294/294  294/294
HSW -1  421/421  420/421
BDW -1  316/316  315/316
-Detailed-
Platform  Testdrm-intel-nightly  Series 
Applied
 SNB  igt_kms_plane_plane-position-hole-pipe-B-plane-1  
DMESG_WARN(12)PASS(3)  DMESG_WARN(1)PASS(1)
 HSW  igt_gem_storedw_loop_vebox  DMESG_WARN(2)PASS(1)  
DMESG_WARN(1)PASS(1)
*BDW  igt_gem_gtt_hog  PASS(6)  DMESG_WARN(1)PASS(1)
Note: You need to pay more attention to line start with '*'
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx