Re: [Intel-gfx] [PATCH] drm: Adding edp1.4 specific dpcd macros

2015-02-20 Thread Jani Nikula
On Thu, 19 Feb 2015, Todd Previte  wrote:
> Just some formatting issues that need to be cleaned up. Otherwise the 
> definitions look correct according to the eDP 1.4 spec.

Actually the formatting seems to be in line with the rest of that
particular file.

BR,
Jani.

>
> -T
>
> On 2/19/15 12:46 AM, Sonika Jindal wrote:
>> Adding dpcd macros related to edp1.4 and link rates
>>
>> v2: Added DP_SUPPORTED_LINK_RATES macros
>>
>> Signed-off-by: Sonika Jindal 
>> ---
>>   include/drm/drm_dp_helper.h |8 
>>   1 file changed, 8 insertions(+)
>>
>> diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h
>> index 11f8c84..77a55e2 100644
>> --- a/include/drm/drm_dp_helper.h
>> +++ b/include/drm/drm_dp_helper.h
>> @@ -92,6 +92,9 @@
>>   # define DP_MSA_TIMING_PAR_IGNORED (1 << 6) /* eDP */
>>   # define DP_OUI_SUPPORT(1 << 7)
>>
>> +#define DP_SUPPORTED_LINK_RATES 0x010 /*eDP 1.4*/
>> +#define DP_MAX_SUPPORTED_RATES  0x8
>> +
> Extra blank line
>>   #define DP_I2C_SPEED_CAP   0x00c/* DPI */
>>   # define DP_I2C_SPEED_1K   0x01
>>   # define DP_I2C_SPEED_5K   0x02
>> @@ -101,6 +104,7 @@
>>   # define DP_I2C_SPEED_1M   0x20
>>
>>   #define DP_EDP_CONFIGURATION_CAP0x00d   /* XXX 1.2? */
>> +# define DP_DPCD_DISPLAY_CONTROL_CAPABLE (1 << 3) /* edp v1.2 or higher 
>> */
> Remove the space between # and define.
>>   #define DP_TRAINING_AUX_RD_INTERVAL 0x00e   /* XXX 1.2? */
>>
>>   /* Multiple stream transport */
>> @@ -221,6 +225,8 @@
>>   # define DP_UP_REQ_EN  (1 << 1)
>>   # define DP_UPSTREAM_IS_SRC(1 << 2)
>>
>> +#define DP_LINK_RATE_SET0x115
>> +
> Extra blank line
>>   #define DP_PSR_EN_CFG  0x170   /* XXX 1.2? */
>>   # define DP_PSR_ENABLE (1 << 0)
>>   # define DP_PSR_MAIN_LINK_ACTIVE   (1 << 1)
>> @@ -332,6 +338,8 @@
>>   # define DP_SET_POWER_D30x2
>>   # define DP_SET_POWER_MASK  0x3
>>
>> +#define DP_EDP_DPCD_REV  0x700
>> +
> Extra blank line
>>   #define DP_SIDEBAND_MSG_DOWN_REQ_BASE  0x1000   /* 1.2 MST */
>>   #define DP_SIDEBAND_MSG_UP_REP_BASE0x1200   /* 1.2 MST */
>>   #define DP_SIDEBAND_MSG_DOWN_REP_BASE  0x1400   /* 1.2 MST */
>
> ___
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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


Re: [Intel-gfx] [PATCH 1/2] drm/i915: Split adding request to smaller functions

2015-02-20 Thread Mika Kuoppala
John Harrison  writes:

> Please note that a lot of the issues with _i915_add_request are cleaned 
> up by my patch series to remove the outstanding_lazy_request. The add to 
> client in some random client context is fixed, the messy execlist vs 
> legacy ringbuf decisions are removed, the execlist vs legacy one-sided 
> context reference is removed, ...
>
> Also, I am in the process of converting the request structure to use 
> struct fence which will possibly answer some of your locking concerns in 
> the subsequent patch.
>
> So can you hold of on merging these two patches at least until the dust 
> has settled on the anti-OLR series?
>

This was just a quick stab at fixing the hangcheck misreports on ring
being idle when not.

Daniel please just ignore these two.

-Mika

> Thanks.
>
>
> On 19/02/2015 16:18, Mika Kuoppala wrote:
>> Clean __i915_add_request by splitting request submission to
>> preparation, actual submission and adding to client.
>>
>> While doing this we can remove the request->start which
>> was not used.
>>
>> Cc: Chris Wilson 
>> Signed-off-by: Mika Kuoppala 
>> ---
>>   drivers/gpu/drm/i915/i915_gem.c | 116 
>> +++-
>>   1 file changed, 78 insertions(+), 38 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i915/i915_gem.c 
>> b/drivers/gpu/drm/i915/i915_gem.c
>> index 61134ab..06265e7 100644
>> --- a/drivers/gpu/drm/i915/i915_gem.c
>> +++ b/drivers/gpu/drm/i915/i915_gem.c
>> @@ -2407,26 +2407,34 @@ i915_gem_get_seqno(struct drm_device *dev, u32 
>> *seqno)
>>  return 0;
>>   }
>>   
>> -int __i915_add_request(struct intel_engine_cs *ring,
>> -   struct drm_file *file,
>> -   struct drm_i915_gem_object *obj)
>> +static struct intel_ringbuffer *
>> +__request_to_ringbuf(struct drm_i915_gem_request *request)
>> +{
>> +if (i915.enable_execlists)
>> +return request->ctx->engine[request->ring->id].ringbuf;
>> +
>> +return request->ring->buffer;
>> +}
>> +
>> +static struct drm_i915_gem_request *
>> +i915_gem_request_prepare(struct intel_engine_cs *ring, struct drm_file 
>> *file)
>>   {
>> -struct drm_i915_private *dev_priv = ring->dev->dev_private;
>>  struct drm_i915_gem_request *request;
>>  struct intel_ringbuffer *ringbuf;
>> -u32 request_start;
>>  int ret;
>>   
>>  request = ring->outstanding_lazy_request;
>>  if (WARN_ON(request == NULL))
>> -return -ENOMEM;
>> +return ERR_PTR(-ENOMEM);
>>   
>> -if (i915.enable_execlists) {
>> -ringbuf = request->ctx->engine[ring->id].ringbuf;
>> -} else
>> -ringbuf = ring->buffer;
>> +/* execlist submission has this already set */
>> +if (!request->ctx)
>> +request->ctx = ring->last_context;
>> +
>> +ringbuf = __request_to_ringbuf(request);
>> +if (WARN_ON(ringbuf == NULL))
>> +return ERR_PTR(-EIO);
>>   
>> -request_start = intel_ring_get_tail(ringbuf);
>>  /*
>>   * Emit any outstanding flushes - execbuf can fail to emit the flush
>>   * after having emitted the batchbuffer command. Hence we need to fix
>> @@ -2434,21 +2442,30 @@ int __i915_add_request(struct intel_engine_cs *ring,
>>   * is that the flush _must_ happen before the next request, no matter
>>   * what.
>>   */
>> -if (i915.enable_execlists) {
>> +if (i915.enable_execlists)
>>  ret = logical_ring_flush_all_caches(ringbuf, request->ctx);
>> -if (ret)
>> -return ret;
>> -} else {
>> +else
>>  ret = intel_ring_flush_all_caches(ring);
>> -if (ret)
>> -return ret;
>> -}
>> +
>> +if (ret)
>> +return ERR_PTR(ret);
>> +
>> +return request;
>> +}
>> +
>> +static int i915_gem_request_submit(struct drm_i915_gem_request *request,
>> +   struct drm_i915_gem_object *batch)
>> +{
>> +struct intel_ringbuffer *ringbuf = __request_to_ringbuf(request);
>> +struct intel_engine_cs *ring = request->ring;
>> +int ret;
>>   
>>  /* Record the position of the start of the request so that
>>   * should we detect the updated seqno part-way through the
>>   * GPU processing the request, we never over-estimate the
>>   * position of the head.
>>   */
>> +request->batch_obj = batch;
>>  request->postfix = intel_ring_get_tail(ringbuf);
>>   
>>  if (i915.enable_execlists) {
>> @@ -2461,7 +2478,6 @@ int __i915_add_request(struct intel_engine_cs *ring,
>>  return ret;
>>  }
>>   
>> -request->head = request_start;
>>  request->tail = intel_ring_get_tail(ringbuf);
>>   
>>  /* Whilst this request exists, batch_obj will be on the
>> @@ -2470,35 +2486,59 @@ int __i915_add_request(struct intel_engine_cs *ring,
>>   * inactive_list and lose its active reference. Hence we do not need
>>   * to explicitly hold another reference here.
>> 

Re: [Intel-gfx] [PATCH v2] drm/i915: FIFO space query code refactor

2015-02-20 Thread Mika Kuoppala
Dave Gordon  writes:

> When querying the GTFIFOCTL register to check the FIFO space, the read value
> must be masked. The operation is repeated explicitly in several places. This
> change refactors the read-and-mask code into a function call.
>
> v2: rebased on top of Mika's forcewake patch set, specifically:
>   [PATCH 8/8] drm/i915: Enum forcewake domains and domain identifiers
>
> Change-Id: Id1a9f3785cb20b82d4caa330c37b31e4e384a3ef
> Signed-off-by: Dave Gordon 

Reviewed-by: Mika Kuoppala 

> ---
>  drivers/gpu/drm/i915/intel_uncore.c |   19 ---
>  1 file changed, 12 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_uncore.c 
> b/drivers/gpu/drm/i915/intel_uncore.c
> index 66365e7..a0331a7 100644
> --- a/drivers/gpu/drm/i915/intel_uncore.c
> +++ b/drivers/gpu/drm/i915/intel_uncore.c
> @@ -205,6 +205,13 @@ static void fw_domains_put_with_fifo(struct 
> drm_i915_private *dev_priv,
>   gen6_gt_check_fifodbg(dev_priv);
>  }
>  
> +static inline u32 fifo_free_entries(struct drm_i915_private *dev_priv)
> +{
> + u32 count = __raw_i915_read32(dev_priv, GTFIFOCTL);
> +
> + return count & GT_FIFO_FREE_ENTRIES_MASK;
> +}
> +
>  static int __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv)
>  {
>   int ret = 0;
> @@ -212,16 +219,15 @@ static int __gen6_gt_wait_for_fifo(struct 
> drm_i915_private *dev_priv)
>   /* On VLV, FIFO will be shared by both SW and HW.
>* So, we need to read the FREE_ENTRIES everytime */
>   if (IS_VALLEYVIEW(dev_priv->dev))
> - dev_priv->uncore.fifo_count =
> - __raw_i915_read32(dev_priv, GTFIFOCTL) &
> - GT_FIFO_FREE_ENTRIES_MASK;
> + dev_priv->uncore.fifo_count = fifo_free_entries(dev_priv);
>  
>   if (dev_priv->uncore.fifo_count < GT_FIFO_NUM_RESERVED_ENTRIES) {
>   int loop = 500;
> - u32 fifo = __raw_i915_read32(dev_priv, GTFIFOCTL) & 
> GT_FIFO_FREE_ENTRIES_MASK;
> + u32 fifo = fifo_free_entries(dev_priv);
> +
>   while (fifo <= GT_FIFO_NUM_RESERVED_ENTRIES && loop--) {
>   udelay(10);
> - fifo = __raw_i915_read32(dev_priv, GTFIFOCTL) & 
> GT_FIFO_FREE_ENTRIES_MASK;
> + fifo = fifo_free_entries(dev_priv);
>   }
>   if (WARN_ON(loop < 0 && fifo <= GT_FIFO_NUM_RESERVED_ENTRIES))
>   ++ret;
> @@ -277,8 +283,7 @@ void intel_uncore_forcewake_reset(struct drm_device *dev, 
> bool restore)
>  
>   if (IS_GEN6(dev) || IS_GEN7(dev))
>   dev_priv->uncore.fifo_count =
> - __raw_i915_read32(dev_priv, GTFIFOCTL) &
> - GT_FIFO_FREE_ENTRIES_MASK;
> + fifo_free_entries(dev_priv);
>   }
>  
>   spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
> -- 
> 1.7.9.5
>
> ___
> 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 1/2] drm/i915: Track last register written (debug)

2015-02-20 Thread Paulo Zanoni
2015-02-20 3:33 GMT-02:00 Ben Widawsky :
> Register writes are supposed to be posted, and therefore "fast." In order to 
> try
> to preserve this behavior, the patch uses percpu variables to make the 
> overhead
> minimal. The slow data collection is done at error time, and that only occurs 
> if
> the user specified mmio_debug=1 module parameter.
>
> I wrote this patch to try to track down annoying and sporadic errors on my
> Broadwell laptop. Sometimes it's obvious how you got to this point from the
> backtrace, but other times it isn't.
>

Register reads can also trigger the unclaimed register error. Don't
you want to also record the last one we read on each CPU too?

Also, just to remind you since you seem to be debugging something:
user space programs (such as intel_reg_dumper or anything else) and
other Kernel modules (like vgacon and others) can also trigger these
errors, and we can't easily catch these cases.

Pinging Chris since he always has some ideas about this code.


> Output looks like this:
> [   63.122716] [drm:hsw_unclaimed_reg_detect] *ERROR* Unclaimed register 
> detected. Please use the i915.mmio_debug=1 to debug this problem.
> [  658.662961] [ cut here ]
> ...
> [  658.663113] ---[ end trace c7f0a18c4d4e027b ]---
> [  658.663114] [drm:hsw_unclaimed_reg_debug] *ERROR* Last registers written:
> [  658.663115] [drm:hsw_unclaimed_reg_debug] *ERROR*0x2030
> [  658.663116] [drm:hsw_unclaimed_reg_debug] *ERROR*0x00022030
> [  658.663117] [drm:hsw_unclaimed_reg_debug] *ERROR*0x2030
> [  658.663118] [drm:hsw_unclaimed_reg_debug] *ERROR*0x2030
> [  658.663119] [drm:hsw_unclaimed_reg_debug] *ERROR*0x
> [  658.663120] [drm:hsw_unclaimed_reg_debug] *ERROR*0x
> [  658.663121] [drm:hsw_unclaimed_reg_debug] *ERROR*0x
> [  658.663122] [drm:hsw_unclaimed_reg_debug] *ERROR*0x
>
> The same data is obtainable with using the various perf/ftrace hooks, but that
> is a bit larger of a hammer. It's hard to tell how useful this is/would be.
>
> Cc: Paulo Zanoni 
> Signed-off-by: Ben Widawsky 
> ---
>  drivers/gpu/drm/i915/i915_drv.h | 11 +--
>  drivers/gpu/drm/i915/intel_uncore.c | 11 ++-
>  2 files changed, 19 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index c33327d..6fa22db 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -2882,10 +2882,17 @@ int vlv_freq_opcode(struct drm_i915_private 
> *dev_priv, int val);
>  #define I915_READ16_NOTRACE(reg)   
> dev_priv->uncore.funcs.mmio_readw(dev_priv, (reg), false)
>  #define I915_WRITE16_NOTRACE(reg, val) 
> dev_priv->uncore.funcs.mmio_writew(dev_priv, (reg), (val), false)
>
> +DECLARE_PER_CPU(uint32_t, i915_last_written);
>  #define I915_READ(reg) dev_priv->uncore.funcs.mmio_readl(dev_priv, 
> (reg), true)
> -#define I915_WRITE(reg, val)   dev_priv->uncore.funcs.mmio_writel(dev_priv, 
> (reg), (val), true)
> +#define I915_WRITE(reg, val)   do {  
>   \
> +   dev_priv->uncore.funcs.mmio_writel(dev_priv, (reg), (val), true); 
>   \
> +   raw_cpu_write(i915_last_written, reg);
>   \
> +} while (0)
>  #define I915_READ_NOTRACE(reg) 
> dev_priv->uncore.funcs.mmio_readl(dev_priv, (reg), false)
> -#define I915_WRITE_NOTRACE(reg, val)   
> dev_priv->uncore.funcs.mmio_writel(dev_priv, (reg), (val), false)
> +#define I915_WRITE_NOTRACE(reg, val)   do {  
>   \
> +   dev_priv->uncore.funcs.mmio_writel(dev_priv, (reg), (val), false);
>   \
> +   raw_cpu_write(i915_last_written, reg);
>   \
> +} while (0)
>
>  /* Be very careful with read/write 64-bit values. On 32-bit machines, they
>   * will be implemented using 2 32-bit writes in an arbitrary order with
> diff --git a/drivers/gpu/drm/i915/intel_uncore.c 
> b/drivers/gpu/drm/i915/intel_uncore.c
> index b29091b..001ce55 100644
> --- a/drivers/gpu/drm/i915/intel_uncore.c
> +++ b/drivers/gpu/drm/i915/intel_uncore.c
> @@ -33,7 +33,10 @@
>  #define __raw_i915_write16(dev_priv__, reg__, val__) writew(val__, 
> (dev_priv__)->regs + (reg__))
>
>  #define __raw_i915_read32(dev_priv__, reg__) readl((dev_priv__)->regs + 
> (reg__))
> -#define __raw_i915_write32(dev_priv__, reg__, val__) writel(val__, 
> (dev_priv__)->regs + (reg__))
> +#define __raw_i915_write32(dev_priv__, reg__, val__) do { \
> +   writel(val__, (dev_priv__)->regs + (reg__));  \
> +   raw_cpu_write(i915_last_written, reg__);  \
> +} while (0)
>
>  #define __raw_i915_read64(dev_priv__, reg__) readq((dev_priv__)->regs + 
> (reg__))
>  #define __raw_i915_write64(dev_priv__, reg__, val__) writeq(val__, 
> (dev_priv__)->regs + (reg__))
> @@ -513,6 +516,7 @@ ilk_dummy_write(struct drm_i915_private *dev_priv)
> __raw_i915_write32(dev_priv

Re: [Intel-gfx] [PATCH 1/2] drm/i915: Track last register written (debug)

2015-02-20 Thread Chris Wilson
On Fri, Feb 20, 2015 at 09:55:09AM -0200, Paulo Zanoni wrote:
> 2015-02-20 3:33 GMT-02:00 Ben Widawsky :
> > Register writes are supposed to be posted, and therefore "fast." In order 
> > to try
> > to preserve this behavior, the patch uses percpu variables to make the 
> > overhead
> > minimal. The slow data collection is done at error time, and that only 
> > occurs if
> > the user specified mmio_debug=1 module parameter.
> >
> > I wrote this patch to try to track down annoying and sporadic errors on my
> > Broadwell laptop. Sometimes it's obvious how you got to this point from the
> > backtrace, but other times it isn't.
> >
> 
> Register reads can also trigger the unclaimed register error. Don't
> you want to also record the last one we read on each CPU too?
> 
> Also, just to remind you since you seem to be debugging something:
> user space programs (such as intel_reg_dumper or anything else) and
> other Kernel modules (like vgacon and others) can also trigger these
> errors, and we can't easily catch these cases.
> 
> Pinging Chris since he always has some ideas about this code.

In this case it is probably better to look at the automatic oneshot
mmio_debug patch.
-Chris

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


Re: [Intel-gfx] [PATCH 2/2] drm/i915: Add the last written reg to error state

2015-02-20 Thread Chris Wilson
At first glance, this is interesting. On reflection I think I still only
care about the register values at the time of the error. Otherwise, I
would rather have the last few registers written - and only those of the
interesting set as defined by the error state - their values and when.
We would also then require the timestamp of batch execution to marry with
the register updates if we suspect them of causing GPU hangs.
-Chris

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


Re: [Intel-gfx] [PATCH 2/2] drm/i915: Add the last written reg to error state

2015-02-20 Thread shuang . he
Tested-By: PRC QA PRTS (Patch Regression Test System Contact: 
shuang...@intel.com)
Task id: 5799
-Summary-
Platform  Delta  drm-intel-nightly  Series Applied
PNV -2  277/277  275/277
ILK  313/313  313/313
SNB -1  309/309  308/309
IVB  382/382  382/382
BYT  296/296  296/296
HSW -1  425/425  424/425
BDW -1  318/318  317/318
-Detailed-
Platform  Testdrm-intel-nightly  Series 
Applied
 PNV  igt_gem_userptr_blits_coherency-sync  
NO_RESULT(1)CRASH(5)NRUN(1)PASS(6)  CRASH(2)
 PNV  igt_gem_userptr_blits_coherency-unsync  CRASH(3)NRUN(1)PASS(4)  
CRASH(2)
*SNB  igt_kms_plane_plane-panning-top-left-pipe-B-plane-2  PASS(2)  
TIMEOUT(1)PASS(1)
*HSW  igt_gem_storedw_batches_loop_secure-dispatch  PASS(2)  
DMESG_WARN(1)PASS(1)
*BDW  igt_gem_gtt_hog  PASS(17)  DMESG_WARN(1)PASS(1)
Note: You need to pay more attention to line start with '*'
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH 6/6] drm/i915: Add debugfs entry for DRRS

2015-02-20 Thread Ramalingam C

Hi,

On Friday 20 February 2015 12:15 AM, Rodrigo Vivi wrote:

On Fri, Feb 13, 2015 at 2:03 AM, Ramalingam C  wrote:

From: Vandana Kannan 

Adding a debugfs entry to determine if DRRS is supported or not

V2: [By Ram]: Following details about the active crtc will be filled
 in seq-file of the debugfs
 1. Encoder output type
 2. DRRS Support on this CRTC
 3. DRRS current state
 4. Current Vrefresh
Format is as follows:
CRTC 1:  Output: eDP, DRRS Supported: Yes (Seamless), DRRS_State: DRRS_HIGH_RR, 
Vrefresh: 60
CRTC 2:  Output: HDMI, DRRS Supported : No, VBT DRRS_type: Seamless
CRTC 1:  Output: eDP, DRRS Supported: Yes (Seamless), DRRS_State: DRRS_LOW_RR, 
Vrefresh: 40
CRTC 2:  Output: HDMI, DRRS Supported : No, VBT DRRS_type: Seamless

V3: [By Ram]: Readability is improved.
 Another error case is covered [Daniel]

V4: [By Ram]: Current status of the Idleness DRRS along with
 the Front buffer bits are added to the debugfs. [Rodrigo]

Signed-off-by: Vandana Kannan 
Signed-off-by: Ramalingam C 
---
  drivers/gpu/drm/i915/i915_debugfs.c |   99 +++
  1 file changed, 99 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c 
b/drivers/gpu/drm/i915/i915_debugfs.c
index 164fa82..e08d63f 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -2869,6 +2869,104 @@ static int i915_ddb_info(struct seq_file *m, void 
*unused)
 return 0;
  }

+static void drrs_status_per_crtc(struct seq_file *m,
+   struct drm_device *dev, struct intel_crtc *intel_crtc)
+{
+   struct intel_encoder *intel_encoder;
+   struct drm_i915_private *dev_priv = dev->dev_private;
+   struct i915_drrs *drrs = &dev_priv->drrs;
+   int vrefresh = 0;
+
+   for_each_encoder_on_crtc(dev, &intel_crtc->base, intel_encoder) {
+   /* Encoder connected on this CRTC */

Do you really need this info here?

Better to have the encoder details



+   switch (intel_encoder->type) {
+   case INTEL_OUTPUT_EDP:
+   seq_puts(m, "Output: eDP, ");
+   break;
+   case INTEL_OUTPUT_DSI:
+   seq_puts(m, "Output: DSI, ");
+   break;
+   case INTEL_OUTPUT_HDMI:
+   seq_puts(m, "Output: HDMI, ");
+   break;
+   case INTEL_OUTPUT_DISPLAYPORT:
+   seq_puts(m, "Output: DP, ");
+   break;
+   default:
+   seq_printf(m, "Output: Others (id=%d), ",
+   intel_encoder->type);
+   }
+   }
+
+   if (intel_crtc->config->has_drrs) {
+   struct intel_panel *panel;
+
+   panel = &drrs->dp->attached_connector->panel;
+   /* DRRS Supported */
+   seq_puts(m, "DRRS Supported: Yes (Seamless), ");

isn't "Yes" enough? Remind that you might want to parse in the future.

Agreed. Yes alone will be simple.



+   seq_printf(m, "busy_frontbuffer_bits: 0x%X,\n\t",
+   drrs->busy_frontbuffer_bits);
+
+   if (drrs->busy_frontbuffer_bits) {
+   seq_puts(m, "Front buffer: busy, ");
+   seq_puts(m, "Idleness Timer: Suspended, ");
+   } else {
+   seq_puts(m, "Front buffer: Idle, ");
+   if (drrs->refresh_rate_type == DRRS_HIGH_RR)
+   seq_puts(m, "Idleness Timer: Ticking, ");
+   else
+   seq_puts(m, "Idleness Timer: Suspended, ");
+   }
+
+   if (drrs->refresh_rate_type == DRRS_HIGH_RR) {
+   seq_puts(m, "DRRS_State: DRRS_HIGH_RR, ");
+   vrefresh = panel->fixed_mode->vrefresh;
+   } else if (drrs->refresh_rate_type == DRRS_LOW_RR) {
+   seq_puts(m, "DRRS_State: DRRS_LOW_RR, ");
+   vrefresh = panel->downclock_mode->vrefresh;
+   } else {
+   seq_printf(m, "DRRS_State: Unknown(%d), ",
+   drrs->refresh_rate_type);
+   }

I wonder what it is printed when DRRS is supported but is disabled?
It will be printing as "Idleness Timer: Suspended". I will rename this 
to remove this confusions :)


Also why not print some info like enabled/disabled?

Sure we will do it.



+   seq_printf(m, "Vrefresh: %d", vrefresh);
+
+   } else {
+   /* DRRS not supported. Print the VBT parameter*/

Why? Should be better a dmesg when enabling DRRS and print why not supported?

Is VBT only reason for not being supported? Is is information useless
when drrs is supported?
VBT details and also the lower refresh rate from EDID both are 
co

Re: [Intel-gfx] [PATCH v4 09/24] drm/i915: Track GEN6 page table usage

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

> From: Ben Widawsky 
>
> Instead of implementing the full tracking + dynamic allocation, this
> patch does a bit less than half of the work, by tracking and warning on
> unexpected conditions. The tracking itself follows which PTEs within a
> page table are currently being used for objects. The next patch will
> modify this to actually allocate the page tables only when necessary.
>
> With the current patch there isn't much in the way of making a gen
> agnostic range allocation function. However, in the next patch we'll add
> more specificity which makes having separate functions a bit easier to
> manage.
>
> One important change introduced here is that DMA mappings are
> created/destroyed at the same page directories/tables are
> allocated/deallocated.
>
> Notice that aliasing PPGTT is not managed here. The patch which actually
> begins dynamic allocation/teardown explains the reasoning for this.
>
> v2: s/pdp.page_directory/pdp.page_directorys
> Make a scratch page allocation helper
>
> v3: Rebase and expand commit message.
>
> v4: Allocate required pagetables only when it is needed, _bind_to_vm
> instead of bind_vma (Daniel).
>
> v5: Rebased to remove the unnecessary noise in the diff, also:
>  - PDE mask is GEN agnostic, renamed GEN6_PDE_MASK to I915_PDE_MASK.
>  - Removed unnecessary checks in gen6_alloc_va_range.
>  - Changed map/unmap_px_single macros to use dma functions directly and
>be part of a static inline function instead.
>  - Moved drm_device plumbing through page tables operation to its own
>patch.
>  - Moved allocate/teardown_va_range calls until they are fully
>implemented (in subsequent patch).
>  - Merged pt and scratch_pt unmap_and_free path.
>  - Moved scratch page allocator helper to the patch that will use it.
>
> v6: Reduce complexity by not tearing down pagetables dynamically, the
> same can be achieved while freeing empty vms. (Daniel)
>
> Cc: Daniel Vetter 
> Signed-off-by: Ben Widawsky 
> Signed-off-by: Michel Thierry  (v3+)
> ---
>  drivers/gpu/drm/i915/i915_gem_gtt.c | 191 
> +---
>  drivers/gpu/drm/i915/i915_gem_gtt.h |  75 ++
>  2 files changed, 206 insertions(+), 60 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
> b/drivers/gpu/drm/i915/i915_gem_gtt.c
> index e2bcd10..760585e 100644
> --- a/drivers/gpu/drm/i915/i915_gem_gtt.c
> +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
> @@ -274,29 +274,88 @@ static gen6_gtt_pte_t iris_pte_encode(dma_addr_t addr,
>   return pte;
>  }
>  
> -static void unmap_and_free_pt(struct i915_page_table_entry *pt, struct 
> drm_device *dev)
> +#define i915_dma_unmap_single(px, dev) \
> + __i915_dma_unmap_single((px)->daddr, dev)
> +
> +static inline void __i915_dma_unmap_single(dma_addr_t daddr,
> + struct drm_device *dev)
> +{
> + struct device *device = &dev->pdev->dev;
> +
> + dma_unmap_page(device, daddr, 4096, PCI_DMA_BIDIRECTIONAL);
> +}
> +
> +/**
> + * i915_dma_map_px_single() - Create a dma mapping for a page table/dir/etc.
> + * @px:  Page table/dir/etc to get a DMA map for
> + * @dev: drm device
> + *
> + * Page table allocations are unified across all gens. They always require a
> + * single 4k allocation, as well as a DMA mapping. 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_px_single(px, dev) \
> + i915_dma_map_page_single((px)->page, (dev), &(px)->daddr)
> +

If this is symmetrical to i915_dma_unmap_single() is the _px_ needed?

> +static inline int i915_dma_map_page_single(struct page *page,
> +struct drm_device *dev,
> +dma_addr_t *daddr)
> +{
> + struct device *device = &dev->pdev->dev;
> +
> + *daddr = dma_map_page(device, page, 0, 4096, PCI_DMA_BIDIRECTIONAL);
> + return dma_mapping_error(device, *daddr);
> +}
> +
> +static void unmap_and_free_pt(struct i915_page_table_entry *pt,
> +struct drm_device *dev)
>  {
>   if (WARN_ON(!pt->page))
>   return;
> +
> + i915_dma_unmap_single(pt, dev);
>   __free_page(pt->page);
> + kfree(pt->used_ptes);
>   kfree(pt);
>  }
>  
>  static struct i915_page_table_entry *alloc_pt_single(struct drm_device *dev)
>  {
>   struct i915_page_table_entry *pt;
> + const size_t count = INTEL_INFO(dev)->gen >= 8 ?
> + GEN8_PTES_PER_PAGE : I915_PPGTT_PT_ENTRIES;
> + int ret = -ENOMEM;
>  
>   pt = kzalloc(sizeof(*pt), GFP_KERNEL);
>   if (!pt)
>   return ERR_PTR(-ENOMEM);
>  
> + pt->used_ptes = kcalloc(BITS_TO_LONGS(count), sizeof(*pt->used_ptes),
> + GFP_KERNEL);
> +
> + if (!pt->used_ptes)
> + goto fail_bitmap;
> +
>   pt->page = alloc_page(GFP_KERNEL | __GFP_ZERO);
> -

Re: [Intel-gfx] [PATCH v4 07/24] drm/i915: Create page table allocators

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

> From: Ben Widawsky 
>
> As we move toward dynamic page table allocation, it becomes much easier
> to manage our data structures if break do things less coarsely by
> breaking up all of our actions into individual tasks.  This makes the
> code easier to write, read, and verify.
>
> Aside from the dissection of the allocation functions, the patch
> statically allocates the page table structures without a page directory.
> This remains the same for all platforms,
>
> The patch itself should not have much functional difference. The primary
> noticeable difference is the fact that page tables are no longer
> allocated, but rather statically declared as part of the page directory.
> This has non-zero overhead, but things gain non-trivial complexity as a
> result.
>
> This patch exists for a few reasons:
> 1. Splitting out the functions allows easily combining GEN6 and GEN8
> code. Page tables have no difference based on GEN8. As we'll see in a
> future patch when we add the DMA mappings to the allocations, it
> requires only one small change to make work, and error handling should
> just fall into place.
>
> 2. Unless we always want to allocate all page tables under a given PDE,
> we'll have to eventually break this up into an array of pointers (or
> pointer to pointer).
>
> 3. Having the discrete functions is easier to review, and understand.
> All allocations and frees now take place in just a couple of locations.
> Reviewing, and catching leaks should be easy.
>
> 4. Less important: the GFP flags are confined to one location, which
> makes playing around with such things trivial.
>
> v2: Updated commit message to explain why this patch exists
>
> v3: For lrc, s/pdp.page_directory[i].daddr/pdp.page_directory[i]->daddr/
>
> v4: Renamed free_pt/pd_single functions to unmap_and_free_pt/pd (Daniel)
>
> v5: Added additional safety checks in gen8 clear/free/unmap.
>
> Signed-off-by: Ben Widawsky 
> Signed-off-by: Michel Thierry  (v3, v4, v5)
> ---
>  drivers/gpu/drm/i915/i915_gem_gtt.c | 251 
> 
>  drivers/gpu/drm/i915/i915_gem_gtt.h |   4 +-
>  drivers/gpu/drm/i915/intel_lrc.c|  16 +--
>  3 files changed, 179 insertions(+), 92 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
> b/drivers/gpu/drm/i915/i915_gem_gtt.c
> index 0fe5c1e..85ea535 100644
> --- a/drivers/gpu/drm/i915/i915_gem_gtt.c
> +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
> @@ -275,6 +275,99 @@ static gen6_gtt_pte_t iris_pte_encode(dma_addr_t addr,
>   return pte;
>  }
>  
> +static void unmap_and_free_pt(struct i915_page_table_entry *pt)
> +{
> + if (WARN_ON(!pt->page))
> + return;
> + __free_page(pt->page);
> + kfree(pt);
> +}
> +
> +static struct i915_page_table_entry *alloc_pt_single(void)
> +{
> + struct i915_page_table_entry *pt;
> +
> + pt = kzalloc(sizeof(*pt), GFP_KERNEL);
> + if (!pt)
> + return ERR_PTR(-ENOMEM);
> +
> + pt->page = alloc_page(GFP_KERNEL | __GFP_ZERO);
> + if (!pt->page) {
> + kfree(pt);
> + return ERR_PTR(-ENOMEM);
> + }
> +
> + return pt;
> +}
> +
> +/**
> + * alloc_pt_range() - Allocate a multiple page tables
> + * @pd:  The page directory which will have at least @count 
> entries
> + *   available to point to the allocated page tables.
> + * @pde: First page directory entry for which we are allocating.
> + * @count:   Number of pages to allocate.
> + *
> + * Allocates multiple page table pages and sets the appropriate entries in 
> the
> + * page table structure within the page directory. Function cleans up after
> + * itself on any failures.
> + *
> + * Return: 0 if allocation succeeded.
> + */
> +static int alloc_pt_range(struct i915_page_directory_entry *pd, uint16_t 
> pde, size_t count)
> +{
> + int i, ret;
> +
> + /* 512 is the max page tables per page_directory on any platform.
> +  * TODO: make WARN after patch series is done
> +  */
> + BUG_ON(pde + count > GEN6_PPGTT_PD_ENTRIES);
> +

WARN_ON in here and return -EINVAL.

-Mika

> + for (i = pde; i < pde + count; i++) {
> + struct i915_page_table_entry *pt = alloc_pt_single();
> +
> + if (IS_ERR(pt)) {
> + ret = PTR_ERR(pt);
> + goto err_out;
> + }
> + WARN(pd->page_tables[i],
> +  "Leaking page directory entry %d (%pa)\n",
> +  i, pd->page_tables[i]);
> + pd->page_tables[i] = pt;
> + }
> +
> + return 0;
> +
> +err_out:
> + while (i--)
> + unmap_and_free_pt(pd->page_tables[i]);
> + return ret;
> +}
> +
> +static void unmap_and_free_pd(struct i915_page_directory_entry *pd)
> +{
> + if (pd->page) {
> + __free_page(pd->page);
> + kfree(pd);
> + }
> +}
> +
> +static struct i915_page_directory_entry *alloc_pd_single(void)
> +{
> + struct i915_page_directory_

Re: [Intel-gfx] [PATCH 11/17] drm/i915: Update the EDID automated compliance test function

2015-02-20 Thread Daniel Vetter
Readding intel-gfx.

On Wed, Feb 18, 2015 at 5:57 PM, Todd Previte  wrote:
> On 12/17/14 1:20 PM, Daniel Vetter wrote:
>> Just something random I've spotted while driving by: drm_get_edid does all
>> the checksum stuff for you already (it retries up to 4 times if the
>> checkusm is off and also checks a few other things). We should never reach
>> this case and the checksum function is essentially dead code.
>>
>> Or do I miss something?
>> -Daniel
>>
>
> The data I have is that when connected to the DPR-100, the logs show that
> the EDID checksum is incorrect from the DRM routines, which is why I went
> and wrote this one. This is most likely a problem with the DPR-100 (that
> they won't fix since they're not updating it anymore) and possibly still a
> problem with the DPR-120 (which I can't test because I don't have one). So
> this code is necessary in order to pass the EDID tests when using the
> DPR-100.
>
> That said, it's also unlikely that the DRM routines are wholly wrong, since
> that would result in many, many errors in the logs for all the shipping DP
> monitors out there. So this is one case where special code is necessary in
> order to pass the tests with a particular test device.

If that's the case then we need to add some quirks to the core edid
code (we have plenty of those already, shipping hw tends to be broken
in all sorts of interesting ways). At least I don't see a point in
passing compliance in such an important aspect as validating sink
behaviour by adding special-purpose code instead of the code we use
for real hw.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH] drm: Adding edp1.4 specific dpcd macros

2015-02-20 Thread Todd Previte


On 2/20/2015 1:25 AM, Jani Nikula wrote:

On Thu, 19 Feb 2015, Todd Previte  wrote:

Just some formatting issues that need to be cleaned up. Otherwise the
definitions look correct according to the eDP 1.4 spec.

Actually the formatting seems to be in line with the rest of that
particular file.

BR,
Jani.
Interesting. Looks like there's some inconsistency in that header then. 
But if the formatting isn't an issue, it's otherwise correct.


Reviewed-by: Todd Previte 


-T

On 2/19/15 12:46 AM, Sonika Jindal wrote:

Adding dpcd macros related to edp1.4 and link rates

v2: Added DP_SUPPORTED_LINK_RATES macros

Signed-off-by: Sonika Jindal 
---
   include/drm/drm_dp_helper.h |8 
   1 file changed, 8 insertions(+)

diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h
index 11f8c84..77a55e2 100644
--- a/include/drm/drm_dp_helper.h
+++ b/include/drm/drm_dp_helper.h
@@ -92,6 +92,9 @@
   # define DP_MSA_TIMING_PAR_IGNORED   (1 << 6) /* eDP */
   # define DP_OUI_SUPPORT  (1 << 7)

+#define DP_SUPPORTED_LINK_RATES0x010 /*eDP 1.4*/
+#define DP_MAX_SUPPORTED_RATES 0x8
+

Extra blank line

   #define DP_I2C_SPEED_CAP 0x00c/* DPI */
   # define DP_I2C_SPEED_1K 0x01
   # define DP_I2C_SPEED_5K 0x02
@@ -101,6 +104,7 @@
   # define DP_I2C_SPEED_1M 0x20

   #define DP_EDP_CONFIGURATION_CAP0x00d   /* XXX 1.2? */
+# define DP_DPCD_DISPLAY_CONTROL_CAPABLE (1 << 3) /* edp v1.2 or higher */

Remove the space between # and define.

   #define DP_TRAINING_AUX_RD_INTERVAL 0x00e   /* XXX 1.2? */

   /* Multiple stream transport */
@@ -221,6 +225,8 @@
   # define DP_UP_REQ_EN(1 << 1)
   # define DP_UPSTREAM_IS_SRC  (1 << 2)

+#define DP_LINK_RATE_SET   0x115
+

Extra blank line

   #define DP_PSR_EN_CFG0x170   /* XXX 1.2? */
   # define DP_PSR_ENABLE   (1 << 0)
   # define DP_PSR_MAIN_LINK_ACTIVE (1 << 1)
@@ -332,6 +338,8 @@
   # define DP_SET_POWER_D30x2
   # define DP_SET_POWER_MASK  0x3

+#define DP_EDP_DPCD_REV  0x700
+

Extra blank line

   #define DP_SIDEBAND_MSG_DOWN_REQ_BASE0x1000   /* 1.2 MST */
   #define DP_SIDEBAND_MSG_UP_REP_BASE  0x1200   /* 1.2 MST */
   #define DP_SIDEBAND_MSG_DOWN_REP_BASE0x1400   /* 1.2 MST */

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


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


[Intel-gfx] [PATCH 07/12] drm/i915/bdw: Support 64 bit PPGTT in lrc mode

2015-02-20 Thread Michel Thierry
In 64b (48bit canonical) PPGTT addressing, the PDP0 register contains
the base address to PML4, while the other PDP registers are ignored.

Also, the addressing mode must be specified in every context descriptor.

Signed-off-by: Michel Thierry 
---
 drivers/gpu/drm/i915/intel_lrc.c | 167 ++-
 1 file changed, 114 insertions(+), 53 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
index f461631..2b6d262 100644
--- a/drivers/gpu/drm/i915/intel_lrc.c
+++ b/drivers/gpu/drm/i915/intel_lrc.c
@@ -255,7 +255,8 @@ 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 drm_i915_gem_object *ctx_obj,
+bool legacy_64bit_ctx)
 {
struct drm_device *dev = ring->dev;
uint64_t desc;
@@ -264,7 +265,10 @@ 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;
+   if (legacy_64bit_ctx)
+   desc |= LEGACY_64B_CONTEXT << GEN8_CTX_MODE_SHIFT;
+   else
+   desc |= LEGACY_CONTEXT << GEN8_CTX_MODE_SHIFT;
desc |= GEN8_CTX_L3LLC_COHERENT;
desc |= GEN8_CTX_PRIVILEGE;
desc |= lrca;
@@ -292,16 +296,17 @@ static void execlists_elsp_write(struct intel_engine_cs 
*ring,
struct drm_i915_private *dev_priv = dev->dev_private;
uint64_t temp = 0;
uint32_t desc[4];
+   bool legacy_64bit_ctx = USES_FULL_48BIT_PPGTT(dev);
 
/* XXX: You must always write both descriptors in the order below. */
if (ctx_obj1)
-   temp = execlists_ctx_descriptor(ring, ctx_obj1);
+   temp = execlists_ctx_descriptor(ring, ctx_obj1, 
legacy_64bit_ctx);
else
temp = 0;
desc[1] = (u32)(temp >> 32);
desc[0] = (u32)temp;
 
-   temp = execlists_ctx_descriptor(ring, ctx_obj0);
+   temp = execlists_ctx_descriptor(ring, ctx_obj0, legacy_64bit_ctx);
desc[3] = (u32)(temp >> 32);
desc[2] = (u32)temp;
 
@@ -332,37 +337,60 @@ static int execlists_update_context(struct 
drm_i915_gem_object *ctx_obj,
reg_state[CTX_RING_TAIL+1] = tail;
reg_state[CTX_RING_BUFFER_START+1] = i915_gem_obj_ggtt_offset(ring_obj);
 
-   /* True PPGTT with dynamic page allocation: update PDP registers and
-* point the unallocated PDPs to the scratch page
-*/
-   if (ppgtt) {
+   if (ppgtt && USES_FULL_48BIT_PPGTT(ppgtt->base.dev)) {
+   /* True 64b PPGTT (48bit canonical)
+* PDP0_DESCRIPTOR contains the base address to PML4 and
+* other PDP Descriptors are ignored
+*/
+   reg_state[CTX_PDP0_UDW+1] = upper_32_bits(ppgtt->pml4.daddr);
+   reg_state[CTX_PDP0_LDW+1] = lower_32_bits(ppgtt->pml4.daddr);
+   } else if (ppgtt) {
+   /* True 32b PPGTT with dynamic page allocation: update PDP
+* registers and point the unallocated PDPs to the scratch page
+*/
if (test_bit(3, ppgtt->pdp.used_pdpes)) {
-   reg_state[CTX_PDP3_UDW+1] = 
upper_32_bits(ppgtt->pdp.page_directory[3]->daddr);
-   reg_state[CTX_PDP3_LDW+1] = 
lower_32_bits(ppgtt->pdp.page_directory[3]->daddr);
+   reg_state[CTX_PDP3_UDW+1] =
+   
upper_32_bits(ppgtt->pdp.page_directory[3]->daddr);
+   reg_state[CTX_PDP3_LDW+1] =
+   
lower_32_bits(ppgtt->pdp.page_directory[3]->daddr);
} else {
-   reg_state[CTX_PDP3_UDW+1] = 
upper_32_bits(ppgtt->scratch_pd->daddr);
-   reg_state[CTX_PDP3_LDW+1] = 
lower_32_bits(ppgtt->scratch_pd->daddr);
+   reg_state[CTX_PDP3_UDW+1] =
+   upper_32_bits(ppgtt->scratch_pd->daddr);
+   reg_state[CTX_PDP3_LDW+1] =
+   lower_32_bits(ppgtt->scratch_pd->daddr);
}
if (test_bit(2, ppgtt->pdp.used_pdpes)) {
-   reg_state[CTX_PDP2_UDW+1] = 
upper_32_bits(ppgtt->pdp.page_directory[2]->daddr);
-   reg_state[CTX_PDP2_LDW+1] = 
lower_32_bits(ppgtt->pdp.page_directory[2]->daddr);
+   reg_state[CTX_PDP2_UDW+1] =
+   
upper_32_bits(ppgtt->pdp.page_directory[2]->daddr);
+   reg_state[CTX_PDP2_LDW+1] =
+   
lower_32_bits(ppgtt->pdp.page_directory[2]->daddr);
} else {
-

[Intel-gfx] [PATCH 02/12] drm/i915/bdw: Abstract PDP usage

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

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

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

v2: Updated after dynamic page allocation changes.

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

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

[Intel-gfx] [PATCH 03/12] drm/i915/bdw: Add dynamic page trace events

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

The dynamic page allocation patch series added it for GEN6, this patch
adds them for GEN8.

v2: Consolidate pagetable/page_directory events
v3: Multiple rebases.

Signed-off-by: Ben Widawsky 
Signed-off-by: Michel Thierry  (v3)
---
 drivers/gpu/drm/i915/i915_gem_gtt.c | 23 +++
 drivers/gpu/drm/i915/i915_trace.h   | 16 
 2 files changed, 31 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/i915_gem_gtt.c
index d3ad517..ecfb62a 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -673,19 +673,24 @@ static void __gen8_do_map_pt(gen8_ppgtt_pde_t * const pde,
 /* It's likely we'll map more than one pagetable at a time. This function will
  * save us unnecessary kmap calls, but do no more functionally than multiple
  * calls to map_pt. */
-static void gen8_map_pagetable_range(struct i915_page_directory_entry *pd,
+static void gen8_map_pagetable_range(struct i915_address_space *vm,
+struct i915_page_directory_entry *pd,
 uint64_t start,
-uint64_t length,
-struct drm_device *dev)
+uint64_t length)
 {
gen8_ppgtt_pde_t * const page_directory = kmap_atomic(pd->page);
struct i915_page_table_entry *pt;
uint64_t temp, pde;
 
-   gen8_for_each_pde(pt, pd, start, length, temp, pde)
-   __gen8_do_map_pt(page_directory + pde, pt, dev);
+   gen8_for_each_pde(pt, pd, start, length, temp, pde) {
+   __gen8_do_map_pt(page_directory + pde, pt, vm->dev);
+   trace_i915_page_table_entry_map(vm, pde, pt,
+gen8_pte_index(start),
+gen8_pte_count(start, length),
+GEN8_PTES_PER_PAGE);
+   }
 
-   if (!HAS_LLC(dev))
+   if (!HAS_LLC(vm->dev))
drm_clflush_virt_range(page_directory, PAGE_SIZE);
 
kunmap_atomic(page_directory);
@@ -815,6 +820,7 @@ static int gen8_ppgtt_alloc_pagetabs(struct 
i915_address_space *vm,
 
pd->page_tables[pde] = pt;
set_bit(pde, new_pts);
+   trace_i915_page_table_entry_alloc(vm, pde, start, 
GEN8_PDE_SHIFT);
}
 
return 0;
@@ -876,6 +882,7 @@ static int gen8_ppgtt_alloc_page_directories(struct 
i915_address_space *vm,
 
pdp->page_directory[pdpe] = pd;
set_bit(pdpe, new_pds);
+   trace_i915_page_directory_entry_alloc(vm, pdpe, start, 
GEN8_PDPE_SHIFT);
}
 
return 0;
@@ -1014,7 +1021,7 @@ static int gen8_alloc_va_range_3lvl(struct 
i915_address_space *vm,
}
 
set_bit(pdpe, pdp->used_pdpes);
-   gen8_map_pagetable_range(pd, start, length, dev);
+   gen8_map_pagetable_range(vm, pd, start, length);
}
 
free_gen8_temp_bitmaps(new_page_dirs, new_page_tables, pdpes);
@@ -1115,7 +1122,7 @@ static int gen8_aliasing_ppgtt_init(struct i915_hw_ppgtt 
*ppgtt)
}
 
gen8_for_each_pdpe(pd, pdp, start, size, temp, pdpe)
-   gen8_map_pagetable_range(pd, start, size, dev);
+   gen8_map_pagetable_range(&ppgtt->base, pd,start, size);
 
ppgtt->base.allocate_va_range = NULL;
ppgtt->base.clear_range = gen8_ppgtt_clear_range;
diff --git a/drivers/gpu/drm/i915/i915_trace.h 
b/drivers/gpu/drm/i915/i915_trace.h
index 3a657e4..6c20f76 100644
--- a/drivers/gpu/drm/i915/i915_trace.h
+++ b/drivers/gpu/drm/i915/i915_trace.h
@@ -214,6 +214,22 @@ DEFINE_EVENT(i915_page_table_entry, 
i915_page_table_entry_alloc,
 TP_ARGS(vm, pde, start, pde_shift)
 );
 
+DEFINE_EVENT_PRINT(i915_page_table_entry, i915_page_directory_entry_alloc,
+  TP_PROTO(struct i915_address_space *vm, u32 pdpe, u64 start, 
u64 pdpe_shift),
+  TP_ARGS(vm, pdpe, start, pdpe_shift),
+
+  TP_printk("vm=%p, pdpe=%d (0x%llx-0x%llx)",
+__entry->vm, __entry->pde, __entry->start, 
__entry->end)
+);
+
+DEFINE_EVENT_PRINT(i915_page_table_entry, 
i915_page_directory_pointer_entry_alloc,
+  TP_PROTO(struct i915_address_space *vm, u32 pml4e, u64 
start, u64 pml4e_shift),
+  TP_ARGS(vm, pml4e, start, pml4e_shift),
+
+  TP_printk("vm=%p, pml4e=%d (0x%llx-0x%llx)",
+__entry->vm, __entry->pde, __entry->start, 
__entry->end)
+);
+
 /* Avoid extra math because we only support two sizes. The format is defined by
  * bitmap_scnprintf. Each 32 bits is 8 HEX digits followed by comma */
 #define TRACE_PT_SIZE(bits) \
-- 
2.1.1

___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.or

[Intel-gfx] [PATCH 10/12] drm/i915/bdw: Add 4 level support in insert_entries and clear_range

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

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

Also add a scratch page for PML4.

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

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

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

[Intel-gfx] [PATCH 08/12] drm/i915/bdw: Generalize PTE writing for GEN8 PPGTT

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

The insert_entries function was the function used to write PTEs. For the
PPGTT it was "hardcoded" to only understand two level page tables, which
was the case for GEN7. We can reuse this for 4 level page tables, and
remove the concept of insert_entries, which was never viable past 2
level page tables anyway, but it requires a bit of rework to make the
function a bit more generic.

This patch begins the generalization work, and it will be heavily used
upon when the 48b code is complete. The patch series attempts to make
each function which touches a part of code specific to the page table
level and here is no exception. Having extra variables (such as the
PPGTT) distracts and provides room to add bugs since the function
shouldn't be touching anything in the higher order page tables.

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

diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/i915_gem_gtt.c
index fb06f67..fcfcb00 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -619,23 +619,19 @@ static int gen8_48b_mm_switch(struct i915_hw_ppgtt *ppgtt,
return gen8_write_pdp(ring, 0, ppgtt->pml4.daddr);
 }
 
-static void gen8_ppgtt_clear_range(struct i915_address_space *vm,
-  uint64_t start,
-  uint64_t length,
-  bool use_scratch)
+static void gen8_ppgtt_clear_pte_range(struct 
i915_page_directory_pointer_entry *pdp,
+  uint64_t start,
+  uint64_t length,
+  gen8_gtt_pte_t scratch_pte,
+  const bool flush)
 {
-   struct i915_hw_ppgtt *ppgtt =
-   container_of(vm, struct i915_hw_ppgtt, base);
-   struct i915_page_directory_pointer_entry *pdp = &ppgtt->pdp; /* FIXME: 
48b */
-   gen8_gtt_pte_t *pt_vaddr, scratch_pte;
+   gen8_gtt_pte_t *pt_vaddr;
unsigned pdpe = start >> GEN8_PDPE_SHIFT & GEN8_PDPE_MASK;
unsigned pde = start >> GEN8_PDE_SHIFT & GEN8_PDE_MASK;
unsigned pte = start >> GEN8_PTE_SHIFT & GEN8_PTE_MASK;
unsigned num_entries = length >> PAGE_SHIFT;
unsigned last_pte, i;
 
-   scratch_pte = gen8_pte_encode(ppgtt->base.scratch.addr,
- I915_CACHE_LLC, use_scratch);
 
while (num_entries) {
struct i915_page_directory_entry *pd;
@@ -668,7 +664,7 @@ static void gen8_ppgtt_clear_range(struct 
i915_address_space *vm,
num_entries--;
}
 
-   if (!HAS_LLC(ppgtt->base.dev))
+   if (flush)
drm_clflush_virt_range(pt_vaddr, PAGE_SIZE);
kunmap_atomic(pt_vaddr);
 
@@ -680,14 +676,27 @@ static void gen8_ppgtt_clear_range(struct 
i915_address_space *vm,
}
 }
 
-static void gen8_ppgtt_insert_entries(struct i915_address_space *vm,
- struct sg_table *pages,
- uint64_t start,
- enum i915_cache_level cache_level, u32 
unused)
+static void gen8_ppgtt_clear_range(struct i915_address_space *vm,
+  uint64_t start,
+  uint64_t length,
+  bool use_scratch)
 {
struct i915_hw_ppgtt *ppgtt =
container_of(vm, struct i915_hw_ppgtt, base);
struct i915_page_directory_pointer_entry *pdp = &ppgtt->pdp; /* FIXME: 
48b */
+
+   gen8_gtt_pte_t scratch_pte = gen8_pte_encode(ppgtt->base.scratch.addr,
+I915_CACHE_LLC, 
use_scratch);
+
+   gen8_ppgtt_clear_pte_range(pdp, start, length, scratch_pte, 
!HAS_LLC(vm->dev));
+}
+
+static void gen8_ppgtt_insert_pte_entries(struct 
i915_page_directory_pointer_entry *pdp,
+ struct sg_table *pages,
+ uint64_t start,
+ enum i915_cache_level cache_level,
+ const bool flush)
+{
gen8_gtt_pte_t *pt_vaddr;
unsigned pdpe = start >> GEN8_PDPE_SHIFT & GEN8_PDPE_MASK;
unsigned pde = start >> GEN8_PDE_SHIFT & GEN8_PDE_MASK;
@@ -709,7 +718,7 @@ static void gen8_ppgtt_insert_entries(struct 
i915_address_space *vm,
gen8_pte_encode(sg_page_iter_dma_address(&sg_iter),
cache_level, true);
if (++pte == GEN8_PTES_PER_PAGE) {
-   if (!HAS_LLC(ppgtt->base.dev))
+   if (flush)
drm_clflush_virt_range(pt

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

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

Aliasing PPGTT remains 32b only.

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

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

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


[Intel-gfx] [PATCH 09/12] drm/i915: Plumb sg_iter through va allocation ->maps

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

As a step towards implementing 4 levels, while not discarding the
existing pte map functions, we need to pass the sg_iter through. The
current function understands to the page directory granularity. An
object's pages may span the page directory, and so using the iter
directly as we write the PTEs allows the iterator to stay coherent
through a VMA mapping operation spanning multiple page table levels.

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

diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/i915_gem_gtt.c
index fcfcb00..a1396cb 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -692,7 +692,7 @@ static void gen8_ppgtt_clear_range(struct 
i915_address_space *vm,
 }
 
 static void gen8_ppgtt_insert_pte_entries(struct 
i915_page_directory_pointer_entry *pdp,
- struct sg_table *pages,
+ struct sg_page_iter *sg_iter,
  uint64_t start,
  enum i915_cache_level cache_level,
  const bool flush)
@@ -701,11 +701,10 @@ static void gen8_ppgtt_insert_pte_entries(struct 
i915_page_directory_pointer_ent
unsigned pdpe = start >> GEN8_PDPE_SHIFT & GEN8_PDPE_MASK;
unsigned pde = start >> GEN8_PDE_SHIFT & GEN8_PDE_MASK;
unsigned pte = start >> GEN8_PTE_SHIFT & GEN8_PTE_MASK;
-   struct sg_page_iter sg_iter;
 
pt_vaddr = NULL;
 
-   for_each_sg_page(pages->sgl, &sg_iter, pages->nents, 0) {
+   while (__sg_page_iter_next(sg_iter)) {
if (pt_vaddr == NULL) {
struct i915_page_directory_entry *pd = 
pdp->page_directory[pdpe];
struct i915_page_table_entry *pt = pd->page_tables[pde];
@@ -715,7 +714,7 @@ static void gen8_ppgtt_insert_pte_entries(struct 
i915_page_directory_pointer_ent
}
 
pt_vaddr[pte] =
-   gen8_pte_encode(sg_page_iter_dma_address(&sg_iter),
+   gen8_pte_encode(sg_page_iter_dma_address(sg_iter),
cache_level, true);
if (++pte == GEN8_PTES_PER_PAGE) {
if (flush)
@@ -744,8 +743,10 @@ static void gen8_ppgtt_insert_entries(struct 
i915_address_space *vm,
 {
struct i915_hw_ppgtt *ppgtt = container_of(vm, struct i915_hw_ppgtt, 
base);
struct i915_page_directory_pointer_entry *pdp = &ppgtt->pdp; /* FIXME: 
48b */
+   struct sg_page_iter sg_iter;
 
-   gen8_ppgtt_insert_pte_entries(pdp, pages, start, cache_level, 
!HAS_LLC(vm->dev));
+   __sg_page_iter_start(&sg_iter, pages->sgl, sg_nents(pages->sgl), 0);
+   gen8_ppgtt_insert_pte_entries(pdp, &sg_iter, start, cache_level, 
!HAS_LLC(vm->dev));
 }
 
 static void __gen8_do_map_pt(gen8_ppgtt_pde_t * const pde,
@@ -1107,10 +1108,12 @@ err_out:
return -ENOMEM;
 }
 
-static int gen8_alloc_va_range_3lvl(struct i915_address_space *vm,
-   struct i915_page_directory_pointer_entry 
*pdp,
-   uint64_t start,
-   uint64_t length)
+static int __gen8_alloc_vma_range_3lvl(struct i915_address_space *vm,
+  struct i915_page_directory_pointer_entry 
*pdp,
+  struct sg_page_iter *sg_iter,
+  uint64_t start,
+  uint64_t length,
+  u32 flags)
 {
unsigned long *new_page_dirs, **new_page_tables;
struct drm_device *dev = vm->dev;
@@ -1179,7 +1182,11 @@ static int gen8_alloc_va_range_3lvl(struct 
i915_address_space *vm,
   gen8_pte_index(pd_start),
   gen8_pte_count(pd_start, pd_len));
 
-   /* Our pde is now pointing to the pagetable, pt */
+   if (sg_iter) {
+   BUG_ON(!sg_iter->__nents);
+   gen8_ppgtt_insert_pte_entries(pdp, sg_iter, 
pd_start,
+ flags, 
!HAS_LLC(vm->dev));
+   }
set_bit(pde, pd->used_pdes);
}
 
@@ -1204,10 +1211,12 @@ err_out:
return ret;
 }
 
-static int gen8_alloc_va_range_4lvl(struct i915_address_space *vm,
-   struct i915_pml4 *pml4,
-   uint64_t start,
-   uint64_t length)
+static int __gen8_alloc_vma_range_4lvl(struct i915_address_space *vm,
+  str

[Intel-gfx] [PATCH 11/12] drm/i915: Expand error state's address width to 64b

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

v2: 0 pad the new 8B fields or else intel_error_decode has a hard time.
Note, regardless we need an igt update.

v3: Make reloc_offset 64b also.

Signed-off-by: Ben Widawsky 
Signed-off-by: Michel Thierry 
---
 drivers/gpu/drm/i915/i915_drv.h   |  4 ++--
 drivers/gpu/drm/i915/i915_gpu_error.c | 17 +
 2 files changed, 11 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index af0d149..056ced5 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -459,7 +459,7 @@ struct drm_i915_error_state {
 
struct drm_i915_error_object {
int page_count;
-   u32 gtt_offset;
+   u64 gtt_offset;
u32 *pages[0];
} *ringbuffer, *batchbuffer, *wa_batchbuffer, *ctx, *hws_page;
 
@@ -485,7 +485,7 @@ struct drm_i915_error_state {
u32 size;
u32 name;
u32 rseqno, wseqno;
-   u32 gtt_offset;
+   u64 gtt_offset;
u32 read_domains;
u32 write_domain;
s32 fence_reg:I915_MAX_NUM_FENCE_BITS;
diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c 
b/drivers/gpu/drm/i915/i915_gpu_error.c
index a982849..bbf25d0 100644
--- a/drivers/gpu/drm/i915/i915_gpu_error.c
+++ b/drivers/gpu/drm/i915/i915_gpu_error.c
@@ -195,7 +195,7 @@ static void print_error_buffers(struct 
drm_i915_error_state_buf *m,
err_printf(m, "  %s [%d]:\n", name, count);
 
while (count--) {
-   err_printf(m, "%08x %8u %02x %02x %x %x",
+   err_printf(m, "%016llx %8u %02x %02x %x %x",
   err->gtt_offset,
   err->size,
   err->read_domains,
@@ -415,7 +415,7 @@ int i915_error_state_to_str(struct drm_i915_error_state_buf 
*m,
err_printf(m, " (submitted by %s [%d])",
   error->ring[i].comm,
   error->ring[i].pid);
-   err_printf(m, " --- gtt_offset = 0x%08x\n",
+   err_printf(m, " --- gtt_offset = 0x%016llx\n",
   obj->gtt_offset);
print_error_obj(m, obj);
}
@@ -423,7 +423,8 @@ int i915_error_state_to_str(struct drm_i915_error_state_buf 
*m,
obj = error->ring[i].wa_batchbuffer;
if (obj) {
err_printf(m, "%s (w/a) --- gtt_offset = 0x%08x\n",
-  dev_priv->ring[i].name, obj->gtt_offset);
+  dev_priv->ring[i].name,
+  lower_32_bits(obj->gtt_offset));
print_error_obj(m, obj);
}
 
@@ -442,14 +443,14 @@ int i915_error_state_to_str(struct 
drm_i915_error_state_buf *m,
if ((obj = error->ring[i].ringbuffer)) {
err_printf(m, "%s --- ringbuffer = 0x%08x\n",
   dev_priv->ring[i].name,
-  obj->gtt_offset);
+  lower_32_bits(obj->gtt_offset));
print_error_obj(m, obj);
}
 
if ((obj = error->ring[i].hws_page)) {
err_printf(m, "%s --- HW Status = 0x%08x\n",
   dev_priv->ring[i].name,
-  obj->gtt_offset);
+  lower_32_bits(obj->gtt_offset));
offset = 0;
for (elt = 0; elt < PAGE_SIZE/16; elt += 4) {
err_printf(m, "[%04x] %08x %08x %08x %08x\n",
@@ -465,13 +466,13 @@ int i915_error_state_to_str(struct 
drm_i915_error_state_buf *m,
if ((obj = error->ring[i].ctx)) {
err_printf(m, "%s --- HW Context = 0x%08x\n",
   dev_priv->ring[i].name,
-  obj->gtt_offset);
+  lower_32_bits(obj->gtt_offset));
print_error_obj(m, obj);
}
}
 
if ((obj = error->semaphore_obj)) {
-   err_printf(m, "Semaphore page = 0x%08x\n", obj->gtt_offset);
+   err_printf(m, "Semaphore page = 0x%016llx\n", obj->gtt_offset);
for (elt = 0; elt < PAGE_SIZE/16; elt += 4) {
err_printf(m, "[%04x] %08x %08x %08x %08x\n",
   elt * 4,
@@ -571,7 +572,7 @@ i915_error_object_create(struct drm_i915_private *dev_priv,
int num_pages;
bool use_ggtt;
int i = 0;
-   u32 reloc_offset;
+   u64 reloc_offset;
 
if (src == NULL || src->pages == NULL)
return

[Intel-gfx] [PATCH 01/12] drm/i915/bdw: Make pdp allocation more dynamic

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

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

v2: Renamed  pdp_free to be similar to  pd/pt (unmap_and_free_pdp),
To facilitate testing, 48b mode will be available on Broadwell, when
i915.enable_ppgtt = 3.

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

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

[Intel-gfx] [PATCH 00/12] PPGTT with 48b addressing

2015-02-20 Thread Michel Thierry
These patches rely on "PPGTT dynamic page allocations", currently under review,
to provide GEN8 dynamic page table support with 64b addresses. As the review
progresses, these patches may be combined.

In order expand the GPU address space, a 4th level translation is added, the
Page Map Level 4 (PML4). This PML4 has 256 PML4 Entries (PML4E), PML4[0-255],
each pointing to a PDP.

For now, this feature will only be available in BDW, in LRC submission mode
(execlists) and when i915.enable_ppgtt=3 is set.
Also note that this expanded address space is only available for full PPGTT,
aliasing PPGTT remains 32b.

Ben Widawsky (9):
  drm/i915/bdw: Make pdp allocation more dynamic
  drm/i915/bdw: Abstract PDP usage
  drm/i915/bdw: Add dynamic page trace events
  drm/i915/bdw: Add ppgtt info for dynamic pages
  drm/i915/bdw: implement alloc/free for 4lvl
  drm/i915/bdw: Add 4 level switching infrastructure
  drm/i915/bdw: Generalize PTE writing for GEN8 PPGTT
  drm/i915: Plumb sg_iter through va allocation ->maps
  drm/i915: Expand error state's address width to 64b

Michel Thierry (3):
  drm/i915/bdw: Support 64 bit PPGTT in lrc mode
  drm/i915/bdw: Add 4 level support in insert_entries and clear_range
  drm/i915/bdw: Flip the 48b switch

 drivers/gpu/drm/i915/i915_debugfs.c   |  19 +-
 drivers/gpu/drm/i915/i915_drv.h   |  11 +-
 drivers/gpu/drm/i915/i915_gem_gtt.c   | 624 --
 drivers/gpu/drm/i915/i915_gem_gtt.h   |  77 -
 drivers/gpu/drm/i915/i915_gpu_error.c |  17 +-
 drivers/gpu/drm/i915/i915_params.c|   2 +-
 drivers/gpu/drm/i915/i915_reg.h   |   1 +
 drivers/gpu/drm/i915/i915_trace.h |  16 +
 drivers/gpu/drm/i915/intel_lrc.c  | 167 ++---
 9 files changed, 746 insertions(+), 188 deletions(-)

-- 
2.1.1

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


[Intel-gfx] [PATCH 05/12] drm/i915/bdw: implement alloc/free for 4lvl

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

The code for 4lvl works just as one would expect, and nicely it is able
to call into the existing 3lvl page table code to handle all of the
lower levels.

PML4 has no special attributes, and there will always be a PML4.
So simply initialize it at creation, and destroy it at the end.

v2: Return something at the end of gen8_alloc_va_range_4lvl to keep the
compiler happy. And define ret only in one place.
Updated gen8_ppgtt_unmap_pages and gen8_ppgtt_free to handle 4lvl.

Signed-off-by: Ben Widawsky 
Signed-off-by: Michel Thierry  (v2)
---
 drivers/gpu/drm/i915/i915_gem_gtt.c | 240 +++-
 drivers/gpu/drm/i915/i915_gem_gtt.h |  11 +-
 2 files changed, 217 insertions(+), 34 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 1edcc17..edada33 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -483,9 +483,12 @@ static void __pdp_fini(struct 
i915_page_directory_pointer_entry *pdp)
 static void unmap_and_free_pdp(struct i915_page_directory_pointer_entry *pdp,
struct drm_device *dev)
 {
-   __pdp_fini(pdp);
-   if (USES_FULL_48BIT_PPGTT(dev))
+   if (USES_FULL_48BIT_PPGTT(dev)) {
+   __pdp_fini(pdp);
+   i915_dma_unmap_single(pdp, dev);
+   __free_page(pdp->page);
kfree(pdp);
+   }
 }
 
 static int __pdp_init(struct i915_page_directory_pointer_entry *pdp,
@@ -511,6 +514,60 @@ static int __pdp_init(struct 
i915_page_directory_pointer_entry *pdp,
return 0;
 }
 
+static struct i915_page_directory_pointer_entry *alloc_pdp_single(struct 
i915_hw_ppgtt *ppgtt,
+  struct i915_pml4 *pml4)
+{
+   struct drm_device *dev = ppgtt->base.dev;
+   struct i915_page_directory_pointer_entry *pdp;
+   int ret;
+
+   BUG_ON(!USES_FULL_48BIT_PPGTT(dev));
+
+   pdp = kmalloc(sizeof(*pdp), GFP_KERNEL);
+   if (!pdp)
+   return ERR_PTR(-ENOMEM);
+
+   pdp->page = alloc_page(GFP_KERNEL | GFP_DMA32 | __GFP_ZERO);
+   if (!pdp->page) {
+   kfree(pdp);
+   return ERR_PTR(-ENOMEM);
+   }
+
+   ret = __pdp_init(pdp, dev);
+   if (ret) {
+   __free_page(pdp->page);
+   kfree(pdp);
+   return ERR_PTR(ret);
+   }
+
+   i915_dma_map_px_single(pdp, dev);
+
+   return pdp;
+}
+
+static void pml4_fini(struct i915_pml4 *pml4)
+{
+   struct i915_hw_ppgtt *ppgtt =
+   container_of(pml4, struct i915_hw_ppgtt, pml4);
+   i915_dma_unmap_single(pml4, ppgtt->base.dev);
+   __free_page(pml4->page);
+   /* HACK */
+   pml4->page = NULL;
+}
+
+static int pml4_init(struct i915_hw_ppgtt *ppgtt)
+{
+   struct i915_pml4 *pml4 = &ppgtt->pml4;
+
+   pml4->page = alloc_page(GFP_KERNEL | __GFP_ZERO);
+   if (!pml4->page)
+   return -ENOMEM;
+
+   i915_dma_map_px_single(pml4, ppgtt->base.dev);
+
+   return 0;
+}
+
 /* Broadwell Page Directory Pointer Descriptors */
 static int gen8_write_pdp(struct intel_engine_cs *ring,
  unsigned entry,
@@ -712,14 +769,13 @@ static void gen8_free_page_tables(struct 
i915_page_directory_entry *pd, struct d
}
 }
 
-static void gen8_ppgtt_unmap_pages(struct i915_hw_ppgtt *ppgtt)
+static void gen8_ppgtt_unmap_pages_3lvl(struct 
i915_page_directory_pointer_entry *pdp,
+   struct drm_device *dev)
 {
-   struct pci_dev *hwdev = ppgtt->base.dev->pdev;
-   struct i915_page_directory_pointer_entry *pdp = &ppgtt->pdp; /* FIXME: 
48b */
+   struct pci_dev *hwdev = dev->pdev;
int i, j;
 
-   for_each_set_bit(i, pdp->used_pdpes,
-   I915_PDPES_PER_PDP(ppgtt->base.dev)) {
+   for_each_set_bit(i, pdp->used_pdpes, I915_PDPES_PER_PDP(dev)) {
struct i915_page_directory_entry *pd;
 
if (WARN_ON(!pdp->page_directory[i]))
@@ -747,27 +803,73 @@ static void gen8_ppgtt_unmap_pages(struct i915_hw_ppgtt 
*ppgtt)
}
 }
 
-static void gen8_ppgtt_free(struct i915_hw_ppgtt *ppgtt)
+static void gen8_ppgtt_unmap_pages_4lvl(struct i915_hw_ppgtt *ppgtt)
 {
+   struct pci_dev *hwdev = ppgtt->base.dev->pdev;
int i;
 
-   if (!USES_FULL_48BIT_PPGTT(ppgtt->base.dev)) {
-   for_each_set_bit(i, ppgtt->pdp.used_pdpes,
-I915_PDPES_PER_PDP(ppgtt->base.dev)) {
-   if (WARN_ON(!ppgtt->pdp.page_directory[i]))
-   continue;
+   for_each_set_bit(i, ppgtt->pml4.used_pml4es, GEN8_PML4ES_PER_PML4) {
+   struct i915_page_directory_pointer_entry *pdp;
 
-   gen8_free_page_tables(ppgtt->pdp.page_directory[i],
- ppgtt->base.dev);
-   unmap_and_free_pd(

[Intel-gfx] [PATCH 04/12] drm/i915/bdw: Add ppgtt info for dynamic pages

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

Note that there is no gen8 ppgtt debug_dump function yet.

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

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

[Intel-gfx] [PATCH 06/12] drm/i915/bdw: Add 4 level switching infrastructure

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

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

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

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

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

Re: [Intel-gfx] [PATCH 2/6] drm/i915/bdw: Add support for DRRS to switch RR

2015-02-20 Thread Rodrigo Vivi
On Thu, Feb 19, 2015 at 10:15 PM, Ramalingam C  wrote:
> Hi,
>
>
> On Thursday 19 February 2015 10:55 PM, Rodrigo Vivi wrote:
>>
>> On Fri, Feb 13, 2015 at 2:03 AM, Ramalingam C 
>> wrote:
>>>
>>> From: Vandana Kannan 
>>>
>>> For Broadwell, there is one instance of Transcoder MN values per
>>> transcoder.
>>> For dynamic switching between multiple refreshr rates, M/N values may be
>>> reprogrammed on the fly. Link N programming triggers update of all data
>>> and
>>> link M & N registers and the new M/N values will be used in the next
>>> frame
>>> that is output.
>>>
>>> V2: [By Ram]: intel_dp_set_m_n() is rewritten to accommodate
>>>  gen >= 8 [Rodrigo]
>>> V3: Coding style correction [Ram]
>>> V4: [By Ram] intel_dp_set_m_n modifications are moved into a
>>>  separate patch, retaining only DRRS related changes here
>>> [Rodrigo]
>>>
>>> Signed-off-by: Vandana Kannan 
>>> Signed-off-by: Pradeep Bhat 
>>> Signed-off-by: Ramalingam C 
>>> ---
>>>   drivers/gpu/drm/i915/intel_dp.c |   16 ++--
>>>   1 file changed, 14 insertions(+), 2 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/i915/intel_dp.c
>>> b/drivers/gpu/drm/i915/intel_dp.c
>>> index 868a07b..6ffbf57 100644
>>> --- a/drivers/gpu/drm/i915/intel_dp.c
>>> +++ b/drivers/gpu/drm/i915/intel_dp.c
>>> @@ -4793,12 +4793,24 @@ static void intel_dp_set_drrs_state(struct
>>> drm_device *dev, int refresh_rate)
>>>  return;
>>>  }
>>>
>>> -   if (INTEL_INFO(dev)->gen > 6 && INTEL_INFO(dev)->gen < 8) {
>>> +   if (INTEL_INFO(dev)->gen >= 8) {
>>> +   switch (index) {
>>> +   case DRRS_HIGH_RR:
>>> +   intel_dp_set_m_n(intel_crtc, M1_N1);
>>> +   break;
>>> +   case DRRS_LOW_RR:
>>> +   intel_dp_set_m_n(intel_crtc, M2_N2);
>>> +   break;
>>> +   case DRRS_MAX_RR:
>>
>> Why to redirect this to an error insted making MAX = HIGH?
>
> This DRRS state is decided within kernel based on the vrefresh requested.
> Hence this can't be out of HIGH/LOW.
> So this case can't occur. If it occurs I would like to report it as an
> error.

Thanks for the explanation
Reviewed-by: Rodrigo Vivi 

>>
>>
>>> +   default:
>>> +   DRM_ERROR("Unsupported refreshrate type\n");
>>> +   }
>>> +   } else if (INTEL_INFO(dev)->gen > 6) {
>>>  reg = PIPECONF(intel_crtc->config->cpu_transcoder);
>>>  val = I915_READ(reg);
>>> +
>>>  if (index > DRRS_HIGH_RR) {
>>>  val |= PIPECONF_EDP_RR_MODE_SWITCH;
>>> -   intel_dp_set_m_n(intel_crtc);
>>>  } else {
>>>  val &= ~PIPECONF_EDP_RR_MODE_SWITCH;
>>>  }
>>> --
>>> 1.7.9.5
>>>
>>> ___
>>> Intel-gfx mailing list
>>> Intel-gfx@lists.freedesktop.org
>>> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
>>
>>
>>
>
> --
> Ram
>



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


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

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

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

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

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

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

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

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

diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 9073119..0dc0382 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -1889,6 +1889,9 @@ static irqreturn_t valleyview_irq_handler(int irq, void 
*arg)
u32 iir, gt_iir, pm_iir;
irqreturn_t ret = IRQ_NONE;
 
+   if (!intel_irqs_enabled(dev_priv))
+   return IRQ_NONE;
+
while (true) {
/* Find, clear, then process each source of interrupt */
 
@@ -1933,6 +1936,9 @@ static irqreturn_t cherryview_irq_handler(int irq, void 
*arg)
u32 master_ctl, iir;
irqreturn_t ret = IRQ_NONE;
 
+   if (!intel_irqs_enabled(dev_priv))
+   return IRQ_NONE;
+
for (;;) {
master_ctl = I915_READ(GEN8_MASTER_IRQ) & 
~GEN8_MASTER_IRQ_CONTROL;
iir = I915_READ(VLV_IIR);
@@ -2205,6 +2211,9 @@ static irqreturn_t ironlake_irq_handler(int irq, void 
*arg)
u32 de_iir, gt_iir, de_ier, sde_ier = 0;
irqreturn_t ret = IRQ_NONE;
 
+   if (!intel_irqs_enabled(dev_priv))
+   return IRQ_NONE;
+
/* We get interrupts on unclaimed registers, so check for this before we
 * do any I915_{READ,WRITE}. */
intel_uncore_check_errors(dev);
@@ -2276,6 +2285,9 @@ static irqreturn_t gen8_irq_handler(int irq, void *arg)
enum pipe pipe;
u32 aux_mask = GEN8_AUX_CHANNEL_A;
 
+   if (!intel_irqs_enabled(dev_priv))
+   return IRQ_NONE;
+
if (IS_GEN9(dev))
aux_mask |=  GEN9_AUX_CHANNEL_B | GEN9_AUX_CHANNEL_C |
GEN9_AUX_CHANNEL_D;
@@ -3768,6 +3780,9 @@ static irqreturn_t i8xx_irq_handler(int irq, void *arg)
I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT |
I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT;
 
+   if (!intel_irqs_enabled(dev_priv))
+   return IRQ_NONE;
+
iir = I915_READ16(IIR);
if (iir == 0)
return IRQ_NONE;
@@ -3948,6 +3963,9 @@ static irqreturn_t i915_irq_handler(int irq, void *arg)
I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT;
int pipe, ret = IRQ_NONE;
 
+   if (!intel_irqs_enabled(dev_priv))
+   return IRQ_NONE;
+
iir = I915_READ(IIR);
do {
bool irq_received = (iir & ~flip_mask) != 0;
@@ -4168,6 +4186,9 @@ static irqreturn_t i965_irq_handler(int irq, void *arg)
I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT |
I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT;
 
+   if (!intel_irqs_enabled(dev_priv))
+   return IRQ_NONE;
+
iir = I915_READ(IIR);
 
for (;;) {
@@ -4469,6 +4490,20 @@ void intel_hpd_init(struct drm_i915_private *dev_priv)
spin_unlock_irq(&dev_priv->irq_lock);
 }
 
+static void intel_irq_set_state(struct drm_i915_private *dev_priv,
+   bool enabled)
+{
+   dev_priv->pm.irqs_enabled = enabled;
+   /*
+* Before we unmask the interrupt or synchronize against it, make sure
+* that a corresponding interrupt handler running on another CPU sees
+* the updated irqs_enabled value.
+*/
+   smp_mb();
+   if (!enabled)
+   synchronize_irq(dev_priv->dev->irq);
+}
+
 /**
  * intel_irq_install - enables the hardware interrupt
  * @dev_priv: i915 device instance
@@ -4487,7 +4522,7 @@ int intel_irq_install(struct drm_i915_private *dev_priv)
 * interrupts as enabled _before_ actually enabling them to avoid
 * special cases in our ordering checks.
 */
-   dev_priv->pm.irqs_enabled = true;

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

2015-02-20 Thread Chris Wilson
On Fri, Feb 20, 2015 at 09:09:02PM +0200, Imre Deak wrote:
> +static void intel_irq_set_state(struct drm_i915_private *dev_priv,
> + bool enabled)
> +{
> + dev_priv->pm.irqs_enabled = enabled;
> + /*
> +  * Before we unmask the interrupt or synchronize against it, make sure
> +  * that a corresponding interrupt handler running on another CPU sees
> +  * the updated irqs_enabled value.
> +  */
> + smp_mb();

I would like a comment here to say something like: before powering down
the hardware make sure that we have no further access via pending
interrupt handlers. At the moment, I read the block comment above and
thought you were trying to imply something about the serialisation from
synchronize_irq() - but the only reason I can see you want sync_irq here
is to be sure that once the irq is disabled it is not going to run again.

> + if (!enabled)
> + synchronize_irq(dev_priv->dev->irq);
> +}

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


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

2015-02-20 Thread Imre Deak
On Fri, 2015-02-20 at 19:40 +, Chris Wilson wrote:
> On Fri, Feb 20, 2015 at 09:09:02PM +0200, Imre Deak wrote:
> > +static void intel_irq_set_state(struct drm_i915_private *dev_priv,
> > +   bool enabled)
> > +{
> > +   dev_priv->pm.irqs_enabled = enabled;
> > +   /*
> > +* Before we unmask the interrupt or synchronize against it, make sure
> > +* that a corresponding interrupt handler running on another CPU sees
> > +* the updated irqs_enabled value.
> > +*/
> > +   smp_mb();
> 
> I would like a comment here to say something like: before powering down
> the hardware make sure that we have no further access via pending
> interrupt handlers. At the moment, I read the block comment above and
> thought you were trying to imply something about the serialisation from
> synchronize_irq() - but the only reason I can see you want sync_irq here
> is to be sure that once the irq is disabled it is not going to run again.

Right. With sync_irq I want to wait for any running handler on another
CPU to finish. Subsequent ones due to any shared/spurious interrupts
will also not run since the barrier guarantees that they see already the
updated value and do an early return. Will add a comment about this.

> 
> > +   if (!enabled)
> > +   synchronize_irq(dev_priv->dev->irq);
> > +}
> 


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


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

2015-02-20 Thread Sean V Kelley
-BEGIN PGP SIGNED MESSAGE-
Hash: SHA1



On 02/11/2015 05:02 AM, Daniel Vetter wrote:
> On Wed, Feb 11, 2015 at 1:55 AM, Sean V Kelley 
> wrote:
>> No corruption seen.  I will add reloc domains to my growing audit
>> list.
> 
> One more for the libva audit list:
> 
> If you do any ioctl directly, please make sure that you clear the 
> ioctl structure with memset(&arg, 0, sizeof(arg)); or similar. 
> Otherwise when we extended them in upstream (which we're just
> doing, the kernel 0-fills the new fields automatically) it'll break
> because after a recompile there's now garbage in the new fields.
> 
> I just spent a while fixing up libdrm ;-) -Daniel
> 

Cleaned up the hybrid driver.  Found numerous instances of the
wrong reloc domain assignments, e.g., write_domain of 0. I've since
verified it was the root cause of the run 2 run issue. Also cleaned up
ioctl and structure clearing.

Thanks,

Sean
-BEGIN PGP SIGNATURE-
Version: GnuPG v1

iQIcBAEBAgAGBQJU57L/AAoJEGScDsMo8QYOFsIQANHSmmYUG5JSqsmewCDO1zHk
dh2h56x5oCIooJ2mOh9lcWTRpVbE4uv6HOt6WfThb4dP11Yg5LlOZA1uR65iniIy
9gi2vUotuajm9cOdXKVXCbQBuymR0rKJuRb74e73jk/u5QpOv/zNtThXOG7FfUVu
p1DpoVuh8iLGexwAd+6UrCOze5hWfCuh+9t9jTZ8Yr0pgSiRsGClX1mW8vUD4+99
7h5VGonr3tKYqHNZBtneaTcmRkVBtuZ/RBGr5FOnzP1VKIXidgt2t4ID33nZmjsx
rJjzQfh408qniBr9L7zIIDUZMiiAucIRm1+4eQ1b+yA9pYkXQfrs/lA9dH80IjAw
iWFS+IX7xUCpKZzLB38+dIV/Nsn0nxoF5N1ptz4RMKoeXJVWsRS72jgCjlrE5w4R
dnyodU7nlmdcNoeGcDEhcN5Jek7OPYoJLgaC100wu6yDZKJ/2CXJ6XwyORWQ7GU1
UWyqOuam84DJqiwzwkLl6Q9Ur7oC8S8jUIFLqRk/1PZOesu90/yNoJUByLQMMZbl
WzUMGdV4D18+uTHhmWGPruCYHLMgRXKVlT/diKH1q5aBOvtP4xeANn+0GSw+E3OZ
TN1TGDW/q8U0uN1CDk5hTIDgiJX0Eo9an0CsJ2yZL3K+J56+e6QUY6EPrU/ctqp0
QbT5eI44/dZX2Xmf/kc7
=24vy
-END PGP SIGNATURE-
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


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

2015-02-20 Thread shuang . he
Tested-By: PRC QA PRTS (Patch Regression Test System Contact: 
shuang...@intel.com)
Task id: 5801
-Summary-
Platform  Delta  drm-intel-nightly  Series Applied
PNV  277/277  277/277
ILK -1  313/313  312/313
SNB  309/309  309/309
IVB  382/382  382/382
BYT  296/296  296/296
HSW  425/425  425/425
BDW -1  318/318  317/318
-Detailed-
Platform  Testdrm-intel-nightly  Series 
Applied
*ILK  igt_gem_unfence_active_buffers  PASS(2)  DMESG_WARN(1)PASS(1)
*BDW  igt_gem_gtt_hog  PASS(18)  DMESG_WARN(1)PASS(1)
Note: You need to pay more attention to line start with '*'
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH v9] drm/i915/skl: Add support for SKL background color

2015-02-20 Thread Chandra Konduru
This patch adds support for Skylake display pipe background color.

v2:
- added property documentation to drm DocBook (Daniel Vetter)
- moved property to drm_mode_config (Daniel Vetter)
- change to set property to NULL once it is freed. (me)
- change to make sure gamma/csc settings were retained during color change (me)
- change to make sure background color is restored after a power event (me)

v3:
- change to add gen check before writing background color (Matt Roper)

v4:
- change to increase color from 8bpc to 16bpc (Daniel Vetter)

v5:
- removed initialization of background color to 0 (Damien Lespiau)
- added change log to commit message (Damien Lespiau)

v6:
- optmization to use _PIPE() (Damien Lespiau)
- updated max limit value in DocBook (Damien Lespiau)
- simplied color conversion equation (Damien Lespiau)
- always enable gamma and csc to align with update plane (Damien Lespiau)
- move resume restoration code to haswell_crtc_enable (Damien Lespiau)

v7:
- remove superfluous comments (Damien)
- remove unused variables left over between v5 and v6 (Damien)

v8:
- remove the destruction of the property, DRM core does that for us (Damien)

v9:
- add ULL to a 64bits constant

Reviewed-by: Damien Lespiau 
Signed-off-by: Chandra Konduru 
Signed-off-by: Damien Lespiau 
---
 Documentation/DocBook/drm.tmpl   |   10 ++-
 drivers/gpu/drm/i915/i915_reg.h  |   10 +++
 drivers/gpu/drm/i915/intel_display.c |   54 ++
 drivers/gpu/drm/i915/intel_drv.h |2 ++
 include/drm/drm_crtc.h   |3 ++
 5 files changed, 78 insertions(+), 1 deletion(-)

diff --git a/Documentation/DocBook/drm.tmpl b/Documentation/DocBook/drm.tmpl
index 249f0c9..c83ffe6 100644
--- a/Documentation/DocBook/drm.tmpl
+++ b/Documentation/DocBook/drm.tmpl
@@ -2834,7 +2834,7 @@ void intel_crt_init(struct drm_device *dev)
TBD


-   i915
+   i915
Generic
"Broadcast RGB"
ENUM
@@ -2858,6 +2858,14 @@ void intel_crt_init(struct drm_device *dev)
TBD


+   CRTC
+   “background_color”
+   Range
+   Min=0, Max=0x
+   CRTC
+   Background color in 16bpc BGR (B-MSB, R-LSB)
+   
+   
SDVO-TV
“mode”
ENUM
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 040cd83..2d7a9f5 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -6758,6 +6758,16 @@ enum skl_disp_power_wells {
 #define PIPE_CSC_POSTOFF_ME(pipe) _PIPE(pipe, _PIPE_A_CSC_POSTOFF_ME, 
_PIPE_B_CSC_POSTOFF_ME)
 #define PIPE_CSC_POSTOFF_LO(pipe) _PIPE(pipe, _PIPE_A_CSC_POSTOFF_LO, 
_PIPE_B_CSC_POSTOFF_LO)
 
+/* Skylake pipe bottom color */
+#define _PIPE_BOTTOM_COLOR_A0x70034
+#define _PIPE_BOTTOM_COLOR_B0x71034
+#define _PIPE_BOTTOM_COLOR_C0x72034
+#define PIPE_BOTTOM_GAMMA_ENABLE   (1 << 31)
+#define PIPE_BOTTOM_CSC_ENABLE (1 << 30)
+#define PIPE_BOTTOM_COLOR_MASK 0x3FFF
+#define PIPE_BOTTOM_COLOR(pipe) \
+   _PIPE(pipe, _PIPE_BOTTOM_COLOR_A, _PIPE_BOTTOM_COLOR_B)
+
 /* MIPI DSI registers */
 
 #define _MIPI_PORT(port, a, c) _PORT3(port, a, 0, c)   /* ports A and C only */
diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index 3b0fe9f..4dc5cb2 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -4413,6 +4413,20 @@ static void haswell_mode_set_planes_workaround(struct 
intel_crtc *crtc)
intel_wait_for_vblank(dev, other_active_crtc->pipe);
 }
 
+static void skl_crtc_set_background_color(struct intel_crtc *intel_crtc)
+{
+   struct drm_device *dev = intel_crtc->base.dev;
+   struct drm_i915_private *dev_priv = dev->dev_private;
+
+   if (INTEL_INFO(dev)->gen < 9)
+   return;
+
+   I915_WRITE(PIPE_BOTTOM_COLOR(intel_crtc->pipe),
+   intel_crtc->background_color |
+   PIPE_BOTTOM_GAMMA_ENABLE |
+   PIPE_BOTTOM_CSC_ENABLE);
+}
+
 static void haswell_crtc_enable(struct drm_crtc *crtc)
 {
struct drm_device *dev = crtc->dev;
@@ -4474,6 +4488,8 @@ static void haswell_crtc_enable(struct drm_crtc *crtc)
 */
intel_crtc_load_lut(crtc);
 
+   skl_crtc_set_background_color(intel_crtc);
+
intel_ddi_set_pipe_settings(crtc);
intel_ddi_enable_transcoder_func(crtc);
 
@@ -9882,6 +9898,30 @@ out_hang:
return ret;
 }
 
+static int intel_crtc_set_property(struct drm_crtc *crtc,
+   struct drm_property *property, uint64_t val)
+{
+   struct drm_device *dev = crtc->dev;
+   struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+   int i;
+
+   if (INTEL_INFO(dev)->gen >= 9) {
+   if (property == dev->mode_config.background_color_property) {
+   uint64_t bottom = 0;
+
+   /* BGR 16bpc ==> RGB 10bpc */
+   for (i = 0; i < 3; i++)

[Intel-gfx] [PATCH] i-g-t: Adding test case to test background color.

2015-02-20 Thread Chandra Konduru
From: chandra konduru 

Adding i-g-t test case to test display crtc background color.

Signed-off-by: chandra konduru 
---
 lib/igt_kms.c |  60 +++
 lib/igt_kms.h |   4 +
 tests/Android.mk  |   1 +
 tests/Makefile.sources|   1 +
 tests/kms_crtc_background_color.c | 220 ++
 5 files changed, 286 insertions(+)
 create mode 100644 tests/kms_crtc_background_color.c

diff --git a/lib/igt_kms.c b/lib/igt_kms.c
index d0c3690..7246e59 100644
--- a/lib/igt_kms.c
+++ b/lib/igt_kms.c
@@ -926,6 +926,22 @@ igt_plane_set_property(igt_plane_t *plane, uint32_t 
prop_id, uint64_t value)
 DRM_MODE_OBJECT_PLANE, prop_id, value);
 }
 
+static bool
+get_crtc_property(int drm_fd, uint32_t crtc_id, const char *name,
+  uint32_t *prop_id /* out */, uint64_t *value /* out */,
+  drmModePropertyPtr *prop /* out */)
+{
+   return kmstest_get_property(drm_fd, crtc_id, DRM_MODE_OBJECT_CRTC,
+   name, prop_id, value, prop);
+}
+
+static void
+igt_crtc_set_property(igt_output_t *output, uint32_t prop_id, uint64_t value)
+{
+   drmModeObjectSetProperty(output->display->drm_fd,
+   output->config.crtc->crtc_id, DRM_MODE_OBJECT_CRTC, prop_id, 
value);
+}
+
 /*
  * Walk a plane's property list to determine its type.  If we don't
  * find a type property, then the kernel doesn't support universal
@@ -1083,6 +1099,7 @@ void igt_display_init(igt_display_t *display, int drm_fd)
igt_assert(display->outputs);
 
for (i = 0; i < display->n_outputs; i++) {
+   int j;
igt_output_t *output = &display->outputs[i];
 
/*
@@ -1094,6 +,19 @@ void igt_display_init(igt_display_t *display, int drm_fd)
output->display = display;
 
igt_output_refresh(output);
+
+   for (j = 0; j < display->n_pipes; j++) {
+   uint64_t prop_value;
+   igt_pipe_t *pipe = &display->pipes[j];
+   if (output->config.crtc) {
+   get_crtc_property(display->drm_fd, 
output->config.crtc->crtc_id,
+  "background_color",
+  &pipe->background_property,
+  &prop_value,
+  NULL);
+   pipe->background = (uint32_t)prop_value;
+   }
+   }
}
 
drmModeFreePlaneResources(plane_resources);
@@ -1513,6 +1543,13 @@ static int igt_output_commit(igt_output_t *output,
 
pipe = igt_output_get_driving_pipe(output);
 
+   if (pipe->background_changed) {
+   igt_crtc_set_property(output, pipe->background_property,
+   pipe->background);
+
+   pipe->background_changed = false;
+   }
+
for (i = 0; i < pipe->n_planes; i++) {
igt_plane_t *plane = &pipe->planes[i];
 
@@ -1765,6 +1802,29 @@ void igt_plane_set_rotation(igt_plane_t *plane, 
igt_rotation_t rotation)
plane->rotation_changed = true;
 }
 
+/**
+ * igt_crtc_set_background:
+ * @pipe: pipe pointer to which background color to be set
+ * @background: background color value
+ *
+ * Sets background color for requested pipe. Color value provided here
+ * will be actually submitted at output commit time via "background_color"
+ * property.
+ */
+void igt_crtc_set_background(igt_pipe_t *pipe, uint64_t background)
+{
+   igt_display_t *display = pipe->display;
+
+   LOG(display, "%s.%d: crtc_set_background(%lu)\n",
+   kmstest_pipe_name(pipe->pipe),
+   pipe->pipe, background);
+
+   pipe->background = background;
+
+   pipe->background_changed = true;
+}
+
+
 void igt_wait_for_vblank(int drm_fd, enum pipe pipe)
 {
drmVBlank wait_vbl;
diff --git a/lib/igt_kms.h b/lib/igt_kms.h
index a1483a4..4fada1b 100644
--- a/lib/igt_kms.h
+++ b/lib/igt_kms.h
@@ -206,6 +206,9 @@ struct igt_pipe {
 #define IGT_MAX_PLANES 4
int n_planes;
igt_plane_t planes[IGT_MAX_PLANES];
+   uint64_t background; /* Background color MSB BGR 16bpc LSB */
+   uint32_t background_changed : 1;
+   uint32_t background_property;
 };
 
 typedef struct {
@@ -251,6 +254,7 @@ void igt_plane_set_position(igt_plane_t *plane, int x, int 
y);
 void igt_plane_set_size(igt_plane_t *plane, int w, int h);
 void igt_plane_set_panning(igt_plane_t *plane, int x, int y);
 void igt_plane_set_rotation(igt_plane_t *plane, igt_rotation_t rotation);
+void igt_crtc_set_background(igt_pipe_t *pipe, uint64_t background);
 
 void igt_wait_for_vblank(int drm_fd, enum pipe pipe);
 
diff --git a/tests/Android.mk b/tests/Android.mk
index 814b846..96a32b9 100644
--- a/tests/Android.mk
+++ b/tes

[Intel-gfx] [PATCH] drm/i915/skl: Update edp 1.4 DDI translation table

2015-02-20 Thread Sonika Jindal
Updating recommended DDI translation table for edp 1.4
as per bspec update

Signed-off-by: Sonika Jindal 
Reviewed-by: Damien Lespiau 
---
 drivers/gpu/drm/i915/intel_ddi.c |   18 +-
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index 114b729..f17cc48 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -141,16 +141,16 @@ static const struct ddi_buf_trans 
skl_ddi_translations_dp[] = {
 
 /* eDP 1.4 low vswing translation parameters */
 static const struct ddi_buf_trans skl_ddi_translations_edp[] = {
-   { 0x0018, 0x0428 },
-   { 0x2016, 0x0067 },
-   { 0x6012, 0x0032 },
+   { 0x0018, 0x00a8 },
+   { 0x2016, 0x00ab },
+   { 0x6012, 0x00a2 },
{ 0x8010, 0x0088 },
-   { 0x0018, 0x0067 },
-   { 0x4014, 0x0032 },
-   { 0x6012, 0x0098 },
-   { 0x0018, 0x0032 },
-   { 0x5013, 0x0098 },
-   { 0x6012, 0x001e },
+   { 0x0018, 0x00ab },
+   { 0x4014, 0x00a2 },
+   { 0x6012, 0x00a6 },
+   { 0x0018, 0x00a2 },
+   { 0x5013, 0x009c },
+   { 0x0018, 0x0088 },
 };
 
 
-- 
1.7.10.4

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


[Intel-gfx] [PATCH 0/4] drm/i915/skl: Support for edp1.4 intermediate frequencies

2015-02-20 Thread Sonika Jindal
This series adds support for edp1.4 intermediate frequencies supported by 
Skylake
This addresses review comments by Ville and some reformatting.

Sonika Jindal (4):
  drm: Adding edp1.4 specific dpcd macros
  drm/i915/skl: Read sink supported rates from edp panel
  drm/i915/skl: Add support for edp 1.4 intermediate frequencies
  drm/i915/skl: Program PLL for edp1.4 intermediate frequencies

 drivers/gpu/drm/i915/intel_ddi.c |9 ++
 drivers/gpu/drm/i915/intel_dp.c  |  179 +++---
 drivers/gpu/drm/i915/intel_drv.h |2 +
 include/drm/drm_dp_helper.h  |8 ++
 4 files changed, 184 insertions(+), 14 deletions(-)

-- 
1.7.10.4

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


[Intel-gfx] [PATCH 1/4] drm: Adding edp1.4 specific dpcd macros

2015-02-20 Thread Sonika Jindal
Adding dpcd macros related to edp1.4 and link rates

v2: Added DP_SUPPORTED_LINK_RATES macros

Cc: dri-de...@lists.freedesktop.org
Signed-off-by: Sonika Jindal 
Reviewed-by: Todd Previte 
---
 include/drm/drm_dp_helper.h |8 
 1 file changed, 8 insertions(+)

diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h
index 11f8c84..77a55e2 100644
--- a/include/drm/drm_dp_helper.h
+++ b/include/drm/drm_dp_helper.h
@@ -92,6 +92,9 @@
 # define DP_MSA_TIMING_PAR_IGNORED (1 << 6) /* eDP */
 # define DP_OUI_SUPPORT(1 << 7)
 
+#define DP_SUPPORTED_LINK_RATES0x010 /*eDP 1.4*/
+#define DP_MAX_SUPPORTED_RATES 0x8
+
 #define DP_I2C_SPEED_CAP   0x00c/* DPI */
 # define DP_I2C_SPEED_1K   0x01
 # define DP_I2C_SPEED_5K   0x02
@@ -101,6 +104,7 @@
 # define DP_I2C_SPEED_1M   0x20
 
 #define DP_EDP_CONFIGURATION_CAP0x00d   /* XXX 1.2? */
+# define DP_DPCD_DISPLAY_CONTROL_CAPABLE (1 << 3) /* edp v1.2 or higher */
 #define DP_TRAINING_AUX_RD_INTERVAL 0x00e   /* XXX 1.2? */
 
 /* Multiple stream transport */
@@ -221,6 +225,8 @@
 # define DP_UP_REQ_EN  (1 << 1)
 # define DP_UPSTREAM_IS_SRC(1 << 2)
 
+#define DP_LINK_RATE_SET   0x115
+
 #define DP_PSR_EN_CFG  0x170   /* XXX 1.2? */
 # define DP_PSR_ENABLE (1 << 0)
 # define DP_PSR_MAIN_LINK_ACTIVE   (1 << 1)
@@ -332,6 +338,8 @@
 # define DP_SET_POWER_D30x2
 # define DP_SET_POWER_MASK  0x3
 
+#define DP_EDP_DPCD_REV  0x700
+
 #define DP_SIDEBAND_MSG_DOWN_REQ_BASE  0x1000   /* 1.2 MST */
 #define DP_SIDEBAND_MSG_UP_REP_BASE0x1200   /* 1.2 MST */
 #define DP_SIDEBAND_MSG_DOWN_REP_BASE  0x1400   /* 1.2 MST */
-- 
1.7.10.4

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


[Intel-gfx] [PATCH 3/4] drm/i915/skl: Add support for edp 1.4 intermediate frequencies

2015-02-20 Thread Sonika Jindal
eDp 1.4 supports custom frequencies.
Skylake supports following intermediate frequencies : 3.24 GHz, 2.16 GHz and
4.32 GHz along with usual LBR, HBR and HBR2 frequencies.
Read sink supported frequencies and get common frequencies from sink and
source and use these for link training.

v2: Rebased, removed calculation of min_clock since for edp it is taken as
max_clock (as per comment).
v3: Keeping single array for link rates (Satheesh)
v4: Setting LINK_BW_SET to 0 when setting LINK_RATE_SET (Satheesh)
v5: Some minor nits (Ville)
v6: Keeping separate arrays for source and sink rates (Ville)

Signed-off-by: Sonika Jindal 
---
 drivers/gpu/drm/i915/intel_ddi.c |9 +++
 drivers/gpu/drm/i915/intel_dp.c  |  113 +++---
 drivers/gpu/drm/i915/intel_drv.h |1 +
 3 files changed, 115 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index 4d8c38d..db00db8 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -803,9 +803,18 @@ static void skl_ddi_clock_get(struct intel_encoder 
*encoder,
case DPLL_CRTL1_LINK_RATE_810:
link_clock = 81000;
break;
+   case DPLL_CRTL1_LINK_RATE_1080:
+   link_clock = 108000;
+   break;
case DPLL_CRTL1_LINK_RATE_1350:
link_clock = 135000;
break;
+   case DPLL_CRTL1_LINK_RATE_1620:
+   link_clock = 162000;
+   break;
+   case DPLL_CRTL1_LINK_RATE_2160:
+   link_clock = 216000;
+   break;
case DPLL_CRTL1_LINK_RATE_2700:
link_clock = 27;
break;
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 72deac6..cf7a0f5 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -83,6 +83,11 @@ static const struct dp_link_dpll chv_dpll[] = {
{ DP_LINK_BW_5_4,   /* m2_int = 27, m2_fraction = 0 */
{ .p1 = 2, .p2 = 1, .n = 1, .m1 = 2, .m2 = 0x6c0 } }
 };
+/* Skylake supports following rates */
+static const uint32_t gen9_rates[] = { 162000, 216000, 27, 324000,
+   432000, 54 };
+
+static const uint32_t default_rates[] = { 162000, 27, 54 };
 
 /**
  * is_edp - is the given port attached to an eDP panel (either CPU or PCH)
@@ -1143,6 +1148,25 @@ intel_read_sink_rates(struct intel_dp *intel_dp, 
uint32_t *sink_rates)
return i;
 }
 
+static int
+intel_read_source_rates(struct intel_dp *intel_dp, uint32_t *source_rates)
+{
+   struct drm_device *dev = intel_dp_to_dev(intel_dp);
+   int i;
+   int max_default_rate;
+
+   if (INTEL_INFO(dev)->gen >= 9 && intel_dp->supported_rates[0]) {
+   for (i = 0; i < ARRAY_SIZE(gen9_rates); ++i)
+   source_rates[i] = gen9_rates[i];
+   } else {
+   /* Index of the max_link_bw supported + 1 */
+   max_default_rate = (intel_dp_max_link_bw(intel_dp) >> 3) + 1;
+   for (i = 0; i < max_default_rate; ++i)
+   source_rates[i] = default_rates[i];
+   }
+   return i;
+}
+
 static void
 intel_dp_set_clock(struct intel_encoder *encoder,
   struct intel_crtc_state *pipe_config, int link_bw)
@@ -1176,6 +1200,45 @@ intel_dp_set_clock(struct intel_encoder *encoder,
}
 }
 
+static int intel_supported_rates(const uint32_t *source_rates, int source_len,
+const uint32_t *sink_rates, int sink_len, uint32_t *supported_rates)
+{
+   int i = 0, j = 0, k = 0;
+
+   /* For panels with edp version less than 1.4 */
+   if (sink_len == 0) {
+   for (i = 0; i < source_len; ++i)
+   supported_rates[i] = source_rates[i];
+   return source_len;
+   }
+
+   /* For edp1.4 panels, find the common rates between source and sink */
+   while (i < source_len && j < sink_len) {
+   if (source_rates[i] == sink_rates[j]) {
+   supported_rates[k] = source_rates[i];
+   ++k;
+   ++i;
+   ++j;
+   } else if (source_rates[i] < sink_rates[j]) {
+   ++i;
+   } else {
+   ++j;
+   }
+   }
+   return k;
+}
+
+static int rate_to_index(uint32_t find, const uint32_t *rates)
+{
+   int i = 0;
+
+   for (i = 0; i < DP_MAX_SUPPORTED_RATES; ++i)
+   if (find == rates[i])
+   break;
+
+   return i;
+}
+
 bool
 intel_dp_compute_config(struct intel_encoder *encoder,
struct intel_crtc_state *pipe_config)
@@ -1192,10 +1255,25 @@ intel_dp_compute_config(struct intel_

[Intel-gfx] [PATCH 4/4] drm/i915/skl: Program PLL for edp1.4 intermediate frequencies

2015-02-20 Thread Sonika Jindal
v2: Making the link_clock half in switch inline with the DPLL_CTRL1_* macros
(Ville)

Signed-off-by: Sonika Jindal 
---
 drivers/gpu/drm/i915/intel_dp.c |   28 ++--
 1 file changed, 22 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index cf7a0f5..62bc6c1 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -1079,7 +1079,7 @@ intel_dp_connector_unregister(struct intel_connector 
*intel_connector)
 }
 
 static void
-skl_edp_set_pll_config(struct intel_crtc_state *pipe_config, int link_bw)
+skl_edp_set_pll_config(struct intel_crtc_state *pipe_config, int link_clock)
 {
u32 ctrl1;
 
@@ -1088,19 +1088,35 @@ skl_edp_set_pll_config(struct intel_crtc_state 
*pipe_config, int link_bw)
pipe_config->dpll_hw_state.cfgcr2 = 0;
 
ctrl1 = DPLL_CTRL1_OVERRIDE(SKL_DPLL0);
-   switch (link_bw) {
-   case DP_LINK_BW_1_62:
+   switch (link_clock / 2) {
+   case 81000:
ctrl1 |= DPLL_CRTL1_LINK_RATE(DPLL_CRTL1_LINK_RATE_810,
  SKL_DPLL0);
break;
-   case DP_LINK_BW_2_7:
+   case 135000:
ctrl1 |= DPLL_CRTL1_LINK_RATE(DPLL_CRTL1_LINK_RATE_1350,
  SKL_DPLL0);
break;
-   case DP_LINK_BW_5_4:
+   case 27:
ctrl1 |= DPLL_CRTL1_LINK_RATE(DPLL_CRTL1_LINK_RATE_2700,
  SKL_DPLL0);
break;
+   case 162000:
+   ctrl1 |= DPLL_CRTL1_LINK_RATE(DPLL_CRTL1_LINK_RATE_1620,
+ SKL_DPLL0);
+   break;
+   /* TBD: For DP link rates 2.16 GHz and 4.32 GHz, VCO is 8640 which
+   results in CDCLK change. Need to handle the change of CDCLK by
+   disabling pipes and re-enabling them */
+   case 108000:
+   ctrl1 |= DPLL_CRTL1_LINK_RATE(DPLL_CRTL1_LINK_RATE_1080,
+ SKL_DPLL0);
+   break;
+   case 216000:
+   ctrl1 |= DPLL_CRTL1_LINK_RATE(DPLL_CRTL1_LINK_RATE_2160,
+ SKL_DPLL0);
+   break;
+
}
pipe_config->dpll_hw_state.ctrl1 = ctrl1;
 }
@@ -1395,7 +1411,7 @@ found:
}
 
if (IS_SKYLAKE(dev) && is_edp(intel_dp))
-   skl_edp_set_pll_config(pipe_config, intel_dp->link_bw);
+   skl_edp_set_pll_config(pipe_config, supported_rates[clock]);
else if (IS_HASWELL(dev) || IS_BROADWELL(dev))
hsw_dp_set_ddi_pll_sel(pipe_config, intel_dp->link_bw);
else
-- 
1.7.10.4

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


[Intel-gfx] [PATCH 2/4] drm/i915/skl: Read sink supported rates from edp panel

2015-02-20 Thread Sonika Jindal
v2: Using DP_SUPPORTED_LINK_RATES macro for supported_rates array (Satheesh).
v3: Reading dpcd's supported link rates tables based upon edp version in the
same patch.
v4: Move version check under is_edp (Satheesh)
v5: Using le16 for rates, some naming, and removing nested if block (Ville)
v6: Correctly using DP_MAX_SUPPORTED_RATES and removing DP_SUPPORTED_LINK_RATES
(Ville)
v7: Incorrectly removed DP_SUPPORTED_LINK_RATES in v6, re-adding it

Signed-off-by: Sonika Jindal 
---
 drivers/gpu/drm/i915/intel_dp.c  |   38 ++
 drivers/gpu/drm/i915/intel_drv.h |1 +
 2 files changed, 39 insertions(+)

diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 42ac99f..72deac6 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -1116,6 +1116,33 @@ hsw_dp_set_ddi_pll_sel(struct intel_crtc_state 
*pipe_config, int link_bw)
}
 }
 
+static int
+intel_read_sink_rates(struct intel_dp *intel_dp, uint32_t *sink_rates)
+{
+   struct drm_device *dev = intel_dp_to_dev(intel_dp);
+   int i = 0;
+   uint16_t val;
+
+   if (INTEL_INFO(dev)->gen >= 9 && intel_dp->supported_rates[0]) {
+   /*
+* Receiver supports only main-link rate selection by
+* link rate table method, so read link rates from
+* supported_link_rates
+*/
+   for (i = 0; i < DP_MAX_SUPPORTED_RATES; ++i) {
+   val = le16_to_cpu(intel_dp->supported_rates[i]);
+   if (val == 0)
+   break;
+
+   sink_rates[i] = val * 200;
+   }
+
+   if (i <= 0)
+   DRM_ERROR("No rates in SUPPORTED_LINK_RATES");
+   }
+   return i;
+}
+
 static void
 intel_dp_set_clock(struct intel_encoder *encoder,
   struct intel_crtc_state *pipe_config, int link_bw)
@@ -3592,6 +3619,7 @@ intel_dp_get_dpcd(struct intel_dp *intel_dp)
struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
struct drm_device *dev = dig_port->base.base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
+   uint8_t rev;
 
if (intel_dp_dpcd_read_wake(&intel_dp->aux, 0x000, intel_dp->dpcd,
sizeof(intel_dp->dpcd)) < 0)
@@ -3623,6 +3651,16 @@ intel_dp_get_dpcd(struct intel_dp *intel_dp)
} else
intel_dp->use_tps3 = false;
 
+   /* Intermediate frequency support */
+   if (is_edp(intel_dp) &&
+   (intel_dp->dpcd[DP_EDP_CONFIGURATION_CAP] & 
DP_DPCD_DISPLAY_CONTROL_CAPABLE) &&
+   intel_dp_dpcd_read_wake(&intel_dp->aux, DP_EDP_DPCD_REV, &rev, 1) &&
+   (rev >= 0x03)) { /* eDp v1.4 or higher */
+   intel_dp_dpcd_read_wake(&intel_dp->aux,
+   DP_SUPPORTED_LINK_RATES,
+   intel_dp->supported_rates,
+   sizeof(intel_dp->supported_rates));
+   }
if (!(intel_dp->dpcd[DP_DOWNSTREAMPORT_PRESENT] &
  DP_DWN_STRM_PORT_PRESENT))
return true; /* native DP sink */
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 6832eb8..24e5411 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -602,6 +602,7 @@ struct intel_dp {
uint8_t dpcd[DP_RECEIVER_CAP_SIZE];
uint8_t psr_dpcd[EDP_PSR_RECEIVER_CAP_SIZE];
uint8_t downstream_ports[DP_MAX_DOWNSTREAM_PORTS];
+   __le16 supported_rates[DP_MAX_SUPPORTED_RATES];
struct drm_dp_aux aux;
uint8_t train_set[4];
int panel_power_up_delay;
-- 
1.7.10.4

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