The docs recommend that we use one high sense to detect composite and
S-Video, and low/inverted sense for component (or general output
detection, but we don't bother with that).

This might or might not finally clear up the confusion around TV
detection. Historically we've flip-flopped an aweful lot between high
and low sense, with varying amounts of justification (usually none
that would have survived scrunitation). The last just change was

commit d42c9e2c24f7e7897405b85816bdf4ac924881c0
Author: Daniel Vetter <[email protected]>
Date:   Sun Mar 25 22:56:14 2012 +0200

    drm/i915: reinstate GM45 TV detection fix

Motivated by the last TV detection bug I could find in our bugzilla.

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=31519
Signed-off-by: Daniel Vetter <[email protected]>
---
 drivers/gpu/drm/i915/intel_tv.c |   56 ++++++++++++++++++++++++---------------
 1 file changed, 34 insertions(+), 22 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c
index 62bb048..b8d783f 100644
--- a/drivers/gpu/drm/i915/intel_tv.c
+++ b/drivers/gpu/drm/i915/intel_tv.c
@@ -1167,7 +1167,8 @@ static const struct drm_display_mode reported_modes[] = {
  */
 static int
 intel_tv_detect_type(struct intel_tv *intel_tv,
-                     struct drm_connector *connector)
+                    struct drm_connector *connector,
+                    bool invert_sense)
 {
        struct drm_encoder *encoder = &intel_tv->base.base;
        struct drm_crtc *crtc = encoder->crtc;
@@ -1201,9 +1202,6 @@ intel_tv_detect_type(struct intel_tv *intel_tv,
 
        tv_dac &= ~(TVDAC_SENSE_MASK | DAC_A_MASK | DAC_B_MASK | DAC_C_MASK);
        tv_dac |= (TVDAC_STATE_CHG_EN |
-                  TVDAC_A_SENSE_CTL |
-                  TVDAC_B_SENSE_CTL |
-                  TVDAC_C_SENSE_CTL |
                   DAC_CTL_OVERRIDE |
                   DAC_A_0_7_V |
                   DAC_B_0_7_V |
@@ -1211,12 +1209,13 @@ intel_tv_detect_type(struct intel_tv *intel_tv,
 
 
        /*
-        * The TV sense state should be cleared to zero on cantiga platform. 
Otherwise
-        * the TV is misdetected. This is hardware requirement.
+        * We need to have two runs with opposite sense, since otherwise we
+        * won't be able to differentiate 
         */
-       if (IS_GM45(dev))
-               tv_dac &= ~(TVDAC_STATE_CHG_EN | TVDAC_A_SENSE_CTL |
-                           TVDAC_B_SENSE_CTL | TVDAC_C_SENSE_CTL);
+       if (invert_sense)
+               tv_dac &= ~(TVDAC_A_SENSE_CTL | TVDAC_B_SENSE_CTL | 
TVDAC_C_SENSE_CTL);
+       else
+               tv_dac |= TVDAC_A_SENSE_CTL | TVDAC_B_SENSE_CTL | 
TVDAC_C_SENSE_CTL;
 
        I915_WRITE(TV_CTL, tv_ctl);
        I915_WRITE(TV_DAC, tv_dac);
@@ -1229,23 +1228,28 @@ intel_tv_detect_type(struct intel_tv *intel_tv,
        tv_dac = I915_READ(TV_DAC);
        DRM_DEBUG_KMS("TV detected: %x, %x\n", tv_ctl, tv_dac);
        /*
+        *  TV sense for non-inverted sense controls ...
+        *
         *  A B C
         *  0 1 1 Composite
         *  1 0 X svideo
-        *  0 0 0 Component
+        *  0 0 0 Component (test with inverted sense)
         */
-       if ((tv_dac & TVDAC_SENSE_MASK) == (TVDAC_B_SENSE | TVDAC_C_SENSE)) {
-               DRM_DEBUG_KMS("Detected Composite TV connection\n");
-               type = DRM_MODE_CONNECTOR_Composite;
-       } else if ((tv_dac & (TVDAC_A_SENSE|TVDAC_B_SENSE)) == TVDAC_A_SENSE) {
-               DRM_DEBUG_KMS("Detected S-Video TV connection\n");
-               type = DRM_MODE_CONNECTOR_SVIDEO;
-       } else if ((tv_dac & TVDAC_SENSE_MASK) == 0) {
-               DRM_DEBUG_KMS("Detected Component TV connection\n");
-               type = DRM_MODE_CONNECTOR_Component;
+       if (invert_sense) {
+               if ((tv_dac & TVDAC_SENSE_MASK) == TVDAC_SENSE_MASK) {
+                       DRM_DEBUG_KMS("Detected Component TV connection\n");
+                       type = DRM_MODE_CONNECTOR_Component;
+               }
        } else {
-               DRM_DEBUG_KMS("Unrecognised TV connection\n");
-               type = -1;
+               if ((tv_dac & TVDAC_SENSE_MASK) ==
+                   (TVDAC_B_SENSE | TVDAC_C_SENSE)) {
+                       DRM_DEBUG_KMS("Detected Composite TV connection\n");
+                       type = DRM_MODE_CONNECTOR_Composite;
+               } else if ((tv_dac & (TVDAC_A_SENSE|TVDAC_B_SENSE)) ==
+                          TVDAC_A_SENSE) {
+                       DRM_DEBUG_KMS("Detected S-Video TV connection\n");
+                       type = DRM_MODE_CONNECTOR_SVIDEO;
+               }
        }
 
        I915_WRITE(TV_DAC, save_tv_dac & ~TVDAC_STATE_CHG_EN);
@@ -1315,7 +1319,15 @@ intel_tv_detect(struct drm_connector *connector, bool 
force)
                struct intel_load_detect_pipe tmp;
 
                if (intel_get_load_detect_pipe(connector, &mode, &tmp)) {
-                       type = intel_tv_detect_type(intel_tv, connector);
+                       /*
+                        * We need to run the load detection twice, since we
+                        * can't detect all output types correctly with just one
+                        * run.
+                        */
+                       type = intel_tv_detect_type(intel_tv, connector, false);
+                       if (type == -1)
+                               type = intel_tv_detect_type(intel_tv, connector,
+                                                           true);
                        intel_release_load_detect_pipe(connector, &tmp);
                } else
                        return connector_status_unknown;
-- 
1.7.10.4

_______________________________________________
Intel-gfx mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to