aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/i915_irq.c
diff options
context:
space:
mode:
authorImre Deak <imre.deak@intel.com>2014-03-04 12:23:07 -0500
committerDaniel Vetter <daniel.vetter@ffwll.ch>2014-03-07 16:36:56 -0500
commitf8b79e58dc79f3f0edeb5194198a331374b11f82 (patch)
tree829c2379504153de2f2202d46309fe61f0cf17a8 /drivers/gpu/drm/i915/i915_irq.c
parent25eaa003bd186e415d94bf0191152f1cd7252d9a (diff)
drm/i915: vlv: factor out valleyview_display_irq_install
We'll need to disable/re-enable the display-side IRQs when turning off/on the VLV display power well. Factor out the helper functions for this. For now keep the display IRQs enabled by default, so the functionality doesn't change. This will be changed to enable/disable the IRQs on-demand when adding support for VLV power wells in an upcoming patch. v2: - take the irq spin lock for the whole enable/disable sequence as these can be called with interrupts enabled Signed-off-by: Imre Deak <imre.deak@intel.com> Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu/drm/i915/i915_irq.c')
-rw-r--r--drivers/gpu/drm/i915/i915_irq.c116
1 files changed, 100 insertions, 16 deletions
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 4a19306b2d73..d6f827ab8f01 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -3025,36 +3025,113 @@ static int ironlake_irq_postinstall(struct drm_device *dev)
3025 return 0; 3025 return 0;
3026} 3026}
3027 3027
3028static void valleyview_display_irqs_install(struct drm_i915_private *dev_priv)
3029{
3030 u32 pipestat_mask;
3031 u32 iir_mask;
3032
3033 pipestat_mask = PIPESTAT_INT_STATUS_MASK |
3034 PIPE_FIFO_UNDERRUN_STATUS;
3035
3036 I915_WRITE(PIPESTAT(PIPE_A), pipestat_mask);
3037 I915_WRITE(PIPESTAT(PIPE_B), pipestat_mask);
3038 POSTING_READ(PIPESTAT(PIPE_A));
3039
3040 pipestat_mask = PLANE_FLIP_DONE_INT_STATUS_VLV |
3041 PIPE_CRC_DONE_INTERRUPT_STATUS;
3042
3043 i915_enable_pipestat(dev_priv, PIPE_A, pipestat_mask |
3044 PIPE_GMBUS_INTERRUPT_STATUS);
3045 i915_enable_pipestat(dev_priv, PIPE_B, pipestat_mask);
3046
3047 iir_mask = I915_DISPLAY_PORT_INTERRUPT |
3048 I915_DISPLAY_PIPE_A_EVENT_INTERRUPT |
3049 I915_DISPLAY_PIPE_B_EVENT_INTERRUPT;
3050 dev_priv->irq_mask &= ~iir_mask;
3051
3052 I915_WRITE(VLV_IIR, iir_mask);
3053 I915_WRITE(VLV_IIR, iir_mask);
3054 I915_WRITE(VLV_IMR, dev_priv->irq_mask);
3055 I915_WRITE(VLV_IER, ~dev_priv->irq_mask);
3056 POSTING_READ(VLV_IER);
3057}
3058
3059static void valleyview_display_irqs_uninstall(struct drm_i915_private *dev_priv)
3060{
3061 u32 pipestat_mask;
3062 u32 iir_mask;
3063
3064 iir_mask = I915_DISPLAY_PORT_INTERRUPT |
3065 I915_DISPLAY_PIPE_A_EVENT_INTERRUPT |
3066 I915_DISPLAY_PIPE_A_EVENT_INTERRUPT;
3067
3068 dev_priv->irq_mask |= iir_mask;
3069 I915_WRITE(VLV_IER, ~dev_priv->irq_mask);
3070 I915_WRITE(VLV_IMR, dev_priv->irq_mask);
3071 I915_WRITE(VLV_IIR, iir_mask);
3072 I915_WRITE(VLV_IIR, iir_mask);
3073 POSTING_READ(VLV_IIR);
3074
3075 pipestat_mask = PLANE_FLIP_DONE_INT_STATUS_VLV |
3076 PIPE_CRC_DONE_INTERRUPT_STATUS;
3077
3078 i915_disable_pipestat(dev_priv, PIPE_A, pipestat_mask |
3079 PIPE_GMBUS_INTERRUPT_STATUS);
3080 i915_disable_pipestat(dev_priv, PIPE_B, pipestat_mask);
3081
3082 pipestat_mask = PIPESTAT_INT_STATUS_MASK |
3083 PIPE_FIFO_UNDERRUN_STATUS;
3084 I915_WRITE(PIPESTAT(PIPE_A), pipestat_mask);
3085 I915_WRITE(PIPESTAT(PIPE_B), pipestat_mask);
3086 POSTING_READ(PIPESTAT(PIPE_A));
3087}
3088
3089void valleyview_enable_display_irqs(struct drm_i915_private *dev_priv)
3090{
3091 assert_spin_locked(&dev_priv->irq_lock);
3092
3093 if (dev_priv->display_irqs_enabled)
3094 return;
3095
3096 dev_priv->display_irqs_enabled = true;
3097
3098 if (dev_priv->dev->irq_enabled)
3099 valleyview_display_irqs_install(dev_priv);
3100}
3101
3102void valleyview_disable_display_irqs(struct drm_i915_private *dev_priv)
3103{
3104 assert_spin_locked(&dev_priv->irq_lock);
3105
3106 if (!dev_priv->display_irqs_enabled)
3107 return;
3108
3109 dev_priv->display_irqs_enabled = false;
3110
3111 if (dev_priv->dev->irq_enabled)
3112 valleyview_display_irqs_uninstall(dev_priv);
3113}
3114
3028static int valleyview_irq_postinstall(struct drm_device *dev) 3115static int valleyview_irq_postinstall(struct drm_device *dev)
3029{ 3116{
3030 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; 3117 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
3031 u32 enable_mask;
3032 u32 pipestat_enable = PLANE_FLIP_DONE_INT_STATUS_VLV |
3033 PIPE_CRC_DONE_INTERRUPT_STATUS;
3034 unsigned long irqflags; 3118 unsigned long irqflags;
3035 3119
3036 enable_mask = I915_DISPLAY_PORT_INTERRUPT; 3120 dev_priv->irq_mask = ~0;
3037 enable_mask |= I915_DISPLAY_PIPE_A_EVENT_INTERRUPT |
3038 I915_DISPLAY_PIPE_B_EVENT_INTERRUPT;
3039
3040 dev_priv->irq_mask = ~enable_mask;
3041 3121
3042 I915_WRITE(PORT_HOTPLUG_EN, 0); 3122 I915_WRITE(PORT_HOTPLUG_EN, 0);
3043 POSTING_READ(PORT_HOTPLUG_EN); 3123 POSTING_READ(PORT_HOTPLUG_EN);
3044 3124
3045 I915_WRITE(VLV_IMR, dev_priv->irq_mask); 3125 I915_WRITE(VLV_IMR, dev_priv->irq_mask);
3046 I915_WRITE(VLV_IER, enable_mask); 3126 I915_WRITE(VLV_IER, ~dev_priv->irq_mask);
3047 I915_WRITE(VLV_IIR, 0xffffffff); 3127 I915_WRITE(VLV_IIR, 0xffffffff);
3048 I915_WRITE(PIPESTAT(0), 0xffff);
3049 I915_WRITE(PIPESTAT(1), 0xffff);
3050 POSTING_READ(VLV_IER); 3128 POSTING_READ(VLV_IER);
3051 3129
3052 /* Interrupt setup is already guaranteed to be single-threaded, this is 3130 /* Interrupt setup is already guaranteed to be single-threaded, this is
3053 * just to make the assert_spin_locked check happy. */ 3131 * just to make the assert_spin_locked check happy. */
3054 spin_lock_irqsave(&dev_priv->irq_lock, irqflags); 3132 spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
3055 i915_enable_pipestat(dev_priv, PIPE_A, pipestat_enable); 3133 if (dev_priv->display_irqs_enabled)
3056 i915_enable_pipestat(dev_priv, PIPE_A, PIPE_GMBUS_INTERRUPT_STATUS); 3134 valleyview_display_irqs_install(dev_priv);
3057 i915_enable_pipestat(dev_priv, PIPE_B, pipestat_enable);
3058 spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); 3135 spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
3059 3136
3060 I915_WRITE(VLV_IIR, 0xffffffff); 3137 I915_WRITE(VLV_IIR, 0xffffffff);
@@ -3185,6 +3262,7 @@ static void gen8_irq_uninstall(struct drm_device *dev)
3185static void valleyview_irq_uninstall(struct drm_device *dev) 3262static void valleyview_irq_uninstall(struct drm_device *dev)
3186{ 3263{
3187 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; 3264 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
3265 unsigned long irqflags;
3188 int pipe; 3266 int pipe;
3189 3267
3190 if (!dev_priv) 3268 if (!dev_priv)
@@ -3198,8 +3276,14 @@ static void valleyview_irq_uninstall(struct drm_device *dev)
3198 I915_WRITE(HWSTAM, 0xffffffff); 3276 I915_WRITE(HWSTAM, 0xffffffff);
3199 I915_WRITE(PORT_HOTPLUG_EN, 0); 3277 I915_WRITE(PORT_HOTPLUG_EN, 0);
3200 I915_WRITE(PORT_HOTPLUG_STAT, I915_READ(PORT_HOTPLUG_STAT)); 3278 I915_WRITE(PORT_HOTPLUG_STAT, I915_READ(PORT_HOTPLUG_STAT));
3201 for_each_pipe(pipe) 3279
3202 I915_WRITE(PIPESTAT(pipe), 0xffff); 3280 spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
3281 if (dev_priv->display_irqs_enabled)
3282 valleyview_display_irqs_uninstall(dev_priv);
3283 spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
3284
3285 dev_priv->irq_mask = 0;
3286
3203 I915_WRITE(VLV_IIR, 0xffffffff); 3287 I915_WRITE(VLV_IIR, 0xffffffff);
3204 I915_WRITE(VLV_IMR, 0xffffffff); 3288 I915_WRITE(VLV_IMR, 0xffffffff);
3205 I915_WRITE(VLV_IER, 0x0); 3289 I915_WRITE(VLV_IER, 0x0);