1. add DxeI2c Library in OptionRomPkg.
authorvanjeff <vanjeff@6f19259b-4bc3-4df7-8a09-765794883524>
Thu, 3 Jan 2008 06:44:03 +0000 (06:44 +0000)
committervanjeff <vanjeff@6f19259b-4bc3-4df7-8a09-765794883524>
Thu, 3 Jan 2008 06:44:03 +0000 (06:44 +0000)
2. produce EFI_EDID_DISCOVERED_PROTOCOL and EFI_EDID_ACTIVE_PROTOCOL in CirrusLogic5430 module.
3. consume EFI_OVERRIDE_PROTOCOL in CirrusLogic5430 module.
4. setup video mode according to EDID information in CirrusLogic5430 module.

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@4479 6f19259b-4bc3-4df7-8a09-765794883524

OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430.c
OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430.h
OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430Dxe.inf
OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430GraphicsOutput.c
OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430UgaDraw.c
OptionRomPkg/CirrusLogic5430Dxe/Edid.c [new file with mode: 0644]
OptionRomPkg/Include/Library/DxeI2cLib.h [new file with mode: 0644]
OptionRomPkg/Library/CirrusLogicI2cLib/CirrusLogic5430I2cLib.c [new file with mode: 0644]
OptionRomPkg/Library/CirrusLogicI2cLib/CirrusLogic5430I2cLib.inf [new file with mode: 0644]
OptionRomPkg/OptionRomPkg.dec
OptionRomPkg/OptionRomPkg.dsc

index 424e19d..1507b55 100644 (file)
@@ -106,6 +106,7 @@ CIRRUS_LOGIC_5430_VIDEO_MODES  CirrusLogic5430VideoModes[] = {
   { 1024, 768, 8, 60, Crtc_1024_768_256_60, Seq_1024_768_256_60, 0xef }\r
 };\r
 \r
+\r
 /**\r
   CirrusLogic5430ControllerDriverSupported\r
 \r
@@ -212,6 +213,8 @@ CirrusLogic5430ControllerDriverStart (
   EFI_STATUS                      Status;\r
   CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private;\r
   BOOLEAN                         PciAttributesSaved;\r
+  EFI_DEVICE_PATH_PROTOCOL        *ParentDevicePath;\r
+  ACPI_ADR_DEVICE_PATH            AcpiDeviceNode;\r
 \r
   PciAttributesSaved = FALSE;\r
   //\r
@@ -227,7 +230,7 @@ CirrusLogic5430ControllerDriverStart (
   // Set up context record\r
   //\r
   Private->Signature  = CIRRUS_LOGIC_5430_PRIVATE_DATA_SIGNATURE;\r
-  Private->Handle     = Controller;\r
+  Private->Handle     = NULL;\r
 \r
   //\r
   // Open PCI I/O Protocol\r
@@ -269,52 +272,98 @@ CirrusLogic5430ControllerDriverStart (
     goto Error;\r
   }\r
 \r
+  //\r
+  // Get ParentDevicePath\r
+  //\r
+  Status = gBS->HandleProtocol (\r
+                  Controller,\r
+                  &gEfiDevicePathProtocolGuid,\r
+                  (VOID **) &ParentDevicePath\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    goto Error;\r
+  }\r
+\r
+  if (FeaturePcdGet (PcdSupportGop)) {\r
+    //\r
+    // Set Gop Device Path\r
+    //\r
+    if (RemainingDevicePath == NULL) {\r
+      ZeroMem (&AcpiDeviceNode, sizeof (ACPI_ADR_DEVICE_PATH));\r
+      AcpiDeviceNode.Header.Type = ACPI_DEVICE_PATH;\r
+      AcpiDeviceNode.Header.SubType = ACPI_ADR_DP;\r
+      AcpiDeviceNode.ADR = ACPI_DISPLAY_ADR (1, 0, 0, 1, 0, ACPI_ADR_DISPLAY_TYPE_VGA, 0, 0);\r
+      SetDevicePathNodeLength (&AcpiDeviceNode.Header, sizeof (ACPI_ADR_DEVICE_PATH));\r
+\r
+      Private->GopDevicePath = AppendDevicePathNode (\r
+                                          ParentDevicePath,\r
+                                          (EFI_DEVICE_PATH_PROTOCOL *) &AcpiDeviceNode\r
+                                          );\r
+    } else {\r
+      Private->GopDevicePath = AppendDevicePathNode (ParentDevicePath, RemainingDevicePath);\r
+    }\r
+\r
+    //\r
+    // Creat child handle and device path protocol firstly\r
+    //\r
+    Private->Handle = NULL;\r
+    Status = gBS->InstallMultipleProtocolInterfaces (\r
+                    &Private->Handle,\r
+                    &gEfiDevicePathProtocolGuid,\r
+                    Private->GopDevicePath,\r
+                    NULL\r
+                    );\r
+  }\r
+\r
+  //\r
+  // Construct video mode buffer\r
+  //\r
+  Status = CirrusLogic5430VideoModeSetup (Private);\r
+  if (EFI_ERROR (Status)) {\r
+    goto Error;\r
+  }\r
+\r
   if (FeaturePcdGet (PcdSupportUga)) {\r
     //\r
     // Start the UGA Draw software stack.\r
     //\r
     Status = CirrusLogic5430UgaDrawConstructor (Private);\r
     ASSERT_EFI_ERROR (Status);\r
-    if (FeaturePcdGet (PcdSupportGop)) {\r
-      Status = CirrusLogic5430GraphicsOutputConstructor (Private);\r
-      ASSERT_EFI_ERROR (Status);\r
 \r
-      Status = gBS->InstallMultipleProtocolInterfaces (\r
-                      &Private->Handle,\r
-                      &gEfiUgaDrawProtocolGuid,\r
-                      &Private->UgaDraw,\r
-                      &gEfiGraphicsOutputProtocolGuid,\r
-                      &Private->GraphicsOutput,\r
-                      NULL\r
-                      );\r
-    } else {\r
-      Status = gBS->InstallMultipleProtocolInterfaces (\r
-                      &Private->Handle,\r
-                      &gEfiUgaDrawProtocolGuid,\r
-                      &Private->UgaDraw,\r
-                      NULL\r
-                      );\r
+    Private->UgaDevicePath = ParentDevicePath;\r
+    Status = gBS->InstallMultipleProtocolInterfaces (\r
+                    &Controller,\r
+                    &gEfiUgaDrawProtocolGuid,\r
+                    &Private->UgaDraw,\r
+                    &gEfiDevicePathProtocolGuid,\r
+                    Private->UgaDevicePath,\r
+                    NULL\r
+                    );\r
 \r
-    }\r
-  } else {\r
-    if (FeaturePcdGet (PcdSupportGop)) {\r
-      Status = CirrusLogic5430GraphicsOutputConstructor (Private);\r
-      ASSERT_EFI_ERROR (Status);\r
+  } else if (FeaturePcdGet (PcdSupportGop)) {\r
+    //\r
+    // Start the GOP software stack.\r
+    //\r
+    Status = CirrusLogic5430GraphicsOutputConstructor (Private);\r
+    ASSERT_EFI_ERROR (Status);\r
 \r
-      Status = gBS->InstallMultipleProtocolInterfaces (\r
-                      &Private->Handle,\r
-                      &gEfiGraphicsOutputProtocolGuid,\r
-                      &Private->GraphicsOutput,\r
-                      NULL\r
-                      );\r
+    Status = gBS->InstallMultipleProtocolInterfaces (\r
+                    &Private->Handle,\r
+                    &gEfiGraphicsOutputProtocolGuid,\r
+                    &Private->GraphicsOutput,\r
+                    &gEfiEdidDiscoveredProtocolGuid,\r
+                    &Private->EdidDiscovered,\r
+                    &gEfiEdidActiveProtocolGuid,\r
+                    &Private->EdidActive,\r
+                    NULL\r
+                    );\r
 \r
-    } else {\r
-      //\r
-      // This driver must support eithor GOP or UGA or both.\r
-      //\r
-      ASSERT (FALSE);\r
-      Status = EFI_UNSUPPORTED;\r
-    }\r
+  } else {\r
+    //\r
+    // This driver must support eithor GOP or UGA or both.\r
+    //\r
+    ASSERT (FALSE);\r
+    Status = EFI_UNSUPPORTED;\r
   }\r
 \r
 \r
index 719cf7c..f7d9282 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   Cirrus Logic 5430 Controller Driver\r
 \r
-  Copyright (c) 2006, Intel Corporation\r
+  Copyright (c) 2006 - 2007, Intel Corporation\r
   All rights reserved. This program and the accompanying materials\r
   are licensed and made available under the terms and conditions of the BSD License\r
   which accompanies this distribution.  The full text of the license may be found at\r
 #include <Protocol/GraphicsOutput.h>\r
 #include <Protocol/PciIo.h>\r
 #include <Protocol/DriverSupportedEfiVersion.h>\r
+#include <Protocol/EdidOverride.h>\r
+#include <Protocol/EdidDiscovered.h>\r
+#include <Protocol/EdidActive.h>\r
+#include <Protocol/DevicePath.h>\r
 \r
 #include <Library/DebugLib.h>\r
 #include <Library/UefiDriverEntryPoint.h>\r
@@ -32,6 +36,9 @@
 #include <Library/PcdLib.h>\r
 #include <Library/MemoryAllocationLib.h>\r
 #include <Library/UefiBootServicesTableLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/DevicePathLib.h>\r
+#include <Library/DxeI2cLib.h>\r
 \r
 #include <IndustryStandard/pci22.h>\r
 //\r
@@ -48,6 +55,7 @@
 #define CIRRUS_LOGIC_5430_MODE_COUNT         3\r
 \r
 typedef struct {\r
+  UINT32  ModeNumber;\r
   UINT32  HorizontalResolution;\r
   UINT32  VerticalResolution;\r
   UINT32  ColorDepth;\r
@@ -68,6 +76,10 @@ typedef struct {
   UINT64                                OriginalPciAttributes;\r
   EFI_UGA_DRAW_PROTOCOL                 UgaDraw;\r
   EFI_GRAPHICS_OUTPUT_PROTOCOL          GraphicsOutput;\r
+  EFI_EDID_DISCOVERED_PROTOCOL          EdidDiscovered;\r
+  EFI_EDID_ACTIVE_PROTOCOL              EdidActive;\r
+  EFI_DEVICE_PATH_PROTOCOL              *GopDevicePath;\r
+  EFI_DEVICE_PATH_PROTOCOL              *UgaDevicePath;\r
   UINTN                                 CurrentMode;\r
   UINTN                                 MaxMode;\r
   CIRRUS_LOGIC_5430_MODE_DATA           ModeData[CIRRUS_LOGIC_5430_MODE_COUNT];\r
@@ -128,6 +140,18 @@ extern EFI_DRIVER_SUPPORTED_EFI_VERSION_PROTOCOL  gCirrusLogic5430DriverSupporte
 #define PALETTE_INDEX_REGISTER  0x3c8\r
 #define PALETTE_DATA_REGISTER   0x3c9\r
 \r
+#define ACPI_ADR_DISPLAY_TYPE_VGA               1\r
+\r
+#define ACPI_DISPLAY_ADR(_DeviceIdScheme, _HeadId, _NonVgaOutput, _BiosCanDetect, _VendorInfo, _Type, _Port, _Index) \\r
+          ((UINT32) ( (((_DeviceIdScheme) & 0x1) << 31) |  \\r
+                      (((_HeadId)         & 0x7) << 18) |  \\r
+                      (((_NonVgaOutput)   & 0x1) << 17) |  \\r
+                      (((_BiosCanDetect)  & 0x1) << 16) |  \\r
+                      (((_VendorInfo)     & 0xf) << 12) |  \\r
+                      (((_Type)           & 0xf) << 8)  |  \\r
+                      (((_Port)           & 0xf) << 4)  |  \\r
+                       ((_Index)          & 0xf) ))\r
+\r
 //\r
 // UGA Draw Hardware abstraction internal worker functions\r
 //\r
@@ -407,4 +431,9 @@ inw (
   UINTN                           Address\r
   );\r
 \r
+EFI_STATUS\r
+CirrusLogic5430VideoModeSetup (\r
+  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private\r
+  );\r
+\r
 #endif\r
index 8749727..dca2b11 100644 (file)
@@ -37,8 +37,8 @@
 #\r
 #  VALID_ARCHITECTURES           = IA32 X64 IPF EBC\r
 #\r
-#  DRIVER_BINDING                =  gCirrusLogic5430DriverBinding                \r
-#  COMPONENT_NAME                =  gCirrusLogic5430ComponentName                \r
+#  DRIVER_BINDING                =  gCirrusLogic5430DriverBinding\r
+#  COMPONENT_NAME                =  gCirrusLogic5430ComponentName\r
 #\r
 \r
 [Sources.common]\r
@@ -48,6 +48,7 @@
   CirrusLogic5430GraphicsOutput.c\r
   CirrusLogic5430.c\r
   CirrusLogic5430.h\r
+  Edid.c\r
 \r
 [Packages]\r
   MdePkg/MdePkg.dec\r
   UefiLib\r
   UefiDriverEntryPoint\r
   DebugLib\r
-\r
+  BaseMemoryLib\r
+  DevicePathLib\r
+  DxeI2cLib\r
 \r
 [Protocols]\r
   gEfiDriverSupportedEfiVersionProtocolGuid     # PROTOCOL ALWAYS_PRODUCED\r
   gEfiUgaDrawProtocolGuid                       # PROTOCOL BY_START\r
   gEfiGraphicsOutputProtocolGuid                # PROTOCOL BY_START\r
+  gEfiEdidDiscoveredProtocolGuid                # PROTOCOL BY_START\r
+  gEfiEdidActiveProtocolGuid                    # PROTOCOL BY_START\r
+  gEfiDevicePathProtocolGuid                    # PROTOCOL BY_START\r
   gEfiPciIoProtocolGuid                         # PROTOCOL TO_START\r
-  \r
+  gEfiEdidOverrideProtocolGuid                  # PROTOCOL TO_START\r
+\r
+\r
 [FeaturePcd.common]\r
   gOptionRomPkgTokenSpaceGuid.PcdSupportGop\r
   gOptionRomPkgTokenSpaceGuid.PcdSupportUga\r
index 7fdb3e0..b639edb 100644 (file)
@@ -1,13 +1,13 @@
 /*++\r
 \r
-Copyright (c) 2007, Intel Corporation                                                         \r
-All rights reserved. This program and the accompanying materials                          \r
-are licensed and made available under the terms and conditions of the BSD License         \r
-which accompanies this distribution.  The full text of the license may be found at        \r
-http://opensource.org/licenses/bsd-license.php                                            \r
-                                                                                          \r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+Copyright (c) 2007, Intel Corporation\r
+All rights reserved. This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
 \r
 Module Name:\r
 \r
@@ -15,8 +15,8 @@ Module Name:
 \r
 Abstract:\r
 \r
-  This file produces the graphics abstration of Graphics Output Protocol. It is called by \r
-  CirrusLogic5430.c file which deals with the EFI 1.1 driver model. \r
+  This file produces the graphics abstration of Graphics Output Protocol. It is called by\r
+  CirrusLogic5430.c file which deals with the EFI 1.1 driver model.\r
   This file just does graphics.\r
 \r
 --*/\r
@@ -127,7 +127,7 @@ Routine Description:
     return EFI_OUT_OF_RESOURCES;\r
   }\r
 \r
-  InitializeGraphicsMode (Private, &CirrusLogic5430VideoModes[ModeNumber]);\r
+  InitializeGraphicsMode (Private, &CirrusLogic5430VideoModes[ModeData->ModeNumber]);\r
 \r
   This->Mode->Mode = ModeNumber;\r
   This->Mode->Info->HorizontalResolution = ModeData->HorizontalResolution;\r
@@ -444,7 +444,6 @@ CirrusLogic5430GraphicsOutputConstructor (
 {\r
   EFI_STATUS                   Status;\r
   EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;\r
-  UINTN                        Index;\r
 \r
 \r
   GraphicsOutput            = &Private->GraphicsOutput;\r
@@ -471,17 +470,10 @@ CirrusLogic5430GraphicsOutputConstructor (
   if (EFI_ERROR (Status)) {\r
     return Status;\r
   }\r
-  Private->GraphicsOutput.Mode->MaxMode = CIRRUS_LOGIC_5430_MODE_COUNT;\r
-  Private->GraphicsOutput.Mode->Mode = GRAPHICS_OUTPUT_INVALIDE_MODE_NUMBER;\r
-  for (Index = 0; Index < Private->GraphicsOutput.Mode->MaxMode; Index++) {\r
-    Private->ModeData[Index].HorizontalResolution = CirrusLogic5430VideoModes[Index].Width;\r
-    Private->ModeData[Index].VerticalResolution   = CirrusLogic5430VideoModes[Index].Height;\r
-    Private->ModeData[Index].ColorDepth           = 32;\r
-    Private->ModeData[Index].RefreshRate          = CirrusLogic5430VideoModes[Index].RefreshRate;\r
-  }\r
-\r
-  Private->HardwareNeedsStarting  = TRUE;\r
-  Private->LineBuffer             = NULL;\r
+  Private->GraphicsOutput.Mode->MaxMode = (UINT32) Private->MaxMode;\r
+  Private->GraphicsOutput.Mode->Mode    = GRAPHICS_OUTPUT_INVALIDE_MODE_NUMBER;\r
+  Private->HardwareNeedsStarting        = TRUE;\r
+  Private->LineBuffer                   = NULL;\r
 \r
   //\r
   // Initialize the hardware\r
index 75b1d24..59613fb 100644 (file)
@@ -1,16 +1,16 @@
 /** @file\r
-  This file produces the graphics abstration of UGA Draw. It is called by \r
-  CirrusLogic5430.c file which deals with the EFI 1.1 driver model. \r
+  This file produces the graphics abstration of UGA Draw. It is called by\r
+  CirrusLogic5430.c file which deals with the EFI 1.1 driver model.\r
   This file just does graphics.\r
 \r
-  Copyright (c) 2006, Intel Corporation                                                         \r
-  All rights reserved. This program and the accompanying materials                          \r
-  are licensed and made available under the terms and conditions of the BSD License         \r
-  which accompanies this distribution.  The full text of the license may be found at        \r
-  http://opensource.org/licenses/bsd-license.php                                            \r
+  Copyright (c) 2006, Intel Corporation\r
+  All rights reserved. This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php\r
 \r
-  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
-  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
 \r
 **/\r
 \r
@@ -95,7 +95,7 @@ CirrusLogic5430UgaDrawSetMode (
       return EFI_OUT_OF_RESOURCES;\r
     }\r
 \r
-    InitializeGraphicsMode (Private, &CirrusLogic5430VideoModes[Index]);\r
+    InitializeGraphicsMode (Private, &CirrusLogic5430VideoModes[Private->ModeData[Index].ModeNumber]);\r
 \r
     Private->CurrentMode            = Index;\r
 \r
@@ -380,7 +380,6 @@ CirrusLogic5430UgaDrawConstructor (
   )\r
 {\r
   EFI_UGA_DRAW_PROTOCOL *UgaDraw;\r
-  UINTN                 Index;\r
 \r
   //\r
   // Fill in Private->UgaDraw protocol\r
@@ -394,15 +393,7 @@ CirrusLogic5430UgaDrawConstructor (
   //\r
   // Initialize the private data\r
   //\r
-  Private->MaxMode      = CIRRUS_LOGIC_5430_MODE_COUNT;\r
-  Private->CurrentMode  = 0;\r
-  for (Index = 0; Index < Private->MaxMode; Index++) {\r
-    Private->ModeData[Index].HorizontalResolution = CirrusLogic5430VideoModes[Index].Width;\r
-    Private->ModeData[Index].VerticalResolution   = CirrusLogic5430VideoModes[Index].Height;\r
-    Private->ModeData[Index].ColorDepth           = 32;\r
-    Private->ModeData[Index].RefreshRate          = CirrusLogic5430VideoModes[Index].RefreshRate;\r
-  }\r
-\r
+  Private->CurrentMode            = 0;\r
   Private->HardwareNeedsStarting  = TRUE;\r
   Private->LineBuffer             = NULL;\r
 \r
diff --git a/OptionRomPkg/CirrusLogic5430Dxe/Edid.c b/OptionRomPkg/CirrusLogic5430Dxe/Edid.c
new file mode 100644 (file)
index 0000000..4ef733b
--- /dev/null
@@ -0,0 +1,531 @@
+/** @file\r
+  Read EDID information and parse EDID information.\r
+\r
+  Copyright (c) 2008, Intel Corporation\r
+  All rights reserved. This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include "CirrusLogic5430.h"\r
+\r
+//\r
+// EDID block\r
+//\r
+typedef struct {\r
+  UINT8   Header[8];                        //EDID header "00 FF FF FF FF FF FF 00"\r
+  UINT16  ManufactureName;                  //EISA 3-character ID\r
+  UINT16  ProductCode;                      //Vendor assigned code\r
+  UINT32  SerialNumber;                     //32-bit serial number\r
+  UINT8   WeekOfManufacture;                //Week number\r
+  UINT8   YearOfManufacture;                //Year\r
+  UINT8   EdidVersion;                      //EDID Structure Version\r
+  UINT8   EdidRevision;                     //EDID Structure Revision\r
+  UINT8   VideoInputDefinition;\r
+  UINT8   MaxHorizontalImageSize;           //cm\r
+  UINT8   MaxVerticalImageSize;             //cm\r
+  UINT8   DisplayTransferCharacteristic;\r
+  UINT8   FeatureSupport;\r
+  UINT8   RedGreenLowBits;                  //Rx1 Rx0 Ry1 Ry0 Gx1 Gx0 Gy1Gy0\r
+  UINT8   BlueWhiteLowBits;                 //Bx1 Bx0 By1 By0 Wx1 Wx0 Wy1 Wy0\r
+  UINT8   RedX;                             //Red-x Bits 9 - 2\r
+  UINT8   RedY;                             //Red-y Bits 9 - 2\r
+  UINT8   GreenX;                           //Green-x Bits 9 - 2\r
+  UINT8   GreenY;                           //Green-y Bits 9 - 2\r
+  UINT8   BlueX;                            //Blue-x Bits 9 - 2\r
+  UINT8   BlueY;                            //Blue-y Bits 9 - 2\r
+  UINT8   WhiteX;                           //White-x Bits 9 - 2\r
+  UINT8   WhiteY;                           //White-x Bits 9 - 2\r
+  UINT8   EstablishedTimings[3];\r
+  UINT8   StandardTimingIdentification[16];\r
+  UINT8   DetailedTimingDescriptions[72];\r
+  UINT8   ExtensionFlag;                    //Number of (optional) 128-byte EDID extension blocks to follow\r
+  UINT8   Checksum;\r
+} EDID_BLOCK;\r
+\r
+#define EDID_BLOCK_SIZE                        128\r
+#define VBE_EDID_ESTABLISHED_TIMING_MAX_NUMBER 17\r
+\r
+typedef struct {\r
+  UINT16  HorizontalResolution;\r
+  UINT16  VerticalResolution;\r
+  UINT16  RefreshRate;\r
+} EDID_TIMING;\r
+\r
+typedef struct {\r
+  UINT32  ValidNumber;\r
+  UINT32  Key[VBE_EDID_ESTABLISHED_TIMING_MAX_NUMBER];\r
+} VALID_EDID_TIMING;\r
+\r
+//\r
+// Standard timing defined by VESA EDID\r
+//\r
+EDID_TIMING mVbeEstablishedEdidTiming[] = {\r
+  //\r
+  // Established Timing I\r
+  //\r
+  {800, 600, 60},\r
+  {800, 600, 56},\r
+  {640, 480, 75},\r
+  {640, 480, 72},\r
+  {640, 480, 67},\r
+  {640, 480, 60},\r
+  {720, 400, 88},\r
+  {720, 400, 70},\r
+  //\r
+  // Established Timing II\r
+  //\r
+  {1280, 1024, 75},\r
+  {1024,  768, 75},\r
+  {1024,  768, 70},\r
+  {1024,  768, 60},\r
+  {1024,  768, 87},\r
+  {832,   624, 75},\r
+  {800,   600, 75},\r
+  {800,   600, 72},\r
+  //\r
+  // Established Timing III\r
+  //\r
+  {1152, 870, 75}\r
+};\r
+\r
+/**\r
+  Read EDID information from I2C Bus on CirrusLogic.\r
+\r
+  @param  Private             Pointer to CIRRUS_LOGIC_5430_PRIVATE_DATA.\r
+  @param  EdidDataBlock       Pointer to EDID data block.\r
+  @param  EdidSize            Returned EDID block size.\r
+\r
+  @retval EFI_UNSUPPORTED\r
+  @retval EFI_SUCCESS\r
+\r
+**/\r
+STATIC\r
+EFI_STATUS\r
+ReadEdidData (\r
+  CIRRUS_LOGIC_5430_PRIVATE_DATA     *Private,\r
+  UINT8                              **EdidDataBlock,\r
+  UINTN                              *EdidSize\r
+  )\r
+{\r
+  UINT8             Index;\r
+  UINT8             EdidData[EDID_BLOCK_SIZE * 2];\r
+  UINT8             *ValidEdid;\r
+  UINT64            Signature;\r
+\r
+  for (Index = 0; Index < EDID_BLOCK_SIZE * 2; Index ++) {\r
+    I2cReadByte (Private->PciIo, 0xa0, Index, &EdidData[Index]);\r
+  }\r
+\r
+  //\r
+  // Search for the EDID signature\r
+  //\r
+  ValidEdid = &EdidData[0];\r
+  Signature = 0x00ffffffffffff00ull;\r
+  for (Index = 0; Index < EDID_BLOCK_SIZE * 2; Index ++, ValidEdid ++) {\r
+    if (CompareMem (ValidEdid, &Signature, 8) == 0) {\r
+      break;\r
+    }\r
+  }\r
+\r
+  if (Index == 256) {\r
+    //\r
+    // No EDID signature found\r
+    //\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  *EdidDataBlock = AllocateCopyPool (\r
+                     sizeof (EDID_BLOCK_SIZE),\r
+                     ValidEdid\r
+                     );\r
+  if (*EdidDataBlock == NULL) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+\r
+  //\r
+  // Currently only support EDID 1.x\r
+  //\r
+  *EdidSize = EDID_BLOCK_SIZE;\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Generate a search key for a specified timing data.\r
+\r
+  @param  EdidTiming             Pointer to EDID timing\r
+\r
+  @return The 32 bit unique key for search.\r
+\r
+**/\r
+STATIC\r
+UINT32\r
+CalculateEdidKey (\r
+  EDID_TIMING       *EdidTiming\r
+  )\r
+{\r
+  UINT32 Key;\r
+\r
+  //\r
+  // Be sure no conflicts for all standard timing defined by VESA.\r
+  //\r
+  Key = (EdidTiming->HorizontalResolution * 2) + EdidTiming->VerticalResolution;\r
+  return Key;\r
+}\r
+\r
+/**\r
+  Search a specified Timing in all the valid EDID timings.\r
+\r
+  @param  ValidEdidTiming        All valid EDID timing information.\r
+  @param  EdidTiming             The Timing to search for.\r
+\r
+  @retval TRUE                   Found.\r
+  @retval FALSE                  Not found.\r
+\r
+**/\r
+STATIC\r
+BOOLEAN\r
+SearchEdidTiming (\r
+  VALID_EDID_TIMING *ValidEdidTiming,\r
+  EDID_TIMING       *EdidTiming\r
+  )\r
+{\r
+  UINT32 Index;\r
+  UINT32 Key;\r
+\r
+  Key = CalculateEdidKey (EdidTiming);\r
+\r
+  for (Index = 0; Index < ValidEdidTiming->ValidNumber; Index ++) {\r
+    if (Key == ValidEdidTiming->Key[Index]) {\r
+      return TRUE;\r
+    }\r
+  }\r
+\r
+  return FALSE;\r
+}\r
+\r
+/**\r
+  Parse the Established Timing and Standard Timing in EDID data block.\r
+\r
+  @param  EdidBuffer             Pointer to EDID data block\r
+  @param  ValidEdidTiming        Valid EDID timing information\r
+\r
+  @retval TRUE                   The EDID data is valid.\r
+  @retval FALSE                  The EDID data is invalid.\r
+\r
+**/\r
+STATIC\r
+BOOLEAN\r
+ParseEdidData (\r
+  UINT8                         *EdidBuffer,\r
+  VALID_EDID_TIMING             *ValidEdidTiming\r
+  )\r
+{\r
+  UINT8        CheckSum;\r
+  UINT32       Index;\r
+  UINT32       ValidNumber;\r
+  UINT32       TimingBits;\r
+  UINT8        *BufferIndex;\r
+  UINT16       HorizontalResolution;\r
+  UINT16       VerticalResolution;\r
+  UINT8        AspectRatio;\r
+  UINT8        RefreshRate;\r
+  EDID_TIMING  TempTiming;\r
+  EDID_BLOCK   *EdidDataBlock;\r
+\r
+  EdidDataBlock = (EDID_BLOCK *) EdidBuffer;\r
+\r
+  //\r
+  // Check the checksum of EDID data\r
+  //\r
+  CheckSum = 0;\r
+  for (Index = 0; Index < EDID_BLOCK_SIZE; Index ++) {\r
+    CheckSum = (UINT8) (CheckSum + EdidBuffer[Index]);\r
+  }\r
+  if (CheckSum != 0) {\r
+    return FALSE;\r
+  }\r
+\r
+  ValidNumber = 0;\r
+  SetMem (ValidEdidTiming, sizeof (VALID_EDID_TIMING), 0);\r
+\r
+  if ((EdidDataBlock->EstablishedTimings[0] != 0) ||\r
+      (EdidDataBlock->EstablishedTimings[1] != 0) ||\r
+      (EdidDataBlock->EstablishedTimings[2] != 0)\r
+      ) {\r
+    //\r
+    // Established timing data\r
+    //\r
+    TimingBits = EdidDataBlock->EstablishedTimings[0] |\r
+                 (EdidDataBlock->EstablishedTimings[1] << 8) |\r
+                 ((EdidDataBlock->EstablishedTimings[2] & 0x80) << 9) ;\r
+    for (Index = 0; Index < VBE_EDID_ESTABLISHED_TIMING_MAX_NUMBER; Index ++) {\r
+      if (TimingBits & 0x1) {\r
+        ValidEdidTiming->Key[ValidNumber] = CalculateEdidKey (&mVbeEstablishedEdidTiming[Index]);\r
+        ValidNumber ++;\r
+      }\r
+      TimingBits = TimingBits >> 1;\r
+    }\r
+  } else {\r
+    //\r
+    // If no Established timing data, read the standard timing data\r
+    //\r
+    BufferIndex = &EdidDataBlock->StandardTimingIdentification[0];\r
+    for (Index = 0; Index < 8; Index ++) {\r
+      if ((BufferIndex[0] != 0x1) && (BufferIndex[1] != 0x1)){\r
+        //\r
+        // A valid Standard Timing\r
+        //\r
+        HorizontalResolution = (UINT16) (BufferIndex[0] * 8 + 248);\r
+        AspectRatio = (UINT8) (BufferIndex[1] >> 6);\r
+        switch (AspectRatio) {\r
+          case 0:\r
+            VerticalResolution = (UINT16) (HorizontalResolution / 16 * 10);\r
+            break;\r
+          case 1:\r
+            VerticalResolution = (UINT16) (HorizontalResolution / 4 * 3);\r
+            break;\r
+          case 2:\r
+            VerticalResolution = (UINT16) (HorizontalResolution / 5 * 4);\r
+            break;\r
+          case 3:\r
+            VerticalResolution = (UINT16) (HorizontalResolution / 16 * 9);\r
+            break;\r
+          default:\r
+            VerticalResolution = (UINT16) (HorizontalResolution / 4 * 3);\r
+            break;\r
+        }\r
+        RefreshRate = (UINT8) ((BufferIndex[1] & 0x1f) + 60);\r
+        TempTiming.HorizontalResolution = HorizontalResolution;\r
+        TempTiming.VerticalResolution = VerticalResolution;\r
+        TempTiming.RefreshRate = RefreshRate;\r
+        ValidEdidTiming->Key[ValidNumber] = CalculateEdidKey (&TempTiming);\r
+        ValidNumber ++;\r
+      }\r
+      BufferIndex += 2;\r
+    }\r
+  }\r
+\r
+  ValidEdidTiming->ValidNumber = ValidNumber;\r
+  return TRUE;\r
+}\r
+\r
+/**\r
+  Construct the valid video modes for CirrusLogic5430.\r
+\r
+**/\r
+EFI_STATUS\r
+CirrusLogic5430VideoModeSetup (\r
+  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private\r
+  )\r
+{\r
+  EFI_STATUS                             Status;\r
+  UINT32                                 Index;\r
+  BOOLEAN                                EdidFound;\r
+  EFI_EDID_OVERRIDE_PROTOCOL             *EdidOverride;\r
+  UINT32                                 EdidAttributes;\r
+  BOOLEAN                                EdidOverrideFound;\r
+  UINTN                                  EdidOverrideDataSize;\r
+  UINT8                                  *EdidOverrideDataBlock;\r
+  UINTN                                  EdidDiscoveredDataSize;\r
+  UINT8                                  *EdidDiscoveredDataBlock;\r
+  UINTN                                  EdidActiveDataSize;\r
+  UINT8                                  *EdidActiveDataBlock;\r
+  VALID_EDID_TIMING                      ValidEdidTiming;\r
+  UINT32                                 ValidModeCount;\r
+  CIRRUS_LOGIC_5430_MODE_DATA            *ModeData;\r
+  BOOLEAN                                TimingMatch;\r
+  CIRRUS_LOGIC_5430_VIDEO_MODES          *VideoMode;\r
+  EDID_TIMING                            TempTiming;\r
+\r
+  //\r
+  // setup EDID information\r
+  //\r
+  Private->EdidDiscovered.Edid       = NULL;\r
+  Private->EdidDiscovered.SizeOfEdid = 0;\r
+  Private->EdidActive.Edid           = NULL;\r
+  Private->EdidActive.SizeOfEdid     = 0;\r
+\r
+  EdidFound               = FALSE;\r
+  EdidOverrideFound       = FALSE;\r
+  EdidAttributes          = 0xff;\r
+  EdidOverrideDataSize    = 0;\r
+  EdidOverrideDataBlock   = NULL;\r
+  EdidActiveDataSize      = 0;\r
+  EdidActiveDataBlock     = NULL;\r
+  EdidDiscoveredDataBlock = NULL;\r
+\r
+  //\r
+  // Find EDID Override protocol firstly, this protocol is installed by platform if needed.\r
+  //\r
+  Status = gBS->LocateProtocol (\r
+                   &gEfiEdidOverrideProtocolGuid,\r
+                   NULL,\r
+                   (VOID **) &EdidOverride\r
+                   );\r
+  if (!EFI_ERROR (Status)) {\r
+    //\r
+    // Allocate double size of VESA_BIOS_EXTENSIONS_EDID_BLOCK_SIZE to avoid overflow\r
+    //\r
+    EdidOverrideDataBlock = AllocatePool (sizeof (EDID_BLOCK_SIZE * 2));\r
+    if (NULL == EdidOverrideDataBlock) {\r
+               Status = EFI_OUT_OF_RESOURCES;\r
+      goto Done;\r
+    }\r
+\r
+    Status = EdidOverride->GetEdid (\r
+                             EdidOverride,\r
+                             Private->Handle,\r
+                             &EdidAttributes,\r
+                             &EdidOverrideDataSize,\r
+                             (UINT8 **) &EdidOverrideDataBlock\r
+                             );\r
+    if (!EFI_ERROR (Status)  &&\r
+         EdidAttributes == 0 &&\r
+         EdidOverrideDataSize != 0) {\r
+      //\r
+      // Succeeded to get EDID Override Data\r
+      //\r
+      EdidOverrideFound = TRUE;\r
+    }\r
+  }\r
+\r
+  if (EdidOverrideFound != TRUE || EdidAttributes == EFI_EDID_OVERRIDE_DONT_OVERRIDE) {\r
+    //\r
+    // If EDID Override data doesn't exist or EFI_EDID_OVERRIDE_DONT_OVERRIDE returned,\r
+    // read EDID information through I2C Bus\r
+    //\r
+    if (ReadEdidData (Private, &EdidDiscoveredDataBlock, &EdidDiscoveredDataSize) == EFI_SUCCESS) {;\r
+      Private->EdidDiscovered.SizeOfEdid = (UINT32) EdidDiscoveredDataSize;\r
+       Private->EdidDiscovered.Edid = (UINT8 *) AllocateCopyPool (\r
+                                                          EdidDiscoveredDataSize,\r
+                                                          EdidDiscoveredDataBlock\r
+                                                                                                                                                                                                                 );\r
+\r
+      if (NULL == Private->EdidDiscovered.Edid) {\r
+         Status = EFI_OUT_OF_RESOURCES;\r
+        goto Done;\r
+      }\r
+\r
+      EdidActiveDataSize  = Private->EdidDiscovered.SizeOfEdid;\r
+      EdidActiveDataBlock = Private->EdidDiscovered.Edid;\r
+\r
+      EdidFound = TRUE;\r
+    }\r
+  }\r
+\r
+  if (EdidFound != TRUE && EdidOverrideFound == TRUE) {\r
+    EdidActiveDataSize  = EdidOverrideDataSize;\r
+    EdidActiveDataBlock = EdidOverrideDataBlock;\r
+    EdidFound = TRUE;\r
+       }\r
+\r
+       if (EdidFound == TRUE) {\r
+    //\r
+    // Parse EDID data structure to retrieve modes supported by monitor\r
+    //\r
+    if (ParseEdidData ((UINT8 *) EdidActiveDataBlock, &ValidEdidTiming) == TRUE) {\r
+      //\r
+      // Copy EDID Override Data to EDID Active Data\r
+      //\r
+      Private->EdidActive.SizeOfEdid = (UINT32) EdidActiveDataSize;\r
+      Private->EdidActive.Edid = (UINT8 *) AllocateCopyPool (\r
+                                             EdidActiveDataSize,\r
+                                             EdidActiveDataBlock\r
+                                             );\r
+      if (NULL == Private->EdidActive.Edid) {\r
+                 Status = EFI_OUT_OF_RESOURCES;\r
+        goto Done;\r
+      }\r
+    }\r
+  } else {\r
+    Private->EdidActive.SizeOfEdid = 0;\r
+    Private->EdidActive.Edid = NULL;\r
+    EdidFound = FALSE;\r
+  }\r
+\r
+  if (EdidFound) {\r
+    //\r
+    // Initialize the private mode data with the supported modes.\r
+    //\r
+    ValidModeCount = 0;\r
+    ModeData = &Private->ModeData[0];\r
+    VideoMode = &CirrusLogic5430VideoModes[0];\r
+    for (Index = 0; Index < CIRRUS_LOGIC_5430_MODE_COUNT; Index++) {\r
+\r
+      TimingMatch = TRUE;\r
+\r
+      //\r
+      // Check whether match with CirrusLogic5430 video mode\r
+      //\r
+      TempTiming.HorizontalResolution = (UINT16) VideoMode->Width;\r
+      TempTiming.VerticalResolution   = (UINT16) VideoMode->Height;\r
+      TempTiming.RefreshRate          = (UINT16) VideoMode->RefreshRate;\r
+      if (SearchEdidTiming (&ValidEdidTiming, &TempTiming) != TRUE) {\r
+        TimingMatch = FALSE;\r
+      }\r
+\r
+      //\r
+      // Not export Mode 0x0 as GOP mode, this is not defined in spec.\r
+      //\r
+      if ((VideoMode->Width == 0) || (VideoMode->Height == 0)) {\r
+        TimingMatch = FALSE;\r
+      }\r
+\r
+      if (TimingMatch) {\r
+        ModeData->ModeNumber = Index;\r
+        ModeData->HorizontalResolution          = VideoMode->Width;\r
+        ModeData->VerticalResolution            = VideoMode->Height;\r
+        ModeData->ColorDepth                    = VideoMode->ColorDepth;\r
+        ModeData->RefreshRate                   = VideoMode->RefreshRate;\r
+\r
+        ModeData ++;\r
+        ValidModeCount ++;\r
+      }\r
+\r
+      VideoMode ++;\r
+    }\r
+\r
+    Private->MaxMode = ValidModeCount;\r
+\r
+  } else {\r
+    //\r
+    // If EDID information wasn't found\r
+    //\r
+    ModeData = &Private->ModeData[0];\r
+    VideoMode = &CirrusLogic5430VideoModes[0];\r
+    for (Index = 0; Index < CIRRUS_LOGIC_5430_MODE_COUNT; Index ++) {\r
+      ModeData->ModeNumber = Index;\r
+      ModeData->HorizontalResolution          = VideoMode->Width;\r
+      ModeData->VerticalResolution            = VideoMode->Height;\r
+      ModeData->ColorDepth                    = VideoMode->ColorDepth;\r
+      ModeData->RefreshRate                   = VideoMode->RefreshRate;\r
+\r
+      ModeData ++ ;\r
+      VideoMode ++;\r
+    }\r
+    Private->MaxMode = CIRRUS_LOGIC_5430_MODE_COUNT;\r
+  }\r
+\r
+  FreePool (EdidOverrideDataBlock);\r
+  return EFI_SUCCESS;\r
+\r
+Done:\r
+  if (EdidOverrideDataBlock != NULL) {\r
+    FreePool (EdidOverrideDataBlock);\r
+  }\r
+  if (Private->EdidDiscovered.Edid != NULL) {\r
+    FreePool (Private->EdidDiscovered.Edid);\r
+  }\r
+  if (Private->EdidDiscovered.Edid != NULL) {\r
+    FreePool (Private->EdidActive.Edid);\r
+  }\r
+\r
+  return EFI_DEVICE_ERROR;\r
+}\r
diff --git a/OptionRomPkg/Include/Library/DxeI2cLib.h b/OptionRomPkg/Include/Library/DxeI2cLib.h
new file mode 100644 (file)
index 0000000..5325560
--- /dev/null
@@ -0,0 +1,64 @@
+/** @file
+  I2c Bus byte read/write functions.
+
+  Copyright (c) 2008, Intel Corporation
+  All rights reserved. This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/\r
+\r
+#include <Protocol/PciIo.h>\r
+\r
+/**\r
+  Read one byte data on I2C Bus.\r
+\r
+  Read one byte data from the slave device connectet to I2C Bus.\r
+  If Data is NULL, then ASSERT().\r
+\r
+  @param  PciIo              The pointer to PCI_IO_PROTOCOL.\r
+  @param  DeviceAddress      Slave device's address.\r
+  @param  RegisterAddress    The register address on slave device.\r
+  @param  Data               The pointer to returned data if EFI_SUCCESS returned.\r
+\r
+  @retval EFI_DEVICE_ERROR\r
+  @retval EFI_SUCCESS\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+I2cReadByte (\r
+  EFI_PCI_IO_PROTOCOL    *PciIo,\r
+  UINT8                  DeviceAddress,\r
+  UINT8                  RegisterAddress,\r
+  UINT8                  *Data\r
+  );\r
+\r
+/**\r
+  Write one byte data onto I2C Bus.\r
+\r
+  Write one byte data to the slave device connectet to I2C Bus.\r
+  If Data is NULL, then ASSERT().\r
+\r
+  @param  PciIo              The pointer to PCI_IO_PROTOCOL.\r
+  @param  DeviceAddress      Slave device's address.\r
+  @param  RegisterAddress    The register address on slave device.\r
+  @param  Data               The pointer to write data.\r
+\r
+  @retval EFI_DEVICE_ERROR\r
+  @retval EFI_SUCCESS\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+I2cWriteByte (\r
+  EFI_PCI_IO_PROTOCOL    *PciIo,\r
+  UINT8                  DeviceAddress,\r
+  UINT8                  RegisterAddress,\r
+  UINT8                  *Data\r
+  );\r
+\r
diff --git a/OptionRomPkg/Library/CirrusLogicI2cLib/CirrusLogic5430I2cLib.c b/OptionRomPkg/Library/CirrusLogicI2cLib/CirrusLogic5430I2cLib.c
new file mode 100644 (file)
index 0000000..2a693ce
--- /dev/null
@@ -0,0 +1,447 @@
+/** @file\r
+  I2C Bus Libary implementation upon CirrusLogic.\r
+\r
+  Copyright (c) 2008, Intel Corporation\r
+  All rights reserved. This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <PiDxe.h>\r
+\r
+#include <Library/DxeI2cLib.h>\r
+#include <Library/TimerLib.h>\r
+#include <Library/DebugLib.h>\r
+\r
+#define SEQ_ADDRESS_REGISTER    0x3c4\r
+#define SEQ_DATA_REGISTER       0x3c5\r
+\r
+#define I2C_CONTROL             0x08\r
+#define I2CDAT_IN               7\r
+#define I2CCLK_IN               2\r
+#define I2CDAT_OUT              1\r
+#define I2CCLK_OUT              0\r
+\r
+#define I2C_BUS_SPEED           100  //100kbps\r
+\r
+/**\r
+  PCI I/O byte write function.\r
+\r
+  @param  PciIo        The pointer to PCI_IO_PROTOCOL.\r
+  @param  Address      The bit map of I2C Data or I2C Clock pins.\r
+  @param  Data         The date to write.\r
+\r
+**/\r
+STATIC\r
+VOID\r
+outb (\r
+  EFI_PCI_IO_PROTOCOL    *PciIo,\r
+  UINTN                  Address,\r
+  UINT8                  Data\r
+  )\r
+{\r
+  PciIo->Io.Write (\r
+             PciIo,\r
+             EfiPciIoWidthUint8,\r
+             EFI_PCI_IO_PASS_THROUGH_BAR,\r
+             Address,\r
+             1,\r
+             &Data\r
+             );\r
+}\r
+/**\r
+  PCI I/O byte read function.\r
+\r
+  @param  PciIo        The pointer to PCI_IO_PROTOCOL.\r
+  @param  Address      The bit map of I2C Data or I2C Clock pins.\r
+\r
+  return byte value read from PCI I/O space.\r
+\r
+**/\r
+STATIC\r
+UINT8\r
+inb (\r
+  EFI_PCI_IO_PROTOCOL    *PciIo,\r
+  UINTN                  Address\r
+  )\r
+{\r
+  UINT8 Data;\r
+\r
+  PciIo->Io.Read (\r
+             PciIo,\r
+             EfiPciIoWidthUint8,\r
+             EFI_PCI_IO_PASS_THROUGH_BAR,\r
+             Address,\r
+             1,\r
+             &Data\r
+             );\r
+  return Data;\r
+}\r
+\r
+/**\r
+  Read status of I2C Data and I2C Clock Pins.\r
+\r
+  @param  PciIo        The pointer to PCI_IO_PROTOCOL.\r
+  @param  Blt          The bit map of I2C Data or I2C Clock pins.\r
+\r
+  @retval 0            Low on I2C Data or I2C Clock Pin.\r
+  @retval 1            High on I2C Data or I2C Clock Pin.\r
+\r
+**/\r
+STATIC\r
+UINT8\r
+I2cPinRead (\r
+  EFI_PCI_IO_PROTOCOL    *PciIo,\r
+  UINT8                  Bit\r
+  )\r
+{\r
+  outb (PciIo, SEQ_ADDRESS_REGISTER, I2C_CONTROL);\r
+  return (UINT8) ((inb (PciIo, SEQ_DATA_REGISTER) >> Bit ) & 0xfe);\r
+}\r
+\r
+\r
+/**\r
+  Set/Clear I2C Data and I2C Clock Pins.\r
+\r
+  @param  PciIo              The pointer to PCI_IO_PROTOCOL.\r
+  @param  Blt                The bit map to controller I2C Data or I2C Clock pins.\r
+  @param  Value              1 or 0 stands for Set or Clear I2C Data and I2C Clock Pins.\r
+\r
+**/\r
+STATIC\r
+VOID\r
+I2cPinWrite (\r
+  EFI_PCI_IO_PROTOCOL    *PciIo,\r
+  UINT8                  Bit,\r
+  UINT8                  Value\r
+  )\r
+{\r
+  UINT8        Byte;\r
+  outb (PciIo, SEQ_ADDRESS_REGISTER, I2C_CONTROL);\r
+  Byte = (UINT8) (inb (PciIo, SEQ_DATA_REGISTER) & (UINT8) ~(1 << Bit)) ;\r
+  Byte = (UINT8) (Byte | ((Value & 0x01) << Bit));\r
+  outb (PciIo, SEQ_DATA_REGISTER, (UINT8) (Byte | 0x40));\r
+  return;\r
+}\r
+\r
+/**\r
+  Read/write delay acoording to I2C Bus Speed.\r
+\r
+**/\r
+STATIC\r
+VOID\r
+I2cDelay (\r
+  VOID\r
+  )\r
+{\r
+  MicroSecondDelay (1000 / I2C_BUS_SPEED);\r
+}\r
+\r
+/**\r
+  Write a 8-bit data onto I2C Data Pin.\r
+\r
+  @param  PciIo              The pointer to PCI_IO_PROTOCOL.\r
+  @param  Data               The byte data to write.\r
+\r
+**/\r
+STATIC\r
+VOID\r
+I2cSendByte (\r
+  EFI_PCI_IO_PROTOCOL    *PciIo,\r
+  UINT8                  Data\r
+  )\r
+{\r
+  UINTN                  Index;\r
+  //\r
+  // Send byte data onto I2C Bus\r
+  //\r
+  for (Index = 0; Index < 8; Index --) {\r
+    I2cPinWrite (PciIo, I2CDAT_OUT, (UINT8) (Data >> (7 - Index)));\r
+    I2cPinWrite (PciIo, I2CCLK_OUT, 1);\r
+    I2cDelay ();\r
+    I2cPinWrite (PciIo, I2CCLK_OUT, 0);\r
+  }\r
+}\r
+\r
+/**\r
+  Read a 8-bit data from I2C Data Pin.\r
+\r
+  @param  PciIo              The pointer to PCI_IO_PROTOCOL.\r
+\r
+  Return the byte data read from I2C Data Pin.\r
+**/\r
+STATIC\r
+UINT8\r
+I2cReceiveByte (\r
+  EFI_PCI_IO_PROTOCOL    *PciIo\r
+  )\r
+{\r
+  UINT8          Data;\r
+  UINTN          Index;\r
+\r
+  Data = 0;\r
+  //\r
+  // Read byte data from I2C Bus\r
+  //\r
+  for (Index = 0; Index < 8; Index --) {\r
+    I2cPinWrite (PciIo, I2CCLK_OUT, 1);\r
+    I2cDelay ();\r
+    Data = (UINT8) (Data << 1);\r
+    Data = (UINT8) (Data | I2cPinRead (PciIo, I2CDAT_IN));\r
+    I2cPinWrite (PciIo, I2CCLK_OUT, 0);\r
+  }\r
+\r
+  return Data;\r
+}\r
+\r
+/**\r
+  Receive an ACK signal from I2C Bus.\r
+\r
+  @param  PciIo              The pointer to PCI_IO_PROTOCOL.\r
+\r
+**/\r
+STATIC\r
+BOOLEAN\r
+I2cWaitAck (\r
+  EFI_PCI_IO_PROTOCOL    *PciIo\r
+  )\r
+{\r
+  //\r
+  // Wait for ACK signal\r
+  //\r
+  I2cPinWrite (PciIo, I2CDAT_OUT, 1);\r
+  I2cPinWrite (PciIo, I2CCLK_OUT, 1);\r
+  I2cDelay ();\r
+  if (I2cPinRead (PciIo, I2CDAT_IN) == 0) {\r
+    I2cPinWrite (PciIo, I2CDAT_OUT, 1);\r
+    return TRUE;\r
+  } else {\r
+    return FALSE;\r
+  }\r
+}\r
+\r
+/**\r
+  Send an ACK signal onto I2C Bus.\r
+\r
+  @param  PciIo              The pointer to PCI_IO_PROTOCOL.\r
+\r
+**/\r
+STATIC\r
+VOID\r
+I2cSendAck (\r
+  EFI_PCI_IO_PROTOCOL    *PciIo\r
+  )\r
+{\r
+  I2cPinWrite (PciIo, I2CCLK_OUT, 1);\r
+  I2cPinWrite (PciIo, I2CDAT_OUT, 1);\r
+  I2cPinWrite (PciIo, I2CDAT_OUT, 0);\r
+  I2cPinWrite (PciIo, I2CCLK_OUT, 0);\r
+}\r
+\r
+/**\r
+  Start a I2C transfer on I2C Bus.\r
+\r
+  @param  PciIo              The pointer to PCI_IO_PROTOCOL.\r
+\r
+**/\r
+STATIC\r
+VOID\r
+I2cStart (\r
+  EFI_PCI_IO_PROTOCOL    *PciIo\r
+  )\r
+{\r
+  //\r
+  // Init CLK and DAT pins\r
+  //\r
+  I2cPinWrite (PciIo, I2CCLK_OUT, 1);\r
+  I2cPinWrite (PciIo, I2CDAT_OUT, 1);\r
+  //\r
+  // Start a I2C transfer, set SDA low from high, when SCL is high\r
+  //\r
+  I2cPinWrite (PciIo, I2CDAT_OUT, 0);\r
+  I2cPinWrite (PciIo, I2CCLK_OUT, 0);\r
+}\r
+\r
+/**\r
+  Stop a I2C transfer on I2C Bus.\r
+\r
+  @param  PciIo              The pointer to PCI_IO_PROTOCOL.\r
+\r
+**/\r
+STATIC\r
+VOID\r
+I2cStop (\r
+  EFI_PCI_IO_PROTOCOL    *PciIo\r
+  )\r
+{\r
+  //\r
+  // Stop a I2C transfer, set SDA high from low, when SCL is high\r
+  //\r
+  I2cPinWrite (PciIo, I2CDAT_OUT, 0);\r
+  I2cPinWrite (PciIo, I2CCLK_OUT, 1);\r
+  I2cPinWrite (PciIo, I2CDAT_OUT, 1);\r
+}\r
+\r
+/**\r
+  Read one byte data on I2C Bus.\r
+\r
+  Read one byte data from the slave device connectet to I2C Bus.\r
+  If Data is NULL, then ASSERT().\r
+\r
+  @param  PciIo              The pointer to PCI_IO_PROTOCOL.\r
+  @param  DeviceAddress      Slave device's address.\r
+  @param  RegisterAddress    The register address on slave device.\r
+  @param  Data               The pointer to returned data if EFI_SUCCESS returned.\r
+\r
+  @retval EFI_DEVICE_ERROR\r
+  @retval EFI_SUCCESS\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+I2cReadByte (\r
+  EFI_PCI_IO_PROTOCOL    *PciIo,\r
+  UINT8                  DeviceAddress,\r
+  UINT8                  RegisterAddress,\r
+  UINT8                  *Data\r
+  )\r
+{\r
+  ASSERT (Data != NULL);\r
+\r
+  //\r
+  // Start I2C transfer\r
+  //\r
+  I2cStart (PciIo);\r
+\r
+  //\r
+  // Send slave address with enabling write flag\r
+  //\r
+  I2cSendByte (PciIo, (UINT8) (DeviceAddress & 0xfe));\r
+\r
+  //\r
+  // Wait for ACK signal\r
+  //\r
+  if (I2cWaitAck (PciIo) == FALSE) {\r
+    return EFI_DEVICE_ERROR;\r
+  }\r
+\r
+  //\r
+  // Send register address\r
+  //\r
+  I2cSendByte (PciIo, RegisterAddress);\r
+\r
+  //\r
+  // Wait for ACK signal\r
+  //\r
+  if (I2cWaitAck (PciIo) == FALSE) {\r
+    return EFI_DEVICE_ERROR;\r
+  }\r
+\r
+  //\r
+  // Send slave address with enabling read flag\r
+  //\r
+  I2cSendByte (PciIo, (UINT8) (DeviceAddress | 0x01));\r
+\r
+  //\r
+  // Wait for ACK signal\r
+  //\r
+  if (I2cWaitAck (PciIo) == FALSE) {\r
+    return EFI_DEVICE_ERROR;\r
+  }\r
+\r
+  //\r
+  // Read byte data from I2C Bus\r
+  //\r
+  *Data = I2cReceiveByte (PciIo);\r
+\r
+  //\r
+  // Send ACK signal onto I2C Bus\r
+  //\r
+  I2cSendAck (PciIo);\r
+\r
+  //\r
+  // Stop a I2C transfer\r
+  //\r
+  I2cStop (PciIo);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Write one byte data onto I2C Bus.\r
+\r
+  Write one byte data to the slave device connectet to I2C Bus.\r
+  If Data is NULL, then ASSERT().\r
+\r
+  @param  PciIo              The pointer to PCI_IO_PROTOCOL.\r
+  @param  DeviceAddress      Slave device's address.\r
+  @param  RegisterAddress    The register address on slave device.\r
+  @param  Data               The pointer to write data.\r
+\r
+  @retval EFI_DEVICE_ERROR\r
+  @retval EFI_SUCCESS\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+I2cWriteByte (\r
+  EFI_PCI_IO_PROTOCOL    *PciIo,\r
+  UINT8                  DeviceAddress,\r
+  UINT8                  RegisterAddress,\r
+  UINT8                  *Data\r
+  )\r
+{\r
+  ASSERT (Data != NULL);\r
+\r
+  I2cStart (PciIo);\r
+  //\r
+  // Send slave address with enabling write flag\r
+  //\r
+  I2cSendByte (PciIo, (UINT8) (DeviceAddress & 0xfe));\r
+\r
+  //\r
+  // Wait for ACK signal\r
+  //\r
+  if (I2cWaitAck (PciIo) == FALSE) {\r
+    return EFI_DEVICE_ERROR;\r
+  }\r
+\r
+  //\r
+  // Send register address\r
+  //\r
+  I2cSendByte (PciIo, RegisterAddress);\r
+\r
+  //\r
+  // Wait for ACK signal\r
+  //\r
+  if (I2cWaitAck (PciIo) == FALSE) {\r
+    return EFI_DEVICE_ERROR;\r
+  }\r
+\r
+  //\r
+  // Send byte data onto I2C Bus\r
+  //\r
+  I2cSendByte (PciIo, *Data);\r
+\r
+  //\r
+  // Wait for ACK signal\r
+  //\r
+  if (I2cWaitAck (PciIo) == FALSE) {\r
+    return EFI_DEVICE_ERROR;\r
+  }\r
+\r
+  //\r
+  // Stop a I2C transfer\r
+  //\r
+  I2cStop (PciIo);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r
+\r
diff --git a/OptionRomPkg/Library/CirrusLogicI2cLib/CirrusLogic5430I2cLib.inf b/OptionRomPkg/Library/CirrusLogicI2cLib/CirrusLogic5430I2cLib.inf
new file mode 100644 (file)
index 0000000..7474a4f
--- /dev/null
@@ -0,0 +1,45 @@
+#/** @file\r
+# DxeI2c Library implementation on CirrusLogic.\r
+#\r
+# Provides I2c Bus byte read/write functions upon CirrusLogic5430.\r
+# Copyright (c) 2008, Intel Corporation.\r
+#\r
+#  All rights reserved. This program and the accompanying materials\r
+#  are licensed and made available under the terms and conditions of the BSD License\r
+#  which accompanies this distribution. The full text of the license may be found at\r
+#  http://opensource.org/licenses/bsd-license.php\r
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#\r
+#\r
+#**/\r
+\r
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = CirrusLogic5430I2cLib\r
+  FILE_GUID                      = 0C86ADD7-ED2A-4b9a-ABC9-D932E8AA349B\r
+  MODULE_TYPE                    = DXE_DRIVER\r
+  VERSION_STRING                 = 1.0\r
+  LIBRARY_CLASS                  = DxeI2cLib\r
+  EDK_RELEASE_VERSION            = 0x00020000\r
+  EFI_SPECIFICATION_VERSION      = 0x00020000\r
+\r
+\r
+#\r
+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC\r
+#\r
+\r
+[Sources.common]\r
+  CirrusLogic5430I2cLib.c\r
+\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  OptionRomPkg/OptionRomPkg.dec\r
+\r
+\r
+[LibraryClasses]\r
+  TimerLib\r
+  DebugLib\r
+\r
+\r
index 281b4d5..539138b 100644 (file)
@@ -4,9 +4,9 @@
 # This package is designed to interoperate with the EDK II open source project\r
 # at http://www.tianocore.org, and this package is required to build PCI compliant\r
 # Option ROM image for all CPU architectures, including EBC target.\r
-# A single driver can support mixes of EFI 1.1, UEFI 2.0 and UEFI 2.1. \r
+# A single driver can support mixes of EFI 1.1, UEFI 2.0 and UEFI 2.1.\r
 #\r
-# Copyright (c) 2007, Intel Corporation.\r
+# Copyright (c) 2007 - 2008, Intel Corporation.\r
 #\r
 # All rights reserved. This program and the accompanying materials\r
 # are licensed and made available under the terms and conditions of the BSD License\r
   PACKAGE_GUID                   = AA3865E8-7F30-4f59-8696-99F560101852\r
   PACKAGE_VERSION                = 0.1\r
 \r
+[Includes.common]\r
+  Include\r
+\r
+[LibraryClasses.common]\r
+  DxeI2cLib|Include/Library/DxeI2cLib.h\r
+\r
 [PcdsFeatureFlag.common]\r
   gOptionRomPkgTokenSpaceGuid.PcdSupportScsiPassThru|TRUE|BOOLEAN|0x00010001\r
   gOptionRomPkgTokenSpaceGuid.PcdSupportExtScsiPassThru|TRUE|BOOLEAN|0x00010002\r
index 9a19b79..c4bf1ca 100644 (file)
@@ -4,9 +4,9 @@
 # This package is designed to interoperate with the EDK II open source project\r
 # at http://www.tianocore.org, and this package is required to build PCI compliant\r
 # Option ROM image for all CPU architectures, including EBC target.\r
-# A single driver can support mixes of EFI 1.1, UEFI 2.0 and UEFI 2.1. \r
+# A single driver can support mixes of EFI 1.1, UEFI 2.0 and UEFI 2.1.\r
 #\r
-# Copyright (c) 2007, Intel Corporation\r
+# Copyright (c) 2007 - 2008, Intel Corporation\r
 #\r
 # All rights reserved. This program and the accompanying materials\r
 # are licensed and made available under the terms and conditions of the BSD License\r
@@ -57,7 +57,9 @@
   PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf\r
   MemoryAllocationLib|MdePkg/Library/DxeMemoryAllocationLib/DxeMemoryAllocationLib.inf\r
   ReportStatusCodeLib|IntelFrameworkModulePkg/Library/DxeReportStatusCodeLibFramework/DxeReportStatusCodeLib.inf\r
-  \r
+  DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf\r
+  DxeI2cLib|OptionRomPkg/Library/CirrusLogicI2cLib/CirrusLogic5430I2cLib.inf\r
+\r
 ################################################################################\r
 #\r
 # Pcd Section - list of all EDK II PCD Entries defined by this Platform\r
@@ -91,4 +93,4 @@
 [Components.common]\r
   OptionRomPkg/AtapiPassThruDxe/AtapiPassThruDxe.inf\r
   OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430Dxe.inf\r
-  \r
+\r