diff options
author | Alan Cox <alan@linux.intel.com> | 2012-04-25 09:38:20 -0400 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2012-04-27 04:24:20 -0400 |
commit | 68cb638f9219eeb4967adf08587f4aba64923c3a (patch) | |
tree | c65ab78fced58037a2cbc429f0b05c361a2c5b0c | |
parent | d235e64a4367ad3ff204309490c4325b4f89b25b (diff) |
gma500: Add ops for hotplug support.
This provides the needed callback hooks to add hotplug display support to
the GMA36x0 devices.
Signed-off-by: Alan Cox <alan@linux.intel.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
-rw-r--r-- | drivers/gpu/drm/gma500/psb_drv.h | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/gma500/psb_irq.c | 30 |
2 files changed, 26 insertions, 7 deletions
diff --git a/drivers/gpu/drm/gma500/psb_drv.h b/drivers/gpu/drm/gma500/psb_drv.h index 6235499f39b8..ab483c34c751 100644 --- a/drivers/gpu/drm/gma500/psb_drv.h +++ b/drivers/gpu/drm/gma500/psb_drv.h | |||
@@ -130,6 +130,7 @@ enum { | |||
130 | #define _PSB_VSYNC_PIPEA_FLAG (1<<7) | 130 | #define _PSB_VSYNC_PIPEA_FLAG (1<<7) |
131 | #define _MDFLD_MIPIA_FLAG (1<<16) | 131 | #define _MDFLD_MIPIA_FLAG (1<<16) |
132 | #define _MDFLD_MIPIC_FLAG (1<<17) | 132 | #define _MDFLD_MIPIC_FLAG (1<<17) |
133 | #define _PSB_IRQ_DISP_HOTSYNC (1<<17) | ||
133 | #define _PSB_IRQ_SGX_FLAG (1<<18) | 134 | #define _PSB_IRQ_SGX_FLAG (1<<18) |
134 | #define _PSB_IRQ_MSVDX_FLAG (1<<19) | 135 | #define _PSB_IRQ_MSVDX_FLAG (1<<19) |
135 | #define _LNC_IRQ_TOPAZ_FLAG (1<<20) | 136 | #define _LNC_IRQ_TOPAZ_FLAG (1<<20) |
@@ -703,6 +704,8 @@ struct psb_ops { | |||
703 | 704 | ||
704 | /* Display management hooks */ | 705 | /* Display management hooks */ |
705 | int (*output_init)(struct drm_device *dev); | 706 | int (*output_init)(struct drm_device *dev); |
707 | int (*hotplug)(struct drm_device *dev); | ||
708 | void (*hotplug_enable)(struct drm_device *dev, bool on); | ||
706 | /* Power management hooks */ | 709 | /* Power management hooks */ |
707 | void (*init_pm)(struct drm_device *dev); | 710 | void (*init_pm)(struct drm_device *dev); |
708 | int (*save_regs)(struct drm_device *dev); | 711 | int (*save_regs)(struct drm_device *dev); |
diff --git a/drivers/gpu/drm/gma500/psb_irq.c b/drivers/gpu/drm/gma500/psb_irq.c index 1869586457b1..2fcdffdc9063 100644 --- a/drivers/gpu/drm/gma500/psb_irq.c +++ b/drivers/gpu/drm/gma500/psb_irq.c | |||
@@ -199,11 +199,9 @@ static void psb_vdc_interrupt(struct drm_device *dev, uint32_t vdc_stat) | |||
199 | 199 | ||
200 | irqreturn_t psb_irq_handler(DRM_IRQ_ARGS) | 200 | irqreturn_t psb_irq_handler(DRM_IRQ_ARGS) |
201 | { | 201 | { |
202 | struct drm_device *dev = (struct drm_device *) arg; | 202 | struct drm_device *dev = arg; |
203 | struct drm_psb_private *dev_priv = | 203 | struct drm_psb_private *dev_priv = dev->dev_private; |
204 | (struct drm_psb_private *) dev->dev_private; | 204 | 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; | 205 | int handled = 0; |
208 | 206 | ||
209 | spin_lock(&dev_priv->irqmask_lock); | 207 | spin_lock(&dev_priv->irqmask_lock); |
@@ -220,6 +218,8 @@ irqreturn_t psb_irq_handler(DRM_IRQ_ARGS) | |||
220 | 218 | ||
221 | if (vdc_stat & _PSB_IRQ_SGX_FLAG) | 219 | if (vdc_stat & _PSB_IRQ_SGX_FLAG) |
222 | sgx_int = 1; | 220 | sgx_int = 1; |
221 | if (vdc_stat & _PSB_IRQ_DISP_HOTSYNC) | ||
222 | hotplug_int = 1; | ||
223 | 223 | ||
224 | vdc_stat &= dev_priv->vdc_irq_mask; | 224 | vdc_stat &= dev_priv->vdc_irq_mask; |
225 | spin_unlock(&dev_priv->irqmask_lock); | 225 | spin_unlock(&dev_priv->irqmask_lock); |
@@ -241,6 +241,13 @@ irqreturn_t psb_irq_handler(DRM_IRQ_ARGS) | |||
241 | handled = 1; | 241 | handled = 1; |
242 | } | 242 | } |
243 | 243 | ||
244 | /* Note: this bit has other meanings on some devices, so we will | ||
245 | need to address that later if it ever matters */ | ||
246 | if (hotplug_int && dev_priv->ops->hotplug) { | ||
247 | handled = dev_priv->ops->hotplug(dev); | ||
248 | REG_WRITE(PORT_HOTPLUG_STAT, REG_READ(PORT_HOTPLUG_STAT)); | ||
249 | } | ||
250 | |||
244 | PSB_WVDC32(vdc_stat, PSB_INT_IDENTITY_R); | 251 | PSB_WVDC32(vdc_stat, PSB_INT_IDENTITY_R); |
245 | (void) PSB_RVDC32(PSB_INT_IDENTITY_R); | 252 | (void) PSB_RVDC32(PSB_INT_IDENTITY_R); |
246 | DRM_READMEMORYBARRIER(); | 253 | DRM_READMEMORYBARRIER(); |
@@ -273,6 +280,10 @@ void psb_irq_preinstall(struct drm_device *dev) | |||
273 | dev_priv->vdc_irq_mask |= _MDFLD_PIPEC_EVENT_FLAG; | 280 | dev_priv->vdc_irq_mask |= _MDFLD_PIPEC_EVENT_FLAG; |
274 | */ | 281 | */ |
275 | 282 | ||
283 | /* Revisit this area - want per device masks ? */ | ||
284 | if (dev_priv->ops->hotplug) | ||
285 | dev_priv->vdc_irq_mask |= _PSB_IRQ_DISP_HOTSYNC; | ||
286 | |||
276 | /* This register is safe even if display island is off */ | 287 | /* This register is safe even if display island is off */ |
277 | PSB_WVDC32(~dev_priv->vdc_irq_mask, PSB_INT_MASK_R); | 288 | PSB_WVDC32(~dev_priv->vdc_irq_mask, PSB_INT_MASK_R); |
278 | spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags); | 289 | spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags); |
@@ -305,18 +316,23 @@ int psb_irq_postinstall(struct drm_device *dev) | |||
305 | else | 316 | else |
306 | psb_disable_pipestat(dev_priv, 2, PIPE_VBLANK_INTERRUPT_ENABLE); | 317 | psb_disable_pipestat(dev_priv, 2, PIPE_VBLANK_INTERRUPT_ENABLE); |
307 | 318 | ||
319 | if (dev_priv->ops->hotplug_enable) | ||
320 | dev_priv->ops->hotplug_enable(dev, true); | ||
321 | |||
308 | spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags); | 322 | spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags); |
309 | return 0; | 323 | return 0; |
310 | } | 324 | } |
311 | 325 | ||
312 | void psb_irq_uninstall(struct drm_device *dev) | 326 | void psb_irq_uninstall(struct drm_device *dev) |
313 | { | 327 | { |
314 | struct drm_psb_private *dev_priv = | 328 | struct drm_psb_private *dev_priv = dev->dev_private; |
315 | (struct drm_psb_private *) dev->dev_private; | ||
316 | unsigned long irqflags; | 329 | unsigned long irqflags; |
317 | 330 | ||
318 | spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags); | 331 | spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags); |
319 | 332 | ||
333 | if (dev_priv->ops->hotplug_enable) | ||
334 | dev_priv->ops->hotplug_enable(dev, false); | ||
335 | |||
320 | PSB_WVDC32(0xFFFFFFFF, PSB_HWSTAM); | 336 | PSB_WVDC32(0xFFFFFFFF, PSB_HWSTAM); |
321 | 337 | ||
322 | if (dev->vblank_enabled[0]) | 338 | if (dev->vblank_enabled[0]) |