/** @file
  Read EDID information and parse EDID information.

  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.

**/

#include "CirrusLogic5430.h"
#include "CirrusLogic5430I2c.h"

//
// EDID block
//
typedef struct {
  UINT8   Header[8];                        //EDID header "00 FF FF FF FF FF FF 00"
  UINT16  ManufactureName;                  //EISA 3-character ID
  UINT16  ProductCode;                      //Vendor assigned code
  UINT32  SerialNumber;                     //32-bit serial number
  UINT8   WeekOfManufacture;                //Week number
  UINT8   YearOfManufacture;                //Year
  UINT8   EdidVersion;                      //EDID Structure Version
  UINT8   EdidRevision;                     //EDID Structure Revision
  UINT8   VideoInputDefinition;
  UINT8   MaxHorizontalImageSize;           //cm
  UINT8   MaxVerticalImageSize;             //cm
  UINT8   DisplayTransferCharacteristic;
  UINT8   FeatureSupport;
  UINT8   RedGreenLowBits;                  //Rx1 Rx0 Ry1 Ry0 Gx1 Gx0 Gy1Gy0
  UINT8   BlueWhiteLowBits;                 //Bx1 Bx0 By1 By0 Wx1 Wx0 Wy1 Wy0
  UINT8   RedX;                             //Red-x Bits 9 - 2
  UINT8   RedY;                             //Red-y Bits 9 - 2
  UINT8   GreenX;                           //Green-x Bits 9 - 2
  UINT8   GreenY;                           //Green-y Bits 9 - 2
  UINT8   BlueX;                            //Blue-x Bits 9 - 2
  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   ExtensionFlag;                    //Number of (optional) 128-byte EDID extension blocks to follow
  UINT8   Checksum;
} EDID_BLOCK;

#define EDID_BLOCK_SIZE                        128
#define VBE_EDID_ESTABLISHED_TIMING_MAX_NUMBER 17

typedef struct {
  UINT16  HorizontalResolution;
  UINT16  VerticalResolution;
  UINT16  RefreshRate;
} EDID_TIMING;

typedef struct {
  UINT32  ValidNumber;
  UINT32  Key[VBE_EDID_ESTABLISHED_TIMING_MAX_NUMBER];
} VALID_EDID_TIMING;

//
// Standard timing defined by VESA EDID
//
EDID_TIMING mVbeEstablishedEdidTiming[] = {
  //
  // Established Timing I
  //
  {800, 600, 60},
  {800, 600, 56},
  {640, 480, 75},
  {640, 480, 72},
  {640, 480, 67},
  {640, 480, 60},
  {720, 400, 88},
  {720, 400, 70},
  //
  // Established Timing II
  //
  {1280, 1024, 75},
  {1024,  768, 75},
  {1024,  768, 70},
  {1024,  768, 60},
  {1024,  768, 87},
  {832,   624, 75},
  {800,   600, 75},
  {800,   600, 72},
  //
  // Established Timing III
  //
  {1152, 870, 75}
};

/**
  Read EDID information from I2C Bus on CirrusLogic.

  @param  Private             Pointer to CIRRUS_LOGIC_5430_PRIVATE_DATA.
  @param  EdidDataBlock       Pointer to EDID data block.
  @param  EdidSize            Returned EDID block size.

  @retval EFI_UNSUPPORTED
  @retval EFI_SUCCESS

**/
EFI_STATUS
ReadEdidData (
  CIRRUS_LOGIC_5430_PRIVATE_DATA     *Private,
  UINT8                              **EdidDataBlock,
  UINTN                              *EdidSize
  )
{
  UINTN             Index;
  UINT8             EdidData[EDID_BLOCK_SIZE * 2];
  UINT8             *ValidEdid;
  UINT64            Signature;

  for (Index = 0; Index < EDID_BLOCK_SIZE * 2; Index ++) {
    I2cReadByte (Private->PciIo, 0xa0, (UINT8)Index, &EdidData[Index]);
  }

  //
  // Search for the EDID signature
  //
  ValidEdid = &EdidData[0];
  Signature = 0x00ffffffffffff00ull;
  for (Index = 0; Index < EDID_BLOCK_SIZE * 2; Index ++, ValidEdid ++) {
    if (CompareMem (ValidEdid, &Signature, 8) == 0) {
      break;
    }
  }

  if (Index == 256) {
    //
    // No EDID signature found
    //
    return EFI_UNSUPPORTED;
  }

  *EdidDataBlock = AllocateCopyPool (
                     sizeof (EDID_BLOCK_SIZE),
                     ValidEdid
                     );
  if (*EdidDataBlock == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  //
  // Currently only support EDID 1.x
  //
  *EdidSize = EDID_BLOCK_SIZE;

  return EFI_SUCCESS;
}

/**
  Generate a search key for a specified timing data.

  @param  EdidTiming             Pointer to EDID timing

  @return The 32 bit unique key for search.

**/
UINT32
CalculateEdidKey (
  EDID_TIMING       *EdidTiming
  )
{
  UINT32 Key;

  //
  // Be sure no conflicts for all standard timing defined by VESA.
  //
  Key = (EdidTiming->HorizontalResolution * 2) + EdidTiming->VerticalResolution;
  return Key;
}

/**
  Search a specified Timing in all the valid EDID timings.

  @param  ValidEdidTiming        All valid EDID timing information.
  @param  EdidTiming             The Timing to search for.

  @retval TRUE                   Found.
  @retval FALSE                  Not found.

**/
BOOLEAN
SearchEdidTiming (
  VALID_EDID_TIMING *ValidEdidTiming,
  EDID_TIMING       *EdidTiming
  )
{
  UINT32 Index;
  UINT32 Key;

  Key = CalculateEdidKey (EdidTiming);

  for (Index = 0; Index < ValidEdidTiming->ValidNumber; Index ++) {
    if (Key == ValidEdidTiming->Key[Index]) {
      return TRUE;
    }
  }

  return FALSE;
}

/**
  Parse the Established Timing and Standard Timing in EDID data block.

  @param  EdidBuffer             Pointer to EDID data block
  @param  ValidEdidTiming        Valid EDID timing information

  @retval TRUE                   The EDID data is valid.
  @retval FALSE                  The EDID data is invalid.

**/
BOOLEAN
ParseEdidData (
  UINT8                         *EdidBuffer,
  VALID_EDID_TIMING             *ValidEdidTiming
  )
{
  UINT8        CheckSum;
  UINT32       Index;
  UINT32       ValidNumber;
  UINT32       TimingBits;
  UINT8        *BufferIndex;
  UINT16       HorizontalResolution;
  UINT16       VerticalResolution;
  UINT8        AspectRatio;
  UINT8        RefreshRate;
  EDID_TIMING  TempTiming;
  EDID_BLOCK   *EdidDataBlock;

  EdidDataBlock = (EDID_BLOCK *) EdidBuffer;

  //
  // Check the checksum of EDID data
  //
  CheckSum = 0;
  for (Index = 0; Index < EDID_BLOCK_SIZE; Index ++) {
    CheckSum = (UINT8) (CheckSum + EdidBuffer[Index]);
  }
  if (CheckSum != 0) {
    return FALSE;
  }

  ValidNumber = 0;
  SetMem (ValidEdidTiming, sizeof (VALID_EDID_TIMING), 0);

  if ((EdidDataBlock->EstablishedTimings[0] != 0) ||
      (EdidDataBlock->EstablishedTimings[1] != 0) ||
      (EdidDataBlock->EstablishedTimings[2] != 0)
      ) {
    //
    // Established timing data
    //
    TimingBits = EdidDataBlock->EstablishedTimings[0] |
                 (EdidDataBlock->EstablishedTimings[1] << 8) |
                 ((EdidDataBlock->EstablishedTimings[2] & 0x80) << 9) ;
    for (Index = 0; Index < VBE_EDID_ESTABLISHED_TIMING_MAX_NUMBER; Index ++) {
      if (TimingBits & 0x1) {
        ValidEdidTiming->Key[ValidNumber] = CalculateEdidKey (&mVbeEstablishedEdidTiming[Index]);
        ValidNumber ++;
      }
      TimingBits = TimingBits >> 1;
    }
  } else {
    //
    // If no Established timing data, read the standard timing data
    //
    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 ++;
      }
      BufferIndex += 2;
    }
  }

  ValidEdidTiming->ValidNumber = ValidNumber;
  return TRUE;
}

/**
  Construct the valid video modes for CirrusLogic5430.

**/
EFI_STATUS
CirrusLogic5430VideoModeSetup (
  CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private
  )
{
  EFI_STATUS                             Status;
  UINT32                                 Index;
  BOOLEAN                                EdidFound;
  EFI_EDID_OVERRIDE_PROTOCOL             *EdidOverride;
  UINT32                                 EdidAttributes;
  BOOLEAN                                EdidOverrideFound;
  UINTN                                  EdidOverrideDataSize;
  UINT8                                  *EdidOverrideDataBlock;
  UINTN                                  EdidDiscoveredDataSize;
  UINT8                                  *EdidDiscoveredDataBlock;
  UINTN                                  EdidActiveDataSize;
  UINT8                                  *EdidActiveDataBlock;
  VALID_EDID_TIMING                      ValidEdidTiming;
  UINT32                                 ValidModeCount;
  CIRRUS_LOGIC_5430_MODE_DATA            *ModeData;
  BOOLEAN                                TimingMatch;
  CIRRUS_LOGIC_5430_VIDEO_MODES          *VideoMode;
  EDID_TIMING                            TempTiming;

  //
  // setup EDID information
  //
  Private->EdidDiscovered.Edid       = NULL;
  Private->EdidDiscovered.SizeOfEdid = 0;
  Private->EdidActive.Edid           = NULL;
  Private->EdidActive.SizeOfEdid     = 0;

  EdidFound               = FALSE;
  EdidOverrideFound       = FALSE;
  EdidAttributes          = 0xff;
  EdidOverrideDataSize    = 0;
  EdidOverrideDataBlock   = NULL;
  EdidActiveDataSize      = 0;
  EdidActiveDataBlock     = NULL;
  EdidDiscoveredDataBlock = NULL;

  //
  // Find EDID Override protocol firstly, this protocol is installed by platform if needed.
  //
  Status = gBS->LocateProtocol (
                   &gEfiEdidOverrideProtocolGuid,
                   NULL,
                   (VOID **) &EdidOverride
                   );
  if (!EFI_ERROR (Status)) {
    //
    // Allocate double size of VESA_BIOS_EXTENSIONS_EDID_BLOCK_SIZE to avoid overflow
    //
    EdidOverrideDataBlock = AllocatePool (sizeof (EDID_BLOCK_SIZE * 2));
    if (NULL == EdidOverrideDataBlock) {
  		Status = EFI_OUT_OF_RESOURCES;
      goto Done;
    }

    Status = EdidOverride->GetEdid (
                             EdidOverride,
                             Private->Handle,
                             &EdidAttributes,
                             &EdidOverrideDataSize,
                             (UINT8 **) &EdidOverrideDataBlock
                             );
    if (!EFI_ERROR (Status)  &&
         EdidAttributes == 0 &&
         EdidOverrideDataSize != 0) {
      //
      // Succeeded to get EDID Override Data
      //
      EdidOverrideFound = TRUE;
    }
  }

  if (EdidOverrideFound != TRUE || EdidAttributes == EFI_EDID_OVERRIDE_DONT_OVERRIDE) {
    //
    // If EDID Override data doesn't exist or EFI_EDID_OVERRIDE_DONT_OVERRIDE returned,
    // read EDID information through I2C Bus
    //
    if (ReadEdidData (Private, &EdidDiscoveredDataBlock, &EdidDiscoveredDataSize) == EFI_SUCCESS) {
      Private->EdidDiscovered.SizeOfEdid = (UINT32) EdidDiscoveredDataSize;
     	Private->EdidDiscovered.Edid = (UINT8 *) AllocateCopyPool (
                                                          EdidDiscoveredDataSize,
                                                          EdidDiscoveredDataBlock
     																										  );

      if (NULL == Private->EdidDiscovered.Edid) {
     	  Status = EFI_OUT_OF_RESOURCES;
        goto Done;
      }

      EdidActiveDataSize  = Private->EdidDiscovered.SizeOfEdid;
      EdidActiveDataBlock = Private->EdidDiscovered.Edid;

      EdidFound = TRUE;
    }
  }

  if (EdidFound != TRUE && EdidOverrideFound == TRUE) {
    EdidActiveDataSize  = EdidOverrideDataSize;
    EdidActiveDataBlock = EdidOverrideDataBlock;
    EdidFound = TRUE;
 	}

 	if (EdidFound == TRUE) {
    //
    // Parse EDID data structure to retrieve modes supported by monitor
    //
    if (ParseEdidData ((UINT8 *) EdidActiveDataBlock, &ValidEdidTiming) == TRUE) {
      //
      // Copy EDID Override Data to EDID Active Data
      //
      Private->EdidActive.SizeOfEdid = (UINT32) EdidActiveDataSize;
      Private->EdidActive.Edid = (UINT8 *) AllocateCopyPool (
                                             EdidActiveDataSize,
                                             EdidActiveDataBlock
                                             );
      if (NULL == Private->EdidActive.Edid) {
   		  Status = EFI_OUT_OF_RESOURCES;
        goto Done;
      }
    }
  } else {
    Private->EdidActive.SizeOfEdid = 0;
    Private->EdidActive.Edid = NULL;
    EdidFound = FALSE;
  }

  if (EdidFound) {
    //
    // Initialize the private mode data with the supported modes.
    //
    ValidModeCount = 0;
    ModeData = &Private->ModeData[0];
    VideoMode = &CirrusLogic5430VideoModes[0];
    for (Index = 0; Index < CIRRUS_LOGIC_5430_MODE_COUNT; Index++) {

      TimingMatch = TRUE;

      //
      // Check whether match with CirrusLogic5430 video mode
      //
      TempTiming.HorizontalResolution = (UINT16) VideoMode->Width;
      TempTiming.VerticalResolution   = (UINT16) VideoMode->Height;
      TempTiming.RefreshRate          = (UINT16) VideoMode->RefreshRate;
      if (SearchEdidTiming (&ValidEdidTiming, &TempTiming) != TRUE) {
        TimingMatch = FALSE;
      }

      //
      // Not export Mode 0x0 as GOP mode, this is not defined in spec.
      //
      if ((VideoMode->Width == 0) || (VideoMode->Height == 0)) {
        TimingMatch = FALSE;
      }

      if (TimingMatch) {
        ModeData->ModeNumber = Index;
        ModeData->HorizontalResolution          = VideoMode->Width;
        ModeData->VerticalResolution            = VideoMode->Height;
        ModeData->ColorDepth                    = VideoMode->ColorDepth;
        ModeData->RefreshRate                   = VideoMode->RefreshRate;

        ModeData ++;
        ValidModeCount ++;
      }

      VideoMode ++;
    }

    Private->MaxMode = ValidModeCount;

  } else {
    //
    // If EDID information wasn't found
    //
    ModeData = &Private->ModeData[0];
    VideoMode = &CirrusLogic5430VideoModes[0];
    for (Index = 0; Index < CIRRUS_LOGIC_5430_MODE_COUNT; Index ++) {
      ModeData->ModeNumber = Index;
      ModeData->HorizontalResolution          = VideoMode->Width;
      ModeData->VerticalResolution            = VideoMode->Height;
      ModeData->ColorDepth                    = VideoMode->ColorDepth;
      ModeData->RefreshRate                   = VideoMode->RefreshRate;

      ModeData ++ ;
      VideoMode ++;
    }
    Private->MaxMode = CIRRUS_LOGIC_5430_MODE_COUNT;
  }

  if (EdidOverrideDataBlock != NULL) {
    FreePool (EdidOverrideDataBlock);
  }

  return EFI_SUCCESS;

Done:
  if (EdidOverrideDataBlock != NULL) {
    FreePool (EdidOverrideDataBlock);
  }
  if (Private->EdidDiscovered.Edid != NULL) {
    FreePool (Private->EdidDiscovered.Edid);
  }
  if (Private->EdidDiscovered.Edid != NULL) {
    FreePool (Private->EdidActive.Edid);
  }

  return EFI_DEVICE_ERROR;
}
