14642e01fSmrg/* 205b261ecSmrg * Copyright 1998 by Egbert Eich <Egbert.Eich@Physik.TU-Darmstadt.DE> 34642e01fSmrg * Copyright 2007 Red Hat, Inc. 44642e01fSmrg * 54642e01fSmrg * Permission is hereby granted, free of charge, to any person obtaining a 66747b715Smrg * copy of this software and associated documentation files (the "Software"), 76747b715Smrg * to deal in the Software without restriction, including without limitation 86747b715Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 96747b715Smrg * and/or sell copies of the Software, and to permit persons to whom the 106747b715Smrg * Software is furnished to do so, subject to the following conditions: 114642e01fSmrg * 124642e01fSmrg * The above copyright notice and this permission notice (including the next 134642e01fSmrg * paragraph) shall be included in all copies or substantial portions of the 144642e01fSmrg * Software. 154642e01fSmrg * 164642e01fSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 176747b715Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 186747b715Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 196747b715Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 206747b715Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 216747b715Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 226747b715Smrg * DEALINGS IN THE SOFTWARE. 234642e01fSmrg * 2435c4bbdfSmrg * print_edid.c: print out all information retrieved from display device 2505b261ecSmrg */ 264642e01fSmrg 2705b261ecSmrg#ifdef HAVE_XORG_CONFIG_H 2805b261ecSmrg#include <xorg-config.h> 2905b261ecSmrg#endif 3005b261ecSmrg 314642e01fSmrg/* XXX kinda gross */ 324642e01fSmrg#define _PARSE_EDID_ 334642e01fSmrg 3405b261ecSmrg#include "misc.h" 3505b261ecSmrg#include "xf86.h" 3605b261ecSmrg#include "xf86_OSproc.h" 3705b261ecSmrg#include "xf86DDC.h" 384642e01fSmrg#include "edid.h" 3935c4bbdfSmrg 4005b261ecSmrg#define EDID_WIDTH 16 4135c4bbdfSmrg 4205b261ecSmrgstatic void 4305b261ecSmrgprint_vendor(int scrnIndex, struct vendor *c) 4405b261ecSmrg{ 4505b261ecSmrg xf86DrvMsg(scrnIndex, X_INFO, "Manufacturer: %s Model: %x Serial#: %u\n", 4635c4bbdfSmrg (char *) &c->name, c->prod_id, c->serial); 4705b261ecSmrg xf86DrvMsg(scrnIndex, X_INFO, "Year: %u Week: %u\n", c->year, c->week); 4805b261ecSmrg} 494642e01fSmrg 5005b261ecSmrgstatic void 5105b261ecSmrgprint_version(int scrnIndex, struct edid_version *c) 5205b261ecSmrg{ 5335c4bbdfSmrg xf86DrvMsg(scrnIndex, X_INFO, "EDID Version: %u.%u\n", c->version, 5435c4bbdfSmrg c->revision); 5505b261ecSmrg} 5635c4bbdfSmrg 574642e01fSmrgstatic const char *digital_interfaces[] = { 584642e01fSmrg "undefined", 594642e01fSmrg "DVI", 604642e01fSmrg "HDMI-a", 614642e01fSmrg "HDMI-b", 624642e01fSmrg "MDDI", 634642e01fSmrg "DisplayPort", 644642e01fSmrg "unknown" 654642e01fSmrg}; 664642e01fSmrg 6735c4bbdfSmrgstatic void 684642e01fSmrgprint_input_features(int scrnIndex, struct disp_features *c, 6935c4bbdfSmrg struct edid_version *v) 7005b261ecSmrg{ 7105b261ecSmrg if (DIGITAL(c->input_type)) { 7235c4bbdfSmrg xf86DrvMsg(scrnIndex, X_INFO, "Digital Display Input\n"); 7335c4bbdfSmrg if (v->revision == 2 || v->revision == 3) { 7435c4bbdfSmrg if (DFP1(c->input_dfp)) 7535c4bbdfSmrg xf86DrvMsg(scrnIndex, X_INFO, "DFP 1.x compatible TMDS\n"); 7635c4bbdfSmrg } 7735c4bbdfSmrg else if (v->revision >= 4) { 7835c4bbdfSmrg int interface = c->input_interface; 7935c4bbdfSmrg int bpc = c->input_bpc; 8035c4bbdfSmrg 8135c4bbdfSmrg if (interface > 6) 8235c4bbdfSmrg interface = 6; /* unknown */ 8335c4bbdfSmrg if (bpc == 0 || bpc == 7) 8435c4bbdfSmrg xf86DrvMsg(scrnIndex, X_INFO, "Undefined color depth\n"); 8535c4bbdfSmrg else 8635c4bbdfSmrg xf86DrvMsg(scrnIndex, X_INFO, "%d bits per channel\n", 8735c4bbdfSmrg bpc * 2 + 4); 8835c4bbdfSmrg xf86DrvMsg(scrnIndex, X_INFO, "Digital interface is %s\n", 8935c4bbdfSmrg digital_interfaces[interface]); 9035c4bbdfSmrg } 9135c4bbdfSmrg } 9235c4bbdfSmrg else { 9335c4bbdfSmrg xf86DrvMsg(scrnIndex, X_INFO, "Analog Display Input, "); 9435c4bbdfSmrg xf86ErrorF("Input Voltage Level: "); 9535c4bbdfSmrg switch (c->input_voltage) { 9635c4bbdfSmrg case V070: 9735c4bbdfSmrg xf86ErrorF("0.700/0.300 V\n"); 9835c4bbdfSmrg break; 9935c4bbdfSmrg case V071: 10035c4bbdfSmrg xf86ErrorF("0.714/0.286 V\n"); 10135c4bbdfSmrg break; 10235c4bbdfSmrg case V100: 10335c4bbdfSmrg xf86ErrorF("1.000/0.400 V\n"); 10435c4bbdfSmrg break; 10535c4bbdfSmrg case V007: 10605b261ecSmrg xf86ErrorF("0.700/0.700 V\n"); 10735c4bbdfSmrg break; 10835c4bbdfSmrg default: 10935c4bbdfSmrg xf86ErrorF("undefined\n"); 11035c4bbdfSmrg } 11135c4bbdfSmrg if (SIG_SETUP(c->input_setup)) 11235c4bbdfSmrg xf86DrvMsg(scrnIndex, X_INFO, "Signal levels configurable\n"); 11335c4bbdfSmrg xf86DrvMsg(scrnIndex, X_INFO, "Sync:"); 11435c4bbdfSmrg if (SEP_SYNC(c->input_sync)) 11535c4bbdfSmrg xf86ErrorF(" Separate"); 11635c4bbdfSmrg if (COMP_SYNC(c->input_sync)) 11735c4bbdfSmrg xf86ErrorF(" Composite"); 11835c4bbdfSmrg if (SYNC_O_GREEN(c->input_sync)) 11935c4bbdfSmrg xf86ErrorF(" SyncOnGreen"); 12035c4bbdfSmrg if (SYNC_SERR(c->input_sync)) 12135c4bbdfSmrg xf86ErrorF("Serration on. " 12235c4bbdfSmrg "V.Sync Pulse req. if CompSync or SyncOnGreen\n"); 12335c4bbdfSmrg else 12435c4bbdfSmrg xf86ErrorF("\n"); 12505b261ecSmrg } 12605b261ecSmrg} 12735c4bbdfSmrg 12835c4bbdfSmrgstatic void 12905b261ecSmrgprint_dpms_features(int scrnIndex, struct disp_features *c, 13035c4bbdfSmrg struct edid_version *v) 13105b261ecSmrg{ 13235c4bbdfSmrg if (c->dpms) { 13335c4bbdfSmrg xf86DrvMsg(scrnIndex, X_INFO, "DPMS capabilities:"); 13435c4bbdfSmrg if (DPMS_STANDBY(c->dpms)) 13535c4bbdfSmrg xf86ErrorF(" StandBy"); 13635c4bbdfSmrg if (DPMS_SUSPEND(c->dpms)) 13735c4bbdfSmrg xf86ErrorF(" Suspend"); 13835c4bbdfSmrg if (DPMS_OFF(c->dpms)) 13935c4bbdfSmrg xf86ErrorF(" Off"); 14035c4bbdfSmrg } 14135c4bbdfSmrg else 14235c4bbdfSmrg xf86DrvMsg(scrnIndex, X_INFO, "No DPMS capabilities specified"); 14335c4bbdfSmrg if (!c->input_type) { /* analog */ 14435c4bbdfSmrg switch (c->display_type) { 14535c4bbdfSmrg case DISP_MONO: 146ed6184dfSmrg xf86ErrorF("; Monochrome/GrayScale Display\n"); 14735c4bbdfSmrg break; 14835c4bbdfSmrg case DISP_RGB: 14935c4bbdfSmrg xf86ErrorF("; RGB/Color Display\n"); 15035c4bbdfSmrg break; 15135c4bbdfSmrg case DISP_MULTCOLOR: 15235c4bbdfSmrg xf86ErrorF("; Non RGB Multicolor Display\n"); 15335c4bbdfSmrg break; 15435c4bbdfSmrg default: 15535c4bbdfSmrg xf86ErrorF("\n"); 15635c4bbdfSmrg break; 15735c4bbdfSmrg } 15835c4bbdfSmrg } 15935c4bbdfSmrg else { 16035c4bbdfSmrg int enc = c->display_type; 16135c4bbdfSmrg 16235c4bbdfSmrg xf86ErrorF("\n"); 16335c4bbdfSmrg xf86DrvMsg(scrnIndex, X_INFO, "Supported color encodings: " 16435c4bbdfSmrg "RGB 4:4:4 %s%s\n", 16535c4bbdfSmrg enc & DISP_YCRCB444 ? "YCrCb 4:4:4 " : "", 16635c4bbdfSmrg enc & DISP_YCRCB422 ? "YCrCb 4:2:2" : ""); 16705b261ecSmrg } 1684642e01fSmrg 16905b261ecSmrg if (STD_COLOR_SPACE(c->msc)) 17035c4bbdfSmrg xf86DrvMsg(scrnIndex, X_INFO, 17135c4bbdfSmrg "Default color space is primary color space\n"); 1724642e01fSmrg 1734642e01fSmrg if (PREFERRED_TIMING_MODE(c->msc) || v->revision >= 4) { 17435c4bbdfSmrg xf86DrvMsg(scrnIndex, X_INFO, 17535c4bbdfSmrg "First detailed timing is preferred mode\n"); 17635c4bbdfSmrg if (v->revision >= 4) 17735c4bbdfSmrg xf86DrvMsg(scrnIndex, X_INFO, 17835c4bbdfSmrg "Preferred mode is native pixel format and refresh rate\n"); 17935c4bbdfSmrg } 18035c4bbdfSmrg else if (v->revision == 3) { 18135c4bbdfSmrg xf86DrvMsg(scrnIndex, X_INFO, 18235c4bbdfSmrg "First detailed timing not preferred " 18335c4bbdfSmrg "mode in violation of standard!\n"); 1844642e01fSmrg } 1854642e01fSmrg 1864642e01fSmrg if (v->revision >= 4) { 18735c4bbdfSmrg if (GFT_SUPPORTED(c->msc)) { 18835c4bbdfSmrg xf86DrvMsg(scrnIndex, X_INFO, "Display is continuous-frequency\n"); 18935c4bbdfSmrg } 19035c4bbdfSmrg } 19135c4bbdfSmrg else { 19235c4bbdfSmrg if (GFT_SUPPORTED(c->msc)) 19335c4bbdfSmrg xf86DrvMsg(scrnIndex, X_INFO, "GTF timings supported\n"); 1944642e01fSmrg } 19505b261ecSmrg} 19635c4bbdfSmrg 19735c4bbdfSmrgstatic void 19805b261ecSmrgprint_whitepoint(int scrnIndex, struct disp_features *disp) 19905b261ecSmrg{ 20035c4bbdfSmrg xf86DrvMsg(scrnIndex, X_INFO, "redX: %.3f redY: %.3f ", 20135c4bbdfSmrg disp->redx, disp->redy); 20235c4bbdfSmrg xf86ErrorF("greenX: %.3f greenY: %.3f\n", disp->greenx, disp->greeny); 20335c4bbdfSmrg xf86DrvMsg(scrnIndex, X_INFO, "blueX: %.3f blueY: %.3f ", 20435c4bbdfSmrg disp->bluex, disp->bluey); 20535c4bbdfSmrg xf86ErrorF("whiteX: %.3f whiteY: %.3f\n", disp->whitex, disp->whitey); 20605b261ecSmrg} 2074642e01fSmrg 2084642e01fSmrgstatic void 20935c4bbdfSmrgprint_display(int scrnIndex, struct disp_features *disp, struct edid_version *v) 2104642e01fSmrg{ 2114642e01fSmrg print_input_features(scrnIndex, disp, v); 2124642e01fSmrg if (disp->hsize && disp->vsize) { 21335c4bbdfSmrg xf86DrvMsg(scrnIndex, X_INFO, "Max Image Size [cm]: "); 21435c4bbdfSmrg xf86ErrorF("horiz.: %i ", disp->hsize); 21535c4bbdfSmrg xf86ErrorF("vert.: %i\n", disp->vsize); 21635c4bbdfSmrg } 21735c4bbdfSmrg else if (v->revision >= 4 && (disp->hsize || disp->vsize)) { 21835c4bbdfSmrg if (disp->hsize) 21935c4bbdfSmrg xf86DrvMsg(scrnIndex, X_INFO, "Aspect ratio: %.2f (landscape)\n", 22035c4bbdfSmrg (disp->hsize + 99) / 100.0); 22135c4bbdfSmrg if (disp->vsize) 22235c4bbdfSmrg xf86DrvMsg(scrnIndex, X_INFO, "Aspect ratio: %.2f (portrait)\n", 22335c4bbdfSmrg 100.0 / (float) (disp->vsize + 99)); 22435c4bbdfSmrg 22535c4bbdfSmrg } 22635c4bbdfSmrg else { 22735c4bbdfSmrg xf86DrvMsg(scrnIndex, X_INFO, "Indeterminate output size\n"); 2284642e01fSmrg } 2294642e01fSmrg 2304642e01fSmrg if (!disp->gamma && v->revision >= 1.4) 23135c4bbdfSmrg xf86DrvMsg(scrnIndex, X_INFO, "Gamma defined in extension block\n"); 2324642e01fSmrg else 23335c4bbdfSmrg xf86DrvMsg(scrnIndex, X_INFO, "Gamma: %.2f\n", disp->gamma); 2344642e01fSmrg 2354642e01fSmrg print_dpms_features(scrnIndex, disp, v); 2364642e01fSmrg print_whitepoint(scrnIndex, disp); 2374642e01fSmrg} 2384642e01fSmrg 23935c4bbdfSmrgstatic void 24005b261ecSmrgprint_established_timings(int scrnIndex, struct established_timings *t) 24105b261ecSmrg{ 24205b261ecSmrg unsigned char c; 24305b261ecSmrg 24405b261ecSmrg if (t->t1 || t->t2 || t->t_manu) 24535c4bbdfSmrg xf86DrvMsg(scrnIndex, X_INFO, "Supported established timings:\n"); 24635c4bbdfSmrg c = t->t1; 24735c4bbdfSmrg if (c & 0x80) 24835c4bbdfSmrg xf86DrvMsg(scrnIndex, X_INFO, "720x400@70Hz\n"); 24935c4bbdfSmrg if (c & 0x40) 25035c4bbdfSmrg xf86DrvMsg(scrnIndex, X_INFO, "720x400@88Hz\n"); 25135c4bbdfSmrg if (c & 0x20) 25235c4bbdfSmrg xf86DrvMsg(scrnIndex, X_INFO, "640x480@60Hz\n"); 25335c4bbdfSmrg if (c & 0x10) 25435c4bbdfSmrg xf86DrvMsg(scrnIndex, X_INFO, "640x480@67Hz\n"); 25535c4bbdfSmrg if (c & 0x08) 25635c4bbdfSmrg xf86DrvMsg(scrnIndex, X_INFO, "640x480@72Hz\n"); 25735c4bbdfSmrg if (c & 0x04) 25835c4bbdfSmrg xf86DrvMsg(scrnIndex, X_INFO, "640x480@75Hz\n"); 25935c4bbdfSmrg if (c & 0x02) 26035c4bbdfSmrg xf86DrvMsg(scrnIndex, X_INFO, "800x600@56Hz\n"); 26135c4bbdfSmrg if (c & 0x01) 26235c4bbdfSmrg xf86DrvMsg(scrnIndex, X_INFO, "800x600@60Hz\n"); 26335c4bbdfSmrg c = t->t2; 26435c4bbdfSmrg if (c & 0x80) 26535c4bbdfSmrg xf86DrvMsg(scrnIndex, X_INFO, "800x600@72Hz\n"); 26635c4bbdfSmrg if (c & 0x40) 26735c4bbdfSmrg xf86DrvMsg(scrnIndex, X_INFO, "800x600@75Hz\n"); 26835c4bbdfSmrg if (c & 0x20) 26935c4bbdfSmrg xf86DrvMsg(scrnIndex, X_INFO, "832x624@75Hz\n"); 27035c4bbdfSmrg if (c & 0x10) 27135c4bbdfSmrg xf86DrvMsg(scrnIndex, X_INFO, "1024x768@87Hz (interlaced)\n"); 27235c4bbdfSmrg if (c & 0x08) 27335c4bbdfSmrg xf86DrvMsg(scrnIndex, X_INFO, "1024x768@60Hz\n"); 27435c4bbdfSmrg if (c & 0x04) 27535c4bbdfSmrg xf86DrvMsg(scrnIndex, X_INFO, "1024x768@70Hz\n"); 27635c4bbdfSmrg if (c & 0x02) 27735c4bbdfSmrg xf86DrvMsg(scrnIndex, X_INFO, "1024x768@75Hz\n"); 27835c4bbdfSmrg if (c & 0x01) 27935c4bbdfSmrg xf86DrvMsg(scrnIndex, X_INFO, "1280x1024@75Hz\n"); 28035c4bbdfSmrg c = t->t_manu; 28135c4bbdfSmrg if (c & 0x80) 28235c4bbdfSmrg xf86DrvMsg(scrnIndex, X_INFO, "1152x864@75Hz\n"); 28335c4bbdfSmrg xf86DrvMsg(scrnIndex, X_INFO, "Manufacturer's mask: %X\n", c & 0x7F); 28405b261ecSmrg} 28535c4bbdfSmrg 28605b261ecSmrgstatic void 28705b261ecSmrgprint_std_timings(int scrnIndex, struct std_timings *t) 28805b261ecSmrg{ 28905b261ecSmrg int i; 29005b261ecSmrg char done = 0; 29135c4bbdfSmrg 29235c4bbdfSmrg for (i = 0; i < STD_TIMINGS; i++) { 29335c4bbdfSmrg if (t[i].hsize > 256) { /* sanity check */ 29435c4bbdfSmrg if (!done) { 29535c4bbdfSmrg xf86DrvMsg(scrnIndex, X_INFO, "Supported standard timings:\n"); 29635c4bbdfSmrg done = 1; 29735c4bbdfSmrg } 29835c4bbdfSmrg xf86DrvMsg(scrnIndex, X_INFO, 29935c4bbdfSmrg "#%i: hsize: %i vsize %i refresh: %i vid: %i\n", 30035c4bbdfSmrg i, t[i].hsize, t[i].vsize, t[i].refresh, t[i].id); 30135c4bbdfSmrg } 30205b261ecSmrg } 30305b261ecSmrg} 3044642e01fSmrg 3054642e01fSmrgstatic void 3064642e01fSmrgprint_cvt_timings(int si, struct cvt_timings *t) 3074642e01fSmrg{ 3084642e01fSmrg int i; 3094642e01fSmrg 3104642e01fSmrg for (i = 0; i < 4; i++) { 31135c4bbdfSmrg if (t[i].height) { 31235c4bbdfSmrg xf86DrvMsg(si, X_INFO, "%dx%d @ %s%s%s%s%s Hz\n", 31335c4bbdfSmrg t[i].width, t[i].height, 31435c4bbdfSmrg t[i].rates & 0x10 ? "50," : "", 31535c4bbdfSmrg t[i].rates & 0x08 ? "60," : "", 31635c4bbdfSmrg t[i].rates & 0x04 ? "75," : "", 31735c4bbdfSmrg t[i].rates & 0x02 ? "85," : "", 31835c4bbdfSmrg t[i].rates & 0x01 ? "60RB" : ""); 31935c4bbdfSmrg } 32035c4bbdfSmrg else 32135c4bbdfSmrg break; 3224642e01fSmrg } 3234642e01fSmrg} 3244642e01fSmrg 3254642e01fSmrgstatic void 3264642e01fSmrgprint_detailed_timings(int scrnIndex, struct detailed_timings *t) 3274642e01fSmrg{ 3284642e01fSmrg 3294642e01fSmrg if (t->clock > 15000000) { /* sanity check */ 33035c4bbdfSmrg xf86DrvMsg(scrnIndex, X_INFO, "Supported detailed timing:\n"); 33135c4bbdfSmrg xf86DrvMsg(scrnIndex, X_INFO, "clock: %.1f MHz ", 33235c4bbdfSmrg t->clock / 1000000.0); 33335c4bbdfSmrg xf86ErrorF("Image Size: %i x %i mm\n", t->h_size, t->v_size); 33435c4bbdfSmrg xf86DrvMsg(scrnIndex, X_INFO, 33535c4bbdfSmrg "h_active: %i h_sync: %i h_sync_end %i h_blank_end %i ", 33635c4bbdfSmrg t->h_active, t->h_sync_off + t->h_active, 33735c4bbdfSmrg t->h_sync_off + t->h_sync_width + t->h_active, 33835c4bbdfSmrg t->h_active + t->h_blanking); 33935c4bbdfSmrg xf86ErrorF("h_border: %i\n", t->h_border); 34035c4bbdfSmrg xf86DrvMsg(scrnIndex, X_INFO, 34135c4bbdfSmrg "v_active: %i v_sync: %i v_sync_end %i v_blanking: %i ", 34235c4bbdfSmrg t->v_active, t->v_sync_off + t->v_active, 34335c4bbdfSmrg t->v_sync_off + t->v_sync_width + t->v_active, 34435c4bbdfSmrg t->v_active + t->v_blanking); 34535c4bbdfSmrg xf86ErrorF("v_border: %i\n", t->v_border); 34635c4bbdfSmrg if (IS_STEREO(t->stereo)) { 34735c4bbdfSmrg xf86DrvMsg(scrnIndex, X_INFO, "Stereo: "); 34835c4bbdfSmrg if (IS_RIGHT_STEREO(t->stereo)) { 34935c4bbdfSmrg if (!t->stereo_1) 35035c4bbdfSmrg xf86ErrorF("right channel on sync\n"); 35135c4bbdfSmrg else 35235c4bbdfSmrg xf86ErrorF("left channel on sync\n"); 35335c4bbdfSmrg } 35435c4bbdfSmrg else if (IS_LEFT_STEREO(t->stereo)) { 35535c4bbdfSmrg if (!t->stereo_1) 35635c4bbdfSmrg xf86ErrorF("right channel on even line\n"); 35735c4bbdfSmrg else 35835c4bbdfSmrg xf86ErrorF("left channel on evel line\n"); 35935c4bbdfSmrg } 36035c4bbdfSmrg if (IS_4WAY_STEREO(t->stereo)) { 36135c4bbdfSmrg if (!t->stereo_1) 36235c4bbdfSmrg xf86ErrorF("4-way interleaved\n"); 36335c4bbdfSmrg else 36435c4bbdfSmrg xf86ErrorF("side-by-side interleaved"); 36535c4bbdfSmrg } 36635c4bbdfSmrg } 3674642e01fSmrg } 3684642e01fSmrg} 3694642e01fSmrg 3706747b715Smrg/* This function handle all detailed patchs, 3716747b715Smrg * including EDID and EDID-extension 3726747b715Smrg */ 37335c4bbdfSmrgstruct det_print_parameter { 37435c4bbdfSmrg xf86MonPtr m; 37535c4bbdfSmrg int index; 37635c4bbdfSmrg ddc_quirk_t quirks; 3776747b715Smrg}; 3786747b715Smrg 37905b261ecSmrgstatic void 38035c4bbdfSmrghandle_detailed_print(struct detailed_monitor_section *det_mon, void *data) 38105b261ecSmrg{ 3826747b715Smrg int j, scrnIndex; 3836747b715Smrg struct det_print_parameter *p; 3846747b715Smrg 38535c4bbdfSmrg p = (struct det_print_parameter *) data; 3866747b715Smrg scrnIndex = p->m->scrnIndex; 38735c4bbdfSmrg xf86DetTimingApplyQuirks(det_mon, p->quirks, 38835c4bbdfSmrg p->m->features.hsize, p->m->features.vsize); 3896747b715Smrg 3906747b715Smrg switch (det_mon->type) { 3916747b715Smrg case DT: 39235c4bbdfSmrg print_detailed_timings(scrnIndex, &det_mon->section.d_timings); 3936747b715Smrg break; 3946747b715Smrg case DS_SERIAL: 39535c4bbdfSmrg xf86DrvMsg(scrnIndex, X_INFO, "Serial No: %s\n", 39635c4bbdfSmrg det_mon->section.serial); 3976747b715Smrg break; 3986747b715Smrg case DS_ASCII_STR: 39935c4bbdfSmrg xf86DrvMsg(scrnIndex, X_INFO, " %s\n", det_mon->section.ascii_data); 4006747b715Smrg break; 4016747b715Smrg case DS_NAME: 40235c4bbdfSmrg xf86DrvMsg(scrnIndex, X_INFO, "Monitor name: %s\n", 40335c4bbdfSmrg det_mon->section.name); 4046747b715Smrg break; 4056747b715Smrg case DS_RANGES: 4066747b715Smrg { 4076747b715Smrg struct monitor_ranges *r = &det_mon->section.ranges; 40835c4bbdfSmrg 40935c4bbdfSmrg xf86DrvMsg(scrnIndex, X_INFO, 4106747b715Smrg "Ranges: V min: %i V max: %i Hz, H min: %i H max: %i kHz,", 4116747b715Smrg r->min_v, r->max_v, r->min_h, r->max_h); 4126747b715Smrg if (r->max_clock_khz != 0) { 4136747b715Smrg xf86ErrorF(" PixClock max %i kHz\n", r->max_clock_khz); 41435c4bbdfSmrg if (r->maxwidth) 41535c4bbdfSmrg xf86DrvMsg(scrnIndex, X_INFO, "Maximum pixel width: %d\n", 41635c4bbdfSmrg r->maxwidth); 41735c4bbdfSmrg xf86DrvMsg(scrnIndex, X_INFO, "Supported aspect ratios:"); 41835c4bbdfSmrg if (r->supported_aspect & SUPPORTED_ASPECT_4_3) 41935c4bbdfSmrg xf86ErrorF(" 4:3%s", 42035c4bbdfSmrg r->preferred_aspect == 42135c4bbdfSmrg PREFERRED_ASPECT_4_3 ? "*" : ""); 42235c4bbdfSmrg if (r->supported_aspect & SUPPORTED_ASPECT_16_9) 42335c4bbdfSmrg xf86ErrorF(" 16:9%s", 42435c4bbdfSmrg r->preferred_aspect == 42535c4bbdfSmrg PREFERRED_ASPECT_16_9 ? "*" : ""); 42635c4bbdfSmrg if (r->supported_aspect & SUPPORTED_ASPECT_16_10) 42735c4bbdfSmrg xf86ErrorF(" 16:10%s", 42835c4bbdfSmrg r->preferred_aspect == 42935c4bbdfSmrg PREFERRED_ASPECT_16_10 ? "*" : ""); 43035c4bbdfSmrg if (r->supported_aspect & SUPPORTED_ASPECT_5_4) 43135c4bbdfSmrg xf86ErrorF(" 5:4%s", 43235c4bbdfSmrg r->preferred_aspect == 43335c4bbdfSmrg PREFERRED_ASPECT_5_4 ? "*" : ""); 43435c4bbdfSmrg if (r->supported_aspect & SUPPORTED_ASPECT_15_9) 43535c4bbdfSmrg xf86ErrorF(" 15:9%s", 43635c4bbdfSmrg r->preferred_aspect == 43735c4bbdfSmrg PREFERRED_ASPECT_15_9 ? "*" : ""); 43835c4bbdfSmrg xf86ErrorF("\n"); 43935c4bbdfSmrg xf86DrvMsg(scrnIndex, X_INFO, "Supported blankings:"); 44035c4bbdfSmrg if (r->supported_blanking & CVT_STANDARD) 44135c4bbdfSmrg xf86ErrorF(" standard"); 44235c4bbdfSmrg if (r->supported_blanking & CVT_REDUCED) 44335c4bbdfSmrg xf86ErrorF(" reduced"); 44435c4bbdfSmrg xf86ErrorF("\n"); 44535c4bbdfSmrg xf86DrvMsg(scrnIndex, X_INFO, "Supported scalings:"); 44635c4bbdfSmrg if (r->supported_scaling & SCALING_HSHRINK) 44735c4bbdfSmrg xf86ErrorF(" hshrink"); 44835c4bbdfSmrg if (r->supported_scaling & SCALING_HSTRETCH) 44935c4bbdfSmrg xf86ErrorF(" hstretch"); 45035c4bbdfSmrg if (r->supported_scaling & SCALING_VSHRINK) 45135c4bbdfSmrg xf86ErrorF(" vshrink"); 45235c4bbdfSmrg if (r->supported_scaling & SCALING_VSTRETCH) 45335c4bbdfSmrg xf86ErrorF(" vstretch"); 45435c4bbdfSmrg xf86ErrorF("\n"); 45535c4bbdfSmrg if (r->preferred_refresh) 45635c4bbdfSmrg xf86DrvMsg(scrnIndex, X_INFO, "Preferred refresh rate: %d\n", 45735c4bbdfSmrg r->preferred_refresh); 45835c4bbdfSmrg else 45935c4bbdfSmrg xf86DrvMsg(scrnIndex, X_INFO, "Buggy monitor, no preferred " 46035c4bbdfSmrg "refresh rate given\n"); 46135c4bbdfSmrg } 46235c4bbdfSmrg else if (r->max_clock != 0) { 46335c4bbdfSmrg xf86ErrorF(" PixClock max %i MHz\n", r->max_clock); 46435c4bbdfSmrg } 46535c4bbdfSmrg else { 46635c4bbdfSmrg xf86ErrorF("\n"); 4676747b715Smrg } 4686747b715Smrg if (r->gtf_2nd_f > 0) 46935c4bbdfSmrg xf86DrvMsg(scrnIndex, X_INFO, " 2nd GTF parameters: f: %i kHz " 4706747b715Smrg "c: %i m: %i k %i j %i\n", r->gtf_2nd_f, 47135c4bbdfSmrg r->gtf_2nd_c, r->gtf_2nd_m, r->gtf_2nd_k, r->gtf_2nd_j); 4726747b715Smrg break; 4736747b715Smrg } 4746747b715Smrg case DS_STD_TIMINGS: 47535c4bbdfSmrg for (j = 0; j < 5; j++) 47635c4bbdfSmrg xf86DrvMsg(scrnIndex, X_INFO, 47735c4bbdfSmrg "#%i: hsize: %i vsize %i refresh: %i " 47835c4bbdfSmrg "vid: %i\n", p->index, det_mon->section.std_t[j].hsize, 47935c4bbdfSmrg det_mon->section.std_t[j].vsize, 48035c4bbdfSmrg det_mon->section.std_t[j].refresh, 48135c4bbdfSmrg det_mon->section.std_t[j].id); 4826747b715Smrg break; 4836747b715Smrg case DS_WHITE_P: 48435c4bbdfSmrg for (j = 0; j < 2; j++) 48535c4bbdfSmrg if (det_mon->section.wp[j].index != 0) 48635c4bbdfSmrg xf86DrvMsg(scrnIndex, X_INFO, 48735c4bbdfSmrg "White point %i: whiteX: %f, whiteY: %f; gamma: %f\n", 48835c4bbdfSmrg det_mon->section.wp[j].index, 48935c4bbdfSmrg det_mon->section.wp[j].white_x, 49035c4bbdfSmrg det_mon->section.wp[j].white_y, 49135c4bbdfSmrg det_mon->section.wp[j].white_gamma); 4926747b715Smrg break; 4936747b715Smrg case DS_CMD: 49435c4bbdfSmrg xf86DrvMsg(scrnIndex, X_INFO, "Color management data: (not decoded)\n"); 4956747b715Smrg break; 4966747b715Smrg case DS_CVT: 49735c4bbdfSmrg xf86DrvMsg(scrnIndex, X_INFO, "CVT 3-byte-code modes:\n"); 4986747b715Smrg print_cvt_timings(scrnIndex, det_mon->section.cvt); 4996747b715Smrg break; 5006747b715Smrg case DS_EST_III: 5016747b715Smrg xf86DrvMsg(scrnIndex, X_INFO, 5026747b715Smrg "Established timings III: (not decoded)\n"); 5036747b715Smrg break; 5046747b715Smrg case DS_DUMMY: 5056747b715Smrg default: 5066747b715Smrg break; 5076747b715Smrg } 5086747b715Smrg if (det_mon->type >= DS_VENDOR && det_mon->type <= DS_VENDOR_MAX) { 5096747b715Smrg xf86DrvMsg(scrnIndex, X_INFO, 510dc61d50dSmrg "Unknown vendor-specific block %x\n", 5116747b715Smrg det_mon->type - DS_VENDOR); 51205b261ecSmrg } 5136747b715Smrg 5146747b715Smrg p->index = p->index + 1; 51505b261ecSmrg} 5166747b715Smrg 51705b261ecSmrgstatic void 51805b261ecSmrgprint_number_sections(int scrnIndex, int num) 51905b261ecSmrg{ 52005b261ecSmrg if (num) 52135c4bbdfSmrg xf86DrvMsg(scrnIndex, X_INFO, "Number of EDID sections to follow: %i\n", 52235c4bbdfSmrg num); 52305b261ecSmrg} 52405b261ecSmrg 5254642e01fSmrgxf86MonPtr 5264642e01fSmrgxf86PrintEDID(xf86MonPtr m) 5274642e01fSmrg{ 5284642e01fSmrg CARD16 i, j, n; 5294642e01fSmrg char buf[EDID_WIDTH * 2 + 1]; 5306747b715Smrg struct det_print_parameter p; 5314642e01fSmrg 53235c4bbdfSmrg if (!m) 53335c4bbdfSmrg return NULL; 5344642e01fSmrg 5354642e01fSmrg print_vendor(m->scrnIndex, &m->vendor); 5364642e01fSmrg print_version(m->scrnIndex, &m->ver); 5374642e01fSmrg print_display(m->scrnIndex, &m->features, &m->ver); 5384642e01fSmrg print_established_timings(m->scrnIndex, &m->timings1); 5394642e01fSmrg print_std_timings(m->scrnIndex, m->timings2); 5406747b715Smrg p.m = m; 5416747b715Smrg p.index = 0; 5426747b715Smrg p.quirks = xf86DDCDetectQuirks(m->scrnIndex, m, FALSE); 54335c4bbdfSmrg xf86ForEachDetailedBlock(m, handle_detailed_print, &p); 5444642e01fSmrg print_number_sections(m->scrnIndex, m->no_sections); 5454642e01fSmrg 5464642e01fSmrg /* extension block section stuff */ 5474642e01fSmrg 5484642e01fSmrg xf86DrvMsg(m->scrnIndex, X_INFO, "EDID (in hex):\n"); 5494642e01fSmrg 5504642e01fSmrg n = 128; 5514642e01fSmrg if (m->flags & EDID_COMPLETE_RAWDATA) 55235c4bbdfSmrg n += m->no_sections * 128; 5534642e01fSmrg 5544642e01fSmrg for (i = 0; i < n; i += j) { 55535c4bbdfSmrg for (j = 0; j < EDID_WIDTH; ++j) { 55635c4bbdfSmrg sprintf(&buf[j * 2], "%02x", m->rawData[i + j]); 55735c4bbdfSmrg } 55835c4bbdfSmrg xf86DrvMsg(m->scrnIndex, X_INFO, "\t%s\n", buf); 5594642e01fSmrg } 5606747b715Smrg 5614642e01fSmrg return m; 5624642e01fSmrg} 563