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