Protocols for the Cirrus Logic 5430 family of PCI video controllers.\r
This driver is only usable in the EFI pre-boot environment.\r
This sample is intended to show how the UGA Draw and Graphics output Protocol\r
- is able to function. \r
+ is able to function.\r
The UGA I/O Protocol is not implemented in this sample.\r
A fully compliant EFI UGA driver requires both\r
the UGA Draw and the UGA I/O Protocol. Please refer to Microsoft's\r
documentation on UGA for details on how to write a UGA driver that is able\r
to function both in the EFI pre-boot environment and from the OS runtime.\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 - 2010, Intel Corporation. All rights reserved.<BR>\r
+ 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
/// Generic Attribute Controller Register Settings\r
///\r
UINT8 AttributeController[21] = {\r
- 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, \r
- 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, \r
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,\r
+ 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,\r
0x41, 0x00, 0x0F, 0x00, 0x00\r
};\r
\r
//\r
UINT8 Crtc_640_480_256_60[28] = {\r
0x5d, 0x4f, 0x50, 0x82, 0x53, 0x9f, 0x00, 0x3e,\r
- 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \r
+ 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
0xe1, 0x83, 0xdf, 0x50, 0x00, 0xe7, 0x04, 0xe3,\r
0xff, 0x00, 0x00, 0x22\r
};\r
\r
UINT16 Seq_640_480_256_60[15] = {\r
- 0x0100, 0x0101, 0x0f02, 0x0003, 0x0e04, 0x1107, 0x0008, 0x4a0b, \r
+ 0x0100, 0x0101, 0x0f02, 0x0003, 0x0e04, 0x1107, 0x0008, 0x4a0b,\r
0x5b0c, 0x450d, 0x7e0e, 0x2b1b, 0x2f1c, 0x301d, 0x331e\r
};\r
\r
// 800 x 600 x 256 color @ 60 Hertz\r
//\r
UINT8 Crtc_800_600_256_60[28] = {\r
- 0x7F, 0x63, 0x64, 0x80, 0x6B, 0x1B, 0x72, 0xF0, \r
- 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \r
+ 0x7F, 0x63, 0x64, 0x80, 0x6B, 0x1B, 0x72, 0xF0,\r
+ 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
0x58, 0x8C, 0x57, 0x64, 0x00, 0x5F, 0x91, 0xE3,\r
0xFF, 0x00, 0x00, 0x22\r
};\r
\r
UINT16 Seq_800_600_256_60[15] = {\r
- 0x0100, 0x0101, 0x0f02, 0x0003, 0x0e04, 0x1107, 0x0008, 0x4a0b, \r
+ 0x0100, 0x0101, 0x0f02, 0x0003, 0x0e04, 0x1107, 0x0008, 0x4a0b,\r
0x5b0c, 0x450d, 0x510e, 0x2b1b, 0x2f1c, 0x301d, 0x3a1e\r
};\r
\r
// 1024 x 768 x 256 color @ 60 Hertz\r
//\r
UINT8 Crtc_1024_768_256_60[28] = {\r
- 0xA3, 0x7F, 0x80, 0x86, 0x85, 0x96, 0x24, 0xFD, \r
- 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \r
+ 0xA3, 0x7F, 0x80, 0x86, 0x85, 0x96, 0x24, 0xFD,\r
+ 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
0x02, 0x88, 0xFF, 0x80, 0x00, 0x00, 0x24, 0xE3,\r
0xFF, 0x4A, 0x00, 0x22\r
};\r
\r
UINT16 Seq_1024_768_256_60[15] = {\r
- 0x0100, 0x0101, 0x0f02, 0x0003, 0x0e04, 0x1107, 0x0008, 0x4a0b, \r
+ 0x0100, 0x0101, 0x0f02, 0x0003, 0x0e04, 0x1107, 0x0008, 0x4a0b,\r
0x5b0c, 0x450d, 0x760e, 0x2b1b, 0x2f1c, 0x301d, 0x341e\r
};\r
\r
///\r
CIRRUS_LOGIC_5430_VIDEO_MODES CirrusLogic5430VideoModes[] = {\r
{ 640, 480, 8, 60, Crtc_640_480_256_60, Seq_640_480_256_60, 0xe3 },\r
- { 800, 600, 8, 60, Crtc_800_600_256_60, Seq_800_600_256_60, 0xef }, \r
- { 1024, 768, 8, 60, Crtc_1024_768_256_60, Seq_1024_768_256_60, 0xef } \r
+ { 800, 600, 8, 60, Crtc_800_600_256_60, Seq_800_600_256_60, 0xef },\r
+ { 1024, 768, 8, 60, Crtc_1024_768_256_60, Seq_1024_768_256_60, 0xef }\r
};\r
\r
+\r
/**\r
CirrusLogic5430ControllerDriverSupported\r
\r
EFI_STATUS Status;\r
EFI_PCI_IO_PROTOCOL *PciIo;\r
PCI_TYPE00 Pci;\r
+ EFI_DEV_PATH *Node;\r
\r
//\r
// Open the PCI I/O Protocol\r
//\r
// See if this is a 5430 or a 5446 PCI controller\r
//\r
- if (Pci.Hdr.DeviceId == CIRRUS_LOGIC_5430_DEVICE_ID) {\r
- Status = EFI_SUCCESS;\r
- }\r
-\r
- if (Pci.Hdr.DeviceId == CIRRUS_LOGIC_5430_ALTERNATE_DEVICE_ID) {\r
- Status = EFI_SUCCESS;\r
- }\r
-\r
- if (Pci.Hdr.DeviceId == CIRRUS_LOGIC_5446_DEVICE_ID) {\r
+ if (Pci.Hdr.DeviceId == CIRRUS_LOGIC_5430_DEVICE_ID || \r
+ Pci.Hdr.DeviceId == CIRRUS_LOGIC_5430_ALTERNATE_DEVICE_ID ||\r
+ Pci.Hdr.DeviceId == CIRRUS_LOGIC_5446_DEVICE_ID) {\r
+ \r
Status = EFI_SUCCESS;\r
+ //\r
+ // If this is an Intel 945 graphics controller,\r
+ // go further check RemainingDevicePath validation\r
+ //\r
+ if (RemainingDevicePath != NULL) {\r
+ Node = (EFI_DEV_PATH *) RemainingDevicePath;\r
+ //\r
+ // Check if RemainingDevicePath is the End of Device Path Node, \r
+ // if yes, return EFI_SUCCESS\r
+ //\r
+ if (!IsDevicePathEnd (Node)) {\r
+ //\r
+ // If RemainingDevicePath isn't the End of Device Path Node,\r
+ // check its validation\r
+ //\r
+ if (Node->DevPath.Type != ACPI_DEVICE_PATH ||\r
+ Node->DevPath.SubType != ACPI_ADR_DP ||\r
+ DevicePathNodeLength(&Node->DevPath) != sizeof(ACPI_ADR_DEVICE_PATH)) {\r
+ Status = EFI_UNSUPPORTED;\r
+ }\r
+ }\r
+ }\r
}\r
}\r
\r
{\r
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
+ UINT64 Supports;\r
\r
+ PciAttributesSaved = FALSE;\r
//\r
// Allocate Private context data for UGA Draw inteface.\r
//\r
// 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
//\r
Status = gBS->OpenProtocol (\r
- Private->Handle,\r
+ Controller,\r
&gEfiPciIoProtocolGuid,\r
(VOID **) &Private->PciIo,\r
This->DriverBindingHandle,\r
- Private->Handle,\r
+ Controller,\r
EFI_OPEN_PROTOCOL_BY_DRIVER\r
);\r
if (EFI_ERROR (Status)) {\r
goto Error;\r
}\r
\r
+ //\r
+ // Get supported PCI attributes\r
+ //\r
Status = Private->PciIo->Attributes (\r
- Private->PciIo,\r
- EfiPciIoAttributeOperationEnable,\r
- EFI_PCI_DEVICE_ENABLE | EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY | EFI_PCI_IO_ATTRIBUTE_VGA_IO,\r
- NULL\r
- );\r
+ Private->PciIo,\r
+ EfiPciIoAttributeOperationSupported,\r
+ 0,\r
+ &Supports\r
+ );\r
if (EFI_ERROR (Status)) {\r
goto Error;\r
}\r
\r
- if (FeaturePcdGet (PcdSupportUga)) {\r
+ Supports &= (EFI_PCI_IO_ATTRIBUTE_VGA_IO | EFI_PCI_IO_ATTRIBUTE_VGA_IO_16);\r
+ if (Supports == 0 || Supports == (EFI_PCI_IO_ATTRIBUTE_VGA_IO | EFI_PCI_IO_ATTRIBUTE_VGA_IO_16)) {\r
+ Status = EFI_UNSUPPORTED;\r
+ goto Error;\r
+ } \r
+\r
+ //\r
+ // Save original PCI attributes\r
+ //\r
+ Status = Private->PciIo->Attributes (\r
+ Private->PciIo,\r
+ EfiPciIoAttributeOperationGet,\r
+ 0,\r
+ &Private->OriginalPciAttributes\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ goto Error;\r
+ }\r
+ PciAttributesSaved = TRUE;\r
+\r
+ Status = Private->PciIo->Attributes (\r
+ Private->PciIo,\r
+ EfiPciIoAttributeOperationEnable,\r
+ EFI_PCI_DEVICE_ENABLE | EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY | Supports,\r
+ NULL\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ 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
- // Start the UGA Draw software stack.\r
+ // Set Gop Device Path\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
+ 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 if (!IsDevicePathEnd (RemainingDevicePath)) {\r
+ //\r
+ // If RemainingDevicePath isn't the End of Device Path Node, \r
+ // only scan the specified device by RemainingDevicePath\r
+ //\r
+ Private->GopDevicePath = AppendDevicePathNode (ParentDevicePath, RemainingDevicePath);\r
} else {\r
+ //\r
+ // If RemainingDevicePath is the End of Device Path Node, \r
+ // don't create child device and return EFI_SUCCESS\r
+ //\r
+ Private->GopDevicePath = NULL;\r
+ }\r
+ \r
+ if (Private->GopDevicePath != NULL) {\r
+ //\r
+ // Creat child handle and device path protocol firstly\r
+ //\r
+ Private->Handle = NULL;\r
Status = gBS->InstallMultipleProtocolInterfaces (\r
&Private->Handle,\r
- &gEfiUgaDrawProtocolGuid,\r
- &Private->UgaDraw,\r
+ &gEfiDevicePathProtocolGuid,\r
+ Private->GopDevicePath,\r
NULL\r
);\r
-\r
}\r
- } else {\r
- if (FeaturePcdGet (PcdSupportGop)) {\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
+\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
+ } else if (FeaturePcdGet (PcdSupportGop)) {\r
+ if (Private->GopDevicePath == NULL) {\r
+ //\r
+ // If RemainingDevicePath is the End of Device Path Node, \r
+ // don't create child device and return EFI_SUCCESS\r
+ //\r
+ Status = EFI_SUCCESS;\r
+ } else {\r
+ \r
+ //\r
+ // Start the GOP software stack.\r
+ //\r
Status = CirrusLogic5430GraphicsOutputConstructor (Private);\r
ASSERT_EFI_ERROR (Status);\r
-\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
\r
Error:\r
if (EFI_ERROR (Status)) {\r
if (Private) {\r
if (Private->PciIo) {\r
- Private->PciIo->Attributes (\r
+ if (PciAttributesSaved == TRUE) {\r
+ //\r
+ // Restore original PCI attributes\r
+ //\r
+ Private->PciIo->Attributes (\r
Private->PciIo,\r
- EfiPciIoAttributeOperationDisable,\r
- EFI_PCI_DEVICE_ENABLE | EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY | EFI_PCI_IO_ATTRIBUTE_VGA_IO,\r
+ EfiPciIoAttributeOperationSet,\r
+ Private->OriginalPciAttributes,\r
NULL\r
);\r
+ }\r
+ //\r
+ // Close the PCI I/O Protocol\r
+ //\r
+ gBS->CloseProtocol (\r
+ Private->Handle,\r
+ &gEfiPciIoProtocolGuid,\r
+ This->DriverBindingHandle,\r
+ Private->Handle\r
+ );\r
}\r
- }\r
\r
- //\r
- // Close the PCI I/O Protocol\r
- //\r
- gBS->CloseProtocol (\r
- Private->Handle,\r
- &gEfiPciIoProtocolGuid,\r
- This->DriverBindingHandle,\r
- Private->Handle\r
- );\r
- if (Private) {\r
gBS->FreePool (Private);\r
}\r
}\r
return Status;\r
}\r
\r
-\r
//\r
- // Shutdown the hardware\r
+ // Restore original PCI attributes\r
//\r
Private->PciIo->Attributes (\r
- Private->PciIo,\r
- EfiPciIoAttributeOperationDisable,\r
- EFI_PCI_DEVICE_ENABLE | EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY | EFI_PCI_IO_ATTRIBUTE_VGA_IO,\r
- NULL\r
- );\r
+ Private->PciIo,\r
+ EfiPciIoAttributeOperationSet,\r
+ Private->OriginalPciAttributes,\r
+ NULL\r
+ );\r
\r
//\r
// Close the PCI I/O Protocol\r
TODO: add return values\r
\r
**/\r
-STATIC\r
VOID\r
ClearScreen (\r
CIRRUS_LOGIC_5430_PRIVATE_DATA *Private\r
UINTN ScreenHeight\r
)\r
{\r
- UINTN Offset;\r
- UINTN X;\r
- UINTN Y;\r
- UINT8 Color;\r
-\r
- Offset = 0;\r
- for (Y = 0; Y < ScreenHeight; Y++) {\r
- for (X = 0; X < ScreenWidth; X++) {\r
- Color = (UINT8) (256 * (X + Y) / (ScreenWidth + ScreenHeight));\r
- Private->LineBuffer[X] = Color;\r
- }\r
-\r
- Private->PciIo->Mem.Write (\r
- Private->PciIo,\r
- EfiPciIoWidthUint32,\r
- 0,\r
- Offset + (Y * ScreenWidth),\r
- ScreenWidth >> 2,\r
- Private->LineBuffer\r
- );\r
- }\r
}\r
\r
/**\r
{\r
UINT8 Byte;\r
UINTN Index;\r
+ UINT16 DeviceId;\r
+ EFI_STATUS Status;\r
+\r
+ Status = Private->PciIo->Pci.Read (\r
+ Private->PciIo,\r
+ EfiPciIoWidthUint16,\r
+ PCI_DEVICE_ID_OFFSET,\r
+ 1,\r
+ &DeviceId\r
+ );\r
+ //\r
+ // Read the PCI Configuration Header from the PCI Device\r
+ //\r
+ ASSERT_EFI_ERROR (Status);\r
\r
outw (Private, SEQ_ADDRESS_REGISTER, 0x1206);\r
outw (Private, SEQ_ADDRESS_REGISTER, 0x0012);\r
outw (Private, SEQ_ADDRESS_REGISTER, ModeData->SeqSettings[Index]);\r
}\r
\r
- outb (Private, SEQ_ADDRESS_REGISTER, 0x0f);\r
- Byte = (UINT8) ((inb (Private, SEQ_DATA_REGISTER) & 0xc7) ^ 0x30);\r
- outb (Private, SEQ_DATA_REGISTER, Byte);\r
+ if (DeviceId != CIRRUS_LOGIC_5446_DEVICE_ID) {\r
+ outb (Private, SEQ_ADDRESS_REGISTER, 0x0f);\r
+ Byte = (UINT8) ((inb (Private, SEQ_DATA_REGISTER) & 0xc7) ^ 0x30);\r
+ outb (Private, SEQ_DATA_REGISTER, Byte);\r
+ }\r
\r
outb (Private, MISC_OUTPUT_REGISTER, ModeData->MiscSetting);\r
outw (Private, GRAPH_ADDRESS_REGISTER, 0x0506);\r
ASSERT_EFI_ERROR (Status);\r
\r
//\r
- // Install EFI Driver Supported EFI Version Protocol required for \r
+ // Install EFI Driver Supported EFI Version Protocol required for\r
// EFI drivers that are on PCI and other plug in cards.\r
//\r
gCirrusLogic5430DriverSupportedEfiVersion.FirmwareVersion = PcdGet32 (PcdDriverSupportedEfiVersion);\r