From 2e0910acd53a5e71c3cac602df5c9b4331672ef5 Mon Sep 17 00:00:00 2001 From: li-elvin Date: Tue, 22 Jan 2013 06:18:50 +0000 Subject: [PATCH] Parse full EDID data to get all video resolutions supported by monitors. Signed-off-by: Li Elvin Reviewed-by: Ni Ruiyu git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@14073 6f19259b-4bc3-4df7-8a09-765794883524 --- .../Csm/BiosThunk/VideoDxe/BiosVideo.c | 100 ++++++++++++------ .../BiosThunk/VideoDxe/VesaBiosExtensions.h | 25 ++++- 2 files changed, 85 insertions(+), 40 deletions(-) diff --git a/IntelFrameworkModulePkg/Csm/BiosThunk/VideoDxe/BiosVideo.c b/IntelFrameworkModulePkg/Csm/BiosThunk/VideoDxe/BiosVideo.c index 21b3e87268..f38c968943 100644 --- a/IntelFrameworkModulePkg/Csm/BiosThunk/VideoDxe/BiosVideo.c +++ b/IntelFrameworkModulePkg/Csm/BiosThunk/VideoDxe/BiosVideo.c @@ -1,7 +1,7 @@ /** @file ConsoleOut Routines that speak VGA. -Copyright (c) 2007 - 2012, Intel Corporation. All rights reserved.
+Copyright (c) 2007 - 2013, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions @@ -1129,49 +1129,79 @@ ParseEdidData ( ((EdidDataBlock->EstablishedTimings[2] & 0x80) << 9) ; for (Index = 0; Index < VESA_BIOS_EXTENSIONS_EDID_ESTABLISHED_TIMING_MAX_NUMBER; Index ++) { 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]); ValidNumber ++; } 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]; - for (Index = 0; Index < 8; Index ++) { - if ((BufferIndex[0] != 0x1) && (BufferIndex[1] != 0x1)){ - // - // A valid Standard Timing - // - HorizontalResolution = (UINT16) (BufferIndex[0] * 8 + 248); - AspectRatio = (UINT8) (BufferIndex[1] >> 6); - switch (AspectRatio) { - case 0: - VerticalResolution = (UINT16) (HorizontalResolution / 16 * 10); - break; - case 1: - VerticalResolution = (UINT16) (HorizontalResolution / 4 * 3); - break; - case 2: - VerticalResolution = (UINT16) (HorizontalResolution / 5 * 4); - break; - case 3: - VerticalResolution = (UINT16) (HorizontalResolution / 16 * 9); - break; - default: - 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 ++; + if ((BufferIndex[0] != 0x1) && (BufferIndex[1] != 0x1)){ + // + // A valid Standard Timing + // + HorizontalResolution = (UINT16) (BufferIndex[0] * 8 + 248); + AspectRatio = (UINT8) (BufferIndex[1] >> 6); + switch (AspectRatio) { + case 0: + VerticalResolution = (UINT16) (HorizontalResolution / 16 * 10); + break; + case 1: + VerticalResolution = (UINT16) (HorizontalResolution / 4 * 3); + break; + case 2: + VerticalResolution = (UINT16) (HorizontalResolution / 5 * 4); + break; + case 3: + VerticalResolution = (UINT16) (HorizontalResolution / 16 * 9); + break; + default: + VerticalResolution = (UINT16) (HorizontalResolution / 4 * 3); + break; } - 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; diff --git a/IntelFrameworkModulePkg/Csm/BiosThunk/VideoDxe/VesaBiosExtensions.h b/IntelFrameworkModulePkg/Csm/BiosThunk/VideoDxe/VesaBiosExtensions.h index dcda3fcd5a..25eee6921d 100644 --- a/IntelFrameworkModulePkg/Csm/BiosThunk/VideoDxe/VesaBiosExtensions.h +++ b/IntelFrameworkModulePkg/Csm/BiosThunk/VideoDxe/VesaBiosExtensions.h @@ -1,6 +1,6 @@ /** @file -Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.
+Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.
This program and the accompanying materials 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_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 { UINT16 HorizontalResolution; UINT16 VerticalResolution; @@ -176,7 +191,7 @@ typedef struct { typedef struct { 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; typedef struct { @@ -203,9 +218,9 @@ typedef struct { UINT8 BlueY; //Blue-y Bits 9 - 2 UINT8 WhiteX; //White-x Bits 9 - 2 UINT8 WhiteY; //White-x Bits 9 - 2 - UINT8 EstablishedTimings[3]; - UINT8 StandardTimingIdentification[16]; - UINT8 DetailedTimingDescriptions[72]; + UINT8 EstablishedTimings[VESA_BIOS_EXTENSIONS_ESTABLISHED_TIMING_SIZE]; + UINT8 StandardTimingIdentification[VESA_BIOS_EXTENSIONS_STANDARD_TIMING_SIZE]; + UINT8 DetailedTimingDescriptions[VESA_BIOS_EXTENSIONS_DETAILED_TIMING_DESCRIPTOR_MAX_SIZE]; UINT8 ExtensionFlag; //Number of (optional) 128-byte EDID extension blocks to follow UINT8 Checksum; } VESA_BIOS_EXTENSIONS_EDID_DATA_BLOCK;