Paul Owen | 1 Mar 2012 03:43
Favicon

Re: HDMI colour space and depth questions (YCbCr, xvYCC, Deep Colour)

On 29 February 2012 18:36, Jesse Barnes <jbarnes <at> virtuousgeek.org> wrote:
>
> Can you file a bug with the findings above just so we don't lose it?  I
> expect the fix should be pretty easy, but I don't want to lose track of
> this.

Done - hope that I submitted to the right place in the right way! Thanks again.

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

Paul
Muhammad Jamil via Yahoo! | 1 Mar 2012 07:04
Picon
Favicon

Muhammad Jamil invites you to connect

this email was sent to you by an automated system - please do not reply directly
Join Muhammad Jamil on Yahoo! Messenger.
Come chat with me, share files and more.

Stay in the loop with all your friends. Get started

  • Stay connected at home, at work, or on the go
  • Have fun with games, emoticons, and more
  • Join a community of over 100 million people from around the world
Join Your Friends
Get easy, one-click access to your favorites. Make Yahoo! your homepage.
Trouble with the button above? Click the link below or copy and paste it into your browser's address bar:
http://invite.msg.yahoo.com/invite?op=accept&intl=us&sig=kWBCvshIMGDauR4TZmRlPvf7B_vw5St_DE_.NxtguEHV3f7JstsazUHYieZW
_______________________________________________
Intel-gfx mailing list
Intel-gfx <at> lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Takashi Iwai | 1 Mar 2012 07:37
Picon

Re: [PATCH] drm/i915: Don't write DSPSURF for old chips

At Wed, 29 Feb 2012 23:54:46 +0000,
Chris Wilson wrote:
> 
> On Tue, 28 Feb 2012 07:43:55 +0100, Takashi Iwai <tiwai <at> suse.de> wrote:
> > At Mon, 27 Feb 2012 14:08:28 +0100,
> > Takashi Iwai wrote:
> > > 
> > > At Mon, 27 Feb 2012 12:17:57 +0000,
> > > Chris Wilson wrote:
> > > > 
> > > > On Mon, 27 Feb 2012 12:39:24 +0100, Takashi Iwai <tiwai <at> suse.de> wrote:
> > > > > It seems that writing DSPSURF in intel_flush_display_plane() causes
> > > > > the blank screen on some old laptops like Dell D630 with 965GM.
> > > > > Since this operation is needed only for ILK+, make it conditional.
> > > > 
> > > > The specs say that DSPASURF is the latch register for updates of the DSPA
> > > > registers on gen4 (including 965gm) as well. Presumably the bug is that
> > > > we only partially update the DSPA registers prior to the first call to
> > > > intel_flush_display_plane() which this papers over by disabling the
> > > > update until a valid address is written to DSPASURF. And there is such a
> > > > spurious call to intel_enable_plane() prior to us setting a valid
> > > > scanout surface:
> > > 
> > > Sounds reasonable.  FWIW, the change was first introduced in commit
> > > [b24e7179: drm/i915: add pipe/plane enable/disable functions],
> > > then in commit [efc2924e: drm/i915: Call intel_enable_plane from
> > > i9xx_crtc_mode_set (again)], it's placed into i9xx_crtc_mode_set().
> > > 
> > > This explains the fact that it was discovered only on old machines
> > > as i9xx_crtc_mode_set() is the only crtc_mode_set op calling
> > > intel_enable_plane().
> > > 
> > > BTW, the bisection leaded to a merge commit, so the bug is really
> > > depending on the activation path or timing.
> > > 
> > > I'll ask a tester to try your patch.
> > 
> > He reported back that it reduces the failure rate but doesn't fix
> > completely.  Still get a blank screen in 20% rate.
> > 
> > Any other clue?
> 
> I haven't yet found anything else in the same vein as this, but the
> 965gm does ring a warning bell for this recent regression:
> 
> commit 5ca0c34ae28344b6b4ca3036bc82f89c8db16a59
> Author: Dave Airlie <airlied <at> redhat.com>
> Date:   Thu Feb 23 15:33:40 2012 +0000
> 
>     drm/i915: fix mode set on load pipe. (v2)
>     
>     Booted my i965 machine and it started printing the unsupported pixel
>     format of 0 message (once I added content to it).
>     
>     Oh looksie here, we pass 0. fix.
>     
>     v2: compile it.
>     
>     Buzilla: https://bugs.freedesktop.org/show_bug.cgi?id=45966
>     
>     Reviewed-by: Daniel Vetter <daniel.vetter <at> ffwll.ch>
>     Reviewed-by: Chris Wilson <chris <at> chris-wilson.co.uk>
>     Signed-off-by: Dave Airlie <airlied <at> redhat.com>
>     Signed-off-by: Jesse Barnes <jbarnes <at> virtuousgeek.org>
> 
> which is currently sitting in airlied/drm-fixes.

Hm, this must be irrelevant (inapplicable) because the tests were done
with 3.1, 3.2 (and SLE11-SP2 kernels which has backports from 3.3-rc2
but without these fixes).  The bug seems to have been introduced
between 3.0 and 3.1.

thanks,

Takashi
Michal Mocny | 1 Mar 2012 17:41
Picon
Favicon

Re: Shared memory management

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 <at> lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Daniel Vetter | 1 Mar 2012 20:36
Picon
Gravatar

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

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 <daniel.vetter <at> ffwll.ch>
---
 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
 <at>  <at>  -333,6 +333,28  <at>  <at>  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
 <at>  <at>  -345,8 +367,9  <at>  <at>  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,
 <at>  <at>  -655,9 +678,10  <at>  <at>  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,
 <at>  <at>  -667,8 +691,9  <at>  <at>  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;
 <at>  <at>  -716,6 +741,7  <at>  <at>  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
 		 *
 <at>  <at>  -728,13 +754,6  <at>  <at>  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));
-
 		if (obj->pages) {
 			page = obj->pages[offset >> PAGE_SHIFT];
 			release_page = 0;
 <at>  <at>  -750,6 +769,19  <at>  <at>  i915_gem_shmem_pwrite(struct drm_device *dev,
 		page_do_bit17_swizzling = obj_do_bit17_swizzling &&
 			(page_to_phys(page) & (1 << 17)) != 0;

+		/* If we need swizzling, ensure that we always flush both
+		 * channels (otherwise we'd need to swizzle the clflushing,
+		 * which is a pain). */
+		clflush_size = page_do_bit17_swizzling ?
+			boot_cpu_data.x86_clflush_size : 128;
+
+		/* 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)
+				& (clflush_size - 1));
+
 		ret = shmem_pwrite_fast(page, shmem_page_offset, page_length,
 					user_data, page_do_bit17_swizzling,
 					partial_cacheline_write, needs_clflush);
--

-- 
1.7.8.3
Daniel Vetter | 1 Mar 2012 20:36
Picon
Gravatar

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

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 <daniel.vetter <at> ffwll.ch>
---
 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
 <at>  <at>  -318,7 +318,7  <at>  <at>  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);
 <at>  <at>  -337,7 +337,7  <at>  <at>  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;

 <at>  <at>  -648,7 +648,7  <at>  <at>  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);
 <at>  <at>  -678,7 +678,7  <at>  <at>  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
Jesse Barnes | 1 Mar 2012 21:37
Favicon

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

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
 <at>  <at>  -7637,6 +7637,66  <at>  <at>  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;
 <at>  <at>  -7669,9 +7729,8  <at>  <at>  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))
 <at>  <at>  -9091,6 +9150,9  <at>  <at>  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);
 <at>  <at>  -9142,6 +9204,9  <at>  <at>  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
 <at>  <at>  -2360,6 +2360,26  <at>  <at>  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)
 {
 <at>  <at>  -2419,6 +2439,7  <at>  <at>  intel_dp_init(struct drm_device *dev, int output_reg)
 	intel_encoder->crtc_mask = (1 << 0) | (1 << 1) | (1 << 2);
 	connector->interlace_allowed = true;
 	connector->doublescan_allowed = 0;
+	connector->encoder = &intel_encoder->base;

 	drm_encoder_init(dev, &intel_encoder->base, &intel_dp_enc_funcs,
 			 DRM_MODE_ENCODER_TMDS);
 <at>  <at>  -2427,6 +2448,8  <at>  <at>  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);
+
 	/* Set up the DDC bus. */
 	switch (output_reg) {
 		case DP_A:
 <at>  <at>  -2538,4 +2561,6  <at>  <at>  intel_dp_init(struct drm_device *dev, int output_reg)
 		u32 temp = I915_READ(PEG_BAND_GAP_DATA);
 		I915_WRITE(PEG_BAND_GAP_DATA, (temp & ~0xf) | 0xd);
 	}
+
+	connector->status = intel_dp_detect(connector, 0);
 }
Daniel Vetter | 1 Mar 2012 21:40
Picon
Gravatar

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

On Wed, Dec 14, 2011 at 01:57:23PM +0100, Daniel Vetter wrote:
> From: Chris Wilson <chris <at> chris-wilson.co.uk>
> 
> 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 <chris <at> chris-wilson.co.uk>
> Cc: stable <at> kernel.org
> Reviewed-by: Daniel Vetter <daniel.vetter <at> ffwll.ch>
> Reviewed-by: Eugeni Dodonov <eugeni.dodonov <at> intel.com>

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: daniel <at> ffwll.ch
Mobile: +41 (0)79 365 57 48
Daniel Vetter | 1 Mar 2012 21:59
Picon
Gravatar

Updated -next

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: daniel <at> ffwll.ch
Mobile: +41 (0)79 365 57 48
Jesse Barnes | 1 Mar 2012 23:18
Favicon

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

On Thu, 1 Mar 2012 12:37:47 -0800
Jesse Barnes <jbarnes <at> virtuousgeek.org> 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
 <at>  <at>  -7637,6 +7637,66  <at>  <at>  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;
 <at>  <at>  -7669,9 +7729,8  <at>  <at>  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))
 <at>  <at>  -9091,6 +9150,7  <at>  <at>  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);
 <at>  <at>  -9142,6 +9202,9  <at>  <at>  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
 <at>  <at>  -2360,6 +2360,26  <at>  <at>  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)
 {
 <at>  <at>  -2419,6 +2439,7  <at>  <at>  intel_dp_init(struct drm_device *dev, int output_reg)
 	intel_encoder->crtc_mask = (1 << 0) | (1 << 1) | (1 << 2);
 	connector->interlace_allowed = true;
 	connector->doublescan_allowed = 0;
+	connector->encoder = &intel_encoder->base;

 	drm_encoder_init(dev, &intel_encoder->base, &intel_dp_enc_funcs,
 			 DRM_MODE_ENCODER_TMDS);
 <at>  <at>  -2427,6 +2448,8  <at>  <at>  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);
+
 	/* Set up the DDC bus. */
 	switch (output_reg) {
 		case DP_A:
 <at>  <at>  -2538,4 +2561,6  <at>  <at>  intel_dp_init(struct drm_device *dev, int output_reg)
 		u32 temp = I915_READ(PEG_BAND_GAP_DATA);
 		I915_WRITE(PEG_BAND_GAP_DATA, (temp & ~0xf) | 0xd);
 	}
+
+	connector->status = intel_dp_detect(connector, 0);
 }
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c
index b103c3b..db73089 100644
--- a/drivers/gpu/drm/i915/intel_lvds.c
+++ b/drivers/gpu/drm/i915/intel_lvds.c
 <at>  <at>  -937,6 +937,7  <at>  <at>  bool intel_lvds_init(struct drm_device *dev)
 	connector->display_info.subpixel_order = SubPixelHorizontalRGB;
 	connector->interlace_allowed = false;
 	connector->doublescan_allowed = false;
+	connector->encoder = encoder;

 	/* create the scaling mode property */
 	drm_mode_create_scaling_mode_property(dev);
 <at>  <at>  -1021,6 +1022,8  <at>  <at>  bool intel_lvds_init(struct drm_device *dev)
 	pipe = (lvds & LVDS_PIPEB_SELECT) ? 1 : 0;
 	crtc = intel_get_crtc_for_pipe(dev, pipe);

+	encoder->crtc = crtc;
+
 	if (crtc && (lvds & LVDS_PORT_EN)) {
 		intel_lvds->fixed_mode = intel_crtc_mode_get(dev, crtc);
 		if (intel_lvds->fixed_mode) {
 <at>  <at>  -1076,6 +1079,8  <at>  <at>  out:
 	dev_priv->int_lvds_connector = connector;
 	drm_sysfs_connector_add(connector);

+	connector->status = intel_lvds_detect(connector, 0);
+
 	intel_panel_setup_backlight(dev);

 	return true;

--

-- 
Jesse Barnes, Intel Open Source Technology Center

Gmane