On Wed, 26 Sep 2012 10:34:00 -0700
Ben Widawsky <b...@bwidawsk.net> wrote:

> There is a special mechanism for communicating with the PCU already
> being used for the ring frequency stuff. As we'll be needing this for
> other commands, extract it now to make future code less error prone and
> the current code more reusable.
> 
> I'm not entirely sure if this code matches 1:1 with the previous code
> behaviorally. Functionally however, it should be the same.
> 
> CC: Jesse Barnes <jbar...@virtuousgeek.org>
> Signed-off-by: Ben Widawsky <b...@bwidawsk.net>
> ---
>  drivers/gpu/drm/i915/i915_debugfs.c | 13 ++---
>  drivers/gpu/drm/i915/i915_drv.h     |  3 ++
>  drivers/gpu/drm/i915/intel_pm.c     | 94 
> +++++++++++++++++++++++--------------
>  3 files changed, 67 insertions(+), 43 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_debugfs.c 
> b/drivers/gpu/drm/i915/i915_debugfs.c
> index 7a4b3f3..6647585 100644
> --- a/drivers/gpu/drm/i915/i915_debugfs.c
> +++ b/drivers/gpu/drm/i915/i915_debugfs.c
> @@ -1283,15 +1283,10 @@ static int i915_ring_freq_table(struct seq_file *m, 
> void *unused)
>       for (gpu_freq = dev_priv->rps.min_delay;
>            gpu_freq <= dev_priv->rps.max_delay;
>            gpu_freq++) {
> -             I915_WRITE(GEN6_PCODE_DATA, gpu_freq);
> -             I915_WRITE(GEN6_PCODE_MAILBOX, GEN6_PCODE_READY |
> -                        GEN6_PCODE_READ_MIN_FREQ_TABLE);
> -             if (wait_for((I915_READ(GEN6_PCODE_MAILBOX) &
> -                           GEN6_PCODE_READY) == 0, 10)) {
> -                     DRM_ERROR("pcode read of freq table timed out\n");
> -                     continue;
> -             }
> -             ia_freq = I915_READ(GEN6_PCODE_DATA);
> +             ia_freq = gpu_freq;
> +             sandybridge_pcode_read(dev_priv,
> +                                    GEN6_PCODE_READ_MIN_FREQ_TABLE,
> +                                    &ia_freq);
>               seq_printf(m, "%d\t\t%d\n", gpu_freq * GT_FREQUENCY_MULTIPLIER, 
> ia_freq * 100);
>       }
>  
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index af5ceb4..b75a7b5 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -1622,6 +1622,9 @@ void gen6_gt_force_wake_get(struct drm_i915_private 
> *dev_priv);
>  void gen6_gt_force_wake_put(struct drm_i915_private *dev_priv);
>  int __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv);
>  
> +int sandybridge_pcode_read(struct drm_i915_private *dev_priv, u8 mbox, u32 
> *val);
> +int sandybridge_pcode_write(struct drm_i915_private *dev_priv, u8 mbox, u32 
> val);
> +
>  #define __i915_read(x, y) \
>       u##x i915_read##x(struct drm_i915_private *dev_priv, u32 reg);
>  
> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> index a3e4f8b..6488cd0 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -2503,30 +2503,16 @@ static void gen6_enable_rps(struct drm_device *dev)
>                  GEN6_RP_UP_BUSY_AVG |
>                  (IS_HASWELL(dev) ? GEN7_RP_DOWN_IDLE_AVG : 
> GEN6_RP_DOWN_IDLE_CONT));
>  
> -     if (wait_for((I915_READ(GEN6_PCODE_MAILBOX) & GEN6_PCODE_READY) == 0,
> -                  500))
> -             DRM_ERROR("timeout waiting for pcode mailbox to become idle\n");
> -
> -     I915_WRITE(GEN6_PCODE_DATA, 0);
> -     I915_WRITE(GEN6_PCODE_MAILBOX,
> -                GEN6_PCODE_READY |
> -                GEN6_PCODE_WRITE_MIN_FREQ_TABLE);
> -     if (wait_for((I915_READ(GEN6_PCODE_MAILBOX) & GEN6_PCODE_READY) == 0,
> -                  500))
> -             DRM_ERROR("timeout waiting for pcode mailbox to finish\n");
> -
> -     /* Check for overclock support */
> -     if (wait_for((I915_READ(GEN6_PCODE_MAILBOX) & GEN6_PCODE_READY) == 0,
> -                  500))
> -             DRM_ERROR("timeout waiting for pcode mailbox to become idle\n");
> -     I915_WRITE(GEN6_PCODE_MAILBOX, GEN6_READ_OC_PARAMS);
> -     pcu_mbox = I915_READ(GEN6_PCODE_DATA);
> -     if (wait_for((I915_READ(GEN6_PCODE_MAILBOX) & GEN6_PCODE_READY) == 0,
> -                  500))
> -             DRM_ERROR("timeout waiting for pcode mailbox to finish\n");
> -     if (pcu_mbox & (1<<31)) { /* OC supported */
> -             dev_priv->rps.max_delay = pcu_mbox & 0xff;
> -             DRM_DEBUG_DRIVER("overclocking supported, adjusting frequency 
> max to %dMHz\n", pcu_mbox * 50);
> +     ret = sandybridge_pcode_write(dev_priv, 
> GEN6_PCODE_WRITE_MIN_FREQ_TABLE, 0);
> +     if (!ret) {
> +             pcu_mbox = 0;
> +             ret = sandybridge_pcode_read(dev_priv, GEN6_READ_OC_PARAMS, 
> &pcu_mbox);
> +             if (ret && pcu_mbox & (1<<31)) { /* OC supported */
> +                     dev_priv->rps.max_delay = pcu_mbox & 0xff;
> +                     DRM_DEBUG_DRIVER("overclocking supported, adjusting 
> frequency max to %dMHz\n", pcu_mbox * 50);
> +             }
> +     } else {
> +             DRM_DEBUG_DRIVER("Failed to set the min frequency\n");
>       }
>  
>       gen6_set_rps(dev_priv->dev, (gt_perf_status & 0xff00) >> 8);
> @@ -2581,17 +2567,11 @@ static void gen6_update_ring_freq(struct drm_device 
> *dev)
>               else
>                       ia_freq = max_ia_freq - ((diff * scaling_factor) / 2);
>               ia_freq = DIV_ROUND_CLOSEST(ia_freq, 100);
> +             ia_freq <<= GEN6_PCODE_FREQ_IA_RATIO_SHIFT;
>  
> -             I915_WRITE(GEN6_PCODE_DATA,
> -                        (ia_freq << GEN6_PCODE_FREQ_IA_RATIO_SHIFT) |
> -                        gpu_freq);
> -             I915_WRITE(GEN6_PCODE_MAILBOX, GEN6_PCODE_READY |
> -                        GEN6_PCODE_WRITE_MIN_FREQ_TABLE);
> -             if (wait_for((I915_READ(GEN6_PCODE_MAILBOX) &
> -                           GEN6_PCODE_READY) == 0, 10)) {
> -                     DRM_ERROR("pcode write of freq table timed out\n");
> -                     continue;
> -             }
> +             sandybridge_pcode_write(dev_priv,
> +                                     GEN6_PCODE_WRITE_MIN_FREQ_TABLE,
> +                                     ia_freq | gpu_freq);
>       }
>  }
>  
> @@ -4143,3 +4123,49 @@ void intel_gt_init(struct drm_device *dev)
>       }
>  }
>  
> +int sandybridge_pcode_read(struct drm_i915_private *dev_priv, u8 mbox, u32 
> *val)
> +{
> +     WARN_ON(!mutex_is_locked(&dev_priv->dev->struct_mutex));
> +
> +     if (I915_READ(GEN6_PCODE_MAILBOX) & GEN6_PCODE_READY) {
> +             DRM_DEBUG_DRIVER("warning: pcode (read) mailbox access 
> failed\n");
> +             return -EAGAIN;
> +     }
> +
> +     I915_WRITE(GEN6_PCODE_DATA, *val);
> +     I915_WRITE(GEN6_PCODE_MAILBOX, GEN6_PCODE_READY | mbox);
> +
> +     if (wait_for((I915_READ(GEN6_PCODE_MAILBOX) & GEN6_PCODE_READY) == 0,
> +                  500)) {
> +             DRM_ERROR("timeout waiting for pcode read (%d) to finish\n", 
> mbox);
> +             return -ETIMEDOUT;
> +     }
> +
> +     *val = I915_READ(GEN6_PCODE_DATA);
> +     I915_WRITE(GEN6_PCODE_DATA, 0);
> +
> +     return 0;
> +}
> +
> +int sandybridge_pcode_write(struct drm_i915_private *dev_priv, u8 mbox, u32 
> val)
> +{
> +     WARN_ON(!mutex_is_locked(&dev_priv->dev->struct_mutex));
> +
> +     if (I915_READ(GEN6_PCODE_MAILBOX) & GEN6_PCODE_READY) {
> +             DRM_DEBUG_DRIVER("warning: pcode (write) mailbox access 
> failed\n");
> +             return -EAGAIN;
> +     }
> +
> +     I915_WRITE(GEN6_PCODE_DATA, val);
> +     I915_WRITE(GEN6_PCODE_MAILBOX, GEN6_PCODE_READY | mbox);
> +
> +     if (wait_for((I915_READ(GEN6_PCODE_MAILBOX) & GEN6_PCODE_READY) == 0,
> +                  500)) {
> +             DRM_ERROR("timeout waiting for pcode write (%d) to finish\n", 
> mbox);
> +             return -ETIMEDOUT;
> +     }
> +
> +     I915_WRITE(GEN6_PCODE_DATA, 0);
> +
> +     return 0;
> +}

I'd call it punit rather than pcode, but that's just a nitpick.  I like
pulling it out into a separate function.

Reviewed-by: Jesse Barnes <jbar...@virtuousgeek.org>

-- 
Jesse Barnes, Intel Open Source Technology Center
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to