diff options
| author | Oscar Mateo <oscar.mateo@intel.com> | 2018-04-05 10:00:50 -0400 |
|---|---|---|
| committer | Mika Kuoppala <mika.kuoppala@linux.intel.com> | 2018-04-06 08:33:25 -0400 |
| commit | d02b98b8e28278f9f0c0f4dd3f172ffcc20fbdbd (patch) | |
| tree | d39c17cd36e82e54c815686125456e352a959108 /drivers/gpu/drm/i915/i915_irq.c | |
| parent | f744dbc2a64d5de0d9b3f883b536c007b1e98fab (diff) | |
drm/i915/icl: Handle RPS interrupts correctly for Gen11
Using the new hierarchical interrupt infrastructure.
v2: Rebase
v3: Rebase
v4: use class/instance handler (Mika)
Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Cc: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Cc: Sagar Arun Kamble <sagar.a.kamble@intel.com>
Cc: Paulo Zanoni <paulo.r.zanoni@intel.com>
Signed-off-by: Oscar Mateo <oscar.mateo@intel.com>
Signed-off-by: Mika Kuoppala <mika.kuoppala@linux.intel.com>
Reviewed-by: Michel Thierry <michel.thierry@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20180405140052.10682-3-mika.kuoppala@linux.intel.com
Diffstat (limited to 'drivers/gpu/drm/i915/i915_irq.c')
| -rw-r--r-- | drivers/gpu/drm/i915/i915_irq.c | 73 |
1 files changed, 62 insertions, 11 deletions
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 45f72a0ece04..36a635475a74 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c | |||
| @@ -308,17 +308,29 @@ void gen5_disable_gt_irq(struct drm_i915_private *dev_priv, uint32_t mask) | |||
| 308 | 308 | ||
| 309 | static i915_reg_t gen6_pm_iir(struct drm_i915_private *dev_priv) | 309 | static i915_reg_t gen6_pm_iir(struct drm_i915_private *dev_priv) |
| 310 | { | 310 | { |
| 311 | WARN_ON_ONCE(INTEL_GEN(dev_priv) >= 11); | ||
| 312 | |||
| 311 | return INTEL_GEN(dev_priv) >= 8 ? GEN8_GT_IIR(2) : GEN6_PMIIR; | 313 | return INTEL_GEN(dev_priv) >= 8 ? GEN8_GT_IIR(2) : GEN6_PMIIR; |
| 312 | } | 314 | } |
| 313 | 315 | ||
| 314 | static i915_reg_t gen6_pm_imr(struct drm_i915_private *dev_priv) | 316 | static i915_reg_t gen6_pm_imr(struct drm_i915_private *dev_priv) |
| 315 | { | 317 | { |
| 316 | return INTEL_GEN(dev_priv) >= 8 ? GEN8_GT_IMR(2) : GEN6_PMIMR; | 318 | if (INTEL_GEN(dev_priv) >= 11) |
| 319 | return GEN11_GPM_WGBOXPERF_INTR_MASK; | ||
| 320 | else if (INTEL_GEN(dev_priv) >= 8) | ||
| 321 | return GEN8_GT_IMR(2); | ||
| 322 | else | ||
| 323 | return GEN6_PMIMR; | ||
| 317 | } | 324 | } |
| 318 | 325 | ||
| 319 | static i915_reg_t gen6_pm_ier(struct drm_i915_private *dev_priv) | 326 | static i915_reg_t gen6_pm_ier(struct drm_i915_private *dev_priv) |
| 320 | { | 327 | { |
| 321 | return INTEL_GEN(dev_priv) >= 8 ? GEN8_GT_IER(2) : GEN6_PMIER; | 328 | if (INTEL_GEN(dev_priv) >= 11) |
| 329 | return GEN11_GPM_WGBOXPERF_INTR_ENABLE; | ||
| 330 | else if (INTEL_GEN(dev_priv) >= 8) | ||
| 331 | return GEN8_GT_IER(2); | ||
| 332 | else | ||
| 333 | return GEN6_PMIER; | ||
| 322 | } | 334 | } |
| 323 | 335 | ||
| 324 | /** | 336 | /** |
| @@ -400,6 +412,32 @@ static void gen6_disable_pm_irq(struct drm_i915_private *dev_priv, u32 disable_m | |||
| 400 | /* though a barrier is missing here, but don't really need a one */ | 412 | /* though a barrier is missing here, but don't really need a one */ |
| 401 | } | 413 | } |
| 402 | 414 | ||
| 415 | static u32 | ||
| 416 | gen11_gt_engine_identity(struct drm_i915_private * const i915, | ||
| 417 | const unsigned int bank, const unsigned int bit); | ||
| 418 | |||
| 419 | void gen11_reset_rps_interrupts(struct drm_i915_private *dev_priv) | ||
| 420 | { | ||
| 421 | u32 dw; | ||
| 422 | |||
| 423 | spin_lock_irq(&dev_priv->irq_lock); | ||
| 424 | |||
| 425 | /* | ||
| 426 | * According to the BSpec, DW_IIR bits cannot be cleared without | ||
| 427 | * first servicing the Selector & Shared IIR registers. | ||
| 428 | */ | ||
| 429 | dw = I915_READ_FW(GEN11_GT_INTR_DW0); | ||
| 430 | while (dw & BIT(GEN11_GTPM)) { | ||
| 431 | gen11_gt_engine_identity(dev_priv, 0, GEN11_GTPM); | ||
| 432 | I915_WRITE_FW(GEN11_GT_INTR_DW0, BIT(GEN11_GTPM)); | ||
| 433 | dw = I915_READ_FW(GEN11_GT_INTR_DW0); | ||
| 434 | } | ||
| 435 | |||
| 436 | dev_priv->gt_pm.rps.pm_iir = 0; | ||
| 437 | |||
| 438 | spin_unlock_irq(&dev_priv->irq_lock); | ||
| 439 | } | ||
| 440 | |||
| 403 | void gen6_reset_rps_interrupts(struct drm_i915_private *dev_priv) | 441 | void gen6_reset_rps_interrupts(struct drm_i915_private *dev_priv) |
| 404 | { | 442 | { |
| 405 | spin_lock_irq(&dev_priv->irq_lock); | 443 | spin_lock_irq(&dev_priv->irq_lock); |
| @@ -415,12 +453,12 @@ void gen6_enable_rps_interrupts(struct drm_i915_private *dev_priv) | |||
| 415 | if (READ_ONCE(rps->interrupts_enabled)) | 453 | if (READ_ONCE(rps->interrupts_enabled)) |
| 416 | return; | 454 | return; |
| 417 | 455 | ||
| 418 | if (WARN_ON_ONCE(IS_GEN11(dev_priv))) | ||
| 419 | return; | ||
| 420 | |||
| 421 | spin_lock_irq(&dev_priv->irq_lock); | 456 | spin_lock_irq(&dev_priv->irq_lock); |
| 422 | WARN_ON_ONCE(rps->pm_iir); | 457 | WARN_ON_ONCE(rps->pm_iir); |
| 423 | WARN_ON_ONCE(I915_READ(gen6_pm_iir(dev_priv)) & dev_priv->pm_rps_events); | 458 | if (INTEL_GEN(dev_priv) >= 11) |
| 459 | WARN_ON_ONCE(I915_READ_FW(GEN11_GT_INTR_DW0) & BIT(GEN11_GTPM)); | ||
| 460 | else | ||
| 461 | WARN_ON_ONCE(I915_READ(gen6_pm_iir(dev_priv)) & dev_priv->pm_rps_events); | ||
| 424 | rps->interrupts_enabled = true; | 462 | rps->interrupts_enabled = true; |
| 425 | gen6_enable_pm_irq(dev_priv, dev_priv->pm_rps_events); | 463 | gen6_enable_pm_irq(dev_priv, dev_priv->pm_rps_events); |
| 426 | 464 | ||
| @@ -434,9 +472,6 @@ void gen6_disable_rps_interrupts(struct drm_i915_private *dev_priv) | |||
| 434 | if (!READ_ONCE(rps->interrupts_enabled)) | 472 | if (!READ_ONCE(rps->interrupts_enabled)) |
| 435 | return; | 473 | return; |
| 436 | 474 | ||
| 437 | if (WARN_ON_ONCE(IS_GEN11(dev_priv))) | ||
| 438 | return; | ||
| 439 | |||
| 440 | spin_lock_irq(&dev_priv->irq_lock); | 475 | spin_lock_irq(&dev_priv->irq_lock); |
| 441 | rps->interrupts_enabled = false; | 476 | rps->interrupts_enabled = false; |
| 442 | 477 | ||
| @@ -453,7 +488,10 @@ void gen6_disable_rps_interrupts(struct drm_i915_private *dev_priv) | |||
| 453 | * state of the worker can be discarded. | 488 | * state of the worker can be discarded. |
| 454 | */ | 489 | */ |
| 455 | cancel_work_sync(&rps->work); | 490 | cancel_work_sync(&rps->work); |
| 456 | gen6_reset_rps_interrupts(dev_priv); | 491 | if (INTEL_GEN(dev_priv) >= 11) |
| 492 | gen11_reset_rps_interrupts(dev_priv); | ||
| 493 | else | ||
| 494 | gen6_reset_rps_interrupts(dev_priv); | ||
| 457 | } | 495 | } |
| 458 | 496 | ||
| 459 | void gen9_reset_guc_interrupts(struct drm_i915_private *dev_priv) | 497 | void gen9_reset_guc_interrupts(struct drm_i915_private *dev_priv) |
| @@ -2768,6 +2806,9 @@ static void | |||
| 2768 | gen11_other_irq_handler(struct drm_i915_private * const i915, | 2806 | gen11_other_irq_handler(struct drm_i915_private * const i915, |
| 2769 | const u8 instance, const u16 iir) | 2807 | const u8 instance, const u16 iir) |
| 2770 | { | 2808 | { |
| 2809 | if (instance == OTHER_GTPM_INSTANCE) | ||
| 2810 | return gen6_rps_irq_handler(i915, iir); | ||
| 2811 | |||
| 2771 | WARN_ONCE(1, "unhandled other interrupt instance=0x%x, iir=0x%x\n", | 2812 | WARN_ONCE(1, "unhandled other interrupt instance=0x%x, iir=0x%x\n", |
| 2772 | instance, iir); | 2813 | instance, iir); |
| 2773 | } | 2814 | } |
| @@ -3330,6 +3371,9 @@ static void gen11_gt_irq_reset(struct drm_i915_private *dev_priv) | |||
| 3330 | I915_WRITE(GEN11_VCS0_VCS1_INTR_MASK, ~0); | 3371 | I915_WRITE(GEN11_VCS0_VCS1_INTR_MASK, ~0); |
| 3331 | I915_WRITE(GEN11_VCS2_VCS3_INTR_MASK, ~0); | 3372 | I915_WRITE(GEN11_VCS2_VCS3_INTR_MASK, ~0); |
| 3332 | I915_WRITE(GEN11_VECS0_VECS1_INTR_MASK, ~0); | 3373 | I915_WRITE(GEN11_VECS0_VECS1_INTR_MASK, ~0); |
| 3374 | |||
| 3375 | I915_WRITE(GEN11_GPM_WGBOXPERF_INTR_ENABLE, 0); | ||
| 3376 | I915_WRITE(GEN11_GPM_WGBOXPERF_INTR_MASK, ~0); | ||
| 3333 | } | 3377 | } |
| 3334 | 3378 | ||
| 3335 | static void gen11_irq_reset(struct drm_device *dev) | 3379 | static void gen11_irq_reset(struct drm_device *dev) |
| @@ -3868,7 +3912,14 @@ static void gen11_gt_irq_postinstall(struct drm_i915_private *dev_priv) | |||
| 3868 | I915_WRITE(GEN11_VCS2_VCS3_INTR_MASK, ~(irqs | irqs << 16)); | 3912 | I915_WRITE(GEN11_VCS2_VCS3_INTR_MASK, ~(irqs | irqs << 16)); |
| 3869 | I915_WRITE(GEN11_VECS0_VECS1_INTR_MASK, ~(irqs | irqs << 16)); | 3913 | I915_WRITE(GEN11_VECS0_VECS1_INTR_MASK, ~(irqs | irqs << 16)); |
| 3870 | 3914 | ||
| 3871 | dev_priv->pm_imr = 0xffffffff; /* TODO */ | 3915 | /* |
| 3916 | * RPS interrupts will get enabled/disabled on demand when RPS itself | ||
| 3917 | * is enabled/disabled. | ||
| 3918 | */ | ||
| 3919 | dev_priv->pm_ier = 0x0; | ||
| 3920 | dev_priv->pm_imr = ~dev_priv->pm_ier; | ||
| 3921 | I915_WRITE(GEN11_GPM_WGBOXPERF_INTR_ENABLE, 0); | ||
| 3922 | I915_WRITE(GEN11_GPM_WGBOXPERF_INTR_MASK, ~0); | ||
| 3872 | } | 3923 | } |
| 3873 | 3924 | ||
| 3874 | static int gen11_irq_postinstall(struct drm_device *dev) | 3925 | static int gen11_irq_postinstall(struct drm_device *dev) |
