Re: [Intel-gfx] Shared memory management

2012-03-01 Thread Michal Mocny
Hello,

I am trying to measure video memory usage as per Ben Widawsky's
instructions from a while back:

mount debugfs
cat /sys/kernel/debug/dri/0/i915_gem_gtt

However, the numbers are difficult to read/draw conclusions from.  Can I
get some insight into the meaning of the various column values?
 Specifically, if I would like to measure the actual current physical
memory usage, should any of the values be ignored?

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


[Intel-gfx] [PATCH] mm: extend prefault helpers to fault in more than PAGE_SIZE

2012-03-01 Thread Daniel Vetter
drm/i915 wants to read/write more than one page in its fastpath
and hence needs to prefault more than PAGE_SIZE bytes.

Add new functions in filemap.h to make that possible.

Also kill a copy&pasted spurious space in both functions while at it.

v2: As suggested by Andrew Morton, add a multipage parameter to both
functions to avoid the additional branch for the pagemap.c hotpath.
My gcc 4.6 here seems to dtrt and indeed reap these branches where not
needed.

v3: Becaus I couldn't find a way around adding a uaddr += PAGE_SIZE to
the filemap.c hotpaths (that the compiler couldn't remove again),
let's go with separate new functions for the multipage use-case.

Cc: linux...@kvack.org
Signed-off-by: Daniel Vetter 
---
 drivers/gpu/drm/i915/i915_gem.c|6 +-
 drivers/gpu/drm/i915/i915_gem_execbuffer.c |2 +-
 include/linux/pagemap.h|   62 +++-
 3 files changed, 64 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 544e528..3e631fc 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -436,7 +436,7 @@ i915_gem_shmem_pread(struct drm_device *dev,
mutex_unlock(&dev->struct_mutex);
 
if (!prefaulted) {
-   ret = fault_in_pages_writeable(user_data, remain);
+   ret = fault_in_multipages_writeable(user_data, remain);
/* Userspace is tricking us, but we've already clobbered
 * its pages with the prefault and promised to write the
 * data up to the first fault. Hence ignore any errors
@@ -822,8 +822,8 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data,
   args->size))
return -EFAULT;
 
-   ret = fault_in_pages_readable((char __user *)(uintptr_t)args->data_ptr,
- args->size);
+   ret = fault_in_multipages_readable((char __user 
*)(uintptr_t)args->data_ptr,
+  args->size);
if (ret)
return -EFAULT;
 
diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c 
b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
index 81687af..ef87f52 100644
--- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
@@ -955,7 +955,7 @@ validate_exec_list(struct drm_i915_gem_exec_object2 *exec,
if (!access_ok(VERIFY_WRITE, ptr, length))
return -EFAULT;
 
-   if (fault_in_pages_readable(ptr, length))
+   if (fault_in_multipages_readable(ptr, length))
return -EFAULT;
}
 
diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h
index cfaaa69..0a91375 100644
--- a/include/linux/pagemap.h
+++ b/include/linux/pagemap.h
@@ -426,7 +426,7 @@ static inline int fault_in_pages_writeable(char __user 
*uaddr, int size)
 */
if (((unsigned long)uaddr & PAGE_MASK) !=
((unsigned long)end & PAGE_MASK))
-   ret = __put_user(0, end);
+   ret = __put_user(0, end);
}
return ret;
 }
@@ -445,13 +445,71 @@ static inline int fault_in_pages_readable(const char 
__user *uaddr, int size)
 
if (((unsigned long)uaddr & PAGE_MASK) !=
((unsigned long)end & PAGE_MASK)) {
-   ret = __get_user(c, end);
+   ret = __get_user(c, end);
(void)c;
}
}
return ret;
 }
 
+/* Multipage variants of the above prefault helpers, useful if more than
+ * PAGE_SIZE of date needs to be prefaulted. These are separate from the above
+ * functions (which only handle up to PAGE_SIZE) to avoid clobbering the
+ * filemap.c hotpaths. */
+static inline int fault_in_multipages_writeable(char __user *uaddr, int size)
+{
+   int ret;
+   const char __user *end = uaddr + size - 1;
+
+   if (unlikely(size == 0))
+   return 0;
+
+   /*
+* Writing zeroes into userspace here is OK, because we know that if
+* the zero gets there, we'll be overwriting it.
+*/
+   while (uaddr <= end) {
+   ret = __put_user(0, uaddr);
+   if (ret != 0)
+   return ret;
+   uaddr += PAGE_SIZE;
+   }
+
+   /* Check whether the range spilled into the next page. */
+   if (((unsigned long)uaddr & PAGE_MASK) ==
+   ((unsigned long)end & PAGE_MASK))
+   ret = __put_user(0, end);
+
+   return ret;
+}
+
+static inline int fault_in_multipages_readable(const char __user *uaddr,
+  int size)
+{
+   volatile char c;
+   int ret;
+   const char __user *end = uaddr + size - 1;
+
+   if (unlikely(si

[Intel-gfx] [PATCH 1/2] drm/i915: fixup in-line clflushing on bit17 swizzled bos

2012-03-01 Thread Daniel Vetter
The issue is that with inline clflushing the clflushing isn't properly
swizzled. Fix this by
- always clflushing entire 128 byte chunks and
- checking against 128 byte chunks for partial cachelines when
  swizzling is required.

Now the usual approach is to fold this into the original patch series, but
I've opted against this because
- this fixes a corner case only very old userspace relies on and
- I'd like to not invalidate all the testing the pwrite rewrite has gotten.

This fixes the regression notice by tests/gem_tiled_partial_prite_pread
from i-g-t. Unfortunately it doesn't fix the issues with partial pwrites to
tiled buffers on bit17 swizzling machines. But that is also broken without
the pwrite patches, so likely a different issue (or a problem with the
testcase).

Signed-Off-by: Daniel Vetter 
---
 drivers/gpu/drm/i915/i915_gem.c |   60 +-
 1 files changed, 46 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 9b200f4e..4219bd1 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -333,6 +333,28 @@ shmem_pread_fast(struct page *page, int shmem_page_offset, 
int page_length,
return ret;
 }
 
+static void
+shmem_clflush_swizzled_range(char *addr, unsigned long length,
+bool swizzled)
+{
+   if (swizzled) {
+   unsigned long start = (unsigned long) addr;
+   unsigned long end = (unsigned long) addr + length;
+
+   /* For swizzling simply ensure that we always flush both
+* channels. Lame, but simple and it works. Swizzled
+* pwrite/pread is far from a hotpath - current userspace
+* doesn't use it at all. */
+   start = round_down(start, 128);
+   end = round_up(end, 128);
+
+   drm_clflush_virt_range((void *)start, end - start);
+   } else {
+   drm_clflush_virt_range(addr, length);
+   }
+
+}
+
 /* Only difference to the fast-path function is that this can handle bit17
  * and uses non-atomic copy and kmap functions. */
 static int
@@ -345,8 +367,9 @@ shmem_pread_slow(struct page *page, int shmem_page_offset, 
int page_length,
 
vaddr = kmap(page);
if (needs_clflush)
-   drm_clflush_virt_range(vaddr + shmem_page_offset,
-  page_length);
+   shmem_clflush_swizzled_range(vaddr + shmem_page_offset,
+page_length,
+page_do_bit17_swizzling);
 
if (page_do_bit17_swizzling)
ret = __copy_to_user_swizzled(user_data,
@@ -655,9 +678,10 @@ shmem_pwrite_slow(struct page *page, int 
shmem_page_offset, int page_length,
int ret;
 
vaddr = kmap(page);
-   if (needs_clflush_before)
-   drm_clflush_virt_range(vaddr + shmem_page_offset,
-  page_length);
+   if (needs_clflush_before || page_do_bit17_swizzling)
+   shmem_clflush_swizzled_range(vaddr + shmem_page_offset,
+page_length,
+page_do_bit17_swizzling);
if (page_do_bit17_swizzling)
ret = __copy_from_user_swizzled(vaddr, shmem_page_offset,
user_data,
@@ -667,8 +691,9 @@ shmem_pwrite_slow(struct page *page, int shmem_page_offset, 
int page_length,
   user_data,
   page_length);
if (needs_clflush)
-   drm_clflush_virt_range(vaddr + shmem_page_offset,
-  page_length);
+   shmem_clflush_swizzled_range(vaddr + shmem_page_offset,
+page_length,
+page_do_bit17_swizzling);
kunmap(page);
 
return ret;
@@ -716,6 +741,7 @@ i915_gem_shmem_pwrite(struct drm_device *dev,
while (remain > 0) {
struct page *page;
int partial_cacheline_write;
+   unsigned clflush_size;
 
/* Operation in this page
 *
@@ -728,13 +754,6 @@ i915_gem_shmem_pwrite(struct drm_device *dev,
if ((shmem_page_offset + page_length) > PAGE_SIZE)
page_length = PAGE_SIZE - shmem_page_offset;
 
-   /* If we don't overwrite a cacheline completely we need to be
-* careful to have up-to-date data by first clflushing. Don't
-* overcomplicate things and flush the entire patch. */
-   partial_cacheline_write = needs_clflush_before &&
-   ((shmem_page_offset | page_length)
-   & (boot_cpu_data.x86_clflush_size - 1));
-
   

[Intel-gfx] [PATCH 2/2] drm/i915: mark pwrite/pread slowpaths with unlikely

2012-03-01 Thread Daniel Vetter
Beside helping the compiler untangle this maze they double-up as
documentation for which a parts aren't performance-critical but just
around to keep old (but already dead-slow) userspace from breaking.

Signed-Off-by: Daniel Vetter 
---
 drivers/gpu/drm/i915/i915_gem.c |8 
 1 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 4219bd1..c5f4eb7 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -318,7 +318,7 @@ shmem_pread_fast(struct page *page, int shmem_page_offset, 
int page_length,
char *vaddr;
int ret;
 
-   if (page_do_bit17_swizzling)
+   if (unlikely(page_do_bit17_swizzling))
return -EINVAL;
 
vaddr = kmap_atomic(page);
@@ -337,7 +337,7 @@ static void
 shmem_clflush_swizzled_range(char *addr, unsigned long length,
 bool swizzled)
 {
-   if (swizzled) {
+   if (unlikely(swizzled)) {
unsigned long start = (unsigned long) addr;
unsigned long end = (unsigned long) addr + length;
 
@@ -648,7 +648,7 @@ shmem_pwrite_fast(struct page *page, int shmem_page_offset, 
int page_length,
char *vaddr;
int ret;
 
-   if (page_do_bit17_swizzling)
+   if (unlikely(page_do_bit17_swizzling))
return -EINVAL;
 
vaddr = kmap_atomic(page);
@@ -678,7 +678,7 @@ shmem_pwrite_slow(struct page *page, int shmem_page_offset, 
int page_length,
int ret;
 
vaddr = kmap(page);
-   if (needs_clflush_before || page_do_bit17_swizzling)
+   if (unlikely(needs_clflush_before || page_do_bit17_swizzling))
shmem_clflush_swizzled_range(vaddr + shmem_page_offset,
 page_length,
 page_do_bit17_swizzling);
-- 
1.7.8.3

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


Re: [Intel-gfx] [PATCH] mm: extend prefault helpers to fault in more than PAGE_SIZE

2012-03-01 Thread Andrew Morton
On Thu,  1 Mar 2012 20:22:59 +0100
Daniel Vetter  wrote:

> drm/i915 wants to read/write more than one page in its fastpath
> and hence needs to prefault more than PAGE_SIZE bytes.
> 
> Add new functions in filemap.h to make that possible.
> 
> Also kill a copy&pasted spurious space in both functions while at it.
> 
>
> ...
>
> +/* Multipage variants of the above prefault helpers, useful if more than
> + * PAGE_SIZE of date needs to be prefaulted. These are separate from the 
> above
> + * functions (which only handle up to PAGE_SIZE) to avoid clobbering the
> + * filemap.c hotpaths. */

Like this please:

/*
 * Multipage variants of the above prefault helpers, useful if more than
 * PAGE_SIZE of date needs to be prefaulted. These are separate from the above
 * functions (which only handle up to PAGE_SIZE) to avoid clobbering the
 * filemap.c hotpaths.
 */

and s/date/data/

> +static inline int fault_in_multipages_writeable(char __user *uaddr, int size)
> +{
> + int ret;
> + const char __user *end = uaddr + size - 1;
> +
> + if (unlikely(size == 0))
> + return 0;
> +
> + /*
> +  * Writing zeroes into userspace here is OK, because we know that if
> +  * the zero gets there, we'll be overwriting it.
> +  */

Yeah, like that.

> + while (uaddr <= end) {
> + ret = __put_user(0, uaddr);
> + if (ret != 0)
> + return ret;
> + uaddr += PAGE_SIZE;
> + }
> +
> + /* Check whether the range spilled into the next page. */
> + if (((unsigned long)uaddr & PAGE_MASK) ==
> + ((unsigned long)end & PAGE_MASK))
> + ret = __put_user(0, end);
> +
> + return ret;
> +}
> +
> +static inline int fault_in_multipages_readable(const char __user *uaddr,
> +int size)
> +{
> + volatile char c;
> + int ret;
> + const char __user *end = uaddr + size - 1;
> +
> + if (unlikely(size == 0))
> + return 0;
> +
> + while (uaddr <= end) {
> + ret = __get_user(c, uaddr);
> + if (ret != 0)
> + return ret;
> + uaddr += PAGE_SIZE;
> + }
> +
> + /* Check whether the range spilled into the next page. */
> + if (((unsigned long)uaddr & PAGE_MASK) ==
> + ((unsigned long)end & PAGE_MASK)) {
> + ret = __get_user(c, end);
> + (void)c;
> + }
> +
> + return ret;
> +}

Please merge it via the DRI tree.
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [RFC] drm/i915: read current config at init time to avoid flicker

2012-03-01 Thread Jesse Barnes
The intent here is to build enough of the configuration to allow
set_config to avoid mode setting if possible.

Seems to speed up boot a bit on my Dell E6510; should help other eDP
platforms as well.

One thing that's missing is creating an initial fb for whatever's
display at driver load time.  This would involve poking around in the
display regs to get the offset and making bo and fb objects for the
current framebuffer.

-- 
Jesse Barnes, Intel Open Source Technology Center

diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index cdcf99b..8f25e68 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -7637,6 +7637,66 @@ static const struct drm_crtc_funcs intel_crtc_funcs = {
.page_flip = intel_crtc_page_flip,
 };
 
+static int intel_crtc_get_bpp(struct drm_crtc *crtc)
+{
+   struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+   int pipeconf;
+   int ret;
+
+   pipeconf = PIPECONF(intel_crtc->pipe);
+
+   switch (pipeconf & PIPE_BPC_MASK) {
+   case PIPE_6BPC:
+   ret = 18;
+   break;
+   case PIPE_8BPC:
+   ret = 24;
+   break;
+   case PIPE_10BPC:
+   ret = 30;
+   break;
+   case PIPE_12BPC:
+   ret = 36;
+   break;
+   default:
+   ret = 24;
+   break;
+   }
+
+   return ret;
+}
+
+static bool intel_crtc_get_status(struct drm_crtc *crtc)
+{
+   struct drm_device *dev = crtc->dev;
+   struct drm_i915_private *dev_priv = dev->dev_private;
+   struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+   int dspcntr, pipeconf;
+
+   dspcntr = DSPCNTR(intel_crtc->pipe);
+   pipeconf = PIPECONF(intel_crtc->pipe);
+
+   if ((I915_READ(dspcntr) & DISPLAY_PLANE_ENABLE) &&
+   (I915_READ(pipeconf) & PIPECONF_ENABLE))
+   return true;
+
+   return false;
+}
+
+/*
+ * Get current mode, encoder, and connector info for this CRTC
+ */
+static void intel_crtc_get_config(struct drm_crtc *crtc)
+{
+   struct drm_device *dev = crtc->dev;
+   struct drm_display_mode *mode;
+
+   mode = intel_crtc_mode_get(dev, crtc);
+   crtc->mode = *mode;
+   kfree(mode);
+   crtc->enabled = drm_helper_crtc_in_use(crtc);
+}
+
 static void intel_crtc_init(struct drm_device *dev, int pipe)
 {
drm_i915_private_t *dev_priv = dev->dev_private;
@@ -7669,9 +7729,8 @@ static void intel_crtc_init(struct drm_device *dev, int 
pipe)
dev_priv->plane_to_crtc_mapping[intel_crtc->plane] = &intel_crtc->base;
dev_priv->pipe_to_crtc_mapping[intel_crtc->pipe] = &intel_crtc->base;
 
-   intel_crtc_reset(&intel_crtc->base);
-   intel_crtc->active = true; /* force the pipe off on setup_init_config */
-   intel_crtc->bpp = 24; /* default for pre-Ironlake */
+   intel_crtc->active = intel_crtc_get_status(&intel_crtc->base);
+   intel_crtc->bpp = intel_crtc_get_bpp(&intel_crtc->base);
 
if (HAS_PCH_SPLIT(dev)) {
if (pipe == 2 && IS_IVYBRIDGE(dev))
@@ -9091,6 +9150,9 @@ static void i915_disable_vga(struct drm_device *dev)
 void intel_modeset_init(struct drm_device *dev)
 {
struct drm_i915_private *dev_priv = dev->dev_private;
+   struct drm_crtc *crtc;
+   struct drm_encoder *encoder;
+   struct drm_connector *connector;
int i, ret;
 
drm_mode_config_init(dev);
@@ -9142,6 +9204,9 @@ void intel_modeset_init(struct drm_device *dev)
gen6_update_ring_freq(dev_priv);
}
 
+   list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
+   intel_crtc_get_config(crtc);
+
INIT_WORK(&dev_priv->idle_work, intel_idle_update);
setup_timer(&dev_priv->idle_timer, intel_gpu_idle_timer,
(unsigned long)dev);
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 39eccf9..3e24f0b 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -2360,6 +2360,26 @@ intel_dp_add_properties(struct intel_dp *intel_dp, 
struct drm_connector *connect
intel_attach_broadcast_rgb_property(connector);
 }
 
+static struct drm_crtc *intel_dp_get_crtc(struct drm_encoder *encoder)
+{
+   struct drm_device *dev = encoder->dev;
+   struct drm_i915_private *dev_priv = dev->dev_private;
+   struct drm_crtc *crtc;
+   struct intel_crtc *intel_crtc;
+   struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
+   int pipe;
+
+   pipe = (I915_READ(intel_dp->output_reg) & DP_PIPE_MASK) >> 30;
+
+   list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
+   intel_crtc = to_intel_crtc(crtc);
+   if (intel_crtc->pipe == pipe)
+   return crtc;
+   }
+
+   return NULL;
+}
+
 void
 intel_dp_init(struct drm_device *dev, int output_reg)
 {
@@ -2419,6 +2439,7 @@ 

Re: [Intel-gfx] [PATCH 26/43] drm/i915: Only clear the GPU domains upon a successful finish

2012-03-01 Thread Daniel Vetter
On Wed, Dec 14, 2011 at 01:57:23PM +0100, Daniel Vetter wrote:
> From: Chris Wilson 
> 
> By clearing the GPU read domains before waiting upon the buffer, we run
> the risk of the wait being interrupted and the domains prematurely
> cleared. The next time we attempt to wait upon the buffer (after
> userspace handles the signal), we believe that the buffer is idle and so
> skip the wait.
> 
> There are a number of bugs across all generations which show signs of an
> overly haste reuse of active buffers.
> 
> Such as:
> 
>   https://bugs.freedesktop.org/show_bug.cgi?id=29046
>   https://bugs.freedesktop.org/show_bug.cgi?id=35863
>   https://bugs.freedesktop.org/show_bug.cgi?id=38952
>   https://bugs.freedesktop.org/show_bug.cgi?id=40282
>   https://bugs.freedesktop.org/show_bug.cgi?id=41098
>   https://bugs.freedesktop.org/show_bug.cgi?id=41102
>   https://bugs.freedesktop.org/show_bug.cgi?id=41284
>   https://bugs.freedesktop.org/show_bug.cgi?id=42141
> 
> A couple of those pre-date i915_gem_object_finish_gpu(), so may be
> unrelated (such as a wild write from a userspace command buffer), but
> this does look like a convincing cause for most of those bugs.
> 
> Signed-off-by: Chris Wilson 
> Cc: sta...@kernel.org
> Reviewed-by: Daniel Vetter 
> Reviewed-by: Eugeni Dodonov 

I really hate it that we have neither a solid testcase nor a decen
explanation for how exactly this fixes issues. But there have been too
many reports from people that this patch here at least improves matters.

/me grumpily merges this for -next.

-Daniel
-- 
Daniel Vetter
Mail: dan...@ffwll.ch
Mobile: +41 (0)79 365 57 48
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] Updated -next

2012-03-01 Thread Daniel Vetter
Hi all,

I've just pushed out update -next and -testing trees. Highlights:
- gmbus fixes, gmbus is now again enabled by default.
- random smaller fixes.

... so not too much this time around. For the 3.4 I think we should now
slowly wind down, of the big outstanding patch series I think only the
pwrite series might still get in. But it has blown up so often in 'final'
review already that I am sceptical.

In other news I'll be at osts next week and on vacation the following
week, so expect slow response times from me and an extended -next cycle.

Happy testing!

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


Re: [Intel-gfx] [RFC] drm/i915: read current config at init time to avoid flicker

2012-03-01 Thread Jesse Barnes
On Thu, 1 Mar 2012 12:37:47 -0800
Jesse Barnes  wrote:

> The intent here is to build enough of the configuration to allow
> set_config to avoid mode setting if possible.
> 
> Seems to speed up boot a bit on my Dell E6510; should help other eDP
> platforms as well.
> 
> One thing that's missing is creating an initial fb for whatever's
> display at driver load time.  This would involve poking around in the
> display regs to get the offset and making bo and fb objects for the
> current framebuffer.

Here's an updated version that works on LVDS too.

-- 
Jesse Barnes, Intel Open Source Technology Center


diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index cdcf99b..70118834 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -7637,6 +7637,66 @@ static const struct drm_crtc_funcs intel_crtc_funcs = {
.page_flip = intel_crtc_page_flip,
 };
 
+static int intel_crtc_get_bpp(struct drm_crtc *crtc)
+{
+   struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+   int pipeconf;
+   int ret;
+
+   pipeconf = PIPECONF(intel_crtc->pipe);
+
+   switch (pipeconf & PIPE_BPC_MASK) {
+   case PIPE_6BPC:
+   ret = 18;
+   break;
+   case PIPE_8BPC:
+   ret = 24;
+   break;
+   case PIPE_10BPC:
+   ret = 30;
+   break;
+   case PIPE_12BPC:
+   ret = 36;
+   break;
+   default:
+   ret = 24;
+   break;
+   }
+
+   return ret;
+}
+
+static bool intel_crtc_get_status(struct drm_crtc *crtc)
+{
+   struct drm_device *dev = crtc->dev;
+   struct drm_i915_private *dev_priv = dev->dev_private;
+   struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+   int dspcntr, pipeconf;
+
+   dspcntr = DSPCNTR(intel_crtc->pipe);
+   pipeconf = PIPECONF(intel_crtc->pipe);
+
+   if ((I915_READ(dspcntr) & DISPLAY_PLANE_ENABLE) &&
+   (I915_READ(pipeconf) & PIPECONF_ENABLE))
+   return true;
+
+   return false;
+}
+
+/*
+ * Get current mode, encoder, and connector info for this CRTC
+ */
+static void intel_crtc_get_config(struct drm_crtc *crtc)
+{
+   struct drm_device *dev = crtc->dev;
+   struct drm_display_mode *mode;
+
+   mode = intel_crtc_mode_get(dev, crtc);
+   crtc->mode = *mode;
+   kfree(mode);
+   crtc->enabled = drm_helper_crtc_in_use(crtc);
+}
+
 static void intel_crtc_init(struct drm_device *dev, int pipe)
 {
drm_i915_private_t *dev_priv = dev->dev_private;
@@ -7669,9 +7729,8 @@ static void intel_crtc_init(struct drm_device *dev, int 
pipe)
dev_priv->plane_to_crtc_mapping[intel_crtc->plane] = &intel_crtc->base;
dev_priv->pipe_to_crtc_mapping[intel_crtc->pipe] = &intel_crtc->base;
 
-   intel_crtc_reset(&intel_crtc->base);
-   intel_crtc->active = true; /* force the pipe off on setup_init_config */
-   intel_crtc->bpp = 24; /* default for pre-Ironlake */
+   intel_crtc->active = intel_crtc_get_status(&intel_crtc->base);
+   intel_crtc->bpp = intel_crtc_get_bpp(&intel_crtc->base);
 
if (HAS_PCH_SPLIT(dev)) {
if (pipe == 2 && IS_IVYBRIDGE(dev))
@@ -9091,6 +9150,7 @@ static void i915_disable_vga(struct drm_device *dev)
 void intel_modeset_init(struct drm_device *dev)
 {
struct drm_i915_private *dev_priv = dev->dev_private;
+   struct drm_crtc *crtc;
int i, ret;
 
drm_mode_config_init(dev);
@@ -9142,6 +9202,9 @@ void intel_modeset_init(struct drm_device *dev)
gen6_update_ring_freq(dev_priv);
}
 
+   list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
+   intel_crtc_get_config(crtc);
+
INIT_WORK(&dev_priv->idle_work, intel_idle_update);
setup_timer(&dev_priv->idle_timer, intel_gpu_idle_timer,
(unsigned long)dev);
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 39eccf9..3e24f0b 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -2360,6 +2360,26 @@ intel_dp_add_properties(struct intel_dp *intel_dp, 
struct drm_connector *connect
intel_attach_broadcast_rgb_property(connector);
 }
 
+static struct drm_crtc *intel_dp_get_crtc(struct drm_encoder *encoder)
+{
+   struct drm_device *dev = encoder->dev;
+   struct drm_i915_private *dev_priv = dev->dev_private;
+   struct drm_crtc *crtc;
+   struct intel_crtc *intel_crtc;
+   struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
+   int pipe;
+
+   pipe = (I915_READ(intel_dp->output_reg) & DP_PIPE_MASK) >> 30;
+
+   list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
+   intel_crtc = to_intel_crtc(crtc);
+   if (intel_crtc->pipe == pipe)
+   return crtc;
+   }
+
+   return NULL;
+}
+
 void
 intel_dp_init(struct drm_dev

Re: [Intel-gfx] [RFC] drm/i915: read current config at init time to avoid flicker

2012-03-01 Thread Chris Wilson
On Thu, 1 Mar 2012 14:18:58 -0800, Jesse Barnes  
wrote:
> @@ -2427,6 +2448,8 @@ intel_dp_init(struct drm_device *dev, int output_reg)
>   intel_connector_attach_encoder(intel_connector, intel_encoder);
>   drm_sysfs_connector_add(connector);
>  
> + intel_encoder->base.crtc = intel_dp_get_crtc(&intel_encoder->base);
intel_encoder->base.crtc = 
dev_priv->pipe_to_crtc_mapping[intel_dp_get_pipe(intel_dp)]

As the pipe-to-crtc mapping is already established by this point, and
indeed used in the LVDS chunk, you may as well use it here.
-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] [RFC] drm/i915: read current config at init time to avoid flicker

2012-03-01 Thread Jesse Barnes
On Thu, 01 Mar 2012 22:41:45 +
Chris Wilson  wrote:

> On Thu, 1 Mar 2012 14:18:58 -0800, Jesse Barnes
>  wrote:
> > @@ -2427,6 +2448,8 @@ intel_dp_init(struct drm_device *dev, int
> > output_reg) intel_connector_attach_encoder(intel_connector,
> > intel_encoder); drm_sysfs_connector_add(connector);
> >  
> > +   intel_encoder->base.crtc =
> > intel_dp_get_crtc(&intel_encoder->base);
> intel_encoder->base.crtc =
> dev_priv->pipe_to_crtc_mapping[intel_dp_get_pipe(intel_dp)]
> 
> As the pipe-to-crtc mapping is already established by this point, and
> indeed used in the LVDS chunk, you may as well use it here.

Ah yeah good point, that saves a bit of code.

Unfortunately, the dp code will still shut off the panel in ->prepare.
To avoid that at boot time, we need a valid fb...

An easy approach might be to allocate a bo of the appropriate size at
CRTC init time, and create an fb for it like we do in the intel_fb.c
code.  We can simply memcpy from the current base into the new bo, flip
to it, and have a valid crtc->fb from very early on...

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


Re: [Intel-gfx] [RFC] drm/i915: read current config at init time to avoid flicker

2012-03-01 Thread Keith Packard
<#part sign=pgpmime>
On Thu, 1 Mar 2012 12:37:47 -0800, Jesse Barnes  
wrote:
> The intent here is to build enough of the configuration to allow
> set_config to avoid mode setting if possible.

When I played with this, not setting the fb across this process tended
to do 'bad' things to the hardware -- the scanout would get unmapped
when the GTT was initialized...

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


Re: [Intel-gfx] [RFC] drm/i915: read current config at init time to avoid flicker

2012-03-01 Thread Jesse Barnes
On Thu, 01 Mar 2012 16:08:03 -0800
Keith Packard  wrote:

> <#part sign=pgpmime>
> On Thu, 1 Mar 2012 12:37:47 -0800, Jesse Barnes  
> wrote:
> > The intent here is to build enough of the configuration to allow
> > set_config to avoid mode setting if possible.
> 
> When I played with this, not setting the fb across this process tended
> to do 'bad' things to the hardware -- the scanout would get unmapped
> when the GTT was initialized...
> 

Yeah we shouldn't do that.  That's why I'd like to allocate a bo, copy
the contents, and have a real fb associated with each active crtc.
That should avoid any problems with scanning out unmapped memory.

-- 
Jesse Barnes, 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] [RFC] drm/i915: read current config at init time to avoid flicker

2012-03-01 Thread Keith Packard
<#part sign=pgpmime>
On Thu, 1 Mar 2012 16:52:43 -0800, Jesse Barnes  
wrote:

> Yeah we shouldn't do that.  That's why I'd like to allocate a bo, copy
> the contents, and have a real fb associated with each active crtc.
> That should avoid any problems with scanning out unmapped memory.

It's a bit tricky as we have to do this across GTT initialization. It
should be possible to duplicate the existing GTT mapping for the frame
buffer up high in GTT space, reset the frame buffer base to that, then
initialize the rest of the GTT, map the new frame buffer and then clean
up the GTT after the fbdev mode set. Ick.

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