aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/gma500/cdv_device.c
diff options
context:
space:
mode:
authorAlan Cox <alan@linux.intel.com>2012-04-25 09:38:32 -0400
committerDave Airlie <airlied@redhat.com>2012-04-27 04:24:21 -0400
commitae0a246aef0d185db2947912fe9cf7dae1d91b7a (patch)
tree05c7256420a977a3dc3d1792de34d5be47a51060 /drivers/gpu/drm/gma500/cdv_device.c
parent68cb638f9219eeb4967adf08587f4aba64923c3a (diff)
gma500: Add the base elements of CDV hotplug support
Signed-off-by: Alan Cox <alan@linux.intel.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/gma500/cdv_device.c')
-rw-r--r--drivers/gpu/drm/gma500/cdv_device.c41
1 files changed, 39 insertions, 2 deletions
diff --git a/drivers/gpu/drm/gma500/cdv_device.c b/drivers/gpu/drm/gma500/cdv_device.c
index 5cc06a8fcb7a..62f9b735459b 100644
--- a/drivers/gpu/drm/gma500/cdv_device.c
+++ b/drivers/gpu/drm/gma500/cdv_device.c
@@ -462,13 +462,48 @@ static void cdv_get_core_freq(struct drm_device *dev)
462 } 462 }
463} 463}
464 464
465static void cdv_hotplug_work_func(struct work_struct *work)
466{
467 struct drm_psb_private *dev_priv = container_of(work, struct drm_psb_private,
468 hotplug_work);
469 struct drm_device *dev = dev_priv->dev;
470
471 /* Just fire off a uevent and let userspace tell us what to do */
472 drm_helper_hpd_irq_event(dev);
473}
474
475/* The core driver has received a hotplug IRQ. We are in IRQ context
476 so extract the needed information and kick off queued processing */
477
478static int cdv_hotplug_event(struct drm_device *dev)
479{
480 struct drm_psb_private *dev_priv = dev->dev_private;
481 schedule_work(&dev_priv->hotplug_work);
482 REG_WRITE(PORT_HOTPLUG_STAT, REG_READ(PORT_HOTPLUG_STAT));
483 return 1;
484}
485
486static void cdv_hotplug_enable(struct drm_device *dev, bool on)
487{
488 if (on) {
489 u32 hotplug = REG_READ(PORT_HOTPLUG_EN);
490 hotplug |= HDMIB_HOTPLUG_INT_EN | HDMIC_HOTPLUG_INT_EN |
491 HDMID_HOTPLUG_INT_EN | CRT_HOTPLUG_INT_EN;
492 REG_WRITE(PORT_HOTPLUG_EN, hotplug);
493 } else {
494 REG_WRITE(PORT_HOTPLUG_EN, 0);
495 REG_WRITE(PORT_HOTPLUG_STAT, REG_READ(PORT_HOTPLUG_STAT));
496 }
497}
498
465static int cdv_chip_setup(struct drm_device *dev) 499static int cdv_chip_setup(struct drm_device *dev)
466{ 500{
501 struct drm_psb_private *dev_priv = dev->dev_private;
502 INIT_WORK(&dev_priv->hotplug_work, cdv_hotplug_work_func);
467 cdv_get_core_freq(dev); 503 cdv_get_core_freq(dev);
468 gma_intel_opregion_init(dev); 504 gma_intel_opregion_init(dev);
469 psb_intel_init_bios(dev); 505 psb_intel_init_bios(dev);
470 REG_WRITE(PORT_HOTPLUG_EN, 0); 506 cdv_hotplug_enable(dev, false);
471 REG_WRITE(PORT_HOTPLUG_STAT, REG_READ(PORT_HOTPLUG_STAT));
472 return 0; 507 return 0;
473} 508}
474 509
@@ -489,6 +524,8 @@ const struct psb_ops cdv_chip_ops = {
489 .crtc_funcs = &cdv_intel_crtc_funcs, 524 .crtc_funcs = &cdv_intel_crtc_funcs,
490 525
491 .output_init = cdv_output_init, 526 .output_init = cdv_output_init,
527 .hotplug = cdv_hotplug_event,
528 .hotplug_enable = cdv_hotplug_enable,
492 529
493#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE 530#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
494 .backlight_init = cdv_backlight_init, 531 .backlight_init = cdv_backlight_init,