Home | History | Annotate | Download | only in CirrusLogic5430Dxe
      1 /** @file
      2   Cirrus Logic 5430 Controller Driver.
      3   This driver is a sample implementation of the UGA Draw and Graphics Output
      4   Protocols for the Cirrus Logic 5430 family of PCI video controllers.
      5   This driver is only usable in the EFI pre-boot environment.
      6   This sample is intended to show how the UGA Draw and Graphics output Protocol
      7   is able to function.
      8   The UGA I/O Protocol is not implemented in this sample.
      9   A fully compliant EFI UGA driver requires both
     10   the UGA Draw and the UGA I/O Protocol.  Please refer to Microsoft's
     11   documentation on UGA for details on how to write a UGA driver that is able
     12   to function both in the EFI pre-boot environment and from the OS runtime.
     13 
     14   Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
     15   This program and the accompanying materials
     16   are licensed and made available under the terms and conditions of the BSD License
     17   which accompanies this distribution.  The full text of the license may be found at
     18   http://opensource.org/licenses/bsd-license.php
     19 
     20   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     21   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     22 
     23 **/
     24 
     25 //
     26 // Cirrus Logic 5430 Controller Driver
     27 //
     28 #include "CirrusLogic5430.h"
     29 
     30 EFI_DRIVER_BINDING_PROTOCOL gCirrusLogic5430DriverBinding = {
     31   CirrusLogic5430ControllerDriverSupported,
     32   CirrusLogic5430ControllerDriverStart,
     33   CirrusLogic5430ControllerDriverStop,
     34   0x10,
     35   NULL,
     36   NULL
     37 };
     38 
     39 ///
     40 /// Generic Attribute Controller Register Settings
     41 ///
     42 UINT8  AttributeController[21] = {
     43   0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
     44   0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
     45   0x41, 0x00, 0x0F, 0x00, 0x00
     46 };
     47 
     48 ///
     49 /// Generic Graphics Controller Register Settings
     50 ///
     51 UINT8 GraphicsController[9] = {
     52   0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, 0xFF
     53 };
     54 
     55 //
     56 // 640 x 480 x 256 color @ 60 Hertz
     57 //
     58 UINT8 Crtc_640_480_256_60[28] = {
     59   0x5d, 0x4f, 0x50, 0x82, 0x53, 0x9f, 0x00, 0x3e,
     60   0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     61   0xe1, 0x83, 0xdf, 0x50, 0x00, 0xe7, 0x04, 0xe3,
     62   0xff, 0x00, 0x00, 0x22
     63 };
     64 
     65 UINT16 Seq_640_480_256_60[15] = {
     66   0x0100, 0x0101, 0x0f02, 0x0003, 0x0e04, 0x1107, 0x0008, 0x4a0b,
     67   0x5b0c, 0x450d, 0x7e0e, 0x2b1b, 0x2f1c, 0x301d, 0x331e
     68 };
     69 
     70 //
     71 // 800 x 600 x 256 color @ 60 Hertz
     72 //
     73 UINT8 Crtc_800_600_256_60[28] = {
     74   0x7F, 0x63, 0x64, 0x80, 0x6B, 0x1B, 0x72, 0xF0,
     75   0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     76   0x58, 0x8C, 0x57, 0x64, 0x00, 0x5F, 0x91, 0xE3,
     77   0xFF, 0x00, 0x00, 0x22
     78 };
     79 
     80 UINT16 Seq_800_600_256_60[15] = {
     81   0x0100, 0x0101, 0x0f02, 0x0003, 0x0e04, 0x1107, 0x0008, 0x4a0b,
     82   0x5b0c, 0x450d, 0x510e, 0x2b1b, 0x2f1c, 0x301d, 0x3a1e
     83 };
     84 
     85 //
     86 // 1024 x 768 x 256 color @ 60 Hertz
     87 //
     88 UINT8 Crtc_1024_768_256_60[28] = {
     89   0xA3, 0x7F, 0x80, 0x86, 0x85, 0x96, 0x24, 0xFD,
     90   0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     91   0x02, 0x88, 0xFF, 0x80, 0x00, 0x00, 0x24, 0xE3,
     92   0xFF, 0x4A, 0x00, 0x22
     93 };
     94 
     95 UINT16 Seq_1024_768_256_60[15] = {
     96   0x0100, 0x0101, 0x0f02, 0x0003, 0x0e04, 0x1107, 0x0008, 0x4a0b,
     97   0x5b0c, 0x450d, 0x760e, 0x2b1b, 0x2f1c, 0x301d, 0x341e
     98 };
     99 
    100 ///
    101 /// Table of supported video modes
    102 ///
    103 CIRRUS_LOGIC_5430_VIDEO_MODES  CirrusLogic5430VideoModes[] = {
    104   {  640, 480, 8, 60, Crtc_640_480_256_60,  Seq_640_480_256_60,  0xe3 },
    105   {  800, 600, 8, 60, Crtc_800_600_256_60,  Seq_800_600_256_60,  0xef },
    106   { 1024, 768, 8, 60, Crtc_1024_768_256_60, Seq_1024_768_256_60, 0xef }
    107 };
    108 
    109 
    110 /**
    111   CirrusLogic5430ControllerDriverSupported
    112 
    113   TODO:    This - add argument and description to function comment
    114   TODO:    Controller - add argument and description to function comment
    115   TODO:    RemainingDevicePath - add argument and description to function comment
    116 **/
    117 EFI_STATUS
    118 EFIAPI
    119 CirrusLogic5430ControllerDriverSupported (
    120   IN EFI_DRIVER_BINDING_PROTOCOL    *This,
    121   IN EFI_HANDLE                     Controller,
    122   IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath
    123   )
    124 {
    125   EFI_STATUS          Status;
    126   EFI_PCI_IO_PROTOCOL *PciIo;
    127   PCI_TYPE00          Pci;
    128   EFI_DEV_PATH        *Node;
    129 
    130   //
    131   // Open the PCI I/O Protocol
    132   //
    133   Status = gBS->OpenProtocol (
    134                   Controller,
    135                   &gEfiPciIoProtocolGuid,
    136                   (VOID **) &PciIo,
    137                   This->DriverBindingHandle,
    138                   Controller,
    139                   EFI_OPEN_PROTOCOL_BY_DRIVER
    140                   );
    141   if (EFI_ERROR (Status)) {
    142     return Status;
    143   }
    144 
    145   //
    146   // Read the PCI Configuration Header from the PCI Device
    147   //
    148   Status = PciIo->Pci.Read (
    149                         PciIo,
    150                         EfiPciIoWidthUint32,
    151                         0,
    152                         sizeof (Pci) / sizeof (UINT32),
    153                         &Pci
    154                         );
    155   if (EFI_ERROR (Status)) {
    156     goto Done;
    157   }
    158 
    159   Status = EFI_UNSUPPORTED;
    160   //
    161   // See if the I/O enable is on.  Most systems only allow one VGA device to be turned on
    162   // at a time, so see if this is one that is turned on.
    163   //
    164   //  if (((Pci.Hdr.Command & 0x01) == 0x01)) {
    165   //
    166   // See if this is a Cirrus Logic PCI controller
    167   //
    168   if (Pci.Hdr.VendorId == CIRRUS_LOGIC_VENDOR_ID) {
    169     //
    170     // See if this is a 5430 or a 5446 PCI controller
    171     //
    172     if (Pci.Hdr.DeviceId == CIRRUS_LOGIC_5430_DEVICE_ID ||
    173         Pci.Hdr.DeviceId == CIRRUS_LOGIC_5430_ALTERNATE_DEVICE_ID ||
    174         Pci.Hdr.DeviceId == CIRRUS_LOGIC_5446_DEVICE_ID) {
    175 
    176       Status = EFI_SUCCESS;
    177       //
    178       // If this is an Intel 945 graphics controller,
    179       // go further check RemainingDevicePath validation
    180       //
    181       if (RemainingDevicePath != NULL) {
    182         Node = (EFI_DEV_PATH *) RemainingDevicePath;
    183         //
    184         // Check if RemainingDevicePath is the End of Device Path Node,
    185         // if yes, return EFI_SUCCESS
    186         //
    187         if (!IsDevicePathEnd (Node)) {
    188           //
    189           // If RemainingDevicePath isn't the End of Device Path Node,
    190           // check its validation
    191           //
    192           if (Node->DevPath.Type != ACPI_DEVICE_PATH ||
    193               Node->DevPath.SubType != ACPI_ADR_DP ||
    194               DevicePathNodeLength(&Node->DevPath) != sizeof(ACPI_ADR_DEVICE_PATH)) {
    195             Status = EFI_UNSUPPORTED;
    196           }
    197         }
    198       }
    199     }
    200   }
    201 
    202 Done:
    203   //
    204   // Close the PCI I/O Protocol
    205   //
    206   gBS->CloseProtocol (
    207         Controller,
    208         &gEfiPciIoProtocolGuid,
    209         This->DriverBindingHandle,
    210         Controller
    211         );
    212 
    213   return Status;
    214 }
    215 
    216 /**
    217   CirrusLogic5430ControllerDriverStart
    218 
    219   TODO:    This - add argument and description to function comment
    220   TODO:    Controller - add argument and description to function comment
    221   TODO:    RemainingDevicePath - add argument and description to function comment
    222 **/
    223 EFI_STATUS
    224 EFIAPI
    225 CirrusLogic5430ControllerDriverStart (
    226   IN EFI_DRIVER_BINDING_PROTOCOL    *This,
    227   IN EFI_HANDLE                     Controller,
    228   IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath
    229   )
    230 {
    231   EFI_STATUS                      Status;
    232   CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private;
    233   BOOLEAN                         PciAttributesSaved;
    234   EFI_DEVICE_PATH_PROTOCOL        *ParentDevicePath;
    235   ACPI_ADR_DEVICE_PATH            AcpiDeviceNode;
    236   UINT64                          Supports;
    237 
    238   PciAttributesSaved = FALSE;
    239   //
    240   // Allocate Private context data for UGA Draw inteface.
    241   //
    242   Private = AllocateZeroPool (sizeof (CIRRUS_LOGIC_5430_PRIVATE_DATA));
    243   if (Private == NULL) {
    244     Status = EFI_OUT_OF_RESOURCES;
    245     goto Error;
    246   }
    247 
    248   //
    249   // Set up context record
    250   //
    251   Private->Signature  = CIRRUS_LOGIC_5430_PRIVATE_DATA_SIGNATURE;
    252   Private->Handle     = NULL;
    253 
    254   //
    255   // Open PCI I/O Protocol
    256   //
    257   Status = gBS->OpenProtocol (
    258                   Controller,
    259                   &gEfiPciIoProtocolGuid,
    260                   (VOID **) &Private->PciIo,
    261                   This->DriverBindingHandle,
    262                   Controller,
    263                   EFI_OPEN_PROTOCOL_BY_DRIVER
    264                   );
    265   if (EFI_ERROR (Status)) {
    266     goto Error;
    267   }
    268 
    269   //
    270   // Get supported PCI attributes
    271   //
    272   Status = Private->PciIo->Attributes (
    273                              Private->PciIo,
    274                              EfiPciIoAttributeOperationSupported,
    275                              0,
    276                              &Supports
    277                              );
    278   if (EFI_ERROR (Status)) {
    279     goto Error;
    280   }
    281 
    282   Supports &= (EFI_PCI_IO_ATTRIBUTE_VGA_IO | EFI_PCI_IO_ATTRIBUTE_VGA_IO_16);
    283   if (Supports == 0 || Supports == (EFI_PCI_IO_ATTRIBUTE_VGA_IO | EFI_PCI_IO_ATTRIBUTE_VGA_IO_16)) {
    284     Status = EFI_UNSUPPORTED;
    285     goto Error;
    286   }
    287 
    288   //
    289   // Save original PCI attributes
    290   //
    291   Status = Private->PciIo->Attributes (
    292                     Private->PciIo,
    293                     EfiPciIoAttributeOperationGet,
    294                     0,
    295                     &Private->OriginalPciAttributes
    296                     );
    297 
    298   if (EFI_ERROR (Status)) {
    299     goto Error;
    300   }
    301   PciAttributesSaved = TRUE;
    302 
    303   Status = Private->PciIo->Attributes (
    304                              Private->PciIo,
    305                              EfiPciIoAttributeOperationEnable,
    306                              EFI_PCI_DEVICE_ENABLE | EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY | Supports,
    307                              NULL
    308                              );
    309   if (EFI_ERROR (Status)) {
    310     goto Error;
    311   }
    312 
    313   //
    314   // Get ParentDevicePath
    315   //
    316   Status = gBS->HandleProtocol (
    317                   Controller,
    318                   &gEfiDevicePathProtocolGuid,
    319                   (VOID **) &ParentDevicePath
    320                   );
    321   if (EFI_ERROR (Status)) {
    322     goto Error;
    323   }
    324 
    325   if (FeaturePcdGet (PcdSupportGop)) {
    326     //
    327     // Set Gop Device Path
    328     //
    329     if (RemainingDevicePath == NULL) {
    330       ZeroMem (&AcpiDeviceNode, sizeof (ACPI_ADR_DEVICE_PATH));
    331       AcpiDeviceNode.Header.Type = ACPI_DEVICE_PATH;
    332       AcpiDeviceNode.Header.SubType = ACPI_ADR_DP;
    333       AcpiDeviceNode.ADR = ACPI_DISPLAY_ADR (1, 0, 0, 1, 0, ACPI_ADR_DISPLAY_TYPE_VGA, 0, 0);
    334       SetDevicePathNodeLength (&AcpiDeviceNode.Header, sizeof (ACPI_ADR_DEVICE_PATH));
    335 
    336       Private->GopDevicePath = AppendDevicePathNode (
    337                                           ParentDevicePath,
    338                                           (EFI_DEVICE_PATH_PROTOCOL *) &AcpiDeviceNode
    339                                           );
    340     } else if (!IsDevicePathEnd (RemainingDevicePath)) {
    341       //
    342       // If RemainingDevicePath isn't the End of Device Path Node,
    343       // only scan the specified device by RemainingDevicePath
    344       //
    345       Private->GopDevicePath = AppendDevicePathNode (ParentDevicePath, RemainingDevicePath);
    346     } else {
    347       //
    348       // If RemainingDevicePath is the End of Device Path Node,
    349       // don't create child device and return EFI_SUCCESS
    350       //
    351       Private->GopDevicePath = NULL;
    352     }
    353 
    354     if (Private->GopDevicePath != NULL) {
    355       //
    356       // Creat child handle and device path protocol firstly
    357       //
    358       Private->Handle = NULL;
    359       Status = gBS->InstallMultipleProtocolInterfaces (
    360                       &Private->Handle,
    361                       &gEfiDevicePathProtocolGuid,
    362                       Private->GopDevicePath,
    363                       NULL
    364                       );
    365     }
    366   }
    367 
    368   //
    369   // Construct video mode buffer
    370   //
    371   Status = CirrusLogic5430VideoModeSetup (Private);
    372   if (EFI_ERROR (Status)) {
    373     goto Error;
    374   }
    375 
    376   if (FeaturePcdGet (PcdSupportUga)) {
    377     //
    378     // Start the UGA Draw software stack.
    379     //
    380     Status = CirrusLogic5430UgaDrawConstructor (Private);
    381     ASSERT_EFI_ERROR (Status);
    382 
    383     Private->UgaDevicePath = ParentDevicePath;
    384     Status = gBS->InstallMultipleProtocolInterfaces (
    385                     &Controller,
    386                     &gEfiUgaDrawProtocolGuid,
    387                     &Private->UgaDraw,
    388                     &gEfiDevicePathProtocolGuid,
    389                     Private->UgaDevicePath,
    390                     NULL
    391                     );
    392 
    393   } else if (FeaturePcdGet (PcdSupportGop)) {
    394     if (Private->GopDevicePath == NULL) {
    395       //
    396       // If RemainingDevicePath is the End of Device Path Node,
    397       // don't create child device and return EFI_SUCCESS
    398       //
    399       Status = EFI_SUCCESS;
    400     } else {
    401 
    402       //
    403       // Start the GOP software stack.
    404       //
    405       Status = CirrusLogic5430GraphicsOutputConstructor (Private);
    406       ASSERT_EFI_ERROR (Status);
    407 
    408       Status = gBS->InstallMultipleProtocolInterfaces (
    409                       &Private->Handle,
    410                       &gEfiGraphicsOutputProtocolGuid,
    411                       &Private->GraphicsOutput,
    412                       &gEfiEdidDiscoveredProtocolGuid,
    413                       &Private->EdidDiscovered,
    414                       &gEfiEdidActiveProtocolGuid,
    415                       &Private->EdidActive,
    416                       NULL
    417                       );
    418     }
    419   } else {
    420     //
    421     // This driver must support eithor GOP or UGA or both.
    422     //
    423     ASSERT (FALSE);
    424     Status = EFI_UNSUPPORTED;
    425   }
    426 
    427 
    428 Error:
    429   if (EFI_ERROR (Status)) {
    430     if (Private) {
    431       if (Private->PciIo) {
    432         if (PciAttributesSaved == TRUE) {
    433           //
    434           // Restore original PCI attributes
    435           //
    436           Private->PciIo->Attributes (
    437                           Private->PciIo,
    438                           EfiPciIoAttributeOperationSet,
    439                           Private->OriginalPciAttributes,
    440                           NULL
    441                           );
    442         }
    443         //
    444         // Close the PCI I/O Protocol
    445         //
    446         gBS->CloseProtocol (
    447               Private->Handle,
    448               &gEfiPciIoProtocolGuid,
    449               This->DriverBindingHandle,
    450               Private->Handle
    451               );
    452       }
    453 
    454       gBS->FreePool (Private);
    455     }
    456   }
    457 
    458   return Status;
    459 }
    460 
    461 /**
    462   CirrusLogic5430ControllerDriverStop
    463 
    464   TODO:    This - add argument and description to function comment
    465   TODO:    Controller - add argument and description to function comment
    466   TODO:    NumberOfChildren - add argument and description to function comment
    467   TODO:    ChildHandleBuffer - add argument and description to function comment
    468   TODO:    EFI_SUCCESS - add return value to function comment
    469 **/
    470 EFI_STATUS
    471 EFIAPI
    472 CirrusLogic5430ControllerDriverStop (
    473   IN EFI_DRIVER_BINDING_PROTOCOL    *This,
    474   IN EFI_HANDLE                     Controller,
    475   IN UINTN                          NumberOfChildren,
    476   IN EFI_HANDLE                     *ChildHandleBuffer
    477   )
    478 {
    479   EFI_UGA_DRAW_PROTOCOL           *UgaDraw;
    480   EFI_GRAPHICS_OUTPUT_PROTOCOL    *GraphicsOutput;
    481 
    482   EFI_STATUS                      Status;
    483   CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private;
    484 
    485   if (FeaturePcdGet (PcdSupportUga)) {
    486     Status = gBS->OpenProtocol (
    487                     Controller,
    488                     &gEfiUgaDrawProtocolGuid,
    489                     (VOID **) &UgaDraw,
    490                     This->DriverBindingHandle,
    491                     Controller,
    492                     EFI_OPEN_PROTOCOL_GET_PROTOCOL
    493                     );
    494     if (EFI_ERROR (Status)) {
    495       return Status;
    496     }
    497     //
    498     // Get our private context information
    499     //
    500     Private = CIRRUS_LOGIC_5430_PRIVATE_DATA_FROM_UGA_DRAW_THIS (UgaDraw);
    501     CirrusLogic5430UgaDrawDestructor (Private);
    502 
    503     if (FeaturePcdGet (PcdSupportGop)) {
    504       CirrusLogic5430GraphicsOutputDestructor (Private);
    505       //
    506       // Remove the UGA and GOP protocol interface from the system
    507       //
    508       Status = gBS->UninstallMultipleProtocolInterfaces (
    509                       Private->Handle,
    510                       &gEfiUgaDrawProtocolGuid,
    511                       &Private->UgaDraw,
    512                       &gEfiGraphicsOutputProtocolGuid,
    513                       &Private->GraphicsOutput,
    514                       NULL
    515                       );
    516     } else {
    517       //
    518       // Remove the UGA Draw interface from the system
    519       //
    520       Status = gBS->UninstallMultipleProtocolInterfaces (
    521                       Private->Handle,
    522                       &gEfiUgaDrawProtocolGuid,
    523                       &Private->UgaDraw,
    524                       NULL
    525                       );
    526     }
    527   } else {
    528     Status = gBS->OpenProtocol (
    529                     Controller,
    530                     &gEfiGraphicsOutputProtocolGuid,
    531                     (VOID **) &GraphicsOutput,
    532                     This->DriverBindingHandle,
    533                     Controller,
    534                     EFI_OPEN_PROTOCOL_GET_PROTOCOL
    535                     );
    536     if (EFI_ERROR (Status)) {
    537       return Status;
    538     }
    539 
    540     //
    541     // Get our private context information
    542     //
    543     Private = CIRRUS_LOGIC_5430_PRIVATE_DATA_FROM_GRAPHICS_OUTPUT_THIS (GraphicsOutput);
    544 
    545     CirrusLogic5430GraphicsOutputDestructor (Private);
    546     //
    547     // Remove the GOP protocol interface from the system
    548     //
    549     Status = gBS->UninstallMultipleProtocolInterfaces (
    550                     Private->Handle,
    551                     &gEfiUgaDrawProtocolGuid,
    552                     &Private->UgaDraw,
    553                     &gEfiGraphicsOutputProtocolGuid,
    554                     &Private->GraphicsOutput,
    555                     NULL
    556                     );
    557   }
    558 
    559   if (EFI_ERROR (Status)) {
    560     return Status;
    561   }
    562 
    563   //
    564   // Restore original PCI attributes
    565   //
    566   Private->PciIo->Attributes (
    567                   Private->PciIo,
    568                   EfiPciIoAttributeOperationSet,
    569                   Private->OriginalPciAttributes,
    570                   NULL
    571                   );
    572 
    573   //
    574   // Close the PCI I/O Protocol
    575   //
    576   gBS->CloseProtocol (
    577         Controller,
    578         &gEfiPciIoProtocolGuid,
    579         This->DriverBindingHandle,
    580         Controller
    581         );
    582 
    583   //
    584   // Free our instance data
    585   //
    586   gBS->FreePool (Private);
    587 
    588   return EFI_SUCCESS;
    589 }
    590 
    591 /**
    592   CirrusLogic5430UgaDrawDestructor
    593 
    594   TODO:    Private - add argument and description to function comment
    595   TODO:    EFI_SUCCESS - add return value to function comment
    596 **/
    597 EFI_STATUS
    598 CirrusLogic5430UgaDrawDestructor (
    599   CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private
    600   )
    601 {
    602   return EFI_SUCCESS;
    603 }
    604 
    605 /**
    606   TODO: Add function description
    607 
    608   @param  Private TODO: add argument description
    609   @param  Address TODO: add argument description
    610   @param  Data TODO: add argument description
    611 
    612   TODO: add return values
    613 
    614 **/
    615 VOID
    616 outb (
    617   CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private,
    618   UINTN                           Address,
    619   UINT8                           Data
    620   )
    621 {
    622   Private->PciIo->Io.Write (
    623                       Private->PciIo,
    624                       EfiPciIoWidthUint8,
    625                       EFI_PCI_IO_PASS_THROUGH_BAR,
    626                       Address,
    627                       1,
    628                       &Data
    629                       );
    630 }
    631 
    632 /**
    633   TODO: Add function description
    634 
    635   @param  Private TODO: add argument description
    636   @param  Address TODO: add argument description
    637   @param  Data TODO: add argument description
    638 
    639   TODO: add return values
    640 
    641 **/
    642 VOID
    643 outw (
    644   CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private,
    645   UINTN                           Address,
    646   UINT16                          Data
    647   )
    648 {
    649   Private->PciIo->Io.Write (
    650                       Private->PciIo,
    651                       EfiPciIoWidthUint16,
    652                       EFI_PCI_IO_PASS_THROUGH_BAR,
    653                       Address,
    654                       1,
    655                       &Data
    656                       );
    657 }
    658 
    659 /**
    660   TODO: Add function description
    661 
    662   @param  Private TODO: add argument description
    663   @param  Address TODO: add argument description
    664 
    665   TODO: add return values
    666 
    667 **/
    668 UINT8
    669 inb (
    670   CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private,
    671   UINTN                           Address
    672   )
    673 {
    674   UINT8 Data;
    675 
    676   Private->PciIo->Io.Read (
    677                       Private->PciIo,
    678                       EfiPciIoWidthUint8,
    679                       EFI_PCI_IO_PASS_THROUGH_BAR,
    680                       Address,
    681                       1,
    682                       &Data
    683                       );
    684   return Data;
    685 }
    686 
    687 /**
    688   TODO: Add function description
    689 
    690   @param  Private TODO: add argument description
    691   @param  Address TODO: add argument description
    692 
    693   TODO: add return values
    694 
    695 **/
    696 UINT16
    697 inw (
    698   CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private,
    699   UINTN                           Address
    700   )
    701 {
    702   UINT16  Data;
    703 
    704   Private->PciIo->Io.Read (
    705                       Private->PciIo,
    706                       EfiPciIoWidthUint16,
    707                       EFI_PCI_IO_PASS_THROUGH_BAR,
    708                       Address,
    709                       1,
    710                       &Data
    711                       );
    712   return Data;
    713 }
    714 
    715 /**
    716   TODO: Add function description
    717 
    718   @param  Private TODO: add argument description
    719   @param  Index TODO: add argument description
    720   @param  Red TODO: add argument description
    721   @param  Green TODO: add argument description
    722   @param  Blue TODO: add argument description
    723 
    724   TODO: add return values
    725 
    726 **/
    727 VOID
    728 SetPaletteColor (
    729   CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private,
    730   UINTN                           Index,
    731   UINT8                           Red,
    732   UINT8                           Green,
    733   UINT8                           Blue
    734   )
    735 {
    736   outb (Private, PALETTE_INDEX_REGISTER, (UINT8) Index);
    737   outb (Private, PALETTE_DATA_REGISTER, (UINT8) (Red >> 2));
    738   outb (Private, PALETTE_DATA_REGISTER, (UINT8) (Green >> 2));
    739   outb (Private, PALETTE_DATA_REGISTER, (UINT8) (Blue >> 2));
    740 }
    741 
    742 /**
    743   TODO: Add function description
    744 
    745   @param  Private TODO: add argument description
    746 
    747   TODO: add return values
    748 
    749 **/
    750 VOID
    751 SetDefaultPalette (
    752   CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private
    753   )
    754 {
    755   UINTN Index;
    756   UINTN RedIndex;
    757   UINTN GreenIndex;
    758   UINTN BlueIndex;
    759 
    760   Index = 0;
    761   for (RedIndex = 0; RedIndex < 8; RedIndex++) {
    762     for (GreenIndex = 0; GreenIndex < 8; GreenIndex++) {
    763       for (BlueIndex = 0; BlueIndex < 4; BlueIndex++) {
    764         SetPaletteColor (Private, Index, (UINT8) (RedIndex << 5), (UINT8) (GreenIndex << 5), (UINT8) (BlueIndex << 6));
    765         Index++;
    766       }
    767     }
    768   }
    769 }
    770 
    771 /**
    772   TODO: Add function description
    773 
    774   @param  Private TODO: add argument description
    775 
    776   TODO: add return values
    777 
    778 **/
    779 VOID
    780 ClearScreen (
    781   CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private
    782   )
    783 {
    784   UINT32  Color;
    785 
    786   Color = 0;
    787   Private->PciIo->Mem.Write (
    788                         Private->PciIo,
    789                         EfiPciIoWidthFillUint32,
    790                         0,
    791                         0,
    792                         0x100000 >> 2,
    793                         &Color
    794                         );
    795 }
    796 
    797 /**
    798   TODO: Add function description
    799 
    800   @param  Private TODO: add argument description
    801 
    802   TODO: add return values
    803 
    804 **/
    805 VOID
    806 DrawLogo (
    807   CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private,
    808   UINTN                           ScreenWidth,
    809   UINTN                           ScreenHeight
    810   )
    811 {
    812 }
    813 
    814 /**
    815   TODO: Add function description
    816 
    817   @param  Private TODO: add argument description
    818   @param  ModeData TODO: add argument description
    819 
    820   TODO: add return values
    821 
    822 **/
    823 VOID
    824 InitializeGraphicsMode (
    825   CIRRUS_LOGIC_5430_PRIVATE_DATA  *Private,
    826   CIRRUS_LOGIC_5430_VIDEO_MODES   *ModeData
    827   )
    828 {
    829   UINT8 Byte;
    830   UINTN Index;
    831   UINT16 DeviceId;
    832   EFI_STATUS Status;
    833 
    834   Status = Private->PciIo->Pci.Read (
    835              Private->PciIo,
    836              EfiPciIoWidthUint16,
    837              PCI_DEVICE_ID_OFFSET,
    838              1,
    839              &DeviceId
    840              );
    841   //
    842   // Read the PCI Configuration Header from the PCI Device
    843   //
    844   ASSERT_EFI_ERROR (Status);
    845 
    846   outw (Private, SEQ_ADDRESS_REGISTER, 0x1206);
    847   outw (Private, SEQ_ADDRESS_REGISTER, 0x0012);
    848 
    849   for (Index = 0; Index < 15; Index++) {
    850     outw (Private, SEQ_ADDRESS_REGISTER, ModeData->SeqSettings[Index]);
    851   }
    852 
    853   if (DeviceId != CIRRUS_LOGIC_5446_DEVICE_ID) {
    854     outb (Private, SEQ_ADDRESS_REGISTER, 0x0f);
    855     Byte = (UINT8) ((inb (Private, SEQ_DATA_REGISTER) & 0xc7) ^ 0x30);
    856     outb (Private, SEQ_DATA_REGISTER, Byte);
    857   }
    858 
    859   outb (Private, MISC_OUTPUT_REGISTER, ModeData->MiscSetting);
    860   outw (Private, GRAPH_ADDRESS_REGISTER, 0x0506);
    861   outw (Private, SEQ_ADDRESS_REGISTER, 0x0300);
    862   outw (Private, CRTC_ADDRESS_REGISTER, 0x2011);
    863 
    864   for (Index = 0; Index < 28; Index++) {
    865     outw (Private, CRTC_ADDRESS_REGISTER, (UINT16) ((ModeData->CrtcSettings[Index] << 8) | Index));
    866   }
    867 
    868   for (Index = 0; Index < 9; Index++) {
    869     outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((GraphicsController[Index] << 8) | Index));
    870   }
    871 
    872   inb (Private, INPUT_STATUS_1_REGISTER);
    873 
    874   for (Index = 0; Index < 21; Index++) {
    875     outb (Private, ATT_ADDRESS_REGISTER, (UINT8) Index);
    876     outb (Private, ATT_ADDRESS_REGISTER, AttributeController[Index]);
    877   }
    878 
    879   outb (Private, ATT_ADDRESS_REGISTER, 0x20);
    880 
    881   outw (Private, GRAPH_ADDRESS_REGISTER, 0x0009);
    882   outw (Private, GRAPH_ADDRESS_REGISTER, 0x000a);
    883   outw (Private, GRAPH_ADDRESS_REGISTER, 0x000b);
    884   outb (Private, DAC_PIXEL_MASK_REGISTER, 0xff);
    885 
    886   SetDefaultPalette (Private);
    887   ClearScreen (Private);
    888 }
    889 
    890 EFI_STATUS
    891 EFIAPI
    892 InitializeCirrusLogic5430 (
    893   IN EFI_HANDLE           ImageHandle,
    894   IN EFI_SYSTEM_TABLE     *SystemTable
    895   )
    896 {
    897   EFI_STATUS              Status;
    898 
    899   Status = EfiLibInstallDriverBindingComponentName2 (
    900              ImageHandle,
    901              SystemTable,
    902              &gCirrusLogic5430DriverBinding,
    903              ImageHandle,
    904              &gCirrusLogic5430ComponentName,
    905              &gCirrusLogic5430ComponentName2
    906              );
    907   ASSERT_EFI_ERROR (Status);
    908 
    909   //
    910   // Install EFI Driver Supported EFI Version Protocol required for
    911   // EFI drivers that are on PCI and other plug in cards.
    912   //
    913   gCirrusLogic5430DriverSupportedEfiVersion.FirmwareVersion = PcdGet32 (PcdDriverSupportedEfiVersion);
    914   Status = gBS->InstallMultipleProtocolInterfaces (
    915                   &ImageHandle,
    916                   &gEfiDriverSupportedEfiVersionProtocolGuid,
    917                   &gCirrusLogic5430DriverSupportedEfiVersion,
    918                   NULL
    919                   );
    920   ASSERT_EFI_ERROR (Status);
    921 
    922   return Status;
    923 }
    924