aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlan Cox <alan@linux.intel.com>2012-04-25 09:38:20 -0400
committerDave Airlie <airlied@redhat.com>2012-04-27 04:24:20 -0400
commit68cb638f9219eeb4967adf08587f4aba64923c3a (patch)
treec65ab78fced58037a2cbc429f0b05c361a2c5b0c
parentd235e64a4367ad3ff204309490c4325b4f89b25b (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.h3
-rw-r--r--drivers/gpu/drm/gma500/psb_irq.c30
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
200irqreturn_t psb_irq_handler(DRM_IRQ_ARGS) 200irqreturn_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
312void psb_irq_uninstall(struct drm_device *dev) 326void 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])