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
;
216 // Allocate Private context data for UGA Draw inteface.
218 Private
= AllocateZeroPool (sizeof (CIRRUS_LOGIC_5430_PRIVATE_DATA
));
219 if (Private
== NULL
) {
220 Status
= EFI_OUT_OF_RESOURCES
;
225 // Set up context record
227 Private
->Signature
= CIRRUS_LOGIC_5430_PRIVATE_DATA_SIGNATURE
;
228 Private
->Handle
= Controller
;
231 // Open PCI I/O Protocol
233 Status
= gBS
->OpenProtocol (
235 &gEfiPciIoProtocolGuid
,
236 (VOID
**) &Private
->PciIo
,
237 This
->DriverBindingHandle
,
239 EFI_OPEN_PROTOCOL_BY_DRIVER
241 if (EFI_ERROR (Status
)) {
245 Status
= Private
->PciIo
->Attributes (
247 EfiPciIoAttributeOperationEnable
,
248 EFI_PCI_DEVICE_ENABLE
| EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY
| EFI_PCI_IO_ATTRIBUTE_VGA_IO
,
251 if (EFI_ERROR (Status
)) {
255 if (FeaturePcdGet (PcdSupportUga
)) {
257 // Start the UGA Draw software stack.
259 Status
= CirrusLogic5430UgaDrawConstructor (Private
);
260 ASSERT_EFI_ERROR (Status
);
261 if (FeaturePcdGet (PcdSupportGop
)) {
262 Status
= CirrusLogic5430GraphicsOutputConstructor (Private
);
263 ASSERT_EFI_ERROR (Status
);
265 Status
= gBS
->InstallMultipleProtocolInterfaces (
267 &gEfiUgaDrawProtocolGuid
,
269 &gEfiGraphicsOutputProtocolGuid
,
270 &Private
->GraphicsOutput
,
274 Status
= gBS
->InstallMultipleProtocolInterfaces (
276 &gEfiUgaDrawProtocolGuid
,
283 if (FeaturePcdGet (PcdSupportGop
)) {
284 Status
= CirrusLogic5430GraphicsOutputConstructor (Private
);
285 ASSERT_EFI_ERROR (Status
);
287 Status
= gBS
->InstallMultipleProtocolInterfaces (
289 &gEfiGraphicsOutputProtocolGuid
,
290 &Private
->GraphicsOutput
,
296 // This driver must support eithor GOP or UGA or both.
299 Status
= EFI_UNSUPPORTED
;
305 if (EFI_ERROR (Status
)) {
307 if (Private
->PciIo
) {
308 Private
->PciIo
->Attributes (
310 EfiPciIoAttributeOperationDisable
,
311 EFI_PCI_DEVICE_ENABLE
| EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY
| EFI_PCI_IO_ATTRIBUTE_VGA_IO
,
318 // Close the PCI I/O Protocol
322 &gEfiPciIoProtocolGuid
,
323 This
->DriverBindingHandle
,
327 gBS
->FreePool (Private
);
335 CirrusLogic5430ControllerDriverStop
337 TODO: This - add argument and description to function comment
338 TODO: Controller - add argument and description to function comment
339 TODO: NumberOfChildren - add argument and description to function comment
340 TODO: ChildHandleBuffer - add argument and description to function comment
341 TODO: EFI_SUCCESS - add return value to function comment
345 CirrusLogic5430ControllerDriverStop (
346 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
347 IN EFI_HANDLE Controller
,
348 IN UINTN NumberOfChildren
,
349 IN EFI_HANDLE
*ChildHandleBuffer
352 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
353 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
356 CIRRUS_LOGIC_5430_PRIVATE_DATA
*Private
;
358 if (FeaturePcdGet (PcdSupportUga
)) {
359 Status
= gBS
->OpenProtocol (
361 &gEfiUgaDrawProtocolGuid
,
363 This
->DriverBindingHandle
,
365 EFI_OPEN_PROTOCOL_GET_PROTOCOL
367 if (EFI_ERROR (Status
)) {
371 // Get our private context information
373 Private
= CIRRUS_LOGIC_5430_PRIVATE_DATA_FROM_UGA_DRAW_THIS (UgaDraw
);
374 CirrusLogic5430UgaDrawDestructor (Private
);
376 if (FeaturePcdGet (PcdSupportGop
)) {
377 CirrusLogic5430GraphicsOutputDestructor (Private
);
379 // Remove the UGA and GOP protocol interface from the system
381 Status
= gBS
->UninstallMultipleProtocolInterfaces (
383 &gEfiUgaDrawProtocolGuid
,
385 &gEfiGraphicsOutputProtocolGuid
,
386 &Private
->GraphicsOutput
,
391 // Remove the UGA Draw interface from the system
393 Status
= gBS
->UninstallMultipleProtocolInterfaces (
395 &gEfiUgaDrawProtocolGuid
,
401 Status
= gBS
->OpenProtocol (
403 &gEfiGraphicsOutputProtocolGuid
,
404 (VOID
**) &GraphicsOutput
,
405 This
->DriverBindingHandle
,
407 EFI_OPEN_PROTOCOL_GET_PROTOCOL
409 if (EFI_ERROR (Status
)) {
414 // Get our private context information
416 Private
= CIRRUS_LOGIC_5430_PRIVATE_DATA_FROM_GRAPHICS_OUTPUT_THIS (GraphicsOutput
);
418 CirrusLogic5430GraphicsOutputDestructor (Private
);
420 // Remove the GOP protocol interface from the system
422 Status
= gBS
->UninstallMultipleProtocolInterfaces (
424 &gEfiUgaDrawProtocolGuid
,
426 &gEfiGraphicsOutputProtocolGuid
,
427 &Private
->GraphicsOutput
,
432 if (EFI_ERROR (Status
)) {
438 // Shutdown the hardware
440 Private
->PciIo
->Attributes (
442 EfiPciIoAttributeOperationDisable
,
443 EFI_PCI_DEVICE_ENABLE
| EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY
| EFI_PCI_IO_ATTRIBUTE_VGA_IO
,
448 // Close the PCI I/O Protocol
452 &gEfiPciIoProtocolGuid
,
453 This
->DriverBindingHandle
,
458 // Free our instance data
460 gBS
->FreePool (Private
);
466 CirrusLogic5430UgaDrawDestructor
468 TODO: Private - add argument and description to function comment
469 TODO: EFI_SUCCESS - add return value to function comment
472 CirrusLogic5430UgaDrawDestructor (
473 CIRRUS_LOGIC_5430_PRIVATE_DATA
*Private
480 TODO: Add function description
482 @param Private TODO: add argument description
483 @param Address TODO: add argument description
484 @param Data TODO: add argument description
486 TODO: add return values
491 CIRRUS_LOGIC_5430_PRIVATE_DATA
*Private
,
496 Private
->PciIo
->Io
.Write (
499 EFI_PCI_IO_PASS_THROUGH_BAR
,
507 TODO: Add function description
509 @param Private TODO: add argument description
510 @param Address TODO: add argument description
511 @param Data TODO: add argument description
513 TODO: add return values
518 CIRRUS_LOGIC_5430_PRIVATE_DATA
*Private
,
523 Private
->PciIo
->Io
.Write (
526 EFI_PCI_IO_PASS_THROUGH_BAR
,
534 TODO: Add function description
536 @param Private TODO: add argument description
537 @param Address TODO: add argument description
539 TODO: add return values
544 CIRRUS_LOGIC_5430_PRIVATE_DATA
*Private
,
550 Private
->PciIo
->Io
.Read (
553 EFI_PCI_IO_PASS_THROUGH_BAR
,
562 TODO: Add function description
564 @param Private TODO: add argument description
565 @param Address TODO: add argument description
567 TODO: add return values
572 CIRRUS_LOGIC_5430_PRIVATE_DATA
*Private
,
578 Private
->PciIo
->Io
.Read (
581 EFI_PCI_IO_PASS_THROUGH_BAR
,
590 TODO: Add function description
592 @param Private TODO: add argument description
593 @param Index TODO: add argument description
594 @param Red TODO: add argument description
595 @param Green TODO: add argument description
596 @param Blue TODO: add argument description
598 TODO: add return values
603 CIRRUS_LOGIC_5430_PRIVATE_DATA
*Private
,
610 outb (Private
, PALETTE_INDEX_REGISTER
, (UINT8
) Index
);
611 outb (Private
, PALETTE_DATA_REGISTER
, (UINT8
) (Red
>> 2));
612 outb (Private
, PALETTE_DATA_REGISTER
, (UINT8
) (Green
>> 2));
613 outb (Private
, PALETTE_DATA_REGISTER
, (UINT8
) (Blue
>> 2));
617 TODO: Add function description
619 @param Private TODO: add argument description
621 TODO: add return values
626 CIRRUS_LOGIC_5430_PRIVATE_DATA
*Private
635 for (RedIndex
= 0; RedIndex
< 8; RedIndex
++) {
636 for (GreenIndex
= 0; GreenIndex
< 8; GreenIndex
++) {
637 for (BlueIndex
= 0; BlueIndex
< 4; BlueIndex
++) {
638 SetPaletteColor (Private
, Index
, (UINT8
) (RedIndex
<< 5), (UINT8
) (GreenIndex
<< 5), (UINT8
) (BlueIndex
<< 6));
646 TODO: Add function description
648 @param Private TODO: add argument description
650 TODO: add return values
656 CIRRUS_LOGIC_5430_PRIVATE_DATA
*Private
662 Private
->PciIo
->Mem
.Write (
664 EfiPciIoWidthFillUint32
,
673 TODO: Add function description
675 @param Private TODO: add argument description
677 TODO: add return values
682 CIRRUS_LOGIC_5430_PRIVATE_DATA
*Private
,
693 for (Y
= 0; Y
< ScreenHeight
; Y
++) {
694 for (X
= 0; X
< ScreenWidth
; X
++) {
695 Color
= (UINT8
) (256 * (X
+ Y
) / (ScreenWidth
+ ScreenHeight
));
696 Private
->LineBuffer
[X
] = Color
;
699 Private
->PciIo
->Mem
.Write (
703 Offset
+ (Y
* ScreenWidth
),
711 TODO: Add function description
713 @param Private TODO: add argument description
714 @param ModeData TODO: add argument description
716 TODO: add return values
720 InitializeGraphicsMode (
721 CIRRUS_LOGIC_5430_PRIVATE_DATA
*Private
,
722 CIRRUS_LOGIC_5430_VIDEO_MODES
*ModeData
728 outw (Private
, SEQ_ADDRESS_REGISTER
, 0x1206);
729 outw (Private
, SEQ_ADDRESS_REGISTER
, 0x0012);
731 for (Index
= 0; Index
< 15; Index
++) {
732 outw (Private
, SEQ_ADDRESS_REGISTER
, ModeData
->SeqSettings
[Index
]);
735 outb (Private
, SEQ_ADDRESS_REGISTER
, 0x0f);
736 Byte
= (UINT8
) ((inb (Private
, SEQ_DATA_REGISTER
) & 0xc7) ^ 0x30);
737 outb (Private
, SEQ_DATA_REGISTER
, Byte
);
739 outb (Private
, MISC_OUTPUT_REGISTER
, ModeData
->MiscSetting
);
740 outw (Private
, GRAPH_ADDRESS_REGISTER
, 0x0506);
741 outw (Private
, SEQ_ADDRESS_REGISTER
, 0x0300);
742 outw (Private
, CRTC_ADDRESS_REGISTER
, 0x2011);
744 for (Index
= 0; Index
< 28; Index
++) {
745 outw (Private
, CRTC_ADDRESS_REGISTER
, (UINT16
) ((ModeData
->CrtcSettings
[Index
] << 8) | Index
));
748 for (Index
= 0; Index
< 9; Index
++) {
749 outw (Private
, GRAPH_ADDRESS_REGISTER
, (UINT16
) ((GraphicsController
[Index
] << 8) | Index
));
752 inb (Private
, INPUT_STATUS_1_REGISTER
);
754 for (Index
= 0; Index
< 21; Index
++) {
755 outb (Private
, ATT_ADDRESS_REGISTER
, (UINT8
) Index
);
756 outb (Private
, ATT_ADDRESS_REGISTER
, AttributeController
[Index
]);
759 outb (Private
, ATT_ADDRESS_REGISTER
, 0x20);
761 outw (Private
, GRAPH_ADDRESS_REGISTER
, 0x0009);
762 outw (Private
, GRAPH_ADDRESS_REGISTER
, 0x000a);
763 outw (Private
, GRAPH_ADDRESS_REGISTER
, 0x000b);
764 outb (Private
, DAC_PIXEL_MASK_REGISTER
, 0xff);
766 SetDefaultPalette (Private
);
767 ClearScreen (Private
);
772 InitializeCirrusLogic5430 (
773 IN EFI_HANDLE ImageHandle
,
774 IN EFI_SYSTEM_TABLE
*SystemTable
779 Status
= EfiLibInstallDriverBindingComponentName2 (
782 &gCirrusLogic5430DriverBinding
,
784 &gCirrusLogic5430ComponentName
,
785 &gCirrusLogic5430ComponentName2
787 ASSERT_EFI_ERROR (Status
);
790 // Install EFI Driver Supported EFI Version Protocol required for
791 // EFI drivers that are on PCI and other plug in cards.
793 gCirrusLogic5430DriverSupportedEfiVersion
.FirmwareVersion
= PcdGet32 (PcdDriverSupportedEfiVersion
);
794 Status
= gBS
->InstallMultipleProtocolInterfaces (
796 &gEfiDriverSupportedEfiVersionProtocolGuid
,
797 &gCirrusLogic5430DriverSupportedEfiVersion
,
800 ASSERT_EFI_ERROR (Status
);