Re: [Intel-gfx] [PATCH v3.5 02.5/22] drm/i915: add intel_display_suspend

2015-05-22 Thread Matt Roper
On Thu, May 21, 2015 at 02:33:31PM +0200, Maarten Lankhorst wrote:
> This is a function used to disable all crtc's. This makes it clearer
> to distinguish between when mode needs to be preserved and when
> it can be trashed.

To clarify, when you talk about mode being preserved or trashed here,
you're talking about the hardware's idea of the mode, not the driver's
software state, right?  I.e., because when we shut down a power well the
registers vanish and whatever was programmed in them is lost?

See my comments farther down.

> 
> Signed-off-by: Maarten Lankhorst 
> ---
> Oops, I was trashing all state during suspend and on gpu reset.
> I will send an amended intel_crtc_control patch too with the
> suspend and prepare_reset parts taken out.
> 
>  drivers/gpu/drm/i915/i915_drv.c  |  4 +---
>  drivers/gpu/drm/i915/intel_display.c | 29 +++--
>  drivers/gpu/drm/i915/intel_drv.h |  1 +
>  3 files changed, 21 insertions(+), 13 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
> index 5cc57f2ec192..d1a090a9f653 100644
> --- a/drivers/gpu/drm/i915/i915_drv.c
> +++ b/drivers/gpu/drm/i915/i915_drv.c
> @@ -600,7 +600,6 @@ static int skl_resume_prepare(struct drm_i915_private 
> *dev_priv);
>  static int i915_drm_suspend(struct drm_device *dev)
>  {
>   struct drm_i915_private *dev_priv = dev->dev_private;
> - struct drm_crtc *crtc;
>   pci_power_t opregion_target_state;
>   int error;
>  
> @@ -631,8 +630,7 @@ static int i915_drm_suspend(struct drm_device *dev)
>* for _thaw. Also, power gate the CRTC power wells.
>*/
>   drm_modeset_lock_all(dev);
> - for_each_crtc(dev, crtc)
> - intel_crtc_control(crtc, false);
> + intel_display_suspend(dev);

I'm not terribly familiar with the power well details, but it looks like
part of the motivation of commit

commit b04c5bd6fda54703e56f29569e4bca489d6c5a5c
Author: Borun Fu 
Date:   Sat Jul 12 10:02:27 2014 +0530

drm/i915: Power gating display wells during i915_pm_suspend

which added intel_crtc_control() was to ensure the power wells were
gated at this point; by replacing the intel_crtc_control() with
intel_display_suspend() here, you're removing that power well
programming...is that intentional (and is it going to cause the display
to stay in D0 state)?

If it is intentional, the comment above this block is out of date now.
Since this patch (and the following one) seem to change the semantics of
when we're touching power wells at various points in the code, maybe you
can elaborate a little bit on that in the commit message of one or both
commits.


Matt

>   drm_modeset_unlock_all(dev);
>  
>   intel_dp_mst_suspend(dev);
> diff --git a/drivers/gpu/drm/i915/intel_display.c 
> b/drivers/gpu/drm/i915/intel_display.c
> index cae36ec1c2ef..8d50c4ca561f 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -3204,9 +3204,6 @@ void intel_crtc_reset(struct intel_crtc *crtc)
>  
>  void intel_prepare_reset(struct drm_device *dev)
>  {
> - struct drm_i915_private *dev_priv = to_i915(dev);
> - struct intel_crtc *crtc;
> -
>   /* no reset support for gen2 */
>   if (IS_GEN2(dev))
>   return;
> @@ -3221,13 +3218,7 @@ void intel_prepare_reset(struct drm_device *dev)
>* Disabling the crtcs gracefully seems nicer. Also the
>* g33 docs say we should at least disable all the planes.
>*/
> - for_each_intel_crtc(dev, crtc) {
> - if (!crtc->active)
> - continue;
> -
> - intel_crtc_disable_planes(&crtc->base);
> - dev_priv->display.crtc_disable(&crtc->base);
> - }
> + intel_display_suspend(dev);
>  }
>  
>  void intel_finish_reset(struct drm_device *dev)
> @@ -6018,6 +6009,24 @@ static void i9xx_crtc_disable(struct drm_crtc *crtc)
>   mutex_unlock(&dev->struct_mutex);
>  }
>  
> +/*
> + * turn all crtc's off, but do not adjust state
> + * This has to be paired with a call to intel_modeset_setup_hw_state.
> + */
> +void intel_display_suspend(struct drm_device *dev)
> +{
> + struct drm_i915_private *dev_priv = to_i915(dev);
> + struct drm_crtc *crtc;
> +
> + for_each_crtc(dev, crtc) {
> + if (!to_intel_crtc(crtc)->active)
> + continue;
> +
> + intel_crtc_disable_planes(crtc);
> + dev_priv->display.crtc_disable(crtc);
> + }
> +}
> +
>  /* Master function to enable/disable CRTC and corresponding power wells */
>  void intel_crtc_control(struct drm_crtc *crtc, bool enable)
>  {
> diff --git a/drivers/gpu/drm/i915/intel_drv.h 
> b/drivers/gpu/drm/i915/intel_drv.h
> index 70d0cc8fe70e..c24d670529e3 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -992,6 +992,7 @@ int intel_pch_rawclk(struct drm_device *dev);
>  void intel_mark_busy(struct drm_

[Intel-gfx] drivers/gpu/drm/i915/i915_gem_gtt.c

2015-05-22 Thread Andrew Morton

I'm not sure what's happened to the drm code in linux-next - it's
exploding all over the place.  Did someone turn on -Werror without
doing anywhere near enough testing?

Anyway, I don't know how to fix this i386 build error:

drivers/gpu/drm/i915/i915_gem_gtt.c: In function 'gen8_ppgtt_init':
drivers/gpu/drm/i915/i915_gem_gtt.c:954:2: error: large integer implicitly 
truncated to unsigned type [-Werror=overflow]

ppgtt->base.total = 1ULL << 32;

i915_address_space.total is a ulong: 32-bit.

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


Re: [Intel-gfx] [PATCH] drm/i915: Disable idle messaging before ring disable

2015-05-22 Thread Chris Wilson
On Fri, May 22, 2015 at 08:18:46PM +0300, Mika Kuoppala wrote:
> diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c 
> b/drivers/gpu/drm/i915/intel_ringbuffer.c
> index d934f85..c06dc76 100644
> --- a/drivers/gpu/drm/i915/intel_ringbuffer.c
> +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
> @@ -531,6 +531,31 @@ static void intel_ring_setup_status_page(struct 
> intel_engine_cs *ring)
>   }
>  }
>  
> +static void disable_ring(struct intel_engine_cs *ring)
> +{
> + struct drm_i915_private *dev_priv = to_i915(ring->dev);
> + const bool need_idle_disable = ring->id == RCS &&
> + INTEL_INFO(ring->dev)->gen > 7;
> +
> + assert_forcewakes_active(dev_priv);
> +
> + if (need_idle_disable) {
> + I915_WRITE(RING_PSMI_CTL(ring->mmio_base),
> +_MASKED_BIT_ENABLE(GEN6_PSMI_SLEEP_MSG_DISABLE));
[snip]
> + if (need_idle_disable)
> + I915_WRITE(GEN6_RC_SLEEP_PSMI_CONTROL,
> +_MASKED_BIT_DISABLE(GEN6_PSMI_SLEEP_MSG_DISABLE));

Snap!

Oh wait.
-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] Fix resume from suspend to RAM on IBM X30

2015-05-22 Thread Thomas Richter

Hi folks,

this is re-submitting the intel DVO patch that closes bug #49838, namely
that resuming from suspend-to-RAM on the IBM x30 leaves the laptop with
a blank screen. See the attached patch for details.

Please let me know what else is missing to make this patch go into the
kernel. It has been tested by Stefan Monnier, see 
https://bugs.freedesktop.org/show_bug.cgi?id=49838

for details.

Thanks,
Thomas
>From 8ea307cc203d217cb6513ace045678d06c23ad61 Mon Sep 17 00:00:00 2001
From: Thomas Richter 
Date: Fri, 22 May 2015 20:55:54 +0200
Subject: [PATCH 1/1] Fixes for IBM x30 suspend to ram.

This patch fixes the resume from suspend on the X30
thinkpad. The bug is due to the X30 bios failing to
restore the IVCH (DVO) registers, specifically the PLL
registers.

This patch makes a backup of the internal DVO registers upon
initialization - assuming that the BIOS sets up everything
correctly. The values are then restored whenever the mode
has to be restored.

Signed-off-by: Thomas Richter 
---
 drivers/gpu/drm/i915/dvo_ivch.c |  119 +++
 1 file changed, 95 insertions(+), 24 deletions(-)

diff --git a/drivers/gpu/drm/i915/dvo_ivch.c b/drivers/gpu/drm/i915/dvo_ivch.c
index baaf65b..d60edf8 100644
--- a/drivers/gpu/drm/i915/dvo_ivch.c
+++ b/drivers/gpu/drm/i915/dvo_ivch.c
@@ -22,6 +22,7 @@
  *
  * Authors:
  *Eric Anholt 
+ *Thomas Richter 
  *
  */
 
@@ -59,6 +60,8 @@
 # define VR01_DVO_BYPASS_ENABLE		(1 << 1)
 /** Enables the DVO clock */
 # define VR01_DVO_ENABLE		(1 << 0)
+/** Enables dithering */
+# define VR01_DITHER_ENABLE (1 << 4)
 
 /*
  * LCD Interface Format
@@ -83,7 +86,7 @@
 /*
  * LCD Vertical Display Size
  */
-#define VR21	0x20
+#define VR21	0x21
 
 /*
  * Panel power down status
@@ -148,16 +151,41 @@
 # define VR8F_POWER_MASK		(0x3c)
 # define VR8F_POWER_POS			(2)
 
+/* Some Bios implementations do not restore the DVO state upon
+ * resume from standby. Thus, this driver has to handle it
+ * instead. The following list contains all registers that
+ * require saving.
+ */
+static const uint16_t backup_addresses[] = {
+	0x11, 0x12,
+	0x18, 0x19, 0x1a, 0x1f,
+	0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
+	0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+	0x8e, 0x8f,
+	0x10		/* this must come last */
+};
+
 
 struct ivch_priv {
 	bool quiet;
 
 	uint16_t width, height;
+
+	/* Register backup */
+
+	uint16_t reg_backup[ARRAY_SIZE(backup_addresses)];
 };
 
 
 static void ivch_dump_regs(struct intel_dvo_device *dvo);
 
+static inline struct intel_gmbus *
+to_intel_gmbus(struct i2c_adapter *i2c)
+{
+	return container_of(i2c, struct intel_gmbus, adapter);
+}
+
+
 /**
  * Reads a register on the ivch.
  *
@@ -167,6 +195,7 @@ static bool ivch_read(struct intel_dvo_device *dvo, int addr, uint16_t *data)
 {
 	struct ivch_priv *priv = dvo->dev_priv;
 	struct i2c_adapter *adapter = dvo->i2c_bus;
+	struct intel_gmbus *bus = to_intel_gmbus(adapter);
 	u8 out_buf[1];
 	u8 in_buf[2];
 
@@ -191,17 +220,19 @@ static bool ivch_read(struct intel_dvo_device *dvo, int addr, uint16_t *data)
 	};
 
 	out_buf[0] = addr;
-
+	bus->force_bit++; /* the IVCH requires bit-banging */
 	if (i2c_transfer(adapter, msgs, 3) == 3) {
 		*data = (in_buf[1] << 8) | in_buf[0];
+		bus->force_bit--;
 		return true;
-	};
+	}
 
 	if (!priv->quiet) {
 		DRM_DEBUG_KMS("Unable to read register 0x%02x from "
 "%s:%02x.\n",
 			  addr, adapter->name, dvo->slave_addr);
 	}
+	bus->force_bit--;
 	return false;
 }
 
@@ -210,6 +241,7 @@ static bool ivch_write(struct intel_dvo_device *dvo, int addr, uint16_t data)
 {
 	struct ivch_priv *priv = dvo->dev_priv;
 	struct i2c_adapter *adapter = dvo->i2c_bus;
+	struct intel_gmbus *bus = to_intel_gmbus(adapter);
 	u8 out_buf[3];
 	struct i2c_msg msg = {
 		.addr = dvo->slave_addr,
@@ -221,15 +253,19 @@ static bool ivch_write(struct intel_dvo_device *dvo, int addr, uint16_t data)
 	out_buf[0] = addr;
 	out_buf[1] = data & 0xff;
 	out_buf[2] = data >> 8;
+	bus->force_bit++; /* bit-banging required for the IVCH */
 
-	if (i2c_transfer(adapter, &msg, 1) == 1)
+	if (i2c_transfer(adapter, &msg, 1) == 1) {
+		bus->force_bit--;
 		return true;
+	}
 
 	if (!priv->quiet) {
 		DRM_DEBUG_KMS("Unable to write register 0x%02x to %s:%d.\n",
 			  addr, adapter->name, dvo->slave_addr);
 	}
 
+	bus->force_bit--;
 	return false;
 }
 
@@ -239,6 +275,7 @@ static bool ivch_init(struct intel_dvo_device *dvo,
 {
 	struct ivch_priv *priv;
 	uint16_t temp;
+	int i;
 
 	priv = kzalloc(sizeof(struct ivch_priv), GFP_KERNEL);
 	if (priv == NULL)
@@ -266,6 +303,14 @@ static bool ivch_init(struct intel_dvo_device *dvo,
 	ivch_read(dvo, VR20, &priv->width);
 	ivch_read(dvo, VR21, &priv->height);
 
+	/* Make a backup of the registers to be able to restore them
+	 * upon suspend.
+	 */
+	for (i = 0; i < ARRAY_SIZE(backup_addresses); i++)
+		ivch_read(dvo, backup_addresses[i], priv->reg_backup + i);
+
+	ivch_dump_regs(dvo);
+
 	return true;
 
 out:
@@ -287,12 +332,31 @@ static en

[Intel-gfx] [PATCH] Enable dithering on the S6010 notebook and others

2015-05-22 Thread Thomas Richter

Hi folks,

the attached patch enables dithering for the Fujitsu S6010 notebook (and 
others using the ns2501 DVO chip). It also uses explicit programming for 
*some* of the DVO registers whose functions I revealed by reverse 
engineering (thus, guesswork).


Please let me know what is missing to include this patch in the kernel.

Greetings,
Thomas
>From 3353aee162b45b8a03fa13e470858b5157263831 Mon Sep 17 00:00:00 2001
From: Thomas Richter 
Date: Fri, 22 May 2015 19:56:28 +0200
Subject: [PATCH 1/1] Added the dithering enable for the ns2501.

This patch enables dithering for notebooks using the ns2501 DVO
chip. For that, the DVO bypass for the native display resolution
has to be disabled, and timing values for the 1024x768 resolution
had to be added.

This patch also reveals some of the internals of the DVO, which is
unfortunately not documented. Hence, register meanings are only the
result of reverse engineering.

Signed-off-by: Thomas Richter 
---
 drivers/gpu/drm/i915/dvo_ns2501.c |  693 +++--
 1 file changed, 441 insertions(+), 252 deletions(-)

diff --git a/drivers/gpu/drm/i915/dvo_ns2501.c b/drivers/gpu/drm/i915/dvo_ns2501.c
index 954acb2..924383d 100644
--- a/drivers/gpu/drm/i915/dvo_ns2501.c
+++ b/drivers/gpu/drm/i915/dvo_ns2501.c
@@ -60,32 +60,328 @@
 
 #define NS2501_REGC 0x0c
 
-struct ns2501_priv {
-	//I2CDevRec d;
-	bool quiet;
-	int reg_8_shadow;
-	int reg_8_set;
-	// Shadow registers for i915
-	int dvoc;
-	int pll_a;
-	int srcdim;
-	int fw_blc;
+/*
+ * The following registers are not part of the official datasheet
+ * and are the result of reverse engineering.
+ */
+
+/*
+ * Register c0 controls how the DVO synchronizes with
+ * its input.
+ */
+#define NS2501_REGC0 0xc0
+#define NS2501_C0_ENABLE (1<<0)	/* enable the DVO sync in general */
+#define NS2501_C0_HSYNC (1<<1)	/* synchronize horizontal with input */
+#define NS2501_C0_VSYNC (1<<2)	/* synchronize vertical with input */
+#define NS2501_C0_RESET (1<<7)	/* reset the synchronization flip/flops */
+
+/*
+ * Register 41 is somehow related to the sync register and sync
+ * configuration. It should be 0x32 whenever regC0 is 0x05 (hsync off)
+ * and 0x00 otherwise.
+ */
+#define NS2501_REG41 0x41
+
+/*
+ * this register controls the dithering of the DVO
+ * One bit enables it, the other define the dithering depth.
+ * The higher the value, the lower the dithering depth.
+ */
+#define NS2501_F9_REG 0xf9
+#define NS2501_F9_ENABLE (1<<0)		/* if set, dithering is enabled */
+#define NS2501_F9_DITHER_MASK (0x7f<<1)	/* controls the dither depth */
+#define NS2501_F9_DITHER_SHIFT 1	/* shifts the dither mask */
+
+/*
+ * PLL configuration register. This is a pair of registers,
+ * one single byte register at 1B, and a pair at 1C,1D.
+ * These registers are counters/dividers.
+ */
+#define NS2501_REG1B 0x1b /* one byte PLL control register */
+#define NS2501_REG1C 0x1c /* low-part of the second register */
+#define NS2501_REG1D 0x1d /* high-part of the second register */
+
+/*
+ * Scaler control registers. Horizontal at b8,b9,
+ * vertical at 10,11. The scale factor is computed as
+ * 2^16/control-value. The low-byte comes first.
+ */
+#define NS2501_REG10 0x10 /* low-byte vertical scaler */
+#define NS2501_REG11 0x11 /* high-byte vertical scaler */
+#define NS2501_REGB8 0xb8 /* low-byte horizontal scaler */
+#define NS2501_REGB9 0xb9 /* high-byte horizontal scaler */
+
+/*
+ * Display window definition. This consists of four registers
+ * per dimension. One register pair defines the start of the
+ * display, one the end.
+ * As far as I understand, this defines the window within which
+ * the scaler samples the input.
+ */
+#define NS2501_REGC1 0xc1 /* low-byte horizontal display start */
+#define NS2501_REGC2 0xc2 /* high-byte horizontal display start */
+#define NS2501_REGC3 0xc3 /* low-byte horizontal display stop */
+#define NS2501_REGC4 0xc4 /* high-byte horizontal display stop */
+#define NS2501_REGC5 0xc5 /* low-byte vertical display start */
+#define NS2501_REGC6 0xc6 /* high-byte vertical display start */
+#define NS2501_REGC7 0xc7 /* low-byte vertical display stop */
+#define NS2501_REGC8 0xc8 /* high-byte vertical display stop */
+
+/*
+ * The following register pair seems to define the start of
+ * the vertical sync. If automatic syncing is enabled, and the
+ * register value defines a sync pulse that is later than the
+ * incoming sync, then the register value is ignored and the
+ * external hsync triggers the synchronization.
+ */
+#define NS2501_REG80 0x80 /* low-byte vsync-start */
+#define NS2501_REG81 0x81 /* high-byte vsync-start */
+
+/*
+ * The following register pair seems to define the total number
+ * of lines created at the output side of the scaler.
+ * This is again a low-high register pair.
+ */
+#define NS2501_REG82 0x82 /* output display height, low byte */
+#define NS2501_REG83 0x83 /* output display height, high byte */
+
+/*
+ * The following registers define the end of the fro

Re: [Intel-gfx] [PATCH 08/12] drm/i915: Add NV12 support to intel_framebuffer_init

2015-05-22 Thread Runyan, Arthur J
>From: Konduru, Chandra

>> >
>> > Hi Daniel,
>> > NV12 programming is documented in bspec under display planes "Plane
>> > Planar YUV programming". There it talks about aux_dist which is the
>> > distance between y and uv planes expecting uv to be after y.
>>
>> Bspec talks about wrap-around, which at least indicates that this might be
>> possible and the hw doesn't have a real restriction here. Art, can you please
>> double-check whether we could wrape-around PLANE_AUX_DIST with a 2s
>> complement to avoid placement restrictions on the aux buffers?
>>
>> Bspec doesn't say anything about this being required to be positive ...
>> -Daniel
>
>Yeah, it isn't explicit, so to be sure a while ago checked with hw team about
>uv plane positioning relative to y-plane. It was confirmed that aux_dist to be
>positive. Certainly Art can double confirm for you.
>
Positive is correct.  We'll update the bspec to make it clear. 
___
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: Add 90/270 rotation for NV12 format.

2015-05-22 Thread Ville Syrjälä
On Fri, May 22, 2015 at 06:07:36PM +, Runyan, Arthur J wrote:
> >From: Ville Syrjälä [mailto:ville.syrj...@linux.intel.com]
> 
> >On Mon, May 18, 2015 at 07:19:19PM +, Runyan, Arthur J wrote:
> >> The statement is correct - " the X offset must always be even for 
> >> YUV422+NV12,
> >and the Y offset must be even when rotated 90/270 degrees."
> >
> >Hmm. Can you elaborate a bit? I'm curious where this limitation comes
> >from.
> >
> Ah, I get what you are asking now.   They don't both have to be even when 
> roated.  The text should say " the X offset must be even for YUV422+NV12 
> ***when not rotated 90/270***, and the Y offset must be even when rotated 
> 90/270 degrees."  I'll fix that text.

Excellent. Thanks for confirming my hunch :)

-- 
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 2/2] drm/i915: Add 90/270 rotation for NV12 format.

2015-05-22 Thread Runyan, Arthur J
>From: Ville Syrjälä [mailto:ville.syrj...@linux.intel.com]

>On Mon, May 18, 2015 at 07:19:19PM +, Runyan, Arthur J wrote:
>> The statement is correct - " the X offset must always be even for 
>> YUV422+NV12,
>and the Y offset must be even when rotated 90/270 degrees."
>
>Hmm. Can you elaborate a bit? I'm curious where this limitation comes
>from.
>
Ah, I get what you are asking now.   They don't both have to be even when 
roated.  The text should say " the X offset must be even for YUV422+NV12 
***when not rotated 90/270***, and the Y offset must be even when rotated 
90/270 degrees."  I'll fix that text.
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] Updated drm-intel-testing

2015-05-22 Thread Daniel Vetter
Hi all,

New -testing cycle with cool stuff:
- cpt modeset sequence fixes from Ville
- more rps boosting tuning from Chris
- S3 support for skl (Damien)
- a pile of w/a for bxt from various people
- cleanup of primary plane pixel formats (Damien)
- a big pile of small patches with fixes and cleanups all over

Happy testing!

Cheers, Daniel

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH] drm/i915: Disable idle messaging before ring disable

2015-05-22 Thread Mika Kuoppala
According to bspec, with ring mode scheduling on gen >= 8,
we need to disable ring idle message before writing zero to
Ring Buffer Enable.

Signed-off-by: Mika Kuoppala 
---
 drivers/gpu/drm/i915/i915_drv.h |  2 ++
 drivers/gpu/drm/i915/i915_reg.h |  2 ++
 drivers/gpu/drm/i915/intel_ringbuffer.c | 28 +++-
 drivers/gpu/drm/i915/intel_uncore.c | 12 
 4 files changed, 43 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 1038f5c..564c593 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2609,6 +2609,8 @@ void intel_uncore_forcewake_get__locked(struct 
drm_i915_private *dev_priv,
 void intel_uncore_forcewake_put__locked(struct drm_i915_private *dev_priv,
enum forcewake_domains domains);
 void assert_forcewakes_inactive(struct drm_i915_private *dev_priv);
+void assert_forcewakes_active(struct drm_i915_private *dev_priv);
+
 static inline bool intel_vgpu_active(struct drm_device *dev)
 {
return to_i915(dev)->vgpu.active;
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 6eeba63..9bead93 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -1643,6 +1643,8 @@ enum skl_disp_power_wells {
 #define   GFX_PSMI_GRANULARITY (1<<10)
 #define   GFX_PPGTT_ENABLE (1<<9)
 
+#define CSPWRFSM   0x022AC
+
 #define VLV_DISPLAY_BASE 0x18
 #define VLV_MIPI_BASE VLV_DISPLAY_BASE
 
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c 
b/drivers/gpu/drm/i915/intel_ringbuffer.c
index d934f85..c06dc76 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -531,6 +531,31 @@ static void intel_ring_setup_status_page(struct 
intel_engine_cs *ring)
}
 }
 
+static void disable_ring(struct intel_engine_cs *ring)
+{
+   struct drm_i915_private *dev_priv = to_i915(ring->dev);
+   const bool need_idle_disable = ring->id == RCS &&
+   INTEL_INFO(ring->dev)->gen > 7;
+
+   assert_forcewakes_active(dev_priv);
+
+   if (need_idle_disable) {
+   I915_WRITE(RING_PSMI_CTL(ring->mmio_base),
+  _MASKED_BIT_ENABLE(GEN6_PSMI_SLEEP_MSG_DISABLE));
+
+   if (wait_for((I915_READ(CSPWRFSM) & ((1 << 6) - 1)) == 0x30,
+1000))
+   DRM_ERROR("%s: disable idle msg timeout\n",
+ ring->name);
+   }
+
+   I915_WRITE_CTL(ring, 0);
+
+   if (need_idle_disable)
+   I915_WRITE(GEN6_RC_SLEEP_PSMI_CONTROL,
+  _MASKED_BIT_DISABLE(GEN6_PSMI_SLEEP_MSG_DISABLE));
+}
+
 static bool stop_ring(struct intel_engine_cs *ring)
 {
struct drm_i915_private *dev_priv = to_i915(ring->dev);
@@ -548,7 +573,8 @@ static bool stop_ring(struct intel_engine_cs *ring)
}
}
 
-   I915_WRITE_CTL(ring, 0);
+   disable_ring(ring);
+
I915_WRITE_HEAD(ring, 0);
ring->write_tail(ring, 0);
 
diff --git a/drivers/gpu/drm/i915/intel_uncore.c 
b/drivers/gpu/drm/i915/intel_uncore.c
index a6d8a3e..4e070e0 100644
--- a/drivers/gpu/drm/i915/intel_uncore.c
+++ b/drivers/gpu/drm/i915/intel_uncore.c
@@ -525,6 +525,18 @@ void assert_forcewakes_inactive(struct drm_i915_private 
*dev_priv)
WARN_ON(domain->wake_count);
 }
 
+void assert_forcewakes_active(struct drm_i915_private *dev_priv)
+{
+   struct intel_uncore_forcewake_domain *domain;
+   enum forcewake_domain_id id;
+
+   if (!dev_priv->uncore.funcs.force_wake_get)
+   return;
+
+   for_each_fw_domain(domain, dev_priv, id)
+   WARN_ON(domain->wake_count == 0);
+}
+
 /* We give fast paths for the really cool registers */
 #define NEEDS_FORCE_WAKE(dev_priv, reg) \
 ((reg) < 0x4 && (reg) != FORCEWAKE)
-- 
1.9.1

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


[Intel-gfx] [PATCH 2/2] drm/i915: Let hardware keep track of ctx buf read pointer

2015-05-22 Thread Mika Kuoppala
We initialize the internal read pointer to zero on init/reset,
but only the reset will actually zero the write pointer.
This means that on module reload we might re-read context
status buffers that were written prior reload.

It is safest just to let the hardware keep track of the read pointer,
so that we get valid value as there is no driver state involved.

Signed-off-by: Mika Kuoppala 
---
 drivers/gpu/drm/i915/i915_debugfs.c |  6 +++---
 drivers/gpu/drm/i915/intel_lrc.c| 11 ---
 drivers/gpu/drm/i915/intel_ringbuffer.h |  2 +-
 3 files changed, 8 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c 
b/drivers/gpu/drm/i915/i915_debugfs.c
index fece922..b079dd3 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -2026,8 +2026,8 @@ static int i915_execlists(struct seq_file *m, void *data)
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_engine_cs *ring;
u32 status_pointer;
-   u8 read_pointer;
-   u8 write_pointer;
+   u32 read_pointer;
+   u32 write_pointer;
u32 status;
u32 ctx_id;
struct list_head *cursor;
@@ -2060,7 +2060,7 @@ static int i915_execlists(struct seq_file *m, void *data)
status_pointer = I915_READ(RING_CONTEXT_STATUS_PTR(ring));
seq_printf(m, "\tStatus pointer: 0x%08X\n", status_pointer);
 
-   read_pointer = ring->next_context_status_buffer;
+   read_pointer = (status_pointer >> 8) & 0x07;
write_pointer = status_pointer & 0x07;
if (read_pointer > write_pointer)
write_pointer += 6;
diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
index 14dec0d..f03e81f 100644
--- a/drivers/gpu/drm/i915/intel_lrc.c
+++ b/drivers/gpu/drm/i915/intel_lrc.c
@@ -494,15 +494,15 @@ void intel_lrc_irq_handler(struct intel_engine_cs *ring)
 {
struct drm_i915_private *dev_priv = ring->dev->dev_private;
u32 status_pointer;
-   u8 read_pointer;
-   u8 write_pointer;
+   u32 read_pointer;
+   u32 write_pointer;
u32 status;
u32 status_id;
u32 submit_contexts = 0;
 
status_pointer = I915_READ(RING_CONTEXT_STATUS_PTR(ring));
 
-   read_pointer = ring->next_context_status_buffer;
+   read_pointer = (status_pointer >> 8) & 0x07;
write_pointer = status_pointer & 0x07;
if (read_pointer > write_pointer)
write_pointer += 6;
@@ -537,11 +537,9 @@ void intel_lrc_irq_handler(struct intel_engine_cs *ring)
spin_unlock(&ring->execlist_lock);
 
WARN(submit_contexts > 2, "More than two context complete events?\n");
-   ring->next_context_status_buffer = write_pointer % 6;
 
I915_WRITE(RING_CONTEXT_STATUS_PTR(ring),
-  _MASKED_FIELD(0x07 << 8,
-((u32)ring->next_context_status_buffer & 0x07) 
<< 8));
+  _MASKED_FIELD(0x07 << 8, (write_pointer % 6) << 8));
 }
 
 static int execlists_context_queue(struct intel_engine_cs *ring,
@@ -1090,7 +1088,6 @@ static int gen8_init_common_ring(struct intel_engine_cs 
*ring)
   _MASKED_BIT_DISABLE(GFX_REPLAY_MODE) |
   _MASKED_BIT_ENABLE(GFX_RUN_LIST_ENABLE));
POSTING_READ(RING_MODE_GEN7(ring));
-   ring->next_context_status_buffer = 0;
DRM_DEBUG_DRIVER("Execlists enabled for %s\n", ring->name);
 
memset(&ring->hangcheck, 0, sizeof(ring->hangcheck));
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h 
b/drivers/gpu/drm/i915/intel_ringbuffer.h
index 39f6dfc..400d69f 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.h
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.h
@@ -240,7 +240,7 @@ struct  intel_engine_cs {
spinlock_t execlist_lock;
struct list_head execlist_queue;
struct list_head execlist_retired_req_list;
-   u8 next_context_status_buffer;
+
u32 irq_keep_mask; /* bitmask for interrupts that should 
not be masked */
int (*emit_request)(struct intel_ringbuffer *ringbuf,
struct drm_i915_gem_request *request);
-- 
1.9.1

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


[Intel-gfx] [PATCH 1/2] drm/i915: Use masked write for Context Status Buffer Pointer

2015-05-22 Thread Mika Kuoppala
This register needs to be updated with masked writes.

Cc: Damien Lespiau 
Cc: Thomas Daniel 
Signed-off-by: Mika Kuoppala 
---
 drivers/gpu/drm/i915/intel_lrc.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
index 96ae90a..14dec0d 100644
--- a/drivers/gpu/drm/i915/intel_lrc.c
+++ b/drivers/gpu/drm/i915/intel_lrc.c
@@ -540,7 +540,8 @@ void intel_lrc_irq_handler(struct intel_engine_cs *ring)
ring->next_context_status_buffer = write_pointer % 6;
 
I915_WRITE(RING_CONTEXT_STATUS_PTR(ring),
-  ((u32)ring->next_context_status_buffer & 0x07) << 8);
+  _MASKED_FIELD(0x07 << 8,
+((u32)ring->next_context_status_buffer & 0x07) 
<< 8));
 }
 
 static int execlists_context_queue(struct intel_engine_cs *ring,
-- 
1.9.1

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


[Intel-gfx] [PATCH 05/21] drm/i915/gtt: Don't leak scratch page on mapping error

2015-05-22 Thread Mika Kuoppala
Free the scratch page if dma mapping fails.

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

diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/i915_gem_gtt.c
index c61de4a..a608b1b 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -2191,8 +2191,10 @@ static int setup_scratch_page(struct drm_device *dev)
 #ifdef CONFIG_INTEL_IOMMU
dma_addr = pci_map_page(dev->pdev, page, 0, PAGE_SIZE,
PCI_DMA_BIDIRECTIONAL);
-   if (pci_dma_mapping_error(dev->pdev, dma_addr))
+   if (pci_dma_mapping_error(dev->pdev, dma_addr)) {
+   __free_page(page);
return -EINVAL;
+   }
 #else
dma_addr = page_to_phys(page);
 #endif
-- 
1.9.1

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


[Intel-gfx] [PATCH 20/21] drm/i915/gtt: Use nonatomic bitmap ops

2015-05-22 Thread Mika Kuoppala
There is no need for atomicity here. Convert all bitmap
operations to nonatomic variants.

Cc: Ville Syrjälä 
Signed-off-by: Mika Kuoppala 
---
 drivers/gpu/drm/i915/i915_gem_gtt.c | 12 ++--
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/i915_gem_gtt.c
index ab113ce..95c39e5 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -842,7 +842,7 @@ static int gen8_ppgtt_alloc_pagetabs(struct i915_hw_ppgtt 
*ppgtt,
 
gen8_initialize_pt(&ppgtt->base, pt);
pd->page_table[pde] = pt;
-   set_bit(pde, new_pts);
+   __set_bit(pde, new_pts);
}
 
return 0;
@@ -900,7 +900,7 @@ static int gen8_ppgtt_alloc_page_directories(struct 
i915_hw_ppgtt *ppgtt,
 
gen8_initialize_pd(&ppgtt->base, pd);
pdp->page_directory[pdpe] = pd;
-   set_bit(pdpe, new_pds);
+   __set_bit(pdpe, new_pds);
}
 
return 0;
@@ -1040,7 +1040,7 @@ static int gen8_alloc_va_range(struct i915_address_space 
*vm,
   gen8_pte_count(pd_start, pd_len));
 
/* Our pde is now pointing to the pagetable, pt */
-   set_bit(pde, pd->used_pdes);
+   __set_bit(pde, pd->used_pdes);
 
/* Map the PDE to the page table */
page_directory[pde] = gen8_pde_encode(px_dma(pt),
@@ -1052,7 +1052,7 @@ static int gen8_alloc_va_range(struct i915_address_space 
*vm,
 
kunmap_px(ppgtt, page_directory);
 
-   set_bit(pdpe, ppgtt->pdp.used_pdpes);
+   __set_bit(pdpe, ppgtt->pdp.used_pdpes);
}
 
free_gen8_temp_bitmaps(new_page_dirs, new_page_tables);
@@ -1497,7 +1497,7 @@ static int gen6_alloc_va_range(struct i915_address_space 
*vm,
gen6_initialize_pt(vm, pt);
 
ppgtt->pd.page_table[pde] = pt;
-   set_bit(pde, new_page_tables);
+   __set_bit(pde, new_page_tables);
trace_i915_page_table_entry_alloc(vm, pde, start, 
GEN6_PDE_SHIFT);
}
 
@@ -1511,7 +1511,7 @@ static int gen6_alloc_va_range(struct i915_address_space 
*vm,
bitmap_set(tmp_bitmap, gen6_pte_index(start),
   gen6_pte_count(start, length));
 
-   if (test_and_clear_bit(pde, new_page_tables))
+   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,
-- 
1.9.1

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


[Intel-gfx] [PATCH 10/21] drm/i915/gtt: Remove superfluous free_pd with gen6/7

2015-05-22 Thread Mika Kuoppala
This has slipped in somewhere but it was harmless
as we check the page pointer before teardown.

Signed-off-by: Mika Kuoppala 
---
 drivers/gpu/drm/i915/i915_gem_gtt.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/i915_gem_gtt.c
index f58aa63..f747bd3 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -1416,7 +1416,6 @@ static void gen6_ppgtt_cleanup(struct i915_address_space 
*vm)
}
 
free_pt(ppgtt->base.dev, ppgtt->scratch_pt);
-   free_pd(ppgtt->base.dev, &ppgtt->pd);
 }
 
 static int gen6_ppgtt_allocate_page_directories(struct i915_hw_ppgtt *ppgtt)
-- 
1.9.1

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


[Intel-gfx] [PATCH 11/21] drm/i915/gtt: Introduce fill_page_dma()

2015-05-22 Thread Mika Kuoppala
When we setup page directories and tables, we point the entries
to a to the next level scratch structure. Make this generic
by introducing a fill_page_dma which maps and flushes. We also
need 32 bit variant for legacy gens.

v2: Fix flushes and handle valleyview (Ville)

Signed-off-by: Mika Kuoppala 
---
 drivers/gpu/drm/i915/i915_gem_gtt.c | 71 +++--
 1 file changed, 37 insertions(+), 34 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/i915_gem_gtt.c
index f747bd3..d020b5e 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -330,6 +330,31 @@ static void cleanup_page_dma(struct drm_device *dev, 
struct i915_page_dma *p)
memset(p, 0, sizeof(*p));
 }
 
+static void fill_page_dma(struct drm_device *dev, struct i915_page_dma *p,
+ const uint64_t val)
+{
+   int i;
+   uint64_t * const vaddr = kmap_atomic(p->page);
+
+   for (i = 0; i < 512; i++)
+   vaddr[i] = val;
+
+   if (!HAS_LLC(dev) && !IS_VALLEYVIEW(dev))
+   drm_clflush_virt_range(vaddr, PAGE_SIZE);
+
+   kunmap_atomic(vaddr);
+}
+
+static void fill_page_dma_32(struct drm_device *dev, struct i915_page_dma *p,
+const uint32_t val32)
+{
+   uint64_t v = val32;
+
+   v = v << 32 | val32;
+
+   fill_page_dma(dev, p, v);
+}
+
 static void free_pt(struct drm_device *dev, struct i915_page_table *pt)
 {
cleanup_page_dma(dev, &pt->base);
@@ -340,19 +365,11 @@ static void free_pt(struct drm_device *dev, struct 
i915_page_table *pt)
 static void gen8_initialize_pt(struct i915_address_space *vm,
   struct i915_page_table *pt)
 {
-   gen8_pte_t *pt_vaddr, scratch_pte;
-   int i;
-
-   pt_vaddr = kmap_atomic(pt->base.page);
-   scratch_pte = gen8_pte_encode(vm->scratch.addr,
- I915_CACHE_LLC, true);
+   gen8_pte_t scratch_pte;
 
-   for (i = 0; i < GEN8_PTES; i++)
-   pt_vaddr[i] = scratch_pte;
+   scratch_pte = gen8_pte_encode(vm->scratch.addr, I915_CACHE_LLC, true);
 
-   if (!HAS_LLC(vm->dev))
-   drm_clflush_virt_range(pt_vaddr, PAGE_SIZE);
-   kunmap_atomic(pt_vaddr);
+   fill_page_dma(vm->dev, &pt->base, scratch_pte);
 }
 
 static struct i915_page_table *alloc_pt(struct drm_device *dev)
@@ -585,20 +602,13 @@ static void gen8_initialize_pd(struct i915_address_space 
*vm,
   struct i915_page_directory *pd)
 {
struct i915_hw_ppgtt *ppgtt =
-   container_of(vm, struct i915_hw_ppgtt, base);
-   gen8_pde_t *page_directory;
-   struct i915_page_table *pt;
-   int i;
+   container_of(vm, struct i915_hw_ppgtt, base);
+   gen8_pde_t scratch_pde;
 
-   page_directory = kmap_atomic(pd->base.page);
-   pt = ppgtt->scratch_pt;
-   for (i = 0; i < I915_PDES; i++)
-   /* Map the PDE to the page table */
-   __gen8_do_map_pt(page_directory + i, pt, vm->dev);
+   scratch_pde = gen8_pde_encode(vm->dev, ppgtt->scratch_pt->base.daddr,
+ I915_CACHE_LLC);
 
-   if (!HAS_LLC(vm->dev))
-   drm_clflush_virt_range(page_directory, PAGE_SIZE);
-   kunmap_atomic(page_directory);
+   fill_page_dma(vm->dev, &pd->base, scratch_pde);
 }
 
 static void gen8_free_page_tables(struct i915_page_directory *pd, struct 
drm_device *dev)
@@ -1292,22 +1302,15 @@ static void gen6_ppgtt_insert_entries(struct 
i915_address_space *vm,
 }
 
 static void gen6_initialize_pt(struct i915_address_space *vm,
-   struct i915_page_table *pt)
+  struct i915_page_table *pt)
 {
-   gen6_pte_t *pt_vaddr, scratch_pte;
-   int i;
+   gen6_pte_t scratch_pte;
 
WARN_ON(vm->scratch.addr == 0);
 
-   scratch_pte = vm->pte_encode(vm->scratch.addr,
-   I915_CACHE_LLC, true, 0);
-
-   pt_vaddr = kmap_atomic(pt->base.page);
-
-   for (i = 0; i < GEN6_PTES; i++)
-   pt_vaddr[i] = scratch_pte;
+   scratch_pte = vm->pte_encode(vm->scratch.addr, I915_CACHE_LLC, true, 0);
 
-   kunmap_atomic(pt_vaddr);
+   fill_page_dma_32(vm->dev, &pt->base, scratch_pte);
 }
 
 static int gen6_alloc_va_range(struct i915_address_space *vm,
-- 
1.9.1

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


[Intel-gfx] [PATCH 19/21] drm/i915/gtt: One instance of scratch page table/directory

2015-05-22 Thread Mika Kuoppala
As we use one scratch page for all ppgtt instances, we can
use one scratch page table and scratch directory across
all ppgtt instances, saving 2 pages + structs per ppgtt.

v2: Rebase

Signed-off-by: Mika Kuoppala 
---
 drivers/gpu/drm/i915/i915_gem_gtt.c | 273 +++-
 1 file changed, 178 insertions(+), 95 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 61f4da0..ab113ce 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -430,6 +430,17 @@ fail_bitmap:
return ERR_PTR(ret);
 }
 
+static void gen6_initialize_pt(struct i915_address_space *vm,
+  struct i915_page_table *pt)
+{
+   gen6_pte_t scratch_pte;
+
+   scratch_pte = vm->pte_encode(px_dma(vm->scratch_page),
+I915_CACHE_LLC, true, 0);
+
+   fill32_px(vm->dev, pt, scratch_pte);
+}
+
 static void free_pd(struct drm_device *dev, struct i915_page_directory *pd)
 {
if (px_page(pd)) {
@@ -467,6 +478,156 @@ free_pd:
return ERR_PTR(ret);
 }
 
+static void gen8_initialize_pd(struct i915_address_space *vm,
+  struct i915_page_directory *pd)
+{
+   gen8_pde_t scratch_pde;
+
+   scratch_pde = gen8_pde_encode(px_dma(vm->scratch_pt), I915_CACHE_LLC);
+
+   fill_px(vm->dev, pd, scratch_pde);
+}
+
+#define SCRATCH_PAGE_MAGIC 0x00ff00ffULL
+
+static int alloc_scratch_page(struct i915_address_space *vm)
+{
+   struct i915_page_scratch *sp;
+   int ret;
+
+   WARN_ON(vm->scratch_page);
+
+   sp = kzalloc(sizeof(*sp), GFP_KERNEL);
+   if (sp == NULL)
+   return -ENOMEM;
+
+   ret = __setup_page_dma(vm->dev, px_base(sp), GFP_DMA32 | __GFP_ZERO);
+   if (ret) {
+   kfree(sp);
+   return ret;
+   }
+
+   fill_px(vm->dev, sp, SCRATCH_PAGE_MAGIC);
+   set_pages_uc(px_page(sp), 1);
+
+   vm->scratch_page = sp;
+
+   return 0;
+}
+
+static void free_scratch_page(struct i915_address_space *vm)
+{
+   struct i915_page_scratch *sp = vm->scratch_page;
+
+   set_pages_wb(px_page(sp), 1);
+
+   cleanup_px(vm->dev, sp);
+   kfree(sp);
+
+   vm->scratch_page = NULL;
+}
+
+static int setup_scratch_ggtt(struct i915_address_space *vm)
+{
+   int ret;
+
+   ret = alloc_scratch_page(vm);
+   if (ret)
+   return ret;
+
+   WARN_ON(vm->scratch_pt);
+
+   if (INTEL_INFO(vm->dev)->gen < 6)
+   return 0;
+
+   vm->scratch_pt = alloc_pt(vm->dev);
+   if (IS_ERR(vm->scratch_pt))
+   return PTR_ERR(vm->scratch_pt);
+
+   WARN_ON(px_dma(vm->scratch_page) == 0);
+
+   if (INTEL_INFO(vm->dev)->gen >= 8) {
+   gen8_initialize_pt(vm, vm->scratch_pt);
+
+   WARN_ON(vm->scratch_pd);
+
+   vm->scratch_pd = alloc_pd(vm->dev);
+   if (IS_ERR(vm->scratch_pd)) {
+   ret = PTR_ERR(vm->scratch_pd);
+   goto err_pd;
+   }
+
+   WARN_ON(px_dma(vm->scratch_pt) == 0);
+   gen8_initialize_pd(vm, vm->scratch_pd);
+   } else {
+   gen6_initialize_pt(vm, vm->scratch_pt);
+   }
+
+   return 0;
+
+err_pd:
+   free_pt(vm->dev, vm->scratch_pt);
+   return ret;
+}
+
+static int setup_scratch(struct i915_address_space *vm)
+{
+   struct i915_address_space *ggtt_vm = &to_i915(vm->dev)->gtt.base;
+
+   if (i915_is_ggtt(vm))
+   return setup_scratch_ggtt(vm);
+
+   vm->scratch_page = ggtt_vm->scratch_page;
+   vm->scratch_pt = ggtt_vm->scratch_pt;
+   vm->scratch_pd = ggtt_vm->scratch_pd;
+
+   return 0;
+}
+
+static void check_scratch_page(struct i915_address_space *vm)
+{
+   struct i915_hw_ppgtt *ppgtt =
+   container_of(vm, struct i915_hw_ppgtt, base);
+   int i;
+   u64 *vaddr;
+
+   vaddr = kmap_px(vm->scratch_page);
+
+   for (i = 0; i < PAGE_SIZE / sizeof(u64); i++) {
+   if (vaddr[i] == SCRATCH_PAGE_MAGIC)
+   continue;
+
+   DRM_ERROR("%p scratch[%d] = 0x%08llx\n", vm, i, vaddr[i]);
+   break;
+   }
+
+   kunmap_px(ppgtt, vaddr);
+}
+
+static void cleanup_scratch_ggtt(struct i915_address_space *vm)
+{
+   check_scratch_page(vm);
+   free_scratch_page(vm);
+
+   if (INTEL_INFO(vm->dev)->gen < 6)
+   return;
+
+   free_pt(vm->dev, vm->scratch_pt);
+
+   if (INTEL_INFO(vm->dev)->gen >= 8)
+   free_pd(vm->dev, vm->scratch_pd);
+}
+
+static void cleanup_scratch(struct i915_address_space *vm)
+{
+   if (i915_is_ggtt(vm))
+   cleanup_scratch_ggtt(vm);
+
+   vm->scratch_page = NULL;
+   vm->scratch_pt = NULL;
+   vm->scratch_pd = NULL;
+}
+
 /* Broadwell Page Directory Pointer Descriptors */
 static int gen8_write_pdp(struct intel

[Intel-gfx] [PATCH 03/21] drm/i915/gtt: Check va range against vm size

2015-05-22 Thread Mika Kuoppala
Check the allocation area against the known end
of address space instead of against fixed value.

v2: Return ENODEV on internal bugs (Chris)

Signed-off-by: Mika Kuoppala 
---
 drivers/gpu/drm/i915/i915_gem_gtt.c | 18 +++---
 1 file changed, 11 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 1a5ad4c..76de781 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -756,9 +756,6 @@ static int gen8_ppgtt_alloc_page_directories(struct 
i915_hw_ppgtt *ppgtt,
 
WARN_ON(!bitmap_empty(new_pds, GEN8_LEGACY_PDPES));
 
-   /* FIXME: upper bound must not overflow 32 bits  */
-   WARN_ON((start + length) > (1ULL << 32));
-
gen8_for_each_pdpe(pd, pdp, start, length, temp, pdpe) {
if (pd)
continue;
@@ -857,7 +854,10 @@ static int gen8_alloc_va_range(struct i915_address_space 
*vm,
 * actually use the other side of the canonical address space.
 */
if (WARN_ON(start + length < start))
-   return -ERANGE;
+   return -ENODEV;
+
+   if (WARN_ON(start + length > ppgtt->base.total))
+   return -ENODEV;
 
ret = alloc_gen8_temp_bitmaps(&new_page_dirs, &new_page_tables);
if (ret)
@@ -1341,7 +1341,7 @@ static void gen6_initialize_pt(struct i915_address_space 
*vm,
 }
 
 static int gen6_alloc_va_range(struct i915_address_space *vm,
-  uint64_t start, uint64_t length)
+  uint64_t start_in, uint64_t length_in)
 {
DECLARE_BITMAP(new_page_tables, I915_PDES);
struct drm_device *dev = vm->dev;
@@ -1349,11 +1349,15 @@ static int gen6_alloc_va_range(struct 
i915_address_space *vm,
struct i915_hw_ppgtt *ppgtt =
container_of(vm, struct i915_hw_ppgtt, base);
struct i915_page_table *pt;
-   const uint32_t start_save = start, length_save = length;
+   uint32_t start, length, start_save, length_save;
uint32_t pde, temp;
int ret;
 
-   WARN_ON(upper_32_bits(start));
+   if (WARN_ON(start_in + length_in > ppgtt->base.total))
+   return -ENODEV;
+
+   start = start_save = start_in;
+   length = length_save = length_in;
 
bitmap_zero(new_page_tables, I915_PDES);
 
-- 
1.9.1

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


[Intel-gfx] [PATCH 09/21] drm/i915/gtt: Rename unmap_and_free_px to free_px

2015-05-22 Thread Mika Kuoppala
All the paging structures are now similar and mapped for
dma. The unmapping is taken care of by common accessors, so
don't overload the reader with such details.

Signed-off-by: Mika Kuoppala 
---
 drivers/gpu/drm/i915/i915_gem_gtt.c | 32 +++-
 1 file changed, 15 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 1e1a7a1..f58aa63 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -330,8 +330,7 @@ static void cleanup_page_dma(struct drm_device *dev, struct 
i915_page_dma *p)
memset(p, 0, sizeof(*p));
 }
 
-static void unmap_and_free_pt(struct i915_page_table *pt,
-  struct drm_device *dev)
+static void free_pt(struct drm_device *dev, struct i915_page_table *pt)
 {
cleanup_page_dma(dev, &pt->base);
kfree(pt->used_ptes);
@@ -387,8 +386,7 @@ fail_bitmap:
return ERR_PTR(ret);
 }
 
-static void unmap_and_free_pd(struct i915_page_directory *pd,
- struct drm_device *dev)
+static void free_pd(struct drm_device *dev, struct i915_page_directory *pd)
 {
if (pd->base.page) {
cleanup_page_dma(dev, &pd->base);
@@ -614,7 +612,7 @@ static void gen8_free_page_tables(struct 
i915_page_directory *pd, struct drm_dev
if (WARN_ON(!pd->page_table[i]))
continue;
 
-   unmap_and_free_pt(pd->page_table[i], dev);
+   free_pt(dev, pd->page_table[i]);
pd->page_table[i] = NULL;
}
 }
@@ -630,11 +628,11 @@ static void gen8_ppgtt_cleanup(struct i915_address_space 
*vm)
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);
+   free_pd(ppgtt->base.dev, ppgtt->pdp.page_directory[i]);
}
 
-   unmap_and_free_pd(ppgtt->scratch_pd, ppgtt->base.dev);
-   unmap_and_free_pt(ppgtt->scratch_pt, ppgtt->base.dev);
+   free_pd(ppgtt->base.dev, ppgtt->scratch_pd);
+   free_pt(ppgtt->base.dev, ppgtt->scratch_pt);
 }
 
 /**
@@ -687,7 +685,7 @@ static int gen8_ppgtt_alloc_pagetabs(struct i915_hw_ppgtt 
*ppgtt,
 
 unwind_out:
for_each_set_bit(pde, new_pts, I915_PDES)
-   unmap_and_free_pt(pd->page_table[pde], dev);
+   free_pt(dev, pd->page_table[pde]);
 
return -ENOMEM;
 }
@@ -745,7 +743,7 @@ static int gen8_ppgtt_alloc_page_directories(struct 
i915_hw_ppgtt *ppgtt,
 
 unwind_out:
for_each_set_bit(pdpe, new_pds, GEN8_LEGACY_PDPES)
-   unmap_and_free_pd(pdp->page_directory[pdpe], dev);
+   free_pd(dev, pdp->page_directory[pdpe]);
 
return -ENOMEM;
 }
@@ -902,11 +900,11 @@ static int gen8_alloc_va_range(struct i915_address_space 
*vm,
 err_out:
while (pdpe--) {
for_each_set_bit(temp, new_page_tables[pdpe], I915_PDES)
-   
unmap_and_free_pt(ppgtt->pdp.page_directory[pdpe]->page_table[temp], vm->dev);
+   free_pt(vm->dev, 
ppgtt->pdp.page_directory[pdpe]->page_table[temp]);
}
 
for_each_set_bit(pdpe, new_page_dirs, GEN8_LEGACY_PDPES)
-   unmap_and_free_pd(ppgtt->pdp.page_directory[pdpe], vm->dev);
+   free_pd(vm->dev, ppgtt->pdp.page_directory[pdpe]);
 
free_gen8_temp_bitmaps(new_page_dirs, new_page_tables);
mark_tlbs_dirty(ppgtt);
@@ -1395,7 +1393,7 @@ unwind_out:
struct i915_page_table *pt = ppgtt->pd.page_table[pde];
 
ppgtt->pd.page_table[pde] = ppgtt->scratch_pt;
-   unmap_and_free_pt(pt, vm->dev);
+   free_pt(vm->dev, pt);
}
 
mark_tlbs_dirty(ppgtt);
@@ -1414,11 +1412,11 @@ static void gen6_ppgtt_cleanup(struct 
i915_address_space *vm)
 
gen6_for_all_pdes(pt, ppgtt, pde) {
if (pt != ppgtt->scratch_pt)
-   unmap_and_free_pt(pt, ppgtt->base.dev);
+   free_pt(ppgtt->base.dev, pt);
}
 
-   unmap_and_free_pt(ppgtt->scratch_pt, ppgtt->base.dev);
-   unmap_and_free_pd(&ppgtt->pd, ppgtt->base.dev);
+   free_pt(ppgtt->base.dev, ppgtt->scratch_pt);
+   free_pd(ppgtt->base.dev, &ppgtt->pd);
 }
 
 static int gen6_ppgtt_allocate_page_directories(struct i915_hw_ppgtt *ppgtt)
@@ -1468,7 +1466,7 @@ alloc:
return 0;
 
 err_out:
-   unmap_and_free_pt(ppgtt->scratch_pt, ppgtt->base.dev);
+   free_pt(ppgtt->base.dev, ppgtt->scratch_pt);
return ret;
 }
 
-- 
1.9.1

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


[Intel-gfx] [PATCH 15/21] drm/i915/gtt: Fill scratch page

2015-05-22 Thread Mika Kuoppala
During review of dynamic page tables series, I was able
to hit a lite restore bug with execlists. I assume that
due to incorrect pd, the batch run out of legit address space
and into the scratch page area. The ACTHD was increasing
due to scratch being all zeroes (MI_NOOPs). And as gen8
address space is quite large, the hangcheck happily waited
for a long long time, keeping the process effectively stuck.

According to Chris Wilson any modern gpu will grind to halt
if it encounters commands of all ones. This seemed to do the
trick and hang was declared promptly when the gpu wandered into
the scratch land.

v2: Use 0x00ff pattern (Chris)

Cc: Chris Wilson 
Signed-off-by: Mika Kuoppala 
---
 drivers/gpu/drm/i915/i915_gem_gtt.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 43fa543..a2a0c88 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -2168,6 +2168,8 @@ void i915_global_gtt_cleanup(struct drm_device *dev)
vm->cleanup(vm);
 }
 
+#define SCRATCH_PAGE_MAGIC 0x00ff00ffULL
+
 static int alloc_scratch_page(struct i915_address_space *vm)
 {
struct i915_page_scratch *sp;
@@ -2185,6 +2187,7 @@ static int alloc_scratch_page(struct i915_address_space 
*vm)
return ret;
}
 
+   fill_px(vm->dev, sp, SCRATCH_PAGE_MAGIC);
set_pages_uc(px_page(sp), 1);
 
vm->scratch_page = sp;
-- 
1.9.1

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


[Intel-gfx] [PATCH 00/21] ppgtt cleanups / scratch merge (V2)

2015-05-22 Thread Mika Kuoppala
Hi,

I have replaced patch 2 from v1 series with version
that preallocates top level pdp structure with 32bit addressing
on architectures that have problems with pdp tlb flushes.

All issues raised with v1 should be addressed by this series.
Ville also noticed that copying scratch structures means unnecessary read
as we can straight out fill them. This change among others
triggered alot of rebasing thus new series.

I also included one patch that makes our bitops nonatomic.

Thanks,
-Mika

Mika Kuoppala (21):
  drm/i915/gtt: Mark TLBS dirty for gen8+
  drm/i915/gtt: Workaround for HW preload not flushing pdps
  drm/i915/gtt: Check va range against vm size
  drm/i915/gtt: Allow >= 4GB sizes for vm.
  drm/i915/gtt: Don't leak scratch page on mapping error
  drm/i915/gtt: Remove _single from page table allocator
  drm/i915/gtt: Introduce i915_page_dir_dma_addr
  drm/i915/gtt: Introduce struct i915_page_dma
  drm/i915/gtt: Rename unmap_and_free_px to free_px
  drm/i915/gtt: Remove superfluous free_pd with gen6/7
  drm/i915/gtt: Introduce fill_page_dma()
  drm/i915/gtt: Introduce kmap|kunmap for dma page
  drm/i915/gtt: Use macros to access dma mapped pages
  drm/i915/gtt: Make scratch page i915_page_dma compatible
  drm/i915/gtt: Fill scratch page
  drm/i915/gtt: Pin vma during virtual address allocation
  drm/i915/gtt: Cleanup page directory encoding
  drm/i915/gtt: Move scratch_pd and scratch_pt into vm area
  drm/i915/gtt: One instance of scratch page table/directory
  drm/i915/gtt: Use nonatomic bitmap ops
  drm/i915/gtt: Reorder page alloc/free/init functions

 drivers/char/agp/intel-gtt.c|   4 +-
 drivers/gpu/drm/i915/i915_debugfs.c |  44 +--
 drivers/gpu/drm/i915/i915_gem.c |   6 +-
 drivers/gpu/drm/i915/i915_gem_gtt.c | 709 +---
 drivers/gpu/drm/i915/i915_gem_gtt.h |  55 ++-
 drivers/gpu/drm/i915/i915_reg.h |  17 +
 drivers/gpu/drm/i915/intel_lrc.c|  19 +-
 include/drm/intel-gtt.h |   4 +-
 8 files changed, 499 insertions(+), 359 deletions(-)

-- 
1.9.1

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


[Intel-gfx] [PATCH 08/21] drm/i915/gtt: Introduce struct i915_page_dma

2015-05-22 Thread Mika Kuoppala
All our paging structures have struct page and dma address
for that page.

Add struct for page/dma address pairs and use it to make
the setup and teardown for different paging structures
identical.

Include the page directory offset also in the struct for legacy
gens. Rename it to clearly point out that it is offset into the
ggtt.

Signed-off-by: Mika Kuoppala 
---
 drivers/gpu/drm/i915/i915_debugfs.c |   2 +-
 drivers/gpu/drm/i915/i915_gem_gtt.c | 120 ++--
 drivers/gpu/drm/i915/i915_gem_gtt.h |  21 ---
 3 files changed, 60 insertions(+), 83 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c 
b/drivers/gpu/drm/i915/i915_debugfs.c
index c7a840b..22770aa 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -2245,7 +2245,7 @@ static void gen6_ppgtt_info(struct seq_file *m, struct 
drm_device *dev)
struct i915_hw_ppgtt *ppgtt = dev_priv->mm.aliasing_ppgtt;
 
seq_puts(m, "aliasing PPGTT:\n");
-   seq_printf(m, "pd gtt offset: 0x%08x\n", ppgtt->pd.pd_offset);
+   seq_printf(m, "pd gtt offset: 0x%08x\n", 
ppgtt->pd.base.ggtt_offset);
 
ppgtt->debug_dump(ppgtt, m);
}
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 18989f7..1e1a7a1 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -301,52 +301,39 @@ static gen6_pte_t iris_pte_encode(dma_addr_t addr,
return pte;
 }
 
-#define i915_dma_unmap_single(px, dev) \
-   __i915_dma_unmap_single((px)->daddr, dev)
-
-static void __i915_dma_unmap_single(dma_addr_t daddr,
-   struct drm_device *dev)
+static int setup_page_dma(struct drm_device *dev, struct i915_page_dma *p)
 {
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)
+   p->page = alloc_page(GFP_KERNEL);
+   if (!p->page)
+   return -ENOMEM;
 
-static int i915_dma_map_page_single(struct page *page,
-   struct drm_device *dev,
-   dma_addr_t *daddr)
-{
-   struct device *device = &dev->pdev->dev;
+   p->daddr = dma_map_page(device,
+   p->page, 0, 4096, PCI_DMA_BIDIRECTIONAL);
 
-   *daddr = dma_map_page(device, page, 0, 4096, PCI_DMA_BIDIRECTIONAL);
-   if (dma_mapping_error(device, *daddr))
-   return -ENOMEM;
+   if (dma_mapping_error(device, p->daddr)) {
+   __free_page(p->page);
+   return -EINVAL;
+   }
 
return 0;
 }
 
-static void unmap_and_free_pt(struct i915_page_table *pt,
-  struct drm_device *dev)
+static void cleanup_page_dma(struct drm_device *dev, struct i915_page_dma *p)
 {
-   if (WARN_ON(!pt->page))
+   if (WARN_ON(!p->page))
return;
 
-   i915_dma_unmap_single(pt, dev);
-   __free_page(pt->page);
+   dma_unmap_page(&dev->pdev->dev, p->daddr, 4096, PCI_DMA_BIDIRECTIONAL);
+   __free_page(p->page);
+   memset(p, 0, sizeof(*p));
+}
+
+static void unmap_and_free_pt(struct i915_page_table *pt,
+  struct drm_device *dev)
+{
+   cleanup_page_dma(dev, &pt->base);
kfree(pt->used_ptes);
kfree(pt);
 }
@@ -357,7 +344,7 @@ static void gen8_initialize_pt(struct i915_address_space 
*vm,
gen8_pte_t *pt_vaddr, scratch_pte;
int i;
 
-   pt_vaddr = kmap_atomic(pt->page);
+   pt_vaddr = kmap_atomic(pt->base.page);
scratch_pte = gen8_pte_encode(vm->scratch.addr,
  I915_CACHE_LLC, true);
 
@@ -386,19 +373,13 @@ static struct i915_page_table *alloc_pt(struct drm_device 
*dev)
if (!pt->used_ptes)
goto fail_bitmap;
 
-   pt->page = alloc_page(GFP_KERNEL);
-   if (!pt->page)
-   goto fail_page;
-
-   ret = i915_dma_map_single(pt, dev);
+   ret = setup_page_dma(dev, &pt->base);
if (ret)
-   goto fail_dma;
+   goto fail_page_m;
 
return pt;
 
-fail_dma:
-   __free_page(pt->page);
-fail_page:
+fail_page_m:
kfree(pt->used_ptes);
 fail_bitmap:
kfree(pt);
@@ -409,9 +390,8 @@ fail_bitmap:
 static void unmap_and_free_pd(struct i915_page_directory *pd,
  

[Intel-gfx] [PATCH 21/21] drm/i915/gtt: Reorder page alloc/free/init functions

2015-05-22 Thread Mika Kuoppala
Introduce base page handling functions in order of
alloc, free, init. No functional changes.

Signed-off-by: Mika Kuoppala 
---
 drivers/gpu/drm/i915/i915_gem_gtt.c | 54 ++---
 1 file changed, 27 insertions(+), 27 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 95c39e5..24f31ad 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -381,24 +381,6 @@ static void fill_page_dma_32(struct drm_device *dev, 
struct i915_page_dma *p,
fill_page_dma(dev, p, v);
 }
 
-static void free_pt(struct drm_device *dev, struct i915_page_table *pt)
-{
-   cleanup_px(dev, pt);
-   kfree(pt->used_ptes);
-   kfree(pt);
-}
-
-static void gen8_initialize_pt(struct i915_address_space *vm,
-  struct i915_page_table *pt)
-{
-   gen8_pte_t scratch_pte;
-
-   scratch_pte = gen8_pte_encode(px_dma(vm->scratch_page),
- I915_CACHE_LLC, true);
-
-   fill_px(vm->dev, pt, scratch_pte);
-}
-
 static struct i915_page_table *alloc_pt(struct drm_device *dev)
 {
struct i915_page_table *pt;
@@ -430,6 +412,24 @@ fail_bitmap:
return ERR_PTR(ret);
 }
 
+static void free_pt(struct drm_device *dev, struct i915_page_table *pt)
+{
+   cleanup_px(dev, pt);
+   kfree(pt->used_ptes);
+   kfree(pt);
+}
+
+static void gen8_initialize_pt(struct i915_address_space *vm,
+  struct i915_page_table *pt)
+{
+   gen8_pte_t scratch_pte;
+
+   scratch_pte = gen8_pte_encode(px_dma(vm->scratch_page),
+ I915_CACHE_LLC, true);
+
+   fill_px(vm->dev, pt, scratch_pte);
+}
+
 static void gen6_initialize_pt(struct i915_address_space *vm,
   struct i915_page_table *pt)
 {
@@ -441,15 +441,6 @@ static void gen6_initialize_pt(struct i915_address_space 
*vm,
fill32_px(vm->dev, pt, scratch_pte);
 }
 
-static void free_pd(struct drm_device *dev, struct i915_page_directory *pd)
-{
-   if (px_page(pd)) {
-   cleanup_px(dev, pd);
-   kfree(pd->used_pdes);
-   kfree(pd);
-   }
-}
-
 static struct i915_page_directory *alloc_pd(struct drm_device *dev)
 {
struct i915_page_directory *pd;
@@ -478,6 +469,15 @@ free_pd:
return ERR_PTR(ret);
 }
 
+static void free_pd(struct drm_device *dev, struct i915_page_directory *pd)
+{
+   if (px_page(pd)) {
+   cleanup_px(dev, pd);
+   kfree(pd->used_pdes);
+   kfree(pd);
+   }
+}
+
 static void gen8_initialize_pd(struct i915_address_space *vm,
   struct i915_page_directory *pd)
 {
-- 
1.9.1

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


[Intel-gfx] [PATCH 04/21] drm/i915/gtt: Allow >= 4GB sizes for vm.

2015-05-22 Thread Mika Kuoppala
We can have exactly 4GB sized ppgtt with 32bit system.
size_t is inadequate for this.

Signed-off-by: Mika Kuoppala 
---
 drivers/char/agp/intel-gtt.c|  4 ++--
 drivers/gpu/drm/i915/i915_debugfs.c | 42 ++---
 drivers/gpu/drm/i915/i915_gem.c |  6 +++---
 drivers/gpu/drm/i915/i915_gem_gtt.c | 22 +--
 drivers/gpu/drm/i915/i915_gem_gtt.h | 12 +--
 include/drm/intel-gtt.h |  4 ++--
 6 files changed, 45 insertions(+), 45 deletions(-)

diff --git a/drivers/char/agp/intel-gtt.c b/drivers/char/agp/intel-gtt.c
index 0b4188b..4734d02 100644
--- a/drivers/char/agp/intel-gtt.c
+++ b/drivers/char/agp/intel-gtt.c
@@ -1408,8 +1408,8 @@ int intel_gmch_probe(struct pci_dev *bridge_pdev, struct 
pci_dev *gpu_pdev,
 }
 EXPORT_SYMBOL(intel_gmch_probe);
 
-void intel_gtt_get(size_t *gtt_total, size_t *stolen_size,
-  phys_addr_t *mappable_base, unsigned long *mappable_end)
+void intel_gtt_get(u64 *gtt_total, size_t *stolen_size,
+  phys_addr_t *mappable_base, u64 *mappable_end)
 {
*gtt_total = intel_private.gtt_total_entries << PAGE_SHIFT;
*stolen_size = intel_private.stolen_size;
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c 
b/drivers/gpu/drm/i915/i915_debugfs.c
index fece922..c7a840b 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -198,7 +198,7 @@ static int i915_gem_object_list_info(struct seq_file *m, 
void *data)
struct drm_i915_private *dev_priv = dev->dev_private;
struct i915_address_space *vm = &dev_priv->gtt.base;
struct i915_vma *vma;
-   size_t total_obj_size, total_gtt_size;
+   u64 total_obj_size, total_gtt_size;
int count, ret;
 
ret = mutex_lock_interruptible(&dev->struct_mutex);
@@ -231,7 +231,7 @@ static int i915_gem_object_list_info(struct seq_file *m, 
void *data)
}
mutex_unlock(&dev->struct_mutex);
 
-   seq_printf(m, "Total %d objects, %zu bytes, %zu GTT size\n",
+   seq_printf(m, "Total %d objects, %llu bytes, %llu GTT size\n",
   count, total_obj_size, total_gtt_size);
return 0;
 }
@@ -253,7 +253,7 @@ static int i915_gem_stolen_list_info(struct seq_file *m, 
void *data)
struct drm_device *dev = node->minor->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_i915_gem_object *obj;
-   size_t total_obj_size, total_gtt_size;
+   u64 total_obj_size, total_gtt_size;
LIST_HEAD(stolen);
int count, ret;
 
@@ -292,7 +292,7 @@ static int i915_gem_stolen_list_info(struct seq_file *m, 
void *data)
}
mutex_unlock(&dev->struct_mutex);
 
-   seq_printf(m, "Total %d objects, %zu bytes, %zu GTT size\n",
+   seq_printf(m, "Total %d objects, %llu bytes, %llu GTT size\n",
   count, total_obj_size, total_gtt_size);
return 0;
 }
@@ -310,10 +310,10 @@ static int i915_gem_stolen_list_info(struct seq_file *m, 
void *data)
 
 struct file_stats {
struct drm_i915_file_private *file_priv;
-   int count;
-   size_t total, unbound;
-   size_t global, shared;
-   size_t active, inactive;
+   unsigned long count;
+   u64 total, unbound;
+   u64 global, shared;
+   u64 active, inactive;
 };
 
 static int per_file_stats(int id, void *ptr, void *data)
@@ -370,7 +370,7 @@ static int per_file_stats(int id, void *ptr, void *data)
 
 #define print_file_stats(m, name, stats) do { \
if (stats.count) \
-   seq_printf(m, "%s: %u objects, %zu bytes (%zu active, %zu 
inactive, %zu global, %zu shared, %zu unbound)\n", \
+   seq_printf(m, "%s: %lu objects, %llu bytes (%llu active, %llu 
inactive, %llu global, %llu shared, %llu unbound)\n", \
   name, \
   stats.count, \
   stats.total, \
@@ -420,7 +420,7 @@ static int i915_gem_object_info(struct seq_file *m, void* 
data)
struct drm_device *dev = node->minor->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
u32 count, mappable_count, purgeable_count;
-   size_t size, mappable_size, purgeable_size;
+   u64 size, mappable_size, purgeable_size;
struct drm_i915_gem_object *obj;
struct i915_address_space *vm = &dev_priv->gtt.base;
struct drm_file *file;
@@ -437,17 +437,17 @@ static int i915_gem_object_info(struct seq_file *m, void* 
data)
 
size = count = mappable_size = mappable_count = 0;
count_objects(&dev_priv->mm.bound_list, global_list);
-   seq_printf(m, "%u [%u] objects, %zu [%zu] bytes in gtt\n",
+   seq_printf(m, "%u [%u] objects, %llu [%llu] bytes in gtt\n",
   count, mappable_count, size, mappable_size);
 
size = count = mappable_size = mappable_count = 0;
count_vmas(&vm->active_list, mm_list);
-   seq_printf(m, "  %u [%u] active objects, %zu [%zu] by

[Intel-gfx] [PATCH 06/21] drm/i915/gtt: Remove _single from page table allocator

2015-05-22 Thread Mika Kuoppala
We are always allocating a single page. No need to be verbose so
remove the suffix.

Signed-off-by: Mika Kuoppala 
---
 drivers/gpu/drm/i915/i915_gem_gtt.c | 16 
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/i915_gem_gtt.c
index a608b1b..4cf47f9 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -369,7 +369,7 @@ static void gen8_initialize_pt(struct i915_address_space 
*vm,
kunmap_atomic(pt_vaddr);
 }
 
-static struct i915_page_table *alloc_pt_single(struct drm_device *dev)
+static struct i915_page_table *alloc_pt(struct drm_device *dev)
 {
struct i915_page_table *pt;
const size_t count = INTEL_INFO(dev)->gen >= 8 ?
@@ -417,7 +417,7 @@ static void unmap_and_free_pd(struct i915_page_directory 
*pd,
}
 }
 
-static struct i915_page_directory *alloc_pd_single(struct drm_device *dev)
+static struct i915_page_directory *alloc_pd(struct drm_device *dev)
 {
struct i915_page_directory *pd;
int ret = -ENOMEM;
@@ -702,7 +702,7 @@ static int gen8_ppgtt_alloc_pagetabs(struct i915_hw_ppgtt 
*ppgtt,
continue;
}
 
-   pt = alloc_pt_single(dev);
+   pt = alloc_pt(dev);
if (IS_ERR(pt))
goto unwind_out;
 
@@ -760,7 +760,7 @@ static int gen8_ppgtt_alloc_page_directories(struct 
i915_hw_ppgtt *ppgtt,
if (pd)
continue;
 
-   pd = alloc_pd_single(dev);
+   pd = alloc_pd(dev);
if (IS_ERR(pd))
goto unwind_out;
 
@@ -992,11 +992,11 @@ static int gen8_preallocate_top_level_pdps(struct 
i915_hw_ppgtt *ppgtt)
  */
 static int gen8_ppgtt_init(struct i915_hw_ppgtt *ppgtt)
 {
-   ppgtt->scratch_pt = alloc_pt_single(ppgtt->base.dev);
+   ppgtt->scratch_pt = alloc_pt(ppgtt->base.dev);
if (IS_ERR(ppgtt->scratch_pt))
return PTR_ERR(ppgtt->scratch_pt);
 
-   ppgtt->scratch_pd = alloc_pd_single(ppgtt->base.dev);
+   ppgtt->scratch_pd = alloc_pd(ppgtt->base.dev);
if (IS_ERR(ppgtt->scratch_pd))
return PTR_ERR(ppgtt->scratch_pd);
 
@@ -1375,7 +1375,7 @@ static int gen6_alloc_va_range(struct i915_address_space 
*vm,
/* We've already allocated a page table */
WARN_ON(!bitmap_empty(pt->used_ptes, GEN6_PTES));
 
-   pt = alloc_pt_single(dev);
+   pt = alloc_pt(dev);
if (IS_ERR(pt)) {
ret = PTR_ERR(pt);
goto unwind_out;
@@ -1461,7 +1461,7 @@ static int gen6_ppgtt_allocate_page_directories(struct 
i915_hw_ppgtt *ppgtt)
 * size. We allocate at the top of the GTT to avoid fragmentation.
 */
BUG_ON(!drm_mm_initialized(&dev_priv->gtt.base.mm));
-   ppgtt->scratch_pt = alloc_pt_single(ppgtt->base.dev);
+   ppgtt->scratch_pt = alloc_pt(ppgtt->base.dev);
if (IS_ERR(ppgtt->scratch_pt))
return PTR_ERR(ppgtt->scratch_pt);
 
-- 
1.9.1

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


[Intel-gfx] [PATCH 18/21] drm/i915/gtt: Move scratch_pd and scratch_pt into vm area

2015-05-22 Thread Mika Kuoppala
Scratch page is part of i915_address_space due to that we
have only one of that. Move other scratch entities into
the same struct. This is a preparatory patch for having
only one instance of each scratch_pt/pd.

Signed-off-by: Mika Kuoppala 
---
 drivers/gpu/drm/i915/i915_gem_gtt.c | 51 +
 drivers/gpu/drm/i915/i915_gem_gtt.h |  7 +++--
 2 files changed, 27 insertions(+), 31 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/i915_gem_gtt.c
index a1d6d7a..61f4da0 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -608,12 +608,9 @@ static void gen8_ppgtt_insert_entries(struct 
i915_address_space *vm,
 static void gen8_initialize_pd(struct i915_address_space *vm,
   struct i915_page_directory *pd)
 {
-   struct i915_hw_ppgtt *ppgtt =
-   container_of(vm, struct i915_hw_ppgtt, base);
gen8_pde_t scratch_pde;
 
-   scratch_pde = gen8_pde_encode(px_dma(ppgtt->scratch_pt),
- I915_CACHE_LLC);
+   scratch_pde = gen8_pde_encode(px_dma(vm->scratch_pt), I915_CACHE_LLC);
 
fill_px(vm->dev, pd, scratch_pde);
 }
@@ -648,8 +645,8 @@ static void gen8_ppgtt_cleanup(struct i915_address_space 
*vm)
free_pd(ppgtt->base.dev, ppgtt->pdp.page_directory[i]);
}
 
-   free_pd(ppgtt->base.dev, ppgtt->scratch_pd);
-   free_pt(ppgtt->base.dev, ppgtt->scratch_pt);
+   free_pd(vm->dev, vm->scratch_pd);
+   free_pt(vm->dev, vm->scratch_pt);
 }
 
 /**
@@ -685,7 +682,7 @@ static int gen8_ppgtt_alloc_pagetabs(struct i915_hw_ppgtt 
*ppgtt,
/* Don't reallocate page tables */
if (pt) {
/* Scratch is never allocated this way */
-   WARN_ON(pt == ppgtt->scratch_pt);
+   WARN_ON(pt == ppgtt->base.scratch_pt);
continue;
}
 
@@ -977,16 +974,16 @@ static int gen8_preallocate_top_level_pdps(struct 
i915_hw_ppgtt *ppgtt)
  */
 static int gen8_ppgtt_init(struct i915_hw_ppgtt *ppgtt)
 {
-   ppgtt->scratch_pt = alloc_pt(ppgtt->base.dev);
-   if (IS_ERR(ppgtt->scratch_pt))
-   return PTR_ERR(ppgtt->scratch_pt);
+   ppgtt->base.scratch_pt = alloc_pt(ppgtt->base.dev);
+   if (IS_ERR(ppgtt->base.scratch_pt))
+   return PTR_ERR(ppgtt->base.scratch_pt);
 
-   ppgtt->scratch_pd = alloc_pd(ppgtt->base.dev);
-   if (IS_ERR(ppgtt->scratch_pd))
-   return PTR_ERR(ppgtt->scratch_pd);
+   ppgtt->base.scratch_pd = alloc_pd(ppgtt->base.dev);
+   if (IS_ERR(ppgtt->base.scratch_pd))
+   return PTR_ERR(ppgtt->base.scratch_pd);
 
-   gen8_initialize_pt(&ppgtt->base, ppgtt->scratch_pt);
-   gen8_initialize_pd(&ppgtt->base, ppgtt->scratch_pd);
+   gen8_initialize_pt(&ppgtt->base, ppgtt->base.scratch_pt);
+   gen8_initialize_pd(&ppgtt->base, ppgtt->base.scratch_pd);
 
ppgtt->base.start = 0;
ppgtt->base.total = 1ULL << 32;
@@ -1019,7 +1016,8 @@ static void gen6_dump_ppgtt(struct i915_hw_ppgtt *ppgtt, 
struct seq_file *m)
uint32_t  pte, pde, temp;
uint32_t start = ppgtt->base.start, length = ppgtt->base.total;
 
-   scratch_pte = vm->pte_encode(px_dma(vm->scratch_page), I915_CACHE_LLC, 
true, 0);
+   scratch_pte = vm->pte_encode(px_dma(vm->scratch_page),
+I915_CACHE_LLC, true, 0);
 
gen6_for_each_pde(unused, &ppgtt->pd, start, length, temp, pde) {
u32 expected;
@@ -1348,7 +1346,7 @@ static int gen6_alloc_va_range(struct i915_address_space 
*vm,
 * tables.
 */
gen6_for_each_pde(pt, &ppgtt->pd, start, length, temp, pde) {
-   if (pt != ppgtt->scratch_pt) {
+   if (pt != vm->scratch_pt) {
WARN_ON(bitmap_empty(pt->used_ptes, GEN6_PTES));
continue;
}
@@ -1403,7 +1401,7 @@ unwind_out:
for_each_set_bit(pde, new_page_tables, I915_PDES) {
struct i915_page_table *pt = ppgtt->pd.page_table[pde];
 
-   ppgtt->pd.page_table[pde] = ppgtt->scratch_pt;
+   ppgtt->pd.page_table[pde] = vm->scratch_pt;
free_pt(vm->dev, pt);
}
 
@@ -1418,15 +1416,14 @@ static void gen6_ppgtt_cleanup(struct 
i915_address_space *vm)
struct i915_page_table *pt;
uint32_t pde;
 
-
drm_mm_remove_node(&ppgtt->node);
 
gen6_for_all_pdes(pt, ppgtt, pde) {
-   if (pt != ppgtt->scratch_pt)
+   if (pt != vm->scratch_pt)
free_pt(ppgtt->base.dev, pt);
}
 
-   free_pt(ppgtt->base.dev, ppgtt->scratch_pt);
+   free_pt(vm->dev, vm->scratch_pt);
 }
 
 static int gen6_ppgtt_allocate_page_directories(struct i915_hw_ppgtt *ppgtt)
@@ -1441,11 +1438,11 @@ static int gen6_ppgtt_allocate_

[Intel-gfx] [PATCH 01/21] drm/i915/gtt: Mark TLBS dirty for gen8+

2015-05-22 Thread Mika Kuoppala
When we touch gen8+ page maps, mark them dirty like we
do with previous gens.

Signed-off-by: Mika Kuoppala 
---
 drivers/gpu/drm/i915/i915_gem_gtt.c | 21 +++--
 1 file changed, 11 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 17b7df0..0ffd459 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -830,6 +830,15 @@ err_out:
return -ENOMEM;
 }
 
+/* PDE TLBs are a pain invalidate pre GEN8. It requires a context reload. If we
+ * are switching between contexts with the same LRCA, we also must do a force
+ * restore.
+ */
+static void mark_tlbs_dirty(struct i915_hw_ppgtt *ppgtt)
+{
+   ppgtt->pd_dirty_rings = INTEL_INFO(ppgtt->base.dev)->ring_mask;
+}
+
 static int gen8_alloc_va_range(struct i915_address_space *vm,
   uint64_t start,
   uint64_t length)
@@ -915,6 +924,7 @@ static int gen8_alloc_va_range(struct i915_address_space 
*vm,
}
 
free_gen8_temp_bitmaps(new_page_dirs, new_page_tables);
+   mark_tlbs_dirty(ppgtt);
return 0;
 
 err_out:
@@ -927,6 +937,7 @@ err_out:
unmap_and_free_pd(ppgtt->pdp.page_directory[pdpe], vm->dev);
 
free_gen8_temp_bitmaps(new_page_dirs, new_page_tables);
+   mark_tlbs_dirty(ppgtt);
return ret;
 }
 
@@ -1260,16 +1271,6 @@ static void gen6_ppgtt_insert_entries(struct 
i915_address_space *vm,
kunmap_atomic(pt_vaddr);
 }
 
-/* PDE TLBs are a pain invalidate pre GEN8. It requires a context reload. If we
- * are switching between contexts with the same LRCA, we also must do a force
- * restore.
- */
-static void mark_tlbs_dirty(struct i915_hw_ppgtt *ppgtt)
-{
-   /* If current vm != vm, */
-   ppgtt->pd_dirty_rings = INTEL_INFO(ppgtt->base.dev)->ring_mask;
-}
-
 static void gen6_initialize_pt(struct i915_address_space *vm,
struct i915_page_table *pt)
 {
-- 
1.9.1

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


[Intel-gfx] [PATCH 13/21] drm/i915/gtt: Use macros to access dma mapped pages

2015-05-22 Thread Mika Kuoppala
Make paging structure type agnostic *_px macros to access
page dma struct, the backing page and the dma address.

This makes the code less cluttered on internals of
i915_page_dma.

v2: Superfluous const -> nonconst removed

Signed-off-by: Mika Kuoppala 
---
 drivers/gpu/drm/i915/i915_gem_gtt.c | 37 +
 drivers/gpu/drm/i915/i915_gem_gtt.h |  8 ++--
 2 files changed, 27 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 072295f..4f9a000 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -346,8 +346,13 @@ static void kunmap_page_dma(struct drm_device *dev, void 
*vaddr)
kunmap_atomic(vaddr);
 }
 
-#define kmap_px(px) kmap_page_dma(&(px)->base)
-#define kunmap_px(ppgtt, vaddr) kunmap_page_dma((ppgtt)->base.dev, (vaddr));
+#define kmap_px(px) kmap_page_dma(px_base(px))
+#define kunmap_px(ppgtt, vaddr) kunmap_page_dma((ppgtt)->base.dev, (vaddr))
+
+#define setup_px(dev, px) setup_page_dma((dev), px_base(px))
+#define cleanup_px(dev, px) cleanup_page_dma((dev), px_base(px))
+#define fill_px(dev, px, v) fill_page_dma((dev), px_base(px), (v))
+#define fill32_px(dev, px, v) fill_page_dma_32((dev), px_base(px), (v))
 
 static void fill_page_dma(struct drm_device *dev, struct i915_page_dma *p,
  const uint64_t val)
@@ -373,7 +378,7 @@ static void fill_page_dma_32(struct drm_device *dev, struct 
i915_page_dma *p,
 
 static void free_pt(struct drm_device *dev, struct i915_page_table *pt)
 {
-   cleanup_page_dma(dev, &pt->base);
+   cleanup_px(dev, pt);
kfree(pt->used_ptes);
kfree(pt);
 }
@@ -385,7 +390,7 @@ static void gen8_initialize_pt(struct i915_address_space 
*vm,
 
scratch_pte = gen8_pte_encode(vm->scratch.addr, I915_CACHE_LLC, true);
 
-   fill_page_dma(vm->dev, &pt->base, scratch_pte);
+   fill_px(vm->dev, pt, scratch_pte);
 }
 
 static struct i915_page_table *alloc_pt(struct drm_device *dev)
@@ -405,7 +410,7 @@ static struct i915_page_table *alloc_pt(struct drm_device 
*dev)
if (!pt->used_ptes)
goto fail_bitmap;
 
-   ret = setup_page_dma(dev, &pt->base);
+   ret = setup_px(dev, pt);
if (ret)
goto fail_page_m;
 
@@ -421,8 +426,8 @@ fail_bitmap:
 
 static void free_pd(struct drm_device *dev, struct i915_page_directory *pd)
 {
-   if (pd->base.page) {
-   cleanup_page_dma(dev, &pd->base);
+   if (px_page(pd)) {
+   cleanup_px(dev, pd);
kfree(pd->used_pdes);
kfree(pd);
}
@@ -442,7 +447,7 @@ static struct i915_page_directory *alloc_pd(struct 
drm_device *dev)
if (!pd->used_pdes)
goto free_pd;
 
-   ret = setup_page_dma(dev, &pd->base);
+   ret = setup_px(dev, pd);
if (ret)
goto free_bitmap;
 
@@ -527,7 +532,7 @@ static void gen8_ppgtt_clear_range(struct 
i915_address_space *vm,
 
pt = pd->page_table[pde];
 
-   if (WARN_ON(!pt->base.page))
+   if (WARN_ON(!px_page(pt)))
continue;
 
last_pte = pte + num_entries;
@@ -599,7 +604,7 @@ static void __gen8_do_map_pt(gen8_pde_t * const pde,
 struct drm_device *dev)
 {
gen8_pde_t entry =
-   gen8_pde_encode(dev, pt->base.daddr, I915_CACHE_LLC);
+   gen8_pde_encode(dev, px_dma(pt), I915_CACHE_LLC);
*pde = entry;
 }
 
@@ -610,17 +615,17 @@ static void gen8_initialize_pd(struct i915_address_space 
*vm,
container_of(vm, struct i915_hw_ppgtt, base);
gen8_pde_t scratch_pde;
 
-   scratch_pde = gen8_pde_encode(vm->dev, ppgtt->scratch_pt->base.daddr,
+   scratch_pde = gen8_pde_encode(vm->dev, px_dma(ppgtt->scratch_pt),
  I915_CACHE_LLC);
 
-   fill_page_dma(vm->dev, &pd->base, scratch_pde);
+   fill_px(vm->dev, pd, scratch_pde);
 }
 
 static void gen8_free_page_tables(struct i915_page_directory *pd, struct 
drm_device *dev)
 {
int i;
 
-   if (!pd->base.page)
+   if (!px_page(pd))
return;
 
for_each_set_bit(i, pd->used_pdes, I915_PDES) {
@@ -1021,7 +1026,7 @@ static void gen6_dump_ppgtt(struct i915_hw_ppgtt *ppgtt, 
struct seq_file *m)
gen6_for_each_pde(unused, &ppgtt->pd, start, length, temp, pde) {
u32 expected;
gen6_pte_t *pt_vaddr;
-   dma_addr_t pt_addr = ppgtt->pd.page_table[pde]->base.daddr;
+   const dma_addr_t pt_addr = px_dma(ppgtt->pd.page_table[pde]);
pd_entry = readl(ppgtt->pd_addr + pde);
expected = (GEN6_PDE_ADDR_ENCODE(pt_addr) | GEN6_PDE_VALID);
 
@@ -1068,7 +1073,7 @@ static void gen6_write_pde(struct i915_page_directory *pd,
container_of(pd, struct i915_hw_ppgtt, pd);
u32 pd_entry;

[Intel-gfx] [PATCH 07/21] drm/i915/gtt: Introduce i915_page_dir_dma_addr

2015-05-22 Thread Mika Kuoppala
The legacy mode mm switch and the execlist context assignment
needs dma address for the page directories.

Introduce a function that encapsulates the scratch_pd dma
fallback if no pd is found.

Signed-off-by: Mika Kuoppala 
---
 drivers/gpu/drm/i915/i915_gem_gtt.c | 6 ++
 drivers/gpu/drm/i915/i915_gem_gtt.h | 8 
 drivers/gpu/drm/i915/intel_lrc.c| 4 +---
 3 files changed, 11 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 4cf47f9..18989f7 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -481,10 +481,8 @@ static int gen8_mm_switch(struct i915_hw_ppgtt *ppgtt,
int i, ret;
 
for (i = GEN8_LEGACY_PDPES - 1; i >= 0; i--) {
-   struct i915_page_directory *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. */
+   const dma_addr_t pd_daddr = i915_page_dir_dma_addr(ppgtt, i);
+
ret = gen8_write_pdp(ring, i, pd_daddr);
if (ret)
return ret;
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h 
b/drivers/gpu/drm/i915/i915_gem_gtt.h
index c343161..da67542 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.h
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.h
@@ -468,6 +468,14 @@ static inline size_t gen8_pte_count(uint64_t address, 
uint64_t length)
return i915_pte_count(address, length, GEN8_PDE_SHIFT);
 }
 
+static inline dma_addr_t
+i915_page_dir_dma_addr(const struct i915_hw_ppgtt *ppgtt, const unsigned n)
+{
+   return test_bit(n, ppgtt->pdp.used_pdpes) ?
+   ppgtt->pdp.page_directory[n]->daddr :
+   ppgtt->scratch_pd->daddr;
+}
+
 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);
diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
index d793d4e..626949a 100644
--- a/drivers/gpu/drm/i915/intel_lrc.c
+++ b/drivers/gpu/drm/i915/intel_lrc.c
@@ -184,9 +184,7 @@
 #define CTX_GPGPU_CSR_BASE_ADDRESS 0x44
 
 #define ASSIGN_CTX_PDP(ppgtt, reg_state, n) { \
-   const u64 _addr = test_bit(n, ppgtt->pdp.used_pdpes) ? \
-   ppgtt->pdp.page_directory[n]->daddr : \
-   ppgtt->scratch_pd->daddr; \
+   const u64 _addr = i915_page_dir_dma_addr((ppgtt), (n)); \
reg_state[CTX_PDP ## n ## _UDW+1] = upper_32_bits(_addr); \
reg_state[CTX_PDP ## n ## _LDW+1] = lower_32_bits(_addr); \
 }
-- 
1.9.1

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


[Intel-gfx] [PATCH 02/21] drm/i915/gtt: Workaround for HW preload not flushing pdps

2015-05-22 Thread Mika Kuoppala
With BDW/SKL and 32bit addressing mode only, the hardware preloads
pdps. However the TLB invalidation only has effect on levels below
the pdps. This means that if pdps change, hw might access with
stale pdp entry.

To combat this problem, preallocate the top pdps so that hw sees
them as immutable for each context.

Cc: Ville Syrjälä 
Cc: Rafael Barbalho 
Signed-off-by: Mika Kuoppala 
---
 drivers/gpu/drm/i915/i915_gem_gtt.c | 50 +
 drivers/gpu/drm/i915/i915_reg.h | 17 +
 drivers/gpu/drm/i915/intel_lrc.c| 15 +--
 3 files changed, 68 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 0ffd459..1a5ad4c 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -941,6 +941,48 @@ err_out:
return ret;
 }
 
+/* With some architectures and 32bit legacy mode, hardware pre-loads the
+ * top level pdps but the tlb invalidation only invalidates the lower levels.
+ * This might lead to hw fetching with stale pdp entries if top level
+ * structure changes, ie va space grows with dynamic page tables.
+ */
+static bool hw_wont_flush_pdp_tlbs(struct i915_hw_ppgtt *ppgtt)
+{
+   struct drm_device *dev = ppgtt->base.dev;
+
+   if (GEN8_CTX_ADDRESSING_MODE != LEGACY_32B_CONTEXT)
+   return false;
+
+   if (IS_BROADWELL(dev) || IS_SKYLAKE(dev))
+   return true;
+
+   return false;
+}
+
+static int gen8_preallocate_top_level_pdps(struct i915_hw_ppgtt *ppgtt)
+{
+   unsigned long *new_page_dirs, **new_page_tables;
+   int ret;
+
+   /* We allocate temp bitmap for page tables for no gain
+* but as this is for init only, lets keep the things simple
+*/
+   ret = alloc_gen8_temp_bitmaps(&new_page_dirs, &new_page_tables);
+   if (ret)
+   return ret;
+
+   /* Allocate for all pdps regardless of how the ppgtt
+* was defined.
+*/
+   ret = gen8_ppgtt_alloc_page_directories(ppgtt, &ppgtt->pdp,
+   0, 1ULL << 32,
+   new_page_dirs);
+
+   free_gen8_temp_bitmaps(new_page_dirs, new_page_tables);
+
+   return ret;
+}
+
 /*
  * GEN8 legacy ppgtt programming is accomplished through a max 4 PDP registers
  * with a net effect resembling a 2-level page table in normal x86 terms. Each
@@ -972,6 +1014,14 @@ static int gen8_ppgtt_init(struct i915_hw_ppgtt *ppgtt)
 
ppgtt->switch_mm = gen8_mm_switch;
 
+   if (hw_wont_flush_pdp_tlbs(ppgtt)) {
+   /* Avoid the tlb flush bug by preallocating
+* whole top level pdp structure so it stays
+* static even if our va space grows.
+*/
+   return gen8_preallocate_top_level_pdps(ppgtt);
+   }
+
return 0;
 }
 
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 6eeba63..334324b 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -2777,6 +2777,23 @@ enum skl_disp_power_wells {
 #define VLV_CLK_CTL2   0x101104
 #define   CLK_CTL2_CZCOUNT_30NS_SHIFT  28
 
+/* Context descriptor format bits */
+#define GEN8_CTX_VALID (1<<0)
+#define GEN8_CTX_FORCE_PD_RESTORE  (1<<1)
+#define GEN8_CTX_FORCE_RESTORE (1<<2)
+#define GEN8_CTX_L3LLC_COHERENT(1<<5)
+#define GEN8_CTX_PRIVILEGE (1<<8)
+
+enum {
+   ADVANCED_CONTEXT = 0,
+   LEGACY_32B_CONTEXT,
+   ADVANCED_AD_CONTEXT,
+   LEGACY_64B_CONTEXT
+};
+
+#define GEN8_CTX_ADDRESSING_MODE_SHIFT 3
+#define GEN8_CTX_ADDRESSING_MODE   LEGACY_32B_CONTEXT
+
 /*
  * Overlay regs
  */
diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
index 96ae90a..d793d4e 100644
--- a/drivers/gpu/drm/i915/intel_lrc.c
+++ b/drivers/gpu/drm/i915/intel_lrc.c
@@ -183,12 +183,6 @@
 #define CTX_R_PWR_CLK_STATE0x42
 #define CTX_GPGPU_CSR_BASE_ADDRESS 0x44
 
-#define GEN8_CTX_VALID (1<<0)
-#define GEN8_CTX_FORCE_PD_RESTORE (1<<1)
-#define GEN8_CTX_FORCE_RESTORE (1<<2)
-#define GEN8_CTX_L3LLC_COHERENT (1<<5)
-#define GEN8_CTX_PRIVILEGE (1<<8)
-
 #define ASSIGN_CTX_PDP(ppgtt, reg_state, n) { \
const u64 _addr = test_bit(n, ppgtt->pdp.used_pdpes) ? \
ppgtt->pdp.page_directory[n]->daddr : \
@@ -198,13 +192,6 @@
 }
 
 enum {
-   ADVANCED_CONTEXT = 0,
-   LEGACY_CONTEXT,
-   ADVANCED_AD_CONTEXT,
-   LEGACY_64B_CONTEXT
-};
-#define GEN8_CTX_MODE_SHIFT 3
-enum {
FAULT_AND_HANG = 0,
FAULT_AND_HALT, /* Debug only */
FAULT_AND_STREAM,
@@ -273,7 +260,7 @@ static uint64_t execlists_ctx_descriptor(struct 
intel_engine_cs *ring,
WARN_ON(lrca & 0x0FFFULL);
 
desc = GEN8_CTX_VALID;
-   desc |= LEGACY_CONTEXT << GEN8_CTX_MODE_SHIFT;
+   desc |= GEN8_CTX

[Intel-gfx] [PATCH 12/21] drm/i915/gtt: Introduce kmap|kunmap for dma page

2015-05-22 Thread Mika Kuoppala
As there is flushing involved when we have done the cpu
write, make functions for mapping for cpu space. Make macros
to map any type of paging structure.

v2: Make it clear tha flushing kunmap is only for ppgtt (Ville)

Cc: Ville Syrjälä 
Signed-off-by: Mika Kuoppala 
---
 drivers/gpu/drm/i915/i915_gem_gtt.c | 73 +++--
 1 file changed, 38 insertions(+), 35 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/i915_gem_gtt.c
index d020b5e..072295f 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -330,19 +330,35 @@ static void cleanup_page_dma(struct drm_device *dev, 
struct i915_page_dma *p)
memset(p, 0, sizeof(*p));
 }
 
+static void *kmap_page_dma(struct i915_page_dma *p)
+{
+   return kmap_atomic(p->page);
+}
+
+/* We use the flushing unmap only with ppgtt structures:
+ * page directories, page tables and scratch pages.
+ */
+static void kunmap_page_dma(struct drm_device *dev, void *vaddr)
+{
+   if (!HAS_LLC(dev) && !IS_VALLEYVIEW(dev))
+   drm_clflush_virt_range(vaddr, PAGE_SIZE);
+
+   kunmap_atomic(vaddr);
+}
+
+#define kmap_px(px) kmap_page_dma(&(px)->base)
+#define kunmap_px(ppgtt, vaddr) kunmap_page_dma((ppgtt)->base.dev, (vaddr));
+
 static void fill_page_dma(struct drm_device *dev, struct i915_page_dma *p,
  const uint64_t val)
 {
int i;
-   uint64_t * const vaddr = kmap_atomic(p->page);
+   uint64_t * const vaddr = kmap_page_dma(p);
 
for (i = 0; i < 512; i++)
vaddr[i] = val;
 
-   if (!HAS_LLC(dev) && !IS_VALLEYVIEW(dev))
-   drm_clflush_virt_range(vaddr, PAGE_SIZE);
-
-   kunmap_atomic(vaddr);
+   kunmap_page_dma(dev, vaddr);
 }
 
 static void fill_page_dma_32(struct drm_device *dev, struct i915_page_dma *p,
@@ -500,7 +516,6 @@ static void gen8_ppgtt_clear_range(struct 
i915_address_space *vm,
while (num_entries) {
struct i915_page_directory *pd;
struct i915_page_table *pt;
-   struct page *page_table;
 
if (WARN_ON(!ppgtt->pdp.page_directory[pdpe]))
continue;
@@ -515,22 +530,18 @@ static void gen8_ppgtt_clear_range(struct 
i915_address_space *vm,
if (WARN_ON(!pt->base.page))
continue;
 
-   page_table = pt->base.page;
-
last_pte = pte + num_entries;
if (last_pte > GEN8_PTES)
last_pte = GEN8_PTES;
 
-   pt_vaddr = kmap_atomic(page_table);
+   pt_vaddr = kmap_px(pt);
 
for (i = pte; i < last_pte; i++) {
pt_vaddr[i] = scratch_pte;
num_entries--;
}
 
-   if (!HAS_LLC(ppgtt->base.dev))
-   drm_clflush_virt_range(pt_vaddr, PAGE_SIZE);
-   kunmap_atomic(pt_vaddr);
+   kunmap_px(ppgtt, pt);
 
pte = 0;
if (++pde == I915_PDES) {
@@ -562,18 +573,14 @@ static void gen8_ppgtt_insert_entries(struct 
i915_address_space *vm,
if (pt_vaddr == NULL) {
struct i915_page_directory *pd = 
ppgtt->pdp.page_directory[pdpe];
struct i915_page_table *pt = pd->page_table[pde];
-   struct page *page_table = pt->base.page;
-
-   pt_vaddr = kmap_atomic(page_table);
+   pt_vaddr = kmap_px(pt);
}
 
pt_vaddr[pte] =
gen8_pte_encode(sg_page_iter_dma_address(&sg_iter),
cache_level, true);
if (++pte == GEN8_PTES) {
-   if (!HAS_LLC(ppgtt->base.dev))
-   drm_clflush_virt_range(pt_vaddr, PAGE_SIZE);
-   kunmap_atomic(pt_vaddr);
+   kunmap_px(ppgtt, pt_vaddr);
pt_vaddr = NULL;
if (++pde == I915_PDES) {
pdpe++;
@@ -582,11 +589,9 @@ static void gen8_ppgtt_insert_entries(struct 
i915_address_space *vm,
pte = 0;
}
}
-   if (pt_vaddr) {
-   if (!HAS_LLC(ppgtt->base.dev))
-   drm_clflush_virt_range(pt_vaddr, PAGE_SIZE);
-   kunmap_atomic(pt_vaddr);
-   }
+
+   if (pt_vaddr)
+   kunmap_px(ppgtt, pt_vaddr);
 }
 
 static void __gen8_do_map_pt(gen8_pde_t * const pde,
@@ -865,7 +870,7 @@ static int gen8_alloc_va_range(struct i915_address_space 
*vm,
/* Allocations have completed successfully, so set the bitmaps, and do
 * the mappings. */
gen8_for_each_pdpe(pd, &ppgtt->pdp, start, length, temp, pdpe) {
-   gen8_pde_t *const page_directory = kmap_atomic(pd->base.page);
+   gen8_

[Intel-gfx] [PATCH 16/21] drm/i915/gtt: Pin vma during virtual address allocation

2015-05-22 Thread Mika Kuoppala
Dynamic page table allocation might wake the shrinker
when memory is requested for page table structures.
As this happens when we try to allocate the virtual address
during binding, our vma might be among the targets for eviction.
We should do i915_vma_pin() and do pin early in there like Chris
suggests but this is interim solution.

Shield our vma from shrinker by incrementing pin count before
the virtual address is allocated.

The proper place to fix this would be in gem, inside of
i915_vma_pin(). But we don't have that yet so take the short
cut as a intermediate solution.

Testcase: igt/gem_ctx_thrash
Signed-off-by: Mika Kuoppala 
---
 drivers/gpu/drm/i915/i915_gem_gtt.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/i915_gem_gtt.c
index a2a0c88..b938964 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -2916,9 +2916,12 @@ int i915_vma_bind(struct i915_vma *vma, enum 
i915_cache_level cache_level,
vma->node.size,
VM_TO_TRACE_NAME(vma->vm));
 
+   /* XXX: i915_vma_pin() will fix this +- hack */
+   vma->pin_count++;
ret = vma->vm->allocate_va_range(vma->vm,
 vma->node.start,
 vma->node.size);
+   vma->pin_count--;
if (ret)
return ret;
}
-- 
1.9.1

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


[Intel-gfx] [PATCH 17/21] drm/i915/gtt: Cleanup page directory encoding

2015-05-22 Thread Mika Kuoppala
Write page directory entry without using superfluous
indirect function. Also remove unused device parameter
from the encode function.

Signed-off-by: Mika Kuoppala 
---
 drivers/gpu/drm/i915/i915_gem_gtt.c | 19 +--
 1 file changed, 5 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/i915_gem_gtt.c
index b938964..a1d6d7a 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -192,9 +192,8 @@ static gen8_pte_t gen8_pte_encode(dma_addr_t addr,
return pte;
 }
 
-static gen8_pde_t gen8_pde_encode(struct drm_device *dev,
- dma_addr_t addr,
- enum i915_cache_level level)
+static gen8_pde_t gen8_pde_encode(const dma_addr_t addr,
+ const enum i915_cache_level level)
 {
gen8_pde_t pde = _PAGE_PRESENT | _PAGE_RW;
pde |= addr;
@@ -606,15 +605,6 @@ static void gen8_ppgtt_insert_entries(struct 
i915_address_space *vm,
kunmap_px(ppgtt, pt_vaddr);
 }
 
-static void __gen8_do_map_pt(gen8_pde_t * const pde,
-struct i915_page_table *pt,
-struct drm_device *dev)
-{
-   gen8_pde_t entry =
-   gen8_pde_encode(dev, px_dma(pt), I915_CACHE_LLC);
-   *pde = entry;
-}
-
 static void gen8_initialize_pd(struct i915_address_space *vm,
   struct i915_page_directory *pd)
 {
@@ -622,7 +612,7 @@ static void gen8_initialize_pd(struct i915_address_space 
*vm,
container_of(vm, struct i915_hw_ppgtt, base);
gen8_pde_t scratch_pde;
 
-   scratch_pde = gen8_pde_encode(vm->dev, px_dma(ppgtt->scratch_pt),
+   scratch_pde = gen8_pde_encode(px_dma(ppgtt->scratch_pt),
  I915_CACHE_LLC);
 
fill_px(vm->dev, pd, scratch_pde);
@@ -906,7 +896,8 @@ static int gen8_alloc_va_range(struct i915_address_space 
*vm,
set_bit(pde, pd->used_pdes);
 
/* Map the PDE to the page table */
-   __gen8_do_map_pt(page_directory + pde, pt, vm->dev);
+   page_directory[pde] = gen8_pde_encode(px_dma(pt),
+ I915_CACHE_LLC);
 
/* NB: We haven't yet mapped ptes to pages. At this
 * point we're still relying on insert_entries() */
-- 
1.9.1

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


[Intel-gfx] [PATCH 14/21] drm/i915/gtt: Make scratch page i915_page_dma compatible

2015-05-22 Thread Mika Kuoppala
Lay out scratch page structure in similar manner than other
paging structures. This allows us to use the same tools for
setup and teardown.

Signed-off-by: Mika Kuoppala 
---
 drivers/gpu/drm/i915/i915_gem_gtt.c | 89 -
 drivers/gpu/drm/i915/i915_gem_gtt.h |  9 ++--
 2 files changed, 54 insertions(+), 44 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 4f9a000..43fa543 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -301,11 +301,12 @@ static gen6_pte_t iris_pte_encode(dma_addr_t addr,
return pte;
 }
 
-static int setup_page_dma(struct drm_device *dev, struct i915_page_dma *p)
+static int __setup_page_dma(struct drm_device *dev,
+   struct i915_page_dma *p, gfp_t flags)
 {
struct device *device = &dev->pdev->dev;
 
-   p->page = alloc_page(GFP_KERNEL);
+   p->page = alloc_page(flags);
if (!p->page)
return -ENOMEM;
 
@@ -320,6 +321,11 @@ static int setup_page_dma(struct drm_device *dev, struct 
i915_page_dma *p)
return 0;
 }
 
+static int setup_page_dma(struct drm_device *dev, struct i915_page_dma *p)
+{
+   return __setup_page_dma(dev, p, GFP_KERNEL);
+}
+
 static void cleanup_page_dma(struct drm_device *dev, struct i915_page_dma *p)
 {
if (WARN_ON(!p->page))
@@ -388,7 +394,8 @@ static void gen8_initialize_pt(struct i915_address_space 
*vm,
 {
gen8_pte_t scratch_pte;
 
-   scratch_pte = gen8_pte_encode(vm->scratch.addr, I915_CACHE_LLC, true);
+   scratch_pte = gen8_pte_encode(px_dma(vm->scratch_page),
+ I915_CACHE_LLC, true);
 
fill_px(vm->dev, pt, scratch_pte);
 }
@@ -515,7 +522,7 @@ static void gen8_ppgtt_clear_range(struct 
i915_address_space *vm,
unsigned num_entries = length >> PAGE_SHIFT;
unsigned last_pte, i;
 
-   scratch_pte = gen8_pte_encode(ppgtt->base.scratch.addr,
+   scratch_pte = gen8_pte_encode(px_dma(ppgtt->base.scratch_page),
  I915_CACHE_LLC, use_scratch);
 
while (num_entries) {
@@ -1021,7 +1028,7 @@ static void gen6_dump_ppgtt(struct i915_hw_ppgtt *ppgtt, 
struct seq_file *m)
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);
+   scratch_pte = vm->pte_encode(px_dma(vm->scratch_page), I915_CACHE_LLC, 
true, 0);
 
gen6_for_each_pde(unused, &ppgtt->pd, start, length, temp, pde) {
u32 expected;
@@ -1256,7 +1263,8 @@ static void gen6_ppgtt_clear_range(struct 
i915_address_space *vm,
unsigned first_pte = first_entry % GEN6_PTES;
unsigned last_pte, i;
 
-   scratch_pte = vm->pte_encode(vm->scratch.addr, I915_CACHE_LLC, true, 0);
+   scratch_pte = vm->pte_encode(px_dma(vm->scratch_page),
+I915_CACHE_LLC, true, 0);
 
while (num_entries) {
last_pte = first_pte + num_entries;
@@ -1314,9 +1322,10 @@ static void gen6_initialize_pt(struct i915_address_space 
*vm,
 {
gen6_pte_t scratch_pte;
 
-   WARN_ON(vm->scratch.addr == 0);
+   WARN_ON(px_dma(vm->scratch_page) == 0);
 
-   scratch_pte = vm->pte_encode(vm->scratch.addr, I915_CACHE_LLC, true, 0);
+   scratch_pte = vm->pte_encode(px_dma(vm->scratch_page),
+I915_CACHE_LLC, true, 0);
 
fill32_px(vm->dev, pt, scratch_pte);
 }
@@ -1553,13 +1562,14 @@ static int __hw_ppgtt_init(struct drm_device *dev, 
struct i915_hw_ppgtt *ppgtt)
struct drm_i915_private *dev_priv = dev->dev_private;
 
ppgtt->base.dev = dev;
-   ppgtt->base.scratch = dev_priv->gtt.base.scratch;
+   ppgtt->base.scratch_page = dev_priv->gtt.base.scratch_page;
 
if (INTEL_INFO(dev)->gen < 8)
return gen6_ppgtt_init(ppgtt);
else
return gen8_ppgtt_init(ppgtt);
 }
+
 int i915_ppgtt_init(struct drm_device *dev, struct i915_hw_ppgtt *ppgtt)
 {
struct drm_i915_private *dev_priv = dev->dev_private;
@@ -1874,7 +1884,7 @@ static void gen8_ggtt_clear_range(struct 
i915_address_space *vm,
 first_entry, num_entries, max_entries))
num_entries = max_entries;
 
-   scratch_pte = gen8_pte_encode(vm->scratch.addr,
+   scratch_pte = gen8_pte_encode(px_dma(vm->scratch_page),
  I915_CACHE_LLC,
  use_scratch);
for (i = 0; i < num_entries; i++)
@@ -1900,7 +1910,8 @@ static void gen6_ggtt_clear_range(struct 
i915_address_space *vm,
 first_entry, num_entries, max_entries))
num_entries = max_entries;
 
-   scratch_pte = vm->pte_encode(vm->scratch.addr, I915_CACHE_LLC, 
use_scratch, 0);
+   scratch_pte = vm->pte_encod

Re: [Intel-gfx] [PATCH 02/20] drm/i915: Force PD restore on dirty ppGTTs

2015-05-22 Thread Mika Kuoppala
"Barbalho, Rafael"  writes:

>> -Original Message-
>> From: Ville Syrjälä [mailto:ville.syrj...@linux.intel.com]
>> Sent: Thursday, May 21, 2015 4:08 PM
>> To: Mika Kuoppala
>> Cc: intel-gfx@lists.freedesktop.org; m...@iki.fi; Barbalho, Rafael
>> Subject: Re: [Intel-gfx] [PATCH 02/20] drm/i915: Force PD restore on dirty
>> ppGTTs
>> 
>> On Thu, May 21, 2015 at 05:37:30PM +0300, Mika Kuoppala wrote:
>> > Force page directory reload when ppgtt va->pa
>> > mapping has changed. Extend dirty rings mechanism
>> > for gen > 7 and use it to force pd restore in execlist
>> > mode when vm has been changed.
>> >
>> > Some parts of execlist context update cleanup based on
>> > work by Chris Wilson.
>> >
>> > v2: Add comment about lite restore (Chris)
>> >
>> > Signed-off-by: Mika Kuoppala 
>> > ---
>> >  drivers/gpu/drm/i915/intel_lrc.c | 65 -
>> ---
>> >  1 file changed, 33 insertions(+), 32 deletions(-)
>> >
>> > diff --git a/drivers/gpu/drm/i915/intel_lrc.c
>> b/drivers/gpu/drm/i915/intel_lrc.c
>> > index 0413b8f..5ee2a8c 100644
>> > --- a/drivers/gpu/drm/i915/intel_lrc.c
>> > +++ b/drivers/gpu/drm/i915/intel_lrc.c
>> > @@ -264,9 +264,10 @@ u32 intel_execlists_ctx_id(struct
>> drm_i915_gem_object *ctx_obj)
>> >  }
>> >
>> >  static uint64_t execlists_ctx_descriptor(struct intel_engine_cs *ring,
>> > -   struct drm_i915_gem_object
>> *ctx_obj)
>> > +   struct intel_context *ctx)
>> >  {
>> >struct drm_device *dev = ring->dev;
>> > +  struct drm_i915_gem_object *ctx_obj = ctx->engine[ring->id].state;
>> >uint64_t desc;
>> >uint64_t lrca = i915_gem_obj_ggtt_offset(ctx_obj);
>> >
>> > @@ -284,6 +285,14 @@ static uint64_t execlists_ctx_descriptor(struct
>> intel_engine_cs *ring,
>> > * signalling between Command Streamers */
>> >/* desc |= GEN8_CTX_FORCE_RESTORE; */
>> >
>> > +  /* When performing a LiteRestore but with updated PD we need
>> > +   * to force the GPU to reload the PD
>> > +   */
>> > +  if (intel_ring_flag(ring) & ctx->ppgtt->pd_dirty_rings) {
>> > +  desc |= GEN8_CTX_FORCE_PD_RESTORE;
>> 
>> Wasn't there a hardware issue which basically meant you are not
>> allowed to actually set this bit?
>> 
>> Rafael had some details on that as far as I recall so adding cc...
>
> Ville is correct, there is a hardware issue in CHV with this bit and it should
> not be set. On BDW I am not sure, although you can stop the pre-fetching
> & caching in BDW by using 64-bit PPGTT addressing.
>
> So it's no from me I'm afraid.

Thanks for pointing out the details on this.

I worked around this with preallocating our top level PDP structure (4 pages
with 32bit mode) so that hardware sees immutable top level structure
per context.

Ville also noticed that initializing scratch structures by copying
is not good as it introduces unnecessary read. Better to just fill with
pte/pde entries always. This triggered a rebase on rest of the
series so I will resend whole series.

-Mika

>
>> 
>> > +  ctx->ppgtt->pd_dirty_rings &= ~intel_ring_flag(ring);
>> > +  }
>> > +
>
> 
>
>> > --
>> > 1.9.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 02/12] drm/i915/bxt: Enable BXT DSI PLL

2015-05-22 Thread Uma Shankar
From: Shashank Sharma 

This patch adds new functions for BXT clock and PLL programming.
They are:
1. configure_dsi_pll for BXT.
   This function does the basic math and generates the divider ratio
   based on requested pixclock, and program clock registers.
2. enable_dsi_pll function.
   This function programs the calculated clock values on the PLL.
3. intel_enable_dsi_pll
   Wrapper function to use same code for multiple platforms. It checks the
   platform and calls appropriate core pll enable function.

Signed-off-by: Shashank Sharma 
Signed-off-by: Uma Shankar 
---
 drivers/gpu/drm/i915/i915_reg.h  |   35 ++
 drivers/gpu/drm/i915/intel_dsi.c |2 +-
 drivers/gpu/drm/i915/intel_dsi.h |2 +-
 drivers/gpu/drm/i915/intel_dsi_pll.c |   85 +-
 4 files changed, 121 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 46ef269..b63bdce 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -7352,6 +7352,41 @@ enum skl_disp_power_wells {
 
 /* MIPI DSI registers */
 
+/* BXT DSI PLL Control */
+#define BXT_DSI_PLL_CTL   0x161000
+#define BXT_DSI_PLL_MASK_PVD_RATIO   (3 << 16)
+#define BXT_DSI_PLL_PVD_RATIO_1  (1<<16)
+#define BXT_DSIC_16X_BY2 (1 << 10)
+#define BXT_DSIC_16X_BY3 (1 << 11)
+#define BXT_DSIC_16X_BY4 (3 << 10)
+#define BXT_DSIA_16X_BY2 (1 << 8)
+#define BXT_DSIA_16X_BY3 (1 << 9)
+#define BXT_DSIA_16X_BY4 (3 << 8)
+
+#define BXT_DSI_MASK_FREQ_SEL(0xF << 8)
+
+#define BXT_DSI_PLL_RATIO_MAX0x7D
+#define BXT_DSI_PLL_RATIO_MIN0x22
+#define BXT_DSI_MASK_PLL_RATIO   0x7F
+#define BXT_REF_CLOCK_KHZ19500
+
+#define BXT_DSI_PLL_ENABLE0x46080
+#define BXT_DSI_PLL_DO_ENABLE (1 << 31)
+#define BXT_DSI_PLL_LOCKED(1 << 30)
+
+/* BXT power well control2, for driver */
+#define BXT_PWR_WELL_CTL2 0x45404
+#define BXT_PWR_WELL_2_ENABLE (1 << 31)
+#define BXT_PWR_WELL_2_ENABLED(1 << 30)
+#define BXT_PWR_WELL_1_ENABLE (1 << 29)
+#define BXT_PWR_WELL_1_ENABLED(1 << 28)
+#define BXT_PWR_WELL_ENABLED  (BXT_PWR_WELL_1_ENABLED | \
+   BXT_PWR_WELL_2_ENABLED)
+#define GEN9_FUSE_STATUS   0x42000
+#define GEN9_FUSE_PG2_ENABLED  (1 << 25)
+#define GEN9_FUSE_PG1_ENABLED  (1 << 26)
+#define GEN9_FUSE_PG0_ENABLED  (1 << 27)
+
 #define _MIPI_PORT(port, a, c) _PORT3(port, a, 0, c)   /* ports A and C only */
 
 #define _MIPIA_PORT_CTRL   (VLV_DISPLAY_BASE + 0x61190)
diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c
index 2419929e..1927546 100644
--- a/drivers/gpu/drm/i915/intel_dsi.c
+++ b/drivers/gpu/drm/i915/intel_dsi.c
@@ -903,8 +903,8 @@ static void intel_dsi_pre_pll_enable(struct intel_encoder 
*encoder)
DRM_DEBUG_KMS("\n");
 
intel_dsi_prepare(encoder);
+   intel_enable_dsi_pll(encoder);
 
-   vlv_enable_dsi_pll(encoder);
 }
 
 static enum drm_connector_status
diff --git a/drivers/gpu/drm/i915/intel_dsi.h b/drivers/gpu/drm/i915/intel_dsi.h
index 2784ac4..20cfcf07 100644
--- a/drivers/gpu/drm/i915/intel_dsi.h
+++ b/drivers/gpu/drm/i915/intel_dsi.h
@@ -121,7 +121,7 @@ static inline struct intel_dsi *enc_to_intel_dsi(struct 
drm_encoder *encoder)
return container_of(encoder, struct intel_dsi, base.base);
 }
 
-extern void vlv_enable_dsi_pll(struct intel_encoder *encoder);
+extern void intel_enable_dsi_pll(struct intel_encoder *encoder);
 extern void vlv_disable_dsi_pll(struct intel_encoder *encoder);
 extern u32 vlv_get_dsi_pclk(struct intel_encoder *encoder, int pipe_bpp);
 
diff --git a/drivers/gpu/drm/i915/intel_dsi_pll.c 
b/drivers/gpu/drm/i915/intel_dsi_pll.c
index 9688d99..a58f0a1 100644
--- a/drivers/gpu/drm/i915/intel_dsi_pll.c
+++ b/drivers/gpu/drm/i915/intel_dsi_pll.c
@@ -237,7 +237,7 @@ static void vlv_configure_dsi_pll(struct intel_encoder 
*encoder)
vlv_cck_write(dev_priv, CCK_REG_DSI_PLL_CONTROL, dsi_mnp.dsi_pll_ctrl);
 }
 
-void vlv_enable_dsi_pll(struct intel_encoder *encoder)
+static void vlv_enable_dsi_pll(struct intel_encoder *encoder)
 {
struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
u32 tmp;
@@ -368,3 +368,86 @@ u32 vlv_get_dsi_pclk(struct intel_encoder *encoder, int 
pipe_bpp)
 
return pclk;
 }
+
+static bool bxt_configure_dsi_pll(struct intel_encoder *

[Intel-gfx] [PATCH 08/12] drm/i915/bxt: DSI disable and post-disable

2015-05-22 Thread Uma Shankar
From: Shashank Sharma 

This patch contains changes to support DSI disble sequence in BXT.
The changes are:
1. BXT specific changes in clear_device_ready function.
2. BXT specific changes in DSI disable and post-disable functions.
3. Add a new function to reset BXT Dphy clock and dividers
   (bxt_dsi_reset_clocks).
4. Moved some part of the vlv clock reset code, in a new function
   (vlv_dsi_reset_clocks) maintaining the exact same sequence.
5. Wrapper function to call corresponding reset clock function.

Signed-off-by: Uma Shankar 
Signed-off-by: Shashank Sharma 
---
 drivers/gpu/drm/i915/intel_dsi.c |   39 
 drivers/gpu/drm/i915/intel_dsi.h |2 ++
 drivers/gpu/drm/i915/intel_dsi_pll.c |   41 ++
 3 files changed, 68 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c
index 729faf6..e4b96bc 100644
--- a/drivers/gpu/drm/i915/intel_dsi.c
+++ b/drivers/gpu/drm/i915/intel_dsi.c
@@ -427,12 +427,16 @@ static void intel_dsi_port_disable(struct intel_encoder 
*encoder)
struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
enum port port;
u32 temp;
+   u32 port_ctrl;
 
for_each_dsi_port(port, intel_dsi->ports) {
/* de-assert ip_tg_enable signal */
-   temp = I915_READ(MIPI_PORT_CTRL(port));
-   I915_WRITE(MIPI_PORT_CTRL(port), temp & ~DPI_ENABLE);
-   POSTING_READ(MIPI_PORT_CTRL(port));
+   port_ctrl = IS_BROXTON(dev) ?
+   BXT_MIPI_PORT_CTRL(port) :
+   MIPI_PORT_CTRL(port);
+   temp = I915_READ(port_ctrl);
+   I915_WRITE(port_ctrl, temp & ~DPI_ENABLE);
+   POSTING_READ(port_ctrl);
}
 }
 
@@ -570,12 +574,7 @@ static void intel_dsi_disable(struct intel_encoder 
*encoder)
/* Panel commands can be sent when clock is in LP11 */
I915_WRITE(MIPI_DEVICE_READY(port), 0x0);
 
-   temp = I915_READ(MIPI_CTRL(port));
-   temp &= ~ESCAPE_CLOCK_DIVIDER_MASK;
-   I915_WRITE(MIPI_CTRL(port), temp |
-  intel_dsi->escape_clk_div <<
-  ESCAPE_CLOCK_DIVIDER_SHIFT);
-
+   intel_dsi_reset_clocks(encoder, port);
I915_WRITE(MIPI_EOT_DISABLE(port), CLOCKSTOP);
 
temp = I915_READ(MIPI_DSI_FUNC_PRG(port));
@@ -594,12 +593,15 @@ static void intel_dsi_disable(struct intel_encoder 
*encoder)
 
 static void intel_dsi_clear_device_ready(struct intel_encoder *encoder)
 {
+   struct drm_device *dev = encoder->base.dev;
struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
enum port port;
u32 val;
+   u32 port_ctrl;
 
DRM_DEBUG_KMS("\n");
+
for_each_dsi_port(port, intel_dsi->ports) {
 
I915_WRITE(MIPI_DEVICE_READY(port), DEVICE_READY |
@@ -614,18 +616,27 @@ static void intel_dsi_clear_device_ready(struct 
intel_encoder *encoder)
ULPS_STATE_ENTER);
usleep_range(2000, 2500);
 
+   if (IS_BROXTON(dev))
+   port_ctrl = BXT_MIPI_PORT_CTRL(port);
+   else if (IS_VALLEYVIEW(dev))
+   port_ctrl = MIPI_PORT_CTRL(PORT_A);
+   else {
+   DRM_ERROR("Invalid DSI device to clear device ready\n");
+   return;
+   }
+
/* Wait till Clock lanes are in LP-00 state for MIPI Port A
 * only. MIPI Port C has no similar bit for checking
 */
-   if (wait_for(((I915_READ(MIPI_PORT_CTRL(PORT_A)) & AFE_LATCHOUT)
+   if (wait_for(((I915_READ(port_ctrl) & AFE_LATCHOUT)
== 0x0), 30))
DRM_ERROR("DSI LP not going Low\n");
 
/* Disable MIPI PHY transparent latch
 * Common bit for both MIPI Port A & MIPI Port C
 */
-   val = I915_READ(MIPI_PORT_CTRL(PORT_A));
-   I915_WRITE(MIPI_PORT_CTRL(PORT_A), val & ~LP_OUTPUT_HOLD);
+   val = I915_READ(port_ctrl);
+   I915_WRITE(port_ctrl, val & ~LP_OUTPUT_HOLD);
usleep_range(1000, 1500);
 
I915_WRITE(MIPI_DEVICE_READY(port), 0x00);
@@ -637,14 +648,14 @@ static void intel_dsi_clear_device_ready(struct 
intel_encoder *encoder)
 
 static void intel_dsi_post_disable(struct intel_encoder *encoder)
 {
-   struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
+   struct drm_device *dev = encoder->base.dev;
+   struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_dsi *intel_dsi 

[Intel-gfx] [PATCH 00/12] *** MIPI DSI Support for BXT ***

2015-05-22 Thread Uma Shankar
This patch series adds support for MIPI DSI for BXT platform.
Support for VBT v3 sequence parsing and programming is needed
for panel, backlight enable and control. The same will be added
as part of a different patch series.

Shashank Sharma (10):
  drm/i915/bxt: Initialize MIPI for BXT
  drm/i915/bxt: Enable BXT DSI PLL
  drm/i915/bxt: Disable DSI PLL for BXT
  drm/i915/bxt: DSI prepare changes for BXT
  drm/i915/bxt: DSI encoder support in CRTC modeset
  drm/i915/bxt: DSI enable for BXT
  drm/i915/bxt: Program Tx Rx and Dphy clocks
  drm/i915/bxt: DSI disable and post-disable
  drm/i915/bxt: get_hw_state for BXT
  drm/i915/bxt: get DSI pixelclock

Sunil Kamath (1):
  drm/i915/bxt: Modify BXT BLC according to VBT changes

Uma Shankar (1):
  drm/i915/bxt: Remove DSP CLK_GATE programming for BXT

 drivers/gpu/drm/i915/i915_drv.h   |1 +
 drivers/gpu/drm/i915/i915_reg.h   |  140 +-
 drivers/gpu/drm/i915/intel_ddi.c  |   53 -
 drivers/gpu/drm/i915/intel_display.c  |9 +-
 drivers/gpu/drm/i915/intel_drv.h  |2 +
 drivers/gpu/drm/i915/intel_dsi.c  |  341 +
 drivers/gpu/drm/i915/intel_dsi.h  |8 +-
 drivers/gpu/drm/i915/intel_dsi_pll.c  |  227 +-
 drivers/gpu/drm/i915/intel_opregion.c |1 +
 drivers/gpu/drm/i915/intel_panel.c|  100 --
 10 files changed, 765 insertions(+), 117 deletions(-)

-- 
1.7.9.5

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


[Intel-gfx] [PATCH 12/12] drm/i915/bxt: Remove DSP CLK_GATE programming for BXT

2015-05-22 Thread Uma Shankar
DSP CLK_GATE registers are specific to BYT and CHT.
Avoid programming the same for BXT platform.

Signed-off-by: Uma Shankar 
---
 drivers/gpu/drm/i915/intel_dsi.c |8 +---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c
index 5fbcebe..59a52d1 100644
--- a/drivers/gpu/drm/i915/intel_dsi.c
+++ b/drivers/gpu/drm/i915/intel_dsi.c
@@ -658,9 +658,11 @@ static void intel_dsi_post_disable(struct intel_encoder 
*encoder)
intel_dsi_disable(encoder);
intel_dsi_clear_device_ready(encoder);
 
-   val = I915_READ(DSPCLK_GATE_D);
-   val &= ~DPOUNIT_CLOCK_GATE_DISABLE;
-   I915_WRITE(DSPCLK_GATE_D, val);
+   if (!IS_BROXTON(dev)) {
+   val = I915_READ(DSPCLK_GATE_D);
+   val &= ~DPOUNIT_CLOCK_GATE_DISABLE;
+   I915_WRITE(DSPCLK_GATE_D, val);
+   }
 
drm_panel_unprepare(intel_dsi->panel);
 
-- 
1.7.9.5

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


[Intel-gfx] [PATCH 11/12] drm/i915/bxt: Modify BXT BLC according to VBT changes

2015-05-22 Thread Uma Shankar
From: Sunil Kamath 

Latest VBT mentions which set of registers will be used for BLC,
as controller number field. Making use of this field in BXT
BLC implementation. Also, the registers are used in case control
pin indicates display DDI. Adding a check for this.
According to Bspec, BLC_PWM_*_2 uses the display utility pin for output.
To use backlight 2, enable the utility pin with mode = PWM
   v2: Jani's review comments
   addressed
   - Add a prefix _ to BXT BLC registers definitions.
   - Add "bxt only" comment for u8 controller
   - Remove control_pin check for DDI controller
   - Check for valid controller values
   - Set pipe bits in UTIL_PIN_CTL
   - Enable/Disable UTIL_PIN_CTL in enable/disable_backlight()
   - If BLC 2 is used, read active_low_pwm from UTIL_PIN polarity
   Satheesh's review comment addressed
   - If UTIL PIN is already enabled, BIOS would have programmed it. No
   need to disable and enable again.
   v3: Jani's review comments
   - add UTIL_PIN_PIPE_MASK and UTIL_PIN_MODE_MASK
   - Disable UTIL_PIN if controller 1 is used
   - Mask out UTIL_PIN_PIPE_MASK and UTIL_PIN_MODE_MASK before enabling
   UTIL_PIN
   - check valid controller value in intel_bios.c
   - add backlight.util_pin_active_low
   - disable util pin before enabling
   v4: Change for BXT-PO branch:
   Stubbed unwanted definition which was existing before
   because of DC6 patch.
   UTIL_PIN_MODE_PWM (0x1b << 24)

Signed-off-by: Vandana Kannan 
Signed-off-by: Sunil Kamath 
Signed-off-by: Uma Shankar 
---
 drivers/gpu/drm/i915/i915_reg.h|   28 +++---
 drivers/gpu/drm/i915/intel_drv.h   |2 +
 drivers/gpu/drm/i915/intel_panel.c |  100 ++--
 3 files changed, 106 insertions(+), 24 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index f96f049..5e3958f 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -3509,17 +3509,29 @@ enum skl_disp_power_wells {
 #define UTIL_PIN_CTL   0x48400
 #define   UTIL_PIN_ENABLE  (1 << 31)
 
+#define   UTIL_PIN_PIPE(x) ((x) << 29)
+#define   UTIL_PIN_PIPE_MASK   (3 << 29)
+#define   UTIL_PIN_MODE_PWM(1 << 24)
+#define   UTIL_PIN_MODE_MASK   (0xf << 24)
+#define   UTIL_PIN_POLARITY(1 << 22)
+
 /* BXT backlight register definition. */
-#define BXT_BLC_PWM_CTL1   0xC8250
+#define _BXT_BLC_PWM_CTL1  0xC8250
 #define   BXT_BLC_PWM_ENABLE   (1 << 31)
 #define   BXT_BLC_PWM_POLARITY (1 << 29)
-#define BXT_BLC_PWM_FREQ1  0xC8254
-#define BXT_BLC_PWM_DUTY1  0xC8258
-
-#define BXT_BLC_PWM_CTL2   0xC8350
-#define BXT_BLC_PWM_FREQ2  0xC8354
-#define BXT_BLC_PWM_DUTY2  0xC8358
-
+#define _BXT_BLC_PWM_FREQ1 0xC8254
+#define _BXT_BLC_PWM_DUTY1 0xC8258
+
+#define _BXT_BLC_PWM_CTL2  0xC8350
+#define _BXT_BLC_PWM_FREQ2 0xC8354
+#define _BXT_BLC_PWM_DUTY2 0xC8358
+
+#define BXT_BLC_PWM_CTL(controller)_PIPE(controller, \
+   _BXT_BLC_PWM_CTL1, _BXT_BLC_PWM_CTL2)
+#define BXT_BLC_PWM_FREQ(controller)   _PIPE(controller, \
+   _BXT_BLC_PWM_FREQ1, _BXT_BLC_PWM_FREQ2)
+#define BXT_BLC_PWM_DUTY(controller)   _PIPE(controller, \
+   _BXT_BLC_PWM_DUTY1, _BXT_BLC_PWM_DUTY2)
 
 #define PCH_GTC_CTL0xe7000
 #define   PCH_GTC_ENABLE   (1 << 31)
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 47bc729..ee9eb2b 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -182,7 +182,9 @@ struct intel_panel {
bool enabled;
bool combination_mode;  /* gen 2/4 only */
bool active_low_pwm;
+   bool util_pin_active_low;   /* bxt+ */
struct backlight_device *device;
+   u8 controller;  /* bxt+ only */
} backlight;
 
void (*backlight_power)(struct intel_connector *, bool enable);
diff --git a/drivers/gpu/drm/i915/intel_panel.c 
b/drivers/gpu/drm/i915/intel_panel.c
index 7d83527..23847f2 100644
--- a/drivers/gpu/drm/i915/intel_panel.c
+++ b/drivers/gpu/drm/i915/intel_panel.c
@@ -32,7 +32,10 @@
 
 #include 
 #include 
+#include 
 #include "intel_drv.h"
+#include "intel_dsi.h"
+#include "i915_drv.h"
 
 void
 intel_fixed_panel_mode(const struct drm_display_mode *fixed_mode,
@@ -539,9 +542,10 @@ static u32 vlv_get_backlight(struct intel_connector 
*connector)
 static u32 bxt_get_backlight(struct intel_connector *connector)
 {
struct drm_device *dev = connector->base.dev;
+   struct intel_panel *panel = &connector->panel;
struct drm_i915_priv

[Intel-gfx] [PATCH 03/12] drm/i915/bxt: Disable DSI PLL for BXT

2015-05-22 Thread Uma Shankar
From: Shashank Sharma 

This patch adds two new functions:
- disable_dsi_pll.
  BXT DSI disable sequence and registers are
  different from previous platforms.
- intel_disable_dsi_pll
  wrapper function to re-use the same code for
  multiple platforms. It checks platform type and
  calls appropriate core pll disable function.

Signed-off-by: Shashank Sharma 
Signed-off-by: Uma Shankar 
---
 drivers/gpu/drm/i915/intel_dsi.c |2 +-
 drivers/gpu/drm/i915/intel_dsi.h |2 +-
 drivers/gpu/drm/i915/intel_dsi_pll.c |   31 ++-
 3 files changed, 32 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c
index 1927546..2c0ea6f 100644
--- a/drivers/gpu/drm/i915/intel_dsi.c
+++ b/drivers/gpu/drm/i915/intel_dsi.c
@@ -553,7 +553,7 @@ static void intel_dsi_clear_device_ready(struct 
intel_encoder *encoder)
usleep_range(2000, 2500);
}
 
-   vlv_disable_dsi_pll(encoder);
+   intel_disable_dsi_pll(encoder);
 }
 
 static void intel_dsi_post_disable(struct intel_encoder *encoder)
diff --git a/drivers/gpu/drm/i915/intel_dsi.h b/drivers/gpu/drm/i915/intel_dsi.h
index 20cfcf07..759983e 100644
--- a/drivers/gpu/drm/i915/intel_dsi.h
+++ b/drivers/gpu/drm/i915/intel_dsi.h
@@ -122,7 +122,7 @@ static inline struct intel_dsi *enc_to_intel_dsi(struct 
drm_encoder *encoder)
 }
 
 extern void intel_enable_dsi_pll(struct intel_encoder *encoder);
-extern void vlv_disable_dsi_pll(struct intel_encoder *encoder);
+extern void intel_disable_dsi_pll(struct intel_encoder *encoder);
 extern u32 vlv_get_dsi_pclk(struct intel_encoder *encoder, int pipe_bpp);
 
 struct drm_panel *vbt_panel_init(struct intel_dsi *intel_dsi, u16 panel_id);
diff --git a/drivers/gpu/drm/i915/intel_dsi_pll.c 
b/drivers/gpu/drm/i915/intel_dsi_pll.c
index a58f0a1..0cbcf32 100644
--- a/drivers/gpu/drm/i915/intel_dsi_pll.c
+++ b/drivers/gpu/drm/i915/intel_dsi_pll.c
@@ -267,7 +267,7 @@ static void vlv_enable_dsi_pll(struct intel_encoder 
*encoder)
DRM_DEBUG_KMS("DSI PLL locked\n");
 }
 
-void vlv_disable_dsi_pll(struct intel_encoder *encoder)
+static void vlv_disable_dsi_pll(struct intel_encoder *encoder)
 {
struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
u32 tmp;
@@ -440,6 +440,23 @@ static void bxt_enable_dsi_pll(struct intel_encoder 
*encoder)
DRM_DEBUG_KMS("DSI PLL locked\n");
 }
 
+static void bxt_disable_dsi_pll(struct intel_encoder *encoder)
+{
+   struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
+
+   DRM_DEBUG_KMS("\n");
+
+   /* Disable DSI PLL */
+   I915_WRITE(BXT_DSI_PLL_ENABLE, 0);
+
+   /* Should timeout and fail if not locked after 200 us */
+   if (wait_for((I915_READ(BXT_DSI_PLL_ENABLE)
+   & BXT_DSI_PLL_LOCKED) == 0, 1)) {
+   DRM_ERROR("Disable: DSI PLL not locked\n");
+   return;
+   }
+}
+
 void intel_enable_dsi_pll(struct intel_encoder *encoder)
 {
struct drm_device *dev = encoder->base.dev;
@@ -451,3 +468,15 @@ void intel_enable_dsi_pll(struct intel_encoder *encoder)
else
DRM_ERROR("Invalid DSI device to pre_pll_enable\n");
 }
+
+void intel_disable_dsi_pll(struct intel_encoder *encoder)
+{
+   struct drm_device *dev = encoder->base.dev;
+
+   if (IS_VALLEYVIEW(dev))
+   vlv_disable_dsi_pll(encoder);
+   else if (IS_BROXTON(dev))
+   bxt_disable_dsi_pll(encoder);
+   else
+   DRM_ERROR("Invalid DSI device to pre_pll_enable\n");
+}
-- 
1.7.9.5

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


[Intel-gfx] [PATCH 07/12] drm/i915/bxt: Program Tx Rx and Dphy clocks

2015-05-22 Thread Uma Shankar
From: Shashank Sharma 

BXT DSI clocks are different than previous platforms. So adding a
new function to program following clocks and dividers:
1. Program variable divider to generate input to Tx clock divider
   (Output value must be < 39.5Mhz)
2. Select divide by 2 option to get < 20Mhz for Tx clock
3. Program 8by3 divider to generate Rx clock

Signed-off-by: Shashank Sharma 
Signed-off-by: Uma Shankar 
---
 drivers/gpu/drm/i915/i915_reg.h  |   51 ++
 drivers/gpu/drm/i915/intel_dsi.c |3 ++
 drivers/gpu/drm/i915/intel_dsi.h |1 +
 drivers/gpu/drm/i915/intel_dsi_pll.c |   35 +++
 4 files changed, 90 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 5eeb2b7..f96f049 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -7387,6 +7387,57 @@ enum skl_disp_power_wells {
 #define GEN9_FUSE_PG1_ENABLED  (1 << 26)
 #define GEN9_FUSE_PG0_ENABLED  (1 << 27)
 
+/* BXT MIPI clock controls */
+#define BXT_MAX_VAR_OUTPUT_KHZ  39500
+#define BXT_MIPI_CLOCK_CTL  0x46090
+#define BXT_MIPI_DIV_SHIFT  16
+
+/* Var clock divider to generate TX source. Result must be < 39.5 M */
+#define BXT_MIPI1_ESCLK_VAR_DIV_MASK(0x3F << 26)
+/* BXT MIPI clock controls */
+#define BXT_MAX_VAR_OUTPUT_KHZ  39500
+#define BXT_MIPI_CLOCK_CTL  0x46090
+#define BXT_MIPI_DIV_SHIFT  16
+
+/* Var clock divider to generate TX source. Result must be < 39.5 M */
+#define BXT_MIPI1_ESCLK_VAR_DIV_MASK(0x3F << 26)
+#define BXT_MIPI2_ESCLK_VAR_DIV_MASK(0x3F << 10)
+#define BXT_MIPI_ESCLK_VAR_DIV_MASK(check)\
+   (0x3F << ((!check) * BXT_MIPI_DIV_SHIFT + 10))
+#define BXT_MIPI_ESCLK_VAR_DIV(check, val)\
+   (val << ((!check) * BXT_MIPI_DIV_SHIFT + 10))
+
+/* TX control divider to select actual TX clock output from (8x/var) */
+#define BXT_MIPI1_TX_ESCLK_FIXDIV_MASK(3 << 21)
+#define BXT_MIPI2_TX_ESCLK_FIXDIV_MASK(3 << 5)
+#define BXT_MIPI_TX_ESCLK_FIXDIV_MASK(check)  \
+   (3 << ((!check) * BXT_MIPI_DIV_SHIFT + 5))
+
+#define BXT_MIPI_TX_ESCLK_8XDIV_BY2(check)\
+   (0x0 << ((!check) * BXT_MIPI_DIV_SHIFT + 5))
+#define BXT_MIPI_TX_ESCLK_8XDIV_BY4(check)\
+   (0x1 << ((!check) * BXT_MIPI_DIV_SHIFT + 5))
+#define BXT_MIPI_TX_ESCLK_8XDIV_BY8(check)\
+   (0x2 << ((!check) * BXT_MIPI_DIV_SHIFT + 5))
+
+/* RX control divider to select actual RX clock output from 8x*/
+#define BXT_MIPI1_RX_ESCLK_FIXDIV_MASK(3 << 19)
+#define BXT_MIPI2_RX_ESCLK_FIXDIV_MASK(3 << 3)
+#define BXT_MIPI_RX_ESCLK_FIXDIV_MASK(check)  \
+   (3 << ((!check) * BXT_MIPI_DIV_SHIFT + 3))
+#define BXT_MIPI_RX_ESCLK_8X_BY2(check)   \
+   (1 << ((!check) * BXT_MIPI_DIV_SHIFT + 3))
+#define BXT_MIPI_RX_ESCLK_8X_BY3(check)   \
+   (2 << ((!check) * BXT_MIPI_DIV_SHIFT + 3))
+#define BXT_MIPI_RX_ESCLK_8X_BY4(check)   \
+   (3 << ((!check) * BXT_MIPI_DIV_SHIFT + 3))
+
+/* BXT: Always prog DPHY dividers to 00 */
+#define BXT_MIPI_1_DPHY_DIVIDER_MASK  (3 << 16)
+#define BXT_MIPI_2_DPHY_DIVIDER_MASK  (3 << 0)
+#define BXT_MIPI_DPHY_DIVIDER_MASK(check)   \
+   (3 << ((!check) * BXT_MIPI_DIV_SHIFT))
+
 /* BXT MIPI mode configure */
 #define _BXT_MIPIA_TRANS_HACTIVE   0x6B0F8
 #define _BXT_MIPIC_TRANS_HACTIVE   0x6B8F8
diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c
index 3a1bb04..729faf6 100644
--- a/drivers/gpu/drm/i915/intel_dsi.c
+++ b/drivers/gpu/drm/i915/intel_dsi.c
@@ -503,6 +503,9 @@ static void intel_dsi_pre_enable(struct intel_encoder 
*encoder)
tmp = I915_READ(DSPCLK_GATE_D);
tmp |= DPOUNIT_CLOCK_GATE_DISABLE;
I915_WRITE(DSPCLK_GATE_D, tmp);
+   } else if (IS_BROXTON(dev)) {
+   /* Program Tx Rx and Dphy clocks */
+   bxt_dsi_program_clocks(dev, intel_dsi->ports);
}
 
/* put device in ready state */
diff --git a/drivers/gpu/drm/i915/intel_dsi.h b/drivers/gpu/drm/i915/intel_dsi.h
index 759983e..af5a09f 100644
--- a/drivers/gpu/drm/i915/intel_dsi.h
+++ b/drivers/gpu/drm/i915/intel_dsi.h
@@ -124,6 +124,7 @@ static inline struct intel_dsi *enc_to_intel_dsi(struct 
drm_encoder *encoder)
 extern void intel_enable_dsi_pll(struct intel_encoder *encoder);
 extern void intel_disable_dsi_pll(struct intel_encoder *encoder);
 extern u32 vlv_get_dsi_pclk(struct intel_encoder *encoder, int pipe_bpp);
+extern void bxt_dsi_program_clocks(struct drm_device *dev, int pipe);
 
 struct drm_panel *vbt_panel_init(struct intel_dsi *intel_dsi, u16 panel_id);
 
diff --git a/drivers/gpu/drm/i

[Intel-gfx] [PATCH 06/12] drm/i915/bxt: DSI enable for BXT

2015-05-22 Thread Uma Shankar
From: Shashank Sharma 

This patch contains following changes:
1. MIPI device ready changes to support dsi_pre_enable. Changes
   are specific to BXT device ready sequence. Added check for
   ULPS mode(No effects on VLV).
2. Changes in dsi_enable to pick BXT port control register.
3. Changes in dsi_pre_enable to restrict DPIO programming for VLV

Signed-off-by: Shashank Sharma 
Signed-off-by: Uma Shankar 
---
 drivers/gpu/drm/i915/i915_reg.h  |7 ++
 drivers/gpu/drm/i915/intel_dsi.c |  185 --
 2 files changed, 144 insertions(+), 48 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 57c3a48..5eeb2b7 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -7408,6 +7408,13 @@ enum skl_disp_power_wells {
 #define _MIPIA_PORT_CTRL   (VLV_DISPLAY_BASE + 0x61190)
 #define _MIPIC_PORT_CTRL   (VLV_DISPLAY_BASE + 0x61700)
 #define MIPI_PORT_CTRL(port)   _MIPI_PORT(port, _MIPIA_PORT_CTRL, 
_MIPIC_PORT_CTRL)
+
+ /* BXT port control */
+#define _BXT_MIPIA_PORT_CTRL   0x6B0C0
+#define _BXT_MIPIC_PORT_CTRL   0x6B8C0
+#define BXT_MIPI_PORT_CTRL(tc) _TRANSCODER(tc, _BXT_MIPIA_PORT_CTRL, \
+   _BXT_MIPIC_PORT_CTRL)
+
 #define  DPI_ENABLE(1 << 31) /* A + C */
 #define  MIPIA_MIPI4DPHY_DELAY_COUNT_SHIFT 27
 #define  MIPIA_MIPI4DPHY_DELAY_COUNT_MASK  (0xf << 27)
diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c
index 892b518..3a1bb04 100644
--- a/drivers/gpu/drm/i915/intel_dsi.c
+++ b/drivers/gpu/drm/i915/intel_dsi.c
@@ -286,6 +286,101 @@ static bool intel_dsi_compute_config(struct intel_encoder 
*encoder,
return true;
 }
 
+static void bxt_dsi_device_ready(struct intel_encoder *encoder)
+{
+   struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
+   struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
+   enum port port;
+   u32 val;
+
+   DRM_DEBUG_KMS("\n");
+
+   /* Exit Low power state in 4 steps*/
+   for_each_dsi_port(port, intel_dsi->ports) {
+
+   /* 1. Enable MIPI PHY transparent latch */
+   val = I915_READ(BXT_MIPI_PORT_CTRL(port));
+   I915_WRITE(BXT_MIPI_PORT_CTRL(port), val | LP_OUTPUT_HOLD);
+   usleep_range(2000, 2500);
+
+   /* 2. Enter ULPS */
+   val = I915_READ(MIPI_DEVICE_READY(port));
+   val &= ~ULPS_STATE_MASK;
+   val |= (ULPS_STATE_ENTER | DEVICE_READY);
+   I915_WRITE(MIPI_DEVICE_READY(port), val);
+   usleep_range(2, 3);
+
+   /* 3. Exit ULPS */
+   val = I915_READ(MIPI_DEVICE_READY(port));
+   val &= ~ULPS_STATE_MASK;
+   val |= (ULPS_STATE_EXIT | DEVICE_READY);
+   I915_WRITE(MIPI_DEVICE_READY(port), val);
+   usleep_range(1000, 1500);
+
+   /* Clear ULPS and set device ready */
+   val = I915_READ(MIPI_DEVICE_READY(port));
+   val &= ~ULPS_STATE_MASK;
+   val |= DEVICE_READY;
+   I915_WRITE(MIPI_DEVICE_READY(port), val);
+   }
+}
+
+static void vlv_dsi_device_ready(struct intel_encoder *encoder)
+{
+   struct drm_device *dev = encoder->base.dev;
+   struct drm_i915_private *dev_priv = dev->dev_private;
+   struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
+   struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc);
+   int pipe = intel_crtc->pipe;
+   u32 val;
+   int count = 1;
+   u32 reg = 0;
+   bool afe_latchout = true;
+
+   DRM_DEBUG_KMS("\n");
+
+   pipe = intel_crtc->pipe;
+   reg = MIPI_PORT_CTRL(pipe);
+
+   /* Ceck LP state */
+   val = I915_READ(reg);
+   afe_latchout = (val & AFE_LATCHOUT);
+
+   /* Enter low power state, if not already in */
+   if (afe_latchout) {
+   /* Enter ULPS, wait for 2.5 ms */
+   reg = MIPI_DEVICE_READY(pipe);
+   I915_WRITE(reg, val | ULPS_STATE_ENTER);
+   usleep_range(2000, 2500);
+   }
+
+   /* Enable transparent latch */
+   I915_WRITE(reg, val | LP_OUTPUT_HOLD);
+
+   if (intel_dsi->dual_link) {
+   count = 2;
+   pipe = PIPE_A;
+   }
+
+   do {
+   I915_WRITE(reg, val | ULPS_STATE_EXIT);
+   usleep_range(2000, 2500);
+   /* Clear ULPS state */
+   val = I915_READ(MIPI_DEVICE_READY(pipe)) & ~ULPS_STATE_MASK;
+   I915_WRITE(MIPI_DEVICE_READY(pipe), val);
+   usleep_range(2000, 2500);
+
+   /* Set device ready */
+   val |= DEVICE_READY;
+   I915_WRITE(MIPI_DEVICE_READY(pipe), val);
+   

[Intel-gfx] [PATCH 10/12] drm/i915/bxt: get DSI pixelclock

2015-05-22 Thread Uma Shankar
From: Shashank Sharma 

BXT's DSI PLL is different from that of VLV. So this patch
adds a new function to get the current DSI pixel clock based
on the PLL divider ratio and lane count.

This function is required for intel_dsi_get_config() function.

Signed-off-by: Shashank Sharma 
Signed-off-by: Uma Shankar 
---
 drivers/gpu/drm/i915/intel_dsi.c |   10 --
 drivers/gpu/drm/i915/intel_dsi.h |1 +
 drivers/gpu/drm/i915/intel_dsi_pll.c |   35 ++
 3 files changed, 44 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c
index 2663cdd..5fbcebe 100644
--- a/drivers/gpu/drm/i915/intel_dsi.c
+++ b/drivers/gpu/drm/i915/intel_dsi.c
@@ -714,7 +714,7 @@ static bool intel_dsi_get_hw_state(struct intel_encoder 
*encoder,
 static void intel_dsi_get_config(struct intel_encoder *encoder,
 struct intel_crtc_state *pipe_config)
 {
-   u32 pclk;
+   u32 pclk = 0;
DRM_DEBUG_KMS("\n");
 
/*
@@ -723,7 +723,13 @@ static void intel_dsi_get_config(struct intel_encoder 
*encoder,
 */
pipe_config->dpll_hw_state.dpll_md = 0;
 
-   pclk = vlv_get_dsi_pclk(encoder, pipe_config->pipe_bpp);
+   if (IS_BROXTON(encoder->base.dev))
+   pclk = bxt_get_dsi_pclk(encoder, pipe_config->pipe_bpp);
+   else if (IS_VALLEYVIEW(encoder->base.dev))
+   pclk = vlv_get_dsi_pclk(encoder, pipe_config->pipe_bpp);
+   else
+   DRM_ERROR("Invalid DSI device to get config\n");
+
if (!pclk)
return;
 
diff --git a/drivers/gpu/drm/i915/intel_dsi.h b/drivers/gpu/drm/i915/intel_dsi.h
index 8bc8d94..01e08e7 100644
--- a/drivers/gpu/drm/i915/intel_dsi.h
+++ b/drivers/gpu/drm/i915/intel_dsi.h
@@ -124,6 +124,7 @@ static inline struct intel_dsi *enc_to_intel_dsi(struct 
drm_encoder *encoder)
 extern void intel_enable_dsi_pll(struct intel_encoder *encoder);
 extern void intel_disable_dsi_pll(struct intel_encoder *encoder);
 extern u32 vlv_get_dsi_pclk(struct intel_encoder *encoder, int pipe_bpp);
+extern u32 bxt_get_dsi_pclk(struct intel_encoder *encoder, int pipe_bpp);
 extern void bxt_dsi_program_clocks(struct drm_device *dev, int pipe);
 extern void intel_dsi_reset_clocks(struct intel_encoder *encoder,
enum port port);
diff --git a/drivers/gpu/drm/i915/intel_dsi_pll.c 
b/drivers/gpu/drm/i915/intel_dsi_pll.c
index 49330b0..073bd1f 100644
--- a/drivers/gpu/drm/i915/intel_dsi_pll.c
+++ b/drivers/gpu/drm/i915/intel_dsi_pll.c
@@ -369,6 +369,41 @@ u32 vlv_get_dsi_pclk(struct intel_encoder *encoder, int 
pipe_bpp)
return pclk;
 }
 
+u32 bxt_get_dsi_pclk(struct intel_encoder *encoder, int pipe_bpp)
+{
+   u32 pclk;
+   u32 dsi_clk;
+   u32 dsi_ratio;
+   struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
+   struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
+
+   /* Divide by zero */
+   if (!pipe_bpp) {
+   DRM_ERROR("Invalid BPP(0)\n");
+   return 0;
+   }
+
+   dsi_ratio = I915_READ(BXT_DSI_PLL_CTL) &
+   BXT_DSI_MASK_PLL_RATIO;
+
+   /* Invalid DSI ratio ? */
+   if (dsi_ratio < BXT_DSI_PLL_RATIO_MIN ||
+   dsi_ratio > BXT_DSI_PLL_RATIO_MAX) {
+   DRM_ERROR("Invalid DSI pll ratio(%u) programmed\n", dsi_ratio);
+   return 0;
+   }
+
+   dsi_clk = (dsi_ratio * BXT_REF_CLOCK_KHZ) / 2;
+
+   /* pixel_format and pipe_bpp should agree */
+   assert_bpp_mismatch(intel_dsi->pixel_format, pipe_bpp);
+
+   pclk = DIV_ROUND_CLOSEST(dsi_clk * intel_dsi->lane_count, pipe_bpp);
+
+   DRM_DEBUG_DRIVER("Calculated pclk=%u\n", pclk);
+   return pclk;
+}
+
 void vlv_dsi_reset_clocks(struct intel_encoder *encoder, enum port port)
 {
u32 temp;
-- 
1.7.9.5

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


[Intel-gfx] [PATCH 09/12] drm/i915/bxt: get_hw_state for BXT

2015-05-22 Thread Uma Shankar
From: Shashank Sharma 

Pick appropriate port control register (BXT or VLV), based on device.
Get the current hw state wrt Mipi port.

Signed-off-by: Shashank Sharma 
Signed-off-by: Uma Shankar 
---
 drivers/gpu/drm/i915/intel_dsi.c |7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c
index e4b96bc..2663cdd 100644
--- a/drivers/gpu/drm/i915/intel_dsi.c
+++ b/drivers/gpu/drm/i915/intel_dsi.c
@@ -675,7 +675,7 @@ static bool intel_dsi_get_hw_state(struct intel_encoder 
*encoder,
struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
struct drm_device *dev = encoder->base.dev;
enum intel_display_power_domain power_domain;
-   u32 dpi_enabled, func;
+   u32 dpi_enabled, func, ctrl_reg;
enum port port;
 
DRM_DEBUG_KMS("\n");
@@ -687,8 +687,9 @@ static bool intel_dsi_get_hw_state(struct intel_encoder 
*encoder,
/* XXX: this only works for one DSI output */
for_each_dsi_port(port, intel_dsi->ports) {
func = I915_READ(MIPI_DSI_FUNC_PRG(port));
-   dpi_enabled = I915_READ(MIPI_PORT_CTRL(port)) &
-   DPI_ENABLE;
+   ctrl_reg = IS_BROXTON(dev) ? BXT_MIPI_PORT_CTRL(port) :
+   MIPI_PORT_CTRL(port);
+   dpi_enabled = I915_READ(ctrl_reg) & DPI_ENABLE;
 
/* Due to some hardware limitations on BYT, MIPI Port C DPI
 * Enable bit does not get set. To check whether DSI Port C
-- 
1.7.9.5

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


[Intel-gfx] [PATCH 05/12] drm/i915/bxt: DSI encoder support in CRTC modeset

2015-05-22 Thread Uma Shankar
From: Shashank Sharma 

SKL and BXT qualifies the HAS_DDI() check, and hence haswell modeset
functions are re-used for modeset sequence. But DDI interface doesn't
include support for DSI.
This patch adds:
1. cases for DSI encoder, in those modeset functions and allows a CRTC modeset
2. Adds call to pre_pll enabled from CRTC modeset function. Nothing needs to be
   done as such in CRTC for DSI encoder, as PLL, clock and and transcoder 
programming
   will be taken care in encoder's pre_enable and pre_pll_enable function.

Signed-off-by: Shashank Sharma 
Signed-off-by: Uma Shankar 
---
 drivers/gpu/drm/i915/i915_drv.h   |1 +
 drivers/gpu/drm/i915/intel_ddi.c  |   53 +
 drivers/gpu/drm/i915/intel_display.c  |6 +++-
 drivers/gpu/drm/i915/intel_opregion.c |1 +
 4 files changed, 54 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 840f08f..6874121 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2452,6 +2452,7 @@ struct drm_i915_cmd_table {
 INTEL_INFO(dev)->gen >= 9)
 
 #define HAS_DDI(dev)   (INTEL_INFO(dev)->has_ddi)
+#define has_encoder_ddi(type)  ((type) == (INTEL_OUTPUT_DSI) ?  0 : 1)
 #define HAS_FPGA_DBG_UNCLAIMED(dev)(INTEL_INFO(dev)->has_fpga_dbg)
 #define HAS_PSR(dev)   (IS_HASWELL(dev) || IS_BROADWELL(dev) || \
 IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev) || \
diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index d602db2..2aef8b5 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -395,6 +395,12 @@ void intel_prepare_ddi(struct drm_device *dev)
if (visited[port])
continue;
 
+   if (intel_dig_port->base.type ==
+   INTEL_OUTPUT_DSI) {
+   visited[intel_dig_port->port] = true;
+   continue;
+   }
+
supports_hdmi = intel_dig_port &&
intel_dig_port_supports_hdmi(intel_dig_port);
 
@@ -1568,10 +1574,21 @@ void intel_ddi_enable_transcoder_func(struct drm_crtc 
*crtc)
struct drm_i915_private *dev_priv = dev->dev_private;
enum pipe pipe = intel_crtc->pipe;
enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
-   enum port port = intel_ddi_get_encoder_port(intel_encoder);
+   enum port port;
int type = intel_encoder->type;
uint32_t temp;
 
+   /*
+* Fixme: BXT has DDI, so tries to follow a DDI modeset function,
+* but DDI interface doesn't support DSI yet, so don't do anything
+* for DSI encoders
+*/
+   if (!(HAS_DDI(dev) && has_encoder_ddi(type))) {
+   DRM_DEBUG_DRIVER("Not setting transcoder for DSI\n");
+   return;
+   }
+
+   port = intel_ddi_get_encoder_port(intel_encoder);
/* Enable TRANS_DDI_FUNC_CTL for the pipe to work in HDMI mode */
temp = TRANS_DDI_FUNC_ENABLE;
temp |= TRANS_DDI_SELECT_PORT(port);
@@ -1779,11 +1796,17 @@ bool intel_ddi_get_hw_state(struct intel_encoder 
*encoder,
 void intel_ddi_enable_pipe_clock(struct intel_crtc *intel_crtc)
 {
struct drm_crtc *crtc = &intel_crtc->base;
-   struct drm_i915_private *dev_priv = crtc->dev->dev_private;
+   struct drm_device *dev = crtc->dev;
+   struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
-   enum port port = intel_ddi_get_encoder_port(intel_encoder);
+   enum port port;
enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
+   int type = intel_encoder->type;
 
+   if (!(HAS_DDI(dev) && has_encoder_ddi(type)))
+   return;
+
+   port = intel_ddi_get_encoder_port(intel_encoder);
if (cpu_transcoder != TRANSCODER_EDP)
I915_WRITE(TRANS_CLK_SEL(cpu_transcoder),
   TRANS_CLK_SEL_PORT(port));
@@ -1866,10 +1889,16 @@ static void intel_ddi_pre_enable(struct intel_encoder 
*intel_encoder)
struct drm_device *dev = encoder->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_crtc *crtc = to_intel_crtc(encoder->crtc);
-   enum port port = intel_ddi_get_encoder_port(intel_encoder);
+   enum port port;
int type = intel_encoder->type;
int hdmi_level;
 
+   if (!(HAS_DDI(dev) && has_encoder_ddi(type))) {
+   DRM_ERROR("DDI func getting called for MIPI?\n");
+   return;
+   }
+
+   port = intel_ddi_get_encoder_port(intel_encoder);
if (type == INTEL_OUTPUT_EDP) {
struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
intel_edp_panel_on(intel_dp);
@@ -1942,11 +1971,17 @@ static void 

[Intel-gfx] [PATCH 04/12] drm/i915/bxt: DSI prepare changes for BXT

2015-05-22 Thread Uma Shankar
From: Shashank Sharma 

This patch modifies dsi_prepare() function to support the same
modeset prepare sequence for BXT also. Main changes are:
1. BXT port control register is different than VLV.
2. BXT modeset sequence needs vdisplay and hdisplay programmed
   for transcoder.
3. BXT can select PIPE for MIPI transcoders.
4. BXT needs to program register MIPI_INIT_COUNT for both the ports,
   even if only one is being used.

Signed-off-by: Shashank Sharma 
Signed-off-by: Uma Shankar 
---
 drivers/gpu/drm/i915/i915_reg.h  |   22 +++
 drivers/gpu/drm/i915/intel_dsi.c |   79 +-
 2 files changed, 91 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index b63bdce..57c3a48 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -7387,6 +7387,22 @@ enum skl_disp_power_wells {
 #define GEN9_FUSE_PG1_ENABLED  (1 << 26)
 #define GEN9_FUSE_PG0_ENABLED  (1 << 27)
 
+/* BXT MIPI mode configure */
+#define _BXT_MIPIA_TRANS_HACTIVE   0x6B0F8
+#define _BXT_MIPIC_TRANS_HACTIVE   0x6B8F8
+#define BXT_MIPI_TRANS_HACTIVE(tc)  _TRANSCODER(tc, \
+   _BXT_MIPIA_TRANS_HACTIVE, _BXT_MIPIC_TRANS_HACTIVE)
+
+#define _BXT_MIPIA_TRANS_VACTIVE   0x6B0FC
+#define _BXT_MIPIC_TRANS_VACTIVE   0x6B8FC
+#define BXT_MIPI_TRANS_VACTIVE(tc)  _TRANSCODER(tc, \
+   _BXT_MIPIA_TRANS_VACTIVE, _BXT_MIPIC_TRANS_VACTIVE)
+
+#define _BXT_MIPIA_TRANS_VTOTAL   0x6B100
+#define _BXT_MIPIC_TRANS_VTOTAL   0x6B900
+#define BXT_MIPI_TRANS_VTOTAL(tc)   _TRANSCODER(tc, \
+   _BXT_MIPIA_TRANS_VTOTAL, _BXT_MIPIC_TRANS_VTOTAL)
+
 #define _MIPI_PORT(port, a, c) _PORT3(port, a, 0, c)   /* ports A and C only */
 
 #define _MIPIA_PORT_CTRL   (VLV_DISPLAY_BASE + 0x61190)
@@ -7802,6 +7818,12 @@ enum skl_disp_power_wells {
 #define  READ_REQUEST_PRIORITY_HIGH(3 << 3)
 #define  RGB_FLIP_TO_BGR   (1 << 2)
 
+/* BXT has a pipe select field */
+#define BXT_PIPE_SELECT_A   (0 << 7)
+#define BXT_PIPE_SELECT_B   (1 << 7)
+#define BXT_PIPE_SELECT_C   (2 << 7)
+#define BXT_PIPE_SELECT_MASK(7 << 7)
+
 #define _MIPIA_DATA_ADDRESS(dev_priv->mipi_mmio_base + 0xb108)
 #define _MIPIC_DATA_ADDRESS(dev_priv->mipi_mmio_base + 0xb908)
 #define MIPI_DATA_ADDRESS(port)_MIPI_PORT(port, 
_MIPIA_DATA_ADDRESS, \
diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c
index 2c0ea6f..892b518 100644
--- a/drivers/gpu/drm/i915/intel_dsi.c
+++ b/drivers/gpu/drm/i915/intel_dsi.c
@@ -726,6 +726,21 @@ static void set_dsi_timings(struct drm_encoder *encoder,
hbp = txbyteclkhs(hbp, bpp, lane_count, intel_dsi->burst_mode_ratio);
 
for_each_dsi_port(port, intel_dsi->ports) {
+   if (IS_BROXTON(dev)) {
+   /*
+* Program hdisplay and vdisplay on MIPI transcoder.
+* This is different from calculated hactive and
+* vactive, as they are calculated per channel basis,
+* whereas these values should be based on resolution.
+*/
+   I915_WRITE(BXT_MIPI_TRANS_HACTIVE(port),
+   mode->hdisplay);
+   I915_WRITE(BXT_MIPI_TRANS_VACTIVE(port),
+   mode->vdisplay);
+   I915_WRITE(BXT_MIPI_TRANS_VTOTAL(port),
+   mode->vtotal);
+   }
+
I915_WRITE(MIPI_HACTIVE_AREA_COUNT(port), hactive);
I915_WRITE(MIPI_HFP_COUNT(port), hfp);
 
@@ -766,16 +781,38 @@ static void intel_dsi_prepare(struct intel_encoder 
*intel_encoder)
}
 
for_each_dsi_port(port, intel_dsi->ports) {
-   /* escape clock divider, 20MHz, shared for A and C.
-* device ready must be off when doing this! txclkesc? */
-   tmp = I915_READ(MIPI_CTRL(PORT_A));
-   tmp &= ~ESCAPE_CLOCK_DIVIDER_MASK;
-   I915_WRITE(MIPI_CTRL(PORT_A), tmp | ESCAPE_CLOCK_DIVIDER_1);
-
-   /* read request priority is per pipe */
-   tmp = I915_READ(MIPI_CTRL(port));
-   tmp &= ~READ_REQUEST_PRIORITY_MASK;
-   I915_WRITE(MIPI_CTRL(port), tmp | READ_REQUEST_PRIORITY_HIGH);
+   if (IS_VALLEYVIEW(dev)) {
+   /*
+* escape clock divider, 20MHz, shared for A and C.
+* device ready must be off when doing this! txclkesc?
+

[Intel-gfx] [PATCH 01/12] drm/i915/bxt: Initialize MIPI for BXT

2015-05-22 Thread Uma Shankar
From: Shashank Sharma 

This patch contains following changes:
1. Add BXT MIPI display address base.
2. Call dsi_init from display_setup function.

Signed-off-by: Shashank Sharma 
Signed-off-by: Uma Shankar 
---
 drivers/gpu/drm/i915/i915_reg.h  |1 +
 drivers/gpu/drm/i915/intel_display.c |3 +++
 drivers/gpu/drm/i915/intel_dsi.c |2 ++
 3 files changed, 6 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 84af255..46ef269 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -1643,6 +1643,7 @@ enum skl_disp_power_wells {
 
 #define VLV_DISPLAY_BASE 0x18
 #define VLV_MIPI_BASE VLV_DISPLAY_BASE
+#define BXT_MIPI_BASE 0x6
 
 #define VLV_GU_CTL0(VLV_DISPLAY_BASE + 0x2030)
 #define VLV_GU_CTL1(VLV_DISPLAY_BASE + 0x2034)
diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index 9d2d6fb..c30bfd4 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -13706,6 +13706,9 @@ static void intel_setup_outputs(struct drm_device *dev)
 * DDI_BUF_CTL_A or SFUSE_STRAP registers, find another way to
 * detect the ports.
 */
+   /* Initialize MIPI for BXT */
+   intel_dsi_init(dev);
+
intel_ddi_init(dev, PORT_A);
intel_ddi_init(dev, PORT_B);
intel_ddi_init(dev, PORT_C);
diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c
index 5196642..2419929e 100644
--- a/drivers/gpu/drm/i915/intel_dsi.c
+++ b/drivers/gpu/drm/i915/intel_dsi.c
@@ -998,6 +998,8 @@ void intel_dsi_init(struct drm_device *dev)
 
if (IS_VALLEYVIEW(dev)) {
dev_priv->mipi_mmio_base = VLV_MIPI_BASE;
+   } else if (IS_BROXTON(dev)) {
+   dev_priv->mipi_mmio_base = BXT_MIPI_BASE;
} else {
DRM_ERROR("Unsupported Mipi device to reg base");
return;
-- 
1.7.9.5

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


Re: [Intel-gfx] [PATCH intel-gpu-tools 1/3] drmtest: Add non-i915 device open helpers

2015-05-22 Thread Micah Fedke

Daniel,

Thanks.

I'm working to implement the driver name param and drm_require_driver 
now.  The prime stuff I'll have to familiarize myself with a bit more 
(and maybe dredge up some hw) but your suggestions sound reasonable enough.



-mf

On 05/22/2015 02:17 AM, Daniel Vetter wrote:

Forgotten to add Thomas as the igt maintainer.
-Daniel

On Fri, May 8, 2015 at 3:03 PM, Daniel Vetter  wrote:

On Tue, Apr 21, 2015 at 5:06 PM, Daniel Stone  wrote:

On 21 April 2015 at 16:03, Micah Fedke  wrote:

+ * drm_open_any_any:
+ *
+ * Literally the worst-named function I've ever written.


And I stand by this. This is really an RFC, partly to find out whether
it would be better to find a new name for these functions (open a
modeset-capable DRM node, whether it's Intel or otherwise), or whether
adding a flag to drm_open_any and friends to specify Intel or generic,
with the resulting mega-Cocci run, would be better.


Yeah I think a new param to restrict the driver name (i915, nouveau,
...) would be better. Plus maybe a drm_require_driver so that testcase
could open a generic driver and then only skip specific subtest.
Initial pass could be done with cocci+ follow-up patches to convert
patches from i915 specific to generic.

One thing to keep in mind is how we'll treat machines with more than 1
gpu. I do care about that at least for the prime testcases since I
have a box somewhere with i915+nouveau to run them, and that should
keep working. Aside: We should convert those tests to use
drm_open_any("nouveau") instead of the hand-rolled one. A possible
idea would be to convert the igt_main macros into a loop which would
go over all the available drm devices (well the different ones, we
don't want to separately test control/render/legacy nodes ofc). What
we definitely need is an enviroment variable to override the default
choice.
-Daniel
--
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch






--

Micah Fedke
Collabora Ltd.
+44 1223 362967
https://www.collabora.com/
https://twitter.com/collaboraltd
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH 3/3] drm/i915: Enable GTT caching on gen8

2015-05-22 Thread Jesse Barnes
On 05/21/2015 11:10 PM, Daniel Vetter wrote:
> On Thu, May 21, 2015 at 01:18:44PM -0700, Jesse Barnes wrote:
>> On 05/19/2015 10:32 AM, ville.syrj...@linux.intel.com wrote:
>>> From: Ville Syrjälä 
>>>
>>> GTT caching was disabled by default on gen8 due to not working with
>>> big pages. Some information suggests that it got fixed, but still
>>> GTT caching has been left disabled by default. Or could be it just
>>> meant that the default was changed to off, and hence the problem
>>> got solved.
>>>
>>> Enable GTT caching in the hopes of some performance increase.
>>> Whether or not the big pages issue has been fixed is irrelevant
>>> at this stage since we don't use big pages.
>>>
>>> This gives me a 1-2% improvement in xonotic on my BSW. Haven't tried
>>> BDW, but supposedly it has larger TLBs so might not benefit as much.
>>> On HSW GTT caching is enabled by default.
>>>
>>> Signed-off-by: Ville Syrjälä 
>>> ---
>>>  drivers/gpu/drm/i915/i915_reg.h |  2 ++
>>>  drivers/gpu/drm/i915/intel_pm.c | 13 +
>>>  2 files changed, 15 insertions(+)
>>>
>>> diff --git a/drivers/gpu/drm/i915/i915_reg.h 
>>> b/drivers/gpu/drm/i915/i915_reg.h
>>> index 84af255..90640d5 100644
>>> --- a/drivers/gpu/drm/i915/i915_reg.h
>>> +++ b/drivers/gpu/drm/i915/i915_reg.h
>>> @@ -1461,6 +1461,8 @@ enum skl_disp_power_wells {
>>>  #define RING_HWS_PGA(base) ((base)+0x80)
>>>  #define RING_HWS_PGA_GEN6(base)((base)+0x2080)
>>>  
>>> +#define HSW_GTT_CACHE_EN   0x4024
>>> +#define   GTT_CACHE_EN_ALL 0xF0007FFF
>>>  #define GEN7_WR_WATERMARK  0x4028
>>>  #define GEN7_GFX_PRIO_CTRL 0x402C
>>>  #define ARB_MODE   0x4030
>>> diff --git a/drivers/gpu/drm/i915/intel_pm.c 
>>> b/drivers/gpu/drm/i915/intel_pm.c
>>> index 5ec56b6..58517a50 100644
>>> --- a/drivers/gpu/drm/i915/intel_pm.c
>>> +++ b/drivers/gpu/drm/i915/intel_pm.c
>>> @@ -6205,6 +6205,13 @@ static void broadwell_init_clock_gating(struct 
>>> drm_device *dev)
>>> I915_WRITE(GEN8_L3SQCREG1, BDW_WA_L3SQCREG1_DEFAULT);
>>> I915_WRITE(GEN7_MISCCPCTL, misccpctl);
>>>  
>>> +   /*
>>> +* WaGttCachingOffByDefault:bdw
>>> +* GTT cache may not work with big pages, so if those
>>> +* are ever enabled GTT cache may need to be disabled.
>>> +*/
>>> +   I915_WRITE(HSW_GTT_CACHE_EN, GTT_CACHE_EN_ALL);
>>> +
>>> lpt_init_clock_gating(dev);
>>>  }
>>>  
>>> @@ -6480,6 +6487,12 @@ static void cherryview_init_clock_gating(struct 
>>> drm_device *dev)
>>> /* WaDisableSDEUnitClockGating:chv */
>>> I915_WRITE(GEN8_UCGCTL6, I915_READ(GEN8_UCGCTL6) |
>>>GEN8_SDEUNIT_CLOCK_GATE_DISABLE);
>>> +
>>> +   /*
>>> +* GTT cache may not work with big pages, so if those
>>> +* are ever enabled GTT cache may need to be disabled.
>>> +*/
>>> +   I915_WRITE(HSW_GTT_CACHE_EN, GTT_CACHE_EN_ALL);
>>>  }
>>>  
>>>  static void g4x_init_clock_gating(struct drm_device *dev)
>>>
>>
>> Looks ok to me; I guess testing will be the real review here.
> 
> Just aside: If you think the real test for a patch is the real world imo
> an important part of the review work is to make sure we do have that
> testing coverage. We have a few igts that specifically exercise gtt tlb
> issues (from previous generations), so I think we're covered here.
> 
>> Reviewed-by: Jesse Barnes 
> 
> Merged all three, thanks for patches&review.

Yeah I don't think it's something that requires a dedicated test, just
lots of coverage with our existing stuff to sniff out problems.

Thanks,
Jesse

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


Re: [Intel-gfx] [PATCH] drm/edid: Fix DDC probe for passive DP dongles

2015-05-22 Thread Todd Previte



On 5/21/2015 1:28 AM, Jani Nikula wrote:

On Thu, 21 May 2015, Todd Previte  wrote:

Passive DP->DVI/HDMI dongles show up to the system as HDMI devices, as they
do not have a sink device in them to respond to any AUX traffic. When
probing these dongles over the DDC, sometimes they will NAK the first attempt
even though the transaction is valid and they support the DDC protocol. The
retry loop inside of drm_do_probe_ddc_edid() would normally catch this case
and try the transaction again, resulting in success.

That, however, was thwarted by the fix for fdo.org bug #41059. The patch is:
commit 9292f37e1f5c79400254dca46f83313488093825
Author: Eugeni Dodonov 
Date:   Thu Jan 5 09:34:28 2012 -0200

drm: give up on edid retries when i2c bus is not responding

Some extra background:

That commit refers to the i2c bit banging code, while i915 now prefers
gmbus, and only falls back to big banging on certain failures. (See
gmbux_xfer() in i915/intel_i2c.c). This means that in most cases i915 is
no longer susceptible to the 5*3 timeout loops, but it also means we
don't have the i2c bit banging retry at all on -ENXIO, like Todd notes.

The questions are, is one retry after -ENXIO in drm_do_probe_ddc_edid
enough now? Should we revert the original commit instead since the
underlying algorithm has changed? Or should we return something other
than -ENXIO from our gmbus code to not hit this exit with no retries
path?

Question #1:
During development and testing, all of the passive dongles used would 
NAK once before operating correctly. I had an additional dongle here 
that I tested as well and it exhibited the exact same behavior. While I 
believe that more testing certainly needs to be done (as you mention 
below) at this point I would say allowing a single NAK is sufficient to 
solve this problem.


Question #2:
While I agree to some extent that this patch is dated with respect to 
the underlying algorithm changes, there still appears to be some value 
in keeping it since it does allow for more efficient processing of 
disconnected ports. So I would recommend against reverting this commit 
right now.


Question #3:
I'm looking into this now. I'll have more information by the end of the day.


This added code to exit immediately if the return code from the
i2c_transfer function was -ENXIO in order to reduce the amount of time spent
in waiting for unresponsive or disconnected devices. For the DP dongles,
this means that the second retry never happens which results in a failed
EDID probe and a black screen.

To work around this problem without undoing the fix for bug #41059, the
number of retries is checked along with the return code. This allows for a
device to NAK once and still continue operations. A second NAK will result
in breaking the loop as it would have before and stopping the DDC probe.

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

Maybe throw this at other dongle bugs you can find too?

We're going to need Tested-bys though.

BR,
Jani.
Definitely - I'll go wrangle up the dongle bugs I can find on kernel.org 
and FDO and see if this affects them.


As for testing, the more the merrier on this front. If anyone has 
passive DP->DVI/HDMI dongles and the ability to test them, please see 
the bug Jani referenced above and report your findings there.



-T



Signed-off-by: Todd Previte 
Cc: intel-gfx@lists.freedesktop.org
---
  drivers/gpu/drm/drm_edid.c | 5 -
  1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 7087da3..e8047bd 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -1238,7 +1238,10 @@ drm_do_probe_ddc_edid(void *data, u8 *buf, unsigned int 
block, size_t len)
 */
ret = i2c_transfer(adapter, &msgs[3 - xfers], xfers);
  
-		if (ret == -ENXIO) {

+   /* Passive DP->DVI/HDMI dongles sometimes NAK the first probe
+* Try to probe again but if it NAKs, stop trying
+*/
+   if (ret == -ENXIO && retries < 5) {
DRM_DEBUG_KMS("drm: skipping non-existent adapter %s\n",
adapter->name);
break;
--
1.9.1

___
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


Re: [Intel-gfx] [PATCH 33/70] drm/i915: Use a separate slab for requests

2015-05-22 Thread Robert Beckett

On 07/04/2015 16:20, Chris Wilson wrote:

requests are even more frequently allocated than objects and equally
benefit from having a dedicated slab.

v2: Rebase

Signed-off-by: Chris Wilson 
---
  drivers/gpu/drm/i915/i915_dma.c | 12 ++
  drivers/gpu/drm/i915/i915_drv.h |  4 +++-
  drivers/gpu/drm/i915/i915_gem.c | 41 +++--
  drivers/gpu/drm/i915/intel_ringbuffer.c |  1 -
  4 files changed, 35 insertions(+), 23 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index 7b0109e2ab23..135fbcad367f 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -1010,8 +1010,10 @@ out_regs:
  put_bridge:
pci_dev_put(dev_priv->bridge_dev);
  free_priv:
-   if (dev_priv->slab)
-   kmem_cache_destroy(dev_priv->slab);
+   if (dev_priv->requests)
+   kmem_cache_destroy(dev_priv->requests);
+   if (dev_priv->objects)
+   kmem_cache_destroy(dev_priv->objects);
kfree(dev_priv);
return ret;
  }
@@ -1094,8 +1096,10 @@ int i915_driver_unload(struct drm_device *dev)
if (dev_priv->regs != NULL)
pci_iounmap(dev->pdev, dev_priv->regs);

-   if (dev_priv->slab)
-   kmem_cache_destroy(dev_priv->slab);
+   if (dev_priv->requests)
+   kmem_cache_destroy(dev_priv->requests);
+   if (dev_priv->objects)
+   kmem_cache_destroy(dev_priv->objects);

pci_dev_put(dev_priv->bridge_dev);
kfree(dev_priv);
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 600b6d4a0139..ad08aa532456 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1578,7 +1578,8 @@ struct i915_virtual_gpu {

  struct drm_i915_private {
struct drm_device *dev;
-   struct kmem_cache *slab;
+   struct kmem_cache *objects;
+   struct kmem_cache *requests;

const struct intel_device_info info;

@@ -2070,6 +2071,7 @@ struct drm_i915_gem_request {
struct kref ref;

/** On Which ring this request was generated */
+   struct drm_i915_private *i915;
struct intel_engine_cs *ring;

/** GEM sequence number associated with this request. */
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 1f07cd17be04..a4a62592f0f8 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -381,13 +381,13 @@ out:
  void *i915_gem_object_alloc(struct drm_device *dev)
  {
struct drm_i915_private *dev_priv = dev->dev_private;
-   return kmem_cache_zalloc(dev_priv->slab, GFP_KERNEL);
+   return kmem_cache_zalloc(dev_priv->objects, GFP_KERNEL);
  }

  void i915_gem_object_free(struct drm_i915_gem_object *obj)
  {
struct drm_i915_private *dev_priv = obj->base.dev->dev_private;
-   kmem_cache_free(dev_priv->slab, obj);
+   kmem_cache_free(dev_priv->objects, obj);
  }

  static int
@@ -2633,43 +2633,45 @@ void i915_gem_request_free(struct kref *req_ref)
i915_gem_context_unreference(ctx);
}

-   kfree(req);
+   kmem_cache_free(req->i915->requests, req);
  }

  int i915_gem_request_alloc(struct intel_engine_cs *ring,
   struct intel_context *ctx)
  {
+   struct drm_i915_private *dev_priv = to_i915(ring->dev);
+   struct drm_i915_gem_request *rq;
int ret;
-   struct drm_i915_gem_request *request;
-   struct drm_i915_private *dev_private = ring->dev->dev_private;

if (ring->outstanding_lazy_request)
return 0;

-   request = kzalloc(sizeof(*request), GFP_KERNEL);
-   if (request == NULL)
+   rq = kmem_cache_zalloc(dev_priv->requests, GFP_KERNEL);
+   if (rq == NULL)
return -ENOMEM;

-   ret = i915_gem_get_seqno(ring->dev, &request->seqno);
+   kref_init(&rq->ref);
+   rq->i915 = dev_priv;
+
+   ret = i915_gem_get_seqno(ring->dev, &rq->seqno);
if (ret) {
-   kfree(request);
+   kfree(rq);
return ret;
}

-   kref_init(&request->ref);
-   request->ring = ring;
-   request->uniq = dev_private->request_uniq++;
+   rq->ring = ring;
+   rq->uniq = dev_priv->request_uniq++;

if (i915.enable_execlists)
-   ret = intel_logical_ring_alloc_request_extras(request, ctx);
+   ret = intel_logical_ring_alloc_request_extras(rq, ctx);
else
-   ret = intel_ring_alloc_request_extras(request);
+   ret = intel_ring_alloc_request_extras(rq);
if (ret) {
-   kfree(request);
+   kfree(rq);
return ret;
}

-   ring->outstanding_lazy_request = request;
+   ring->outstanding_lazy_request = rq;
return 0;
  }

@@ -5204,11 +5206,16 @@ i915_gem_load(struct drm_device *dev)
struct dr

Re: [Intel-gfx] [PATCH] drm/i915: Document IPS restriction with 1 plane on the pipe.

2015-05-22 Thread shuang . he
Tested-By: Intel Graphics QA PRTS (Patch Regression Test System Contact: 
shuang...@intel.com)
Task id: 6455
-Summary-
Platform  Delta  drm-intel-nightly  Series Applied
PNV  234/234  234/234
ILK  262/262  262/262
SNB -1  282/282  281/282
IVB  300/300  300/300
BYT  254/254  254/254
BDW  275/275  275/275
-Detailed-
Platform  Testdrm-intel-nightly  Series 
Applied
 SNB  igt@pm_rpm@dpms-mode-unset-non-lpsp  DMESG_WARN(18)PASS(1)  
DMESG_WARN(1)
(dmesg patch 
applied)WARNING:at_drivers/gpu/drm/i915/intel_uncore.c:#assert_device_not_suspended[i915]()@WARNING:.*
 at .* assert_device_not_suspended+0x
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


[Intel-gfx] [PATCH i-g-t] kms_rotation_crc: Update rotation direction for kernel changes

2015-05-22 Thread Tvrtko Ursulin
From: Tvrtko Ursulin 

commit 1e8df16778b0d8fd8102b3ee799b028f8f961089
Author: Sonika Jindal 
Date:   Wed May 20 13:40:48 2015 +0530

drm/i915/skl: Swapping 90 and 270 to be compliant with Xrand

Changed the rotation direction so IGT needs to be told.

Signed-off-by: Tvrtko Ursulin 
Cc: Ville Syrjälä 
Cc: Sonika Jindal 
---
 tests/kms_rotation_crc.c | 16 +++-
 1 file changed, 7 insertions(+), 9 deletions(-)

diff --git a/tests/kms_rotation_crc.c b/tests/kms_rotation_crc.c
index e16056d..3fd77c4 100644
--- a/tests/kms_rotation_crc.c
+++ b/tests/kms_rotation_crc.c
@@ -61,21 +61,19 @@ paint_squares(data_t *data, drmModeModeInfo *mode, 
igt_rotation_t rotation,
}
 
if (rotation == IGT_ROTATION_90) {
-   /* Paint 4 squares with width == height in Blue, Red,
-   Green, White Clockwise order to look like 90 degree rotated*/
-   igt_paint_color(cr, 0, 0, w / 2, h / 2, 0.0, 0.0, 1.0);
-   igt_paint_color(cr, w / 2, 0, w / 2, h / 2, 1.0, 0.0, 0.0);
-   igt_paint_color(cr, 0, h / 2, w / 2, h / 2, 1.0, 1.0, 1.0);
-   igt_paint_color(cr, w / 2, h / 2, w / 2, h / 2, 0.0, 1.0, 0.0);
-
-   } else if (rotation == IGT_ROTATION_270) {
/* Paint 4 squares with width == height in Green, White,
Blue, Red Clockwise order to look like 270 degree rotated*/
igt_paint_color(cr, 0, 0, w / 2, h / 2, 0.0, 1.0, 0.0);
igt_paint_color(cr, w / 2, 0, w / 2, h / 2, 1.0, 1.0, 1.0);
igt_paint_color(cr, 0, h / 2, w / 2, h / 2, 1.0, 0.0, 0.0);
igt_paint_color(cr, w / 2, h / 2, w / 2, h / 2, 0.0, 0.0, 1.0);
-
+   } else if (rotation == IGT_ROTATION_270) {
+   /* Paint 4 squares with width == height in Blue, Red,
+   Green, White Clockwise order to look like 90 degree rotated*/
+   igt_paint_color(cr, 0, 0, w / 2, h / 2, 0.0, 0.0, 1.0);
+   igt_paint_color(cr, w / 2, 0, w / 2, h / 2, 1.0, 0.0, 0.0);
+   igt_paint_color(cr, 0, h / 2, w / 2, h / 2, 1.0, 1.0, 1.0);
+   igt_paint_color(cr, w / 2, h / 2, w / 2, h / 2, 0.0, 1.0, 0.0);
} else {
/* Paint with 4 squares of Red, Green, White, Blue Clockwise */
igt_paint_color(cr, 0, 0, w / 2, h / 2, 1.0, 0.0, 0.0);
-- 
2.4.0

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


Re: [Intel-gfx] [PATCH v4 00/12] All sort of cdclk stuff

2015-05-22 Thread Jani Nikula
On Fri, 22 May 2015, Jani Nikula  wrote:
> On Fri, 22 May 2015, Mika Kahola  wrote:
>> This patch series rebases Ville's original cdclk patch series
>> excluding the ones that  are already reviewed.
>>
>> http://lists.freedesktop.org/archives/intel-gfx/2014-November/055633.html
>>
>> The patches are rebased to the latest drm-intel-nightly and while I was
>> doing it I tagged the reviewed-by. Maybe Daniel/Jani can comment if this
>> is procedure is ok or not. There is one exception to this and that
>> is the patch 'HSW cdclk support' which I had to modify to support the
>> recent atomic changes. This patch requires a review.
>
> Since you're sending the patches, you do need to add your Signed-off-by:
> line after Ville's, and IMO you don't need to add your Reviewed-by: if
> you have your s-o-b there (but if there's review from someone else that
> still applies, you should add that).
>
> Also, you don't need to add any Author: tags; if you have git configured
> properly, and it seems that you do, git will automatically add a From:
> line at the beginning, and when we apply the patches, that gets used for
> authorship.
>
> To recap, you'd end up with this, From: line gets added by git in
> format-patch/send-email if you're not the author:
>
> ---
>
> From: Ville Syrjälä 
>
> Commit message, bla bla blah.
>
> v2: version history goes here for us.

Oh, and I tend to add e.g. "v2 by Jani" if I'm picking up someone else's
work. And for patches that I basically rewrite, I'll take the authorship
to myself, and, depending on the case, add e.g. "Based on a patch by
J. Random Hacker ".

It is a bit of a pity that you can only have one author even when shared
credit would be fair.


J.

>
> Signed-off-by: Ville Syrjälä 
> Signed-off-by: Mika Kahola 
>
> ---
>
> BR,
> Jani.
>
>>
>> Ville Syrjälä (12):
>>   drm/i915: Fix i855 get_display_clock_speed
>>   drm/i915: Fix 852GM/GMV cdclk
>>   drm/i915: Add cdclk extraction for g33, g965gm and g4x
>>   drm/i915: Warn when cdclk for the platforms is not known
>>   drm/i915: Cache current cdclk frequency in dev_priv
>>   drm/i915: Use cached cdclk value
>>   drm/i915: Unify ilk and hsw .get_aux_clock_divider
>>   drm/i915: Store max cdclk value in dev_priv
>>   drm/i915: Don't enable IPS when pixel rate exceeds 95%
>>   drm/i915: HSW cdclk support
>>   drm/i915: Add IS_BDW_ULX
>>   drm/i915: BDW clock change support
>>
>>  drivers/gpu/drm/i915/i915_drv.h  |   5 +-
>>  drivers/gpu/drm/i915/i915_reg.h  |  18 +-
>>  drivers/gpu/drm/i915/intel_display.c | 546 
>> +--
>>  drivers/gpu/drm/i915/intel_dp.c  |  24 +-
>>  drivers/gpu/drm/i915/intel_drv.h |   2 +-
>>  drivers/gpu/drm/i915/intel_pm.c  |  19 +-
>>  6 files changed, 560 insertions(+), 54 deletions(-)
>>
>> -- 
>> 1.9.1
>>
>> ___
>> Intel-gfx mailing list
>> Intel-gfx@lists.freedesktop.org
>> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
>
> -- 
> 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 v4 00/12] All sort of cdclk stuff

2015-05-22 Thread Jani Nikula
On Fri, 22 May 2015, Mika Kahola  wrote:
> This patch series rebases Ville's original cdclk patch series
> excluding the ones that   are already reviewed.
>
> http://lists.freedesktop.org/archives/intel-gfx/2014-November/055633.html
>
> The patches are rebased to the latest drm-intel-nightly and while I was
> doing it I tagged the reviewed-by. Maybe Daniel/Jani can comment if this
> is procedure is ok or not. There is one exception to this and that
> is the patch 'HSW cdclk support' which I had to modify to support the
> recent atomic changes. This patch requires a review.

Since you're sending the patches, you do need to add your Signed-off-by:
line after Ville's, and IMO you don't need to add your Reviewed-by: if
you have your s-o-b there (but if there's review from someone else that
still applies, you should add that).

Also, you don't need to add any Author: tags; if you have git configured
properly, and it seems that you do, git will automatically add a From:
line at the beginning, and when we apply the patches, that gets used for
authorship.

To recap, you'd end up with this, From: line gets added by git in
format-patch/send-email if you're not the author:

---

From: Ville Syrjälä 

Commit message, bla bla blah.

v2: version history goes here for us.

Signed-off-by: Ville Syrjälä 
Signed-off-by: Mika Kahola 

---

BR,
Jani.

>
> Ville Syrjälä (12):
>   drm/i915: Fix i855 get_display_clock_speed
>   drm/i915: Fix 852GM/GMV cdclk
>   drm/i915: Add cdclk extraction for g33, g965gm and g4x
>   drm/i915: Warn when cdclk for the platforms is not known
>   drm/i915: Cache current cdclk frequency in dev_priv
>   drm/i915: Use cached cdclk value
>   drm/i915: Unify ilk and hsw .get_aux_clock_divider
>   drm/i915: Store max cdclk value in dev_priv
>   drm/i915: Don't enable IPS when pixel rate exceeds 95%
>   drm/i915: HSW cdclk support
>   drm/i915: Add IS_BDW_ULX
>   drm/i915: BDW clock change support
>
>  drivers/gpu/drm/i915/i915_drv.h  |   5 +-
>  drivers/gpu/drm/i915/i915_reg.h  |  18 +-
>  drivers/gpu/drm/i915/intel_display.c | 546 
> +--
>  drivers/gpu/drm/i915/intel_dp.c  |  24 +-
>  drivers/gpu/drm/i915/intel_drv.h |   2 +-
>  drivers/gpu/drm/i915/intel_pm.c  |  19 +-
>  6 files changed, 560 insertions(+), 54 deletions(-)
>
> -- 
> 1.9.1
>
> ___
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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


[Intel-gfx] [PATCH v4 11/12] drm/i915: Add IS_BDW_ULX

2015-05-22 Thread Mika Kahola
From: Ville Syrjälä 

We need to tell BDW ULT and ULX apart.

Signed-off-by: Ville Syrjälä 

v2: Rebased to the latest
v3: Rebased to the latest

Reviewed-by: Mika Kahola 

Author:Ville Syrjälä 
---
 drivers/gpu/drm/i915/i915_drv.h | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 37e8e9d..c85d802 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2362,6 +2362,9 @@ struct drm_i915_cmd_table {
 ((INTEL_DEVID(dev) & 0xf) == 0x6 ||\
 (INTEL_DEVID(dev) & 0xf) == 0xb || \
 (INTEL_DEVID(dev) & 0xf) == 0xe))
+/* ULX machines are also considered ULT. */
+#define IS_BDW_ULX(dev)(IS_BROADWELL(dev) && \
+(INTEL_DEVID(dev) & 0xf) == 0xe)
 #define IS_BDW_GT3(dev)(IS_BROADWELL(dev) && \
 (INTEL_DEVID(dev) & 0x00F0) == 0x0020)
 #define IS_HSW_ULT(dev)(IS_HASWELL(dev) && \
-- 
1.9.1

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


[Intel-gfx] [PATCH v4 07/12] drm/i915: Unify ilk and hsw .get_aux_clock_divider

2015-05-22 Thread Mika Kahola
From: Ville Syrjälä 

ilk_get_aux_clock_divider() is now a subset of
hsw_get_aux_clock_divider() so unify them.

Signed-off-by: Ville Syrjälä 

v2: Rebased to the latest
v3: Rebased to the latest

Reviewed-by: Mika Kahola 

Author:Ville Syrjälä 
---
 drivers/gpu/drm/i915/intel_dp.c | 23 +++
 1 file changed, 3 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 2dd4d28..8d9c928 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -704,23 +704,6 @@ static uint32_t ilk_get_aux_clock_divider(struct intel_dp 
*intel_dp, int index)
struct drm_device *dev = intel_dig_port->base.base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
 
-   if (index)
-   return 0;
-
-   if (intel_dig_port->port == PORT_A) {
-   return DIV_ROUND_UP(dev_priv->cdclk_freq, 2000);
-
-   } else {
-   return DIV_ROUND_UP(intel_pch_rawclk(dev), 2);
-   }
-}
-
-static uint32_t hsw_get_aux_clock_divider(struct intel_dp *intel_dp, int index)
-{
-   struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
-   struct drm_device *dev = intel_dig_port->base.base.dev;
-   struct drm_i915_private *dev_priv = dev->dev_private;
-
if (intel_dig_port->port == PORT_A) {
if (index)
return 0;
@@ -733,7 +716,9 @@ static uint32_t hsw_get_aux_clock_divider(struct intel_dp 
*intel_dp, int index)
default: return 0;
}
} else  {
-   return index ? 0 : DIV_ROUND_UP(intel_pch_rawclk(dev), 2);
+   if (index)
+   return 0;
+   return DIV_ROUND_UP(intel_pch_rawclk(dev), 2);
}
 }
 
@@ -5731,8 +5716,6 @@ intel_dp_init_connector(struct intel_digital_port 
*intel_dig_port,
intel_dp->get_aux_clock_divider = skl_get_aux_clock_divider;
else if (IS_VALLEYVIEW(dev))
intel_dp->get_aux_clock_divider = vlv_get_aux_clock_divider;
-   else if (IS_HASWELL(dev) || IS_BROADWELL(dev))
-   intel_dp->get_aux_clock_divider = hsw_get_aux_clock_divider;
else if (HAS_PCH_SPLIT(dev))
intel_dp->get_aux_clock_divider = ilk_get_aux_clock_divider;
else
-- 
1.9.1

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


[Intel-gfx] [PATCH v4 00/12] All sort of cdclk stuff

2015-05-22 Thread Mika Kahola
This patch series rebases Ville's original cdclk patch series
excluding the ones that are already reviewed.

http://lists.freedesktop.org/archives/intel-gfx/2014-November/055633.html

The patches are rebased to the latest drm-intel-nightly and while I was
doing it I tagged the reviewed-by. Maybe Daniel/Jani can comment if this
is procedure is ok or not. There is one exception to this and that
is the patch 'HSW cdclk support' which I had to modify to support the
recent atomic changes. This patch requires a review. 

Ville Syrjälä (12):
  drm/i915: Fix i855 get_display_clock_speed
  drm/i915: Fix 852GM/GMV cdclk
  drm/i915: Add cdclk extraction for g33, g965gm and g4x
  drm/i915: Warn when cdclk for the platforms is not known
  drm/i915: Cache current cdclk frequency in dev_priv
  drm/i915: Use cached cdclk value
  drm/i915: Unify ilk and hsw .get_aux_clock_divider
  drm/i915: Store max cdclk value in dev_priv
  drm/i915: Don't enable IPS when pixel rate exceeds 95%
  drm/i915: HSW cdclk support
  drm/i915: Add IS_BDW_ULX
  drm/i915: BDW clock change support

 drivers/gpu/drm/i915/i915_drv.h  |   5 +-
 drivers/gpu/drm/i915/i915_reg.h  |  18 +-
 drivers/gpu/drm/i915/intel_display.c | 546 +--
 drivers/gpu/drm/i915/intel_dp.c  |  24 +-
 drivers/gpu/drm/i915/intel_drv.h |   2 +-
 drivers/gpu/drm/i915/intel_pm.c  |  19 +-
 6 files changed, 560 insertions(+), 54 deletions(-)

-- 
1.9.1

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


[Intel-gfx] [PATCH v4 02/12] drm/i915: Fix 852GM/GMV cdclk

2015-05-22 Thread Mika Kahola
From: Ville Syrjälä 

It seems 852GM/GMV uses a different HPLLCC encoding than the other
85x platforms. For 852GM/GMV cdclk is always 133MHz. Try to detect that
using the PCI revision (sinc the device ID seems useless for that). I'm
not at all sure this is a good idea, but according to the specs it
should work.

Signed-off-by: Ville Syrjälä 

v2: Rebased to the latest
v3: Rebased to the latest

Reviewed-by: Mika Kahola 

Author:Ville Syrjälä 
---
 drivers/gpu/drm/i915/intel_display.c | 8 
 1 file changed, 8 insertions(+)

diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index 64debfb..4b17aad 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -6631,6 +6631,14 @@ static int i85x_get_display_clock_speed(struct 
drm_device *dev)
 {
u16 hpllcc = 0;
 
+   /*
+* 852GM/852GMV only supports 133 MHz and the HPLLCC
+* encoding is different :(
+* FIXME is this the right way to detect 852GM/852GMV?
+*/
+   if (dev->pdev->revision == 0x1)
+   return 13;
+
pci_bus_read_config_word(dev->pdev->bus,
 PCI_DEVFN(0, 3), HPLLCC, &hpllcc);
 
-- 
1.9.1

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


[Intel-gfx] [PATCH v4 04/12] drm/i915: Warn when cdclk for the platforms is not known

2015-05-22 Thread Mika Kahola
From: Ville Syrjälä 

Print a warning if we fall through the .get_display_clock_speed() function
pointer setup. We end up assuming a 133MHz cdclk which should mean that
at least we avoid any 0 deivisions and whatnot. But this could at least
help remind people that they have to provide this function for new platforms.

Signed-off-by: Ville Syrjälä 

v2: Rebased to the latest
v3: Rebased to the latest

Reviewed-by: Mika Kahola 

Author:Ville Syrjälä 
---
 drivers/gpu/drm/i915/intel_display.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index 86c9140..de65737 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -14398,9 +14398,11 @@ static void intel_init_display(struct drm_device *dev)
else if (IS_I85X(dev))
dev_priv->display.get_display_clock_speed =
i85x_get_display_clock_speed;
-   else /* 830 */
+   else { /* 830 */
+   WARN(!IS_I830(dev), "Unknown platform. Assuming 133 MHz 
CDCLK\n");
dev_priv->display.get_display_clock_speed =
i830_get_display_clock_speed;
+   }
 
if (IS_GEN5(dev)) {
dev_priv->display.fdi_link_train = ironlake_fdi_link_train;
-- 
1.9.1

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


[Intel-gfx] [PATCH v4 06/12] drm/i915: Use cached cdclk value

2015-05-22 Thread Mika Kahola
From: Ville Syrjälä 

Rather than reading out the current cdclk value use the cached value we
have tucked away in dev_priv.

Signed-off-by: Ville Syrjälä 

v2: Rebased to the latest
v3: Rebased to the latest

Reviewed-by: Mika Kahola 

Author:Ville Syrjälä 
---
 drivers/gpu/drm/i915/intel_display.c | 3 +--
 drivers/gpu/drm/i915/intel_dp.c  | 5 +++--
 drivers/gpu/drm/i915/intel_pm.c  | 2 +-
 3 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index 75b11d6..fcd4112 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -6406,8 +6406,7 @@ static int intel_crtc_compute_config(struct intel_crtc 
*crtc,
 
/* FIXME should check pixel clock limits on all platforms */
if (INTEL_INFO(dev)->gen < 4) {
-   int clock_limit =
-   dev_priv->display.get_display_clock_speed(dev);
+   int clock_limit = dev_priv->cdclk_freq;
 
/*
 * Enable pixel doubling when the dot clock
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 0edc305..2dd4d28 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -708,7 +708,8 @@ static uint32_t ilk_get_aux_clock_divider(struct intel_dp 
*intel_dp, int index)
return 0;
 
if (intel_dig_port->port == PORT_A) {
-   return 
DIV_ROUND_UP(dev_priv->display.get_display_clock_speed(dev), 2000);
+   return DIV_ROUND_UP(dev_priv->cdclk_freq, 2000);
+
} else {
return DIV_ROUND_UP(intel_pch_rawclk(dev), 2);
}
@@ -723,7 +724,7 @@ static uint32_t hsw_get_aux_clock_divider(struct intel_dp 
*intel_dp, int index)
if (intel_dig_port->port == PORT_A) {
if (index)
return 0;
-   return 
DIV_ROUND_CLOSEST(dev_priv->display.get_display_clock_speed(dev), 2000);
+   return DIV_ROUND_CLOSEST(dev_priv->cdclk_freq, 2000);
} else if (dev_priv->pch_id == INTEL_PCH_LPT_DEVICE_ID_TYPE) {
/* Workaround for non-ULT HSW */
switch (index) {
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index ce1d079..0046cb4 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -1815,7 +1815,7 @@ hsw_compute_linetime_wm(struct drm_device *dev, struct 
drm_crtc *crtc)
linetime = DIV_ROUND_CLOSEST(mode->crtc_htotal * 1000 * 8,
 mode->crtc_clock);
ips_linetime = DIV_ROUND_CLOSEST(mode->crtc_htotal * 1000 * 8,
-
dev_priv->display.get_display_clock_speed(dev_priv->dev));
+dev_priv->cdclk_freq);
 
return PIPE_WM_LINETIME_IPS_LINETIME(ips_linetime) |
   PIPE_WM_LINETIME_TIME(linetime);
-- 
1.9.1

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


[Intel-gfx] [PATCH v4 03/12] drm/i915: Add cdclk extraction for g33, g965gm and g4x

2015-05-22 Thread Mika Kahola
From: Ville Syrjälä 

Implement cdclk extraction for g33, 965gm and g4x platforms. The details
came from configdb. Sadly there isn't anything there for other gen3/gen4
chipsets.

So far I've tested this on one ELK where it gave me a HPLL VCO of 5333
MHz and cdclk of 444 MHz which seems perfectly sane for this machine.

Signed-off-by: Ville Syrjälä 

v2: Rebased to the latest
v3: Rebased to the latest

Reviewed-by: Mika Kahola 

Author:Ville Syrjälä 
---
 drivers/gpu/drm/i915/i915_reg.h  |   3 +
 drivers/gpu/drm/i915/intel_display.c | 183 ++-
 2 files changed, 185 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 6625fb3..14366c8 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -2491,6 +2491,9 @@ enum skl_disp_power_wells {
 #define CLKCFG_MEM_800 (3 << 4)
 #define CLKCFG_MEM_MASK(7 << 4)
 
+#define HPLLVCO (MCHBAR_MIRROR_BASE + 0xc38)
+#define HPLLVCO_MOBILE  (MCHBAR_MIRROR_BASE + 0xc0f)
+
 #define TSC1   0x11001
 #define   TSE  (1<<0)
 #define TR10x11006
diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index 4b17aad..86c9140 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -6669,6 +6669,175 @@ static int i830_get_display_clock_speed(struct 
drm_device *dev)
return 13;
 }
 
+static unsigned int intel_hpll_vco(struct drm_device *dev)
+{
+   struct drm_i915_private *dev_priv = dev->dev_private;
+   static const unsigned int blb_vco[8] = {
+   [0] = 320,
+   [1] = 400,
+   [2] = 533,
+   [3] = 480,
+   [4] = 640,
+   };
+   static const unsigned int pnv_vco[8] = {
+   [0] = 320,
+   [1] = 400,
+   [2] = 533,
+   [3] = 480,
+   [4] = 267,
+   };
+   static const unsigned int cl_vco[8] = {
+   [0] = 320,
+   [1] = 400,
+   [2] = 533,
+   [3] = 640,
+   [4] = 333,
+   [5] = 357,
+   [6] = 427,
+   };
+   static const unsigned int elk_vco[8] = {
+   [0] = 320,
+   [1] = 400,
+   [2] = 533,
+   [3] = 480,
+   };
+   static const unsigned int ctg_vco[8] = {
+   [0] = 320,
+   [1] = 400,
+   [2] = 533,
+   [3] = 640,
+   [4] = 267,
+   [5] = 427,
+   };
+   const unsigned int *vco_table;
+   unsigned int vco;
+   uint8_t tmp = 0;
+
+   /* FIXME other chipsets? */
+   if (IS_GM45(dev))
+   vco_table = ctg_vco;
+   else if (IS_G4X(dev))
+   vco_table = elk_vco;
+   else if (IS_CRESTLINE(dev))
+   vco_table = cl_vco;
+   else if (IS_PINEVIEW(dev))
+   vco_table = pnv_vco;
+   else if (IS_G33(dev))
+   vco_table = blb_vco;
+   else
+   return 0;
+
+   tmp = I915_READ(IS_MOBILE(dev) ? HPLLVCO_MOBILE : HPLLVCO);
+
+   vco = vco_table[tmp & 0x7];
+   if (vco == 0)
+   DRM_ERROR("Bad HPLL VCO (HPLLVCO=0x%02x)\n", tmp);
+   else
+   DRM_DEBUG_KMS("HPLL VCO %u kHz\n", vco);
+
+   return vco;
+}
+
+static int gm45_get_display_clock_speed(struct drm_device *dev)
+{
+   unsigned int cdclk_sel, vco = intel_hpll_vco(dev);
+   uint16_t tmp = 0;
+
+   pci_read_config_word(dev->pdev, GCFGC, &tmp);
+
+   cdclk_sel = (tmp >> 12) & 0x1;
+
+   switch (vco) {
+   case 267:
+   case 400:
+   case 533:
+   return cdclk_sel ? 33 : 22;
+   case 320:
+   return cdclk_sel ? 32 : 228571;
+   default:
+   DRM_ERROR("Unable to determine CDCLK. HPLL VCO=%u, 
CFGC=0x%04x\n", vco, tmp);
+   return 22;
+   }
+}
+
+static int i965gm_get_display_clock_speed(struct drm_device *dev)
+{
+   static const uint8_t div_3200[] = { 16, 10,  8 };
+   static const uint8_t div_4000[] = { 20, 12, 10 };
+   static const uint8_t div_5333[] = { 24, 16, 14 };
+   const uint8_t *div_table;
+   unsigned int cdclk_sel, vco = intel_hpll_vco(dev);
+   uint16_t tmp = 0;
+
+   pci_read_config_word(dev->pdev, GCFGC, &tmp);
+
+   cdclk_sel = ((tmp >> 8) & 0x1f) - 1;
+
+   if (cdclk_sel >= ARRAY_SIZE(div_3200))
+   goto fail;
+
+   switch (vco) {
+   case 320:
+   div_table = div_3200;
+   break;
+   case 400:
+   div_table = div_4000;
+   br

[Intel-gfx] [PATCH v4 01/12] drm/i915: Fix i855 get_display_clock_speed

2015-05-22 Thread Mika Kahola
From: Ville Syrjälä 

Actually read the HPLLCC register insted of assuming it's 0. Fix the
HPLLCC bit definitions and all the missing ones from the 852GME spec.

852GME, 854 and 855 all seem to match the same HPLLC encoding even
though only some of the values are valid is some of the platforms.

Signed-off-by: Ville Syrjälä 

v2: Rebased to the latest
v3: Rebased to the latest

Reviewed-by: Mika Kahola 

Author:Ville Syrjälä 
---
 drivers/gpu/drm/i915/i915_reg.h  | 11 ---
 drivers/gpu/drm/i915/intel_display.c | 15 ---
 2 files changed, 20 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 84af255..6625fb3 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -50,12 +50,17 @@
 
 /* PCI config space */
 
-#define HPLLCC 0xc0 /* 855 only */
-#define   GC_CLOCK_CONTROL_MASK(0xf << 0)
+#define HPLLCC 0xc0 /* 85x only */
+#define   GC_CLOCK_CONTROL_MASK(0x7 << 0)
 #define   GC_CLOCK_133_200 (0 << 0)
 #define   GC_CLOCK_100_200 (1 << 0)
 #define   GC_CLOCK_100_133 (2 << 0)
-#define   GC_CLOCK_166_250 (3 << 0)
+#define   GC_CLOCK_133_266 (3 << 0)
+#define   GC_CLOCK_133_200_2   (4 << 0)
+#define   GC_CLOCK_133_266_2   (5 << 0)
+#define   GC_CLOCK_166_266 (6 << 0)
+#define   GC_CLOCK_166_250 (7 << 0)
+
 #define GCFGC2 0xda
 #define GCFGC  0xf0 /* 915+ only */
 #define   GC_LOW_FREQUENCY_ENABLE  (1 << 7)
diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index c97b496..64debfb 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -6627,20 +6627,29 @@ static int i865_get_display_clock_speed(struct 
drm_device *dev)
return 27;
 }
 
-static int i855_get_display_clock_speed(struct drm_device *dev)
+static int i85x_get_display_clock_speed(struct drm_device *dev)
 {
u16 hpllcc = 0;
+
+   pci_bus_read_config_word(dev->pdev->bus,
+PCI_DEVFN(0, 3), HPLLCC, &hpllcc);
+
/* Assume that the hardware is in the high speed state.  This
 * should be the default.
 */
switch (hpllcc & GC_CLOCK_CONTROL_MASK) {
case GC_CLOCK_133_200:
+   case GC_CLOCK_133_200_2:
case GC_CLOCK_100_200:
return 20;
case GC_CLOCK_166_250:
return 25;
case GC_CLOCK_100_133:
return 13;
+   case GC_CLOCK_133_266:
+   case GC_CLOCK_133_266_2:
+   case GC_CLOCK_166_266:
+   return 27;
}
 
/* Shouldn't happen */
@@ -14199,8 +14208,8 @@ static void intel_init_display(struct drm_device *dev)
i865_get_display_clock_speed;
else if (IS_I85X(dev))
dev_priv->display.get_display_clock_speed =
-   i855_get_display_clock_speed;
-   else /* 852, 830 */
+   i85x_get_display_clock_speed;
+   else /* 830 */
dev_priv->display.get_display_clock_speed =
i830_get_display_clock_speed;
 
-- 
1.9.1

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


[Intel-gfx] [PATCH v4 05/12] drm/i915: Cache current cdclk frequency in dev_priv

2015-05-22 Thread Mika Kahola
From: Ville Syrjälä 

Rather that extracting the current cdclk freuqncy every time someone
wants to know it, cache the current value and use that. VLV/CHV already
stored a cached value there so just expand that to cover all platforms.

Signed-off-by: Ville Syrjälä 

v2: Rebased to the latest
v3: Rebased to the latest

Reviewed-by: Mika Kahola 

Author:Ville Syrjälä 
---
 drivers/gpu/drm/i915/intel_display.c | 25 ++---
 1 file changed, 18 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index de65737..75b11d6 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -5541,7 +5541,7 @@ static int valleyview_get_vco(struct drm_i915_private 
*dev_priv)
return vco_freq[hpll_freq] * 1000;
 }
 
-static void vlv_update_cdclk(struct drm_device *dev)
+static void intel_update_cdclk(struct drm_device *dev)
 {
struct drm_i915_private *dev_priv = dev->dev_private;
 
@@ -5554,7 +5554,14 @@ static void vlv_update_cdclk(struct drm_device *dev)
 * BSpec erroneously claims we should aim for 4MHz, but
 * in fact 1MHz is the correct frequency.
 */
-   I915_WRITE(GMBUSFREQ_VLV, DIV_ROUND_UP(dev_priv->cdclk_freq, 1000));
+   if (IS_VALLEYVIEW(dev)) {
+   /*
+* Program the gmbus_freq based on the cdclk frequency.
+* BSpec erroneously claims we should aim for 4MHz, but
+* in fact 1MHz is the correct frequency.
+*/
+   I915_WRITE(GMBUSFREQ_VLV, DIV_ROUND_UP(dev_priv->cdclk_freq, 
1000));
+   }
 }
 
 /* Adjust CDclk dividers to allow high res or save power if possible */
@@ -5620,7 +5627,7 @@ static void valleyview_set_cdclk(struct drm_device *dev, 
int cdclk)
vlv_bunit_write(dev_priv, BUNIT_REG_BISOC, val);
mutex_unlock(&dev_priv->dpio_lock);
 
-   vlv_update_cdclk(dev);
+   intel_update_cdclk(dev);
 }
 
 static void cherryview_set_cdclk(struct drm_device *dev, int cdclk)
@@ -5661,7 +5668,7 @@ static void cherryview_set_cdclk(struct drm_device *dev, 
int cdclk)
}
mutex_unlock(&dev_priv->rps.hw_lock);
 
-   vlv_update_cdclk(dev);
+   intel_update_cdclk(dev);
 }
 
 static int valleyview_calc_cdclk(struct drm_i915_private *dev_priv,
@@ -5850,6 +5857,8 @@ static void valleyview_modeset_global_resources(struct 
drm_atomic_state *old_sta
 
intel_display_power_put(dev_priv, POWER_DOMAIN_PIPE_A);
}
+
+   intel_update_cdclk(dev);
 }
 
 static void valleyview_crtc_enable(struct drm_crtc *crtc)
@@ -9273,6 +9282,7 @@ static void hsw_restore_lcpll(struct drm_i915_private 
*dev_priv)
}
 
intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
+   intel_update_cdclk(dev_priv->dev);
 }
 
 /*
@@ -13065,6 +13075,8 @@ static void intel_shared_dpll_init(struct drm_device 
*dev)
 {
struct drm_i915_private *dev_priv = dev->dev_private;
 
+   intel_update_cdclk(dev);
+
if (HAS_DDI(dev))
intel_ddi_pll_init(dev);
else if (HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev))
@@ -14637,10 +14649,9 @@ static void i915_disable_vga(struct drm_device *dev)
 
 void intel_modeset_init_hw(struct drm_device *dev)
 {
-   intel_prepare_ddi(dev);
+   intel_update_cdclk(dev);
 
-   if (IS_VALLEYVIEW(dev))
-   vlv_update_cdclk(dev);
+   intel_prepare_ddi(dev);
 
intel_init_clock_gating(dev);
 
-- 
1.9.1

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


[Intel-gfx] [PATCH v4 09/12] drm/i915: Don't enable IPS when pixel rate exceeds 95%

2015-05-22 Thread Mika Kahola
From: Ville Syrjälä 

Bspec says we shouldn't enable IPS on BDW when the pipe pixel rate
exceeds 95% of the core display clock. Apparently this can cause
underruns.

There's no similar restriction listed for HSW, so leave that one alone
for now.

v2: Add pipe_config_supports_ips() (Chris)
v3: Compare against the max cdclk insted of the current cdclk

Tested-by: Timo Aaltonen 
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=83497
Signed-off-by: Ville Syrjälä 

v4: Rebased to the latest
v5: Rebased to the latest

Reviewed-by: Mika Kahola 

Author:Ville Syrjälä 
---
 drivers/gpu/drm/i915/intel_display.c | 30 --
 drivers/gpu/drm/i915/intel_drv.h |  2 +-
 drivers/gpu/drm/i915/intel_pm.c  | 17 -
 3 files changed, 37 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index 7db1eee..febf993 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -6406,12 +6406,38 @@ retry:
return ret;
 }
 
+static bool pipe_config_supports_ips(struct drm_i915_private *dev_priv,
+struct intel_crtc_state *pipe_config)
+{
+   if (pipe_config->pipe_bpp > 24)
+   return false;
+
+   /* HSW can handle pixel rate up to cdclk? */
+   if (IS_HASWELL(dev_priv->dev))
+   return true;
+
+   /*
+* FIXME if we compare against max we should then
+* increase the cdclk frequency when the current
+* value is too low. The other option is to compare
+* against the cdclk frequency we're going have post
+* modeset (ie. one we computed using other constraints).
+* Need to measure whether using a lower cdclk w/o IPS
+* is better or worse than a higher cdclk w/ IPS.
+*/
+   return ilk_pipe_pixel_rate(pipe_config) <=
+   dev_priv->max_cdclk_freq * 95 / 100;
+}
+
 static void hsw_compute_ips_config(struct intel_crtc *crtc,
   struct intel_crtc_state *pipe_config)
 {
+   struct drm_device *dev = crtc->base.dev;
+   struct drm_i915_private *dev_priv = dev->dev_private;
+
pipe_config->ips_enabled = i915.enable_ips &&
-  hsw_crtc_supports_ips(crtc) &&
-  pipe_config->pipe_bpp <= 24;
+   hsw_crtc_supports_ips(crtc) &&
+   pipe_config_supports_ips(dev_priv, pipe_config);
 }
 
 static int intel_crtc_compute_config(struct intel_crtc *crtc,
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 47bc729..09df4b5 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1371,7 +1371,7 @@ void ilk_wm_get_hw_state(struct drm_device *dev);
 void skl_wm_get_hw_state(struct drm_device *dev);
 void skl_ddb_get_hw_state(struct drm_i915_private *dev_priv,
  struct skl_ddb_allocation *ddb /* out */);
-
+uint32_t ilk_pipe_pixel_rate(const struct intel_crtc_state *pipe_config);
 
 /* intel_sdvo.c */
 bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob);
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 0046cb4..282ad59 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -1434,23 +1434,22 @@ static void i845_update_wm(struct drm_crtc *unused_crtc)
I915_WRITE(FW_BLC, fwater_lo);
 }
 
-static uint32_t ilk_pipe_pixel_rate(struct drm_device *dev,
-   struct drm_crtc *crtc)
+uint32_t ilk_pipe_pixel_rate(const struct intel_crtc_state *pipe_config)
 {
-   struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
uint32_t pixel_rate;
 
-   pixel_rate = intel_crtc->config->base.adjusted_mode.crtc_clock;
+   pixel_rate = pipe_config->base.adjusted_mode.crtc_clock;
 
/* We only use IF-ID interlacing. If we ever use PF-ID we'll need to
 * adjust the pixel_rate here. */
 
-   if (intel_crtc->config->pch_pfit.enabled) {
+   if (pipe_config->pch_pfit.enabled) {
uint64_t pipe_w, pipe_h, pfit_w, pfit_h;
-   uint32_t pfit_size = intel_crtc->config->pch_pfit.size;
+   uint32_t pfit_size = pipe_config->pch_pfit.size;
+
+   pipe_w = pipe_config->pipe_src_w;
+   pipe_h = pipe_config->pipe_src_h;
 
-   pipe_w = intel_crtc->config->pipe_src_w;
-   pipe_h = intel_crtc->config->pipe_src_h;
pfit_w = (pfit_size >> 16) & 0x;
pfit_h = pfit_size & 0x;
if (pipe_w < pfit_w)
@@ -2066,7 +2065,7 @@ static void ilk_compute_wm_parameters(struct drm_crtc 
*crtc,
 
p->active = true;
p->pipe_htotal = intel_crtc->config->base.adjusted_mode.crtc_htotal;
-   p->pixel_rate = ilk_pipe_pixel_rate(dev, crtc);
+   p->pixel_rate = ilk_pipe_pix

[Intel-gfx] [PATCH v4 12/12] drm/i915: BDW clock change support

2015-05-22 Thread Mika Kahola
From: Ville Syrjälä 

Add support for changing cdclk frequency during runtime on BDW. The
procedure is quite a bit different on BDW from the one on HSW, so
add a separate function for it.

Also with IPS enabled the actual pixel rate mustn't exceed 95% of cdclk,
so take that into account when computing the max pixel rate.

v2: Grab rps.hw_lock around sandybridge_pcode_write()
v3: Rebase due to power well vs. .global_resources() reordering

Signed-off-by: Ville Syrjälä 

v4: Rebased to the latest
v5: Rebased to the latest

Reviewed-by: Mika Kahola 

Author:Ville Syrjälä 
---
 drivers/gpu/drm/i915/i915_reg.h  |   1 +
 drivers/gpu/drm/i915/intel_display.c | 139 ++-
 2 files changed, 122 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 015fe12..64ec500 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -6702,6 +6702,7 @@ enum skl_disp_power_wells {
 #define GEN6_ENCODE_RC6_VID(mv)(((mv) - 245) / 5)
 #define GEN6_DECODE_RC6_VID(vids)  (((vids) * 5) + 245)
 #define   HSW_PCODE_DE_WRITE_FREQ_REQ  0x17
+#define   BDW_PCODE_DISPLAY_FREQ_CHANGE_REQ0x18
 #define   GEN9_PCODE_READ_MEM_LATENCY  0x6
 #define GEN9_MEM_LATENCY_LEVEL_MASK0xFF
 #define GEN9_MEM_LATENCY_LEVEL_1_5_SHIFT   8
diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index 556d0ec7..71efd2f 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -5545,7 +5545,22 @@ static void intel_update_max_cdclk(struct drm_device 
*dev)
 {
struct drm_i915_private *dev_priv = dev->dev_private;
 
-   if (IS_HASWELL(dev)) {
+   if (IS_BROADWELL(dev))  {
+   /*
+* FIXME with extra cooling we can allow
+* 540 MHz for ULX and 675 Mhz for ULT.
+* How can we know if extra cooling is
+* available? PCI ID, VTB, something else?
+*/
+   if (I915_READ(FUSE_STRAP) & HSW_CDCLK_LIMIT)
+   dev_priv->max_cdclk_freq = 45;
+   else if (IS_BDW_ULX(dev))
+   dev_priv->max_cdclk_freq = 45;
+   else if (IS_BDW_ULT(dev))
+   dev_priv->max_cdclk_freq = 54;
+   else
+   dev_priv->max_cdclk_freq = 675000;
+   } else if (IS_HASWELL(dev)) {
if (I915_READ(FUSE_STRAP) & HSW_CDCLK_LIMIT)
dev_priv->max_cdclk_freq = 45;
else if (IS_HSW_ULX(dev))
@@ -6426,13 +6441,11 @@ static bool pipe_config_supports_ips(struct 
drm_i915_private *dev_priv,
return true;
 
/*
-* FIXME if we compare against max we should then
-* increase the cdclk frequency when the current
-* value is too low. The other option is to compare
-* against the cdclk frequency we're going have post
-* modeset (ie. one we computed using other constraints).
-* Need to measure whether using a lower cdclk w/o IPS
-* is better or worse than a higher cdclk w/ IPS.
+* We compare against max which means we must take
+* the increased cdclk requirement into account when
+* calculating the new cdclk.
+*
+* Should measure whether using a lower cdclk w/o IPS
 */
return ilk_pipe_pixel_rate(pipe_config) <=
dev_priv->max_cdclk_freq * 95 / 100;
@@ -9421,9 +9434,18 @@ static int ilk_max_pixel_rate(struct drm_i915_private 
*dev_priv)
int max_pixel_rate = 0;
 
for_each_intel_crtc(dev, crtc) {
-   if (crtc->new_enabled)
-   max_pixel_rate = max((int)max_pixel_rate,
-
(int)ilk_pipe_pixel_rate(crtc->config));
+   int pixel_rate;
+
+   if (!crtc->new_enabled)
+   continue;
+
+   pixel_rate = ilk_pipe_pixel_rate(crtc->config);
+
+   /* pixel rate mustn't exceed 95% of cdclk with IPS on BDW */
+   if (IS_BROADWELL(dev) && crtc->config->ips_enabled)
+   pixel_rate = DIV_ROUND_UP(pixel_rate * 100, 95);
+
+   max_pixel_rate = max(max_pixel_rate, pixel_rate);
}
 
return max_pixel_rate;
@@ -9438,7 +9460,9 @@ static int haswell_calc_cdclk(struct drm_i915_private 
*dev_priv,
 * FIXME should also account for plane ratio
 * once 64bpp pixel formats are supported.
 */
-   if (max_pixel_rate > 45)
+   if (max_pixel_rate > 54)
+   cdclk = 675000;
+   else if (max_pixel_rate > 45)
cdclk = 54;
else if (max_pixel_rate > 337500 || !IS_HSW_ULX(dev_priv))
cdclk = 45;
@@ -9503,6 +9527,83 @@ static void haswell_set_cdclk

[Intel-gfx] [PATCH v4 8/8] drm/i915: Store max cdclk value in dev_priv

2015-05-22 Thread Mika Kahola
From: Ville Syrjälä 

Keep the cdclk maximum supported frequency around in dev_priv so that we
can verify certain things against it before actually changing the cdclk
frequency.

For now only VLV/CHV have support changing cdclk frequency, so other
plarforms get to assume cdclk is fixed.

Signed-off-by: Ville Syrjälä 

v2: Rebased to the latest
v3: Rebased to the latest

Reviewed-by: Mika Kahola 

Author:Ville Syrjälä 
---
 drivers/gpu/drm/i915/i915_drv.h  |  2 +-
 drivers/gpu/drm/i915/intel_display.c | 20 +++-
 2 files changed, 20 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 1038f5c..186a9e6 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1712,7 +1712,7 @@ struct drm_i915_private {
 
unsigned int fsb_freq, mem_freq, is_ddr3;
unsigned int skl_boot_cdclk;
-   unsigned int cdclk_freq;
+   unsigned int cdclk_freq, max_cdclk_freq;
unsigned int hpll_freq;
 
/**
diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index 1bdd2d7..51cbbca 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -5750,6 +5750,21 @@ static int valleyview_get_vco(struct drm_i915_private 
*dev_priv)
return vco_freq[hpll_freq] * 1000;
 }
 
+static void intel_update_max_cdclk(struct drm_device *dev)
+{
+   struct drm_i915_private *dev_priv = dev->dev_private;
+
+   if (IS_VALLEYVIEW(dev)) {
+   dev_priv->max_cdclk_freq = 40;
+   } else {
+   /* otherwise assume cdclk is fixed */
+   dev_priv->max_cdclk_freq = dev_priv->cdclk_freq;
+   }
+
+   DRM_DEBUG_DRIVER("Max CD clock rate: %d kHz\n",
+dev_priv->max_cdclk_freq);
+}
+
 static void intel_update_cdclk(struct drm_device *dev)
 {
struct drm_i915_private *dev_priv = dev->dev_private;
@@ -5771,6 +5786,9 @@ static void intel_update_cdclk(struct drm_device *dev)
 */
I915_WRITE(GMBUSFREQ_VLV, DIV_ROUND_UP(dev_priv->cdclk_freq, 
1000));
}
+
+   if (dev_priv->max_cdclk_freq == 0)
+   intel_update_max_cdclk(dev);
 }
 
 /* Adjust CDclk dividers to allow high res or save power if possible */
@@ -6615,7 +6633,7 @@ static int intel_crtc_compute_config(struct intel_crtc 
*crtc,
 
/* FIXME should check pixel clock limits on all platforms */
if (INTEL_INFO(dev)->gen < 4) {
-   int clock_limit = dev_priv->cdclk_freq;
+   int clock_limit = dev_priv->max_cdclk_freq;
 
/*
 * Enable pixel doubling when the dot clock
-- 
1.9.1

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


[Intel-gfx] [PATCH v4 10/12] drm/i915: HSW cdclk support

2015-05-22 Thread Mika Kahola
From: Ville Syrjälä 

Implement support for changing the cdclk frequency during runtime on
HSW. VLV/CHV already have support for this, so we can follow their
example for the most part. Only the actual hardware programming differs,
the rest is pretty much the same.

The pipe pixel rate stuff is handled a bit differently for now due to
the difference in pch vs. gmch pfit handling. Eventually we should unify
that part to eliminate what is essentially duplicated code.

v2: Grab rps.hw_lock around sandybridge_pcode_write()
v3: Rebase due to power well vs. .global_resources() reordering

Signed-off-by: Ville Syrjälä 

v3: Rebased to the latest
v4: Reformatting 'haswell_modeset_global_pipes' function to
support atomic state

Signed-off-by: Mika Kahola 

Author:Ville Syrjälä 
---
 drivers/gpu/drm/i915/i915_reg.h  |   3 +
 drivers/gpu/drm/i915/intel_display.c | 161 +--
 2 files changed, 159 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 14366c8..015fe12 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -6701,6 +6701,7 @@ enum skl_disp_power_wells {
 #define  GEN6_PCODE_READ_RC6VIDS   0x5
 #define GEN6_ENCODE_RC6_VID(mv)(((mv) - 245) / 5)
 #define GEN6_DECODE_RC6_VID(vids)  (((vids) * 5) + 245)
+#define   HSW_PCODE_DE_WRITE_FREQ_REQ  0x17
 #define   GEN9_PCODE_READ_MEM_LATENCY  0x6
 #define GEN9_MEM_LATENCY_LEVEL_MASK0xFF
 #define GEN9_MEM_LATENCY_LEVEL_1_5_SHIFT   8
@@ -7159,10 +7160,12 @@ enum skl_disp_power_wells {
 #define  LCPLL_PLL_LOCK(1<<30)
 #define  LCPLL_CLK_FREQ_MASK   (3<<26)
 #define  LCPLL_CLK_FREQ_450(0<<26)
+#define  LCPLL_CLK_FREQ_ALT_HSW(1<<26) /* 337.5 (ULX) or 540 */
 #define  LCPLL_CLK_FREQ_54O_BDW(1<<26)
 #define  LCPLL_CLK_FREQ_337_5_BDW  (2<<26)
 #define  LCPLL_CLK_FREQ_675_BDW(3<<26)
 #define  LCPLL_CD_CLOCK_DISABLE(1<<25)
+#define  LCPLL_ROOT_CD_CLOCK_DISABLE   (1<<24)
 #define  LCPLL_CD2X_CLOCK_DISABLE  (1<<23)
 #define  LCPLL_POWER_DOWN_ALLOW(1<<22)
 #define  LCPLL_CD_SOURCE_FCLK  (1<<21)
diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index febf993..556d0ec7 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -5545,7 +5545,16 @@ static void intel_update_max_cdclk(struct drm_device 
*dev)
 {
struct drm_i915_private *dev_priv = dev->dev_private;
 
-   if (IS_VALLEYVIEW(dev)) {
+   if (IS_HASWELL(dev)) {
+   if (I915_READ(FUSE_STRAP) & HSW_CDCLK_LIMIT)
+   dev_priv->max_cdclk_freq = 45;
+   else if (IS_HSW_ULX(dev))
+   dev_priv->max_cdclk_freq = 337500;
+   else if (IS_HSW_ULT(dev))
+   dev_priv->max_cdclk_freq = 45;
+   else
+   dev_priv->max_cdclk_freq = 54;
+   } else if (IS_VALLEYVIEW(dev)) {
dev_priv->max_cdclk_freq = 40;
} else {
/* otherwise assume cdclk is fixed */
@@ -9404,6 +9413,139 @@ static void broxton_modeset_global_resources(struct 
drm_atomic_state *old_state)
broxton_set_cdclk(dev, req_cdclk);
 }
 
+/* compute the max rate for new configuration */
+static int ilk_max_pixel_rate(struct drm_i915_private *dev_priv)
+{
+   struct drm_device *dev = dev_priv->dev;
+   struct intel_crtc *crtc;
+   int max_pixel_rate = 0;
+
+   for_each_intel_crtc(dev, crtc) {
+   if (crtc->new_enabled)
+   max_pixel_rate = max((int)max_pixel_rate,
+
(int)ilk_pipe_pixel_rate(crtc->config));
+   }
+
+   return max_pixel_rate;
+}
+
+static int haswell_calc_cdclk(struct drm_i915_private *dev_priv,
+ int max_pixel_rate)
+{
+   int cdclk;
+
+   /*
+* FIXME should also account for plane ratio
+* once 64bpp pixel formats are supported.
+*/
+   if (max_pixel_rate > 45)
+   cdclk = 54;
+   else if (max_pixel_rate > 337500 || !IS_HSW_ULX(dev_priv))
+   cdclk = 45;
+   else
+   cdclk = 337500;
+
+   /*
+* FIXME move the cdclk caclulation to
+* compute_config() so we can fail gracegully.
+*/
+   if (cdclk > dev_priv->max_cdclk_freq) {
+   DRM_ERROR("requested cdclk (%d kHz) exceeds max (%d kHz)\n",
+ cdclk, dev_priv->max_cdclk_freq);
+   cdclk = dev_priv->max_cdclk_freq;
+   }
+
+   return cdclk;
+}
+
+static void haswell_set_cdclk(struct drm_device *dev, int cdclk)
+{
+   struct drm_i915_private *dev_priv = dev->dev_private;
+

Re: [Intel-gfx] [PATCH] drm/i915: Fix IPS related flicker

2015-05-22 Thread shuang . he
Tested-By: Intel Graphics QA PRTS (Patch Regression Test System Contact: 
shuang...@intel.com)
Task id: 6453
-Summary-
Platform  Delta  drm-intel-nightly  Series Applied
PNV  234/234  234/234
ILK  262/262  262/262
SNB -1  282/282  281/282
IVB  300/300  300/300
BYT  254/254  254/254
BDW  275/275  275/275
-Detailed-
Platform  Testdrm-intel-nightly  Series 
Applied
 SNB  igt@pm_rpm@dpms-mode-unset-non-lpsp  DMESG_WARN(18)PASS(1)  
DMESG_WARN(1)
(dmesg patch 
applied)WARNING:at_drivers/gpu/drm/i915/intel_uncore.c:#assert_device_not_suspended[i915]()@WARNING:.*
 at .* assert_device_not_suspended+0x
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


Re: [Intel-gfx] [PATCH intel-gpu-tools 1/3] drmtest: Add non-i915 device open helpers

2015-05-22 Thread Daniel Vetter
Forgotten to add Thomas as the igt maintainer.
-Daniel

On Fri, May 8, 2015 at 3:03 PM, Daniel Vetter  wrote:
> On Tue, Apr 21, 2015 at 5:06 PM, Daniel Stone  wrote:
>> On 21 April 2015 at 16:03, Micah Fedke  wrote:
>>> + * drm_open_any_any:
>>> + *
>>> + * Literally the worst-named function I've ever written.
>>
>> And I stand by this. This is really an RFC, partly to find out whether
>> it would be better to find a new name for these functions (open a
>> modeset-capable DRM node, whether it's Intel or otherwise), or whether
>> adding a flag to drm_open_any and friends to specify Intel or generic,
>> with the resulting mega-Cocci run, would be better.
>
> Yeah I think a new param to restrict the driver name (i915, nouveau,
> ...) would be better. Plus maybe a drm_require_driver so that testcase
> could open a generic driver and then only skip specific subtest.
> Initial pass could be done with cocci+ follow-up patches to convert
> patches from i915 specific to generic.
>
> One thing to keep in mind is how we'll treat machines with more than 1
> gpu. I do care about that at least for the prime testcases since I
> have a box somewhere with i915+nouveau to run them, and that should
> keep working. Aside: We should convert those tests to use
> drm_open_any("nouveau") instead of the hand-rolled one. A possible
> idea would be to convert the igt_main macros into a loop which would
> go over all the available drm devices (well the different ones, we
> don't want to separately test control/render/legacy nodes ofc). What
> we definitely need is an enviroment variable to override the default
> choice.
> -Daniel
> --
> Daniel Vetter
> Software Engineer, Intel Corporation
> +41 (0) 79 365 57 48 - http://blog.ffwll.ch



-- 
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 IPS related flicker

2015-05-22 Thread Ville Syrjälä
On Thu, May 21, 2015 at 12:53:03PM -0700, Rodrigo Vivi wrote:
> We cannot let IPS enabled with no plane on the pipe:
> 
> BSpec: "IPS cannot be enabled until after at least one plane has
> been enabled for at least one vertical blank." and "IPS must be
> disabled while there is still at least one plane enabled on the
> same pipe as IPS.
> 
> However this shortcut path to make primary plane invisible when
> updating primary plane was leting IPS enabled while there was no
> other plane enabled on the pipe causing flickerings that we were
> believing that it was caused by that other restriction where
> ips cannot be used when pixel rate is greater than 95% of cdclok.
> 
> Reference: https://bugs.freedesktop.org/show_bug.cgi?id=85583
> Cc: Joe Konno 
> Cc: Paulo Zanoni 
> Signed-off-by: Rodrigo Vivi 
> ---
>  drivers/gpu/drm/i915/intel_display.c | 13 +
>  1 file changed, 13 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/intel_display.c 
> b/drivers/gpu/drm/i915/intel_display.c
> index 9d2d6fb..5519d56 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -2789,6 +2789,19 @@ static void ironlake_update_primary_plane(struct 
> drm_crtc *crtc,
>   int pixel_size;
>  
>   if (!visible || !fb) {
> + /*
> +  * This shortcut path disables the primary plane making
> +  * IPS really sad and lost when it is enabled alone with no
> +  * plane around on the pipe. So, for now it is safe to disable
> +  * IPS here.
> +  /
> +  /*
> +  * FIXME: Any other plane enabled should be enough so it would
> +  * be better to check if there is really no sprite or
> +  * cursor around.
> +  */
> + hsw_disable_ips(intel_crtc);
> +

This isn't really the right place for it. It should be called by higher
level functions outside of the atomic critical section. I suppose we're
missing it from some legacy path.

>   I915_WRITE(reg, 0);
>   I915_WRITE(DSPSURF(plane), 0);
>   POSTING_READ(reg);
> -- 
> 2.1.0
> 
> ___
> 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: Document IPS restriction with 1 plane on the pipe.

2015-05-22 Thread Ville Syrjälä
On Thu, May 21, 2015 at 01:06:10PM -0700, Rodrigo Vivi wrote:
> With this well documented we can remove that FIXME comment.
> 
> We just need to make sure that on primary -> sprite transition there
> is no vblank time where ips gets alone on the pipe with absolutelly
> no plane. If this happens even for a quickly momment IPS won't get
> recovered and it might cause strange flickering screens.

Last time I tried this the hardware had problems with this, hence the
FIXME comments. I think that was on HSW. IIRC it manifested as a
(presumably) single black frame, but I can't recall if it happened on
every transition or just sometimes. 

> 
> Signed-off-by: Rodrigo Vivi 
> ---
>  drivers/gpu/drm/i915/intel_display.c | 37 
> 
>  1 file changed, 25 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_display.c 
> b/drivers/gpu/drm/i915/intel_display.c
> index 5519d56..d2c417b 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -4620,6 +4620,17 @@ static void intel_enable_sprite_planes(struct drm_crtc 
> *crtc)
>   }
>  }
>  
> +/**
> + * hsw_enable_ips - Enable IPS
> + * @intel_crtc: crtc
> + *
> + * This function needs to be called after there are at least on plane enabled
> + * on the pipe.
> + *
> + * IPS is fine as long as one plane is enabled.
> + *
> + * Pre-requisite: IPS cannot be enabled until after at least one plane has 
> been enabled for at least one vertical blank.
> + */
>  void hsw_enable_ips(struct intel_crtc *crtc)
>  {
>   struct drm_device *dev = crtc->base.dev;
> @@ -4653,6 +4664,20 @@ void hsw_enable_ips(struct intel_crtc *crtc)
>   }
>  }
>  
> +/**
> + * hsw_disable_ips - Disable IPS
> + * @intel_crtc: crtc
> + *
> + * This function needs to be called everytime that there will be no plane
> + * enabled on the pipe on the next vblank.
> + *
> + * IPS is fine as long as one plane is enabled, however it gets confused
> + * in a non recoverable state when it stays enabled on the pipe with no
> + * other plane enabled at same vblank time. So please make sure this
> + * function is called everytime that we have no plane enabled on the pipe.
> + *
> + * Pre-requisite: IPS must be disabled while there is still at least one 
> plane enabled on the same pipe as IPS.
> + */
>  void hsw_disable_ips(struct intel_crtc *crtc)
>  {
>   struct drm_device *dev = crtc->base.dev;
> @@ -4769,12 +4794,6 @@ intel_post_enable_primary(struct drm_crtc *crtc)
>   if (IS_BROADWELL(dev))
>   intel_wait_for_vblank(dev, pipe);
>  
> - /*
> -  * FIXME IPS should be fine as long as one plane is
> -  * enabled, but in practice it seems to have problems
> -  * when going from primary only to sprite only and vice
> -  * versa.
> -  */
>   hsw_enable_ips(intel_crtc);
>  
>   mutex_lock(&dev->struct_mutex);
> @@ -4840,12 +4859,6 @@ intel_pre_disable_primary(struct drm_crtc *crtc)
>   intel_fbc_disable(dev);
>   mutex_unlock(&dev->struct_mutex);
>  
> - /*
> -  * FIXME IPS should be fine as long as one plane is
> -  * enabled, but in practice it seems to have problems
> -  * when going from primary only to sprite only and vice
> -  * versa.
> -  */
>   hsw_disable_ips(intel_crtc);
>  }
>  
> -- 
> 2.1.0
> 
> ___
> 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 4/4] drm/i915: Introduce DRM_I915_THROTTLE_JIFFIES

2015-05-22 Thread Daniel Vetter
On Thu, May 21, 2015 at 09:01:48PM +0100, Chris Wilson wrote:
> As Daniel commented on
> 
> commit b7ffe1362c5f468b853223acc9268804aa92afc8
> Author: Chris Wilson 
> Date:   Mon Apr 27 13:41:24 2015 +0100
> 
> drm/i915: Free RPS boosts for all laggards
> 
> it is better to be explicit when sharing hardcoded values such as
> throttle/boost timeouts. Make it so!
> 
> Signed-off-by: Chris Wilson 
> Cc: Daniel Vetter 

I merged patch 1&4 from this to dinq. I'd like a "I want this" for 2. And
3 needs more time to properly review the locking and everything, I'll try
to do that later today.

Thanks, Daniel

> ---
>  drivers/gpu/drm/i915/i915_drv.h | 6 ++
>  drivers/gpu/drm/i915/i915_gem.c | 2 +-
>  drivers/gpu/drm/i915/intel_pm.c | 2 +-
>  3 files changed, 8 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index abd0914b4849..30ffb9138116 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -279,6 +279,12 @@ struct drm_i915_file_private {
>   struct {
>   spinlock_t lock;
>   struct list_head request_list;
> +/* 20ms is a fairly arbitrary limit (greater than the average frame time)
> + * chosen to prevent the CPU getting more than a frame ahead of the GPU
> + * (when using lax throttling for the frontbuffer). We also use it to
> + * offer free GPU waitboosts for severely congested workloads.
> + */
> +#define DRM_I915_THROTTLE_JIFFIES msecs_to_jiffies(20)
>   } mm;
>   struct idr context_idr;
>  
> diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
> index ca41fc56f246..9ae98b00ff56 100644
> --- a/drivers/gpu/drm/i915/i915_gem.c
> +++ b/drivers/gpu/drm/i915/i915_gem.c
> @@ -4211,7 +4211,7 @@ i915_gem_ring_throttle(struct drm_device *dev, struct 
> drm_file *file)
>  {
>   struct drm_i915_private *dev_priv = dev->dev_private;
>   struct drm_i915_file_private *file_priv = file->driver_priv;
> - unsigned long recent_enough = jiffies - msecs_to_jiffies(20);
> + unsigned long recent_enough = jiffies - DRM_I915_THROTTLE_JIFFIES;
>   struct drm_i915_gem_request *request, *target = NULL;
>   unsigned reset_counter;
>   int ret;
> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> index 833f9dd28fea..abeb7fca17c8 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -4164,7 +4164,7 @@ void gen6_rps_boost(struct drm_i915_private *dev_priv,
>   /* Force a RPS boost (and don't count it against the client) if
>* the GPU is severely congested.
>*/
> - if (rps && time_after(jiffies, submitted + msecs_to_jiffies(20)))
> + if (rps && time_after(jiffies, submitted + DRM_I915_THROTTLE_JIFFIES))
>   rps = NULL;
>  
>   spin_lock(&dev_priv->rps.client_lock);
> -- 
> 2.1.4
> 

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx