1 /* 2 * QEMU EDID generator. 3 * 4 * This work is licensed under the terms of the GNU GPL, version 2 or later. 5 * See the COPYING file in the top-level directory. 6 */ 7 #include "qemu/osdep.h" 8 #include "qemu/bswap.h" 9 #include "hw/display/edid.h" 10 11 static const struct edid_mode { 12 uint32_t xres; 13 uint32_t yres; 14 uint32_t byte; 15 uint32_t xtra3; 16 uint32_t bit; 17 uint32_t dta; 18 } modes[] = { 19 /* dea/dta extension timings (all @ 50 Hz) */ 20 { .xres = 5120, .yres = 2160, .dta = 125 }, 21 { .xres = 4096, .yres = 2160, .dta = 101 }, 22 { .xres = 3840, .yres = 2160, .dta = 96 }, 23 { .xres = 2560, .yres = 1080, .dta = 89 }, 24 { .xres = 2048, .yres = 1152 }, 25 { .xres = 1920, .yres = 1080, .dta = 31 }, 26 27 /* dea/dta extension timings (all @ 60 Hz) */ 28 { .xres = 3840, .yres = 2160, .dta = 97 }, 29 30 /* additional standard timings 3 (all @ 60Hz) */ 31 { .xres = 1920, .yres = 1200, .xtra3 = 10, .bit = 0 }, 32 { .xres = 1600, .yres = 1200, .xtra3 = 9, .bit = 2 }, 33 { .xres = 1680, .yres = 1050, .xtra3 = 9, .bit = 5 }, 34 { .xres = 1440, .yres = 900, .xtra3 = 8, .bit = 5 }, 35 { .xres = 1280, .yres = 1024, .xtra3 = 7, .bit = 1 }, 36 { .xres = 1280, .yres = 960, .xtra3 = 7, .bit = 3 }, 37 { .xres = 1280, .yres = 768, .xtra3 = 7, .bit = 6 }, 38 39 { .xres = 1920, .yres = 1440, .xtra3 = 11, .bit = 5 }, 40 { .xres = 1856, .yres = 1392, .xtra3 = 10, .bit = 3 }, 41 { .xres = 1792, .yres = 1344, .xtra3 = 10, .bit = 5 }, 42 { .xres = 1440, .yres = 1050, .xtra3 = 8, .bit = 1 }, 43 { .xres = 1360, .yres = 768, .xtra3 = 8, .bit = 7 }, 44 45 /* established timings (all @ 60Hz) */ 46 { .xres = 1024, .yres = 768, .byte = 36, .bit = 3 }, 47 { .xres = 800, .yres = 600, .byte = 35, .bit = 0 }, 48 { .xres = 640, .yres = 480, .byte = 35, .bit = 5 }, 49 }; 50 51 typedef struct Timings { 52 uint32_t xfront; 53 uint32_t xsync; 54 uint32_t xblank; 55 56 uint32_t yfront; 57 uint32_t ysync; 58 uint32_t yblank; 59 60 uint64_t clock; 61 } Timings; 62 63 static void generate_timings(Timings *timings, uint32_t refresh_rate, 64 uint32_t xres, uint32_t yres) 65 { 66 /* pull some realistic looking timings out of thin air */ 67 timings->xfront = xres * 25 / 100; 68 timings->xsync = xres * 3 / 100; 69 timings->xblank = xres * 35 / 100; 70 71 timings->yfront = yres * 5 / 1000; 72 timings->ysync = yres * 5 / 1000; 73 timings->yblank = yres * 35 / 1000; 74 75 timings->clock = ((uint64_t)refresh_rate * 76 (xres + timings->xblank) * 77 (yres + timings->yblank)) / 10000000; 78 } 79 80 static void edid_ext_dta(uint8_t *dta) 81 { 82 dta[0] = 0x02; 83 dta[1] = 0x03; 84 dta[2] = 0x05; 85 dta[3] = 0x00; 86 87 /* video data block */ 88 dta[4] = 0x40; 89 } 90 91 static void edid_ext_dta_mode(uint8_t *dta, uint8_t nr) 92 { 93 dta[dta[2]] = nr; 94 dta[2]++; 95 dta[4]++; 96 } 97 98 static int edid_std_mode(uint8_t *mode, uint32_t xres, uint32_t yres) 99 { 100 uint32_t aspect; 101 102 if (xres == 0 || yres == 0) { 103 mode[0] = 0x01; 104 mode[1] = 0x01; 105 return 0; 106 107 } else if (xres * 10 == yres * 16) { 108 aspect = 0; 109 } else if (xres * 3 == yres * 4) { 110 aspect = 1; 111 } else if (xres * 4 == yres * 5) { 112 aspect = 2; 113 } else if (xres * 9 == yres * 16) { 114 aspect = 3; 115 } else { 116 return -1; 117 } 118 119 if ((xres / 8) - 31 > 255) { 120 return -1; 121 } 122 123 mode[0] = (xres / 8) - 31; 124 mode[1] = ((aspect << 6) | (60 - 60)); 125 return 0; 126 } 127 128 static void edid_fill_modes(uint8_t *edid, uint8_t *xtra3, uint8_t *dta, 129 uint32_t maxx, uint32_t maxy) 130 { 131 const struct edid_mode *mode; 132 int std = 38; 133 int rc, i; 134 135 for (i = 0; i < ARRAY_SIZE(modes); i++) { 136 mode = modes + i; 137 138 if ((maxx && mode->xres > maxx) || 139 (maxy && mode->yres > maxy)) { 140 continue; 141 } 142 143 if (mode->byte) { 144 edid[mode->byte] |= (1 << mode->bit); 145 } else if (std < 54) { 146 rc = edid_std_mode(edid + std, mode->xres, mode->yres); 147 if (rc == 0) { 148 std += 2; 149 } 150 } else if (mode->xtra3 && xtra3) { 151 xtra3[mode->xtra3] |= (1 << mode->bit); 152 } 153 154 if (dta && mode->dta) { 155 edid_ext_dta_mode(dta, mode->dta); 156 } 157 } 158 159 while (std < 54) { 160 edid_std_mode(edid + std, 0, 0); 161 std += 2; 162 } 163 } 164 165 static void edid_checksum(uint8_t *edid, size_t len) 166 { 167 uint32_t sum = 0; 168 int i; 169 170 for (i = 0; i < len; i++) { 171 sum += edid[i]; 172 } 173 sum &= 0xff; 174 if (sum) { 175 edid[len] = 0x100 - sum; 176 } 177 } 178 179 static uint8_t *edid_desc_next(uint8_t *edid, uint8_t *dta, uint8_t *desc) 180 { 181 if (desc == NULL) { 182 return NULL; 183 } 184 if (desc + 18 + 18 < edid + 127) { 185 return desc + 18; 186 } 187 if (dta) { 188 if (desc < edid + 127) { 189 return dta + dta[2]; 190 } 191 if (desc + 18 + 18 < dta + 127) { 192 return desc + 18; 193 } 194 } 195 return NULL; 196 } 197 198 static void edid_desc_type(uint8_t *desc, uint8_t type) 199 { 200 desc[0] = 0; 201 desc[1] = 0; 202 desc[2] = 0; 203 desc[3] = type; 204 desc[4] = 0; 205 } 206 207 static void edid_desc_text(uint8_t *desc, uint8_t type, 208 const char *text) 209 { 210 size_t len; 211 212 edid_desc_type(desc, type); 213 memset(desc + 5, ' ', 13); 214 215 len = strlen(text); 216 if (len > 12) { 217 len = 12; 218 } 219 memcpy(desc + 5, text, len); 220 desc[5 + len] = '\n'; 221 } 222 223 static void edid_desc_ranges(uint8_t *desc) 224 { 225 edid_desc_type(desc, 0xfd); 226 227 /* vertical (50 -> 125 Hz) */ 228 desc[5] = 50; 229 desc[6] = 125; 230 231 /* horizontal (30 -> 160 kHz) */ 232 desc[7] = 30; 233 desc[8] = 160; 234 235 /* max dot clock (2550 MHz) */ 236 desc[9] = 2550 / 10; 237 238 /* no extended timing information */ 239 desc[10] = 0x01; 240 241 /* padding */ 242 desc[11] = '\n'; 243 memset(desc + 12, ' ', 6); 244 } 245 246 /* additional standard timings 3 */ 247 static void edid_desc_xtra3_std(uint8_t *desc) 248 { 249 edid_desc_type(desc, 0xf7); 250 desc[5] = 10; 251 } 252 253 static void edid_desc_dummy(uint8_t *desc) 254 { 255 edid_desc_type(desc, 0x10); 256 } 257 258 static void edid_desc_timing(uint8_t *desc, uint32_t refresh_rate, 259 uint32_t xres, uint32_t yres, 260 uint32_t xmm, uint32_t ymm) 261 { 262 Timings timings; 263 generate_timings(&timings, refresh_rate, xres, yres); 264 stl_le_p(desc, timings.clock); 265 266 desc[2] = xres & 0xff; 267 desc[3] = timings.xblank & 0xff; 268 desc[4] = (((xres & 0xf00) >> 4) | 269 ((timings.xblank & 0xf00) >> 8)); 270 271 desc[5] = yres & 0xff; 272 desc[6] = timings.yblank & 0xff; 273 desc[7] = (((yres & 0xf00) >> 4) | 274 ((timings.yblank & 0xf00) >> 8)); 275 276 desc[8] = timings.xfront & 0xff; 277 desc[9] = timings.xsync & 0xff; 278 279 desc[10] = (((timings.yfront & 0x00f) << 4) | 280 ((timings.ysync & 0x00f) << 0)); 281 desc[11] = (((timings.xfront & 0x300) >> 2) | 282 ((timings.xsync & 0x300) >> 4) | 283 ((timings.yfront & 0x030) >> 2) | 284 ((timings.ysync & 0x030) >> 4)); 285 286 desc[12] = xmm & 0xff; 287 desc[13] = ymm & 0xff; 288 desc[14] = (((xmm & 0xf00) >> 4) | 289 ((ymm & 0xf00) >> 8)); 290 291 desc[17] = 0x18; 292 } 293 294 static uint32_t edid_to_10bit(float value) 295 { 296 return (uint32_t)(value * 1024 + 0.5); 297 } 298 299 static void edid_colorspace(uint8_t *edid, 300 float rx, float ry, 301 float gx, float gy, 302 float bx, float by, 303 float wx, float wy) 304 { 305 uint32_t red_x = edid_to_10bit(rx); 306 uint32_t red_y = edid_to_10bit(ry); 307 uint32_t green_x = edid_to_10bit(gx); 308 uint32_t green_y = edid_to_10bit(gy); 309 uint32_t blue_x = edid_to_10bit(bx); 310 uint32_t blue_y = edid_to_10bit(by); 311 uint32_t white_x = edid_to_10bit(wx); 312 uint32_t white_y = edid_to_10bit(wy); 313 314 edid[25] = (((red_x & 0x03) << 6) | 315 ((red_y & 0x03) << 4) | 316 ((green_x & 0x03) << 2) | 317 ((green_y & 0x03) << 0)); 318 edid[26] = (((blue_x & 0x03) << 6) | 319 ((blue_y & 0x03) << 4) | 320 ((white_x & 0x03) << 2) | 321 ((white_y & 0x03) << 0)); 322 edid[27] = red_x >> 2; 323 edid[28] = red_y >> 2; 324 edid[29] = green_x >> 2; 325 edid[30] = green_y >> 2; 326 edid[31] = blue_x >> 2; 327 edid[32] = blue_y >> 2; 328 edid[33] = white_x >> 2; 329 edid[34] = white_y >> 2; 330 } 331 332 static uint32_t qemu_edid_dpi_from_mm(uint32_t mm, uint32_t res) 333 { 334 return res * 254 / 10 / mm; 335 } 336 337 uint32_t qemu_edid_dpi_to_mm(uint32_t dpi, uint32_t res) 338 { 339 return res * 254 / 10 / dpi; 340 } 341 342 static void init_displayid(uint8_t *did) 343 { 344 did[0] = 0x70; /* display id extension */ 345 did[1] = 0x13; /* version 1.3 */ 346 did[2] = 4; /* length */ 347 did[3] = 0x03; /* product type (0x03 == standalone display device) */ 348 edid_checksum(did + 1, did[2] + 4); 349 } 350 351 static void qemu_displayid_generate(uint8_t *did, uint32_t refresh_rate, 352 uint32_t xres, uint32_t yres, 353 uint32_t xmm, uint32_t ymm) 354 { 355 Timings timings; 356 generate_timings(&timings, refresh_rate, xres, yres); 357 358 did[0] = 0x70; /* display id extension */ 359 did[1] = 0x13; /* version 1.3 */ 360 did[2] = 23; /* length */ 361 did[3] = 0x03; /* product type (0x03 == standalone display device) */ 362 363 did[5] = 0x03; /* Detailed Timings Data Block */ 364 did[6] = 0x00; /* revision */ 365 did[7] = 0x14; /* block length */ 366 367 did[8] = timings.clock & 0xff; 368 did[9] = (timings.clock & 0xff00) >> 8; 369 did[10] = (timings.clock & 0xff0000) >> 16; 370 371 did[11] = 0x88; /* leave aspect ratio undefined */ 372 373 stw_le_p(did + 12, 0xffff & (xres - 1)); 374 stw_le_p(did + 14, 0xffff & (timings.xblank - 1)); 375 stw_le_p(did + 16, 0xffff & (timings.xfront - 1)); 376 stw_le_p(did + 18, 0xffff & (timings.xsync - 1)); 377 378 stw_le_p(did + 20, 0xffff & (yres - 1)); 379 stw_le_p(did + 22, 0xffff & (timings.yblank - 1)); 380 stw_le_p(did + 24, 0xffff & (timings.yfront - 1)); 381 stw_le_p(did + 26, 0xffff & (timings.ysync - 1)); 382 383 edid_checksum(did + 1, did[2] + 4); 384 } 385 386 void qemu_edid_generate(uint8_t *edid, size_t size, 387 qemu_edid_info *info) 388 { 389 uint8_t *desc = edid + 54; 390 uint8_t *xtra3 = NULL; 391 uint8_t *dta = NULL; 392 uint8_t *did = NULL; 393 uint32_t width_mm, height_mm; 394 uint32_t refresh_rate = info->refresh_rate ? info->refresh_rate : 75000; 395 uint32_t dpi = 100; /* if no width_mm/height_mm */ 396 uint32_t large_screen = 0; 397 398 /* =============== set defaults =============== */ 399 400 if (!info->vendor || strlen(info->vendor) != 3) { 401 info->vendor = "RHT"; 402 } 403 if (!info->name) { 404 info->name = "QEMU Monitor"; 405 } 406 if (!info->prefx) { 407 info->prefx = 1280; 408 } 409 if (!info->prefy) { 410 info->prefy = 800; 411 } 412 if (info->prefx >= 4096 || info->prefy >= 4096) { 413 large_screen = 1; 414 } 415 if (info->width_mm && info->height_mm) { 416 width_mm = info->width_mm; 417 height_mm = info->height_mm; 418 dpi = qemu_edid_dpi_from_mm(width_mm, info->prefx); 419 } else { 420 width_mm = qemu_edid_dpi_to_mm(dpi, info->prefx); 421 height_mm = qemu_edid_dpi_to_mm(dpi, info->prefy); 422 } 423 424 /* =============== extensions =============== */ 425 426 if (size >= 256) { 427 dta = edid + 128; 428 edid[126]++; 429 edid_ext_dta(dta); 430 } 431 432 if (size >= 384 && large_screen) { 433 did = edid + 256; 434 edid[126]++; 435 init_displayid(did); 436 } 437 438 /* =============== header information =============== */ 439 440 /* fixed */ 441 edid[0] = 0x00; 442 edid[1] = 0xff; 443 edid[2] = 0xff; 444 edid[3] = 0xff; 445 edid[4] = 0xff; 446 edid[5] = 0xff; 447 edid[6] = 0xff; 448 edid[7] = 0x00; 449 450 /* manufacturer id, product code, serial number */ 451 uint16_t vendor_id = ((((info->vendor[0] - '@') & 0x1f) << 10) | 452 (((info->vendor[1] - '@') & 0x1f) << 5) | 453 (((info->vendor[2] - '@') & 0x1f) << 0)); 454 uint16_t model_nr = 0x1234; 455 uint32_t serial_nr = info->serial ? atoi(info->serial) : 0; 456 stw_be_p(edid + 8, vendor_id); 457 stw_le_p(edid + 10, model_nr); 458 stl_le_p(edid + 12, serial_nr); 459 460 /* manufacture week and year */ 461 edid[16] = 42; 462 edid[17] = 2014 - 1990; 463 464 /* edid version */ 465 edid[18] = 1; 466 edid[19] = 4; 467 468 469 /* =============== basic display parameters =============== */ 470 471 /* video input: digital, 8bpc, displayport */ 472 edid[20] = 0xa5; 473 474 /* screen size: undefined */ 475 edid[21] = width_mm / 10; 476 edid[22] = height_mm / 10; 477 478 /* display gamma: 2.2 */ 479 edid[23] = 220 - 100; 480 481 /* supported features bitmap: std sRGB, preferred timing */ 482 edid[24] = 0x06; 483 484 485 /* =============== chromaticity coordinates =============== */ 486 487 /* standard sRGB colorspace */ 488 edid_colorspace(edid, 489 0.6400, 0.3300, /* red */ 490 0.3000, 0.6000, /* green */ 491 0.1500, 0.0600, /* blue */ 492 0.3127, 0.3290); /* white point */ 493 494 /* =============== established timing bitmap =============== */ 495 /* =============== standard timing information =============== */ 496 497 /* both filled by edid_fill_modes() */ 498 499 500 /* =============== descriptor blocks =============== */ 501 502 if (!large_screen) { 503 /* The DTD section has only 12 bits to store the resolution */ 504 edid_desc_timing(desc, refresh_rate, info->prefx, info->prefy, 505 width_mm, height_mm); 506 desc = edid_desc_next(edid, dta, desc); 507 } 508 509 xtra3 = desc; 510 edid_desc_xtra3_std(xtra3); 511 desc = edid_desc_next(edid, dta, desc); 512 edid_fill_modes(edid, xtra3, dta, info->maxx, info->maxy); 513 /* 514 * dta video data block is finished at thus point, 515 * so dta descriptor offsets don't move any more. 516 */ 517 518 edid_desc_ranges(desc); 519 desc = edid_desc_next(edid, dta, desc); 520 521 if (desc && info->name) { 522 edid_desc_text(desc, 0xfc, info->name); 523 desc = edid_desc_next(edid, dta, desc); 524 } 525 526 if (desc && info->serial) { 527 edid_desc_text(desc, 0xff, info->serial); 528 desc = edid_desc_next(edid, dta, desc); 529 } 530 531 while (desc) { 532 edid_desc_dummy(desc); 533 desc = edid_desc_next(edid, dta, desc); 534 } 535 536 /* =============== display id extensions =============== */ 537 538 if (did && large_screen) { 539 qemu_displayid_generate(did, refresh_rate, info->prefx, info->prefy, 540 width_mm, height_mm); 541 } 542 543 /* =============== finish up =============== */ 544 545 edid_checksum(edid, 127); 546 if (dta) { 547 edid_checksum(dta, 127); 548 } 549 if (did) { 550 edid_checksum(did, 127); 551 } 552 } 553 554 size_t qemu_edid_size(uint8_t *edid) 555 { 556 uint32_t exts; 557 558 if (edid[0] != 0x00 || 559 edid[1] != 0xff) { 560 /* doesn't look like a valid edid block */ 561 return 0; 562 } 563 564 exts = edid[126]; 565 return 128 * (exts + 1); 566 } 567