OSDN Git Service

i915: do a better job of parsing VBIOS data
[android-x86/external-libdrm.git] / linux-core / intel_tv.c
index 89bdda1..650c46f 100644 (file)
@@ -1012,7 +1012,7 @@ intel_tv_restore(struct drm_output *output)
                int pipeconf = I915_READ(pipeconf_reg);
                int dspcntr = I915_READ(dspcntr_reg);
                int dspbase_reg = (intel_crtc->plane == 0) ?
-                       DSPABASE : DSPBBASE;
+                       DSPAADDR : DSPBADDR;
                /* Pipe must be off here */
                I915_WRITE(dspcntr_reg, dspcntr & ~DISPLAY_PLANE_ENABLE);
                /* Flush the plane changes */
@@ -1277,7 +1277,7 @@ intel_tv_mode_set(struct drm_output *output, struct drm_display_mode *mode,
                int pipeconf = I915_READ(pipeconf_reg);
                int dspcntr = I915_READ(dspcntr_reg);
                int dspbase_reg = (intel_crtc->plane == 0) ?
-                       DSPABASE : DSPBBASE;
+                       DSPAADDR : DSPBADDR;
                int xpos = 0x0, ypos = 0x0;
                unsigned int xsize, ysize;
                /* Pipe must be off here */
@@ -1360,11 +1360,21 @@ intel_tv_detect_type (struct drm_crtc *crtc, struct drm_output *output)
        struct drm_device *dev = output->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct intel_output *intel_output = output->driver_private;
+       u32 pipeastat, pipeastat_save;
        u32 tv_ctl, save_tv_ctl;
        u32 tv_dac, save_tv_dac;
        int type = ConnectorUnknown;
 
        tv_dac = I915_READ(TV_DAC);
+
+       /* Disable TV interrupts around load detect or we'll recurse */
+       pipeastat = I915_READ(PIPEASTAT);
+       pipeastat_save = pipeastat;
+       pipeastat &= ~PIPE_HOTPLUG_INTERRUPT_ENABLE;
+       pipeastat &= ~PIPE_HOTPLUG_TV_INTERRUPT_ENABLE;
+       I915_WRITE(PIPEASTAT, pipeastat | PIPE_HOTPLUG_TV_INTERRUPT_STATUS |
+                  PIPE_HOTPLUG_INTERRUPT_STATUS);
+
        /*
         * Detect TV by polling)
         */
@@ -1412,6 +1422,10 @@ intel_tv_detect_type (struct drm_crtc *crtc, struct drm_output *output)
                type = -1;
        }
 
+       /* Restore interrupt config */
+       I915_WRITE(PIPEASTAT, pipeastat_save | PIPE_HOTPLUG_TV_INTERRUPT_STATUS |
+                  PIPE_HOTPLUG_INTERRUPT_STATUS);
+
        return type;
 }
 
@@ -1434,10 +1448,15 @@ intel_tv_detect(struct drm_output *output)
        mode = reported_modes[0];
        drm_mode_set_crtcinfo(&mode, CRTC_INTERLACE_HALVE_V);
 
-       crtc = intel_get_load_detect_pipe(output, &mode, &dpms_mode);
-       if (crtc) {
-               type = intel_tv_detect_type(crtc, output);
-               intel_release_load_detect_pipe(output, dpms_mode);
+       if (output->crtc) {
+               type = intel_tv_detect_type(output->crtc, output);
+       } else {
+               crtc = intel_get_load_detect_pipe(output, &mode, &dpms_mode);
+               if (crtc) {
+                       type = intel_tv_detect_type(crtc, output);
+                       intel_release_load_detect_pipe(output, dpms_mode);
+               } else
+                       type = -1;
        }
 
        if (type != tv_priv->type) {
@@ -1597,14 +1616,13 @@ intel_tv_init(struct drm_device *dev)
        char **tv_format_names;
        int i, initial_mode = 0;
 
-       /* FIXME: better TV detection and/or quirks */
-#if 0
-       if (tv_priv->quirk_flag & QUIRK_IGNORE_TV)
-               return;
-#endif
        if ((I915_READ(TV_CTL) & TV_FUSE_STATE_MASK) == TV_FUSE_STATE_DISABLED)
                return;
 
+       /* Even if we have an encoder we may not have a connector */
+       if (!dev_priv->int_tv_support)
+               return;
+
        /*
         * Sanity check the TV output by checking to see if the
         * DAC register holds a value