LCOV - code coverage report
Current view: top level - dev/pci/drm/i915 - intel_sdvo.c (source / functions) Hit Total Coverage
Test: 6.4 Lines: 0 1285 0.0 %
Date: 2018-10-19 03:25:38 Functions: 0 88 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright 2006 Dave Airlie <airlied@linux.ie>
       3             :  * Copyright © 2006-2007 Intel Corporation
       4             :  *   Jesse Barnes <jesse.barnes@intel.com>
       5             :  *
       6             :  * Permission is hereby granted, free of charge, to any person obtaining a
       7             :  * copy of this software and associated documentation files (the "Software"),
       8             :  * to deal in the Software without restriction, including without limitation
       9             :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      10             :  * and/or sell copies of the Software, and to permit persons to whom the
      11             :  * Software is furnished to do so, subject to the following conditions:
      12             :  *
      13             :  * The above copyright notice and this permission notice (including the next
      14             :  * paragraph) shall be included in all copies or substantial portions of the
      15             :  * Software.
      16             :  *
      17             :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
      18             :  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      19             :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
      20             :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      21             :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      22             :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      23             :  * DEALINGS IN THE SOFTWARE.
      24             :  *
      25             :  * Authors:
      26             :  *      Eric Anholt <eric@anholt.net>
      27             :  */
      28             : #ifdef __linux__
      29             : #include <linux/i2c.h>
      30             : #include <linux/slab.h>
      31             : #include <linux/delay.h>
      32             : #include <linux/export.h>
      33             : #endif
      34             : #include <dev/pci/drm/drmP.h>
      35             : #include <dev/pci/drm/drm_atomic_helper.h>
      36             : #include <dev/pci/drm/drm_crtc.h>
      37             : #include <dev/pci/drm/drm_edid.h>
      38             : #include "intel_drv.h"
      39             : #include <dev/pci/drm/i915_drm.h>
      40             : #include "i915_drv.h"
      41             : #include "intel_sdvo_regs.h"
      42             : 
      43             : #define SDVO_TMDS_MASK (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1)
      44             : #define SDVO_RGB_MASK  (SDVO_OUTPUT_RGB0 | SDVO_OUTPUT_RGB1)
      45             : #define SDVO_LVDS_MASK (SDVO_OUTPUT_LVDS0 | SDVO_OUTPUT_LVDS1)
      46             : #define SDVO_TV_MASK   (SDVO_OUTPUT_CVBS0 | SDVO_OUTPUT_SVID0 | SDVO_OUTPUT_YPRPB0)
      47             : 
      48             : #define SDVO_OUTPUT_MASK (SDVO_TMDS_MASK | SDVO_RGB_MASK | SDVO_LVDS_MASK |\
      49             :                         SDVO_TV_MASK)
      50             : 
      51             : #define IS_TV(c)        (c->output_flag & SDVO_TV_MASK)
      52             : #define IS_TMDS(c)      (c->output_flag & SDVO_TMDS_MASK)
      53             : #define IS_LVDS(c)      (c->output_flag & SDVO_LVDS_MASK)
      54             : #define IS_TV_OR_LVDS(c) (c->output_flag & (SDVO_TV_MASK | SDVO_LVDS_MASK))
      55             : #define IS_DIGITAL(c) (c->output_flag & (SDVO_TMDS_MASK | SDVO_LVDS_MASK))
      56             : 
      57             : 
      58             : static const char * const tv_format_names[] = {
      59             :         "NTSC_M"   , "NTSC_J"  , "NTSC_443",
      60             :         "PAL_B"    , "PAL_D"   , "PAL_G"   ,
      61             :         "PAL_H"    , "PAL_I"   , "PAL_M"   ,
      62             :         "PAL_N"    , "PAL_NC"  , "PAL_60"  ,
      63             :         "SECAM_B"  , "SECAM_D" , "SECAM_G" ,
      64             :         "SECAM_K"  , "SECAM_K1", "SECAM_L" ,
      65             :         "SECAM_60"
      66             : };
      67             : 
      68             : #define TV_FORMAT_NUM  ARRAY_SIZE(tv_format_names)
      69             : 
      70             : struct intel_sdvo {
      71             :         struct intel_encoder base;
      72             : 
      73             :         struct i2c_adapter *i2c;
      74             :         u8 slave_addr;
      75             : 
      76             :         struct i2c_adapter ddc;
      77             : 
      78             :         /* Register for the SDVO device: SDVOB or SDVOC */
      79             :         uint32_t sdvo_reg;
      80             : 
      81             :         /* Active outputs controlled by this SDVO output */
      82             :         uint16_t controlled_output;
      83             : 
      84             :         /*
      85             :          * Capabilities of the SDVO device returned by
      86             :          * intel_sdvo_get_capabilities()
      87             :          */
      88             :         struct intel_sdvo_caps caps;
      89             : 
      90             :         /* Pixel clock limitations reported by the SDVO device, in kHz */
      91             :         int pixel_clock_min, pixel_clock_max;
      92             : 
      93             :         /*
      94             :         * For multiple function SDVO device,
      95             :         * this is for current attached outputs.
      96             :         */
      97             :         uint16_t attached_output;
      98             : 
      99             :         /*
     100             :          * Hotplug activation bits for this device
     101             :          */
     102             :         uint16_t hotplug_active;
     103             : 
     104             :         /**
     105             :          * This is used to select the color range of RBG outputs in HDMI mode.
     106             :          * It is only valid when using TMDS encoding and 8 bit per color mode.
     107             :          */
     108             :         uint32_t color_range;
     109             :         bool color_range_auto;
     110             : 
     111             :         /**
     112             :          * HDMI user specified aspect ratio
     113             :          */
     114             :         enum hdmi_picture_aspect aspect_ratio;
     115             : 
     116             :         /**
     117             :          * This is set if we're going to treat the device as TV-out.
     118             :          *
     119             :          * While we have these nice friendly flags for output types that ought
     120             :          * to decide this for us, the S-Video output on our HDMI+S-Video card
     121             :          * shows up as RGB1 (VGA).
     122             :          */
     123             :         bool is_tv;
     124             : 
     125             :         /* On different gens SDVOB is at different places. */
     126             :         bool is_sdvob;
     127             : 
     128             :         /* This is for current tv format name */
     129             :         int tv_format_index;
     130             : 
     131             :         /**
     132             :          * This is set if we treat the device as HDMI, instead of DVI.
     133             :          */
     134             :         bool is_hdmi;
     135             :         bool has_hdmi_monitor;
     136             :         bool has_hdmi_audio;
     137             :         bool rgb_quant_range_selectable;
     138             : 
     139             :         /**
     140             :          * This is set if we detect output of sdvo device as LVDS and
     141             :          * have a valid fixed mode to use with the panel.
     142             :          */
     143             :         bool is_lvds;
     144             : 
     145             :         /**
     146             :          * This is sdvo fixed pannel mode pointer
     147             :          */
     148             :         struct drm_display_mode *sdvo_lvds_fixed_mode;
     149             : 
     150             :         /* DDC bus used by this SDVO encoder */
     151             :         uint8_t ddc_bus;
     152             : 
     153             :         /*
     154             :          * the sdvo flag gets lost in round trip: dtd->adjusted_mode->dtd
     155             :          */
     156             :         uint8_t dtd_sdvo_flags;
     157             : };
     158             : 
     159             : struct intel_sdvo_connector {
     160             :         struct intel_connector base;
     161             : 
     162             :         /* Mark the type of connector */
     163             :         uint16_t output_flag;
     164             : 
     165             :         enum hdmi_force_audio force_audio;
     166             : 
     167             :         /* This contains all current supported TV format */
     168             :         u8 tv_format_supported[TV_FORMAT_NUM];
     169             :         int   format_supported_num;
     170             :         struct drm_property *tv_format;
     171             : 
     172             :         /* add the property for the SDVO-TV */
     173             :         struct drm_property *left;
     174             :         struct drm_property *right;
     175             :         struct drm_property *top;
     176             :         struct drm_property *bottom;
     177             :         struct drm_property *hpos;
     178             :         struct drm_property *vpos;
     179             :         struct drm_property *contrast;
     180             :         struct drm_property *saturation;
     181             :         struct drm_property *hue;
     182             :         struct drm_property *sharpness;
     183             :         struct drm_property *flicker_filter;
     184             :         struct drm_property *flicker_filter_adaptive;
     185             :         struct drm_property *flicker_filter_2d;
     186             :         struct drm_property *tv_chroma_filter;
     187             :         struct drm_property *tv_luma_filter;
     188             :         struct drm_property *dot_crawl;
     189             : 
     190             :         /* add the property for the SDVO-TV/LVDS */
     191             :         struct drm_property *brightness;
     192             : 
     193             :         /* Add variable to record current setting for the above property */
     194             :         u32     left_margin, right_margin, top_margin, bottom_margin;
     195             : 
     196             :         /* this is to get the range of margin.*/
     197             :         u32     max_hscan,  max_vscan;
     198             :         u32     max_hpos, cur_hpos;
     199             :         u32     max_vpos, cur_vpos;
     200             :         u32     cur_brightness, max_brightness;
     201             :         u32     cur_contrast,   max_contrast;
     202             :         u32     cur_saturation, max_saturation;
     203             :         u32     cur_hue,        max_hue;
     204             :         u32     cur_sharpness,  max_sharpness;
     205             :         u32     cur_flicker_filter,             max_flicker_filter;
     206             :         u32     cur_flicker_filter_adaptive,    max_flicker_filter_adaptive;
     207             :         u32     cur_flicker_filter_2d,          max_flicker_filter_2d;
     208             :         u32     cur_tv_chroma_filter,   max_tv_chroma_filter;
     209             :         u32     cur_tv_luma_filter,     max_tv_luma_filter;
     210             :         u32     cur_dot_crawl,  max_dot_crawl;
     211             : };
     212             : 
     213           0 : static struct intel_sdvo *to_sdvo(struct intel_encoder *encoder)
     214             : {
     215           0 :         return container_of(encoder, struct intel_sdvo, base);
     216             : }
     217             : 
     218           0 : static struct intel_sdvo *intel_attached_sdvo(struct drm_connector *connector)
     219             : {
     220           0 :         return to_sdvo(intel_attached_encoder(connector));
     221             : }
     222             : 
     223           0 : static struct intel_sdvo_connector *to_intel_sdvo_connector(struct drm_connector *connector)
     224             : {
     225           0 :         return container_of(to_intel_connector(connector), struct intel_sdvo_connector, base);
     226             : }
     227             : 
     228             : static bool
     229             : intel_sdvo_output_setup(struct intel_sdvo *intel_sdvo, uint16_t flags);
     230             : static bool
     231             : intel_sdvo_tv_create_property(struct intel_sdvo *intel_sdvo,
     232             :                               struct intel_sdvo_connector *intel_sdvo_connector,
     233             :                               int type);
     234             : static bool
     235             : intel_sdvo_create_enhance_property(struct intel_sdvo *intel_sdvo,
     236             :                                    struct intel_sdvo_connector *intel_sdvo_connector);
     237             : 
     238             : /**
     239             :  * Writes the SDVOB or SDVOC with the given value, but always writes both
     240             :  * SDVOB and SDVOC to work around apparent hardware issues (according to
     241             :  * comments in the BIOS).
     242             :  */
     243           0 : static void intel_sdvo_write_sdvox(struct intel_sdvo *intel_sdvo, u32 val)
     244             : {
     245           0 :         struct drm_device *dev = intel_sdvo->base.base.dev;
     246           0 :         struct drm_i915_private *dev_priv = dev->dev_private;
     247             :         u32 bval = val, cval = val;
     248             :         int i;
     249             : 
     250           0 :         if (intel_sdvo->sdvo_reg == PCH_SDVOB) {
     251           0 :                 I915_WRITE(intel_sdvo->sdvo_reg, val);
     252           0 :                 POSTING_READ(intel_sdvo->sdvo_reg);
     253             :                 /*
     254             :                  * HW workaround, need to write this twice for issue
     255             :                  * that may result in first write getting masked.
     256             :                  */
     257           0 :                 if (HAS_PCH_IBX(dev)) {
     258           0 :                         I915_WRITE(intel_sdvo->sdvo_reg, val);
     259           0 :                         POSTING_READ(intel_sdvo->sdvo_reg);
     260           0 :                 }
     261           0 :                 return;
     262             :         }
     263             : 
     264           0 :         if (intel_sdvo->sdvo_reg == GEN3_SDVOB)
     265           0 :                 cval = I915_READ(GEN3_SDVOC);
     266             :         else
     267           0 :                 bval = I915_READ(GEN3_SDVOB);
     268             : 
     269             :         /*
     270             :          * Write the registers twice for luck. Sometimes,
     271             :          * writing them only once doesn't appear to 'stick'.
     272             :          * The BIOS does this too. Yay, magic
     273             :          */
     274           0 :         for (i = 0; i < 2; i++)
     275             :         {
     276           0 :                 I915_WRITE(GEN3_SDVOB, bval);
     277           0 :                 POSTING_READ(GEN3_SDVOB);
     278           0 :                 I915_WRITE(GEN3_SDVOC, cval);
     279           0 :                 POSTING_READ(GEN3_SDVOC);
     280             :         }
     281           0 : }
     282             : 
     283           0 : static bool intel_sdvo_read_byte(struct intel_sdvo *intel_sdvo, u8 addr, u8 *ch)
     284             : {
     285           0 :         struct i2c_msg msgs[] = {
     286           0 :                 {
     287           0 :                         .addr = intel_sdvo->slave_addr,
     288             :                         .flags = 0,
     289             :                         .len = 1,
     290             :                         .buf = &addr,
     291             :                 },
     292           0 :                 {
     293           0 :                         .addr = intel_sdvo->slave_addr,
     294             :                         .flags = I2C_M_RD,
     295             :                         .len = 1,
     296             :                         .buf = ch,
     297             :                 }
     298             :         };
     299             :         int ret;
     300             : 
     301           0 :         if ((ret = i2c_transfer(intel_sdvo->i2c, msgs, 2)) == 2)
     302           0 :                 return true;
     303             : 
     304             :         DRM_DEBUG_KMS("i2c transfer returned %d\n", ret);
     305           0 :         return false;
     306           0 : }
     307             : 
     308             : #define SDVO_CMD_NAME_ENTRY(cmd) {cmd, #cmd}
     309             : /** Mapping of command numbers to names, for debug output */
     310             : static const struct _sdvo_cmd_name {
     311             :         u8 cmd;
     312             :         const char *name;
     313             : } sdvo_cmd_names[] = {
     314             :         SDVO_CMD_NAME_ENTRY(SDVO_CMD_RESET),
     315             :         SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_DEVICE_CAPS),
     316             :         SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_FIRMWARE_REV),
     317             :         SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_TRAINED_INPUTS),
     318             :         SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_ACTIVE_OUTPUTS),
     319             :         SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_ACTIVE_OUTPUTS),
     320             :         SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_IN_OUT_MAP),
     321             :         SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_IN_OUT_MAP),
     322             :         SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_ATTACHED_DISPLAYS),
     323             :         SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HOT_PLUG_SUPPORT),
     324             :         SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_ACTIVE_HOT_PLUG),
     325             :         SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_ACTIVE_HOT_PLUG),
     326             :         SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_INTERRUPT_EVENT_SOURCE),
     327             :         SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_TARGET_INPUT),
     328             :         SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_TARGET_OUTPUT),
     329             :         SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_INPUT_TIMINGS_PART1),
     330             :         SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_INPUT_TIMINGS_PART2),
     331             :         SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_INPUT_TIMINGS_PART1),
     332             :         SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_INPUT_TIMINGS_PART2),
     333             :         SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_INPUT_TIMINGS_PART1),
     334             :         SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_OUTPUT_TIMINGS_PART1),
     335             :         SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_OUTPUT_TIMINGS_PART2),
     336             :         SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_OUTPUT_TIMINGS_PART1),
     337             :         SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_OUTPUT_TIMINGS_PART2),
     338             :         SDVO_CMD_NAME_ENTRY(SDVO_CMD_CREATE_PREFERRED_INPUT_TIMING),
     339             :         SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART1),
     340             :         SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART2),
     341             :         SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_INPUT_PIXEL_CLOCK_RANGE),
     342             :         SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_OUTPUT_PIXEL_CLOCK_RANGE),
     343             :         SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SUPPORTED_CLOCK_RATE_MULTS),
     344             :         SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_CLOCK_RATE_MULT),
     345             :         SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_CLOCK_RATE_MULT),
     346             :         SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SUPPORTED_TV_FORMATS),
     347             :         SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_TV_FORMAT),
     348             :         SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_TV_FORMAT),
     349             :         SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SUPPORTED_POWER_STATES),
     350             :         SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_POWER_STATE),
     351             :         SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_ENCODER_POWER_STATE),
     352             :         SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_DISPLAY_POWER_STATE),
     353             :         SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_CONTROL_BUS_SWITCH),
     354             :         SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SDTV_RESOLUTION_SUPPORT),
     355             :         SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SCALED_HDTV_RESOLUTION_SUPPORT),
     356             :         SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SUPPORTED_ENHANCEMENTS),
     357             : 
     358             :         /* Add the op code for SDVO enhancements */
     359             :         SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_HPOS),
     360             :         SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HPOS),
     361             :         SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_HPOS),
     362             :         SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_VPOS),
     363             :         SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_VPOS),
     364             :         SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_VPOS),
     365             :         SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_SATURATION),
     366             :         SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SATURATION),
     367             :         SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_SATURATION),
     368             :         SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_HUE),
     369             :         SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HUE),
     370             :         SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_HUE),
     371             :         SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_CONTRAST),
     372             :         SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_CONTRAST),
     373             :         SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_CONTRAST),
     374             :         SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_BRIGHTNESS),
     375             :         SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_BRIGHTNESS),
     376             :         SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_BRIGHTNESS),
     377             :         SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_OVERSCAN_H),
     378             :         SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_OVERSCAN_H),
     379             :         SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_OVERSCAN_H),
     380             :         SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_OVERSCAN_V),
     381             :         SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_OVERSCAN_V),
     382             :         SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_OVERSCAN_V),
     383             :         SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_FLICKER_FILTER),
     384             :         SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_FLICKER_FILTER),
     385             :         SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_FLICKER_FILTER),
     386             :         SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_FLICKER_FILTER_ADAPTIVE),
     387             :         SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_FLICKER_FILTER_ADAPTIVE),
     388             :         SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_FLICKER_FILTER_ADAPTIVE),
     389             :         SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_FLICKER_FILTER_2D),
     390             :         SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_FLICKER_FILTER_2D),
     391             :         SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_FLICKER_FILTER_2D),
     392             :         SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_SHARPNESS),
     393             :         SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SHARPNESS),
     394             :         SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_SHARPNESS),
     395             :         SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_DOT_CRAWL),
     396             :         SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_DOT_CRAWL),
     397             :         SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_TV_CHROMA_FILTER),
     398             :         SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_TV_CHROMA_FILTER),
     399             :         SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_TV_CHROMA_FILTER),
     400             :         SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_TV_LUMA_FILTER),
     401             :         SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_TV_LUMA_FILTER),
     402             :         SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_TV_LUMA_FILTER),
     403             : 
     404             :         /* HDMI op code */
     405             :         SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SUPP_ENCODE),
     406             :         SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_ENCODE),
     407             :         SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_ENCODE),
     408             :         SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_PIXEL_REPLI),
     409             :         SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_PIXEL_REPLI),
     410             :         SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_COLORIMETRY_CAP),
     411             :         SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_COLORIMETRY),
     412             :         SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_COLORIMETRY),
     413             :         SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_AUDIO_ENCRYPT_PREFER),
     414             :         SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_AUDIO_STAT),
     415             :         SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_AUDIO_STAT),
     416             :         SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HBUF_INDEX),
     417             :         SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_HBUF_INDEX),
     418             :         SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HBUF_INFO),
     419             :         SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HBUF_AV_SPLIT),
     420             :         SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_HBUF_AV_SPLIT),
     421             :         SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HBUF_TXRATE),
     422             :         SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_HBUF_TXRATE),
     423             :         SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_HBUF_DATA),
     424             :         SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HBUF_DATA),
     425             : };
     426             : 
     427             : #define SDVO_NAME(svdo) ((svdo)->is_sdvob ? "SDVOB" : "SDVOC")
     428             : 
     429           0 : static void intel_sdvo_debug_write(struct intel_sdvo *intel_sdvo, u8 cmd,
     430             :                                    const void *args, int args_len)
     431             : {
     432             :         int i, pos = 0;
     433             : #define BUF_LEN 256
     434           0 :         char buffer[BUF_LEN];
     435             : 
     436             : #define BUF_PRINT(args...) \
     437             :         pos += snprintf(buffer + pos, max_t(int, BUF_LEN - pos, 0), args)
     438             : 
     439             : 
     440           0 :         for (i = 0; i < args_len; i++) {
     441           0 :                 BUF_PRINT("%02X ", ((u8 *)args)[i]);
     442             :         }
     443           0 :         for (; i < 8; i++) {
     444           0 :                 BUF_PRINT("   ");
     445             :         }
     446           0 :         for (i = 0; i < ARRAY_SIZE(sdvo_cmd_names); i++) {
     447           0 :                 if (cmd == sdvo_cmd_names[i].cmd) {
     448           0 :                         BUF_PRINT("(%s)", sdvo_cmd_names[i].name);
     449           0 :                         break;
     450             :                 }
     451             :         }
     452           0 :         if (i == ARRAY_SIZE(sdvo_cmd_names)) {
     453           0 :                 BUF_PRINT("(%02X)", cmd);
     454           0 :         }
     455           0 :         BUG_ON(pos >= BUF_LEN - 1);
     456             : #undef BUF_PRINT
     457             : #undef BUF_LEN
     458             : 
     459             :         DRM_DEBUG_KMS("%s: W: %02X %s\n", SDVO_NAME(intel_sdvo), cmd, buffer);
     460           0 : }
     461             : 
     462             : static const char * const cmd_status_names[] = {
     463             :         "Power on",
     464             :         "Success",
     465             :         "Not supported",
     466             :         "Invalid arg",
     467             :         "Pending",
     468             :         "Target not specified",
     469             :         "Scaling not supported"
     470             : };
     471             : 
     472           0 : static bool intel_sdvo_write_cmd(struct intel_sdvo *intel_sdvo, u8 cmd,
     473             :                                  const void *args, int args_len)
     474             : {
     475           0 :         u8 *buf, status;
     476             :         struct i2c_msg *msgs;
     477             :         int i, ret = true;
     478             : 
     479             :         /* Would be simpler to allocate both in one go ? */        
     480           0 :         buf = kzalloc(args_len * 2 + 2, GFP_KERNEL);
     481           0 :         if (!buf)
     482           0 :                 return false;
     483             : 
     484           0 :         msgs = kcalloc(args_len + 3, sizeof(*msgs), GFP_KERNEL);
     485           0 :         if (!msgs) {
     486           0 :                 kfree(buf);
     487           0 :                 return false;
     488             :         }
     489             : 
     490           0 :         intel_sdvo_debug_write(intel_sdvo, cmd, args, args_len);
     491             : 
     492           0 :         for (i = 0; i < args_len; i++) {
     493             :                 msgs[i].addr = intel_sdvo->slave_addr;
     494             :                 msgs[i].flags = 0;
     495             :                 msgs[i].len = 2;
     496             :                 msgs[i].buf = buf + 2 *i;
     497           0 :                 buf[2*i + 0] = SDVO_I2C_ARG_0 - i;
     498           0 :                 buf[2*i + 1] = ((u8*)args)[i];
     499             :         }
     500             :         msgs[i].addr = intel_sdvo->slave_addr;
     501             :         msgs[i].flags = 0;
     502             :         msgs[i].len = 2;
     503             :         msgs[i].buf = buf + 2*i;
     504           0 :         buf[2*i + 0] = SDVO_I2C_OPCODE;
     505           0 :         buf[2*i + 1] = cmd;
     506             : 
     507             :         /* the following two are to read the response */
     508           0 :         status = SDVO_I2C_CMD_STATUS;
     509           0 :         msgs[i+1].addr = intel_sdvo->slave_addr;
     510           0 :         msgs[i+1].flags = 0;
     511           0 :         msgs[i+1].len = 1;
     512           0 :         msgs[i+1].buf = &status;
     513             : 
     514           0 :         msgs[i+2].addr = intel_sdvo->slave_addr;
     515           0 :         msgs[i+2].flags = I2C_M_RD;
     516           0 :         msgs[i+2].len = 1;
     517           0 :         msgs[i+2].buf = &status;
     518             : 
     519           0 :         ret = i2c_transfer(intel_sdvo->i2c, msgs, i+3);
     520           0 :         if (ret < 0) {
     521             :                 DRM_DEBUG_KMS("I2c transfer returned %d\n", ret);
     522             :                 ret = false;
     523           0 :                 goto out;
     524             :         }
     525           0 :         if (ret != i+3) {
     526             :                 /* failure in I2C transfer */
     527             :                 DRM_DEBUG_KMS("I2c transfer returned %d/%d\n", ret, i+3);
     528             :                 ret = false;
     529           0 :         }
     530             : 
     531             : out:
     532           0 :         kfree(msgs);
     533           0 :         kfree(buf);
     534           0 :         return ret;
     535           0 : }
     536             : 
     537           0 : static bool intel_sdvo_read_response(struct intel_sdvo *intel_sdvo,
     538             :                                      void *response, int response_len)
     539             : {
     540             :         u8 retry = 15; /* 5 quick checks, followed by 10 long checks */
     541           0 :         u8 status;
     542             :         int i, pos = 0;
     543             : #define BUF_LEN 256
     544           0 :         char buffer[BUF_LEN];
     545             : 
     546             : 
     547             :         /*
     548             :          * The documentation states that all commands will be
     549             :          * processed within 15µs, and that we need only poll
     550             :          * the status byte a maximum of 3 times in order for the
     551             :          * command to be complete.
     552             :          *
     553             :          * Check 5 times in case the hardware failed to read the docs.
     554             :          *
     555             :          * Also beware that the first response by many devices is to
     556             :          * reply PENDING and stall for time. TVs are notorious for
     557             :          * requiring longer than specified to complete their replies.
     558             :          * Originally (in the DDX long ago), the delay was only ever 15ms
     559             :          * with an additional delay of 30ms applied for TVs added later after
     560             :          * many experiments. To accommodate both sets of delays, we do a
     561             :          * sequence of slow checks if the device is falling behind and fails
     562             :          * to reply within 5*15µs.
     563             :          */
     564           0 :         if (!intel_sdvo_read_byte(intel_sdvo,
     565             :                                   SDVO_I2C_CMD_STATUS,
     566             :                                   &status))
     567             :                 goto log_fail;
     568             : 
     569           0 :         while ((status == SDVO_CMD_STATUS_PENDING ||
     570           0 :                 status == SDVO_CMD_STATUS_TARGET_NOT_SPECIFIED) && --retry) {
     571           0 :                 if (retry < 10)
     572           0 :                         drm_msleep(15);
     573             :                 else
     574           0 :                         udelay(15);
     575             : 
     576           0 :                 if (!intel_sdvo_read_byte(intel_sdvo,
     577             :                                           SDVO_I2C_CMD_STATUS,
     578             :                                           &status))
     579             :                         goto log_fail;
     580             :         }
     581             : 
     582             : #define BUF_PRINT(args...) \
     583             :         pos += snprintf(buffer + pos, max_t(int, BUF_LEN - pos, 0), args)
     584             : 
     585           0 :         if (status <= SDVO_CMD_STATUS_SCALING_NOT_SUPP)
     586           0 :                 BUF_PRINT("(%s)", cmd_status_names[status]);
     587             :         else
     588           0 :                 BUF_PRINT("(??? %d)", status);
     589             : 
     590           0 :         if (status != SDVO_CMD_STATUS_SUCCESS)
     591             :                 goto log_fail;
     592             : 
     593             :         /* Read the command response */
     594           0 :         for (i = 0; i < response_len; i++) {
     595           0 :                 if (!intel_sdvo_read_byte(intel_sdvo,
     596           0 :                                           SDVO_I2C_RETURN_0 + i,
     597           0 :                                           &((u8 *)response)[i]))
     598             :                         goto log_fail;
     599           0 :                 BUF_PRINT(" %02X", ((u8 *)response)[i]);
     600             :         }
     601           0 :         BUG_ON(pos >= BUF_LEN - 1);
     602             : #undef BUF_PRINT
     603             : #undef BUF_LEN
     604             : 
     605             :         DRM_DEBUG_KMS("%s: R: %s\n", SDVO_NAME(intel_sdvo), buffer);
     606           0 :         return true;
     607             : 
     608             : log_fail:
     609             :         DRM_DEBUG_KMS("%s: R: ... failed\n", SDVO_NAME(intel_sdvo));
     610           0 :         return false;
     611           0 : }
     612             : 
     613           0 : static int intel_sdvo_get_pixel_multiplier(const struct drm_display_mode *adjusted_mode)
     614             : {
     615           0 :         if (adjusted_mode->crtc_clock >= 100000)
     616           0 :                 return 1;
     617           0 :         else if (adjusted_mode->crtc_clock >= 50000)
     618           0 :                 return 2;
     619             :         else
     620           0 :                 return 4;
     621           0 : }
     622             : 
     623           0 : static bool intel_sdvo_set_control_bus_switch(struct intel_sdvo *intel_sdvo,
     624             :                                               u8 ddc_bus)
     625             : {
     626             :         /* This must be the immediately preceding write before the i2c xfer */
     627           0 :         return intel_sdvo_write_cmd(intel_sdvo,
     628             :                                     SDVO_CMD_SET_CONTROL_BUS_SWITCH,
     629             :                                     &ddc_bus, 1);
     630             : }
     631             : 
     632           0 : static bool intel_sdvo_set_value(struct intel_sdvo *intel_sdvo, u8 cmd, const void *data, int len)
     633             : {
     634           0 :         if (!intel_sdvo_write_cmd(intel_sdvo, cmd, data, len))
     635           0 :                 return false;
     636             : 
     637           0 :         return intel_sdvo_read_response(intel_sdvo, NULL, 0);
     638           0 : }
     639             : 
     640             : static bool
     641           0 : intel_sdvo_get_value(struct intel_sdvo *intel_sdvo, u8 cmd, void *value, int len)
     642             : {
     643           0 :         if (!intel_sdvo_write_cmd(intel_sdvo, cmd, NULL, 0))
     644           0 :                 return false;
     645             : 
     646           0 :         return intel_sdvo_read_response(intel_sdvo, value, len);
     647           0 : }
     648             : 
     649           0 : static bool intel_sdvo_set_target_input(struct intel_sdvo *intel_sdvo)
     650             : {
     651           0 :         struct intel_sdvo_set_target_input_args targets = {0};
     652           0 :         return intel_sdvo_set_value(intel_sdvo,
     653             :                                     SDVO_CMD_SET_TARGET_INPUT,
     654             :                                     &targets, sizeof(targets));
     655           0 : }
     656             : 
     657             : /**
     658             :  * Return whether each input is trained.
     659             :  *
     660             :  * This function is making an assumption about the layout of the response,
     661             :  * which should be checked against the docs.
     662             :  */
     663           0 : static bool intel_sdvo_get_trained_inputs(struct intel_sdvo *intel_sdvo, bool *input_1, bool *input_2)
     664             : {
     665           0 :         struct intel_sdvo_get_trained_inputs_response response;
     666             : 
     667             :         BUILD_BUG_ON(sizeof(response) != 1);
     668           0 :         if (!intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_TRAINED_INPUTS,
     669             :                                   &response, sizeof(response)))
     670           0 :                 return false;
     671             : 
     672           0 :         *input_1 = response.input0_trained;
     673           0 :         *input_2 = response.input1_trained;
     674           0 :         return true;
     675           0 : }
     676             : 
     677           0 : static bool intel_sdvo_set_active_outputs(struct intel_sdvo *intel_sdvo,
     678             :                                           u16 outputs)
     679             : {
     680           0 :         return intel_sdvo_set_value(intel_sdvo,
     681             :                                     SDVO_CMD_SET_ACTIVE_OUTPUTS,
     682           0 :                                     &outputs, sizeof(outputs));
     683             : }
     684             : 
     685           0 : static bool intel_sdvo_get_active_outputs(struct intel_sdvo *intel_sdvo,
     686             :                                           u16 *outputs)
     687             : {
     688           0 :         return intel_sdvo_get_value(intel_sdvo,
     689             :                                     SDVO_CMD_GET_ACTIVE_OUTPUTS,
     690           0 :                                     outputs, sizeof(*outputs));
     691             : }
     692             : 
     693             : static bool intel_sdvo_set_encoder_power_state(struct intel_sdvo *intel_sdvo,
     694             :                                                int mode)
     695             : {
     696             :         u8 state = SDVO_ENCODER_STATE_ON;
     697             : 
     698             :         switch (mode) {
     699             :         case DRM_MODE_DPMS_ON:
     700             :                 state = SDVO_ENCODER_STATE_ON;
     701             :                 break;
     702             :         case DRM_MODE_DPMS_STANDBY:
     703             :                 state = SDVO_ENCODER_STATE_STANDBY;
     704             :                 break;
     705             :         case DRM_MODE_DPMS_SUSPEND:
     706             :                 state = SDVO_ENCODER_STATE_SUSPEND;
     707             :                 break;
     708             :         case DRM_MODE_DPMS_OFF:
     709             :                 state = SDVO_ENCODER_STATE_OFF;
     710             :                 break;
     711             :         }
     712             : 
     713             :         return intel_sdvo_set_value(intel_sdvo,
     714             :                                     SDVO_CMD_SET_ENCODER_POWER_STATE, &state, sizeof(state));
     715             : }
     716             : 
     717           0 : static bool intel_sdvo_get_input_pixel_clock_range(struct intel_sdvo *intel_sdvo,
     718             :                                                    int *clock_min,
     719             :                                                    int *clock_max)
     720             : {
     721           0 :         struct intel_sdvo_pixel_clock_range clocks;
     722             : 
     723             :         BUILD_BUG_ON(sizeof(clocks) != 4);
     724           0 :         if (!intel_sdvo_get_value(intel_sdvo,
     725             :                                   SDVO_CMD_GET_INPUT_PIXEL_CLOCK_RANGE,
     726             :                                   &clocks, sizeof(clocks)))
     727           0 :                 return false;
     728             : 
     729             :         /* Convert the values from units of 10 kHz to kHz. */
     730           0 :         *clock_min = clocks.min * 10;
     731           0 :         *clock_max = clocks.max * 10;
     732           0 :         return true;
     733           0 : }
     734             : 
     735           0 : static bool intel_sdvo_set_target_output(struct intel_sdvo *intel_sdvo,
     736             :                                          u16 outputs)
     737             : {
     738           0 :         return intel_sdvo_set_value(intel_sdvo,
     739             :                                     SDVO_CMD_SET_TARGET_OUTPUT,
     740           0 :                                     &outputs, sizeof(outputs));
     741             : }
     742             : 
     743           0 : static bool intel_sdvo_set_timing(struct intel_sdvo *intel_sdvo, u8 cmd,
     744             :                                   struct intel_sdvo_dtd *dtd)
     745             : {
     746           0 :         return intel_sdvo_set_value(intel_sdvo, cmd, &dtd->part1, sizeof(dtd->part1)) &&
     747           0 :                 intel_sdvo_set_value(intel_sdvo, cmd + 1, &dtd->part2, sizeof(dtd->part2));
     748             : }
     749             : 
     750           0 : static bool intel_sdvo_get_timing(struct intel_sdvo *intel_sdvo, u8 cmd,
     751             :                                   struct intel_sdvo_dtd *dtd)
     752             : {
     753           0 :         return intel_sdvo_get_value(intel_sdvo, cmd, &dtd->part1, sizeof(dtd->part1)) &&
     754           0 :                 intel_sdvo_get_value(intel_sdvo, cmd + 1, &dtd->part2, sizeof(dtd->part2));
     755             : }
     756             : 
     757           0 : static bool intel_sdvo_set_input_timing(struct intel_sdvo *intel_sdvo,
     758             :                                          struct intel_sdvo_dtd *dtd)
     759             : {
     760           0 :         return intel_sdvo_set_timing(intel_sdvo,
     761             :                                      SDVO_CMD_SET_INPUT_TIMINGS_PART1, dtd);
     762             : }
     763             : 
     764           0 : static bool intel_sdvo_set_output_timing(struct intel_sdvo *intel_sdvo,
     765             :                                          struct intel_sdvo_dtd *dtd)
     766             : {
     767           0 :         return intel_sdvo_set_timing(intel_sdvo,
     768             :                                      SDVO_CMD_SET_OUTPUT_TIMINGS_PART1, dtd);
     769             : }
     770             : 
     771           0 : static bool intel_sdvo_get_input_timing(struct intel_sdvo *intel_sdvo,
     772             :                                         struct intel_sdvo_dtd *dtd)
     773             : {
     774           0 :         return intel_sdvo_get_timing(intel_sdvo,
     775             :                                      SDVO_CMD_GET_INPUT_TIMINGS_PART1, dtd);
     776             : }
     777             : 
     778             : static bool
     779           0 : intel_sdvo_create_preferred_input_timing(struct intel_sdvo *intel_sdvo,
     780             :                                          uint16_t clock,
     781             :                                          uint16_t width,
     782             :                                          uint16_t height)
     783             : {
     784           0 :         struct intel_sdvo_preferred_input_timing_args args;
     785             : 
     786           0 :         memset(&args, 0, sizeof(args));
     787           0 :         args.clock = clock;
     788           0 :         args.width = width;
     789           0 :         args.height = height;
     790           0 :         args.interlace = 0;
     791             : 
     792           0 :         if (intel_sdvo->is_lvds &&
     793           0 :            (intel_sdvo->sdvo_lvds_fixed_mode->hdisplay != width ||
     794           0 :             intel_sdvo->sdvo_lvds_fixed_mode->vdisplay != height))
     795           0 :                 args.scaled = 1;
     796             : 
     797           0 :         return intel_sdvo_set_value(intel_sdvo,
     798             :                                     SDVO_CMD_CREATE_PREFERRED_INPUT_TIMING,
     799             :                                     &args, sizeof(args));
     800           0 : }
     801             : 
     802           0 : static bool intel_sdvo_get_preferred_input_timing(struct intel_sdvo *intel_sdvo,
     803             :                                                   struct intel_sdvo_dtd *dtd)
     804             : {
     805             :         BUILD_BUG_ON(sizeof(dtd->part1) != 8);
     806             :         BUILD_BUG_ON(sizeof(dtd->part2) != 8);
     807           0 :         return intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART1,
     808           0 :                                     &dtd->part1, sizeof(dtd->part1)) &&
     809           0 :                 intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART2,
     810           0 :                                      &dtd->part2, sizeof(dtd->part2));
     811             : }
     812             : 
     813           0 : static bool intel_sdvo_set_clock_rate_mult(struct intel_sdvo *intel_sdvo, u8 val)
     814             : {
     815           0 :         return intel_sdvo_set_value(intel_sdvo, SDVO_CMD_SET_CLOCK_RATE_MULT, &val, 1);
     816             : }
     817             : 
     818           0 : static void intel_sdvo_get_dtd_from_mode(struct intel_sdvo_dtd *dtd,
     819             :                                          const struct drm_display_mode *mode)
     820             : {
     821             :         uint16_t width, height;
     822             :         uint16_t h_blank_len, h_sync_len, v_blank_len, v_sync_len;
     823             :         uint16_t h_sync_offset, v_sync_offset;
     824             :         int mode_clock;
     825             : 
     826           0 :         memset(dtd, 0, sizeof(*dtd));
     827             : 
     828           0 :         width = mode->hdisplay;
     829           0 :         height = mode->vdisplay;
     830             : 
     831             :         /* do some mode translations */
     832           0 :         h_blank_len = mode->htotal - mode->hdisplay;
     833           0 :         h_sync_len = mode->hsync_end - mode->hsync_start;
     834             : 
     835           0 :         v_blank_len = mode->vtotal - mode->vdisplay;
     836           0 :         v_sync_len = mode->vsync_end - mode->vsync_start;
     837             : 
     838           0 :         h_sync_offset = mode->hsync_start - mode->hdisplay;
     839           0 :         v_sync_offset = mode->vsync_start - mode->vdisplay;
     840             : 
     841           0 :         mode_clock = mode->clock;
     842           0 :         mode_clock /= 10;
     843           0 :         dtd->part1.clock = mode_clock;
     844             : 
     845           0 :         dtd->part1.h_active = width & 0xff;
     846           0 :         dtd->part1.h_blank = h_blank_len & 0xff;
     847           0 :         dtd->part1.h_high = (((width >> 8) & 0xf) << 4) |
     848           0 :                 ((h_blank_len >> 8) & 0xf);
     849           0 :         dtd->part1.v_active = height & 0xff;
     850           0 :         dtd->part1.v_blank = v_blank_len & 0xff;
     851           0 :         dtd->part1.v_high = (((height >> 8) & 0xf) << 4) |
     852           0 :                 ((v_blank_len >> 8) & 0xf);
     853             : 
     854           0 :         dtd->part2.h_sync_off = h_sync_offset & 0xff;
     855           0 :         dtd->part2.h_sync_width = h_sync_len & 0xff;
     856           0 :         dtd->part2.v_sync_off_width = (v_sync_offset & 0xf) << 4 |
     857           0 :                 (v_sync_len & 0xf);
     858           0 :         dtd->part2.sync_off_width_high = ((h_sync_offset & 0x300) >> 2) |
     859           0 :                 ((h_sync_len & 0x300) >> 4) | ((v_sync_offset & 0x30) >> 2) |
     860           0 :                 ((v_sync_len & 0x30) >> 4);
     861             : 
     862           0 :         dtd->part2.dtd_flags = 0x18;
     863           0 :         if (mode->flags & DRM_MODE_FLAG_INTERLACE)
     864           0 :                 dtd->part2.dtd_flags |= DTD_FLAG_INTERLACE;
     865           0 :         if (mode->flags & DRM_MODE_FLAG_PHSYNC)
     866           0 :                 dtd->part2.dtd_flags |= DTD_FLAG_HSYNC_POSITIVE;
     867           0 :         if (mode->flags & DRM_MODE_FLAG_PVSYNC)
     868           0 :                 dtd->part2.dtd_flags |= DTD_FLAG_VSYNC_POSITIVE;
     869             : 
     870           0 :         dtd->part2.v_sync_off_high = v_sync_offset & 0xc0;
     871           0 : }
     872             : 
     873           0 : static void intel_sdvo_get_mode_from_dtd(struct drm_display_mode *pmode,
     874             :                                          const struct intel_sdvo_dtd *dtd)
     875             : {
     876           0 :         struct drm_display_mode mode = {};
     877             : 
     878           0 :         mode.hdisplay = dtd->part1.h_active;
     879           0 :         mode.hdisplay += ((dtd->part1.h_high >> 4) & 0x0f) << 8;
     880           0 :         mode.hsync_start = mode.hdisplay + dtd->part2.h_sync_off;
     881           0 :         mode.hsync_start += (dtd->part2.sync_off_width_high & 0xc0) << 2;
     882           0 :         mode.hsync_end = mode.hsync_start + dtd->part2.h_sync_width;
     883           0 :         mode.hsync_end += (dtd->part2.sync_off_width_high & 0x30) << 4;
     884           0 :         mode.htotal = mode.hdisplay + dtd->part1.h_blank;
     885           0 :         mode.htotal += (dtd->part1.h_high & 0xf) << 8;
     886             : 
     887           0 :         mode.vdisplay = dtd->part1.v_active;
     888           0 :         mode.vdisplay += ((dtd->part1.v_high >> 4) & 0x0f) << 8;
     889           0 :         mode.vsync_start = mode.vdisplay;
     890           0 :         mode.vsync_start += (dtd->part2.v_sync_off_width >> 4) & 0xf;
     891           0 :         mode.vsync_start += (dtd->part2.sync_off_width_high & 0x0c) << 2;
     892           0 :         mode.vsync_start += dtd->part2.v_sync_off_high & 0xc0;
     893           0 :         mode.vsync_end = mode.vsync_start +
     894           0 :                 (dtd->part2.v_sync_off_width & 0xf);
     895           0 :         mode.vsync_end += (dtd->part2.sync_off_width_high & 0x3) << 4;
     896           0 :         mode.vtotal = mode.vdisplay + dtd->part1.v_blank;
     897           0 :         mode.vtotal += (dtd->part1.v_high & 0xf) << 8;
     898             : 
     899           0 :         mode.clock = dtd->part1.clock * 10;
     900             : 
     901           0 :         if (dtd->part2.dtd_flags & DTD_FLAG_INTERLACE)
     902           0 :                 mode.flags |= DRM_MODE_FLAG_INTERLACE;
     903           0 :         if (dtd->part2.dtd_flags & DTD_FLAG_HSYNC_POSITIVE)
     904           0 :                 mode.flags |= DRM_MODE_FLAG_PHSYNC;
     905             :         else
     906           0 :                 mode.flags |= DRM_MODE_FLAG_NHSYNC;
     907           0 :         if (dtd->part2.dtd_flags & DTD_FLAG_VSYNC_POSITIVE)
     908           0 :                 mode.flags |= DRM_MODE_FLAG_PVSYNC;
     909             :         else
     910           0 :                 mode.flags |= DRM_MODE_FLAG_NVSYNC;
     911             : 
     912           0 :         drm_mode_set_crtcinfo(&mode, 0);
     913             : 
     914           0 :         drm_mode_copy(pmode, &mode);
     915           0 : }
     916             : 
     917           0 : static bool intel_sdvo_check_supp_encode(struct intel_sdvo *intel_sdvo)
     918             : {
     919           0 :         struct intel_sdvo_encode encode;
     920             : 
     921             :         BUILD_BUG_ON(sizeof(encode) != 2);
     922           0 :         return intel_sdvo_get_value(intel_sdvo,
     923             :                                   SDVO_CMD_GET_SUPP_ENCODE,
     924             :                                   &encode, sizeof(encode));
     925           0 : }
     926             : 
     927           0 : static bool intel_sdvo_set_encode(struct intel_sdvo *intel_sdvo,
     928             :                                   uint8_t mode)
     929             : {
     930           0 :         return intel_sdvo_set_value(intel_sdvo, SDVO_CMD_SET_ENCODE, &mode, 1);
     931             : }
     932             : 
     933           0 : static bool intel_sdvo_set_colorimetry(struct intel_sdvo *intel_sdvo,
     934             :                                        uint8_t mode)
     935             : {
     936           0 :         return intel_sdvo_set_value(intel_sdvo, SDVO_CMD_SET_COLORIMETRY, &mode, 1);
     937             : }
     938             : 
     939             : #if 0
     940             : static void intel_sdvo_dump_hdmi_buf(struct intel_sdvo *intel_sdvo)
     941             : {
     942             :         int i, j;
     943             :         uint8_t set_buf_index[2];
     944             :         uint8_t av_split;
     945             :         uint8_t buf_size;
     946             :         uint8_t buf[48];
     947             :         uint8_t *pos;
     948             : 
     949             :         intel_sdvo_get_value(encoder, SDVO_CMD_GET_HBUF_AV_SPLIT, &av_split, 1);
     950             : 
     951             :         for (i = 0; i <= av_split; i++) {
     952             :                 set_buf_index[0] = i; set_buf_index[1] = 0;
     953             :                 intel_sdvo_write_cmd(encoder, SDVO_CMD_SET_HBUF_INDEX,
     954             :                                      set_buf_index, 2);
     955             :                 intel_sdvo_write_cmd(encoder, SDVO_CMD_GET_HBUF_INFO, NULL, 0);
     956             :                 intel_sdvo_read_response(encoder, &buf_size, 1);
     957             : 
     958             :                 pos = buf;
     959             :                 for (j = 0; j <= buf_size; j += 8) {
     960             :                         intel_sdvo_write_cmd(encoder, SDVO_CMD_GET_HBUF_DATA,
     961             :                                              NULL, 0);
     962             :                         intel_sdvo_read_response(encoder, pos, 8);
     963             :                         pos += 8;
     964             :                 }
     965             :         }
     966             : }
     967             : #endif
     968             : 
     969           0 : static bool intel_sdvo_write_infoframe(struct intel_sdvo *intel_sdvo,
     970             :                                        unsigned if_index, uint8_t tx_rate,
     971             :                                        const uint8_t *data, unsigned length)
     972             : {
     973           0 :         uint8_t set_buf_index[2] = { if_index, 0 };
     974           0 :         uint8_t hbuf_size, tmp[8];
     975             :         int i;
     976             : 
     977           0 :         if (!intel_sdvo_set_value(intel_sdvo,
     978             :                                   SDVO_CMD_SET_HBUF_INDEX,
     979           0 :                                   set_buf_index, 2))
     980           0 :                 return false;
     981             : 
     982           0 :         if (!intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_HBUF_INFO,
     983             :                                   &hbuf_size, 1))
     984           0 :                 return false;
     985             : 
     986             :         /* Buffer size is 0 based, hooray! */
     987           0 :         hbuf_size++;
     988             : 
     989             :         DRM_DEBUG_KMS("writing sdvo hbuf: %i, hbuf_size %i, hbuf_size: %i\n",
     990             :                       if_index, length, hbuf_size);
     991             : 
     992           0 :         for (i = 0; i < hbuf_size; i += 8) {
     993           0 :                 memset(tmp, 0, 8);
     994           0 :                 if (i < length)
     995           0 :                         memcpy(tmp, data + i, min_t(unsigned, 8, length - i));
     996             : 
     997           0 :                 if (!intel_sdvo_set_value(intel_sdvo,
     998             :                                           SDVO_CMD_SET_HBUF_DATA,
     999             :                                           tmp, 8))
    1000           0 :                         return false;
    1001             :         }
    1002             : 
    1003           0 :         return intel_sdvo_set_value(intel_sdvo,
    1004             :                                     SDVO_CMD_SET_HBUF_TXRATE,
    1005             :                                     &tx_rate, 1);
    1006           0 : }
    1007             : 
    1008           0 : static bool intel_sdvo_set_avi_infoframe(struct intel_sdvo *intel_sdvo,
    1009             :                                          const struct drm_display_mode *adjusted_mode)
    1010             : {
    1011           0 :         uint8_t sdvo_data[HDMI_INFOFRAME_SIZE(AVI)];
    1012           0 :         struct drm_crtc *crtc = intel_sdvo->base.base.crtc;
    1013           0 :         struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
    1014           0 :         union hdmi_infoframe frame;
    1015             :         int ret;
    1016             :         ssize_t len;
    1017             : 
    1018           0 :         ret = drm_hdmi_avi_infoframe_from_display_mode(&frame.avi,
    1019             :                                                        adjusted_mode);
    1020           0 :         if (ret < 0) {
    1021           0 :                 DRM_ERROR("couldn't fill AVI infoframe\n");
    1022           0 :                 return false;
    1023             :         }
    1024             : 
    1025           0 :         if (intel_sdvo->rgb_quant_range_selectable) {
    1026           0 :                 if (intel_crtc->config->limited_color_range)
    1027           0 :                         frame.avi.quantization_range =
    1028             :                                 HDMI_QUANTIZATION_RANGE_LIMITED;
    1029             :                 else
    1030           0 :                         frame.avi.quantization_range =
    1031             :                                 HDMI_QUANTIZATION_RANGE_FULL;
    1032             :         }
    1033             : 
    1034           0 :         len = hdmi_infoframe_pack(&frame, sdvo_data, sizeof(sdvo_data));
    1035           0 :         if (len < 0)
    1036           0 :                 return false;
    1037             : 
    1038           0 :         return intel_sdvo_write_infoframe(intel_sdvo, SDVO_HBUF_INDEX_AVI_IF,
    1039             :                                           SDVO_HBUF_TX_VSYNC,
    1040             :                                           sdvo_data, sizeof(sdvo_data));
    1041           0 : }
    1042             : 
    1043           0 : static bool intel_sdvo_set_tv_format(struct intel_sdvo *intel_sdvo)
    1044             : {
    1045           0 :         struct intel_sdvo_tv_format format;
    1046           0 :         uint32_t format_map;
    1047             : 
    1048           0 :         format_map = 1 << intel_sdvo->tv_format_index;
    1049           0 :         memset(&format, 0, sizeof(format));
    1050           0 :         memcpy(&format, &format_map, min(sizeof(format), sizeof(format_map)));
    1051             : 
    1052             :         BUILD_BUG_ON(sizeof(format) != 6);
    1053           0 :         return intel_sdvo_set_value(intel_sdvo,
    1054             :                                     SDVO_CMD_SET_TV_FORMAT,
    1055             :                                     &format, sizeof(format));
    1056           0 : }
    1057             : 
    1058             : static bool
    1059           0 : intel_sdvo_set_output_timings_from_mode(struct intel_sdvo *intel_sdvo,
    1060             :                                         const struct drm_display_mode *mode)
    1061             : {
    1062           0 :         struct intel_sdvo_dtd output_dtd;
    1063             : 
    1064           0 :         if (!intel_sdvo_set_target_output(intel_sdvo,
    1065           0 :                                           intel_sdvo->attached_output))
    1066           0 :                 return false;
    1067             : 
    1068           0 :         intel_sdvo_get_dtd_from_mode(&output_dtd, mode);
    1069           0 :         if (!intel_sdvo_set_output_timing(intel_sdvo, &output_dtd))
    1070           0 :                 return false;
    1071             : 
    1072           0 :         return true;
    1073           0 : }
    1074             : 
    1075             : /* Asks the sdvo controller for the preferred input mode given the output mode.
    1076             :  * Unfortunately we have to set up the full output mode to do that. */
    1077             : static bool
    1078           0 : intel_sdvo_get_preferred_input_mode(struct intel_sdvo *intel_sdvo,
    1079             :                                     const struct drm_display_mode *mode,
    1080             :                                     struct drm_display_mode *adjusted_mode)
    1081             : {
    1082           0 :         struct intel_sdvo_dtd input_dtd;
    1083             : 
    1084             :         /* Reset the input timing to the screen. Assume always input 0. */
    1085           0 :         if (!intel_sdvo_set_target_input(intel_sdvo))
    1086           0 :                 return false;
    1087             : 
    1088           0 :         if (!intel_sdvo_create_preferred_input_timing(intel_sdvo,
    1089           0 :                                                       mode->clock / 10,
    1090           0 :                                                       mode->hdisplay,
    1091           0 :                                                       mode->vdisplay))
    1092           0 :                 return false;
    1093             : 
    1094           0 :         if (!intel_sdvo_get_preferred_input_timing(intel_sdvo,
    1095             :                                                    &input_dtd))
    1096           0 :                 return false;
    1097             : 
    1098           0 :         intel_sdvo_get_mode_from_dtd(adjusted_mode, &input_dtd);
    1099           0 :         intel_sdvo->dtd_sdvo_flags = input_dtd.part2.sdvo_flags;
    1100             : 
    1101           0 :         return true;
    1102           0 : }
    1103             : 
    1104           0 : static void i9xx_adjust_sdvo_tv_clock(struct intel_crtc_state *pipe_config)
    1105             : {
    1106           0 :         unsigned dotclock = pipe_config->port_clock;
    1107           0 :         struct dpll *clock = &pipe_config->dpll;
    1108             : 
    1109             :         /* SDVO TV has fixed PLL values depend on its clock range,
    1110             :            this mirrors vbios setting. */
    1111           0 :         if (dotclock >= 100000 && dotclock < 140500) {
    1112           0 :                 clock->p1 = 2;
    1113           0 :                 clock->p2 = 10;
    1114           0 :                 clock->n = 3;
    1115           0 :                 clock->m1 = 16;
    1116           0 :                 clock->m2 = 8;
    1117           0 :         } else if (dotclock >= 140500 && dotclock <= 200000) {
    1118           0 :                 clock->p1 = 1;
    1119           0 :                 clock->p2 = 10;
    1120           0 :                 clock->n = 6;
    1121           0 :                 clock->m1 = 12;
    1122           0 :                 clock->m2 = 8;
    1123           0 :         } else {
    1124           0 :                 WARN(1, "SDVO TV clock out of range: %i\n", dotclock);
    1125             :         }
    1126             : 
    1127           0 :         pipe_config->clock_set = true;
    1128           0 : }
    1129             : 
    1130           0 : static bool intel_sdvo_compute_config(struct intel_encoder *encoder,
    1131             :                                       struct intel_crtc_state *pipe_config)
    1132             : {
    1133           0 :         struct intel_sdvo *intel_sdvo = to_sdvo(encoder);
    1134           0 :         struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
    1135           0 :         struct drm_display_mode *mode = &pipe_config->base.mode;
    1136             : 
    1137             :         DRM_DEBUG_KMS("forcing bpc to 8 for SDVO\n");
    1138           0 :         pipe_config->pipe_bpp = 8*3;
    1139             : 
    1140           0 :         if (HAS_PCH_SPLIT(encoder->base.dev))
    1141           0 :                 pipe_config->has_pch_encoder = true;
    1142             : 
    1143             :         /* We need to construct preferred input timings based on our
    1144             :          * output timings.  To do that, we have to set the output
    1145             :          * timings, even though this isn't really the right place in
    1146             :          * the sequence to do it. Oh well.
    1147             :          */
    1148           0 :         if (intel_sdvo->is_tv) {
    1149           0 :                 if (!intel_sdvo_set_output_timings_from_mode(intel_sdvo, mode))
    1150           0 :                         return false;
    1151             : 
    1152           0 :                 (void) intel_sdvo_get_preferred_input_mode(intel_sdvo,
    1153             :                                                            mode,
    1154             :                                                            adjusted_mode);
    1155           0 :                 pipe_config->sdvo_tv_clock = true;
    1156           0 :         } else if (intel_sdvo->is_lvds) {
    1157           0 :                 if (!intel_sdvo_set_output_timings_from_mode(intel_sdvo,
    1158           0 :                                                              intel_sdvo->sdvo_lvds_fixed_mode))
    1159           0 :                         return false;
    1160             : 
    1161           0 :                 (void) intel_sdvo_get_preferred_input_mode(intel_sdvo,
    1162             :                                                            mode,
    1163             :                                                            adjusted_mode);
    1164           0 :         }
    1165             : 
    1166             :         /* Make the CRTC code factor in the SDVO pixel multiplier.  The
    1167             :          * SDVO device will factor out the multiplier during mode_set.
    1168             :          */
    1169           0 :         pipe_config->pixel_multiplier =
    1170           0 :                 intel_sdvo_get_pixel_multiplier(adjusted_mode);
    1171             : 
    1172           0 :         pipe_config->has_hdmi_sink = intel_sdvo->has_hdmi_monitor;
    1173             : 
    1174           0 :         if (intel_sdvo->color_range_auto) {
    1175             :                 /* See CEA-861-E - 5.1 Default Encoding Parameters */
    1176             :                 /* FIXME: This bit is only valid when using TMDS encoding and 8
    1177             :                  * bit per color mode. */
    1178           0 :                 if (pipe_config->has_hdmi_sink &&
    1179           0 :                     drm_match_cea_mode(adjusted_mode) > 1)
    1180           0 :                         pipe_config->limited_color_range = true;
    1181             :         } else {
    1182           0 :                 if (pipe_config->has_hdmi_sink &&
    1183           0 :                     intel_sdvo->color_range == HDMI_COLOR_RANGE_16_235)
    1184           0 :                         pipe_config->limited_color_range = true;
    1185             :         }
    1186             : 
    1187             :         /* Clock computation needs to happen after pixel multiplier. */
    1188           0 :         if (intel_sdvo->is_tv)
    1189           0 :                 i9xx_adjust_sdvo_tv_clock(pipe_config);
    1190             : 
    1191             :         /* Set user selected PAR to incoming mode's member */
    1192           0 :         if (intel_sdvo->is_hdmi)
    1193           0 :                 adjusted_mode->picture_aspect_ratio = intel_sdvo->aspect_ratio;
    1194             : 
    1195           0 :         return true;
    1196           0 : }
    1197             : 
    1198           0 : static void intel_sdvo_pre_enable(struct intel_encoder *intel_encoder)
    1199             : {
    1200           0 :         struct drm_device *dev = intel_encoder->base.dev;
    1201           0 :         struct drm_i915_private *dev_priv = dev->dev_private;
    1202           0 :         struct intel_crtc *crtc = to_intel_crtc(intel_encoder->base.crtc);
    1203           0 :         const struct drm_display_mode *adjusted_mode = &crtc->config->base.adjusted_mode;
    1204           0 :         struct drm_display_mode *mode = &crtc->config->base.mode;
    1205           0 :         struct intel_sdvo *intel_sdvo = to_sdvo(intel_encoder);
    1206             :         u32 sdvox;
    1207           0 :         struct intel_sdvo_in_out_map in_out;
    1208           0 :         struct intel_sdvo_dtd input_dtd, output_dtd;
    1209             :         int rate;
    1210             : 
    1211           0 :         if (!mode)
    1212           0 :                 return;
    1213             : 
    1214             :         /* First, set the input mapping for the first input to our controlled
    1215             :          * output. This is only correct if we're a single-input device, in
    1216             :          * which case the first input is the output from the appropriate SDVO
    1217             :          * channel on the motherboard.  In a two-input device, the first input
    1218             :          * will be SDVOB and the second SDVOC.
    1219             :          */
    1220           0 :         in_out.in0 = intel_sdvo->attached_output;
    1221           0 :         in_out.in1 = 0;
    1222             : 
    1223           0 :         intel_sdvo_set_value(intel_sdvo,
    1224             :                              SDVO_CMD_SET_IN_OUT_MAP,
    1225             :                              &in_out, sizeof(in_out));
    1226             : 
    1227             :         /* Set the output timings to the screen */
    1228           0 :         if (!intel_sdvo_set_target_output(intel_sdvo,
    1229           0 :                                           intel_sdvo->attached_output))
    1230           0 :                 return;
    1231             : 
    1232             :         /* lvds has a special fixed output timing. */
    1233           0 :         if (intel_sdvo->is_lvds)
    1234           0 :                 intel_sdvo_get_dtd_from_mode(&output_dtd,
    1235           0 :                                              intel_sdvo->sdvo_lvds_fixed_mode);
    1236             :         else
    1237           0 :                 intel_sdvo_get_dtd_from_mode(&output_dtd, mode);
    1238           0 :         if (!intel_sdvo_set_output_timing(intel_sdvo, &output_dtd))
    1239             :                 DRM_INFO("Setting output timings on %s failed\n",
    1240             :                          SDVO_NAME(intel_sdvo));
    1241             : 
    1242             :         /* Set the input timing to the screen. Assume always input 0. */
    1243           0 :         if (!intel_sdvo_set_target_input(intel_sdvo))
    1244           0 :                 return;
    1245             : 
    1246           0 :         if (crtc->config->has_hdmi_sink) {
    1247           0 :                 intel_sdvo_set_encode(intel_sdvo, SDVO_ENCODE_HDMI);
    1248           0 :                 intel_sdvo_set_colorimetry(intel_sdvo,
    1249             :                                            SDVO_COLORIMETRY_RGB256);
    1250           0 :                 intel_sdvo_set_avi_infoframe(intel_sdvo, adjusted_mode);
    1251           0 :         } else
    1252           0 :                 intel_sdvo_set_encode(intel_sdvo, SDVO_ENCODE_DVI);
    1253             : 
    1254           0 :         if (intel_sdvo->is_tv &&
    1255           0 :             !intel_sdvo_set_tv_format(intel_sdvo))
    1256           0 :                 return;
    1257             : 
    1258           0 :         intel_sdvo_get_dtd_from_mode(&input_dtd, adjusted_mode);
    1259             : 
    1260           0 :         if (intel_sdvo->is_tv || intel_sdvo->is_lvds)
    1261           0 :                 input_dtd.part2.sdvo_flags = intel_sdvo->dtd_sdvo_flags;
    1262           0 :         if (!intel_sdvo_set_input_timing(intel_sdvo, &input_dtd))
    1263             :                 DRM_INFO("Setting input timings on %s failed\n",
    1264             :                          SDVO_NAME(intel_sdvo));
    1265             : 
    1266           0 :         switch (crtc->config->pixel_multiplier) {
    1267             :         default:
    1268           0 :                 WARN(1, "unknown pixel multiplier specified\n");
    1269           0 :         case 1: rate = SDVO_CLOCK_RATE_MULT_1X; break;
    1270           0 :         case 2: rate = SDVO_CLOCK_RATE_MULT_2X; break;
    1271           0 :         case 4: rate = SDVO_CLOCK_RATE_MULT_4X; break;
    1272             :         }
    1273           0 :         if (!intel_sdvo_set_clock_rate_mult(intel_sdvo, rate))
    1274           0 :                 return;
    1275             : 
    1276             :         /* Set the SDVO control regs. */
    1277           0 :         if (INTEL_INFO(dev)->gen >= 4) {
    1278             :                 /* The real mode polarity is set by the SDVO commands, using
    1279             :                  * struct intel_sdvo_dtd. */
    1280             :                 sdvox = SDVO_VSYNC_ACTIVE_HIGH | SDVO_HSYNC_ACTIVE_HIGH;
    1281           0 :                 if (!HAS_PCH_SPLIT(dev) && crtc->config->limited_color_range)
    1282           0 :                         sdvox |= HDMI_COLOR_RANGE_16_235;
    1283           0 :                 if (INTEL_INFO(dev)->gen < 5)
    1284           0 :                         sdvox |= SDVO_BORDER_ENABLE;
    1285             :         } else {
    1286           0 :                 sdvox = I915_READ(intel_sdvo->sdvo_reg);
    1287           0 :                 switch (intel_sdvo->sdvo_reg) {
    1288             :                 case GEN3_SDVOB:
    1289           0 :                         sdvox &= SDVOB_PRESERVE_MASK;
    1290           0 :                         break;
    1291             :                 case GEN3_SDVOC:
    1292           0 :                         sdvox &= SDVOC_PRESERVE_MASK;
    1293           0 :                         break;
    1294             :                 }
    1295           0 :                 sdvox |= (9 << 19) | SDVO_BORDER_ENABLE;
    1296             :         }
    1297             : 
    1298           0 :         if (INTEL_PCH_TYPE(dev) >= PCH_CPT)
    1299           0 :                 sdvox |= SDVO_PIPE_SEL_CPT(crtc->pipe);
    1300             :         else
    1301           0 :                 sdvox |= SDVO_PIPE_SEL(crtc->pipe);
    1302             : 
    1303           0 :         if (intel_sdvo->has_hdmi_audio)
    1304           0 :                 sdvox |= SDVO_AUDIO_ENABLE;
    1305             : 
    1306           0 :         if (INTEL_INFO(dev)->gen >= 4) {
    1307             :                 /* done in crtc_mode_set as the dpll_md reg must be written early */
    1308           0 :         } else if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev)) {
    1309             :                 /* done in crtc_mode_set as it lives inside the dpll register */
    1310             :         } else {
    1311           0 :                 sdvox |= (crtc->config->pixel_multiplier - 1)
    1312           0 :                         << SDVO_PORT_MULTIPLY_SHIFT;
    1313             :         }
    1314             : 
    1315           0 :         if (input_dtd.part2.sdvo_flags & SDVO_NEED_TO_STALL &&
    1316           0 :             INTEL_INFO(dev)->gen < 5)
    1317           0 :                 sdvox |= SDVO_STALL_SELECT;
    1318           0 :         intel_sdvo_write_sdvox(intel_sdvo, sdvox);
    1319           0 : }
    1320             : 
    1321           0 : static bool intel_sdvo_connector_get_hw_state(struct intel_connector *connector)
    1322             : {
    1323             :         struct intel_sdvo_connector *intel_sdvo_connector =
    1324           0 :                 to_intel_sdvo_connector(&connector->base);
    1325           0 :         struct intel_sdvo *intel_sdvo = intel_attached_sdvo(&connector->base);
    1326           0 :         u16 active_outputs = 0;
    1327             : 
    1328           0 :         intel_sdvo_get_active_outputs(intel_sdvo, &active_outputs);
    1329             : 
    1330           0 :         if (active_outputs & intel_sdvo_connector->output_flag)
    1331           0 :                 return true;
    1332             :         else
    1333           0 :                 return false;
    1334           0 : }
    1335             : 
    1336           0 : static bool intel_sdvo_get_hw_state(struct intel_encoder *encoder,
    1337             :                                     enum pipe *pipe)
    1338             : {
    1339           0 :         struct drm_device *dev = encoder->base.dev;
    1340           0 :         struct drm_i915_private *dev_priv = dev->dev_private;
    1341           0 :         struct intel_sdvo *intel_sdvo = to_sdvo(encoder);
    1342           0 :         u16 active_outputs = 0;
    1343             :         u32 tmp;
    1344             : 
    1345           0 :         tmp = I915_READ(intel_sdvo->sdvo_reg);
    1346           0 :         intel_sdvo_get_active_outputs(intel_sdvo, &active_outputs);
    1347             : 
    1348           0 :         if (!(tmp & SDVO_ENABLE) && (active_outputs == 0))
    1349           0 :                 return false;
    1350             : 
    1351           0 :         if (HAS_PCH_CPT(dev))
    1352           0 :                 *pipe = PORT_TO_PIPE_CPT(tmp);
    1353             :         else
    1354           0 :                 *pipe = PORT_TO_PIPE(tmp);
    1355             : 
    1356           0 :         return true;
    1357           0 : }
    1358             : 
    1359           0 : static void intel_sdvo_get_config(struct intel_encoder *encoder,
    1360             :                                   struct intel_crtc_state *pipe_config)
    1361             : {
    1362           0 :         struct drm_device *dev = encoder->base.dev;
    1363           0 :         struct drm_i915_private *dev_priv = dev->dev_private;
    1364           0 :         struct intel_sdvo *intel_sdvo = to_sdvo(encoder);
    1365           0 :         struct intel_sdvo_dtd dtd;
    1366             :         int encoder_pixel_multiplier = 0;
    1367             :         int dotclock;
    1368             :         u32 flags = 0, sdvox;
    1369           0 :         u8 val;
    1370             :         bool ret;
    1371             : 
    1372           0 :         sdvox = I915_READ(intel_sdvo->sdvo_reg);
    1373             : 
    1374           0 :         ret = intel_sdvo_get_input_timing(intel_sdvo, &dtd);
    1375           0 :         if (!ret) {
    1376             :                 /* Some sdvo encoders are not spec compliant and don't
    1377             :                  * implement the mandatory get_timings function. */
    1378             :                 DRM_DEBUG_DRIVER("failed to retrieve SDVO DTD\n");
    1379           0 :                 pipe_config->quirks |= PIPE_CONFIG_QUIRK_MODE_SYNC_FLAGS;
    1380           0 :         } else {
    1381           0 :                 if (dtd.part2.dtd_flags & DTD_FLAG_HSYNC_POSITIVE)
    1382           0 :                         flags |= DRM_MODE_FLAG_PHSYNC;
    1383             :                 else
    1384             :                         flags |= DRM_MODE_FLAG_NHSYNC;
    1385             : 
    1386           0 :                 if (dtd.part2.dtd_flags & DTD_FLAG_VSYNC_POSITIVE)
    1387           0 :                         flags |= DRM_MODE_FLAG_PVSYNC;
    1388             :                 else
    1389           0 :                         flags |= DRM_MODE_FLAG_NVSYNC;
    1390             :         }
    1391             : 
    1392           0 :         pipe_config->base.adjusted_mode.flags |= flags;
    1393             : 
    1394             :         /*
    1395             :          * pixel multiplier readout is tricky: Only on i915g/gm it is stored in
    1396             :          * the sdvo port register, on all other platforms it is part of the dpll
    1397             :          * state. Since the general pipe state readout happens before the
    1398             :          * encoder->get_config we so already have a valid pixel multplier on all
    1399             :          * other platfroms.
    1400             :          */
    1401           0 :         if (IS_I915G(dev) || IS_I915GM(dev)) {
    1402           0 :                 pipe_config->pixel_multiplier =
    1403           0 :                         ((sdvox & SDVO_PORT_MULTIPLY_MASK)
    1404           0 :                          >> SDVO_PORT_MULTIPLY_SHIFT) + 1;
    1405           0 :         }
    1406             : 
    1407           0 :         dotclock = pipe_config->port_clock;
    1408           0 :         if (pipe_config->pixel_multiplier)
    1409           0 :                 dotclock /= pipe_config->pixel_multiplier;
    1410             : 
    1411           0 :         if (HAS_PCH_SPLIT(dev))
    1412           0 :                 ironlake_check_encoder_dotclock(pipe_config, dotclock);
    1413             : 
    1414           0 :         pipe_config->base.adjusted_mode.crtc_clock = dotclock;
    1415             : 
    1416             :         /* Cross check the port pixel multiplier with the sdvo encoder state. */
    1417           0 :         if (intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_CLOCK_RATE_MULT,
    1418             :                                  &val, 1)) {
    1419           0 :                 switch (val) {
    1420             :                 case SDVO_CLOCK_RATE_MULT_1X:
    1421             :                         encoder_pixel_multiplier = 1;
    1422           0 :                         break;
    1423             :                 case SDVO_CLOCK_RATE_MULT_2X:
    1424             :                         encoder_pixel_multiplier = 2;
    1425           0 :                         break;
    1426             :                 case SDVO_CLOCK_RATE_MULT_4X:
    1427             :                         encoder_pixel_multiplier = 4;
    1428           0 :                         break;
    1429             :                 }
    1430             :         }
    1431             : 
    1432           0 :         if (sdvox & HDMI_COLOR_RANGE_16_235)
    1433           0 :                 pipe_config->limited_color_range = true;
    1434             : 
    1435           0 :         if (intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_ENCODE,
    1436             :                                  &val, 1)) {
    1437           0 :                 if (val == SDVO_ENCODE_HDMI)
    1438           0 :                         pipe_config->has_hdmi_sink = true;
    1439             :         }
    1440             : 
    1441           0 :         WARN(encoder_pixel_multiplier != pipe_config->pixel_multiplier,
    1442             :              "SDVO pixel multiplier mismatch, port: %i, encoder: %i\n",
    1443             :              pipe_config->pixel_multiplier, encoder_pixel_multiplier);
    1444           0 : }
    1445             : 
    1446           0 : static void intel_disable_sdvo(struct intel_encoder *encoder)
    1447             : {
    1448           0 :         struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
    1449           0 :         struct intel_sdvo *intel_sdvo = to_sdvo(encoder);
    1450           0 :         struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc);
    1451             :         u32 temp;
    1452             : 
    1453           0 :         intel_sdvo_set_active_outputs(intel_sdvo, 0);
    1454             :         if (0)
    1455             :                 intel_sdvo_set_encoder_power_state(intel_sdvo,
    1456             :                                                    DRM_MODE_DPMS_OFF);
    1457             : 
    1458           0 :         temp = I915_READ(intel_sdvo->sdvo_reg);
    1459             : 
    1460           0 :         temp &= ~SDVO_ENABLE;
    1461           0 :         intel_sdvo_write_sdvox(intel_sdvo, temp);
    1462             : 
    1463             :         /*
    1464             :          * HW workaround for IBX, we need to move the port
    1465             :          * to transcoder A after disabling it to allow the
    1466             :          * matching DP port to be enabled on transcoder A.
    1467             :          */
    1468           0 :         if (HAS_PCH_IBX(dev_priv) && crtc->pipe == PIPE_B) {
    1469           0 :                 temp &= ~SDVO_PIPE_B_SELECT;
    1470           0 :                 temp |= SDVO_ENABLE;
    1471           0 :                 intel_sdvo_write_sdvox(intel_sdvo, temp);
    1472             : 
    1473             :                 temp &= ~SDVO_ENABLE;
    1474           0 :                 intel_sdvo_write_sdvox(intel_sdvo, temp);
    1475           0 :         }
    1476           0 : }
    1477             : 
    1478           0 : static void pch_disable_sdvo(struct intel_encoder *encoder)
    1479             : {
    1480           0 : }
    1481             : 
    1482           0 : static void pch_post_disable_sdvo(struct intel_encoder *encoder)
    1483             : {
    1484           0 :         intel_disable_sdvo(encoder);
    1485           0 : }
    1486             : 
    1487           0 : static void intel_enable_sdvo(struct intel_encoder *encoder)
    1488             : {
    1489           0 :         struct drm_device *dev = encoder->base.dev;
    1490           0 :         struct drm_i915_private *dev_priv = dev->dev_private;
    1491           0 :         struct intel_sdvo *intel_sdvo = to_sdvo(encoder);
    1492           0 :         struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc);
    1493             :         u32 temp;
    1494           0 :         bool input1, input2;
    1495             :         int i;
    1496             :         bool success;
    1497             : 
    1498           0 :         temp = I915_READ(intel_sdvo->sdvo_reg);
    1499           0 :         temp |= SDVO_ENABLE;
    1500           0 :         intel_sdvo_write_sdvox(intel_sdvo, temp);
    1501             : 
    1502           0 :         for (i = 0; i < 2; i++)
    1503           0 :                 intel_wait_for_vblank(dev, intel_crtc->pipe);
    1504             : 
    1505           0 :         success = intel_sdvo_get_trained_inputs(intel_sdvo, &input1, &input2);
    1506             :         /* Warn if the device reported failure to sync.
    1507             :          * A lot of SDVO devices fail to notify of sync, but it's
    1508             :          * a given it the status is a success, we succeeded.
    1509             :          */
    1510             :         if (success && !input1) {
    1511             :                 DRM_DEBUG_KMS("First %s output reported failure to "
    1512             :                                 "sync\n", SDVO_NAME(intel_sdvo));
    1513             :         }
    1514             : 
    1515             :         if (0)
    1516             :                 intel_sdvo_set_encoder_power_state(intel_sdvo,
    1517             :                                                    DRM_MODE_DPMS_ON);
    1518           0 :         intel_sdvo_set_active_outputs(intel_sdvo, intel_sdvo->attached_output);
    1519           0 : }
    1520             : 
    1521             : static enum drm_mode_status
    1522           0 : intel_sdvo_mode_valid(struct drm_connector *connector,
    1523             :                       struct drm_display_mode *mode)
    1524             : {
    1525           0 :         struct intel_sdvo *intel_sdvo = intel_attached_sdvo(connector);
    1526             : 
    1527           0 :         if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
    1528           0 :                 return MODE_NO_DBLESCAN;
    1529             : 
    1530           0 :         if (intel_sdvo->pixel_clock_min > mode->clock)
    1531           0 :                 return MODE_CLOCK_LOW;
    1532             : 
    1533           0 :         if (intel_sdvo->pixel_clock_max < mode->clock)
    1534           0 :                 return MODE_CLOCK_HIGH;
    1535             : 
    1536           0 :         if (intel_sdvo->is_lvds) {
    1537           0 :                 if (mode->hdisplay > intel_sdvo->sdvo_lvds_fixed_mode->hdisplay)
    1538           0 :                         return MODE_PANEL;
    1539             : 
    1540           0 :                 if (mode->vdisplay > intel_sdvo->sdvo_lvds_fixed_mode->vdisplay)
    1541           0 :                         return MODE_PANEL;
    1542             :         }
    1543             : 
    1544           0 :         return MODE_OK;
    1545           0 : }
    1546             : 
    1547           0 : static bool intel_sdvo_get_capabilities(struct intel_sdvo *intel_sdvo, struct intel_sdvo_caps *caps)
    1548             : {
    1549             :         BUILD_BUG_ON(sizeof(*caps) != 8);
    1550           0 :         if (!intel_sdvo_get_value(intel_sdvo,
    1551             :                                   SDVO_CMD_GET_DEVICE_CAPS,
    1552           0 :                                   caps, sizeof(*caps)))
    1553           0 :                 return false;
    1554             : 
    1555             :         DRM_DEBUG_KMS("SDVO capabilities:\n"
    1556             :                       "  vendor_id: %d\n"
    1557             :                       "  device_id: %d\n"
    1558             :                       "  device_rev_id: %d\n"
    1559             :                       "  sdvo_version_major: %d\n"
    1560             :                       "  sdvo_version_minor: %d\n"
    1561             :                       "  sdvo_inputs_mask: %d\n"
    1562             :                       "  smooth_scaling: %d\n"
    1563             :                       "  sharp_scaling: %d\n"
    1564             :                       "  up_scaling: %d\n"
    1565             :                       "  down_scaling: %d\n"
    1566             :                       "  stall_support: %d\n"
    1567             :                       "  output_flags: %d\n",
    1568             :                       caps->vendor_id,
    1569             :                       caps->device_id,
    1570             :                       caps->device_rev_id,
    1571             :                       caps->sdvo_version_major,
    1572             :                       caps->sdvo_version_minor,
    1573             :                       caps->sdvo_inputs_mask,
    1574             :                       caps->smooth_scaling,
    1575             :                       caps->sharp_scaling,
    1576             :                       caps->up_scaling,
    1577             :                       caps->down_scaling,
    1578             :                       caps->stall_support,
    1579             :                       caps->output_flags);
    1580             : 
    1581           0 :         return true;
    1582           0 : }
    1583             : 
    1584           0 : static uint16_t intel_sdvo_get_hotplug_support(struct intel_sdvo *intel_sdvo)
    1585             : {
    1586           0 :         struct drm_device *dev = intel_sdvo->base.base.dev;
    1587           0 :         uint16_t hotplug;
    1588             : 
    1589           0 :         if (!I915_HAS_HOTPLUG(dev))
    1590           0 :                 return 0;
    1591             : 
    1592             :         /* HW Erratum: SDVO Hotplug is broken on all i945G chips, there's noise
    1593             :          * on the line. */
    1594           0 :         if (IS_I945G(dev) || IS_I945GM(dev))
    1595           0 :                 return 0;
    1596             : 
    1597           0 :         if (!intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_HOT_PLUG_SUPPORT,
    1598             :                                         &hotplug, sizeof(hotplug)))
    1599           0 :                 return 0;
    1600             : 
    1601           0 :         return hotplug;
    1602           0 : }
    1603             : 
    1604           0 : static void intel_sdvo_enable_hotplug(struct intel_encoder *encoder)
    1605             : {
    1606           0 :         struct intel_sdvo *intel_sdvo = to_sdvo(encoder);
    1607             : 
    1608           0 :         intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_SET_ACTIVE_HOT_PLUG,
    1609           0 :                         &intel_sdvo->hotplug_active, 2);
    1610           0 : }
    1611             : 
    1612             : static bool
    1613           0 : intel_sdvo_multifunc_encoder(struct intel_sdvo *intel_sdvo)
    1614             : {
    1615             :         /* Is there more than one type of output? */
    1616           0 :         return hweight16(intel_sdvo->caps.output_flags) > 1;
    1617             : }
    1618             : 
    1619             : static struct edid *
    1620           0 : intel_sdvo_get_edid(struct drm_connector *connector)
    1621             : {
    1622           0 :         struct intel_sdvo *sdvo = intel_attached_sdvo(connector);
    1623           0 :         return drm_get_edid(connector, &sdvo->ddc);
    1624             : }
    1625             : 
    1626             : /* Mac mini hack -- use the same DDC as the analog connector */
    1627             : static struct edid *
    1628           0 : intel_sdvo_get_analog_edid(struct drm_connector *connector)
    1629             : {
    1630           0 :         struct drm_i915_private *dev_priv = connector->dev->dev_private;
    1631             : 
    1632           0 :         return drm_get_edid(connector,
    1633           0 :                             intel_gmbus_get_adapter(dev_priv,
    1634           0 :                                                     dev_priv->vbt.crt_ddc_pin));
    1635             : }
    1636             : 
    1637             : static enum drm_connector_status
    1638           0 : intel_sdvo_tmds_sink_detect(struct drm_connector *connector)
    1639             : {
    1640           0 :         struct intel_sdvo *intel_sdvo = intel_attached_sdvo(connector);
    1641             :         enum drm_connector_status status;
    1642             :         struct edid *edid;
    1643             : 
    1644           0 :         edid = intel_sdvo_get_edid(connector);
    1645             : 
    1646           0 :         if (edid == NULL && intel_sdvo_multifunc_encoder(intel_sdvo)) {
    1647           0 :                 u8 ddc, saved_ddc = intel_sdvo->ddc_bus;
    1648             : 
    1649             :                 /*
    1650             :                  * Don't use the 1 as the argument of DDC bus switch to get
    1651             :                  * the EDID. It is used for SDVO SPD ROM.
    1652             :                  */
    1653           0 :                 for (ddc = intel_sdvo->ddc_bus >> 1; ddc > 1; ddc >>= 1) {
    1654           0 :                         intel_sdvo->ddc_bus = ddc;
    1655           0 :                         edid = intel_sdvo_get_edid(connector);
    1656           0 :                         if (edid)
    1657             :                                 break;
    1658             :                 }
    1659             :                 /*
    1660             :                  * If we found the EDID on the other bus,
    1661             :                  * assume that is the correct DDC bus.
    1662             :                  */
    1663           0 :                 if (edid == NULL)
    1664           0 :                         intel_sdvo->ddc_bus = saved_ddc;
    1665           0 :         }
    1666             : 
    1667             :         /*
    1668             :          * When there is no edid and no monitor is connected with VGA
    1669             :          * port, try to use the CRT ddc to read the EDID for DVI-connector.
    1670             :          */
    1671           0 :         if (edid == NULL)
    1672           0 :                 edid = intel_sdvo_get_analog_edid(connector);
    1673             : 
    1674             :         status = connector_status_unknown;
    1675           0 :         if (edid != NULL) {
    1676             :                 /* DDC bus is shared, match EDID to connector type */
    1677           0 :                 if (edid->input & DRM_EDID_INPUT_DIGITAL) {
    1678             :                         status = connector_status_connected;
    1679           0 :                         if (intel_sdvo->is_hdmi) {
    1680           0 :                                 intel_sdvo->has_hdmi_monitor = drm_detect_hdmi_monitor(edid);
    1681           0 :                                 intel_sdvo->has_hdmi_audio = drm_detect_monitor_audio(edid);
    1682           0 :                                 intel_sdvo->rgb_quant_range_selectable =
    1683           0 :                                         drm_rgb_quant_range_selectable(edid);
    1684           0 :                         }
    1685             :                 } else
    1686             :                         status = connector_status_disconnected;
    1687           0 :                 kfree(edid);
    1688           0 :         }
    1689             : 
    1690           0 :         if (status == connector_status_connected) {
    1691           0 :                 struct intel_sdvo_connector *intel_sdvo_connector = to_intel_sdvo_connector(connector);
    1692           0 :                 if (intel_sdvo_connector->force_audio != HDMI_AUDIO_AUTO)
    1693           0 :                         intel_sdvo->has_hdmi_audio = (intel_sdvo_connector->force_audio == HDMI_AUDIO_ON);
    1694           0 :         }
    1695             : 
    1696           0 :         return status;
    1697             : }
    1698             : 
    1699             : static bool
    1700           0 : intel_sdvo_connector_matches_edid(struct intel_sdvo_connector *sdvo,
    1701             :                                   struct edid *edid)
    1702             : {
    1703           0 :         bool monitor_is_digital = !!(edid->input & DRM_EDID_INPUT_DIGITAL);
    1704           0 :         bool connector_is_digital = !!IS_DIGITAL(sdvo);
    1705             : 
    1706             :         DRM_DEBUG_KMS("connector_is_digital? %d, monitor_is_digital? %d\n",
    1707             :                       connector_is_digital, monitor_is_digital);
    1708           0 :         return connector_is_digital == monitor_is_digital;
    1709             : }
    1710             : 
    1711             : static enum drm_connector_status
    1712           0 : intel_sdvo_detect(struct drm_connector *connector, bool force)
    1713             : {
    1714           0 :         uint16_t response;
    1715           0 :         struct intel_sdvo *intel_sdvo = intel_attached_sdvo(connector);
    1716           0 :         struct intel_sdvo_connector *intel_sdvo_connector = to_intel_sdvo_connector(connector);
    1717             :         enum drm_connector_status ret;
    1718             : 
    1719             :         DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
    1720             :                       connector->base.id, connector->name);
    1721             : 
    1722           0 :         if (!intel_sdvo_get_value(intel_sdvo,
    1723             :                                   SDVO_CMD_GET_ATTACHED_DISPLAYS,
    1724             :                                   &response, 2))
    1725           0 :                 return connector_status_unknown;
    1726             : 
    1727             :         DRM_DEBUG_KMS("SDVO response %d %d [%x]\n",
    1728             :                       response & 0xff, response >> 8,
    1729             :                       intel_sdvo_connector->output_flag);
    1730             : 
    1731           0 :         if (response == 0)
    1732           0 :                 return connector_status_disconnected;
    1733             : 
    1734           0 :         intel_sdvo->attached_output = response;
    1735             : 
    1736           0 :         intel_sdvo->has_hdmi_monitor = false;
    1737           0 :         intel_sdvo->has_hdmi_audio = false;
    1738           0 :         intel_sdvo->rgb_quant_range_selectable = false;
    1739             : 
    1740           0 :         if ((intel_sdvo_connector->output_flag & response) == 0)
    1741           0 :                 ret = connector_status_disconnected;
    1742           0 :         else if (IS_TMDS(intel_sdvo_connector))
    1743           0 :                 ret = intel_sdvo_tmds_sink_detect(connector);
    1744             :         else {
    1745             :                 struct edid *edid;
    1746             : 
    1747             :                 /* if we have an edid check it matches the connection */
    1748           0 :                 edid = intel_sdvo_get_edid(connector);
    1749           0 :                 if (edid == NULL)
    1750           0 :                         edid = intel_sdvo_get_analog_edid(connector);
    1751           0 :                 if (edid != NULL) {
    1752           0 :                         if (intel_sdvo_connector_matches_edid(intel_sdvo_connector,
    1753             :                                                               edid))
    1754           0 :                                 ret = connector_status_connected;
    1755             :                         else
    1756             :                                 ret = connector_status_disconnected;
    1757             : 
    1758           0 :                         kfree(edid);
    1759           0 :                 } else
    1760             :                         ret = connector_status_connected;
    1761             :         }
    1762             : 
    1763             :         /* May update encoder flag for like clock for SDVO TV, etc.*/
    1764           0 :         if (ret == connector_status_connected) {
    1765           0 :                 intel_sdvo->is_tv = false;
    1766           0 :                 intel_sdvo->is_lvds = false;
    1767             : 
    1768           0 :                 if (response & SDVO_TV_MASK)
    1769           0 :                         intel_sdvo->is_tv = true;
    1770           0 :                 if (response & SDVO_LVDS_MASK)
    1771           0 :                         intel_sdvo->is_lvds = intel_sdvo->sdvo_lvds_fixed_mode != NULL;
    1772             :         }
    1773             : 
    1774           0 :         return ret;
    1775           0 : }
    1776             : 
    1777           0 : static void intel_sdvo_get_ddc_modes(struct drm_connector *connector)
    1778             : {
    1779             :         struct edid *edid;
    1780             : 
    1781             :         DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
    1782             :                       connector->base.id, connector->name);
    1783             : 
    1784             :         /* set the bus switch and get the modes */
    1785           0 :         edid = intel_sdvo_get_edid(connector);
    1786             : 
    1787             :         /*
    1788             :          * Mac mini hack.  On this device, the DVI-I connector shares one DDC
    1789             :          * link between analog and digital outputs. So, if the regular SDVO
    1790             :          * DDC fails, check to see if the analog output is disconnected, in
    1791             :          * which case we'll look there for the digital DDC data.
    1792             :          */
    1793           0 :         if (edid == NULL)
    1794           0 :                 edid = intel_sdvo_get_analog_edid(connector);
    1795             : 
    1796           0 :         if (edid != NULL) {
    1797           0 :                 if (intel_sdvo_connector_matches_edid(to_intel_sdvo_connector(connector),
    1798             :                                                       edid)) {
    1799           0 :                         drm_mode_connector_update_edid_property(connector, edid);
    1800           0 :                         drm_add_edid_modes(connector, edid);
    1801           0 :                 }
    1802             : 
    1803           0 :                 kfree(edid);
    1804           0 :         }
    1805           0 : }
    1806             : 
    1807             : /*
    1808             :  * Set of SDVO TV modes.
    1809             :  * Note!  This is in reply order (see loop in get_tv_modes).
    1810             :  * XXX: all 60Hz refresh?
    1811             :  */
    1812             : static const struct drm_display_mode sdvo_tv_modes[] = {
    1813             :         { DRM_MODE("320x200", DRM_MODE_TYPE_DRIVER, 5815, 320, 321, 384,
    1814             :                    416, 0, 200, 201, 232, 233, 0,
    1815             :                    DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
    1816             :         { DRM_MODE("320x240", DRM_MODE_TYPE_DRIVER, 6814, 320, 321, 384,
    1817             :                    416, 0, 240, 241, 272, 273, 0,
    1818             :                    DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
    1819             :         { DRM_MODE("400x300", DRM_MODE_TYPE_DRIVER, 9910, 400, 401, 464,
    1820             :                    496, 0, 300, 301, 332, 333, 0,
    1821             :                    DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
    1822             :         { DRM_MODE("640x350", DRM_MODE_TYPE_DRIVER, 16913, 640, 641, 704,
    1823             :                    736, 0, 350, 351, 382, 383, 0,
    1824             :                    DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
    1825             :         { DRM_MODE("640x400", DRM_MODE_TYPE_DRIVER, 19121, 640, 641, 704,
    1826             :                    736, 0, 400, 401, 432, 433, 0,
    1827             :                    DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
    1828             :         { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 22654, 640, 641, 704,
    1829             :                    736, 0, 480, 481, 512, 513, 0,
    1830             :                    DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
    1831             :         { DRM_MODE("704x480", DRM_MODE_TYPE_DRIVER, 24624, 704, 705, 768,
    1832             :                    800, 0, 480, 481, 512, 513, 0,
    1833             :                    DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
    1834             :         { DRM_MODE("704x576", DRM_MODE_TYPE_DRIVER, 29232, 704, 705, 768,
    1835             :                    800, 0, 576, 577, 608, 609, 0,
    1836             :                    DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
    1837             :         { DRM_MODE("720x350", DRM_MODE_TYPE_DRIVER, 18751, 720, 721, 784,
    1838             :                    816, 0, 350, 351, 382, 383, 0,
    1839             :                    DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
    1840             :         { DRM_MODE("720x400", DRM_MODE_TYPE_DRIVER, 21199, 720, 721, 784,
    1841             :                    816, 0, 400, 401, 432, 433, 0,
    1842             :                    DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
    1843             :         { DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 25116, 720, 721, 784,
    1844             :                    816, 0, 480, 481, 512, 513, 0,
    1845             :                    DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
    1846             :         { DRM_MODE("720x540", DRM_MODE_TYPE_DRIVER, 28054, 720, 721, 784,
    1847             :                    816, 0, 540, 541, 572, 573, 0,
    1848             :                    DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
    1849             :         { DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 29816, 720, 721, 784,
    1850             :                    816, 0, 576, 577, 608, 609, 0,
    1851             :                    DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
    1852             :         { DRM_MODE("768x576", DRM_MODE_TYPE_DRIVER, 31570, 768, 769, 832,
    1853             :                    864, 0, 576, 577, 608, 609, 0,
    1854             :                    DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
    1855             :         { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 34030, 800, 801, 864,
    1856             :                    896, 0, 600, 601, 632, 633, 0,
    1857             :                    DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
    1858             :         { DRM_MODE("832x624", DRM_MODE_TYPE_DRIVER, 36581, 832, 833, 896,
    1859             :                    928, 0, 624, 625, 656, 657, 0,
    1860             :                    DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
    1861             :         { DRM_MODE("920x766", DRM_MODE_TYPE_DRIVER, 48707, 920, 921, 984,
    1862             :                    1016, 0, 766, 767, 798, 799, 0,
    1863             :                    DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
    1864             :         { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 53827, 1024, 1025, 1088,
    1865             :                    1120, 0, 768, 769, 800, 801, 0,
    1866             :                    DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
    1867             :         { DRM_MODE("1280x1024", DRM_MODE_TYPE_DRIVER, 87265, 1280, 1281, 1344,
    1868             :                    1376, 0, 1024, 1025, 1056, 1057, 0,
    1869             :                    DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
    1870             : };
    1871             : 
    1872           0 : static void intel_sdvo_get_tv_modes(struct drm_connector *connector)
    1873             : {
    1874           0 :         struct intel_sdvo *intel_sdvo = intel_attached_sdvo(connector);
    1875           0 :         struct intel_sdvo_sdtv_resolution_request tv_res;
    1876           0 :         uint32_t reply = 0, format_map = 0;
    1877             :         int i;
    1878             : 
    1879             :         DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
    1880             :                       connector->base.id, connector->name);
    1881             : 
    1882             :         /* Read the list of supported input resolutions for the selected TV
    1883             :          * format.
    1884             :          */
    1885           0 :         format_map = 1 << intel_sdvo->tv_format_index;
    1886           0 :         memcpy(&tv_res, &format_map,
    1887             :                min(sizeof(format_map), sizeof(struct intel_sdvo_sdtv_resolution_request)));
    1888             : 
    1889           0 :         if (!intel_sdvo_set_target_output(intel_sdvo, intel_sdvo->attached_output))
    1890           0 :                 return;
    1891             : 
    1892             :         BUILD_BUG_ON(sizeof(tv_res) != 3);
    1893           0 :         if (!intel_sdvo_write_cmd(intel_sdvo,
    1894             :                                   SDVO_CMD_GET_SDTV_RESOLUTION_SUPPORT,
    1895             :                                   &tv_res, sizeof(tv_res)))
    1896           0 :                 return;
    1897           0 :         if (!intel_sdvo_read_response(intel_sdvo, &reply, 3))
    1898           0 :                 return;
    1899             : 
    1900           0 :         for (i = 0; i < ARRAY_SIZE(sdvo_tv_modes); i++)
    1901           0 :                 if (reply & (1 << i)) {
    1902             :                         struct drm_display_mode *nmode;
    1903           0 :                         nmode = drm_mode_duplicate(connector->dev,
    1904           0 :                                                    &sdvo_tv_modes[i]);
    1905           0 :                         if (nmode)
    1906           0 :                                 drm_mode_probed_add(connector, nmode);
    1907           0 :                 }
    1908           0 : }
    1909             : 
    1910           0 : static void intel_sdvo_get_lvds_modes(struct drm_connector *connector)
    1911             : {
    1912           0 :         struct intel_sdvo *intel_sdvo = intel_attached_sdvo(connector);
    1913           0 :         struct drm_i915_private *dev_priv = connector->dev->dev_private;
    1914             :         struct drm_display_mode *newmode;
    1915             : 
    1916             :         DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
    1917             :                       connector->base.id, connector->name);
    1918             : 
    1919             :         /*
    1920             :          * Fetch modes from VBT. For SDVO prefer the VBT mode since some
    1921             :          * SDVO->LVDS transcoders can't cope with the EDID mode.
    1922             :          */
    1923           0 :         if (dev_priv->vbt.sdvo_lvds_vbt_mode != NULL) {
    1924           0 :                 newmode = drm_mode_duplicate(connector->dev,
    1925             :                                              dev_priv->vbt.sdvo_lvds_vbt_mode);
    1926           0 :                 if (newmode != NULL) {
    1927             :                         /* Guarantee the mode is preferred */
    1928           0 :                         newmode->type = (DRM_MODE_TYPE_PREFERRED |
    1929             :                                          DRM_MODE_TYPE_DRIVER);
    1930           0 :                         drm_mode_probed_add(connector, newmode);
    1931           0 :                 }
    1932             :         }
    1933             : 
    1934             :         /*
    1935             :          * Attempt to get the mode list from DDC.
    1936             :          * Assume that the preferred modes are
    1937             :          * arranged in priority order.
    1938             :          */
    1939           0 :         intel_ddc_get_modes(connector, &intel_sdvo->ddc);
    1940             : 
    1941           0 :         list_for_each_entry(newmode, &connector->probed_modes, head) {
    1942           0 :                 if (newmode->type & DRM_MODE_TYPE_PREFERRED) {
    1943           0 :                         intel_sdvo->sdvo_lvds_fixed_mode =
    1944           0 :                                 drm_mode_duplicate(connector->dev, newmode);
    1945             : 
    1946           0 :                         intel_sdvo->is_lvds = true;
    1947           0 :                         break;
    1948             :                 }
    1949             :         }
    1950           0 : }
    1951             : 
    1952           0 : static int intel_sdvo_get_modes(struct drm_connector *connector)
    1953             : {
    1954           0 :         struct intel_sdvo_connector *intel_sdvo_connector = to_intel_sdvo_connector(connector);
    1955             : 
    1956           0 :         if (IS_TV(intel_sdvo_connector))
    1957           0 :                 intel_sdvo_get_tv_modes(connector);
    1958           0 :         else if (IS_LVDS(intel_sdvo_connector))
    1959           0 :                 intel_sdvo_get_lvds_modes(connector);
    1960             :         else
    1961           0 :                 intel_sdvo_get_ddc_modes(connector);
    1962             : 
    1963           0 :         return !list_empty(&connector->probed_modes);
    1964             : }
    1965             : 
    1966           0 : static void intel_sdvo_destroy(struct drm_connector *connector)
    1967             : {
    1968           0 :         struct intel_sdvo_connector *intel_sdvo_connector = to_intel_sdvo_connector(connector);
    1969             : 
    1970           0 :         drm_connector_cleanup(connector);
    1971           0 :         kfree(intel_sdvo_connector);
    1972           0 : }
    1973             : 
    1974           0 : static bool intel_sdvo_detect_hdmi_audio(struct drm_connector *connector)
    1975             : {
    1976           0 :         struct intel_sdvo *intel_sdvo = intel_attached_sdvo(connector);
    1977             :         struct edid *edid;
    1978             :         bool has_audio = false;
    1979             : 
    1980           0 :         if (!intel_sdvo->is_hdmi)
    1981           0 :                 return false;
    1982             : 
    1983           0 :         edid = intel_sdvo_get_edid(connector);
    1984           0 :         if (edid != NULL && edid->input & DRM_EDID_INPUT_DIGITAL)
    1985           0 :                 has_audio = drm_detect_monitor_audio(edid);
    1986           0 :         kfree(edid);
    1987             : 
    1988           0 :         return has_audio;
    1989           0 : }
    1990             : 
    1991             : static int
    1992           0 : intel_sdvo_set_property(struct drm_connector *connector,
    1993             :                         struct drm_property *property,
    1994             :                         uint64_t val)
    1995             : {
    1996           0 :         struct intel_sdvo *intel_sdvo = intel_attached_sdvo(connector);
    1997           0 :         struct intel_sdvo_connector *intel_sdvo_connector = to_intel_sdvo_connector(connector);
    1998           0 :         struct drm_i915_private *dev_priv = connector->dev->dev_private;
    1999           0 :         uint16_t temp_value;
    2000             :         uint8_t cmd;
    2001             :         int ret;
    2002             : 
    2003           0 :         ret = drm_object_property_set_value(&connector->base, property, val);
    2004           0 :         if (ret)
    2005           0 :                 return ret;
    2006             : 
    2007           0 :         if (property == dev_priv->force_audio_property) {
    2008           0 :                 int i = val;
    2009             :                 bool has_audio;
    2010             : 
    2011           0 :                 if (i == intel_sdvo_connector->force_audio)
    2012           0 :                         return 0;
    2013             : 
    2014           0 :                 intel_sdvo_connector->force_audio = i;
    2015             : 
    2016           0 :                 if (i == HDMI_AUDIO_AUTO)
    2017           0 :                         has_audio = intel_sdvo_detect_hdmi_audio(connector);
    2018             :                 else
    2019           0 :                         has_audio = (i == HDMI_AUDIO_ON);
    2020             : 
    2021           0 :                 if (has_audio == intel_sdvo->has_hdmi_audio)
    2022           0 :                         return 0;
    2023             : 
    2024           0 :                 intel_sdvo->has_hdmi_audio = has_audio;
    2025           0 :                 goto done;
    2026             :         }
    2027             : 
    2028           0 :         if (property == dev_priv->broadcast_rgb_property) {
    2029           0 :                 bool old_auto = intel_sdvo->color_range_auto;
    2030           0 :                 uint32_t old_range = intel_sdvo->color_range;
    2031             : 
    2032           0 :                 switch (val) {
    2033             :                 case INTEL_BROADCAST_RGB_AUTO:
    2034           0 :                         intel_sdvo->color_range_auto = true;
    2035           0 :                         break;
    2036             :                 case INTEL_BROADCAST_RGB_FULL:
    2037           0 :                         intel_sdvo->color_range_auto = false;
    2038           0 :                         intel_sdvo->color_range = 0;
    2039           0 :                         break;
    2040             :                 case INTEL_BROADCAST_RGB_LIMITED:
    2041           0 :                         intel_sdvo->color_range_auto = false;
    2042             :                         /* FIXME: this bit is only valid when using TMDS
    2043             :                          * encoding and 8 bit per color mode. */
    2044           0 :                         intel_sdvo->color_range = HDMI_COLOR_RANGE_16_235;
    2045           0 :                         break;
    2046             :                 default:
    2047           0 :                         return -EINVAL;
    2048             :                 }
    2049             : 
    2050           0 :                 if (old_auto == intel_sdvo->color_range_auto &&
    2051           0 :                     old_range == intel_sdvo->color_range)
    2052           0 :                         return 0;
    2053             : 
    2054           0 :                 goto done;
    2055             :         }
    2056             : 
    2057           0 :         if (property == connector->dev->mode_config.aspect_ratio_property) {
    2058           0 :                 switch (val) {
    2059             :                 case DRM_MODE_PICTURE_ASPECT_NONE:
    2060           0 :                         intel_sdvo->aspect_ratio = HDMI_PICTURE_ASPECT_NONE;
    2061           0 :                         break;
    2062             :                 case DRM_MODE_PICTURE_ASPECT_4_3:
    2063           0 :                         intel_sdvo->aspect_ratio = HDMI_PICTURE_ASPECT_4_3;
    2064           0 :                         break;
    2065             :                 case DRM_MODE_PICTURE_ASPECT_16_9:
    2066           0 :                         intel_sdvo->aspect_ratio = HDMI_PICTURE_ASPECT_16_9;
    2067           0 :                         break;
    2068             :                 default:
    2069           0 :                         return -EINVAL;
    2070             :                 }
    2071             :                 goto done;
    2072             :         }
    2073             : 
    2074             : #define CHECK_PROPERTY(name, NAME) \
    2075             :         if (intel_sdvo_connector->name == property) { \
    2076             :                 if (intel_sdvo_connector->cur_##name == temp_value) return 0; \
    2077             :                 if (intel_sdvo_connector->max_##name < temp_value) return -EINVAL; \
    2078             :                 cmd = SDVO_CMD_SET_##NAME; \
    2079             :                 intel_sdvo_connector->cur_##name = temp_value; \
    2080             :                 goto set_value; \
    2081             :         }
    2082             : 
    2083           0 :         if (property == intel_sdvo_connector->tv_format) {
    2084           0 :                 if (val >= TV_FORMAT_NUM)
    2085           0 :                         return -EINVAL;
    2086             : 
    2087           0 :                 if (intel_sdvo->tv_format_index ==
    2088           0 :                     intel_sdvo_connector->tv_format_supported[val])
    2089           0 :                         return 0;
    2090             : 
    2091           0 :                 intel_sdvo->tv_format_index = intel_sdvo_connector->tv_format_supported[val];
    2092           0 :                 goto done;
    2093           0 :         } else if (IS_TV_OR_LVDS(intel_sdvo_connector)) {
    2094           0 :                 temp_value = val;
    2095           0 :                 if (intel_sdvo_connector->left == property) {
    2096           0 :                         drm_object_property_set_value(&connector->base,
    2097           0 :                                                          intel_sdvo_connector->right, val);
    2098           0 :                         if (intel_sdvo_connector->left_margin == temp_value)
    2099           0 :                                 return 0;
    2100             : 
    2101           0 :                         intel_sdvo_connector->left_margin = temp_value;
    2102           0 :                         intel_sdvo_connector->right_margin = temp_value;
    2103           0 :                         temp_value = intel_sdvo_connector->max_hscan -
    2104           0 :                                 intel_sdvo_connector->left_margin;
    2105             :                         cmd = SDVO_CMD_SET_OVERSCAN_H;
    2106           0 :                         goto set_value;
    2107           0 :                 } else if (intel_sdvo_connector->right == property) {
    2108           0 :                         drm_object_property_set_value(&connector->base,
    2109             :                                                          intel_sdvo_connector->left, val);
    2110           0 :                         if (intel_sdvo_connector->right_margin == temp_value)
    2111           0 :                                 return 0;
    2112             : 
    2113           0 :                         intel_sdvo_connector->left_margin = temp_value;
    2114           0 :                         intel_sdvo_connector->right_margin = temp_value;
    2115           0 :                         temp_value = intel_sdvo_connector->max_hscan -
    2116           0 :                                 intel_sdvo_connector->left_margin;
    2117             :                         cmd = SDVO_CMD_SET_OVERSCAN_H;
    2118           0 :                         goto set_value;
    2119           0 :                 } else if (intel_sdvo_connector->top == property) {
    2120           0 :                         drm_object_property_set_value(&connector->base,
    2121           0 :                                                          intel_sdvo_connector->bottom, val);
    2122           0 :                         if (intel_sdvo_connector->top_margin == temp_value)
    2123           0 :                                 return 0;
    2124             : 
    2125           0 :                         intel_sdvo_connector->top_margin = temp_value;
    2126           0 :                         intel_sdvo_connector->bottom_margin = temp_value;
    2127           0 :                         temp_value = intel_sdvo_connector->max_vscan -
    2128           0 :                                 intel_sdvo_connector->top_margin;
    2129             :                         cmd = SDVO_CMD_SET_OVERSCAN_V;
    2130           0 :                         goto set_value;
    2131           0 :                 } else if (intel_sdvo_connector->bottom == property) {
    2132           0 :                         drm_object_property_set_value(&connector->base,
    2133             :                                                          intel_sdvo_connector->top, val);
    2134           0 :                         if (intel_sdvo_connector->bottom_margin == temp_value)
    2135           0 :                                 return 0;
    2136             : 
    2137           0 :                         intel_sdvo_connector->top_margin = temp_value;
    2138           0 :                         intel_sdvo_connector->bottom_margin = temp_value;
    2139           0 :                         temp_value = intel_sdvo_connector->max_vscan -
    2140           0 :                                 intel_sdvo_connector->top_margin;
    2141             :                         cmd = SDVO_CMD_SET_OVERSCAN_V;
    2142           0 :                         goto set_value;
    2143             :                 }
    2144           0 :                 CHECK_PROPERTY(hpos, HPOS)
    2145           0 :                 CHECK_PROPERTY(vpos, VPOS)
    2146           0 :                 CHECK_PROPERTY(saturation, SATURATION)
    2147           0 :                 CHECK_PROPERTY(contrast, CONTRAST)
    2148           0 :                 CHECK_PROPERTY(hue, HUE)
    2149           0 :                 CHECK_PROPERTY(brightness, BRIGHTNESS)
    2150           0 :                 CHECK_PROPERTY(sharpness, SHARPNESS)
    2151           0 :                 CHECK_PROPERTY(flicker_filter, FLICKER_FILTER)
    2152           0 :                 CHECK_PROPERTY(flicker_filter_2d, FLICKER_FILTER_2D)
    2153           0 :                 CHECK_PROPERTY(flicker_filter_adaptive, FLICKER_FILTER_ADAPTIVE)
    2154           0 :                 CHECK_PROPERTY(tv_chroma_filter, TV_CHROMA_FILTER)
    2155           0 :                 CHECK_PROPERTY(tv_luma_filter, TV_LUMA_FILTER)
    2156           0 :                 CHECK_PROPERTY(dot_crawl, DOT_CRAWL)
    2157             :         }
    2158             : 
    2159           0 :         return -EINVAL; /* unknown property */
    2160             : 
    2161             : set_value:
    2162           0 :         if (!intel_sdvo_set_value(intel_sdvo, cmd, &temp_value, 2))
    2163           0 :                 return -EIO;
    2164             : 
    2165             : 
    2166             : done:
    2167           0 :         if (intel_sdvo->base.base.crtc)
    2168           0 :                 intel_crtc_restore_mode(intel_sdvo->base.base.crtc);
    2169             : 
    2170           0 :         return 0;
    2171             : #undef CHECK_PROPERTY
    2172           0 : }
    2173             : 
    2174             : static const struct drm_connector_funcs intel_sdvo_connector_funcs = {
    2175             :         .dpms = drm_atomic_helper_connector_dpms,
    2176             :         .detect = intel_sdvo_detect,
    2177             :         .fill_modes = drm_helper_probe_single_connector_modes,
    2178             :         .set_property = intel_sdvo_set_property,
    2179             :         .atomic_get_property = intel_connector_atomic_get_property,
    2180             :         .destroy = intel_sdvo_destroy,
    2181             :         .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
    2182             :         .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
    2183             : };
    2184             : 
    2185             : static const struct drm_connector_helper_funcs intel_sdvo_connector_helper_funcs = {
    2186             :         .get_modes = intel_sdvo_get_modes,
    2187             :         .mode_valid = intel_sdvo_mode_valid,
    2188             :         .best_encoder = intel_best_encoder,
    2189             : };
    2190             : 
    2191           0 : static void intel_sdvo_enc_destroy(struct drm_encoder *encoder)
    2192             : {
    2193           0 :         struct intel_sdvo *intel_sdvo = to_sdvo(to_intel_encoder(encoder));
    2194             : 
    2195           0 :         if (intel_sdvo->sdvo_lvds_fixed_mode != NULL)
    2196           0 :                 drm_mode_destroy(encoder->dev,
    2197             :                                  intel_sdvo->sdvo_lvds_fixed_mode);
    2198             : 
    2199             :         i2c_del_adapter(&intel_sdvo->ddc);
    2200           0 :         intel_encoder_destroy(encoder);
    2201           0 : }
    2202             : 
    2203             : static const struct drm_encoder_funcs intel_sdvo_enc_funcs = {
    2204             :         .destroy = intel_sdvo_enc_destroy,
    2205             : };
    2206             : 
    2207             : static void
    2208           0 : intel_sdvo_guess_ddc_bus(struct intel_sdvo *sdvo)
    2209             : {
    2210             :         uint16_t mask = 0;
    2211             :         unsigned int num_bits;
    2212             : 
    2213             :         /* Make a mask of outputs less than or equal to our own priority in the
    2214             :          * list.
    2215             :          */
    2216           0 :         switch (sdvo->controlled_output) {
    2217             :         case SDVO_OUTPUT_LVDS1:
    2218           0 :                 mask |= SDVO_OUTPUT_LVDS1;
    2219             :         case SDVO_OUTPUT_LVDS0:
    2220           0 :                 mask |= SDVO_OUTPUT_LVDS0;
    2221             :         case SDVO_OUTPUT_TMDS1:
    2222           0 :                 mask |= SDVO_OUTPUT_TMDS1;
    2223             :         case SDVO_OUTPUT_TMDS0:
    2224           0 :                 mask |= SDVO_OUTPUT_TMDS0;
    2225             :         case SDVO_OUTPUT_RGB1:
    2226           0 :                 mask |= SDVO_OUTPUT_RGB1;
    2227             :         case SDVO_OUTPUT_RGB0:
    2228           0 :                 mask |= SDVO_OUTPUT_RGB0;
    2229           0 :                 break;
    2230             :         }
    2231             : 
    2232             :         /* Count bits to find what number we are in the priority list. */
    2233           0 :         mask &= sdvo->caps.output_flags;
    2234           0 :         num_bits = hweight16(mask);
    2235             :         /* If more than 3 outputs, default to DDC bus 3 for now. */
    2236           0 :         if (num_bits > 3)
    2237             :                 num_bits = 3;
    2238             : 
    2239             :         /* Corresponds to SDVO_CONTROL_BUS_DDCx */
    2240           0 :         sdvo->ddc_bus = 1 << num_bits;
    2241           0 : }
    2242             : 
    2243             : /**
    2244             :  * Choose the appropriate DDC bus for control bus switch command for this
    2245             :  * SDVO output based on the controlled output.
    2246             :  *
    2247             :  * DDC bus number assignment is in a priority order of RGB outputs, then TMDS
    2248             :  * outputs, then LVDS outputs.
    2249             :  */
    2250             : static void
    2251           0 : intel_sdvo_select_ddc_bus(struct drm_i915_private *dev_priv,
    2252             :                           struct intel_sdvo *sdvo)
    2253             : {
    2254             :         struct sdvo_device_mapping *mapping;
    2255             : 
    2256           0 :         if (sdvo->is_sdvob)
    2257           0 :                 mapping = &(dev_priv->sdvo_mappings[0]);
    2258             :         else
    2259           0 :                 mapping = &(dev_priv->sdvo_mappings[1]);
    2260             : 
    2261           0 :         if (mapping->initialized)
    2262           0 :                 sdvo->ddc_bus = 1 << ((mapping->ddc_pin & 0xf0) >> 4);
    2263             :         else
    2264           0 :                 intel_sdvo_guess_ddc_bus(sdvo);
    2265           0 : }
    2266             : 
    2267             : static void
    2268           0 : intel_sdvo_select_i2c_bus(struct drm_i915_private *dev_priv,
    2269             :                           struct intel_sdvo *sdvo)
    2270             : {
    2271             :         struct sdvo_device_mapping *mapping;
    2272             :         u8 pin;
    2273             : 
    2274           0 :         if (sdvo->is_sdvob)
    2275           0 :                 mapping = &dev_priv->sdvo_mappings[0];
    2276             :         else
    2277           0 :                 mapping = &dev_priv->sdvo_mappings[1];
    2278             : 
    2279           0 :         if (mapping->initialized &&
    2280           0 :             intel_gmbus_is_valid_pin(dev_priv, mapping->i2c_pin))
    2281           0 :                 pin = mapping->i2c_pin;
    2282             :         else
    2283             :                 pin = GMBUS_PIN_DPB;
    2284             : 
    2285           0 :         sdvo->i2c = intel_gmbus_get_adapter(dev_priv, pin);
    2286             : 
    2287             :         /* With gmbus we should be able to drive sdvo i2c at 2MHz, but somehow
    2288             :          * our code totally fails once we start using gmbus. Hence fall back to
    2289             :          * bit banging for now. */
    2290           0 :         intel_gmbus_force_bit(sdvo->i2c, true);
    2291           0 : }
    2292             : 
    2293             : /* undo any changes intel_sdvo_select_i2c_bus() did to sdvo->i2c */
    2294             : static void
    2295           0 : intel_sdvo_unselect_i2c_bus(struct intel_sdvo *sdvo)
    2296             : {
    2297           0 :         intel_gmbus_force_bit(sdvo->i2c, false);
    2298           0 : }
    2299             : 
    2300             : static bool
    2301           0 : intel_sdvo_is_hdmi_connector(struct intel_sdvo *intel_sdvo, int device)
    2302             : {
    2303           0 :         return intel_sdvo_check_supp_encode(intel_sdvo);
    2304             : }
    2305             : 
    2306             : static u8
    2307           0 : intel_sdvo_get_slave_addr(struct drm_device *dev, struct intel_sdvo *sdvo)
    2308             : {
    2309           0 :         struct drm_i915_private *dev_priv = dev->dev_private;
    2310             :         struct sdvo_device_mapping *my_mapping, *other_mapping;
    2311             : 
    2312           0 :         if (sdvo->is_sdvob) {
    2313           0 :                 my_mapping = &dev_priv->sdvo_mappings[0];
    2314           0 :                 other_mapping = &dev_priv->sdvo_mappings[1];
    2315           0 :         } else {
    2316           0 :                 my_mapping = &dev_priv->sdvo_mappings[1];
    2317           0 :                 other_mapping = &dev_priv->sdvo_mappings[0];
    2318             :         }
    2319             : 
    2320             :         /* If the BIOS described our SDVO device, take advantage of it. */
    2321           0 :         if (my_mapping->slave_addr)
    2322           0 :                 return my_mapping->slave_addr;
    2323             : 
    2324             :         /* If the BIOS only described a different SDVO device, use the
    2325             :          * address that it isn't using.
    2326             :          */
    2327           0 :         if (other_mapping->slave_addr) {
    2328           0 :                 if (other_mapping->slave_addr == 0x70)
    2329           0 :                         return 0x72;
    2330             :                 else
    2331           0 :                         return 0x70;
    2332             :         }
    2333             : 
    2334             :         /* No SDVO device info is found for another DVO port,
    2335             :          * so use mapping assumption we had before BIOS parsing.
    2336             :          */
    2337           0 :         if (sdvo->is_sdvob)
    2338           0 :                 return 0x70;
    2339             :         else
    2340           0 :                 return 0x72;
    2341           0 : }
    2342             : 
    2343             : static void
    2344           0 : intel_sdvo_connector_unregister(struct intel_connector *intel_connector)
    2345             : {
    2346             : #ifdef __linux__
    2347             :         struct drm_connector *drm_connector;
    2348             :         struct intel_sdvo *sdvo_encoder;
    2349             : 
    2350             :         drm_connector = &intel_connector->base;
    2351             :         sdvo_encoder = intel_attached_sdvo(&intel_connector->base);
    2352             : 
    2353             :         sysfs_remove_link(&drm_connector->kdev->kobj,
    2354             :                           sdvo_encoder->ddc.dev.kobj.name);
    2355             : #endif
    2356           0 :         intel_connector_unregister(intel_connector);
    2357           0 : }
    2358             : 
    2359             : static int
    2360           0 : intel_sdvo_connector_init(struct intel_sdvo_connector *connector,
    2361             :                           struct intel_sdvo *encoder)
    2362             : {
    2363             :         struct drm_connector *drm_connector;
    2364             :         int ret;
    2365             : 
    2366           0 :         drm_connector = &connector->base.base;
    2367           0 :         ret = drm_connector_init(encoder->base.base.dev,
    2368             :                            drm_connector,
    2369             :                            &intel_sdvo_connector_funcs,
    2370           0 :                            connector->base.base.connector_type);
    2371           0 :         if (ret < 0)
    2372           0 :                 return ret;
    2373             : 
    2374           0 :         drm_connector_helper_add(drm_connector,
    2375             :                                  &intel_sdvo_connector_helper_funcs);
    2376             : 
    2377           0 :         connector->base.base.interlace_allowed = 1;
    2378           0 :         connector->base.base.doublescan_allowed = 0;
    2379           0 :         connector->base.base.display_info.subpixel_order = SubPixelHorizontalRGB;
    2380           0 :         connector->base.get_hw_state = intel_sdvo_connector_get_hw_state;
    2381           0 :         connector->base.unregister = intel_sdvo_connector_unregister;
    2382             : 
    2383           0 :         intel_connector_attach_encoder(&connector->base, &encoder->base);
    2384           0 :         ret = drm_connector_register(drm_connector);
    2385             :         if (ret < 0)
    2386             :                 goto err1;
    2387             : 
    2388             : #ifdef __linux__
    2389             :         ret = sysfs_create_link(&drm_connector->kdev->kobj,
    2390             :                                 &encoder->ddc.dev.kobj,
    2391             :                                 encoder->ddc.dev.kobj.name);
    2392             :         if (ret < 0)
    2393             :                 goto err2;
    2394             : 
    2395             :         return 0;
    2396             : 
    2397             : err2:
    2398             :         drm_connector_unregister(drm_connector);
    2399             : #endif
    2400             : err1:
    2401           0 :         drm_connector_cleanup(drm_connector);
    2402             : 
    2403           0 :         return ret;
    2404           0 : }
    2405             : 
    2406             : static void
    2407           0 : intel_sdvo_add_hdmi_properties(struct intel_sdvo *intel_sdvo,
    2408             :                                struct intel_sdvo_connector *connector)
    2409             : {
    2410           0 :         struct drm_device *dev = connector->base.base.dev;
    2411             : 
    2412           0 :         intel_attach_force_audio_property(&connector->base.base);
    2413           0 :         if (INTEL_INFO(dev)->gen >= 4 && IS_MOBILE(dev)) {
    2414           0 :                 intel_attach_broadcast_rgb_property(&connector->base.base);
    2415           0 :                 intel_sdvo->color_range_auto = true;
    2416           0 :         }
    2417           0 :         intel_attach_aspect_ratio_property(&connector->base.base);
    2418           0 :         intel_sdvo->aspect_ratio = HDMI_PICTURE_ASPECT_NONE;
    2419           0 : }
    2420             : 
    2421           0 : static struct intel_sdvo_connector *intel_sdvo_connector_alloc(void)
    2422             : {
    2423             :         struct intel_sdvo_connector *sdvo_connector;
    2424             : 
    2425           0 :         sdvo_connector = kzalloc(sizeof(*sdvo_connector), GFP_KERNEL);
    2426           0 :         if (!sdvo_connector)
    2427           0 :                 return NULL;
    2428             : 
    2429           0 :         if (intel_connector_init(&sdvo_connector->base) < 0) {
    2430           0 :                 kfree(sdvo_connector);
    2431           0 :                 return NULL;
    2432             :         }
    2433             : 
    2434           0 :         return sdvo_connector;
    2435           0 : }
    2436             : 
    2437             : static bool
    2438           0 : intel_sdvo_dvi_init(struct intel_sdvo *intel_sdvo, int device)
    2439             : {
    2440           0 :         struct drm_encoder *encoder = &intel_sdvo->base.base;
    2441             :         struct drm_connector *connector;
    2442           0 :         struct intel_encoder *intel_encoder = to_intel_encoder(encoder);
    2443             :         struct intel_connector *intel_connector;
    2444             :         struct intel_sdvo_connector *intel_sdvo_connector;
    2445             : 
    2446             :         DRM_DEBUG_KMS("initialising DVI device %d\n", device);
    2447             : 
    2448           0 :         intel_sdvo_connector = intel_sdvo_connector_alloc();
    2449           0 :         if (!intel_sdvo_connector)
    2450           0 :                 return false;
    2451             : 
    2452           0 :         if (device == 0) {
    2453           0 :                 intel_sdvo->controlled_output |= SDVO_OUTPUT_TMDS0;
    2454           0 :                 intel_sdvo_connector->output_flag = SDVO_OUTPUT_TMDS0;
    2455           0 :         } else if (device == 1) {
    2456           0 :                 intel_sdvo->controlled_output |= SDVO_OUTPUT_TMDS1;
    2457           0 :                 intel_sdvo_connector->output_flag = SDVO_OUTPUT_TMDS1;
    2458           0 :         }
    2459             : 
    2460           0 :         intel_connector = &intel_sdvo_connector->base;
    2461           0 :         connector = &intel_connector->base;
    2462           0 :         if (intel_sdvo_get_hotplug_support(intel_sdvo) &
    2463           0 :                 intel_sdvo_connector->output_flag) {
    2464           0 :                 intel_sdvo->hotplug_active |= intel_sdvo_connector->output_flag;
    2465             :                 /* Some SDVO devices have one-shot hotplug interrupts.
    2466             :                  * Ensure that they get re-enabled when an interrupt happens.
    2467             :                  */
    2468           0 :                 intel_encoder->hot_plug = intel_sdvo_enable_hotplug;
    2469           0 :                 intel_sdvo_enable_hotplug(intel_encoder);
    2470           0 :         } else {
    2471           0 :                 intel_connector->polled = DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT;
    2472             :         }
    2473           0 :         encoder->encoder_type = DRM_MODE_ENCODER_TMDS;
    2474           0 :         connector->connector_type = DRM_MODE_CONNECTOR_DVID;
    2475             : 
    2476           0 :         if (intel_sdvo_is_hdmi_connector(intel_sdvo, device)) {
    2477           0 :                 connector->connector_type = DRM_MODE_CONNECTOR_HDMIA;
    2478           0 :                 intel_sdvo->is_hdmi = true;
    2479           0 :         }
    2480             : 
    2481           0 :         if (intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo) < 0) {
    2482           0 :                 kfree(intel_sdvo_connector);
    2483           0 :                 return false;
    2484             :         }
    2485             : 
    2486           0 :         if (intel_sdvo->is_hdmi)
    2487           0 :                 intel_sdvo_add_hdmi_properties(intel_sdvo, intel_sdvo_connector);
    2488             : 
    2489           0 :         return true;
    2490           0 : }
    2491             : 
    2492             : static bool
    2493           0 : intel_sdvo_tv_init(struct intel_sdvo *intel_sdvo, int type)
    2494             : {
    2495           0 :         struct drm_encoder *encoder = &intel_sdvo->base.base;
    2496             :         struct drm_connector *connector;
    2497             :         struct intel_connector *intel_connector;
    2498             :         struct intel_sdvo_connector *intel_sdvo_connector;
    2499             : 
    2500             :         DRM_DEBUG_KMS("initialising TV type %d\n", type);
    2501             : 
    2502           0 :         intel_sdvo_connector = intel_sdvo_connector_alloc();
    2503           0 :         if (!intel_sdvo_connector)
    2504           0 :                 return false;
    2505             : 
    2506           0 :         intel_connector = &intel_sdvo_connector->base;
    2507           0 :         connector = &intel_connector->base;
    2508           0 :         encoder->encoder_type = DRM_MODE_ENCODER_TVDAC;
    2509           0 :         connector->connector_type = DRM_MODE_CONNECTOR_SVIDEO;
    2510             : 
    2511           0 :         intel_sdvo->controlled_output |= type;
    2512           0 :         intel_sdvo_connector->output_flag = type;
    2513             : 
    2514           0 :         intel_sdvo->is_tv = true;
    2515             : 
    2516           0 :         if (intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo) < 0) {
    2517           0 :                 kfree(intel_sdvo_connector);
    2518           0 :                 return false;
    2519             :         }
    2520             : 
    2521           0 :         if (!intel_sdvo_tv_create_property(intel_sdvo, intel_sdvo_connector, type))
    2522             :                 goto err;
    2523             : 
    2524           0 :         if (!intel_sdvo_create_enhance_property(intel_sdvo, intel_sdvo_connector))
    2525             :                 goto err;
    2526             : 
    2527           0 :         return true;
    2528             : 
    2529             : err:
    2530           0 :         drm_connector_unregister(connector);
    2531           0 :         intel_sdvo_destroy(connector);
    2532           0 :         return false;
    2533           0 : }
    2534             : 
    2535             : static bool
    2536           0 : intel_sdvo_analog_init(struct intel_sdvo *intel_sdvo, int device)
    2537             : {
    2538           0 :         struct drm_encoder *encoder = &intel_sdvo->base.base;
    2539             :         struct drm_connector *connector;
    2540             :         struct intel_connector *intel_connector;
    2541             :         struct intel_sdvo_connector *intel_sdvo_connector;
    2542             : 
    2543             :         DRM_DEBUG_KMS("initialising analog device %d\n", device);
    2544             : 
    2545           0 :         intel_sdvo_connector = intel_sdvo_connector_alloc();
    2546           0 :         if (!intel_sdvo_connector)
    2547           0 :                 return false;
    2548             : 
    2549           0 :         intel_connector = &intel_sdvo_connector->base;
    2550           0 :         connector = &intel_connector->base;
    2551           0 :         intel_connector->polled = DRM_CONNECTOR_POLL_CONNECT;
    2552           0 :         encoder->encoder_type = DRM_MODE_ENCODER_DAC;
    2553           0 :         connector->connector_type = DRM_MODE_CONNECTOR_VGA;
    2554             : 
    2555           0 :         if (device == 0) {
    2556           0 :                 intel_sdvo->controlled_output |= SDVO_OUTPUT_RGB0;
    2557           0 :                 intel_sdvo_connector->output_flag = SDVO_OUTPUT_RGB0;
    2558           0 :         } else if (device == 1) {
    2559           0 :                 intel_sdvo->controlled_output |= SDVO_OUTPUT_RGB1;
    2560           0 :                 intel_sdvo_connector->output_flag = SDVO_OUTPUT_RGB1;
    2561           0 :         }
    2562             : 
    2563           0 :         if (intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo) < 0) {
    2564           0 :                 kfree(intel_sdvo_connector);
    2565           0 :                 return false;
    2566             :         }
    2567             : 
    2568           0 :         return true;
    2569           0 : }
    2570             : 
    2571             : static bool
    2572           0 : intel_sdvo_lvds_init(struct intel_sdvo *intel_sdvo, int device)
    2573             : {
    2574           0 :         struct drm_encoder *encoder = &intel_sdvo->base.base;
    2575             :         struct drm_connector *connector;
    2576             :         struct intel_connector *intel_connector;
    2577             :         struct intel_sdvo_connector *intel_sdvo_connector;
    2578             : 
    2579             :         DRM_DEBUG_KMS("initialising LVDS device %d\n", device);
    2580             : 
    2581           0 :         intel_sdvo_connector = intel_sdvo_connector_alloc();
    2582           0 :         if (!intel_sdvo_connector)
    2583           0 :                 return false;
    2584             : 
    2585           0 :         intel_connector = &intel_sdvo_connector->base;
    2586           0 :         connector = &intel_connector->base;
    2587           0 :         encoder->encoder_type = DRM_MODE_ENCODER_LVDS;
    2588           0 :         connector->connector_type = DRM_MODE_CONNECTOR_LVDS;
    2589             : 
    2590           0 :         if (device == 0) {
    2591           0 :                 intel_sdvo->controlled_output |= SDVO_OUTPUT_LVDS0;
    2592           0 :                 intel_sdvo_connector->output_flag = SDVO_OUTPUT_LVDS0;
    2593           0 :         } else if (device == 1) {
    2594           0 :                 intel_sdvo->controlled_output |= SDVO_OUTPUT_LVDS1;
    2595           0 :                 intel_sdvo_connector->output_flag = SDVO_OUTPUT_LVDS1;
    2596           0 :         }
    2597             : 
    2598           0 :         if (intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo) < 0) {
    2599           0 :                 kfree(intel_sdvo_connector);
    2600           0 :                 return false;
    2601             :         }
    2602             : 
    2603           0 :         if (!intel_sdvo_create_enhance_property(intel_sdvo, intel_sdvo_connector))
    2604             :                 goto err;
    2605             : 
    2606           0 :         return true;
    2607             : 
    2608             : err:
    2609           0 :         drm_connector_unregister(connector);
    2610           0 :         intel_sdvo_destroy(connector);
    2611           0 :         return false;
    2612           0 : }
    2613             : 
    2614             : static bool
    2615           0 : intel_sdvo_output_setup(struct intel_sdvo *intel_sdvo, uint16_t flags)
    2616             : {
    2617           0 :         intel_sdvo->is_tv = false;
    2618           0 :         intel_sdvo->is_lvds = false;
    2619             : 
    2620             :         /* SDVO requires XXX1 function may not exist unless it has XXX0 function.*/
    2621             : 
    2622           0 :         if (flags & SDVO_OUTPUT_TMDS0)
    2623           0 :                 if (!intel_sdvo_dvi_init(intel_sdvo, 0))
    2624           0 :                         return false;
    2625             : 
    2626           0 :         if ((flags & SDVO_TMDS_MASK) == SDVO_TMDS_MASK)
    2627           0 :                 if (!intel_sdvo_dvi_init(intel_sdvo, 1))
    2628           0 :                         return false;
    2629             : 
    2630             :         /* TV has no XXX1 function block */
    2631           0 :         if (flags & SDVO_OUTPUT_SVID0)
    2632           0 :                 if (!intel_sdvo_tv_init(intel_sdvo, SDVO_OUTPUT_SVID0))
    2633           0 :                         return false;
    2634             : 
    2635           0 :         if (flags & SDVO_OUTPUT_CVBS0)
    2636           0 :                 if (!intel_sdvo_tv_init(intel_sdvo, SDVO_OUTPUT_CVBS0))
    2637           0 :                         return false;
    2638             : 
    2639           0 :         if (flags & SDVO_OUTPUT_YPRPB0)
    2640           0 :                 if (!intel_sdvo_tv_init(intel_sdvo, SDVO_OUTPUT_YPRPB0))
    2641           0 :                         return false;
    2642             : 
    2643           0 :         if (flags & SDVO_OUTPUT_RGB0)
    2644           0 :                 if (!intel_sdvo_analog_init(intel_sdvo, 0))
    2645           0 :                         return false;
    2646             : 
    2647           0 :         if ((flags & SDVO_RGB_MASK) == SDVO_RGB_MASK)
    2648           0 :                 if (!intel_sdvo_analog_init(intel_sdvo, 1))
    2649           0 :                         return false;
    2650             : 
    2651           0 :         if (flags & SDVO_OUTPUT_LVDS0)
    2652           0 :                 if (!intel_sdvo_lvds_init(intel_sdvo, 0))
    2653           0 :                         return false;
    2654             : 
    2655           0 :         if ((flags & SDVO_LVDS_MASK) == SDVO_LVDS_MASK)
    2656           0 :                 if (!intel_sdvo_lvds_init(intel_sdvo, 1))
    2657           0 :                         return false;
    2658             : 
    2659           0 :         if ((flags & SDVO_OUTPUT_MASK) == 0) {
    2660             :                 unsigned char bytes[2];
    2661             : 
    2662           0 :                 intel_sdvo->controlled_output = 0;
    2663           0 :                 memcpy(bytes, &intel_sdvo->caps.output_flags, 2);
    2664             :                 DRM_DEBUG_KMS("%s: Unknown SDVO output type (0x%02x%02x)\n",
    2665             :                               SDVO_NAME(intel_sdvo),
    2666             :                               bytes[0], bytes[1]);
    2667             :                 return false;
    2668             :         }
    2669           0 :         intel_sdvo->base.crtc_mask = (1 << 0) | (1 << 1) | (1 << 2);
    2670             : 
    2671           0 :         return true;
    2672           0 : }
    2673             : 
    2674           0 : static void intel_sdvo_output_cleanup(struct intel_sdvo *intel_sdvo)
    2675             : {
    2676           0 :         struct drm_device *dev = intel_sdvo->base.base.dev;
    2677             :         struct drm_connector *connector, *tmp;
    2678             : 
    2679           0 :         list_for_each_entry_safe(connector, tmp,
    2680             :                                  &dev->mode_config.connector_list, head) {
    2681           0 :                 if (intel_attached_encoder(connector) == &intel_sdvo->base) {
    2682           0 :                         drm_connector_unregister(connector);
    2683           0 :                         intel_sdvo_destroy(connector);
    2684           0 :                 }
    2685             :         }
    2686           0 : }
    2687             : 
    2688           0 : static bool intel_sdvo_tv_create_property(struct intel_sdvo *intel_sdvo,
    2689             :                                           struct intel_sdvo_connector *intel_sdvo_connector,
    2690             :                                           int type)
    2691             : {
    2692           0 :         struct drm_device *dev = intel_sdvo->base.base.dev;
    2693           0 :         struct intel_sdvo_tv_format format;
    2694           0 :         uint32_t format_map, i;
    2695             : 
    2696           0 :         if (!intel_sdvo_set_target_output(intel_sdvo, type))
    2697           0 :                 return false;
    2698             : 
    2699             :         BUILD_BUG_ON(sizeof(format) != 6);
    2700           0 :         if (!intel_sdvo_get_value(intel_sdvo,
    2701             :                                   SDVO_CMD_GET_SUPPORTED_TV_FORMATS,
    2702             :                                   &format, sizeof(format)))
    2703           0 :                 return false;
    2704             : 
    2705           0 :         memcpy(&format_map, &format, min(sizeof(format_map), sizeof(format)));
    2706             : 
    2707           0 :         if (format_map == 0)
    2708           0 :                 return false;
    2709             : 
    2710           0 :         intel_sdvo_connector->format_supported_num = 0;
    2711           0 :         for (i = 0 ; i < TV_FORMAT_NUM; i++)
    2712           0 :                 if (format_map & (1 << i))
    2713           0 :                         intel_sdvo_connector->tv_format_supported[intel_sdvo_connector->format_supported_num++] = i;
    2714             : 
    2715             : 
    2716           0 :         intel_sdvo_connector->tv_format =
    2717           0 :                         drm_property_create(dev, DRM_MODE_PROP_ENUM,
    2718           0 :                                             "mode", intel_sdvo_connector->format_supported_num);
    2719           0 :         if (!intel_sdvo_connector->tv_format)
    2720           0 :                 return false;
    2721             : 
    2722           0 :         for (i = 0; i < intel_sdvo_connector->format_supported_num; i++)
    2723           0 :                 drm_property_add_enum(
    2724           0 :                                 intel_sdvo_connector->tv_format, i,
    2725           0 :                                 i, tv_format_names[intel_sdvo_connector->tv_format_supported[i]]);
    2726             : 
    2727           0 :         intel_sdvo->tv_format_index = intel_sdvo_connector->tv_format_supported[0];
    2728           0 :         drm_object_attach_property(&intel_sdvo_connector->base.base.base,
    2729           0 :                                       intel_sdvo_connector->tv_format, 0);
    2730           0 :         return true;
    2731             : 
    2732           0 : }
    2733             : 
    2734             : #define ENHANCEMENT(name, NAME) do { \
    2735             :         if (enhancements.name) { \
    2736             :                 if (!intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_MAX_##NAME, &data_value, 4) || \
    2737             :                     !intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_##NAME, &response, 2)) \
    2738             :                         return false; \
    2739             :                 intel_sdvo_connector->max_##name = data_value[0]; \
    2740             :                 intel_sdvo_connector->cur_##name = response; \
    2741             :                 intel_sdvo_connector->name = \
    2742             :                         drm_property_create_range(dev, 0, #name, 0, data_value[0]); \
    2743             :                 if (!intel_sdvo_connector->name) return false; \
    2744             :                 drm_object_attach_property(&connector->base, \
    2745             :                                               intel_sdvo_connector->name, \
    2746             :                                               intel_sdvo_connector->cur_##name); \
    2747             :                 DRM_DEBUG_KMS(#name ": max %d, default %d, current %d\n", \
    2748             :                               data_value[0], data_value[1], response); \
    2749             :         } \
    2750             : } while (0)
    2751             : 
    2752             : static bool
    2753           0 : intel_sdvo_create_enhance_property_tv(struct intel_sdvo *intel_sdvo,
    2754             :                                       struct intel_sdvo_connector *intel_sdvo_connector,
    2755             :                                       struct intel_sdvo_enhancements_reply enhancements)
    2756             : {
    2757           0 :         struct drm_device *dev = intel_sdvo->base.base.dev;
    2758           0 :         struct drm_connector *connector = &intel_sdvo_connector->base.base;
    2759           0 :         uint16_t response, data_value[2];
    2760             : 
    2761             :         /* when horizontal overscan is supported, Add the left/right  property */
    2762           0 :         if (enhancements.overscan_h) {
    2763           0 :                 if (!intel_sdvo_get_value(intel_sdvo,
    2764             :                                           SDVO_CMD_GET_MAX_OVERSCAN_H,
    2765             :                                           &data_value, 4))
    2766           0 :                         return false;
    2767             : 
    2768           0 :                 if (!intel_sdvo_get_value(intel_sdvo,
    2769             :                                           SDVO_CMD_GET_OVERSCAN_H,
    2770             :                                           &response, 2))
    2771           0 :                         return false;
    2772             : 
    2773           0 :                 intel_sdvo_connector->max_hscan = data_value[0];
    2774           0 :                 intel_sdvo_connector->left_margin = data_value[0] - response;
    2775           0 :                 intel_sdvo_connector->right_margin = intel_sdvo_connector->left_margin;
    2776           0 :                 intel_sdvo_connector->left =
    2777           0 :                         drm_property_create_range(dev, 0, "left_margin", 0, data_value[0]);
    2778           0 :                 if (!intel_sdvo_connector->left)
    2779           0 :                         return false;
    2780             : 
    2781           0 :                 drm_object_attach_property(&connector->base,
    2782             :                                               intel_sdvo_connector->left,
    2783           0 :                                               intel_sdvo_connector->left_margin);
    2784             : 
    2785           0 :                 intel_sdvo_connector->right =
    2786           0 :                         drm_property_create_range(dev, 0, "right_margin", 0, data_value[0]);
    2787           0 :                 if (!intel_sdvo_connector->right)
    2788           0 :                         return false;
    2789             : 
    2790           0 :                 drm_object_attach_property(&connector->base,
    2791             :                                               intel_sdvo_connector->right,
    2792           0 :                                               intel_sdvo_connector->right_margin);
    2793             :                 DRM_DEBUG_KMS("h_overscan: max %d, "
    2794             :                               "default %d, current %d\n",
    2795             :                               data_value[0], data_value[1], response);
    2796           0 :         }
    2797             : 
    2798           0 :         if (enhancements.overscan_v) {
    2799           0 :                 if (!intel_sdvo_get_value(intel_sdvo,
    2800             :                                           SDVO_CMD_GET_MAX_OVERSCAN_V,
    2801             :                                           &data_value, 4))
    2802           0 :                         return false;
    2803             : 
    2804           0 :                 if (!intel_sdvo_get_value(intel_sdvo,
    2805             :                                           SDVO_CMD_GET_OVERSCAN_V,
    2806             :                                           &response, 2))
    2807           0 :                         return false;
    2808             : 
    2809           0 :                 intel_sdvo_connector->max_vscan = data_value[0];
    2810           0 :                 intel_sdvo_connector->top_margin = data_value[0] - response;
    2811           0 :                 intel_sdvo_connector->bottom_margin = intel_sdvo_connector->top_margin;
    2812           0 :                 intel_sdvo_connector->top =
    2813           0 :                         drm_property_create_range(dev, 0,
    2814           0 :                                             "top_margin", 0, data_value[0]);
    2815           0 :                 if (!intel_sdvo_connector->top)
    2816           0 :                         return false;
    2817             : 
    2818           0 :                 drm_object_attach_property(&connector->base,
    2819             :                                               intel_sdvo_connector->top,
    2820           0 :                                               intel_sdvo_connector->top_margin);
    2821             : 
    2822           0 :                 intel_sdvo_connector->bottom =
    2823           0 :                         drm_property_create_range(dev, 0,
    2824           0 :                                             "bottom_margin", 0, data_value[0]);
    2825           0 :                 if (!intel_sdvo_connector->bottom)
    2826           0 :                         return false;
    2827             : 
    2828           0 :                 drm_object_attach_property(&connector->base,
    2829             :                                               intel_sdvo_connector->bottom,
    2830           0 :                                               intel_sdvo_connector->bottom_margin);
    2831             :                 DRM_DEBUG_KMS("v_overscan: max %d, "
    2832             :                               "default %d, current %d\n",
    2833             :                               data_value[0], data_value[1], response);
    2834           0 :         }
    2835             : 
    2836           0 :         ENHANCEMENT(hpos, HPOS);
    2837           0 :         ENHANCEMENT(vpos, VPOS);
    2838           0 :         ENHANCEMENT(saturation, SATURATION);
    2839           0 :         ENHANCEMENT(contrast, CONTRAST);
    2840           0 :         ENHANCEMENT(hue, HUE);
    2841           0 :         ENHANCEMENT(sharpness, SHARPNESS);
    2842           0 :         ENHANCEMENT(brightness, BRIGHTNESS);
    2843           0 :         ENHANCEMENT(flicker_filter, FLICKER_FILTER);
    2844           0 :         ENHANCEMENT(flicker_filter_adaptive, FLICKER_FILTER_ADAPTIVE);
    2845           0 :         ENHANCEMENT(flicker_filter_2d, FLICKER_FILTER_2D);
    2846           0 :         ENHANCEMENT(tv_chroma_filter, TV_CHROMA_FILTER);
    2847           0 :         ENHANCEMENT(tv_luma_filter, TV_LUMA_FILTER);
    2848             : 
    2849           0 :         if (enhancements.dot_crawl) {
    2850           0 :                 if (!intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_DOT_CRAWL, &response, 2))
    2851           0 :                         return false;
    2852             : 
    2853           0 :                 intel_sdvo_connector->max_dot_crawl = 1;
    2854           0 :                 intel_sdvo_connector->cur_dot_crawl = response & 0x1;
    2855           0 :                 intel_sdvo_connector->dot_crawl =
    2856           0 :                         drm_property_create_range(dev, 0, "dot_crawl", 0, 1);
    2857           0 :                 if (!intel_sdvo_connector->dot_crawl)
    2858           0 :                         return false;
    2859             : 
    2860           0 :                 drm_object_attach_property(&connector->base,
    2861             :                                               intel_sdvo_connector->dot_crawl,
    2862           0 :                                               intel_sdvo_connector->cur_dot_crawl);
    2863             :                 DRM_DEBUG_KMS("dot crawl: current %d\n", response);
    2864           0 :         }
    2865             : 
    2866           0 :         return true;
    2867           0 : }
    2868             : 
    2869             : static bool
    2870           0 : intel_sdvo_create_enhance_property_lvds(struct intel_sdvo *intel_sdvo,
    2871             :                                         struct intel_sdvo_connector *intel_sdvo_connector,
    2872             :                                         struct intel_sdvo_enhancements_reply enhancements)
    2873             : {
    2874           0 :         struct drm_device *dev = intel_sdvo->base.base.dev;
    2875           0 :         struct drm_connector *connector = &intel_sdvo_connector->base.base;
    2876           0 :         uint16_t response, data_value[2];
    2877             : 
    2878           0 :         ENHANCEMENT(brightness, BRIGHTNESS);
    2879             : 
    2880           0 :         return true;
    2881           0 : }
    2882             : #undef ENHANCEMENT
    2883             : 
    2884           0 : static bool intel_sdvo_create_enhance_property(struct intel_sdvo *intel_sdvo,
    2885             :                                                struct intel_sdvo_connector *intel_sdvo_connector)
    2886             : {
    2887           0 :         union {
    2888             :                 struct intel_sdvo_enhancements_reply reply;
    2889             :                 uint16_t response;
    2890             :         } enhancements;
    2891             : 
    2892             :         BUILD_BUG_ON(sizeof(enhancements) != 2);
    2893             : 
    2894           0 :         enhancements.response = 0;
    2895           0 :         intel_sdvo_get_value(intel_sdvo,
    2896             :                              SDVO_CMD_GET_SUPPORTED_ENHANCEMENTS,
    2897             :                              &enhancements, sizeof(enhancements));
    2898           0 :         if (enhancements.response == 0) {
    2899             :                 DRM_DEBUG_KMS("No enhancement is supported\n");
    2900           0 :                 return true;
    2901             :         }
    2902             : 
    2903           0 :         if (IS_TV(intel_sdvo_connector))
    2904           0 :                 return intel_sdvo_create_enhance_property_tv(intel_sdvo, intel_sdvo_connector, enhancements.reply);
    2905           0 :         else if (IS_LVDS(intel_sdvo_connector))
    2906           0 :                 return intel_sdvo_create_enhance_property_lvds(intel_sdvo, intel_sdvo_connector, enhancements.reply);
    2907             :         else
    2908           0 :                 return true;
    2909           0 : }
    2910             : 
    2911           0 : static int intel_sdvo_ddc_proxy_xfer(struct i2c_adapter *adapter,
    2912             :                                      struct i2c_msg *msgs,
    2913             :                                      int num)
    2914             : {
    2915           0 :         struct intel_sdvo *sdvo = adapter->algo_data;
    2916             : 
    2917           0 :         if (!intel_sdvo_set_control_bus_switch(sdvo, sdvo->ddc_bus))
    2918           0 :                 return -EIO;
    2919             : 
    2920           0 :         return sdvo->i2c->algo->master_xfer(sdvo->i2c, msgs, num);
    2921           0 : }
    2922             : 
    2923           0 : static u32 intel_sdvo_ddc_proxy_func(struct i2c_adapter *adapter)
    2924             : {
    2925           0 :         struct intel_sdvo *sdvo = adapter->algo_data;
    2926           0 :         return sdvo->i2c->algo->functionality(sdvo->i2c);
    2927             : }
    2928             : 
    2929             : static const struct i2c_algorithm intel_sdvo_ddc_proxy = {
    2930             :         .master_xfer    = intel_sdvo_ddc_proxy_xfer,
    2931             :         .functionality  = intel_sdvo_ddc_proxy_func
    2932             : };
    2933             : 
    2934             : static bool
    2935           0 : intel_sdvo_init_ddc_proxy(struct intel_sdvo *sdvo,
    2936             :                           struct drm_device *dev)
    2937             : {
    2938             : #ifdef __linux__
    2939             :         sdvo->ddc.owner = THIS_MODULE;
    2940             :         sdvo->ddc.class = I2C_CLASS_DDC;
    2941             : #endif
    2942           0 :         snprintf(sdvo->ddc.name, I2C_NAME_SIZE, "SDVO DDC proxy");
    2943             : #ifdef __linux__
    2944             :         sdvo->ddc.dev.parent = &dev->pdev->dev;
    2945             : #endif
    2946           0 :         sdvo->ddc.algo_data = sdvo;
    2947           0 :         sdvo->ddc.algo = &intel_sdvo_ddc_proxy;
    2948             : 
    2949           0 :         return i2c_add_adapter(&sdvo->ddc) == 0;
    2950             : }
    2951             : 
    2952           0 : bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob)
    2953             : {
    2954           0 :         struct drm_i915_private *dev_priv = dev->dev_private;
    2955             :         struct intel_encoder *intel_encoder;
    2956             :         struct intel_sdvo *intel_sdvo;
    2957             :         int i;
    2958           0 :         intel_sdvo = kzalloc(sizeof(*intel_sdvo), GFP_KERNEL);
    2959           0 :         if (!intel_sdvo)
    2960           0 :                 return false;
    2961             : 
    2962           0 :         intel_sdvo->sdvo_reg = sdvo_reg;
    2963           0 :         intel_sdvo->is_sdvob = is_sdvob;
    2964           0 :         intel_sdvo->slave_addr = intel_sdvo_get_slave_addr(dev, intel_sdvo) >> 1;
    2965           0 :         intel_sdvo_select_i2c_bus(dev_priv, intel_sdvo);
    2966           0 :         if (!intel_sdvo_init_ddc_proxy(intel_sdvo, dev))
    2967             :                 goto err_i2c_bus;
    2968             : 
    2969             :         /* encoder type will be decided later */
    2970           0 :         intel_encoder = &intel_sdvo->base;
    2971           0 :         intel_encoder->type = INTEL_OUTPUT_SDVO;
    2972           0 :         drm_encoder_init(dev, &intel_encoder->base, &intel_sdvo_enc_funcs, 0);
    2973             : 
    2974             :         /* Read the regs to test if we can talk to the device */
    2975           0 :         for (i = 0; i < 0x40; i++) {
    2976           0 :                 u8 byte;
    2977             : 
    2978           0 :                 if (!intel_sdvo_read_byte(intel_sdvo, i, &byte)) {
    2979             :                         DRM_DEBUG_KMS("No SDVO device found on %s\n",
    2980             :                                       SDVO_NAME(intel_sdvo));
    2981           0 :                         goto err;
    2982             :                 }
    2983           0 :         }
    2984             : 
    2985           0 :         intel_encoder->compute_config = intel_sdvo_compute_config;
    2986           0 :         if (HAS_PCH_SPLIT(dev)) {
    2987           0 :                 intel_encoder->disable = pch_disable_sdvo;
    2988           0 :                 intel_encoder->post_disable = pch_post_disable_sdvo;
    2989           0 :         } else {
    2990           0 :                 intel_encoder->disable = intel_disable_sdvo;
    2991             :         }
    2992           0 :         intel_encoder->pre_enable = intel_sdvo_pre_enable;
    2993           0 :         intel_encoder->enable = intel_enable_sdvo;
    2994           0 :         intel_encoder->get_hw_state = intel_sdvo_get_hw_state;
    2995           0 :         intel_encoder->get_config = intel_sdvo_get_config;
    2996             : 
    2997             :         /* In default case sdvo lvds is false */
    2998           0 :         if (!intel_sdvo_get_capabilities(intel_sdvo, &intel_sdvo->caps))
    2999             :                 goto err;
    3000             : 
    3001           0 :         if (intel_sdvo_output_setup(intel_sdvo,
    3002           0 :                                     intel_sdvo->caps.output_flags) != true) {
    3003             :                 DRM_DEBUG_KMS("SDVO output failed to setup on %s\n",
    3004             :                               SDVO_NAME(intel_sdvo));
    3005             :                 /* Output_setup can leave behind connectors! */
    3006             :                 goto err_output;
    3007             :         }
    3008             : 
    3009             :         /* Only enable the hotplug irq if we need it, to work around noisy
    3010             :          * hotplug lines.
    3011             :          */
    3012           0 :         if (intel_sdvo->hotplug_active) {
    3013           0 :                 intel_encoder->hpd_pin =
    3014           0 :                         intel_sdvo->is_sdvob ?  HPD_SDVO_B : HPD_SDVO_C;
    3015           0 :         }
    3016             : 
    3017             :         /*
    3018             :          * Cloning SDVO with anything is often impossible, since the SDVO
    3019             :          * encoder can request a special input timing mode. And even if that's
    3020             :          * not the case we have evidence that cloning a plain unscaled mode with
    3021             :          * VGA doesn't really work. Furthermore the cloning flags are way too
    3022             :          * simplistic anyway to express such constraints, so just give up on
    3023             :          * cloning for SDVO encoders.
    3024             :          */
    3025           0 :         intel_sdvo->base.cloneable = 0;
    3026             : 
    3027           0 :         intel_sdvo_select_ddc_bus(dev_priv, intel_sdvo);
    3028             : 
    3029             :         /* Set the input timing to the screen. Assume always input 0. */
    3030           0 :         if (!intel_sdvo_set_target_input(intel_sdvo))
    3031             :                 goto err_output;
    3032             : 
    3033           0 :         if (!intel_sdvo_get_input_pixel_clock_range(intel_sdvo,
    3034           0 :                                                     &intel_sdvo->pixel_clock_min,
    3035           0 :                                                     &intel_sdvo->pixel_clock_max))
    3036             :                 goto err_output;
    3037             : 
    3038             :         DRM_DEBUG_KMS("%s device VID/DID: %02X:%02X.%02X, "
    3039             :                         "clock range %dMHz - %dMHz, "
    3040             :                         "input 1: %c, input 2: %c, "
    3041             :                         "output 1: %c, output 2: %c\n",
    3042             :                         SDVO_NAME(intel_sdvo),
    3043             :                         intel_sdvo->caps.vendor_id, intel_sdvo->caps.device_id,
    3044             :                         intel_sdvo->caps.device_rev_id,
    3045             :                         intel_sdvo->pixel_clock_min / 1000,
    3046             :                         intel_sdvo->pixel_clock_max / 1000,
    3047             :                         (intel_sdvo->caps.sdvo_inputs_mask & 0x1) ? 'Y' : 'N',
    3048             :                         (intel_sdvo->caps.sdvo_inputs_mask & 0x2) ? 'Y' : 'N',
    3049             :                         /* check currently supported outputs */
    3050             :                         intel_sdvo->caps.output_flags &
    3051             :                         (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_RGB0) ? 'Y' : 'N',
    3052             :                         intel_sdvo->caps.output_flags &
    3053             :                         (SDVO_OUTPUT_TMDS1 | SDVO_OUTPUT_RGB1) ? 'Y' : 'N');
    3054           0 :         return true;
    3055             : 
    3056             : err_output:
    3057           0 :         intel_sdvo_output_cleanup(intel_sdvo);
    3058             : 
    3059             : err:
    3060           0 :         drm_encoder_cleanup(&intel_encoder->base);
    3061             :         i2c_del_adapter(&intel_sdvo->ddc);
    3062             : err_i2c_bus:
    3063           0 :         intel_sdvo_unselect_i2c_bus(intel_sdvo);
    3064           0 :         kfree(intel_sdvo);
    3065             : 
    3066           0 :         return false;
    3067           0 : }

Generated by: LCOV version 1.13