aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/gma500/psb_irq.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/gma500/psb_irq.c')
-rw-r--r--drivers/gpu/drm/gma500/psb_irq.c36
1 files changed, 28 insertions, 8 deletions
diff --git a/drivers/gpu/drm/gma500/psb_irq.c b/drivers/gpu/drm/gma500/psb_irq.c
index 1869586457b1..8652cdf3f03f 100644
--- a/drivers/gpu/drm/gma500/psb_irq.c
+++ b/drivers/gpu/drm/gma500/psb_irq.c
@@ -190,6 +190,9 @@ static void mid_pipe_event_handler(struct drm_device *dev, int pipe)
190 */ 190 */
191static void psb_vdc_interrupt(struct drm_device *dev, uint32_t vdc_stat) 191static void psb_vdc_interrupt(struct drm_device *dev, uint32_t vdc_stat)
192{ 192{
193 if (vdc_stat & _PSB_IRQ_ASLE)
194 psb_intel_opregion_asle_intr(dev);
195
193 if (vdc_stat & _PSB_VSYNC_PIPEA_FLAG) 196 if (vdc_stat & _PSB_VSYNC_PIPEA_FLAG)
194 mid_pipe_event_handler(dev, 0); 197 mid_pipe_event_handler(dev, 0);
195 198
@@ -199,11 +202,9 @@ static void psb_vdc_interrupt(struct drm_device *dev, uint32_t vdc_stat)
199 202
200irqreturn_t psb_irq_handler(DRM_IRQ_ARGS) 203irqreturn_t psb_irq_handler(DRM_IRQ_ARGS)
201{ 204{
202 struct drm_device *dev = (struct drm_device *) arg; 205 struct drm_device *dev = arg;
203 struct drm_psb_private *dev_priv = 206 struct drm_psb_private *dev_priv = dev->dev_private;
204 (struct drm_psb_private *) dev->dev_private; 207 uint32_t vdc_stat, dsp_int = 0, sgx_int = 0, hotplug_int = 0;
205
206 uint32_t vdc_stat, dsp_int = 0, sgx_int = 0;
207 int handled = 0; 208 int handled = 0;
208 209
209 spin_lock(&dev_priv->irqmask_lock); 210 spin_lock(&dev_priv->irqmask_lock);
@@ -220,6 +221,8 @@ irqreturn_t psb_irq_handler(DRM_IRQ_ARGS)
220 221
221 if (vdc_stat & _PSB_IRQ_SGX_FLAG) 222 if (vdc_stat & _PSB_IRQ_SGX_FLAG)
222 sgx_int = 1; 223 sgx_int = 1;
224 if (vdc_stat & _PSB_IRQ_DISP_HOTSYNC)
225 hotplug_int = 1;
223 226
224 vdc_stat &= dev_priv->vdc_irq_mask; 227 vdc_stat &= dev_priv->vdc_irq_mask;
225 spin_unlock(&dev_priv->irqmask_lock); 228 spin_unlock(&dev_priv->irqmask_lock);
@@ -241,6 +244,13 @@ irqreturn_t psb_irq_handler(DRM_IRQ_ARGS)
241 handled = 1; 244 handled = 1;
242 } 245 }
243 246
247 /* Note: this bit has other meanings on some devices, so we will
248 need to address that later if it ever matters */
249 if (hotplug_int && dev_priv->ops->hotplug) {
250 handled = dev_priv->ops->hotplug(dev);
251 REG_WRITE(PORT_HOTPLUG_STAT, REG_READ(PORT_HOTPLUG_STAT));
252 }
253
244 PSB_WVDC32(vdc_stat, PSB_INT_IDENTITY_R); 254 PSB_WVDC32(vdc_stat, PSB_INT_IDENTITY_R);
245 (void) PSB_RVDC32(PSB_INT_IDENTITY_R); 255 (void) PSB_RVDC32(PSB_INT_IDENTITY_R);
246 DRM_READMEMORYBARRIER(); 256 DRM_READMEMORYBARRIER();
@@ -273,6 +283,11 @@ void psb_irq_preinstall(struct drm_device *dev)
273 dev_priv->vdc_irq_mask |= _MDFLD_PIPEC_EVENT_FLAG; 283 dev_priv->vdc_irq_mask |= _MDFLD_PIPEC_EVENT_FLAG;
274 */ 284 */
275 285
286 /* Revisit this area - want per device masks ? */
287 if (dev_priv->ops->hotplug)
288 dev_priv->vdc_irq_mask |= _PSB_IRQ_DISP_HOTSYNC;
289 dev_priv->vdc_irq_mask |= _PSB_IRQ_ASLE;
290
276 /* This register is safe even if display island is off */ 291 /* This register is safe even if display island is off */
277 PSB_WVDC32(~dev_priv->vdc_irq_mask, PSB_INT_MASK_R); 292 PSB_WVDC32(~dev_priv->vdc_irq_mask, PSB_INT_MASK_R);
278 spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags); 293 spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags);
@@ -305,18 +320,23 @@ int psb_irq_postinstall(struct drm_device *dev)
305 else 320 else
306 psb_disable_pipestat(dev_priv, 2, PIPE_VBLANK_INTERRUPT_ENABLE); 321 psb_disable_pipestat(dev_priv, 2, PIPE_VBLANK_INTERRUPT_ENABLE);
307 322
323 if (dev_priv->ops->hotplug_enable)
324 dev_priv->ops->hotplug_enable(dev, true);
325
308 spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags); 326 spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags);
309 return 0; 327 return 0;
310} 328}
311 329
312void psb_irq_uninstall(struct drm_device *dev) 330void psb_irq_uninstall(struct drm_device *dev)
313{ 331{
314 struct drm_psb_private *dev_priv = 332 struct drm_psb_private *dev_priv = dev->dev_private;
315 (struct drm_psb_private *) dev->dev_private;
316 unsigned long irqflags; 333 unsigned long irqflags;
317 334
318 spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags); 335 spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags);
319 336
337 if (dev_priv->ops->hotplug_enable)
338 dev_priv->ops->hotplug_enable(dev, false);
339
320 PSB_WVDC32(0xFFFFFFFF, PSB_HWSTAM); 340 PSB_WVDC32(0xFFFFFFFF, PSB_HWSTAM);
321 341
322 if (dev->vblank_enabled[0]) 342 if (dev->vblank_enabled[0])
@@ -406,7 +426,7 @@ void psb_irq_turn_off_dpst(struct drm_device *dev)
406 psb_disable_pipestat(dev_priv, 0, PIPE_DPST_EVENT_ENABLE); 426 psb_disable_pipestat(dev_priv, 0, PIPE_DPST_EVENT_ENABLE);
407 427
408 pwm_reg = PSB_RVDC32(PWM_CONTROL_LOGIC); 428 pwm_reg = PSB_RVDC32(PWM_CONTROL_LOGIC);
409 PSB_WVDC32(pwm_reg & !(PWM_PHASEIN_INT_ENABLE), 429 PSB_WVDC32(pwm_reg & ~PWM_PHASEIN_INT_ENABLE,
410 PWM_CONTROL_LOGIC); 430 PWM_CONTROL_LOGIC);
411 pwm_reg = PSB_RVDC32(PWM_CONTROL_LOGIC); 431 pwm_reg = PSB_RVDC32(PWM_CONTROL_LOGIC);
412 432