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
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.
14 Copyright (c) 2006, Intel Corporation
15 All rights reserved. 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
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.
26 // Cirrus Logic 5430 Controller Driver
28 #include "CirrusLogic5430.h"
30 EFI_DRIVER_BINDING_PROTOCOL gCirrusLogic5430DriverBinding
= {
31 CirrusLogic5430ControllerDriverSupported
,
32 CirrusLogic5430ControllerDriverStart
,
33 CirrusLogic5430ControllerDriverStop
,
40 /// Generic Attribute Controller Register Settings
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
49 /// Generic Graphics Controller Register Settings
51 UINT8 GraphicsController
[9] = {
52 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, 0xFF
56 // 640 x 480 x 256 color @ 60 Hertz
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
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
71 // 800 x 600 x 256 color @ 60 Hertz
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
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
86 // 1024 x 768 x 256 color @ 60 Hertz
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
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
101 /// Table of supported video modes
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 }
110 CirrusLogic5430ControllerDriverSupported
112 TODO: This - add argument and description to function comment
113 TODO: Controller - add argument and description to function comment
114 TODO: RemainingDevicePath - add argument and description to function comment
118 CirrusLogic5430ControllerDriverSupported (
119 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
120 IN EFI_HANDLE Controller
,
121 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
125 EFI_PCI_IO_PROTOCOL
*PciIo
;
129 // Open the PCI I/O Protocol
131 Status
= gBS
->OpenProtocol (
133 &gEfiPciIoProtocolGuid
,
135 This
->DriverBindingHandle
,
137 EFI_OPEN_PROTOCOL_BY_DRIVER
139 if (EFI_ERROR (Status
)) {
144 // Read the PCI Configuration Header from the PCI Device
146 Status
= PciIo
->Pci
.Read (
150 sizeof (Pci
) / sizeof (UINT32
),
153 if (EFI_ERROR (Status
)) {
157 Status
= EFI_UNSUPPORTED
;
159 // See if the I/O enable is on. Most systems only allow one VGA device to be turned on
160 // at a time, so see if this is one that is turned on.
162 // if (((Pci.Hdr.Command & 0x01) == 0x01)) {
164 // See if this is a Cirrus Logic PCI controller
166 if (Pci
.Hdr
.VendorId
== CIRRUS_LOGIC_VENDOR_ID
) {
168 // See if this is a 5430 or a 5446 PCI controller
170 if (Pci
.Hdr
.DeviceId
== CIRRUS_LOGIC_5430_DEVICE_ID
) {
171 Status
= EFI_SUCCESS
;
174 if (Pci
.Hdr
.DeviceId
== CIRRUS_LOGIC_5430_ALTERNATE_DEVICE_ID
) {
175 Status
= EFI_SUCCESS
;
178 if (Pci
.Hdr
.DeviceId
== CIRRUS_LOGIC_5446_DEVICE_ID
) {
179 Status
= EFI_SUCCESS
;
185 // Close the PCI I/O Protocol
189 &gEfiPciIoProtocolGuid
,
190 This
->DriverBindingHandle
,
198 CirrusLogic5430ControllerDriverStart
200 TODO: This - add argument and description to function comment
201 TODO: Controller - add argument and description to function comment
202 TODO: RemainingDevicePath - add argument and description to function comment
206 CirrusLogic5430ControllerDriverStart (
207 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
208 IN EFI_HANDLE Controller
,
209 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
213 CIRRUS_LOGIC_5430_PRIVATE_DATA
*Private
;
214 BOOLEAN PciAttributesSaved
;
216 PciAttributesSaved
= FALSE
;
218 // Allocate Private context data for UGA Draw inteface.
220 Private
= AllocateZeroPool (sizeof (CIRRUS_LOGIC_5430_PRIVATE_DATA
));
221 if (Private
== NULL
) {
222 Status
= EFI_OUT_OF_RESOURCES
;
227 // Set up context record
229 Private
->Signature
= CIRRUS_LOGIC_5430_PRIVATE_DATA_SIGNATURE
;
230 Private
->Handle
= Controller
;
233 // Open PCI I/O Protocol
235 Status
= gBS
->OpenProtocol (
237 &gEfiPciIoProtocolGuid
,
238 (VOID
**) &Private
->PciIo
,
239 This
->DriverBindingHandle
,
241 EFI_OPEN_PROTOCOL_BY_DRIVER
243 if (EFI_ERROR (Status
)) {
248 // Save original PCI attributes
250 Status
= Private
->PciIo
->Attributes (
252 EfiPciIoAttributeOperationGet
,
254 &Private
->OriginalPciAttributes
257 if (EFI_ERROR (Status
)) {
260 PciAttributesSaved
= TRUE
;
262 Status
= Private
->PciIo
->Attributes (
264 EfiPciIoAttributeOperationEnable
,
265 EFI_PCI_DEVICE_ENABLE
| EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY
| EFI_PCI_IO_ATTRIBUTE_VGA_IO
,
268 if (EFI_ERROR (Status
)) {
272 if (FeaturePcdGet (PcdSupportUga
)) {
274 // Start the UGA Draw software stack.
276 Status
= CirrusLogic5430UgaDrawConstructor (Private
);
277 ASSERT_EFI_ERROR (Status
);
278 if (FeaturePcdGet (PcdSupportGop
)) {
279 Status
= CirrusLogic5430GraphicsOutputConstructor (Private
);
280 ASSERT_EFI_ERROR (Status
);
282 Status
= gBS
->InstallMultipleProtocolInterfaces (
284 &gEfiUgaDrawProtocolGuid
,
286 &gEfiGraphicsOutputProtocolGuid
,
287 &Private
->GraphicsOutput
,
291 Status
= gBS
->InstallMultipleProtocolInterfaces (
293 &gEfiUgaDrawProtocolGuid
,
300 if (FeaturePcdGet (PcdSupportGop
)) {
301 Status
= CirrusLogic5430GraphicsOutputConstructor (Private
);
302 ASSERT_EFI_ERROR (Status
);
304 Status
= gBS
->InstallMultipleProtocolInterfaces (
306 &gEfiGraphicsOutputProtocolGuid
,
307 &Private
->GraphicsOutput
,
313 // This driver must support eithor GOP or UGA or both.
316 Status
= EFI_UNSUPPORTED
;
322 if (EFI_ERROR (Status
)) {
324 if (Private
->PciIo
) {
325 if (PciAttributesSaved
== TRUE
) {
327 // Restore original PCI attributes
329 Private
->PciIo
->Attributes (
331 EfiPciIoAttributeOperationSet
,
332 Private
->OriginalPciAttributes
,
337 // Close the PCI I/O Protocol
341 &gEfiPciIoProtocolGuid
,
342 This
->DriverBindingHandle
,
347 gBS
->FreePool (Private
);
355 CirrusLogic5430ControllerDriverStop
357 TODO: This - add argument and description to function comment
358 TODO: Controller - add argument and description to function comment
359 TODO: NumberOfChildren - add argument and description to function comment
360 TODO: ChildHandleBuffer - add argument and description to function comment
361 TODO: EFI_SUCCESS - add return value to function comment
365 CirrusLogic5430ControllerDriverStop (
366 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
367 IN EFI_HANDLE Controller
,
368 IN UINTN NumberOfChildren
,
369 IN EFI_HANDLE
*ChildHandleBuffer
372 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
373 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
376 CIRRUS_LOGIC_5430_PRIVATE_DATA
*Private
;
378 if (FeaturePcdGet (PcdSupportUga
)) {
379 Status
= gBS
->OpenProtocol (
381 &gEfiUgaDrawProtocolGuid
,
383 This
->DriverBindingHandle
,
385 EFI_OPEN_PROTOCOL_GET_PROTOCOL
387 if (EFI_ERROR (Status
)) {
391 // Get our private context information
393 Private
= CIRRUS_LOGIC_5430_PRIVATE_DATA_FROM_UGA_DRAW_THIS (UgaDraw
);
394 CirrusLogic5430UgaDrawDestructor (Private
);
396 if (FeaturePcdGet (PcdSupportGop
)) {
397 CirrusLogic5430GraphicsOutputDestructor (Private
);
399 // Remove the UGA and GOP protocol interface from the system
401 Status
= gBS
->UninstallMultipleProtocolInterfaces (
403 &gEfiUgaDrawProtocolGuid
,
405 &gEfiGraphicsOutputProtocolGuid
,
406 &Private
->GraphicsOutput
,
411 // Remove the UGA Draw interface from the system
413 Status
= gBS
->UninstallMultipleProtocolInterfaces (
415 &gEfiUgaDrawProtocolGuid
,
421 Status
= gBS
->OpenProtocol (
423 &gEfiGraphicsOutputProtocolGuid
,
424 (VOID
**) &GraphicsOutput
,
425 This
->DriverBindingHandle
,
427 EFI_OPEN_PROTOCOL_GET_PROTOCOL
429 if (EFI_ERROR (Status
)) {
434 // Get our private context information
436 Private
= CIRRUS_LOGIC_5430_PRIVATE_DATA_FROM_GRAPHICS_OUTPUT_THIS (GraphicsOutput
);
438 CirrusLogic5430GraphicsOutputDestructor (Private
);
440 // Remove the GOP protocol interface from the system
442 Status
= gBS
->UninstallMultipleProtocolInterfaces (
444 &gEfiUgaDrawProtocolGuid
,
446 &gEfiGraphicsOutputProtocolGuid
,
447 &Private
->GraphicsOutput
,
452 if (EFI_ERROR (Status
)) {
457 // Restore original PCI attributes
459 Private
->PciIo
->Attributes (
461 EfiPciIoAttributeOperationSet
,
462 Private
->OriginalPciAttributes
,
467 // Close the PCI I/O Protocol
471 &gEfiPciIoProtocolGuid
,
472 This
->DriverBindingHandle
,
477 // Free our instance data
479 gBS
->FreePool (Private
);
485 CirrusLogic5430UgaDrawDestructor
487 TODO: Private - add argument and description to function comment
488 TODO: EFI_SUCCESS - add return value to function comment
491 CirrusLogic5430UgaDrawDestructor (
492 CIRRUS_LOGIC_5430_PRIVATE_DATA
*Private
499 TODO: Add function description
501 @param Private TODO: add argument description
502 @param Address TODO: add argument description
503 @param Data TODO: add argument description
505 TODO: add return values
510 CIRRUS_LOGIC_5430_PRIVATE_DATA
*Private
,
515 Private
->PciIo
->Io
.Write (
518 EFI_PCI_IO_PASS_THROUGH_BAR
,
526 TODO: Add function description
528 @param Private TODO: add argument description
529 @param Address TODO: add argument description
530 @param Data TODO: add argument description
532 TODO: add return values
537 CIRRUS_LOGIC_5430_PRIVATE_DATA
*Private
,
542 Private
->PciIo
->Io
.Write (
545 EFI_PCI_IO_PASS_THROUGH_BAR
,
553 TODO: Add function description
555 @param Private TODO: add argument description
556 @param Address TODO: add argument description
558 TODO: add return values
563 CIRRUS_LOGIC_5430_PRIVATE_DATA
*Private
,
569 Private
->PciIo
->Io
.Read (
572 EFI_PCI_IO_PASS_THROUGH_BAR
,
581 TODO: Add function description
583 @param Private TODO: add argument description
584 @param Address TODO: add argument description
586 TODO: add return values
591 CIRRUS_LOGIC_5430_PRIVATE_DATA
*Private
,
597 Private
->PciIo
->Io
.Read (
600 EFI_PCI_IO_PASS_THROUGH_BAR
,
609 TODO: Add function description
611 @param Private TODO: add argument description
612 @param Index TODO: add argument description
613 @param Red TODO: add argument description
614 @param Green TODO: add argument description
615 @param Blue TODO: add argument description
617 TODO: add return values
622 CIRRUS_LOGIC_5430_PRIVATE_DATA
*Private
,
629 outb (Private
, PALETTE_INDEX_REGISTER
, (UINT8
) Index
);
630 outb (Private
, PALETTE_DATA_REGISTER
, (UINT8
) (Red
>> 2));
631 outb (Private
, PALETTE_DATA_REGISTER
, (UINT8
) (Green
>> 2));
632 outb (Private
, PALETTE_DATA_REGISTER
, (UINT8
) (Blue
>> 2));
636 TODO: Add function description
638 @param Private TODO: add argument description
640 TODO: add return values
645 CIRRUS_LOGIC_5430_PRIVATE_DATA
*Private
654 for (RedIndex
= 0; RedIndex
< 8; RedIndex
++) {
655 for (GreenIndex
= 0; GreenIndex
< 8; GreenIndex
++) {
656 for (BlueIndex
= 0; BlueIndex
< 4; BlueIndex
++) {
657 SetPaletteColor (Private
, Index
, (UINT8
) (RedIndex
<< 5), (UINT8
) (GreenIndex
<< 5), (UINT8
) (BlueIndex
<< 6));
665 TODO: Add function description
667 @param Private TODO: add argument description
669 TODO: add return values
675 CIRRUS_LOGIC_5430_PRIVATE_DATA
*Private
681 Private
->PciIo
->Mem
.Write (
683 EfiPciIoWidthFillUint32
,
692 TODO: Add function description
694 @param Private TODO: add argument description
696 TODO: add return values
701 CIRRUS_LOGIC_5430_PRIVATE_DATA
*Private
,
712 for (Y
= 0; Y
< ScreenHeight
; Y
++) {
713 for (X
= 0; X
< ScreenWidth
; X
++) {
714 Color
= (UINT8
) (256 * (X
+ Y
) / (ScreenWidth
+ ScreenHeight
));
715 Private
->LineBuffer
[X
] = Color
;
718 Private
->PciIo
->Mem
.Write (
722 Offset
+ (Y
* ScreenWidth
),
730 TODO: Add function description
732 @param Private TODO: add argument description
733 @param ModeData TODO: add argument description
735 TODO: add return values
739 InitializeGraphicsMode (
740 CIRRUS_LOGIC_5430_PRIVATE_DATA
*Private
,
741 CIRRUS_LOGIC_5430_VIDEO_MODES
*ModeData
747 outw (Private
, SEQ_ADDRESS_REGISTER
, 0x1206);
748 outw (Private
, SEQ_ADDRESS_REGISTER
, 0x0012);
750 for (Index
= 0; Index
< 15; Index
++) {
751 outw (Private
, SEQ_ADDRESS_REGISTER
, ModeData
->SeqSettings
[Index
]);
754 outb (Private
, SEQ_ADDRESS_REGISTER
, 0x0f);
755 Byte
= (UINT8
) ((inb (Private
, SEQ_DATA_REGISTER
) & 0xc7) ^ 0x30);
756 outb (Private
, SEQ_DATA_REGISTER
, Byte
);
758 outb (Private
, MISC_OUTPUT_REGISTER
, ModeData
->MiscSetting
);
759 outw (Private
, GRAPH_ADDRESS_REGISTER
, 0x0506);
760 outw (Private
, SEQ_ADDRESS_REGISTER
, 0x0300);
761 outw (Private
, CRTC_ADDRESS_REGISTER
, 0x2011);
763 for (Index
= 0; Index
< 28; Index
++) {
764 outw (Private
, CRTC_ADDRESS_REGISTER
, (UINT16
) ((ModeData
->CrtcSettings
[Index
] << 8) | Index
));
767 for (Index
= 0; Index
< 9; Index
++) {
768 outw (Private
, GRAPH_ADDRESS_REGISTER
, (UINT16
) ((GraphicsController
[Index
] << 8) | Index
));
771 inb (Private
, INPUT_STATUS_1_REGISTER
);
773 for (Index
= 0; Index
< 21; Index
++) {
774 outb (Private
, ATT_ADDRESS_REGISTER
, (UINT8
) Index
);
775 outb (Private
, ATT_ADDRESS_REGISTER
, AttributeController
[Index
]);
778 outb (Private
, ATT_ADDRESS_REGISTER
, 0x20);
780 outw (Private
, GRAPH_ADDRESS_REGISTER
, 0x0009);
781 outw (Private
, GRAPH_ADDRESS_REGISTER
, 0x000a);
782 outw (Private
, GRAPH_ADDRESS_REGISTER
, 0x000b);
783 outb (Private
, DAC_PIXEL_MASK_REGISTER
, 0xff);
785 SetDefaultPalette (Private
);
786 ClearScreen (Private
);
791 InitializeCirrusLogic5430 (
792 IN EFI_HANDLE ImageHandle
,
793 IN EFI_SYSTEM_TABLE
*SystemTable
798 Status
= EfiLibInstallDriverBindingComponentName2 (
801 &gCirrusLogic5430DriverBinding
,
803 &gCirrusLogic5430ComponentName
,
804 &gCirrusLogic5430ComponentName2
806 ASSERT_EFI_ERROR (Status
);
809 // Install EFI Driver Supported EFI Version Protocol required for
810 // EFI drivers that are on PCI and other plug in cards.
812 gCirrusLogic5430DriverSupportedEfiVersion
.FirmwareVersion
= PcdGet32 (PcdDriverSupportedEfiVersion
);
813 Status
= gBS
->InstallMultipleProtocolInterfaces (
815 &gEfiDriverSupportedEfiVersionProtocolGuid
,
816 &gCirrusLogic5430DriverSupportedEfiVersion
,
819 ASSERT_EFI_ERROR (Status
);