Skip to content

Commit

Permalink
gma500: Add ops for hotplug support.
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Alan Cox authored and Dave Airlie committed Apr 27, 2012
1 parent d235e64 commit 68cb638
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 7 deletions.
3 changes: 3 additions & 0 deletions drivers/gpu/drm/gma500/psb_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ enum {
#define _PSB_VSYNC_PIPEA_FLAG (1<<7)
#define _MDFLD_MIPIA_FLAG (1<<16)
#define _MDFLD_MIPIC_FLAG (1<<17)
#define _PSB_IRQ_DISP_HOTSYNC (1<<17)
#define _PSB_IRQ_SGX_FLAG (1<<18)
#define _PSB_IRQ_MSVDX_FLAG (1<<19)
#define _LNC_IRQ_TOPAZ_FLAG (1<<20)
Expand Down Expand Up @@ -703,6 +704,8 @@ struct psb_ops {

/* Display management hooks */
int (*output_init)(struct drm_device *dev);
int (*hotplug)(struct drm_device *dev);
void (*hotplug_enable)(struct drm_device *dev, bool on);
/* Power management hooks */
void (*init_pm)(struct drm_device *dev);
int (*save_regs)(struct drm_device *dev);
Expand Down
30 changes: 23 additions & 7 deletions drivers/gpu/drm/gma500/psb_irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -199,11 +199,9 @@ static void psb_vdc_interrupt(struct drm_device *dev, uint32_t vdc_stat)

irqreturn_t psb_irq_handler(DRM_IRQ_ARGS)
{
struct drm_device *dev = (struct drm_device *) arg;
struct drm_psb_private *dev_priv =
(struct drm_psb_private *) dev->dev_private;

uint32_t vdc_stat, dsp_int = 0, sgx_int = 0;
struct drm_device *dev = arg;
struct drm_psb_private *dev_priv = dev->dev_private;
uint32_t vdc_stat, dsp_int = 0, sgx_int = 0, hotplug_int = 0;
int handled = 0;

spin_lock(&dev_priv->irqmask_lock);
Expand All @@ -220,6 +218,8 @@ irqreturn_t psb_irq_handler(DRM_IRQ_ARGS)

if (vdc_stat & _PSB_IRQ_SGX_FLAG)
sgx_int = 1;
if (vdc_stat & _PSB_IRQ_DISP_HOTSYNC)
hotplug_int = 1;

vdc_stat &= dev_priv->vdc_irq_mask;
spin_unlock(&dev_priv->irqmask_lock);
Expand All @@ -241,6 +241,13 @@ irqreturn_t psb_irq_handler(DRM_IRQ_ARGS)
handled = 1;
}

/* Note: this bit has other meanings on some devices, so we will
need to address that later if it ever matters */
if (hotplug_int && dev_priv->ops->hotplug) {
handled = dev_priv->ops->hotplug(dev);
REG_WRITE(PORT_HOTPLUG_STAT, REG_READ(PORT_HOTPLUG_STAT));
}

PSB_WVDC32(vdc_stat, PSB_INT_IDENTITY_R);
(void) PSB_RVDC32(PSB_INT_IDENTITY_R);
DRM_READMEMORYBARRIER();
Expand Down Expand Up @@ -273,6 +280,10 @@ void psb_irq_preinstall(struct drm_device *dev)
dev_priv->vdc_irq_mask |= _MDFLD_PIPEC_EVENT_FLAG;
*/

/* Revisit this area - want per device masks ? */
if (dev_priv->ops->hotplug)
dev_priv->vdc_irq_mask |= _PSB_IRQ_DISP_HOTSYNC;

/* This register is safe even if display island is off */
PSB_WVDC32(~dev_priv->vdc_irq_mask, PSB_INT_MASK_R);
spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags);
Expand Down Expand Up @@ -305,18 +316,23 @@ int psb_irq_postinstall(struct drm_device *dev)
else
psb_disable_pipestat(dev_priv, 2, PIPE_VBLANK_INTERRUPT_ENABLE);

if (dev_priv->ops->hotplug_enable)
dev_priv->ops->hotplug_enable(dev, true);

spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags);
return 0;
}

void psb_irq_uninstall(struct drm_device *dev)
{
struct drm_psb_private *dev_priv =
(struct drm_psb_private *) dev->dev_private;
struct drm_psb_private *dev_priv = dev->dev_private;
unsigned long irqflags;

spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags);

if (dev_priv->ops->hotplug_enable)
dev_priv->ops->hotplug_enable(dev, false);

PSB_WVDC32(0xFFFFFFFF, PSB_HWSTAM);

if (dev->vblank_enabled[0])
Expand Down

0 comments on commit 68cb638

Please sign in to comment.