1235783Skib/* 2235783Skib * Copyright (c) 2006 Luc Verhaegen (quirks list) 3235783Skib * Copyright (c) 2007-2008 Intel Corporation 4235783Skib * Jesse Barnes <jesse.barnes@intel.com> 5235783Skib * Copyright 2010 Red Hat, Inc. 6235783Skib * 7235783Skib * DDC probing routines (drm_ddc_read & drm_do_probe_ddc_edid) originally from 8235783Skib * FB layer. 9235783Skib * Copyright (C) 2006 Dennis Munsie <dmunsie@cecropia.com> 10235783Skib * 11235783Skib * Permission is hereby granted, free of charge, to any person obtaining a 12235783Skib * copy of this software and associated documentation files (the "Software"), 13235783Skib * to deal in the Software without restriction, including without limitation 14235783Skib * the rights to use, copy, modify, merge, publish, distribute, sub license, 15235783Skib * and/or sell copies of the Software, and to permit persons to whom the 16235783Skib * Software is furnished to do so, subject to the following conditions: 17235783Skib * 18235783Skib * The above copyright notice and this permission notice (including the 19235783Skib * next paragraph) shall be included in all copies or substantial portions 20235783Skib * of the Software. 21235783Skib * 22235783Skib * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 23235783Skib * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 24235783Skib * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 25235783Skib * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 26235783Skib * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 27235783Skib * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 28235783Skib * DEALINGS IN THE SOFTWARE. 29235783Skib */ 30235783Skib 31235783Skib#include <sys/cdefs.h> 32235783Skib__FBSDID("$FreeBSD$"); 33235783Skib 34235783Skib#include <dev/drm2/drmP.h> 35235783Skib#include <dev/drm2/drm_edid.h> 36235783Skib#include <dev/drm2/drm_edid_modes.h> 37235783Skib#include <dev/iicbus/iic.h> 38235783Skib#include <dev/iicbus/iiconf.h> 39235783Skib#include "iicbus_if.h" 40235783Skib 41235783Skib#define version_greater(edid, maj, min) \ 42235783Skib (((edid)->version > (maj)) || \ 43235783Skib ((edid)->version == (maj) && (edid)->revision > (min))) 44235783Skib 45235783Skib#define EDID_EST_TIMINGS 16 46235783Skib#define EDID_STD_TIMINGS 8 47235783Skib#define EDID_DETAILED_TIMINGS 4 48235783Skib 49235783Skib/* 50235783Skib * EDID blocks out in the wild have a variety of bugs, try to collect 51235783Skib * them here (note that userspace may work around broken monitors first, 52235783Skib * but fixes should make their way here so that the kernel "just works" 53235783Skib * on as many displays as possible). 54235783Skib */ 55235783Skib 56235783Skib/* First detailed mode wrong, use largest 60Hz mode */ 57235783Skib#define EDID_QUIRK_PREFER_LARGE_60 (1 << 0) 58235783Skib/* Reported 135MHz pixel clock is too high, needs adjustment */ 59235783Skib#define EDID_QUIRK_135_CLOCK_TOO_HIGH (1 << 1) 60235783Skib/* Prefer the largest mode at 75 Hz */ 61235783Skib#define EDID_QUIRK_PREFER_LARGE_75 (1 << 2) 62235783Skib/* Detail timing is in cm not mm */ 63235783Skib#define EDID_QUIRK_DETAILED_IN_CM (1 << 3) 64235783Skib/* Detailed timing descriptors have bogus size values, so just take the 65235783Skib * maximum size and use that. 66235783Skib */ 67235783Skib#define EDID_QUIRK_DETAILED_USE_MAXIMUM_SIZE (1 << 4) 68235783Skib/* Monitor forgot to set the first detailed is preferred bit. */ 69235783Skib#define EDID_QUIRK_FIRST_DETAILED_PREFERRED (1 << 5) 70235783Skib/* use +hsync +vsync for detailed mode */ 71235783Skib#define EDID_QUIRK_DETAILED_SYNC_PP (1 << 6) 72235783Skib 73235783Skibstruct detailed_mode_closure { 74235783Skib struct drm_connector *connector; 75235783Skib struct edid *edid; 76235783Skib bool preferred; 77235783Skib u32 quirks; 78235783Skib int modes; 79235783Skib}; 80235783Skib 81235783Skib#define LEVEL_DMT 0 82235783Skib#define LEVEL_GTF 1 83235783Skib#define LEVEL_GTF2 2 84235783Skib#define LEVEL_CVT 3 85235783Skib 86235783Skibstatic struct edid_quirk { 87235783Skib char *vendor; 88235783Skib int product_id; 89235783Skib u32 quirks; 90235783Skib} edid_quirk_list[] = { 91235783Skib /* Acer AL1706 */ 92235783Skib { "ACR", 44358, EDID_QUIRK_PREFER_LARGE_60 }, 93235783Skib /* Acer F51 */ 94235783Skib { "API", 0x7602, EDID_QUIRK_PREFER_LARGE_60 }, 95235783Skib /* Unknown Acer */ 96235783Skib { "ACR", 2423, EDID_QUIRK_FIRST_DETAILED_PREFERRED }, 97235783Skib 98235783Skib /* Belinea 10 15 55 */ 99235783Skib { "MAX", 1516, EDID_QUIRK_PREFER_LARGE_60 }, 100235783Skib { "MAX", 0x77e, EDID_QUIRK_PREFER_LARGE_60 }, 101235783Skib 102235783Skib /* Envision Peripherals, Inc. EN-7100e */ 103235783Skib { "EPI", 59264, EDID_QUIRK_135_CLOCK_TOO_HIGH }, 104235783Skib /* Envision EN2028 */ 105235783Skib { "EPI", 8232, EDID_QUIRK_PREFER_LARGE_60 }, 106235783Skib 107235783Skib /* Funai Electronics PM36B */ 108235783Skib { "FCM", 13600, EDID_QUIRK_PREFER_LARGE_75 | 109235783Skib EDID_QUIRK_DETAILED_IN_CM }, 110235783Skib 111235783Skib /* LG Philips LCD LP154W01-A5 */ 112235783Skib { "LPL", 0, EDID_QUIRK_DETAILED_USE_MAXIMUM_SIZE }, 113235783Skib { "LPL", 0x2a00, EDID_QUIRK_DETAILED_USE_MAXIMUM_SIZE }, 114235783Skib 115235783Skib /* Philips 107p5 CRT */ 116235783Skib { "PHL", 57364, EDID_QUIRK_FIRST_DETAILED_PREFERRED }, 117235783Skib 118235783Skib /* Proview AY765C */ 119235783Skib { "PTS", 765, EDID_QUIRK_FIRST_DETAILED_PREFERRED }, 120235783Skib 121235783Skib /* Samsung SyncMaster 205BW. Note: irony */ 122235783Skib { "SAM", 541, EDID_QUIRK_DETAILED_SYNC_PP }, 123235783Skib /* Samsung SyncMaster 22[5-6]BW */ 124235783Skib { "SAM", 596, EDID_QUIRK_PREFER_LARGE_60 }, 125235783Skib { "SAM", 638, EDID_QUIRK_PREFER_LARGE_60 }, 126235783Skib}; 127235783Skib 128235783Skib/*** DDC fetch and block validation ***/ 129235783Skib 130235783Skibstatic const u8 edid_header[] = { 131235783Skib 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00 132235783Skib}; 133235783Skib 134235783Skib /* 135235783Skib * Sanity check the header of the base EDID block. Return 8 if the header 136235783Skib * is perfect, down to 0 if it's totally wrong. 137235783Skib */ 138235783Skibint drm_edid_header_is_valid(const u8 *raw_edid) 139235783Skib{ 140235783Skib int i, score = 0; 141235783Skib 142235783Skib for (i = 0; i < sizeof(edid_header); i++) 143235783Skib if (raw_edid[i] == edid_header[i]) 144235783Skib score++; 145235783Skib 146235783Skib return score; 147235783Skib} 148235783Skib 149235783Skib/* 150235783Skib * Sanity check the EDID block (base or extension). Return 0 if the block 151235783Skib * doesn't check out, or 1 if it's valid. 152235783Skib */ 153235783Skibstatic bool 154235783Skibdrm_edid_block_valid(u8 *raw_edid) 155235783Skib{ 156235783Skib int i; 157235783Skib u8 csum = 0; 158235783Skib struct edid *edid = (struct edid *)raw_edid; 159235783Skib 160235783Skib if (raw_edid[0] == 0x00) { 161235783Skib int score = drm_edid_header_is_valid(raw_edid); 162235783Skib if (score == 8) ; 163235783Skib else if (score >= 6) { 164235783Skib DRM_DEBUG("Fixing EDID header, your hardware may be failing\n"); 165235783Skib memcpy(raw_edid, edid_header, sizeof(edid_header)); 166235783Skib } else { 167235783Skib goto bad; 168235783Skib } 169235783Skib } 170235783Skib 171235783Skib for (i = 0; i < EDID_LENGTH; i++) 172235783Skib csum += raw_edid[i]; 173235783Skib if (csum) { 174259745Sdumbbell DRM_DEBUG("EDID checksum is invalid, remainder is %d\n", csum); 175235783Skib 176235783Skib /* allow CEA to slide through, switches mangle this */ 177235783Skib if (raw_edid[0] != 0x02) 178235783Skib goto bad; 179235783Skib } 180235783Skib 181235783Skib /* per-block-type checks */ 182235783Skib switch (raw_edid[0]) { 183235783Skib case 0: /* base */ 184235783Skib if (edid->version != 1) { 185235783Skib DRM_ERROR("EDID has major version %d, instead of 1\n", edid->version); 186235783Skib goto bad; 187235783Skib } 188235783Skib 189235783Skib if (edid->revision > 4) 190235783Skib DRM_DEBUG("EDID minor > 4, assuming backward compatibility\n"); 191235783Skib break; 192235783Skib 193235783Skib default: 194235783Skib break; 195235783Skib } 196235783Skib 197235783Skib return 1; 198235783Skib 199235783Skibbad: 200235783Skib if (raw_edid) { 201235783Skib DRM_DEBUG_KMS("Raw EDID:\n"); 202235783Skib if ((drm_debug_flag & DRM_DEBUGBITS_KMS) != 0) { 203235783Skib for (i = 0; i < EDID_LENGTH; ) { 204235783Skib printf("%02x", raw_edid[i]); 205235783Skib i++; 206235783Skib if (i % 16 == 0 || i == EDID_LENGTH) 207235783Skib printf("\n"); 208235783Skib else if (i % 8 == 0) 209235783Skib printf(" "); 210235783Skib else 211235783Skib printf(" "); 212235783Skib } 213235783Skib } 214235783Skib } 215235783Skib return 0; 216235783Skib} 217235783Skib 218235783Skib/** 219235783Skib * drm_edid_is_valid - sanity check EDID data 220235783Skib * @edid: EDID data 221235783Skib * 222235783Skib * Sanity-check an entire EDID record (including extensions) 223235783Skib */ 224235783Skibbool drm_edid_is_valid(struct edid *edid) 225235783Skib{ 226235783Skib int i; 227235783Skib u8 *raw = (u8 *)edid; 228235783Skib 229235783Skib if (!edid) 230235783Skib return false; 231235783Skib 232235783Skib for (i = 0; i <= edid->extensions; i++) 233235783Skib if (!drm_edid_block_valid(raw + i * EDID_LENGTH)) 234235783Skib return false; 235235783Skib 236235783Skib return true; 237235783Skib} 238235783Skib 239235783Skib#define DDC_ADDR 0x50 240235783Skib#define DDC_SEGMENT_ADDR 0x30 241235783Skib/** 242235783Skib * Get EDID information via I2C. 243235783Skib * 244235783Skib * \param adapter : i2c device adaptor 245235783Skib * \param buf : EDID data buffer to be filled 246235783Skib * \param len : EDID data buffer length 247235783Skib * \return 0 on success or -1 on failure. 248235783Skib * 249235783Skib * Try to fetch EDID information by calling i2c driver function. 250235783Skib */ 251235783Skibstatic int 252235783Skibdrm_do_probe_ddc_edid(device_t adapter, unsigned char *buf, 253235783Skib int block, int len) 254235783Skib{ 255235783Skib unsigned char start = block * EDID_LENGTH; 256254833Sdumbbell unsigned char segment = block >> 1; 257254833Sdumbbell unsigned char xfers = segment ? 3 : 2; 258235783Skib int ret, retries = 5; 259235783Skib 260235783Skib /* The core i2c driver will automatically retry the transfer if the 261235783Skib * adapter reports EAGAIN. However, we find that bit-banging transfers 262235783Skib * are susceptible to errors under a heavily loaded machine and 263235783Skib * generate spurious NAKs and timeouts. Retrying the transfer 264235783Skib * of the individual block a few times seems to overcome this. 265235783Skib */ 266235783Skib do { 267235783Skib struct iic_msg msgs[] = { 268235783Skib { 269254833Sdumbbell .slave = DDC_SEGMENT_ADDR << 1, 270254833Sdumbbell .flags = 0, 271254833Sdumbbell .len = 1, 272254833Sdumbbell .buf = &segment, 273254833Sdumbbell }, { 274249041Sdumbbell .slave = DDC_ADDR << 1, 275235783Skib .flags = IIC_M_WR, 276235783Skib .len = 1, 277235783Skib .buf = &start, 278235783Skib }, { 279249041Sdumbbell .slave = DDC_ADDR << 1, 280235783Skib .flags = IIC_M_RD, 281235783Skib .len = len, 282235783Skib .buf = buf, 283235783Skib } 284235783Skib }; 285254833Sdumbbell 286254833Sdumbbell /* 287254833Sdumbbell * Avoid sending the segment addr to not upset non-compliant ddc 288254833Sdumbbell * monitors. 289254833Sdumbbell */ 290254833Sdumbbell ret = iicbus_transfer(adapter, &msgs[3 - xfers], xfers); 291254833Sdumbbell 292235783Skib if (ret != 0) 293235783Skib DRM_DEBUG_KMS("iicbus_transfer countdown %d error %d\n", 294235783Skib retries, ret); 295235783Skib } while (ret != 0 && --retries); 296235783Skib 297235783Skib return (ret == 0 ? 0 : -1); 298235783Skib} 299235783Skib 300235783Skibstatic bool drm_edid_is_zero(u8 *in_edid, int length) 301235783Skib{ 302235783Skib int i; 303235783Skib u32 *raw_edid = (u32 *)in_edid; 304235783Skib 305235783Skib for (i = 0; i < length / 4; i++) 306235783Skib if (*(raw_edid + i) != 0) 307235783Skib return false; 308235783Skib return true; 309235783Skib} 310235783Skib 311235783Skibstatic u8 * 312235783Skibdrm_do_get_edid(struct drm_connector *connector, device_t adapter) 313235783Skib{ 314235783Skib int i, j = 0, valid_extensions = 0; 315235783Skib u8 *block, *new; 316235783Skib 317235783Skib block = malloc(EDID_LENGTH, DRM_MEM_KMS, M_WAITOK | M_ZERO); 318235783Skib 319235783Skib /* base block fetch */ 320235783Skib for (i = 0; i < 4; i++) { 321235783Skib if (drm_do_probe_ddc_edid(adapter, block, 0, EDID_LENGTH)) 322235783Skib goto out; 323235783Skib if (drm_edid_block_valid(block)) 324235783Skib break; 325235783Skib if (i == 0 && drm_edid_is_zero(block, EDID_LENGTH)) { 326235783Skib connector->null_edid_counter++; 327235783Skib goto carp; 328235783Skib } 329235783Skib } 330235783Skib if (i == 4) 331235783Skib goto carp; 332235783Skib 333235783Skib /* if there's no extensions, we're done */ 334235783Skib if (block[0x7e] == 0) 335235783Skib return block; 336235783Skib 337235783Skib new = reallocf(block, (block[0x7e] + 1) * EDID_LENGTH, DRM_MEM_KMS, 338235783Skib M_WAITOK); 339235783Skib block = new; 340235783Skib 341235783Skib for (j = 1; j <= block[0x7e]; j++) { 342235783Skib for (i = 0; i < 4; i++) { 343235783Skib if (drm_do_probe_ddc_edid(adapter, 344235783Skib block + (valid_extensions + 1) * EDID_LENGTH, 345235783Skib j, EDID_LENGTH)) 346235783Skib goto out; 347235783Skib if (drm_edid_block_valid(block + (valid_extensions + 1) * EDID_LENGTH)) { 348235783Skib valid_extensions++; 349235783Skib break; 350235783Skib } 351235783Skib } 352235783Skib if (i == 4) 353235783Skib DRM_DEBUG_KMS("%s: Ignoring invalid EDID block %d.\n", 354235783Skib drm_get_connector_name(connector), j); 355235783Skib } 356235783Skib 357235783Skib if (valid_extensions != block[0x7e]) { 358235783Skib block[EDID_LENGTH-1] += block[0x7e] - valid_extensions; 359235783Skib block[0x7e] = valid_extensions; 360235783Skib new = reallocf(block, (valid_extensions + 1) * EDID_LENGTH, 361235783Skib DRM_MEM_KMS, M_WAITOK); 362235783Skib block = new; 363235783Skib } 364235783Skib 365235783Skib DRM_DEBUG_KMS("got EDID from %s\n", drm_get_connector_name(connector)); 366235783Skib return block; 367235783Skib 368235783Skibcarp: 369235783Skib DRM_ERROR("%s: EDID block %d invalid.\n", 370235783Skib drm_get_connector_name(connector), j); 371235783Skib 372235783Skibout: 373235783Skib free(block, DRM_MEM_KMS); 374235783Skib return NULL; 375235783Skib} 376235783Skib 377235783Skib/** 378235783Skib * Probe DDC presence. 379235783Skib * 380235783Skib * \param adapter : i2c device adaptor 381235783Skib * \return 1 on success 382235783Skib */ 383235783Skibstatic bool 384235783Skibdrm_probe_ddc(device_t adapter) 385235783Skib{ 386235783Skib unsigned char out; 387235783Skib 388235783Skib return (drm_do_probe_ddc_edid(adapter, &out, 0, 1) == 0); 389235783Skib} 390235783Skib 391235783Skib/** 392235783Skib * drm_get_edid - get EDID data, if available 393235783Skib * @connector: connector we're probing 394235783Skib * @adapter: i2c adapter to use for DDC 395235783Skib * 396235783Skib * Poke the given i2c channel to grab EDID data if possible. If found, 397235783Skib * attach it to the connector. 398235783Skib * 399235783Skib * Return edid data or NULL if we couldn't find any. 400235783Skib */ 401235783Skibstruct edid *drm_get_edid(struct drm_connector *connector, 402235783Skib device_t adapter) 403235783Skib{ 404235783Skib struct edid *edid = NULL; 405235783Skib 406235783Skib if (drm_probe_ddc(adapter)) 407235783Skib edid = (struct edid *)drm_do_get_edid(connector, adapter); 408235783Skib 409235783Skib connector->display_info.raw_edid = (char *)edid; 410235783Skib 411235783Skib return edid; 412235783Skib 413235783Skib} 414235783Skib 415235783Skib/*** EDID parsing ***/ 416235783Skib 417235783Skib/** 418235783Skib * edid_vendor - match a string against EDID's obfuscated vendor field 419235783Skib * @edid: EDID to match 420235783Skib * @vendor: vendor string 421235783Skib * 422235783Skib * Returns true if @vendor is in @edid, false otherwise 423235783Skib */ 424235783Skibstatic bool edid_vendor(struct edid *edid, char *vendor) 425235783Skib{ 426235783Skib char edid_vendor[3]; 427235783Skib 428235783Skib edid_vendor[0] = ((edid->mfg_id[0] & 0x7c) >> 2) + '@'; 429235783Skib edid_vendor[1] = (((edid->mfg_id[0] & 0x3) << 3) | 430235783Skib ((edid->mfg_id[1] & 0xe0) >> 5)) + '@'; 431235783Skib edid_vendor[2] = (edid->mfg_id[1] & 0x1f) + '@'; 432235783Skib 433235783Skib return !strncmp(edid_vendor, vendor, 3); 434235783Skib} 435235783Skib 436235783Skib/** 437235783Skib * edid_get_quirks - return quirk flags for a given EDID 438235783Skib * @edid: EDID to process 439235783Skib * 440235783Skib * This tells subsequent routines what fixes they need to apply. 441235783Skib */ 442235783Skibstatic u32 edid_get_quirks(struct edid *edid) 443235783Skib{ 444235783Skib struct edid_quirk *quirk; 445235783Skib int i; 446235783Skib 447235783Skib for (i = 0; i < DRM_ARRAY_SIZE(edid_quirk_list); i++) { 448235783Skib quirk = &edid_quirk_list[i]; 449235783Skib 450235783Skib if (edid_vendor(edid, quirk->vendor) && 451235783Skib (EDID_PRODUCT_ID(edid) == quirk->product_id)) 452235783Skib return quirk->quirks; 453235783Skib } 454235783Skib 455235783Skib return 0; 456235783Skib} 457235783Skib 458235783Skib#define MODE_SIZE(m) ((m)->hdisplay * (m)->vdisplay) 459235783Skib#define MODE_REFRESH_DIFF(m,r) (abs((m)->vrefresh - target_refresh)) 460235783Skib 461235783Skib/** 462235783Skib * edid_fixup_preferred - set preferred modes based on quirk list 463235783Skib * @connector: has mode list to fix up 464235783Skib * @quirks: quirks list 465235783Skib * 466235783Skib * Walk the mode list for @connector, clearing the preferred status 467235783Skib * on existing modes and setting it anew for the right mode ala @quirks. 468235783Skib */ 469235783Skibstatic void edid_fixup_preferred(struct drm_connector *connector, 470235783Skib u32 quirks) 471235783Skib{ 472235783Skib struct drm_display_mode *t, *cur_mode, *preferred_mode; 473235783Skib int target_refresh = 0; 474235783Skib 475235783Skib if (list_empty(&connector->probed_modes)) 476235783Skib return; 477235783Skib 478235783Skib if (quirks & EDID_QUIRK_PREFER_LARGE_60) 479235783Skib target_refresh = 60; 480235783Skib if (quirks & EDID_QUIRK_PREFER_LARGE_75) 481235783Skib target_refresh = 75; 482235783Skib 483235783Skib preferred_mode = list_first_entry(&connector->probed_modes, 484235783Skib struct drm_display_mode, head); 485235783Skib 486235783Skib list_for_each_entry_safe(cur_mode, t, &connector->probed_modes, head) { 487235783Skib cur_mode->type &= ~DRM_MODE_TYPE_PREFERRED; 488235783Skib 489235783Skib if (cur_mode == preferred_mode) 490235783Skib continue; 491235783Skib 492235783Skib /* Largest mode is preferred */ 493235783Skib if (MODE_SIZE(cur_mode) > MODE_SIZE(preferred_mode)) 494235783Skib preferred_mode = cur_mode; 495235783Skib 496235783Skib /* At a given size, try to get closest to target refresh */ 497235783Skib if ((MODE_SIZE(cur_mode) == MODE_SIZE(preferred_mode)) && 498235783Skib MODE_REFRESH_DIFF(cur_mode, target_refresh) < 499235783Skib MODE_REFRESH_DIFF(preferred_mode, target_refresh)) { 500235783Skib preferred_mode = cur_mode; 501235783Skib } 502235783Skib } 503235783Skib 504235783Skib preferred_mode->type |= DRM_MODE_TYPE_PREFERRED; 505235783Skib} 506235783Skib 507235783Skibstruct drm_display_mode *drm_mode_find_dmt(struct drm_device *dev, 508235783Skib int hsize, int vsize, int fresh) 509235783Skib{ 510235783Skib struct drm_display_mode *mode = NULL; 511235783Skib int i; 512235783Skib 513235783Skib for (i = 0; i < drm_num_dmt_modes; i++) { 514235783Skib struct drm_display_mode *ptr = &drm_dmt_modes[i]; 515235783Skib if (hsize == ptr->hdisplay && 516235783Skib vsize == ptr->vdisplay && 517235783Skib fresh == drm_mode_vrefresh(ptr)) { 518235783Skib /* get the expected default mode */ 519235783Skib mode = drm_mode_duplicate(dev, ptr); 520235783Skib break; 521235783Skib } 522235783Skib } 523235783Skib return mode; 524235783Skib} 525235783Skib 526235783Skibtypedef void detailed_cb(struct detailed_timing *timing, void *closure); 527235783Skib 528235783Skibstatic void 529235783Skibcea_for_each_detailed_block(u8 *ext, detailed_cb *cb, void *closure) 530235783Skib{ 531235783Skib int i, n = 0; 532235783Skib u8 rev = ext[0x01], d = ext[0x02]; 533235783Skib u8 *det_base = ext + d; 534235783Skib 535235783Skib switch (rev) { 536235783Skib case 0: 537235783Skib /* can't happen */ 538235783Skib return; 539235783Skib case 1: 540235783Skib /* have to infer how many blocks we have, check pixel clock */ 541235783Skib for (i = 0; i < 6; i++) 542235783Skib if (det_base[18*i] || det_base[18*i+1]) 543235783Skib n++; 544235783Skib break; 545235783Skib default: 546235783Skib /* explicit count */ 547235783Skib n = min(ext[0x03] & 0x0f, 6); 548235783Skib break; 549235783Skib } 550235783Skib 551235783Skib for (i = 0; i < n; i++) 552235783Skib cb((struct detailed_timing *)(det_base + 18 * i), closure); 553235783Skib} 554235783Skib 555235783Skibstatic void 556235783Skibvtb_for_each_detailed_block(u8 *ext, detailed_cb *cb, void *closure) 557235783Skib{ 558235783Skib unsigned int i, n = min((int)ext[0x02], 6); 559235783Skib u8 *det_base = ext + 5; 560235783Skib 561235783Skib if (ext[0x01] != 1) 562235783Skib return; /* unknown version */ 563235783Skib 564235783Skib for (i = 0; i < n; i++) 565235783Skib cb((struct detailed_timing *)(det_base + 18 * i), closure); 566235783Skib} 567235783Skib 568235783Skibstatic void 569235783Skibdrm_for_each_detailed_block(u8 *raw_edid, detailed_cb *cb, void *closure) 570235783Skib{ 571235783Skib int i; 572235783Skib struct edid *edid = (struct edid *)raw_edid; 573235783Skib 574235783Skib if (edid == NULL) 575235783Skib return; 576235783Skib 577235783Skib for (i = 0; i < EDID_DETAILED_TIMINGS; i++) 578235783Skib cb(&(edid->detailed_timings[i]), closure); 579235783Skib 580235783Skib for (i = 1; i <= raw_edid[0x7e]; i++) { 581235783Skib u8 *ext = raw_edid + (i * EDID_LENGTH); 582235783Skib switch (*ext) { 583235783Skib case CEA_EXT: 584235783Skib cea_for_each_detailed_block(ext, cb, closure); 585235783Skib break; 586235783Skib case VTB_EXT: 587235783Skib vtb_for_each_detailed_block(ext, cb, closure); 588235783Skib break; 589235783Skib default: 590235783Skib break; 591235783Skib } 592235783Skib } 593235783Skib} 594235783Skib 595235783Skibstatic void 596235783Skibis_rb(struct detailed_timing *t, void *data) 597235783Skib{ 598235783Skib u8 *r = (u8 *)t; 599235783Skib if (r[3] == EDID_DETAIL_MONITOR_RANGE) 600235783Skib if (r[15] & 0x10) 601235783Skib *(bool *)data = true; 602235783Skib} 603235783Skib 604235783Skib/* EDID 1.4 defines this explicitly. For EDID 1.3, we guess, badly. */ 605235783Skibstatic bool 606235783Skibdrm_monitor_supports_rb(struct edid *edid) 607235783Skib{ 608235783Skib if (edid->revision >= 4) { 609235783Skib bool ret; 610235783Skib drm_for_each_detailed_block((u8 *)edid, is_rb, &ret); 611235783Skib return ret; 612235783Skib } 613235783Skib 614235783Skib return ((edid->input & DRM_EDID_INPUT_DIGITAL) != 0); 615235783Skib} 616235783Skib 617235783Skibstatic void 618235783Skibfind_gtf2(struct detailed_timing *t, void *data) 619235783Skib{ 620235783Skib u8 *r = (u8 *)t; 621235783Skib if (r[3] == EDID_DETAIL_MONITOR_RANGE && r[10] == 0x02) 622235783Skib *(u8 **)data = r; 623235783Skib} 624235783Skib 625235783Skib/* Secondary GTF curve kicks in above some break frequency */ 626235783Skibstatic int 627235783Skibdrm_gtf2_hbreak(struct edid *edid) 628235783Skib{ 629235783Skib u8 *r = NULL; 630235783Skib drm_for_each_detailed_block((u8 *)edid, find_gtf2, &r); 631235783Skib return r ? (r[12] * 2) : 0; 632235783Skib} 633235783Skib 634235783Skibstatic int 635235783Skibdrm_gtf2_2c(struct edid *edid) 636235783Skib{ 637235783Skib u8 *r = NULL; 638235783Skib drm_for_each_detailed_block((u8 *)edid, find_gtf2, &r); 639235783Skib return r ? r[13] : 0; 640235783Skib} 641235783Skib 642235783Skibstatic int 643235783Skibdrm_gtf2_m(struct edid *edid) 644235783Skib{ 645235783Skib u8 *r = NULL; 646235783Skib drm_for_each_detailed_block((u8 *)edid, find_gtf2, &r); 647235783Skib return r ? (r[15] << 8) + r[14] : 0; 648235783Skib} 649235783Skib 650235783Skibstatic int 651235783Skibdrm_gtf2_k(struct edid *edid) 652235783Skib{ 653235783Skib u8 *r = NULL; 654235783Skib drm_for_each_detailed_block((u8 *)edid, find_gtf2, &r); 655235783Skib return r ? r[16] : 0; 656235783Skib} 657235783Skib 658235783Skibstatic int 659235783Skibdrm_gtf2_2j(struct edid *edid) 660235783Skib{ 661235783Skib u8 *r = NULL; 662235783Skib drm_for_each_detailed_block((u8 *)edid, find_gtf2, &r); 663235783Skib return r ? r[17] : 0; 664235783Skib} 665235783Skib 666235783Skib/** 667235783Skib * standard_timing_level - get std. timing level(CVT/GTF/DMT) 668235783Skib * @edid: EDID block to scan 669235783Skib */ 670235783Skibstatic int standard_timing_level(struct edid *edid) 671235783Skib{ 672235783Skib if (edid->revision >= 2) { 673235783Skib if (edid->revision >= 4 && (edid->features & DRM_EDID_FEATURE_DEFAULT_GTF)) 674235783Skib return LEVEL_CVT; 675235783Skib if (drm_gtf2_hbreak(edid)) 676235783Skib return LEVEL_GTF2; 677235783Skib return LEVEL_GTF; 678235783Skib } 679235783Skib return LEVEL_DMT; 680235783Skib} 681235783Skib 682235783Skib/* 683235783Skib * 0 is reserved. The spec says 0x01 fill for unused timings. Some old 684235783Skib * monitors fill with ascii space (0x20) instead. 685235783Skib */ 686235783Skibstatic int 687235783Skibbad_std_timing(u8 a, u8 b) 688235783Skib{ 689235783Skib return (a == 0x00 && b == 0x00) || 690235783Skib (a == 0x01 && b == 0x01) || 691235783Skib (a == 0x20 && b == 0x20); 692235783Skib} 693235783Skib 694235783Skib/** 695235783Skib * drm_mode_std - convert standard mode info (width, height, refresh) into mode 696235783Skib * @t: standard timing params 697235783Skib * @timing_level: standard timing level 698235783Skib * 699235783Skib * Take the standard timing params (in this case width, aspect, and refresh) 700235783Skib * and convert them into a real mode using CVT/GTF/DMT. 701235783Skib */ 702235783Skibstatic struct drm_display_mode * 703235783Skibdrm_mode_std(struct drm_connector *connector, struct edid *edid, 704235783Skib struct std_timing *t, int revision) 705235783Skib{ 706235783Skib struct drm_device *dev = connector->dev; 707235783Skib struct drm_display_mode *m, *mode = NULL; 708235783Skib int hsize, vsize; 709235783Skib int vrefresh_rate; 710235783Skib unsigned aspect_ratio = (t->vfreq_aspect & EDID_TIMING_ASPECT_MASK) 711235783Skib >> EDID_TIMING_ASPECT_SHIFT; 712235783Skib unsigned vfreq = (t->vfreq_aspect & EDID_TIMING_VFREQ_MASK) 713235783Skib >> EDID_TIMING_VFREQ_SHIFT; 714235783Skib int timing_level = standard_timing_level(edid); 715235783Skib 716235783Skib if (bad_std_timing(t->hsize, t->vfreq_aspect)) 717235783Skib return NULL; 718235783Skib 719235783Skib /* According to the EDID spec, the hdisplay = hsize * 8 + 248 */ 720235783Skib hsize = t->hsize * 8 + 248; 721235783Skib /* vrefresh_rate = vfreq + 60 */ 722235783Skib vrefresh_rate = vfreq + 60; 723235783Skib /* the vdisplay is calculated based on the aspect ratio */ 724235783Skib if (aspect_ratio == 0) { 725235783Skib if (revision < 3) 726235783Skib vsize = hsize; 727235783Skib else 728235783Skib vsize = (hsize * 10) / 16; 729235783Skib } else if (aspect_ratio == 1) 730235783Skib vsize = (hsize * 3) / 4; 731235783Skib else if (aspect_ratio == 2) 732235783Skib vsize = (hsize * 4) / 5; 733235783Skib else 734235783Skib vsize = (hsize * 9) / 16; 735235783Skib 736235783Skib /* HDTV hack, part 1 */ 737235783Skib if (vrefresh_rate == 60 && 738235783Skib ((hsize == 1360 && vsize == 765) || 739235783Skib (hsize == 1368 && vsize == 769))) { 740235783Skib hsize = 1366; 741235783Skib vsize = 768; 742235783Skib } 743235783Skib 744235783Skib /* 745235783Skib * If this connector already has a mode for this size and refresh 746235783Skib * rate (because it came from detailed or CVT info), use that 747235783Skib * instead. This way we don't have to guess at interlace or 748235783Skib * reduced blanking. 749235783Skib */ 750235783Skib list_for_each_entry(m, &connector->probed_modes, head) 751235783Skib if (m->hdisplay == hsize && m->vdisplay == vsize && 752235783Skib drm_mode_vrefresh(m) == vrefresh_rate) 753235783Skib return NULL; 754235783Skib 755235783Skib /* HDTV hack, part 2 */ 756235783Skib if (hsize == 1366 && vsize == 768 && vrefresh_rate == 60) { 757235783Skib mode = drm_cvt_mode(dev, 1366, 768, vrefresh_rate, 0, 0, 758235783Skib false); 759235783Skib mode->hdisplay = 1366; 760235783Skib mode->hsync_start = mode->hsync_start - 1; 761235783Skib mode->hsync_end = mode->hsync_end - 1; 762235783Skib return mode; 763235783Skib } 764235783Skib 765235783Skib /* check whether it can be found in default mode table */ 766235783Skib mode = drm_mode_find_dmt(dev, hsize, vsize, vrefresh_rate); 767235783Skib if (mode) 768235783Skib return mode; 769235783Skib 770235783Skib switch (timing_level) { 771235783Skib case LEVEL_DMT: 772235783Skib break; 773235783Skib case LEVEL_GTF: 774235783Skib mode = drm_gtf_mode(dev, hsize, vsize, vrefresh_rate, 0, 0); 775235783Skib break; 776235783Skib case LEVEL_GTF2: 777235783Skib /* 778235783Skib * This is potentially wrong if there's ever a monitor with 779235783Skib * more than one ranges section, each claiming a different 780235783Skib * secondary GTF curve. Please don't do that. 781235783Skib */ 782235783Skib mode = drm_gtf_mode(dev, hsize, vsize, vrefresh_rate, 0, 0); 783235783Skib if (drm_mode_hsync(mode) > drm_gtf2_hbreak(edid)) { 784235783Skib free(mode, DRM_MEM_KMS); 785235783Skib mode = drm_gtf_mode_complex(dev, hsize, vsize, 786235783Skib vrefresh_rate, 0, 0, 787235783Skib drm_gtf2_m(edid), 788235783Skib drm_gtf2_2c(edid), 789235783Skib drm_gtf2_k(edid), 790235783Skib drm_gtf2_2j(edid)); 791235783Skib } 792235783Skib break; 793235783Skib case LEVEL_CVT: 794235783Skib mode = drm_cvt_mode(dev, hsize, vsize, vrefresh_rate, 0, 0, 795235783Skib false); 796235783Skib break; 797235783Skib } 798235783Skib return mode; 799235783Skib} 800235783Skib 801235783Skib/* 802235783Skib * EDID is delightfully ambiguous about how interlaced modes are to be 803235783Skib * encoded. Our internal representation is of frame height, but some 804235783Skib * HDTV detailed timings are encoded as field height. 805235783Skib * 806235783Skib * The format list here is from CEA, in frame size. Technically we 807235783Skib * should be checking refresh rate too. Whatever. 808235783Skib */ 809235783Skibstatic void 810235783Skibdrm_mode_do_interlace_quirk(struct drm_display_mode *mode, 811235783Skib struct detailed_pixel_timing *pt) 812235783Skib{ 813235783Skib int i; 814235783Skib static const struct { 815235783Skib int w, h; 816235783Skib } cea_interlaced[] = { 817235783Skib { 1920, 1080 }, 818235783Skib { 720, 480 }, 819235783Skib { 1440, 480 }, 820235783Skib { 2880, 480 }, 821235783Skib { 720, 576 }, 822235783Skib { 1440, 576 }, 823235783Skib { 2880, 576 }, 824235783Skib }; 825235783Skib 826235783Skib if (!(pt->misc & DRM_EDID_PT_INTERLACED)) 827235783Skib return; 828235783Skib 829235783Skib for (i = 0; i < DRM_ARRAY_SIZE(cea_interlaced); i++) { 830235783Skib if ((mode->hdisplay == cea_interlaced[i].w) && 831235783Skib (mode->vdisplay == cea_interlaced[i].h / 2)) { 832235783Skib mode->vdisplay *= 2; 833235783Skib mode->vsync_start *= 2; 834235783Skib mode->vsync_end *= 2; 835235783Skib mode->vtotal *= 2; 836235783Skib mode->vtotal |= 1; 837235783Skib } 838235783Skib } 839235783Skib 840235783Skib mode->flags |= DRM_MODE_FLAG_INTERLACE; 841235783Skib} 842235783Skib 843235783Skib/** 844235783Skib * drm_mode_detailed - create a new mode from an EDID detailed timing section 845235783Skib * @dev: DRM device (needed to create new mode) 846235783Skib * @edid: EDID block 847235783Skib * @timing: EDID detailed timing info 848235783Skib * @quirks: quirks to apply 849235783Skib * 850235783Skib * An EDID detailed timing block contains enough info for us to create and 851235783Skib * return a new struct drm_display_mode. 852235783Skib */ 853235783Skibstatic struct drm_display_mode *drm_mode_detailed(struct drm_device *dev, 854235783Skib struct edid *edid, 855235783Skib struct detailed_timing *timing, 856235783Skib u32 quirks) 857235783Skib{ 858235783Skib struct drm_display_mode *mode; 859235783Skib struct detailed_pixel_timing *pt = &timing->data.pixel_data; 860235783Skib unsigned hactive = (pt->hactive_hblank_hi & 0xf0) << 4 | pt->hactive_lo; 861235783Skib unsigned vactive = (pt->vactive_vblank_hi & 0xf0) << 4 | pt->vactive_lo; 862235783Skib unsigned hblank = (pt->hactive_hblank_hi & 0xf) << 8 | pt->hblank_lo; 863235783Skib unsigned vblank = (pt->vactive_vblank_hi & 0xf) << 8 | pt->vblank_lo; 864235783Skib unsigned hsync_offset = (pt->hsync_vsync_offset_pulse_width_hi & 0xc0) << 2 | pt->hsync_offset_lo; 865235783Skib unsigned hsync_pulse_width = (pt->hsync_vsync_offset_pulse_width_hi & 0x30) << 4 | pt->hsync_pulse_width_lo; 866235783Skib unsigned vsync_offset = (pt->hsync_vsync_offset_pulse_width_hi & 0xc) >> 2 | pt->vsync_offset_pulse_width_lo >> 4; 867235783Skib unsigned vsync_pulse_width = (pt->hsync_vsync_offset_pulse_width_hi & 0x3) << 4 | (pt->vsync_offset_pulse_width_lo & 0xf); 868235783Skib 869235783Skib /* ignore tiny modes */ 870235783Skib if (hactive < 64 || vactive < 64) 871235783Skib return NULL; 872235783Skib 873235783Skib if (pt->misc & DRM_EDID_PT_STEREO) { 874235783Skib printf("stereo mode not supported\n"); 875235783Skib return NULL; 876235783Skib } 877235783Skib if (!(pt->misc & DRM_EDID_PT_SEPARATE_SYNC)) { 878235783Skib printf("composite sync not supported\n"); 879235783Skib } 880235783Skib 881235783Skib /* it is incorrect if hsync/vsync width is zero */ 882235783Skib if (!hsync_pulse_width || !vsync_pulse_width) { 883235783Skib DRM_DEBUG_KMS("Incorrect Detailed timing. " 884235783Skib "Wrong Hsync/Vsync pulse width\n"); 885235783Skib return NULL; 886235783Skib } 887235783Skib mode = drm_mode_create(dev); 888235783Skib if (!mode) 889235783Skib return NULL; 890235783Skib 891235783Skib mode->type = DRM_MODE_TYPE_DRIVER; 892235783Skib 893235783Skib if (quirks & EDID_QUIRK_135_CLOCK_TOO_HIGH) 894235783Skib timing->pixel_clock = htole16(1088); 895235783Skib 896235783Skib mode->clock = le16toh(timing->pixel_clock) * 10; 897235783Skib 898235783Skib mode->hdisplay = hactive; 899235783Skib mode->hsync_start = mode->hdisplay + hsync_offset; 900235783Skib mode->hsync_end = mode->hsync_start + hsync_pulse_width; 901235783Skib mode->htotal = mode->hdisplay + hblank; 902235783Skib 903235783Skib mode->vdisplay = vactive; 904235783Skib mode->vsync_start = mode->vdisplay + vsync_offset; 905235783Skib mode->vsync_end = mode->vsync_start + vsync_pulse_width; 906235783Skib mode->vtotal = mode->vdisplay + vblank; 907235783Skib 908235783Skib /* Some EDIDs have bogus h/vtotal values */ 909235783Skib if (mode->hsync_end > mode->htotal) 910235783Skib mode->htotal = mode->hsync_end + 1; 911235783Skib if (mode->vsync_end > mode->vtotal) 912235783Skib mode->vtotal = mode->vsync_end + 1; 913235783Skib 914235783Skib drm_mode_do_interlace_quirk(mode, pt); 915235783Skib 916235783Skib drm_mode_set_name(mode); 917235783Skib 918235783Skib if (quirks & EDID_QUIRK_DETAILED_SYNC_PP) { 919235783Skib pt->misc |= DRM_EDID_PT_HSYNC_POSITIVE | DRM_EDID_PT_VSYNC_POSITIVE; 920235783Skib } 921235783Skib 922235783Skib mode->flags |= (pt->misc & DRM_EDID_PT_HSYNC_POSITIVE) ? 923235783Skib DRM_MODE_FLAG_PHSYNC : DRM_MODE_FLAG_NHSYNC; 924235783Skib mode->flags |= (pt->misc & DRM_EDID_PT_VSYNC_POSITIVE) ? 925235783Skib DRM_MODE_FLAG_PVSYNC : DRM_MODE_FLAG_NVSYNC; 926235783Skib 927235783Skib mode->width_mm = pt->width_mm_lo | (pt->width_height_mm_hi & 0xf0) << 4; 928235783Skib mode->height_mm = pt->height_mm_lo | (pt->width_height_mm_hi & 0xf) << 8; 929235783Skib 930235783Skib if (quirks & EDID_QUIRK_DETAILED_IN_CM) { 931235783Skib mode->width_mm *= 10; 932235783Skib mode->height_mm *= 10; 933235783Skib } 934235783Skib 935235783Skib if (quirks & EDID_QUIRK_DETAILED_USE_MAXIMUM_SIZE) { 936235783Skib mode->width_mm = edid->width_cm * 10; 937235783Skib mode->height_mm = edid->height_cm * 10; 938235783Skib } 939235783Skib 940235783Skib return mode; 941235783Skib} 942235783Skib 943235783Skibstatic bool 944235783Skibmode_is_rb(const struct drm_display_mode *mode) 945235783Skib{ 946235783Skib return (mode->htotal - mode->hdisplay == 160) && 947235783Skib (mode->hsync_end - mode->hdisplay == 80) && 948235783Skib (mode->hsync_end - mode->hsync_start == 32) && 949235783Skib (mode->vsync_start - mode->vdisplay == 3); 950235783Skib} 951235783Skib 952235783Skibstatic bool 953235783Skibmode_in_hsync_range(struct drm_display_mode *mode, 954235783Skib struct edid *edid, u8 *t) 955235783Skib{ 956235783Skib int hsync, hmin, hmax; 957235783Skib 958235783Skib hmin = t[7]; 959235783Skib if (edid->revision >= 4) 960235783Skib hmin += ((t[4] & 0x04) ? 255 : 0); 961235783Skib hmax = t[8]; 962235783Skib if (edid->revision >= 4) 963235783Skib hmax += ((t[4] & 0x08) ? 255 : 0); 964235783Skib hsync = drm_mode_hsync(mode); 965235783Skib 966235783Skib return (hsync <= hmax && hsync >= hmin); 967235783Skib} 968235783Skib 969235783Skibstatic bool 970235783Skibmode_in_vsync_range(struct drm_display_mode *mode, 971235783Skib struct edid *edid, u8 *t) 972235783Skib{ 973235783Skib int vsync, vmin, vmax; 974235783Skib 975235783Skib vmin = t[5]; 976235783Skib if (edid->revision >= 4) 977235783Skib vmin += ((t[4] & 0x01) ? 255 : 0); 978235783Skib vmax = t[6]; 979235783Skib if (edid->revision >= 4) 980235783Skib vmax += ((t[4] & 0x02) ? 255 : 0); 981235783Skib vsync = drm_mode_vrefresh(mode); 982235783Skib 983235783Skib return (vsync <= vmax && vsync >= vmin); 984235783Skib} 985235783Skib 986235783Skibstatic u32 987235783Skibrange_pixel_clock(struct edid *edid, u8 *t) 988235783Skib{ 989235783Skib /* unspecified */ 990235783Skib if (t[9] == 0 || t[9] == 255) 991235783Skib return 0; 992235783Skib 993235783Skib /* 1.4 with CVT support gives us real precision, yay */ 994235783Skib if (edid->revision >= 4 && t[10] == 0x04) 995235783Skib return (t[9] * 10000) - ((t[12] >> 2) * 250); 996235783Skib 997235783Skib /* 1.3 is pathetic, so fuzz up a bit */ 998235783Skib return t[9] * 10000 + 5001; 999235783Skib} 1000235783Skib 1001235783Skibstatic bool 1002235783Skibmode_in_range(struct drm_display_mode *mode, struct edid *edid, 1003235783Skib struct detailed_timing *timing) 1004235783Skib{ 1005235783Skib u32 max_clock; 1006235783Skib u8 *t = (u8 *)timing; 1007235783Skib 1008235783Skib if (!mode_in_hsync_range(mode, edid, t)) 1009235783Skib return false; 1010235783Skib 1011235783Skib if (!mode_in_vsync_range(mode, edid, t)) 1012235783Skib return false; 1013235783Skib 1014235783Skib if ((max_clock = range_pixel_clock(edid, t))) 1015235783Skib if (mode->clock > max_clock) 1016235783Skib return false; 1017235783Skib 1018235783Skib /* 1.4 max horizontal check */ 1019235783Skib if (edid->revision >= 4 && t[10] == 0x04) 1020235783Skib if (t[13] && mode->hdisplay > 8 * (t[13] + (256 * (t[12]&0x3)))) 1021235783Skib return false; 1022235783Skib 1023235783Skib if (mode_is_rb(mode) && !drm_monitor_supports_rb(edid)) 1024235783Skib return false; 1025235783Skib 1026235783Skib return true; 1027235783Skib} 1028235783Skib 1029235783Skib/* 1030235783Skib * XXX If drm_dmt_modes ever regrows the CVT-R modes (and it will) this will 1031235783Skib * need to account for them. 1032235783Skib */ 1033235783Skibstatic int 1034235783Skibdrm_gtf_modes_for_range(struct drm_connector *connector, struct edid *edid, 1035235783Skib struct detailed_timing *timing) 1036235783Skib{ 1037235783Skib int i, modes = 0; 1038235783Skib struct drm_display_mode *newmode; 1039235783Skib struct drm_device *dev = connector->dev; 1040235783Skib 1041235783Skib for (i = 0; i < drm_num_dmt_modes; i++) { 1042235783Skib if (mode_in_range(drm_dmt_modes + i, edid, timing)) { 1043235783Skib newmode = drm_mode_duplicate(dev, &drm_dmt_modes[i]); 1044235783Skib if (newmode) { 1045235783Skib drm_mode_probed_add(connector, newmode); 1046235783Skib modes++; 1047235783Skib } 1048235783Skib } 1049235783Skib } 1050235783Skib 1051235783Skib return modes; 1052235783Skib} 1053235783Skib 1054235783Skibstatic void 1055235783Skibdo_inferred_modes(struct detailed_timing *timing, void *c) 1056235783Skib{ 1057235783Skib struct detailed_mode_closure *closure = c; 1058235783Skib struct detailed_non_pixel *data = &timing->data.other_data; 1059235783Skib int gtf = (closure->edid->features & DRM_EDID_FEATURE_DEFAULT_GTF); 1060235783Skib 1061235783Skib if (gtf && data->type == EDID_DETAIL_MONITOR_RANGE) 1062235783Skib closure->modes += drm_gtf_modes_for_range(closure->connector, 1063235783Skib closure->edid, 1064235783Skib timing); 1065235783Skib} 1066235783Skib 1067235783Skibstatic int 1068235783Skibadd_inferred_modes(struct drm_connector *connector, struct edid *edid) 1069235783Skib{ 1070235783Skib struct detailed_mode_closure closure = { 1071235783Skib connector, edid, 0, 0, 0 1072235783Skib }; 1073235783Skib 1074235783Skib if (version_greater(edid, 1, 0)) 1075235783Skib drm_for_each_detailed_block((u8 *)edid, do_inferred_modes, 1076235783Skib &closure); 1077235783Skib 1078235783Skib return closure.modes; 1079235783Skib} 1080235783Skib 1081235783Skibstatic int 1082235783Skibdrm_est3_modes(struct drm_connector *connector, struct detailed_timing *timing) 1083235783Skib{ 1084235783Skib int i, j, m, modes = 0; 1085235783Skib struct drm_display_mode *mode; 1086235783Skib u8 *est = ((u8 *)timing) + 5; 1087235783Skib 1088235783Skib for (i = 0; i < 6; i++) { 1089235783Skib for (j = 7; j > 0; j--) { 1090235783Skib m = (i * 8) + (7 - j); 1091235783Skib if (m >= DRM_ARRAY_SIZE(est3_modes)) 1092235783Skib break; 1093235783Skib if (est[i] & (1 << j)) { 1094235783Skib mode = drm_mode_find_dmt(connector->dev, 1095235783Skib est3_modes[m].w, 1096235783Skib est3_modes[m].h, 1097235783Skib est3_modes[m].r 1098235783Skib /*, est3_modes[m].rb */); 1099235783Skib if (mode) { 1100235783Skib drm_mode_probed_add(connector, mode); 1101235783Skib modes++; 1102235783Skib } 1103235783Skib } 1104235783Skib } 1105235783Skib } 1106235783Skib 1107235783Skib return modes; 1108235783Skib} 1109235783Skib 1110235783Skibstatic void 1111235783Skibdo_established_modes(struct detailed_timing *timing, void *c) 1112235783Skib{ 1113235783Skib struct detailed_mode_closure *closure = c; 1114235783Skib struct detailed_non_pixel *data = &timing->data.other_data; 1115235783Skib 1116235783Skib if (data->type == EDID_DETAIL_EST_TIMINGS) 1117235783Skib closure->modes += drm_est3_modes(closure->connector, timing); 1118235783Skib} 1119235783Skib 1120235783Skib/** 1121235783Skib * add_established_modes - get est. modes from EDID and add them 1122235783Skib * @edid: EDID block to scan 1123235783Skib * 1124235783Skib * Each EDID block contains a bitmap of the supported "established modes" list 1125235783Skib * (defined above). Tease them out and add them to the global modes list. 1126235783Skib */ 1127235783Skibstatic int 1128235783Skibadd_established_modes(struct drm_connector *connector, struct edid *edid) 1129235783Skib{ 1130235783Skib struct drm_device *dev = connector->dev; 1131235783Skib unsigned long est_bits = edid->established_timings.t1 | 1132235783Skib (edid->established_timings.t2 << 8) | 1133235783Skib ((edid->established_timings.mfg_rsvd & 0x80) << 9); 1134235783Skib int i, modes = 0; 1135235783Skib struct detailed_mode_closure closure = { 1136235783Skib connector, edid, 0, 0, 0 1137235783Skib }; 1138235783Skib 1139235783Skib for (i = 0; i <= EDID_EST_TIMINGS; i++) { 1140235783Skib if (est_bits & (1<<i)) { 1141235783Skib struct drm_display_mode *newmode; 1142235783Skib newmode = drm_mode_duplicate(dev, &edid_est_modes[i]); 1143235783Skib if (newmode) { 1144235783Skib drm_mode_probed_add(connector, newmode); 1145235783Skib modes++; 1146235783Skib } 1147235783Skib } 1148235783Skib } 1149235783Skib 1150235783Skib if (version_greater(edid, 1, 0)) 1151235783Skib drm_for_each_detailed_block((u8 *)edid, 1152235783Skib do_established_modes, &closure); 1153235783Skib 1154235783Skib return modes + closure.modes; 1155235783Skib} 1156235783Skib 1157235783Skibstatic void 1158235783Skibdo_standard_modes(struct detailed_timing *timing, void *c) 1159235783Skib{ 1160235783Skib struct detailed_mode_closure *closure = c; 1161235783Skib struct detailed_non_pixel *data = &timing->data.other_data; 1162235783Skib struct drm_connector *connector = closure->connector; 1163235783Skib struct edid *edid = closure->edid; 1164235783Skib 1165235783Skib if (data->type == EDID_DETAIL_STD_MODES) { 1166235783Skib int i; 1167235783Skib for (i = 0; i < 6; i++) { 1168235783Skib struct std_timing *std; 1169235783Skib struct drm_display_mode *newmode; 1170235783Skib 1171235783Skib std = &data->data.timings[i]; 1172235783Skib newmode = drm_mode_std(connector, edid, std, 1173235783Skib edid->revision); 1174235783Skib if (newmode) { 1175235783Skib drm_mode_probed_add(connector, newmode); 1176235783Skib closure->modes++; 1177235783Skib } 1178235783Skib } 1179235783Skib } 1180235783Skib} 1181235783Skib 1182235783Skib/** 1183235783Skib * add_standard_modes - get std. modes from EDID and add them 1184235783Skib * @edid: EDID block to scan 1185235783Skib * 1186235783Skib * Standard modes can be calculated using the appropriate standard (DMT, 1187235783Skib * GTF or CVT. Grab them from @edid and add them to the list. 1188235783Skib */ 1189235783Skibstatic int 1190235783Skibadd_standard_modes(struct drm_connector *connector, struct edid *edid) 1191235783Skib{ 1192235783Skib int i, modes = 0; 1193235783Skib struct detailed_mode_closure closure = { 1194235783Skib connector, edid, 0, 0, 0 1195235783Skib }; 1196235783Skib 1197235783Skib for (i = 0; i < EDID_STD_TIMINGS; i++) { 1198235783Skib struct drm_display_mode *newmode; 1199235783Skib 1200235783Skib newmode = drm_mode_std(connector, edid, 1201235783Skib &edid->standard_timings[i], 1202235783Skib edid->revision); 1203235783Skib if (newmode) { 1204235783Skib drm_mode_probed_add(connector, newmode); 1205235783Skib modes++; 1206235783Skib } 1207235783Skib } 1208235783Skib 1209235783Skib if (version_greater(edid, 1, 0)) 1210235783Skib drm_for_each_detailed_block((u8 *)edid, do_standard_modes, 1211235783Skib &closure); 1212235783Skib 1213235783Skib /* XXX should also look for standard codes in VTB blocks */ 1214235783Skib 1215235783Skib return modes + closure.modes; 1216235783Skib} 1217235783Skib 1218235783Skibstatic int drm_cvt_modes(struct drm_connector *connector, 1219235783Skib struct detailed_timing *timing) 1220235783Skib{ 1221235783Skib int i, j, modes = 0; 1222235783Skib struct drm_display_mode *newmode; 1223235783Skib struct drm_device *dev = connector->dev; 1224235783Skib struct cvt_timing *cvt; 1225235783Skib const int rates[] = { 60, 85, 75, 60, 50 }; 1226235783Skib const u8 empty[3] = { 0, 0, 0 }; 1227235783Skib 1228235783Skib for (i = 0; i < 4; i++) { 1229235783Skib int width = 0, height; 1230235783Skib cvt = &(timing->data.other_data.data.cvt[i]); 1231235783Skib 1232235783Skib if (!memcmp(cvt->code, empty, 3)) 1233235783Skib continue; 1234235783Skib 1235235783Skib height = (cvt->code[0] + ((cvt->code[1] & 0xf0) << 4) + 1) * 2; 1236235783Skib switch (cvt->code[1] & 0x0c) { 1237235783Skib case 0x00: 1238235783Skib width = height * 4 / 3; 1239235783Skib break; 1240235783Skib case 0x04: 1241235783Skib width = height * 16 / 9; 1242235783Skib break; 1243235783Skib case 0x08: 1244235783Skib width = height * 16 / 10; 1245235783Skib break; 1246235783Skib case 0x0c: 1247235783Skib width = height * 15 / 9; 1248235783Skib break; 1249235783Skib } 1250235783Skib 1251235783Skib for (j = 1; j < 5; j++) { 1252235783Skib if (cvt->code[2] & (1 << j)) { 1253235783Skib newmode = drm_cvt_mode(dev, width, height, 1254235783Skib rates[j], j == 0, 1255235783Skib false, false); 1256235783Skib if (newmode) { 1257235783Skib drm_mode_probed_add(connector, newmode); 1258235783Skib modes++; 1259235783Skib } 1260235783Skib } 1261235783Skib } 1262235783Skib } 1263235783Skib 1264235783Skib return modes; 1265235783Skib} 1266235783Skib 1267235783Skibstatic void 1268235783Skibdo_cvt_mode(struct detailed_timing *timing, void *c) 1269235783Skib{ 1270235783Skib struct detailed_mode_closure *closure = c; 1271235783Skib struct detailed_non_pixel *data = &timing->data.other_data; 1272235783Skib 1273235783Skib if (data->type == EDID_DETAIL_CVT_3BYTE) 1274235783Skib closure->modes += drm_cvt_modes(closure->connector, timing); 1275235783Skib} 1276235783Skib 1277235783Skibstatic int 1278235783Skibadd_cvt_modes(struct drm_connector *connector, struct edid *edid) 1279235783Skib{ 1280235783Skib struct detailed_mode_closure closure = { 1281235783Skib connector, edid, 0, 0, 0 1282235783Skib }; 1283235783Skib 1284235783Skib if (version_greater(edid, 1, 2)) 1285235783Skib drm_for_each_detailed_block((u8 *)edid, do_cvt_mode, &closure); 1286235783Skib 1287235783Skib /* XXX should also look for CVT codes in VTB blocks */ 1288235783Skib 1289235783Skib return closure.modes; 1290235783Skib} 1291235783Skib 1292235783Skibstatic void 1293235783Skibdo_detailed_mode(struct detailed_timing *timing, void *c) 1294235783Skib{ 1295235783Skib struct detailed_mode_closure *closure = c; 1296235783Skib struct drm_display_mode *newmode; 1297235783Skib 1298235783Skib if (timing->pixel_clock) { 1299235783Skib newmode = drm_mode_detailed(closure->connector->dev, 1300235783Skib closure->edid, timing, 1301235783Skib closure->quirks); 1302235783Skib if (!newmode) 1303235783Skib return; 1304235783Skib 1305235783Skib if (closure->preferred) 1306235783Skib newmode->type |= DRM_MODE_TYPE_PREFERRED; 1307235783Skib 1308235783Skib drm_mode_probed_add(closure->connector, newmode); 1309235783Skib closure->modes++; 1310235783Skib closure->preferred = 0; 1311235783Skib } 1312235783Skib} 1313235783Skib 1314235783Skib/* 1315235783Skib * add_detailed_modes - Add modes from detailed timings 1316235783Skib * @connector: attached connector 1317235783Skib * @edid: EDID block to scan 1318235783Skib * @quirks: quirks to apply 1319235783Skib */ 1320235783Skibstatic int 1321235783Skibadd_detailed_modes(struct drm_connector *connector, struct edid *edid, 1322235783Skib u32 quirks) 1323235783Skib{ 1324235783Skib struct detailed_mode_closure closure = { 1325235783Skib connector, 1326235783Skib edid, 1327235783Skib 1, 1328235783Skib quirks, 1329235783Skib 0 1330235783Skib }; 1331235783Skib 1332235783Skib if (closure.preferred && !version_greater(edid, 1, 3)) 1333235783Skib closure.preferred = 1334235783Skib (edid->features & DRM_EDID_FEATURE_PREFERRED_TIMING); 1335235783Skib 1336235783Skib drm_for_each_detailed_block((u8 *)edid, do_detailed_mode, &closure); 1337235783Skib 1338235783Skib return closure.modes; 1339235783Skib} 1340235783Skib 1341235783Skib#define HDMI_IDENTIFIER 0x000C03 1342235783Skib#define AUDIO_BLOCK 0x01 1343235783Skib#define VENDOR_BLOCK 0x03 1344235783Skib#define SPEAKER_BLOCK 0x04 1345235783Skib#define EDID_BASIC_AUDIO (1 << 6) 1346235783Skib 1347235783Skib/** 1348235783Skib * Search EDID for CEA extension block. 1349235783Skib */ 1350235783Skibu8 *drm_find_cea_extension(struct edid *edid) 1351235783Skib{ 1352235783Skib u8 *edid_ext = NULL; 1353235783Skib int i; 1354235783Skib 1355235783Skib /* No EDID or EDID extensions */ 1356235783Skib if (edid == NULL || edid->extensions == 0) 1357235783Skib return NULL; 1358235783Skib 1359235783Skib /* Find CEA extension */ 1360235783Skib for (i = 0; i < edid->extensions; i++) { 1361235783Skib edid_ext = (u8 *)edid + EDID_LENGTH * (i + 1); 1362235783Skib if (edid_ext[0] == CEA_EXT) 1363235783Skib break; 1364235783Skib } 1365235783Skib 1366235783Skib if (i == edid->extensions) 1367235783Skib return NULL; 1368235783Skib 1369235783Skib return edid_ext; 1370235783Skib} 1371235783Skib 1372235783Skibstatic void 1373235783Skibparse_hdmi_vsdb(struct drm_connector *connector, uint8_t *db) 1374235783Skib{ 1375235783Skib connector->eld[5] |= (db[6] >> 7) << 1; /* Supports_AI */ 1376235783Skib 1377235783Skib connector->dvi_dual = db[6] & 1; 1378235783Skib connector->max_tmds_clock = db[7] * 5; 1379235783Skib 1380235783Skib connector->latency_present[0] = db[8] >> 7; 1381235783Skib connector->latency_present[1] = (db[8] >> 6) & 1; 1382235783Skib connector->video_latency[0] = db[9]; 1383235783Skib connector->audio_latency[0] = db[10]; 1384235783Skib connector->video_latency[1] = db[11]; 1385235783Skib connector->audio_latency[1] = db[12]; 1386235783Skib 1387235783Skib DRM_DEBUG_KMS("HDMI: DVI dual %d, " 1388235783Skib "max TMDS clock %d, " 1389235783Skib "latency present %d %d, " 1390235783Skib "video latency %d %d, " 1391235783Skib "audio latency %d %d\n", 1392235783Skib connector->dvi_dual, 1393235783Skib connector->max_tmds_clock, 1394235783Skib (int) connector->latency_present[0], 1395235783Skib (int) connector->latency_present[1], 1396235783Skib connector->video_latency[0], 1397235783Skib connector->video_latency[1], 1398235783Skib connector->audio_latency[0], 1399235783Skib connector->audio_latency[1]); 1400235783Skib} 1401235783Skib 1402235783Skibstatic void 1403235783Skibmonitor_name(struct detailed_timing *t, void *data) 1404235783Skib{ 1405235783Skib if (t->data.other_data.type == EDID_DETAIL_MONITOR_NAME) 1406235783Skib *(u8 **)data = t->data.other_data.data.str.str; 1407235783Skib} 1408235783Skib 1409235783Skib/** 1410235783Skib * drm_edid_to_eld - build ELD from EDID 1411235783Skib * @connector: connector corresponding to the HDMI/DP sink 1412235783Skib * @edid: EDID to parse 1413235783Skib * 1414235783Skib * Fill the ELD (EDID-Like Data) buffer for passing to the audio driver. 1415235783Skib * Some ELD fields are left to the graphics driver caller: 1416235783Skib * - Conn_Type 1417235783Skib * - HDCP 1418235783Skib * - Port_ID 1419235783Skib */ 1420235783Skibvoid drm_edid_to_eld(struct drm_connector *connector, struct edid *edid) 1421235783Skib{ 1422235783Skib uint8_t *eld = connector->eld; 1423235783Skib u8 *cea; 1424235783Skib u8 *name; 1425235783Skib u8 *db; 1426235783Skib int sad_count = 0; 1427235783Skib int mnl; 1428235783Skib int dbl; 1429235783Skib 1430235783Skib memset(eld, 0, sizeof(connector->eld)); 1431235783Skib 1432235783Skib cea = drm_find_cea_extension(edid); 1433235783Skib if (!cea) { 1434235783Skib DRM_DEBUG_KMS("ELD: no CEA Extension found\n"); 1435235783Skib return; 1436235783Skib } 1437235783Skib 1438235783Skib name = NULL; 1439235783Skib drm_for_each_detailed_block((u8 *)edid, monitor_name, &name); 1440235783Skib for (mnl = 0; name && mnl < 13; mnl++) { 1441235783Skib if (name[mnl] == 0x0a) 1442235783Skib break; 1443235783Skib eld[20 + mnl] = name[mnl]; 1444235783Skib } 1445235783Skib eld[4] = (cea[1] << 5) | mnl; 1446235783Skib DRM_DEBUG_KMS("ELD monitor %s\n", eld + 20); 1447235783Skib 1448235783Skib eld[0] = 2 << 3; /* ELD version: 2 */ 1449235783Skib 1450235783Skib eld[16] = edid->mfg_id[0]; 1451235783Skib eld[17] = edid->mfg_id[1]; 1452235783Skib eld[18] = edid->prod_code[0]; 1453235783Skib eld[19] = edid->prod_code[1]; 1454235783Skib 1455235783Skib for (db = cea + 4; db < cea + cea[2]; db += dbl + 1) { 1456235783Skib dbl = db[0] & 0x1f; 1457235783Skib 1458235783Skib switch ((db[0] & 0xe0) >> 5) { 1459235783Skib case AUDIO_BLOCK: /* Audio Data Block, contains SADs */ 1460235783Skib sad_count = dbl / 3; 1461235783Skib memcpy(eld + 20 + mnl, &db[1], dbl); 1462235783Skib break; 1463235783Skib case SPEAKER_BLOCK: /* Speaker Allocation Data Block */ 1464235783Skib eld[7] = db[1]; 1465235783Skib break; 1466235783Skib case VENDOR_BLOCK: 1467235783Skib /* HDMI Vendor-Specific Data Block */ 1468235783Skib if (db[1] == 0x03 && db[2] == 0x0c && db[3] == 0) 1469235783Skib parse_hdmi_vsdb(connector, db); 1470235783Skib break; 1471235783Skib default: 1472235783Skib break; 1473235783Skib } 1474235783Skib } 1475235783Skib eld[5] |= sad_count << 4; 1476235783Skib eld[2] = (20 + mnl + sad_count * 3 + 3) / 4; 1477235783Skib 1478235783Skib DRM_DEBUG_KMS("ELD size %d, SAD count %d\n", (int)eld[2], sad_count); 1479235783Skib} 1480235783Skib 1481235783Skib/** 1482235783Skib * drm_av_sync_delay - HDMI/DP sink audio-video sync delay in millisecond 1483235783Skib * @connector: connector associated with the HDMI/DP sink 1484235783Skib * @mode: the display mode 1485235783Skib */ 1486235783Skibint drm_av_sync_delay(struct drm_connector *connector, 1487235783Skib struct drm_display_mode *mode) 1488235783Skib{ 1489235783Skib int i = !!(mode->flags & DRM_MODE_FLAG_INTERLACE); 1490235783Skib int a, v; 1491235783Skib 1492235783Skib if (!connector->latency_present[0]) 1493235783Skib return 0; 1494235783Skib if (!connector->latency_present[1]) 1495235783Skib i = 0; 1496235783Skib 1497235783Skib a = connector->audio_latency[i]; 1498235783Skib v = connector->video_latency[i]; 1499235783Skib 1500235783Skib /* 1501235783Skib * HDMI/DP sink doesn't support audio or video? 1502235783Skib */ 1503235783Skib if (a == 255 || v == 255) 1504235783Skib return 0; 1505235783Skib 1506235783Skib /* 1507235783Skib * Convert raw EDID values to millisecond. 1508235783Skib * Treat unknown latency as 0ms. 1509235783Skib */ 1510235783Skib if (a) 1511235783Skib a = min(2 * (a - 1), 500); 1512235783Skib if (v) 1513235783Skib v = min(2 * (v - 1), 500); 1514235783Skib 1515235783Skib return max(v - a, 0); 1516235783Skib} 1517235783Skib 1518235783Skib/** 1519235783Skib * drm_select_eld - select one ELD from multiple HDMI/DP sinks 1520235783Skib * @encoder: the encoder just changed display mode 1521235783Skib * @mode: the adjusted display mode 1522235783Skib * 1523235783Skib * It's possible for one encoder to be associated with multiple HDMI/DP sinks. 1524235783Skib * The policy is now hard coded to simply use the first HDMI/DP sink's ELD. 1525235783Skib */ 1526235783Skibstruct drm_connector *drm_select_eld(struct drm_encoder *encoder, 1527235783Skib struct drm_display_mode *mode) 1528235783Skib{ 1529235783Skib struct drm_connector *connector; 1530235783Skib struct drm_device *dev = encoder->dev; 1531235783Skib 1532235783Skib list_for_each_entry(connector, &dev->mode_config.connector_list, head) 1533235783Skib if (connector->encoder == encoder && connector->eld[0]) 1534235783Skib return connector; 1535235783Skib 1536235783Skib return NULL; 1537235783Skib} 1538235783Skib 1539235783Skib/** 1540235783Skib * drm_detect_hdmi_monitor - detect whether monitor is hdmi. 1541235783Skib * @edid: monitor EDID information 1542235783Skib * 1543235783Skib * Parse the CEA extension according to CEA-861-B. 1544235783Skib * Return true if HDMI, false if not or unknown. 1545235783Skib */ 1546235783Skibbool drm_detect_hdmi_monitor(struct edid *edid) 1547235783Skib{ 1548235783Skib u8 *edid_ext; 1549235783Skib int i, hdmi_id; 1550235783Skib int start_offset, end_offset; 1551235783Skib bool is_hdmi = false; 1552235783Skib 1553235783Skib edid_ext = drm_find_cea_extension(edid); 1554235783Skib if (!edid_ext) 1555235783Skib goto end; 1556235783Skib 1557235783Skib /* Data block offset in CEA extension block */ 1558235783Skib start_offset = 4; 1559235783Skib end_offset = edid_ext[2]; 1560235783Skib 1561235783Skib /* 1562235783Skib * Because HDMI identifier is in Vendor Specific Block, 1563235783Skib * search it from all data blocks of CEA extension. 1564235783Skib */ 1565235783Skib for (i = start_offset; i < end_offset; 1566235783Skib /* Increased by data block len */ 1567235783Skib i += ((edid_ext[i] & 0x1f) + 1)) { 1568235783Skib /* Find vendor specific block */ 1569235783Skib if ((edid_ext[i] >> 5) == VENDOR_BLOCK) { 1570235783Skib hdmi_id = edid_ext[i + 1] | (edid_ext[i + 2] << 8) | 1571235783Skib edid_ext[i + 3] << 16; 1572235783Skib /* Find HDMI identifier */ 1573235783Skib if (hdmi_id == HDMI_IDENTIFIER) 1574235783Skib is_hdmi = true; 1575235783Skib break; 1576235783Skib } 1577235783Skib } 1578235783Skib 1579235783Skibend: 1580235783Skib return is_hdmi; 1581235783Skib} 1582235783Skib 1583235783Skib/** 1584235783Skib * drm_detect_monitor_audio - check monitor audio capability 1585235783Skib * 1586235783Skib * Monitor should have CEA extension block. 1587235783Skib * If monitor has 'basic audio', but no CEA audio blocks, it's 'basic 1588235783Skib * audio' only. If there is any audio extension block and supported 1589235783Skib * audio format, assume at least 'basic audio' support, even if 'basic 1590235783Skib * audio' is not defined in EDID. 1591235783Skib * 1592235783Skib */ 1593235783Skibbool drm_detect_monitor_audio(struct edid *edid) 1594235783Skib{ 1595235783Skib u8 *edid_ext; 1596235783Skib int i, j; 1597235783Skib bool has_audio = false; 1598235783Skib int start_offset, end_offset; 1599235783Skib 1600235783Skib edid_ext = drm_find_cea_extension(edid); 1601235783Skib if (!edid_ext) 1602235783Skib goto end; 1603235783Skib 1604235783Skib has_audio = ((edid_ext[3] & EDID_BASIC_AUDIO) != 0); 1605235783Skib 1606235783Skib if (has_audio) { 1607235783Skib DRM_DEBUG_KMS("Monitor has basic audio support\n"); 1608235783Skib goto end; 1609235783Skib } 1610235783Skib 1611235783Skib /* Data block offset in CEA extension block */ 1612235783Skib start_offset = 4; 1613235783Skib end_offset = edid_ext[2]; 1614235783Skib 1615235783Skib for (i = start_offset; i < end_offset; 1616235783Skib i += ((edid_ext[i] & 0x1f) + 1)) { 1617235783Skib if ((edid_ext[i] >> 5) == AUDIO_BLOCK) { 1618235783Skib has_audio = true; 1619235783Skib for (j = 1; j < (edid_ext[i] & 0x1f); j += 3) 1620235783Skib DRM_DEBUG_KMS("CEA audio format %d\n", 1621235783Skib (edid_ext[i + j] >> 3) & 0xf); 1622235783Skib goto end; 1623235783Skib } 1624235783Skib } 1625235783Skibend: 1626235783Skib return has_audio; 1627235783Skib} 1628235783Skib 1629235783Skib/** 1630235783Skib * drm_add_display_info - pull display info out if present 1631235783Skib * @edid: EDID data 1632235783Skib * @info: display info (attached to connector) 1633235783Skib * 1634235783Skib * Grab any available display info and stuff it into the drm_display_info 1635235783Skib * structure that's part of the connector. Useful for tracking bpp and 1636235783Skib * color spaces. 1637235783Skib */ 1638235783Skibstatic void drm_add_display_info(struct edid *edid, 1639235783Skib struct drm_display_info *info) 1640235783Skib{ 1641235783Skib u8 *edid_ext; 1642235783Skib 1643235783Skib info->width_mm = edid->width_cm * 10; 1644235783Skib info->height_mm = edid->height_cm * 10; 1645235783Skib 1646235783Skib /* driver figures it out in this case */ 1647235783Skib info->bpc = 0; 1648235783Skib info->color_formats = 0; 1649235783Skib 1650235783Skib /* Only defined for 1.4 with digital displays */ 1651235783Skib if (edid->revision < 4) 1652235783Skib return; 1653235783Skib 1654235783Skib if (!(edid->input & DRM_EDID_INPUT_DIGITAL)) 1655235783Skib return; 1656235783Skib 1657235783Skib switch (edid->input & DRM_EDID_DIGITAL_DEPTH_MASK) { 1658235783Skib case DRM_EDID_DIGITAL_DEPTH_6: 1659235783Skib info->bpc = 6; 1660235783Skib break; 1661235783Skib case DRM_EDID_DIGITAL_DEPTH_8: 1662235783Skib info->bpc = 8; 1663235783Skib break; 1664235783Skib case DRM_EDID_DIGITAL_DEPTH_10: 1665235783Skib info->bpc = 10; 1666235783Skib break; 1667235783Skib case DRM_EDID_DIGITAL_DEPTH_12: 1668235783Skib info->bpc = 12; 1669235783Skib break; 1670235783Skib case DRM_EDID_DIGITAL_DEPTH_14: 1671235783Skib info->bpc = 14; 1672235783Skib break; 1673235783Skib case DRM_EDID_DIGITAL_DEPTH_16: 1674235783Skib info->bpc = 16; 1675235783Skib break; 1676235783Skib case DRM_EDID_DIGITAL_DEPTH_UNDEF: 1677235783Skib default: 1678235783Skib info->bpc = 0; 1679235783Skib break; 1680235783Skib } 1681235783Skib 1682235783Skib info->color_formats = DRM_COLOR_FORMAT_RGB444; 1683235783Skib if (info->color_formats & DRM_EDID_FEATURE_RGB_YCRCB444) 1684235783Skib info->color_formats = DRM_COLOR_FORMAT_YCRCB444; 1685235783Skib if (info->color_formats & DRM_EDID_FEATURE_RGB_YCRCB422) 1686235783Skib info->color_formats = DRM_COLOR_FORMAT_YCRCB422; 1687235783Skib 1688235783Skib /* Get data from CEA blocks if present */ 1689235783Skib edid_ext = drm_find_cea_extension(edid); 1690235783Skib if (!edid_ext) 1691235783Skib return; 1692235783Skib 1693235783Skib info->cea_rev = edid_ext[1]; 1694235783Skib} 1695235783Skib 1696235783Skib/** 1697235783Skib * drm_add_edid_modes - add modes from EDID data, if available 1698235783Skib * @connector: connector we're probing 1699235783Skib * @edid: edid data 1700235783Skib * 1701235783Skib * Add the specified modes to the connector's mode list. 1702235783Skib * 1703235783Skib * Return number of modes added or 0 if we couldn't find any. 1704235783Skib */ 1705235783Skibint drm_add_edid_modes(struct drm_connector *connector, struct edid *edid) 1706235783Skib{ 1707235783Skib int num_modes = 0; 1708235783Skib u32 quirks; 1709235783Skib 1710235783Skib if (edid == NULL) { 1711235783Skib return 0; 1712235783Skib } 1713235783Skib if (!drm_edid_is_valid(edid)) { 1714235783Skib device_printf(connector->dev->device, "%s: EDID invalid.\n", 1715235783Skib drm_get_connector_name(connector)); 1716235783Skib return 0; 1717235783Skib } 1718235783Skib 1719235783Skib quirks = edid_get_quirks(edid); 1720235783Skib 1721235783Skib /* 1722235783Skib * EDID spec says modes should be preferred in this order: 1723235783Skib * - preferred detailed mode 1724235783Skib * - other detailed modes from base block 1725235783Skib * - detailed modes from extension blocks 1726235783Skib * - CVT 3-byte code modes 1727235783Skib * - standard timing codes 1728235783Skib * - established timing codes 1729235783Skib * - modes inferred from GTF or CVT range information 1730235783Skib * 1731235783Skib * We get this pretty much right. 1732235783Skib * 1733235783Skib * XXX order for additional mode types in extension blocks? 1734235783Skib */ 1735235783Skib num_modes += add_detailed_modes(connector, edid, quirks); 1736235783Skib num_modes += add_cvt_modes(connector, edid); 1737235783Skib num_modes += add_standard_modes(connector, edid); 1738235783Skib num_modes += add_established_modes(connector, edid); 1739235783Skib num_modes += add_inferred_modes(connector, edid); 1740235783Skib 1741235783Skib if (quirks & (EDID_QUIRK_PREFER_LARGE_60 | EDID_QUIRK_PREFER_LARGE_75)) 1742235783Skib edid_fixup_preferred(connector, quirks); 1743235783Skib 1744235783Skib drm_add_display_info(edid, &connector->display_info); 1745235783Skib 1746235783Skib return num_modes; 1747235783Skib} 1748235783Skib 1749235783Skib/** 1750235783Skib * drm_add_modes_noedid - add modes for the connectors without EDID 1751235783Skib * @connector: connector we're probing 1752235783Skib * @hdisplay: the horizontal display limit 1753235783Skib * @vdisplay: the vertical display limit 1754235783Skib * 1755235783Skib * Add the specified modes to the connector's mode list. Only when the 1756235783Skib * hdisplay/vdisplay is not beyond the given limit, it will be added. 1757235783Skib * 1758235783Skib * Return number of modes added or 0 if we couldn't find any. 1759235783Skib */ 1760235783Skibint drm_add_modes_noedid(struct drm_connector *connector, 1761235783Skib int hdisplay, int vdisplay) 1762235783Skib{ 1763235783Skib int i, count, num_modes = 0; 1764235783Skib struct drm_display_mode *mode; 1765235783Skib struct drm_device *dev = connector->dev; 1766235783Skib 1767235783Skib count = sizeof(drm_dmt_modes) / sizeof(struct drm_display_mode); 1768235783Skib if (hdisplay < 0) 1769235783Skib hdisplay = 0; 1770235783Skib if (vdisplay < 0) 1771235783Skib vdisplay = 0; 1772235783Skib 1773235783Skib for (i = 0; i < count; i++) { 1774235783Skib struct drm_display_mode *ptr = &drm_dmt_modes[i]; 1775235783Skib if (hdisplay && vdisplay) { 1776235783Skib /* 1777235783Skib * Only when two are valid, they will be used to check 1778235783Skib * whether the mode should be added to the mode list of 1779235783Skib * the connector. 1780235783Skib */ 1781235783Skib if (ptr->hdisplay > hdisplay || 1782235783Skib ptr->vdisplay > vdisplay) 1783235783Skib continue; 1784235783Skib } 1785235783Skib if (drm_mode_vrefresh(ptr) > 61) 1786235783Skib continue; 1787235783Skib mode = drm_mode_duplicate(dev, ptr); 1788235783Skib if (mode) { 1789235783Skib drm_mode_probed_add(connector, mode); 1790235783Skib num_modes++; 1791235783Skib } 1792235783Skib } 1793235783Skib return num_modes; 1794235783Skib} 1795