LCOV - code coverage report
Current view: top level - drivers/gpu/drm/i915/display - intel_sdvo.c (source / functions) Hit Total Coverage
Test: combined.info Lines: 0 1319 0.0 %
Date: 2022-03-28 15:32:58 Functions: 0 71 0.0 %
Branches: 0 837 0.0 %

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

Generated by: LCOV version 1.14