Home | History | Annotate | Download | only in CirrusLogic5430Dxe
      1 /** @file
      2 Copyright (c) 2007 - 2012, Intel Corporation. All rights reserved.<BR>
      3 This program and the accompanying materials
      4 are licensed and made available under the terms and conditions of the BSD License
      5 which accompanies this distribution.  The full text of the license may be found at
      6 http://opensource.org/licenses/bsd-license.php
      7 
      8 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
      9 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     10 
     11 Module Name:
     12 
     13   UefiCirrusLogic5430GraphicsOutput.c
     14 
     15 Abstract:
     16 
     17   This file produces the graphics abstration of Graphics Output Protocol. It is called by
     18   CirrusLogic5430.c file which deals with the EFI 1.1 driver model.
     19   This file just does graphics.
     20 
     21 **/
     22 #include "CirrusLogic5430.h"
     23 #include <IndustryStandard/Acpi.h>
     24 
     25 
     26 STATIC
     27 VOID
     28 CirrusLogic5430CompleteModeInfo (
     29   OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION  *Info
     30   )
     31 {
     32   Info->Version = 0;
     33   Info->PixelFormat = PixelBitMask;
     34   Info->PixelInformation.RedMask = PIXEL_RED_MASK;
     35   Info->PixelInformation.GreenMask = PIXEL_GREEN_MASK;
     36   Info->PixelInformation.BlueMask = PIXEL_BLUE_MASK;
     37   Info->PixelInformation.ReservedMask = 0;
     38   Info->PixelsPerScanLine = Info->HorizontalResolution;
     39 }
     40 
     41 
     42 STATIC
     43 EFI_STATUS
     44 CirrusLogic5430CompleteModeData (
     45   IN  CIRRUS_LOGIC_5430_PRIVATE_DATA    *Private,
     46   OUT EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE *Mode
     47   )
     48 {
     49   EFI_GRAPHICS_OUTPUT_MODE_INFORMATION  *Info;
     50   EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR     *FrameBufDesc;
     51 
     52   Info = Mode->Info;
     53   CirrusLogic5430CompleteModeInfo (Info);
     54 
     55   Private->PciIo->GetBarAttributes (
     56                         Private->PciIo,
     57                         0,
     58                         NULL,
     59                         (VOID**) &FrameBufDesc
     60                         );
     61 
     62   Mode->FrameBufferBase = FrameBufDesc->AddrRangeMin;
     63   Mode->FrameBufferSize = Info->HorizontalResolution * Info->VerticalResolution;
     64 
     65   return EFI_SUCCESS;
     66 }
     67 
     68 
     69 //
     70 // Graphics Output Protocol Member Functions
     71 //
     72 EFI_STATUS
     73 EFIAPI
     74 CirrusLogic5430GraphicsOutputQueryMode (
     75   IN  EFI_GRAPHICS_OUTPUT_PROTOCOL          *This,
     76   IN  UINT32                                ModeNumber,
     77   OUT UINTN                                 *SizeOfInfo,
     78   OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION  **Info
     79   )
     80 /*++
     81 
     82 Routine Description:
     83 
     84   Graphics Output protocol interface to query video mode
     85 
     86   Arguments:
     87     This                  - Protocol instance pointer.
     88     ModeNumber            - The mode number to return information on.
     89     Info                  - Caller allocated buffer that returns information about ModeNumber.
     90     SizeOfInfo            - A pointer to the size, in bytes, of the Info buffer.
     91 
     92   Returns:
     93     EFI_SUCCESS           - Mode information returned.
     94     EFI_BUFFER_TOO_SMALL  - The Info buffer was too small.
     95     EFI_DEVICE_ERROR      - A hardware error occurred trying to retrieve the video mode.
     96     EFI_NOT_STARTED       - Video display is not initialized. Call SetMode ()
     97     EFI_INVALID_PARAMETER - One of the input args was NULL.
     98 
     99 --*/
    100 {
    101   CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private;
    102 
    103   Private = CIRRUS_LOGIC_5430_PRIVATE_DATA_FROM_GRAPHICS_OUTPUT_THIS (This);
    104 
    105   if (Private->HardwareNeedsStarting) {
    106     return EFI_NOT_STARTED;
    107   }
    108 
    109   if (Info == NULL || SizeOfInfo == NULL || ModeNumber >= This->Mode->MaxMode) {
    110     return EFI_INVALID_PARAMETER;
    111   }
    112 
    113   *Info = AllocatePool (sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION));
    114   if (*Info == NULL) {
    115     return EFI_OUT_OF_RESOURCES;
    116   }
    117 
    118   *SizeOfInfo = sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION);
    119 
    120   (*Info)->HorizontalResolution = Private->ModeData[ModeNumber].HorizontalResolution;
    121   (*Info)->VerticalResolution   = Private->ModeData[ModeNumber].VerticalResolution;
    122   CirrusLogic5430CompleteModeInfo (*Info);
    123 
    124   return EFI_SUCCESS;
    125 }
    126 
    127 EFI_STATUS
    128 EFIAPI
    129 CirrusLogic5430GraphicsOutputSetMode (
    130   IN  EFI_GRAPHICS_OUTPUT_PROTOCOL *This,
    131   IN  UINT32                       ModeNumber
    132   )
    133 /*++
    134 
    135 Routine Description:
    136 
    137   Graphics Output protocol interface to set video mode
    138 
    139   Arguments:
    140     This             - Protocol instance pointer.
    141     ModeNumber       - The mode number to be set.
    142 
    143   Returns:
    144     EFI_SUCCESS      - Graphics mode was changed.
    145     EFI_DEVICE_ERROR - The device had an error and could not complete the request.
    146     EFI_UNSUPPORTED  - ModeNumber is not supported by this device.
    147 
    148 --*/
    149 {
    150   CIRRUS_LOGIC_5430_PRIVATE_DATA    *Private;
    151   CIRRUS_LOGIC_5430_MODE_DATA       *ModeData;
    152 
    153   Private = CIRRUS_LOGIC_5430_PRIVATE_DATA_FROM_GRAPHICS_OUTPUT_THIS (This);
    154 
    155   if (ModeNumber >= This->Mode->MaxMode) {
    156     return EFI_UNSUPPORTED;
    157   }
    158 
    159   ModeData = &Private->ModeData[ModeNumber];
    160 
    161   if (Private->LineBuffer) {
    162     gBS->FreePool (Private->LineBuffer);
    163   }
    164 
    165   Private->LineBuffer = NULL;
    166   Private->LineBuffer = AllocatePool (ModeData->HorizontalResolution);
    167   if (Private->LineBuffer == NULL) {
    168     return EFI_OUT_OF_RESOURCES;
    169   }
    170 
    171   InitializeGraphicsMode (Private, &CirrusLogic5430VideoModes[ModeData->ModeNumber]);
    172 
    173   This->Mode->Mode = ModeNumber;
    174   This->Mode->Info->HorizontalResolution = ModeData->HorizontalResolution;
    175   This->Mode->Info->VerticalResolution = ModeData->VerticalResolution;
    176   This->Mode->SizeOfInfo = sizeof(EFI_GRAPHICS_OUTPUT_MODE_INFORMATION);
    177 
    178   CirrusLogic5430CompleteModeData (Private, This->Mode);
    179 
    180   Private->HardwareNeedsStarting  = FALSE;
    181 
    182   return EFI_SUCCESS;
    183 }
    184 
    185 EFI_STATUS
    186 EFIAPI
    187 CirrusLogic5430GraphicsOutputBlt (
    188   IN  EFI_GRAPHICS_OUTPUT_PROTOCOL          *This,
    189   IN  EFI_GRAPHICS_OUTPUT_BLT_PIXEL         *BltBuffer, OPTIONAL
    190   IN  EFI_GRAPHICS_OUTPUT_BLT_OPERATION     BltOperation,
    191   IN  UINTN                                 SourceX,
    192   IN  UINTN                                 SourceY,
    193   IN  UINTN                                 DestinationX,
    194   IN  UINTN                                 DestinationY,
    195   IN  UINTN                                 Width,
    196   IN  UINTN                                 Height,
    197   IN  UINTN                                 Delta
    198   )
    199 /*++
    200 
    201 Routine Description:
    202 
    203   Graphics Output protocol instance to block transfer for CirrusLogic device
    204 
    205 Arguments:
    206 
    207   This          - Pointer to Graphics Output protocol instance
    208   BltBuffer     - The data to transfer to screen
    209   BltOperation  - The operation to perform
    210   SourceX       - The X coordinate of the source for BltOperation
    211   SourceY       - The Y coordinate of the source for BltOperation
    212   DestinationX  - The X coordinate of the destination for BltOperation
    213   DestinationY  - The Y coordinate of the destination for BltOperation
    214   Width         - The width of a rectangle in the blt rectangle in pixels
    215   Height        - The height of a rectangle in the blt rectangle in pixels
    216   Delta         - Not used for EfiBltVideoFill and EfiBltVideoToVideo operation.
    217                   If a Delta of 0 is used, the entire BltBuffer will be operated on.
    218                   If a subrectangle of the BltBuffer is used, then Delta represents
    219                   the number of bytes in a row of the BltBuffer.
    220 
    221 Returns:
    222 
    223   EFI_INVALID_PARAMETER - Invalid parameter passed in
    224   EFI_SUCCESS - Blt operation success
    225 
    226 --*/
    227 {
    228   CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private;
    229   EFI_TPL                         OriginalTPL;
    230   UINTN                           DstY;
    231   UINTN                           SrcY;
    232   EFI_GRAPHICS_OUTPUT_BLT_PIXEL   *Blt;
    233   UINTN                           X;
    234   UINT8                           Pixel;
    235   UINT32                          WidePixel;
    236   UINTN                           ScreenWidth;
    237   UINTN                           Offset;
    238   UINTN                           SourceOffset;
    239   UINT32                          CurrentMode;
    240 
    241   Private = CIRRUS_LOGIC_5430_PRIVATE_DATA_FROM_GRAPHICS_OUTPUT_THIS (This);
    242 
    243   if ((UINT32)BltOperation >= EfiGraphicsOutputBltOperationMax) {
    244     return EFI_INVALID_PARAMETER;
    245   }
    246 
    247   if (Width == 0 || Height == 0) {
    248     return EFI_INVALID_PARAMETER;
    249   }
    250 
    251   //
    252   // If Delta is zero, then the entire BltBuffer is being used, so Delta
    253   // is the number of bytes in each row of BltBuffer.  Since BltBuffer is Width pixels size,
    254   // the number of bytes in each row can be computed.
    255   //
    256   if (Delta == 0) {
    257     Delta = Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL);
    258   }
    259 
    260   //
    261   // We need to fill the Virtual Screen buffer with the blt data.
    262   // The virtual screen is upside down, as the first row is the bootom row of
    263   // the image.
    264   //
    265 
    266   CurrentMode = This->Mode->Mode;
    267   //
    268   // Make sure the SourceX, SourceY, DestinationX, DestinationY, Width, and Height parameters
    269   // are valid for the operation and the current screen geometry.
    270   //
    271   if (BltOperation == EfiBltVideoToBltBuffer) {
    272     //
    273     // Video to BltBuffer: Source is Video, destination is BltBuffer
    274     //
    275     if (SourceY + Height > Private->ModeData[CurrentMode].VerticalResolution) {
    276       return EFI_INVALID_PARAMETER;
    277     }
    278 
    279     if (SourceX + Width > Private->ModeData[CurrentMode].HorizontalResolution) {
    280       return EFI_INVALID_PARAMETER;
    281     }
    282   } else {
    283     //
    284     // BltBuffer to Video: Source is BltBuffer, destination is Video
    285     //
    286     if (DestinationY + Height > Private->ModeData[CurrentMode].VerticalResolution) {
    287       return EFI_INVALID_PARAMETER;
    288     }
    289 
    290     if (DestinationX + Width > Private->ModeData[CurrentMode].HorizontalResolution) {
    291       return EFI_INVALID_PARAMETER;
    292     }
    293   }
    294   //
    295   // We have to raise to TPL Notify, so we make an atomic write the frame buffer.
    296   // We would not want a timer based event (Cursor, ...) to come in while we are
    297   // doing this operation.
    298   //
    299   OriginalTPL = gBS->RaiseTPL (TPL_NOTIFY);
    300 
    301   switch (BltOperation) {
    302   case EfiBltVideoToBltBuffer:
    303     //
    304     // Video to BltBuffer: Source is Video, destination is BltBuffer
    305     //
    306     for (SrcY = SourceY, DstY = DestinationY; DstY < (Height + DestinationY); SrcY++, DstY++) {
    307 
    308       Offset = (SrcY * Private->ModeData[CurrentMode].HorizontalResolution) + SourceX;
    309       if (((Offset & 0x03) == 0) && ((Width & 0x03) == 0)) {
    310         Private->PciIo->Mem.Read (
    311                               Private->PciIo,
    312                               EfiPciIoWidthUint32,
    313                               0,
    314                               Offset,
    315                               Width >> 2,
    316                               Private->LineBuffer
    317                               );
    318       } else {
    319         Private->PciIo->Mem.Read (
    320                               Private->PciIo,
    321                               EfiPciIoWidthUint8,
    322                               0,
    323                               Offset,
    324                               Width,
    325                               Private->LineBuffer
    326                               );
    327       }
    328 
    329       for (X = 0; X < Width; X++) {
    330         Blt         = (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) ((UINT8 *) BltBuffer + (DstY * Delta) + (DestinationX + X) * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
    331 
    332         Blt->Red    = PIXEL_TO_RED_BYTE (Private->LineBuffer[X]);
    333         Blt->Green  = PIXEL_TO_GREEN_BYTE (Private->LineBuffer[X]);
    334         Blt->Blue   = PIXEL_TO_BLUE_BYTE (Private->LineBuffer[X]);
    335       }
    336     }
    337     break;
    338 
    339   case EfiBltVideoToVideo:
    340     //
    341     // Perform hardware acceleration for Video to Video operations
    342     //
    343     ScreenWidth   = Private->ModeData[CurrentMode].HorizontalResolution;
    344     SourceOffset  = (SourceY * Private->ModeData[CurrentMode].HorizontalResolution) + (SourceX);
    345     Offset        = (DestinationY * Private->ModeData[CurrentMode].HorizontalResolution) + (DestinationX);
    346 
    347     outw (Private, GRAPH_ADDRESS_REGISTER, 0x0000);
    348     outw (Private, GRAPH_ADDRESS_REGISTER, 0x0010);
    349     outw (Private, GRAPH_ADDRESS_REGISTER, 0x0012);
    350     outw (Private, GRAPH_ADDRESS_REGISTER, 0x0014);
    351 
    352     outw (Private, GRAPH_ADDRESS_REGISTER, 0x0001);
    353     outw (Private, GRAPH_ADDRESS_REGISTER, 0x0011);
    354     outw (Private, GRAPH_ADDRESS_REGISTER, 0x0013);
    355     outw (Private, GRAPH_ADDRESS_REGISTER, 0x0015);
    356 
    357     outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) (((Width << 8) & 0xff00) | 0x20));
    358     outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((Width & 0xff00) | 0x21));
    359     outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) (((Height << 8) & 0xff00) | 0x22));
    360     outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((Height & 0xff00) | 0x23));
    361     outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) (((ScreenWidth << 8) & 0xff00) | 0x24));
    362     outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((ScreenWidth & 0xff00) | 0x25));
    363     outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) (((ScreenWidth << 8) & 0xff00) | 0x26));
    364     outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((ScreenWidth & 0xff00) | 0x27));
    365     outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((((Offset) << 8) & 0xff00) | 0x28));
    366     outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((((Offset) >> 0) & 0xff00) | 0x29));
    367     outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((((Offset) >> 8) & 0xff00) | 0x2a));
    368     outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((((SourceOffset) << 8) & 0xff00) | 0x2c));
    369     outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((((SourceOffset) >> 0) & 0xff00) | 0x2d));
    370     outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((((SourceOffset) >> 8) & 0xff00) | 0x2e));
    371     outw (Private, GRAPH_ADDRESS_REGISTER, 0x002f);
    372     outw (Private, GRAPH_ADDRESS_REGISTER, 0x0030);
    373     outw (Private, GRAPH_ADDRESS_REGISTER, 0x0d32);
    374     outw (Private, GRAPH_ADDRESS_REGISTER, 0x0033);
    375     outw (Private, GRAPH_ADDRESS_REGISTER, 0x0034);
    376     outw (Private, GRAPH_ADDRESS_REGISTER, 0x0035);
    377 
    378     outw (Private, GRAPH_ADDRESS_REGISTER, 0x0231);
    379 
    380     outb (Private, GRAPH_ADDRESS_REGISTER, 0x31);
    381     while ((inb (Private, GRAPH_DATA_REGISTER) & 0x01) == 0x01)
    382       ;
    383     break;
    384 
    385   case EfiBltVideoFill:
    386     Blt       = BltBuffer;
    387     Pixel     = RGB_BYTES_TO_PIXEL (Blt->Red, Blt->Green, Blt->Blue);
    388     WidePixel = (Pixel << 8) | Pixel;
    389     WidePixel = (WidePixel << 16) | WidePixel;
    390 
    391     if (DestinationX == 0 && Width == Private->ModeData[CurrentMode].HorizontalResolution) {
    392       Offset = DestinationY * Private->ModeData[CurrentMode].HorizontalResolution;
    393       if (((Offset & 0x03) == 0) && (((Width * Height) & 0x03) == 0)) {
    394         Private->PciIo->Mem.Write (
    395                               Private->PciIo,
    396                               EfiPciIoWidthFillUint32,
    397                               0,
    398                               Offset,
    399                               (Width * Height) >> 2,
    400                               &WidePixel
    401                               );
    402       } else {
    403         Private->PciIo->Mem.Write (
    404                               Private->PciIo,
    405                               EfiPciIoWidthFillUint8,
    406                               0,
    407                               Offset,
    408                               Width * Height,
    409                               &Pixel
    410                               );
    411       }
    412     } else {
    413       for (SrcY = SourceY, DstY = DestinationY; SrcY < (Height + SourceY); SrcY++, DstY++) {
    414         Offset = (DstY * Private->ModeData[CurrentMode].HorizontalResolution) + DestinationX;
    415         if (((Offset & 0x03) == 0) && ((Width & 0x03) == 0)) {
    416           Private->PciIo->Mem.Write (
    417                                 Private->PciIo,
    418                                 EfiPciIoWidthFillUint32,
    419                                 0,
    420                                 Offset,
    421                                 Width >> 2,
    422                                 &WidePixel
    423                                 );
    424         } else {
    425           Private->PciIo->Mem.Write (
    426                                 Private->PciIo,
    427                                 EfiPciIoWidthFillUint8,
    428                                 0,
    429                                 Offset,
    430                                 Width,
    431                                 &Pixel
    432                                 );
    433         }
    434       }
    435     }
    436     break;
    437 
    438   case EfiBltBufferToVideo:
    439     for (SrcY = SourceY, DstY = DestinationY; SrcY < (Height + SourceY); SrcY++, DstY++) {
    440 
    441       for (X = 0; X < Width; X++) {
    442         Blt =
    443           (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) (
    444               (UINT8 *) BltBuffer +
    445               (SrcY * Delta) +
    446               ((SourceX + X) * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL))
    447             );
    448         Private->LineBuffer[X]  =
    449           RGB_BYTES_TO_PIXEL (Blt->Red, Blt->Green, Blt->Blue);
    450       }
    451 
    452       Offset = (DstY * Private->ModeData[CurrentMode].HorizontalResolution) + DestinationX;
    453 
    454       if (((Offset & 0x03) == 0) && ((Width & 0x03) == 0)) {
    455         Private->PciIo->Mem.Write (
    456                               Private->PciIo,
    457                               EfiPciIoWidthUint32,
    458                               0,
    459                               Offset,
    460                               Width >> 2,
    461                               Private->LineBuffer
    462                               );
    463       } else {
    464         Private->PciIo->Mem.Write (
    465                               Private->PciIo,
    466                               EfiPciIoWidthUint8,
    467                               0,
    468                               Offset,
    469                               Width,
    470                               Private->LineBuffer
    471                               );
    472       }
    473     }
    474     break;
    475   default:
    476     ASSERT (FALSE);
    477   }
    478 
    479   gBS->RestoreTPL (OriginalTPL);
    480 
    481   return EFI_SUCCESS;
    482 }
    483 
    484 EFI_STATUS
    485 CirrusLogic5430GraphicsOutputConstructor (
    486   CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private
    487   )
    488 {
    489   EFI_STATUS                   Status;
    490   EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;
    491 
    492 
    493   GraphicsOutput            = &Private->GraphicsOutput;
    494   GraphicsOutput->QueryMode = CirrusLogic5430GraphicsOutputQueryMode;
    495   GraphicsOutput->SetMode   = CirrusLogic5430GraphicsOutputSetMode;
    496   GraphicsOutput->Blt       = CirrusLogic5430GraphicsOutputBlt;
    497 
    498   //
    499   // Initialize the private data
    500   //
    501   Status = gBS->AllocatePool (
    502                   EfiBootServicesData,
    503                   sizeof (EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE),
    504                   (VOID **) &Private->GraphicsOutput.Mode
    505                   );
    506   if (EFI_ERROR (Status)) {
    507     return Status;
    508   }
    509   Status = gBS->AllocatePool (
    510                   EfiBootServicesData,
    511                   sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION),
    512                   (VOID **) &Private->GraphicsOutput.Mode->Info
    513                   );
    514   if (EFI_ERROR (Status)) {
    515     return Status;
    516   }
    517   Private->GraphicsOutput.Mode->MaxMode = (UINT32) Private->MaxMode;
    518   Private->GraphicsOutput.Mode->Mode    = GRAPHICS_OUTPUT_INVALIDE_MODE_NUMBER;
    519   Private->HardwareNeedsStarting        = TRUE;
    520   Private->LineBuffer                   = NULL;
    521 
    522   //
    523   // Initialize the hardware
    524   //
    525   GraphicsOutput->SetMode (GraphicsOutput, 0);
    526   ASSERT (Private->GraphicsOutput.Mode->Mode < CIRRUS_LOGIC_5430_MODE_COUNT);
    527   DrawLogo (
    528     Private,
    529     Private->ModeData[Private->GraphicsOutput.Mode->Mode].HorizontalResolution,
    530     Private->ModeData[Private->GraphicsOutput.Mode->Mode].VerticalResolution
    531     );
    532 
    533   return EFI_SUCCESS;
    534 }
    535 
    536 EFI_STATUS
    537 CirrusLogic5430GraphicsOutputDestructor (
    538   CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private
    539   )
    540 /*++
    541 
    542 Routine Description:
    543 
    544 Arguments:
    545 
    546 Returns:
    547 
    548   None
    549 
    550 --*/
    551 {
    552   if (Private->GraphicsOutput.Mode != NULL) {
    553     if (Private->GraphicsOutput.Mode->Info != NULL) {
    554       gBS->FreePool (Private->GraphicsOutput.Mode->Info);
    555     }
    556     gBS->FreePool (Private->GraphicsOutput.Mode);
    557   }
    558 
    559   return EFI_SUCCESS;
    560 }
    561 
    562 
    563