Parse full EDID data to get all video resolutions supported by monitors.

Signed-off-by: Li Elvin <elvin.li@intel.com>
Reviewed-by: Ni Ruiyu <ruiyu.ni@intel.com>


git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@14073 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
li-elvin 2013-01-22 06:18:50 +00:00
parent ed729be159
commit 2e0910acd5
2 changed files with 85 additions and 40 deletions

View File

@ -1,7 +1,7 @@
/** @file /** @file
ConsoleOut Routines that speak VGA. ConsoleOut Routines that speak VGA.
Copyright (c) 2007 - 2012, Intel Corporation. All rights reserved.<BR> Copyright (c) 2007 - 2013, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials This program and the accompanying materials
are licensed and made available under the terms and conditions are licensed and made available under the terms and conditions
@ -1129,49 +1129,79 @@ ParseEdidData (
((EdidDataBlock->EstablishedTimings[2] & 0x80) << 9) ; ((EdidDataBlock->EstablishedTimings[2] & 0x80) << 9) ;
for (Index = 0; Index < VESA_BIOS_EXTENSIONS_EDID_ESTABLISHED_TIMING_MAX_NUMBER; Index ++) { for (Index = 0; Index < VESA_BIOS_EXTENSIONS_EDID_ESTABLISHED_TIMING_MAX_NUMBER; Index ++) {
if ((TimingBits & 0x1) != 0) { if ((TimingBits & 0x1) != 0) {
DEBUG ((EFI_D_INFO, "Established Timing: %d x %d\n",
mEstablishedEdidTiming[Index].HorizontalResolution, mEstablishedEdidTiming[Index].VerticalResolution));
ValidEdidTiming->Key[ValidNumber] = CalculateEdidKey (&mEstablishedEdidTiming[Index]); ValidEdidTiming->Key[ValidNumber] = CalculateEdidKey (&mEstablishedEdidTiming[Index]);
ValidNumber ++; ValidNumber ++;
} }
TimingBits = TimingBits >> 1; TimingBits = TimingBits >> 1;
} }
} else { }
//
// Parse the standard timing data
//
BufferIndex = &EdidDataBlock->StandardTimingIdentification[0];
for (Index = 0; Index < 8; Index ++) {
// //
// If no Established timing data, read the standard timing data // Check if this is a valid Standard Timing entry
// VESA documents unused fields should be set to 01h
// //
BufferIndex = &EdidDataBlock->StandardTimingIdentification[0]; if ((BufferIndex[0] != 0x1) && (BufferIndex[1] != 0x1)){
for (Index = 0; Index < 8; Index ++) { //
if ((BufferIndex[0] != 0x1) && (BufferIndex[1] != 0x1)){ // A valid Standard Timing
// //
// A valid Standard Timing HorizontalResolution = (UINT16) (BufferIndex[0] * 8 + 248);
// AspectRatio = (UINT8) (BufferIndex[1] >> 6);
HorizontalResolution = (UINT16) (BufferIndex[0] * 8 + 248); switch (AspectRatio) {
AspectRatio = (UINT8) (BufferIndex[1] >> 6); case 0:
switch (AspectRatio) { VerticalResolution = (UINT16) (HorizontalResolution / 16 * 10);
case 0: break;
VerticalResolution = (UINT16) (HorizontalResolution / 16 * 10); case 1:
break; VerticalResolution = (UINT16) (HorizontalResolution / 4 * 3);
case 1: break;
VerticalResolution = (UINT16) (HorizontalResolution / 4 * 3); case 2:
break; VerticalResolution = (UINT16) (HorizontalResolution / 5 * 4);
case 2: break;
VerticalResolution = (UINT16) (HorizontalResolution / 5 * 4); case 3:
break; VerticalResolution = (UINT16) (HorizontalResolution / 16 * 9);
case 3: break;
VerticalResolution = (UINT16) (HorizontalResolution / 16 * 9); default:
break; VerticalResolution = (UINT16) (HorizontalResolution / 4 * 3);
default: break;
VerticalResolution = (UINT16) (HorizontalResolution / 4 * 3);
break;
}
RefreshRate = (UINT8) ((BufferIndex[1] & 0x1f) + 60);
TempTiming.HorizontalResolution = HorizontalResolution;
TempTiming.VerticalResolution = VerticalResolution;
TempTiming.RefreshRate = RefreshRate;
ValidEdidTiming->Key[ValidNumber] = CalculateEdidKey (&TempTiming);
ValidNumber ++;
} }
BufferIndex += 2; RefreshRate = (UINT8) ((BufferIndex[1] & 0x1f) + 60);
DEBUG ((EFI_D_INFO, "Standard Timing: %d x %d\n", HorizontalResolution, VerticalResolution));
TempTiming.HorizontalResolution = HorizontalResolution;
TempTiming.VerticalResolution = VerticalResolution;
TempTiming.RefreshRate = RefreshRate;
ValidEdidTiming->Key[ValidNumber] = CalculateEdidKey (&TempTiming);
ValidNumber ++;
} }
BufferIndex += 2;
}
//
// Parse the Detailed Timing data
//
BufferIndex = &EdidDataBlock->DetailedTimingDescriptions[0];
for (Index = 0; Index < 4; Index ++, BufferIndex += VESA_BIOS_EXTENSIONS_DETAILED_TIMING_EACH_DESCRIPTOR_SIZE) {
if ((BufferIndex[0] == 0x0) && (BufferIndex[1] == 0x0)) {
//
// Check if this is a valid Detailed Timing Descriptor
// If first 2 bytes are zero, it is monitor descriptor other than detailed timing descriptor
//
continue;
}
//
// Calculate Horizontal and Vertical resolution
//
TempTiming.HorizontalResolution = ((UINT16)(BufferIndex[4] & 0xF0) << 4) | (BufferIndex[2]);
TempTiming.VerticalResolution = ((UINT16)(BufferIndex[7] & 0xF0) << 4) | (BufferIndex[5]);
DEBUG ((EFI_D_INFO, "Detailed Timing %d: %d x %d\n",
Index, TempTiming.HorizontalResolution, TempTiming.VerticalResolution));
ValidEdidTiming->Key[ValidNumber] = CalculateEdidKey (&TempTiming);
ValidNumber ++;
} }
ValidEdidTiming->ValidNumber = ValidNumber; ValidEdidTiming->ValidNumber = ValidNumber;

View File

@ -1,6 +1,6 @@
/** @file /** @file
Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR> Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials This program and the accompanying materials
are licensed and made available under the terms and conditions are licensed and made available under the terms and conditions
@ -168,6 +168,21 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#define VESA_BIOS_EXTENSIONS_EDID_BLOCK_SIZE 128 #define VESA_BIOS_EXTENSIONS_EDID_BLOCK_SIZE 128
#define VESA_BIOS_EXTENSIONS_EDID_ESTABLISHED_TIMING_MAX_NUMBER 17 #define VESA_BIOS_EXTENSIONS_EDID_ESTABLISHED_TIMING_MAX_NUMBER 17
//
// Established Timings: 24 possible resolutions
// Standard Timings: 8 possible resolutions
// Detailed Timings: 4 possible resolutions
//
#define VESA_BIOS_EXTENSIONS_EDID_TIMING_MAX_NUMBER 36
//
// Timing data size for Established Timings, Standard Timings and Detailed Timings
//
#define VESA_BIOS_EXTENSIONS_ESTABLISHED_TIMING_SIZE 3
#define VESA_BIOS_EXTENSIONS_STANDARD_TIMING_SIZE 16
#define VESA_BIOS_EXTENSIONS_DETAILED_TIMING_EACH_DESCRIPTOR_SIZE 18
#define VESA_BIOS_EXTENSIONS_DETAILED_TIMING_DESCRIPTOR_MAX_SIZE 72
typedef struct { typedef struct {
UINT16 HorizontalResolution; UINT16 HorizontalResolution;
UINT16 VerticalResolution; UINT16 VerticalResolution;
@ -176,7 +191,7 @@ typedef struct {
typedef struct { typedef struct {
UINT32 ValidNumber; UINT32 ValidNumber;
UINT32 Key[VESA_BIOS_EXTENSIONS_EDID_ESTABLISHED_TIMING_MAX_NUMBER]; UINT32 Key[VESA_BIOS_EXTENSIONS_EDID_TIMING_MAX_NUMBER];
} VESA_BIOS_EXTENSIONS_VALID_EDID_TIMING; } VESA_BIOS_EXTENSIONS_VALID_EDID_TIMING;
typedef struct { typedef struct {
@ -203,9 +218,9 @@ typedef struct {
UINT8 BlueY; //Blue-y Bits 9 - 2 UINT8 BlueY; //Blue-y Bits 9 - 2
UINT8 WhiteX; //White-x Bits 9 - 2 UINT8 WhiteX; //White-x Bits 9 - 2
UINT8 WhiteY; //White-x Bits 9 - 2 UINT8 WhiteY; //White-x Bits 9 - 2
UINT8 EstablishedTimings[3]; UINT8 EstablishedTimings[VESA_BIOS_EXTENSIONS_ESTABLISHED_TIMING_SIZE];
UINT8 StandardTimingIdentification[16]; UINT8 StandardTimingIdentification[VESA_BIOS_EXTENSIONS_STANDARD_TIMING_SIZE];
UINT8 DetailedTimingDescriptions[72]; UINT8 DetailedTimingDescriptions[VESA_BIOS_EXTENSIONS_DETAILED_TIMING_DESCRIPTOR_MAX_SIZE];
UINT8 ExtensionFlag; //Number of (optional) 128-byte EDID extension blocks to follow UINT8 ExtensionFlag; //Number of (optional) 128-byte EDID extension blocks to follow
UINT8 Checksum; UINT8 Checksum;
} VESA_BIOS_EXTENSIONS_EDID_DATA_BLOCK; } VESA_BIOS_EXTENSIONS_EDID_DATA_BLOCK;