aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm
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
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')
-rw-r--r--drivers/gpu/drm/gma500/cdv_device.c41
-rw-r--r--drivers/gpu/drm/gma500/psb_drv.h5
-rw-r--r--drivers/gpu/drm/gma500/psb_intel_reg.h5
3 files changed, 48 insertions, 3 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,
diff --git a/drivers/gpu/drm/gma500/psb_drv.h b/drivers/gpu/drm/gma500/psb_drv.h
index ab483c34c751..d3528a694206 100644
--- a/drivers/gpu/drm/gma500/psb_drv.h
+++ b/drivers/gpu/drm/gma500/psb_drv.h
@@ -626,6 +626,11 @@ struct drm_psb_private {
626 uint32_t msi_addr; 626 uint32_t msi_addr;
627 uint32_t msi_data; 627 uint32_t msi_data;
628 628
629 /*
630 * Hotplug handling
631 */
632
633 struct work_struct hotplug_work;
629 634
630 /* 635 /*
631 * LID-Switch 636 * LID-Switch
diff --git a/drivers/gpu/drm/gma500/psb_intel_reg.h b/drivers/gpu/drm/gma500/psb_intel_reg.h
index cbd8aee2b7ed..519a9cd9ffbc 100644
--- a/drivers/gpu/drm/gma500/psb_intel_reg.h
+++ b/drivers/gpu/drm/gma500/psb_intel_reg.h
@@ -219,7 +219,7 @@
219#define DPLLB_LVDS_P2_CLOCK_DIV_14 (0 << 24) /* i915 */ 219#define DPLLB_LVDS_P2_CLOCK_DIV_14 (0 << 24) /* i915 */
220#define DPLLB_LVDS_P2_CLOCK_DIV_7 (1 << 24) /* i915 */ 220#define DPLLB_LVDS_P2_CLOCK_DIV_7 (1 << 24) /* i915 */
221#define DPLL_P2_CLOCK_DIV_MASK 0x03000000 /* i915 */ 221#define DPLL_P2_CLOCK_DIV_MASK 0x03000000 /* i915 */
222#define DPLL_FPA01_P1_POST_DIV_MASK 0x00ff0000 /* i915 */ 222#define DPLL_FPA0h1_P1_POST_DIV_MASK 0x00ff0000 /* i915 */
223#define DPLL_LOCK (1 << 15) /* CDV */ 223#define DPLL_LOCK (1 << 15) /* CDV */
224 224
225/* 225/*
@@ -346,6 +346,9 @@
346#define FP_M2_DIV_SHIFT 0 346#define FP_M2_DIV_SHIFT 0
347 347
348#define PORT_HOTPLUG_EN 0x61110 348#define PORT_HOTPLUG_EN 0x61110
349#define HDMIB_HOTPLUG_INT_EN (1 << 29)
350#define HDMIC_HOTPLUG_INT_EN (1 << 28)
351#define HDMID_HOTPLUG_INT_EN (1 << 27)
349#define SDVOB_HOTPLUG_INT_EN (1 << 26) 352#define SDVOB_HOTPLUG_INT_EN (1 << 26)
350#define SDVOC_HOTPLUG_INT_EN (1 << 25) 353#define SDVOC_HOTPLUG_INT_EN (1 << 25)
351#define TV_HOTPLUG_INT_EN (1 << 18) 354#define TV_HOTPLUG_INT_EN (1 << 18)