diff --git a/hw/xfree86/ddc/edid.h b/hw/xfree86/ddc/edid.h index 6708eaaa5..25163a69f 100644 --- a/hw/xfree86/ddc/edid.h +++ b/hw/xfree86/ddc/edid.h @@ -125,6 +125,10 @@ #define SYNC _SYNC(GET(D_INPUT)) #define _DFP(x) (x & 0x01) #define DFP _DFP(GET(D_INPUT)) +#define _BPC(x) ((x & 0x70) >> 4) +#define BPC _BPC(GET(D_INPUT)) +#define _DIGITAL_INTERFACE(x) (x & 0x0F) +#define DIGITAL_INTERFACE _DIGITAL_INTERFACE(GET(D_INPUT)) #define _GAMMA(x) (x == 0xff ? 1.0 : ((x + 100.0)/100.0)) #define GAMMA _GAMMA(GET(D_GAMMA)) #define HSIZE_MAX GET(D_HSIZE) @@ -364,6 +368,9 @@ struct disp_features { unsigned int input_setup:1; unsigned int input_sync:5; unsigned int input_dfp:1; + unsigned int input_bpc:3; + unsigned int input_interface:4; + /* 15 bit hole */ int hsize; int vsize; float gamma; diff --git a/hw/xfree86/ddc/interpret_edid.c b/hw/xfree86/ddc/interpret_edid.c index 982a502fd..045c12d9d 100644 --- a/hw/xfree86/ddc/interpret_edid.c +++ b/hw/xfree86/ddc/interpret_edid.c @@ -148,8 +148,12 @@ get_display_section(Uchar *c, struct disp_features *r, r->input_voltage = INPUT_VOLTAGE; r->input_setup = SETUP; r->input_sync = SYNC; - } else if (v->version > 1 || v->revision > 2) + } else if (v->revision == 2 || v->revision == 3) { r->input_dfp = DFP; + } else if (v->revision >= 4) { + r->input_bpc = BPC; + r->input_interface = DIGITAL_INTERFACE; + } r->hsize = HSIZE_MAX; r->vsize = VSIZE_MAX; r->gamma = GAMMA; diff --git a/hw/xfree86/ddc/print_edid.c b/hw/xfree86/ddc/print_edid.c index 5aebc6e74..9bd7ebcf5 100644 --- a/hw/xfree86/ddc/print_edid.c +++ b/hw/xfree86/ddc/print_edid.c @@ -1,8 +1,28 @@ - -/* print_edid.c: print out all information retrieved from display device - * +/* * Copyright 1998 by Egbert Eich + * Copyright 2007 Red Hat, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software") + * to deal in the software without restriction, including without limitation + * on the rights to use, copy, modify, merge, publish, distribute, sub + * license, and/or sell copies of the Software, and to permit persons to whom + * them Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTIBILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES, OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT, OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * print_edid.c: print out all information retrieved from display device */ + #ifdef HAVE_XORG_CONFIG_H #include #endif @@ -11,53 +31,9 @@ #include "xf86.h" #include "xf86_OSproc.h" #include "xf86DDC.h" +#include "edid.h" -static void print_vendor(int scrnIndex, struct vendor *); -static void print_version(int scrnIndex, struct edid_version *); -static void print_display(int scrnIndex, struct disp_features *, - struct edid_version *); -static void print_established_timings(int scrnIndex, - struct established_timings *); -static void print_std_timings(int scrnIndex, struct std_timings *); -static void print_detailed_monitor_section(int scrnIndex, - struct detailed_monitor_section *); -static void print_detailed_timings(int scrnIndex, struct detailed_timings *); - -static void print_input_features(int scrnIndex, struct disp_features *); -static void print_dpms_features(int scrnIndex, struct disp_features *, - struct edid_version *v); -static void print_whitepoint(int scrnIndex, struct disp_features *); -static void print_number_sections(int scrnIndex, int); - #define EDID_WIDTH 16 - -xf86MonPtr -xf86PrintEDID(xf86MonPtr m) -{ - CARD16 i, j; - char buf[EDID_WIDTH * 2 + 1]; - - if (!(m)) return NULL; - - print_vendor(m->scrnIndex,&m->vendor); - print_version(m->scrnIndex,&m->ver); - print_display(m->scrnIndex,&m->features, &m->ver); - print_established_timings(m->scrnIndex,&m->timings1); - print_std_timings(m->scrnIndex,m->timings2); - print_detailed_monitor_section(m->scrnIndex,m->det_mon); - print_number_sections(m->scrnIndex,m->no_sections); - - xf86DrvMsg(m->scrnIndex, X_INFO, "EDID (in hex):\n"); - - for (i = 0; i < 128; i += j) { - for (j = 0; j < EDID_WIDTH; ++j) { - sprintf(&buf[j * 2], "%02x", m->rawData[i + j]); - } - xf86DrvMsg(m->scrnIndex, X_INFO, "\t%s\n", buf); - } - - return m; -} static void print_vendor(int scrnIndex, struct vendor *c) @@ -66,7 +42,7 @@ print_vendor(int scrnIndex, struct vendor *c) (char *)&c->name, c->prod_id, c->serial); xf86DrvMsg(scrnIndex, X_INFO, "Year: %u Week: %u\n", c->year, c->week); } - + static void print_version(int scrnIndex, struct edid_version *c) { @@ -74,32 +50,38 @@ print_version(int scrnIndex, struct edid_version *c) c->revision); } -static void -print_display(int scrnIndex, struct disp_features *disp, - struct edid_version *version) -{ - print_input_features(scrnIndex,disp); - xf86DrvMsg(scrnIndex,X_INFO,"Max H-Image Size [cm]: "); - if (disp->hsize) - xf86ErrorF("horiz.: %i ",disp->hsize); - else - xf86ErrorF("H-Size may change, "); - if (disp->vsize) - xf86ErrorF("vert.: %i\n",disp->vsize); - else - xf86ErrorF("V-Size may change\n"); - xf86DrvMsg(scrnIndex,X_INFO,"Gamma: %.2f\n", disp->gamma); - print_dpms_features(scrnIndex,disp,version); - print_whitepoint(scrnIndex,disp); -} - +static const char *digital_interfaces[] = { + "undefined", + "DVI", + "HDMI-a", + "HDMI-b", + "MDDI", + "DisplayPort", + "unknown" +}; + static void -print_input_features(int scrnIndex, struct disp_features *c) +print_input_features(int scrnIndex, struct disp_features *c, + struct edid_version *v) { if (DIGITAL(c->input_type)) { - xf86DrvMsg(scrnIndex,X_INFO,"Digital Display Input\n"); - if (DFP1(c->input_dfp)) - xf86DrvMsg(scrnIndex,X_INFO,"DFP 1.x compatible TMDS\n"); + xf86DrvMsg(scrnIndex, X_INFO, "Digital Display Input\n"); + if (v->revision == 2 || v->revision == 3) { + if (DFP1(c->input_dfp)) + xf86DrvMsg(scrnIndex, X_INFO, "DFP 1.x compatible TMDS\n"); + } else if (v->revision >= 4) { + int interface = c->input_interface; + int bpc = c->input_bpc; + if (interface > 6) + interface = 6; /* unknown */ + if (bpc == 0 || bpc == 7) + xf86DrvMsg(scrnIndex, X_INFO, "Undefined color depth\n"); + else + xf86DrvMsg(scrnIndex, X_INFO, "%d bits per channel\n", + bpc * 2 + 4); + xf86DrvMsg(scrnIndex, X_INFO, "Digital interface is %s\n", + digital_interfaces[interface]); + } } else { xf86DrvMsg(scrnIndex,X_INFO,"Analog Display Input, "); xf86ErrorF("Input Voltage Level: "); @@ -187,7 +169,26 @@ print_whitepoint(int scrnIndex, struct disp_features *disp) xf86ErrorF("whiteX: %.3f whiteY: %.3f\n", disp->whitex,disp->whitey); } - + +static void +print_display(int scrnIndex, struct disp_features *disp, + struct edid_version *version) +{ + print_input_features(scrnIndex, disp, version); + xf86DrvMsg(scrnIndex,X_INFO,"Max H-Image Size [cm]: "); + if (disp->hsize) + xf86ErrorF("horiz.: %i ",disp->hsize); + else + xf86ErrorF("H-Size may change, "); + if (disp->vsize) + xf86ErrorF("vert.: %i\n",disp->vsize); + else + xf86ErrorF("V-Size may change\n"); + xf86DrvMsg(scrnIndex,X_INFO,"Gamma: %.2f\n", disp->gamma); + print_dpms_features(scrnIndex,disp,version); + print_whitepoint(scrnIndex,disp); +} + static void print_established_timings(int scrnIndex, struct established_timings *t) { @@ -253,7 +254,50 @@ print_cvt_timings(int si, struct cvt_timings *t) } else break; } } - + +static void +print_detailed_timings(int scrnIndex, struct detailed_timings *t) +{ + + if (t->clock > 15000000) { /* sanity check */ + xf86DrvMsg(scrnIndex,X_INFO,"Supported additional Video Mode:\n"); + xf86DrvMsg(scrnIndex,X_INFO,"clock: %.1f MHz ",t->clock/1000000.0); + xf86ErrorF("Image Size: %i x %i mm\n",t->h_size,t->v_size); + xf86DrvMsg(scrnIndex,X_INFO, + "h_active: %i h_sync: %i h_sync_end %i h_blank_end %i ", + t->h_active, t->h_sync_off + t->h_active, + t->h_sync_off + t->h_sync_width + t->h_active, + t->h_active + t->h_blanking); + xf86ErrorF("h_border: %i\n",t->h_border); + xf86DrvMsg(scrnIndex,X_INFO, + "v_active: %i v_sync: %i v_sync_end %i v_blanking: %i ", + t->v_active, t->v_sync_off + t->v_active, + t->v_sync_off + t->v_sync_width + t->v_active, + t->v_active + t->v_blanking); + xf86ErrorF("v_border: %i\n",t->v_border); + if (IS_STEREO(t->stereo)) { + xf86DrvMsg(scrnIndex,X_INFO,"Stereo: "); + if (IS_RIGHT_STEREO(t->stereo)) { + if (!t->stereo_1) + xf86ErrorF("right channel on sync\n"); + else + xf86ErrorF("left channel on sync\n"); + } else if (IS_LEFT_STEREO(t->stereo)) { + if (!t->stereo_1) + xf86ErrorF("right channel on even line\n"); + else + xf86ErrorF("left channel on evel line\n"); + } + if (IS_4WAY_STEREO(t->stereo)) { + if (!t->stereo_1) + xf86ErrorF("4-way interleaved\n"); + else + xf86ErrorF("side-by-side interleaved"); + } + } + } +} + static void print_detailed_monitor_section(int scrnIndex, struct detailed_monitor_section *m) @@ -333,49 +377,6 @@ print_detailed_monitor_section(int scrnIndex, } } -static void -print_detailed_timings(int scrnIndex, struct detailed_timings *t) -{ - - if (t->clock > 15000000) { /* sanity check */ - xf86DrvMsg(scrnIndex,X_INFO,"Supported additional Video Mode:\n"); - xf86DrvMsg(scrnIndex,X_INFO,"clock: %.1f MHz ",t->clock/1000000.0); - xf86ErrorF("Image Size: %i x %i mm\n",t->h_size,t->v_size); - xf86DrvMsg(scrnIndex,X_INFO, - "h_active: %i h_sync: %i h_sync_end %i h_blank_end %i ", - t->h_active, t->h_sync_off + t->h_active, - t->h_sync_off + t->h_sync_width + t->h_active, - t->h_active + t->h_blanking); - xf86ErrorF("h_border: %i\n",t->h_border); - xf86DrvMsg(scrnIndex,X_INFO, - "v_active: %i v_sync: %i v_sync_end %i v_blanking: %i ", - t->v_active, t->v_sync_off + t->v_active, - t->v_sync_off + t->v_sync_width + t->v_active, - t->v_active + t->v_blanking); - xf86ErrorF("v_border: %i\n",t->v_border); - if (IS_STEREO(t->stereo)) { - xf86DrvMsg(scrnIndex,X_INFO,"Stereo: "); - if (IS_RIGHT_STEREO(t->stereo)) { - if (!t->stereo_1) - xf86ErrorF("right channel on sync\n"); - else - xf86ErrorF("left channel on sync\n"); - } else if (IS_LEFT_STEREO(t->stereo)) { - if (!t->stereo_1) - xf86ErrorF("right channel on even line\n"); - else - xf86ErrorF("left channel on evel line\n"); - } - if (IS_4WAY_STEREO(t->stereo)) { - if (!t->stereo_1) - xf86ErrorF("4-way interleaved\n"); - else - xf86ErrorF("side-by-side interleaved"); - } - } - } -} - static void print_number_sections(int scrnIndex, int num) { @@ -384,3 +385,30 @@ print_number_sections(int scrnIndex, int num) num); } +xf86MonPtr +xf86PrintEDID(xf86MonPtr m) +{ + CARD16 i, j; + char buf[EDID_WIDTH * 2 + 1]; + + if (!(m)) return NULL; + + print_vendor(m->scrnIndex,&m->vendor); + print_version(m->scrnIndex,&m->ver); + print_display(m->scrnIndex,&m->features, &m->ver); + print_established_timings(m->scrnIndex,&m->timings1); + print_std_timings(m->scrnIndex,m->timings2); + print_detailed_monitor_section(m->scrnIndex,m->det_mon); + print_number_sections(m->scrnIndex,m->no_sections); + + xf86DrvMsg(m->scrnIndex, X_INFO, "EDID (in hex):\n"); + + for (i = 0; i < 128; i += j) { + for (j = 0; j < EDID_WIDTH; ++j) { + sprintf(&buf[j * 2], "%02x", m->rawData[i + j]); + } + xf86DrvMsg(m->scrnIndex, X_INFO, "\t%s\n", buf); + } + + return m; +}