drm/i915: Add support for integrated HDMI on G4X hardware.
authorEric Anholt <eric@anholt.net>
Fri, 2 Jan 2009 21:33:00 +0000 (13:33 -0800)
committerDave Airlie <airlied@linux.ie>
Wed, 7 Jan 2009 01:49:47 +0000 (11:49 +1000)
This is ported directly from the userland 2D driver code.  The HDMI audio bits
aren't hooked up yet.

Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@linux.ie>
drivers/gpu/drm/i915/Makefile
drivers/gpu/drm/i915/i915_drv.h
drivers/gpu/drm/i915/i915_reg.h
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/i915/intel_drv.h
drivers/gpu/drm/i915/intel_hdmi.c [new file with mode: 0644]
drivers/gpu/drm/i915/intel_sdvo.c

index dd57a5b..793cba3 100644 (file)
@@ -13,6 +13,7 @@ i915-y := i915_drv.o i915_dma.o i915_irq.o i915_mem.o \
          intel_crt.o \
          intel_lvds.o \
          intel_bios.o \
+         intel_hdmi.o \
          intel_sdvo.o \
          intel_modes.o \
          intel_i2c.o \
index 4756e5c..563de18 100644 (file)
@@ -664,6 +664,7 @@ extern void intel_modeset_cleanup(struct drm_device *dev);
                                 writel(upper_32_bits(val), dev_priv->regs + \
                                        (reg) + 4))
 #endif
+#define POSTING_READ(reg)      (void)I915_READ(reg)
 
 #define I915_VERBOSE 0
 
@@ -760,6 +761,7 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
                        IS_I945GM(dev) || IS_I965GM(dev) || IS_GM45(dev))
 
 #define I915_NEED_GFX_HWS(dev) (IS_G33(dev) || IS_GM45(dev) || IS_G4X(dev))
+#define SUPPORTS_INTEGRATED_HDMI(dev)  (IS_G4X(dev))
 
 #define PRIMARY_RINGBUFFER_SIZE         (128*1024)
 
index 47e6baf..1024315 100644 (file)
 /** GM965 GM45 render standby register */
 #define MCHBAR_RENDER_STANDBY  0x111B8
 
+#define PEG_BAND_GAP_DATA      0x14d68
+
 /*
  * Overlay regs
  */
 
 /* Hotplug control (945+ only) */
 #define PORT_HOTPLUG_EN                0x61110
+#define   HDMIB_HOTPLUG_INT_EN                 (1 << 29)
+#define   HDMIC_HOTPLUG_INT_EN                 (1 << 28)
+#define   HDMID_HOTPLUG_INT_EN                 (1 << 27)
 #define   SDVOB_HOTPLUG_INT_EN                 (1 << 26)
 #define   SDVOC_HOTPLUG_INT_EN                 (1 << 25)
 #define   TV_HOTPLUG_INT_EN                    (1 << 18)
 #define   CRT_HOTPLUG_FORCE_DETECT             (1 << 3)
 
 #define PORT_HOTPLUG_STAT      0x61114
+#define   HDMIB_HOTPLUG_INT_STATUS             (1 << 29)
+#define   HDMIC_HOTPLUG_INT_STATUS             (1 << 28)
+#define   HDMID_HOTPLUG_INT_STATUS             (1 << 27)
 #define   CRT_HOTPLUG_INT_STATUS               (1 << 11)
 #define   TV_HOTPLUG_INT_STATUS                        (1 << 10)
 #define   CRT_HOTPLUG_MONITOR_MASK             (3 << 8)
 #define   SDVO_PHASE_SELECT_DEFAULT    (6 << 19)
 #define   SDVO_CLOCK_OUTPUT_INVERT     (1 << 18)
 #define   SDVOC_GANG_MODE              (1 << 16)
+#define   SDVO_ENCODING_SDVO           (0x0 << 10)
+#define   SDVO_ENCODING_HDMI           (0x2 << 10)
+/** Requird for HDMI operation */
+#define   SDVO_NULL_PACKETS_DURING_VSYNC (1 << 9)
 #define   SDVO_BORDER_ENABLE           (1 << 7)
+#define   SDVO_AUDIO_ENABLE            (1 << 6)
+/** New with 965, default is to be set */
+#define   SDVO_VSYNC_ACTIVE_HIGH       (1 << 4)
+/** New with 965, default is to be set */
+#define   SDVO_HSYNC_ACTIVE_HIGH       (1 << 3)
 #define   SDVOB_PCIE_CONCURRENCY       (1 << 3)
 #define   SDVO_DETECTED                        (1 << 2)
 /* Bits to be preserved when writing */
index 1204d26..67d06fd 100644 (file)
@@ -751,6 +751,7 @@ static void intel_crtc_mode_set(struct drm_crtc *crtc,
                        is_lvds = true;
                        break;
                case INTEL_OUTPUT_SDVO:
+               case INTEL_OUTPUT_HDMI:
                        is_sdvo = true;
                        break;
                case INTEL_OUTPUT_DVO:
@@ -1443,8 +1444,15 @@ static void intel_setup_outputs(struct drm_device *dev)
                intel_lvds_init(dev);
 
        if (IS_I9XX(dev)) {
-               intel_sdvo_init(dev, SDVOB);
-               intel_sdvo_init(dev, SDVOC);
+               int found;
+
+               found = intel_sdvo_init(dev, SDVOB);
+               if (!found && SUPPORTS_INTEGRATED_HDMI(dev))
+                       intel_hdmi_init(dev, SDVOB);
+
+               found = intel_sdvo_init(dev, SDVOC);
+               if (!found && SUPPORTS_INTEGRATED_HDMI(dev))
+                       intel_hdmi_init(dev, SDVOC);
        } else
                intel_dvo_init(dev);
 
@@ -1458,6 +1466,11 @@ static void intel_setup_outputs(struct drm_device *dev)
 
                /* valid crtcs */
                switch(intel_output->type) {
+               case INTEL_OUTPUT_HDMI:
+                       crtc_mask = ((1 << 0)|
+                                    (1 << 1));
+                       clone_mask = ((1 << INTEL_OUTPUT_HDMI));
+                       break;
                case INTEL_OUTPUT_DVO:
                case INTEL_OUTPUT_SDVO:
                        crtc_mask = ((1 << 0)|
index 94981ee..8a4cc50 100644 (file)
@@ -53,6 +53,7 @@
 #define INTEL_OUTPUT_SDVO 3
 #define INTEL_OUTPUT_LVDS 4
 #define INTEL_OUTPUT_TVOUT 5
+#define INTEL_OUTPUT_HDMI 6
 
 #define INTEL_DVO_CHIP_NONE 0
 #define INTEL_DVO_CHIP_LVDS 1
@@ -109,7 +110,8 @@ int intel_ddc_get_modes(struct intel_output *intel_output);
 extern bool intel_ddc_probe(struct intel_output *intel_output);
 
 extern void intel_crt_init(struct drm_device *dev);
-extern void intel_sdvo_init(struct drm_device *dev, int output_device);
+extern void intel_hdmi_init(struct drm_device *dev, int sdvox_reg);
+extern bool intel_sdvo_init(struct drm_device *dev, int output_device);
 extern void intel_dvo_init(struct drm_device *dev);
 extern void intel_tv_init(struct drm_device *dev);
 extern void intel_lvds_init(struct drm_device *dev);
Simple merge
Simple merge