public inbox for intel-gfx@lists.freedesktop.org
 help / color / mirror / Atom feed
From: "S, Deepak" <deepak.s@intel.com>
To: benjamin.widawsky@intel.com, intel-gfx@lists.freedesktop.org
Subject: Re: [PATCH 8/9] drm/i915/bdw: Implement a basic PM interrupt handler
Date: Fri, 07 Feb 2014 12:13:23 +0530	[thread overview]
Message-ID: <52F4808B.6040803@intel.com> (raw)
In-Reply-To: <CAOh5HuXYmUmGM2tDGO6KCT9Q1V6znbAwQf5OoC27++078bvfRg@mail.gmail.com>

On Wed, Jan 29, 2014 at 9:55 AM, Ben Widawsky
> <benjamin.widawsky@intel.com <mailto:benjamin.widawsky@intel.com>> wrote:
>
>     Almost all of it is reusable from the existing code. The primary
>     difference is we need to do even less in the interrupt handler, since
>     interrupts are not shared in the same way.
>
>     The patch is mostly a copy-paste of the existing snb+ code, with updates
>     to the relevant parts requiring changes to the interrupt handling. As
>     such it /should/ be relatively trivial. It's highly likely that I missed
>     some places where I need a gen8 version of the PM interrupts, but it has
>     become invisible to me by now.
>
>     This patch could probably be split into adding the new functions,
>     followed by actually handling the interrupts. Since the code is
>     currently disabled (and broken) I think the patch stands better by
>     itself.
>
>     Signed-off-by: Ben Widawsky <ben@bwidawsk.net <mailto:ben@bwidawsk.net>>
>     ---
>       drivers/gpu/drm/i915/i915_irq.c  | 80
>     ++++++++++++++++++++++++++++++++++++++--
>       drivers/gpu/drm/i915/i915_reg.h  |  1 +
>       drivers/gpu/drm/i915/intel_drv.h |  2 +
>       drivers/gpu/drm/i915/intel_pm.c  | 39 +++++++++++++++++++-
>       4 files changed, 117 insertions(+), 5 deletions(-)
>
>     diff --git a/drivers/gpu/drm/i915/i915_irq.c
>     b/drivers/gpu/drm/i915/i915_irq.c
>     index 72ade87..ab0c7ac 100644
>     --- a/drivers/gpu/drm/i915/i915_irq.c
>     +++ b/drivers/gpu/drm/i915/i915_irq.c
>     @@ -214,6 +214,53 @@ static bool ivb_can_enable_err_int(struct
>     drm_device *dev)
>              return true;
>       }
>
>     +/**
>     +  * bdw_update_pm_irq - update GT interrupt 2
>     +  * @dev_priv: driver private
>     +  * @interrupt_mask: mask of interrupt bits to update
>     +  * @enabled_irq_mask: mask of interrupt bits to enable
>     +  *
>     +  * Copied from the snb function, updated with relevant register
>     offsets
>     +  */
>     +static void bdw_update_pm_irq(struct drm_i915_private *dev_priv,
>     +                             uint32_t interrupt_mask,
>     +                             uint32_t enabled_irq_mask)
>     +{
>     +       uint32_t new_val;
>     +
>     +       assert_spin_locked(&dev_priv->irq_lock);
>     +
>     +       if (dev_priv->pc8.irqs_disabled) {
>     +               WARN(1, "IRQs disabled\n");
>     +               dev_priv->pc8.regsave.gen6_pmimr &= ~interrupt_mask;
>     +               dev_priv->pc8.regsave.gen6_pmimr |= (~enabled_irq_mask &
>     +                                                    interrupt_mask);
>     +               return;
>     +       }
>     +
>     +       new_val = dev_priv->pm_irq_mask;
>     +       new_val &= ~interrupt_mask;
>     +       new_val |= (~enabled_irq_mask & interrupt_mask);
>     +
>     +       if (new_val != dev_priv->pm_irq_mask) {
>     +               dev_priv->pm_irq_mask = new_val;
>     +               I915_WRITE(GEN8_GT_IMR(2), I915_READ(GEN8_GT_IMR(2)) |
>     +                                          dev_priv->pm_irq_mask);
>     +               POSTING_READ(GEN8_GT_IMR(2));
>     +       }
>     +}
>     +
>     +void bdw_enable_pm_irq(struct drm_i915_private *dev_priv, uint32_t
>     mask)
>     +{
>     +       bdw_update_pm_irq(dev_priv, mask, mask);
>     +}
>     +
>     +void bdw_disable_pm_irq(struct drm_i915_private *dev_priv, uint32_t
>     mask)
>     +{
>     +       bdw_update_pm_irq(dev_priv, mask, 0);
>     +}
>     +
>     +
>       static bool cpt_can_enable_serr_int(struct drm_device *dev)
>       {
>              struct drm_i915_private *dev_priv = dev->dev_private;
>     @@ -997,11 +1044,15 @@ static void gen6_pm_rps_work(struct
>     work_struct *work)
>              pm_iir = dev_priv->rps.pm_iir;
>              dev_priv->rps.pm_iir = 0;
>              /* Make sure not to corrupt PMIMR state used by ringbuffer
>     code */
>     -       snb_enable_pm_irq(dev_priv, GEN6_PM_RPS_EVENTS);
>     +       if (IS_BROADWELL(dev_priv->dev))
>     +               bdw_enable_pm_irq(dev_priv, GEN6_PM_RPS_EVENTS);
>     +       else {
>     +               /* Make sure we didn't queue anything we're not
>     going to process. */
>     +               snb_enable_pm_irq(dev_priv, GEN6_PM_RPS_EVENTS);
>     +               WARN_ON(pm_iir & ~GEN6_PM_RPS_EVENTS);
>     +       }
>              spin_unlock_irq(&dev_priv->irq_lock);
>
>     -       /* Make sure we didn't queue anything we're not going to
>     process. */
>     -       WARN_ON(pm_iir & ~GEN6_PM_RPS_EVENTS);
>
>              if ((pm_iir & GEN6_PM_RPS_EVENTS) == 0)
>                      return;
>     @@ -1192,6 +1243,19 @@ static void snb_gt_irq_handler(struct
>     drm_device *dev,
>                      ivybridge_parity_error_irq_handler(dev, gt_iir);
>       }
>
>     +static void gen8_rps_irq_handler(struct drm_i915_private *dev_priv,
>     u32 pm_iir)
>     +{
>     +       if ((pm_iir & GEN6_PM_RPS_EVENTS) == 0)
>     +               return;
>     +
>     +       spin_lock(&dev_priv->irq_lock);
>     +       dev_priv->rps.pm_iir |= pm_iir & GEN6_PM_RPS_EVENTS;
>     +       bdw_disable_pm_irq(dev_priv, pm_iir & GEN6_PM_RPS_EVENTS);
>     +       spin_unlock(&dev_priv->irq_lock);
>     +
>     +       queue_work(dev_priv->wq, &dev_priv->rps.work);
>     +}

We can use the "gen6_rps_irq_handler" right?

>       static irqreturn_t gen8_gt_irq_handler(struct drm_device *dev,
>                                             struct drm_i915_private
>     *dev_priv,
>                                             u32 master_ctl)
>     @@ -1227,6 +1291,16 @@ static irqreturn_t gen8_gt_irq_handler(struct
>     drm_device *dev,
>                              DRM_ERROR("The master control interrupt
>     lied (GT1)!\n");
>              }
>
>     +       if (master_ctl & GEN8_GT_PM_IRQ) {
>     +               tmp = I915_READ(GEN8_GT_IIR(2));
>     +               if (tmp & GEN6_PM_RPS_EVENTS) {
>     +                       ret = IRQ_HANDLED;
>     +                       gen8_rps_irq_handler(dev_priv, tmp);
>     +                       I915_WRITE(GEN8_GT_IIR(1), tmp &
>     GEN6_PM_RPS_EVENTS);
>     +               } else
>     +                       DRM_ERROR("The master control interrupt lied
>     (PM)!\n");
>     +       }
>     +
>              if (master_ctl & GEN8_GT_VECS_IRQ) {
>                      tmp = I915_READ(GEN8_GT_IIR(3));
>                      if (tmp) {
>     diff --git a/drivers/gpu/drm/i915/i915_reg.h
>     b/drivers/gpu/drm/i915/i915_reg.h
>     index d77720e..f9e582e 100644
>     --- a/drivers/gpu/drm/i915/i915_reg.h
>     +++ b/drivers/gpu/drm/i915/i915_reg.h
>     @@ -4024,6 +4024,7 @@
>       #define  GEN8_DE_PIPE_A_IRQ            (1<<16)
>       #define  GEN8_DE_PIPE_IRQ(pipe)                (1<<(16+pipe))
>       #define  GEN8_GT_VECS_IRQ              (1<<6)
>     +#define  GEN8_GT_PM_IRQ                        (1<<4)
>       #define  GEN8_GT_VCS2_IRQ              (1<<3)
>       #define  GEN8_GT_VCS1_IRQ              (1<<2)
>       #define  GEN8_GT_BCS_IRQ               (1<<1)
>     diff --git a/drivers/gpu/drm/i915/intel_drv.h
>     b/drivers/gpu/drm/i915/intel_drv.h
>     index 44067bc..7b49779 100644
>     --- a/drivers/gpu/drm/i915/intel_drv.h
>     +++ b/drivers/gpu/drm/i915/intel_drv.h
>     @@ -608,6 +608,8 @@ void ilk_enable_gt_irq(struct drm_i915_private
>     *dev_priv, uint32_t mask);
>       void ilk_disable_gt_irq(struct drm_i915_private *dev_priv,
>     uint32_t mask);
>       void snb_enable_pm_irq(struct drm_i915_private *dev_priv, uint32_t
>     mask);
>       void snb_disable_pm_irq(struct drm_i915_private *dev_priv,
>     uint32_t mask);
>     +void bdw_enable_pm_irq(struct drm_i915_private *dev_priv, uint32_t
>     mask);
>     +void bdw_disable_pm_irq(struct drm_i915_private *dev_priv, uint32_t
>     mask);
>       void hsw_pc8_disable_interrupts(struct drm_device *dev);
>       void hsw_pc8_restore_interrupts(struct drm_device *dev);
>
>     diff --git a/drivers/gpu/drm/i915/intel_pm.c
>     b/drivers/gpu/drm/i915/intel_pm.c
>     index deaaaf2..a5c9142 100644
>     --- a/drivers/gpu/drm/i915/intel_pm.c
>     +++ b/drivers/gpu/drm/i915/intel_pm.c
>     @@ -3091,6 +3091,25 @@ void valleyview_set_rps(struct drm_device
>     *dev, u8 val)
>              trace_intel_gpu_freq_change(vlv_gpu_freq(dev_priv, val));
>       }
>
>     +static void gen8_disable_rps_interrupts(struct drm_device *dev)
>     +{
>     +       struct drm_i915_private *dev_priv = dev->dev_private;
>     +
>     +       I915_WRITE(GEN6_PMINTRMSK, 0xffffffff);
>     +       I915_WRITE(GEN8_GT_IER(2), I915_READ(GEN8_GT_IER(2)) &
>     +                                  ~GEN6_PM_RPS_EVENTS);
>     +       /* Complete PM interrupt masking here doesn't race with the
>     rps work
>     +        * item again unmasking PM interrupts because that is using
>     a different
>     +        * register (PMIMR) to mask PM interrupts. The only risk is
>     in leaving
>     +        * stale bits in PMIIR and PMIMR which gen6_enable_rps will
>     clean up. */
>     +
>     +       spin_lock_irq(&dev_priv->irq_lock);
>     +       dev_priv->rps.pm_iir = 0;
>     +       spin_unlock_irq(&dev_priv->irq_lock);
>     +
>     +       I915_WRITE(GEN8_GT_IIR(2), GEN6_PM_RPS_EVENTS);
>     +}
>     +
>       static void gen6_disable_rps_interrupts(struct drm_device *dev)
>       {
>              struct drm_i915_private *dev_priv = dev->dev_private;
>     @@ -3116,7 +3135,10 @@ static void gen6_disable_rps(struct
>     drm_device *dev)
>              I915_WRITE(GEN6_RC_CONTROL, 0);
>              I915_WRITE(GEN6_RPNSWREQ, 1 << 31);
>
>     -       gen6_disable_rps_interrupts(dev);
>     +       if (IS_BROADWELL(dev))
>     +               gen8_disable_rps_interrupts(dev);
>     +       else
>     +               gen6_disable_rps_interrupts(dev);
>       }
>
>       static void valleyview_disable_rps(struct drm_device *dev)
>     @@ -3161,6 +3183,19 @@ int intel_enable_rc6(const struct drm_device
>     *dev)
>                      return INTEL_RC6_ENABLE;
>       }
>
>     +static void gen8_enable_rps_interrupts(struct drm_device *dev)
>     +{
>     +       struct drm_i915_private *dev_priv = dev->dev_private;
>     +
>     +       spin_lock_irq(&dev_priv->irq_lock);
>     +       WARN_ON(dev_priv->rps.pm_iir);
>     +       bdw_enable_pm_irq(dev_priv, GEN6_PM_RPS_EVENTS);
>     +       I915_WRITE(GEN8_GT_IIR(2), GEN6_PM_RPS_EVENTS);
>     +       spin_unlock_irq(&dev_priv->irq_lock);
>     +
>     +       I915_WRITE(GEN6_PMINTRMSK, ~GEN6_PM_RPS_EVENTS);
>     +}

As per the spec, I think we need to unmask bit 31 also, if not i don't 
this we will get PM inetrrupts.

>       static void gen6_enable_rps_interrupts(struct drm_device *dev)
>       {
>              struct drm_i915_private *dev_priv = dev->dev_private;
>     @@ -3263,7 +3298,7 @@ static void gen8_enable_rps(struct drm_device
>     *dev)
>
>              gen6_set_rps(dev, (I915_READ(GEN6_GT_PERF_STATUS) & 0xff00)
>      >> 8);
>
>     -       gen6_enable_rps_interrupts(dev);
>     +       gen8_enable_rps_interrupts(dev);
>
>              gen6_gt_force_wake_put(dev_priv, FORCEWAKE_ALL);
>       }
>     --
>     1.8.5.3
>
>     _______________________________________________
>     Intel-gfx mailing list
>     Intel-gfx@lists.freedesktop.org <mailto:Intel-gfx@lists.freedesktop.org>
>     http://lists.freedesktop.org/mailman/listinfo/intel-gfx
>
>

  parent reply	other threads:[~2014-02-07  6:43 UTC|newest]

Thread overview: 97+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-01-29  4:25 [PATCH 0/9] Broadwel RC6 & RPS Ben Widawsky
2014-01-29  4:25 ` [PATCH 1/9] drm/i915: Clarify RC6 enabling Ben Widawsky
2014-02-06 13:38   ` Rodrigo Vivi
     [not found]   ` <CAOh5HuUmDmAC9Nuu3DWYO2kU+Q5kyHyxSmF4rjADaY1iY6=RaQ@mail.gmail.com>
2014-02-07  5:30     ` S, Deepak
2014-02-18  3:01   ` [PATCH 00/11] [v2] BDW RPS + RC6 + rps fixlets Ben Widawsky
2014-02-18  3:01     ` [PATCH 01/11] drm/i915: Reorganize the overclock code Ben Widawsky
2014-02-18  3:01     ` [PATCH 02/11] drm/i915: Fix coding style for RPS Ben Widawsky
2014-02-18  3:01     ` [PATCH 03/11] drm/i915: Rename and comment all the RPS *stuff* Ben Widawsky
2014-02-18 19:03       ` [PATCH 03/11] [v2] " Ben Widawsky
2014-02-22 13:37       ` [PATCH 03/11] " Chris Wilson
2014-02-22 19:34         ` Ben Widawsky
2014-02-22 19:37           ` Chris Wilson
2014-02-22 19:40             ` Ben Widawsky
2014-02-22 20:08               ` Chris Wilson
2014-02-25  0:54                 ` Ben Widawsky
2014-02-22 19:38           ` Ben Widawsky
2014-02-22 20:14             ` Chris Wilson
2014-03-19  1:27         ` Ben Widawsky
2014-03-19  2:38           ` Ben Widawsky
2014-03-19  6:49             ` Chris Wilson
2014-02-18  3:01     ` [PATCH 04/11] drm/i915: Remove extraneous MMIO for RPS Ben Widawsky
2014-02-18  3:01     ` [PATCH 05/11] drm/i915: remove rps local variables Ben Widawsky
2014-02-18  3:01     ` [PATCH 06/11] drm/i915/bdw: Set initial rps freq to nominal Ben Widawsky
2014-02-18  3:01     ` [PATCH 07/11] drm/i915/bdw: Extract rp_state_caps logic Ben Widawsky
2014-02-18  3:01     ` [PATCH 08/11] drm/i915/bdw: RPS frequency bits are the same as HSW Ben Widawsky
2014-02-18  3:01     ` [PATCH 09/11] drm/i915/bdw: Implement a basic PM interrupt handler Ben Widawsky
2014-02-18  3:01     ` [PATCH 10/11] drm/i915/bdw: Enable RC6 Ben Widawsky
2014-02-18  3:01     ` [PATCH 11/11] drm/i915/bdw: Ensure a context is loaded before RC6 Ben Widawsky
2014-02-18  3:03       ` [PATCH 11/11] [v2] " Ben Widawsky
2014-02-18  3:56         ` [PATCH 11/11] [v3] " Ben Widawsky
2014-02-20  6:27           ` [PATCH 11/11] [v4] " Ben Widawsky
2014-03-04 14:30             ` Daniel Vetter
2014-03-20  0:41               ` Ben Widawsky
2014-03-20 13:42                 ` Daniel Vetter
2014-03-20 17:30                   ` Jesse Barnes
2014-03-20 20:12                     ` Jesse Barnes
2014-03-20  1:31     ` [PATCH 00/12] [v3] BDW RPS + RC6 + rps fixlets Ben Widawsky
2014-03-20  1:31       ` [PATCH 01/12] drm/i915: Reorganize the overclock code Ben Widawsky
2014-03-20  7:23         ` Chris Wilson
2014-03-20  1:31       ` [PATCH 02/12] drm/i915: Fix coding style for RPS Ben Widawsky
2014-03-20  7:31         ` Chris Wilson
2014-03-24 10:30         ` Deepak S
2014-03-20  1:31       ` [PATCH 03/12] drm/i915: Store the HW min frequency as min_freq Ben Widawsky
2014-03-20  7:29         ` Chris Wilson
2014-03-24 10:31         ` Deepak S
2014-03-20  1:31       ` [PATCH 04/12] drm/i915: Rename and comment all the RPS *stuff* Ben Widawsky
2014-03-20  7:01         ` Chris Wilson
2014-03-20  1:31       ` [PATCH 05/12] drm/i915: Remove extraneous MMIO for RPS Ben Widawsky
2014-03-20  7:30         ` Chris Wilson
2014-03-20  1:31       ` [PATCH 06/12] drm/i915: remove rps local variables Ben Widawsky
2014-03-20  7:30         ` Chris Wilson
2014-03-20 13:46           ` Daniel Vetter
2014-03-20  1:31       ` [PATCH 07/12] drm/i915/bdw: Set initial rps freq to RP0 Ben Widawsky
2014-03-20  7:24         ` Chris Wilson
2014-03-22 18:42           ` Ben Widawsky
2014-03-22 21:06             ` Chris Wilson
2014-03-24 19:27               ` Ben Widawsky
2014-03-20  1:31       ` [PATCH 08/12] drm/i915/bdw: Extract rp_state_caps logic Ben Widawsky
2014-03-20  7:28         ` Chris Wilson
2014-03-22 18:46           ` Ben Widawsky
2014-03-20  1:31       ` [PATCH 09/12] drm/i915/bdw: RPS frequency bits are the same as HSW Ben Widawsky
2014-03-20  1:31       ` [PATCH 10/12] drm/i915/bdw: Implement a basic PM interrupt handler Ben Widawsky
2014-03-24 19:30         ` Ben Widawsky
2014-03-20  1:31       ` [PATCH 11/12] drm/i915/bdw: Ensure a context is loaded before RC6 Ben Widawsky
2014-03-20  7:35         ` Chris Wilson
2014-03-20  1:31       ` [PATCH 12/12] drm/i915/bdw: Enable RC6 Ben Widawsky
2014-03-24 10:27         ` Deepak S
2014-01-29  4:25 ` [PATCH 2/9] drm/i915: Stop pretending VLV has rc6+ Ben Widawsky
2014-02-06 13:39   ` Rodrigo Vivi
     [not found]   ` <CAOh5HuXxFqRixpPSeOpi=1t2sL=sVfmjdMR445dEQBozg1Z43w@mail.gmail.com>
2014-02-07  5:42     ` S, Deepak
2014-01-29  4:25 ` [PATCH 3/9] drm/i915: Just print rc6 facts Ben Widawsky
2014-02-06 13:41   ` Rodrigo Vivi
     [not found]   ` <CAOh5HuW+_5n=zfDSf_F1aT+v7xzdm_GwUxKC5t8g6_LVCX6X_g@mail.gmail.com>
2014-02-07  5:44     ` S, Deepak
2014-01-29  4:25 ` [PATCH 4/9] drm/i915/bdw: Use centralized rc6 info print Ben Widawsky
2014-02-06 13:42   ` Rodrigo Vivi
2014-02-11 16:12     ` Daniel Vetter
2014-02-14 20:34       ` Ben Widawsky
2014-02-14 20:41         ` Chris Wilson
2014-02-17 19:41           ` Ben Widawsky
     [not found]   ` <CAOh5HuVu0vvQNFKt2FhVf9CrXQa47WAfaqWP2EHp=mBMgExTkQ@mail.gmail.com>
2014-02-07  5:46     ` S, Deepak
2014-01-29  4:25 ` [PATCH 5/9] drm/i915/bdw: Extract rp_state_caps logic Ben Widawsky
2014-01-29  4:25 ` [PATCH 5/9] drm/i915/bdw: Set rp_state_caps Ben Widawsky
2014-02-06 13:45   ` Rodrigo Vivi
     [not found]   ` <CAOh5HuUqCUM-2-yxCbPcCZ53yTxN+8Q5+syiAXqa86Vp47T70A@mail.gmail.com>
2014-02-07  6:10     ` S, Deepak
2014-01-29  4:25 ` [PATCH 6/9] drm/i915/bdw: Set initial rps freq to nominal Ben Widawsky
2014-01-29  4:25 ` [PATCH 7/9] drm/i915/bdw: RPS frequency bits are the same as HSW Ben Widawsky
2014-02-06 13:52   ` Rodrigo Vivi
     [not found]   ` <CAOh5HuU8bnYppf7D5k39QuuDkbHCUVznuVHzvd2dW1mDN0GpBA@mail.gmail.com>
2014-02-07  6:25     ` S, Deepak
2014-01-29  4:25 ` [PATCH 8/9] drm/i915/bdw: Implement a basic PM interrupt handler Ben Widawsky
2014-02-06 14:15   ` Rodrigo Vivi
2014-02-17 20:01     ` Ben Widawsky
     [not found]   ` <CAOh5HuXYmUmGM2tDGO6KCT9Q1V6znbAwQf5OoC27++078bvfRg@mail.gmail.com>
2014-02-07  6:43     ` S, Deepak [this message]
2014-01-29  4:25 ` [PATCH 9/9] drm/i915/bdw: Enable RC6 Ben Widawsky
2014-02-06 13:54   ` Rodrigo Vivi
2014-02-17 20:04     ` Ben Widawsky
2014-02-17 20:07       ` Ben Widawsky
     [not found]   ` <CAOh5HuW-f4xdojasEP3wkSoVH3W1NJNdPACafgnPfVujFe4fjw@mail.gmail.com>
2014-02-07  6:47     ` S, Deepak

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=52F4808B.6040803@intel.com \
    --to=deepak.s@intel.com \
    --cc=benjamin.widawsky@intel.com \
    --cc=intel-gfx@lists.freedesktop.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox