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
)) {
246 // Save original PCI attributes
248 Status
= Private
->PciIo
->Attributes (
250 EfiPciIoAttributeOperationGet
,
252 &Private
->OriginalPciAttributes
255 if (EFI_ERROR (Status
)) {
259 Status
= Private
->PciIo
->Attributes (
261 EfiPciIoAttributeOperationEnable
,
262 EFI_PCI_DEVICE_ENABLE
| EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY
| EFI_PCI_IO_ATTRIBUTE_VGA_IO
,
265 if (EFI_ERROR (Status
)) {
269 if (FeaturePcdGet (PcdSupportUga
)) {
271 // Start the UGA Draw software stack.
273 Status
= CirrusLogic5430UgaDrawConstructor (Private
);
274 ASSERT_EFI_ERROR (Status
);
275 if (FeaturePcdGet (PcdSupportGop
)) {
276 Status
= CirrusLogic5430GraphicsOutputConstructor (Private
);
277 ASSERT_EFI_ERROR (Status
);
279 Status
= gBS
->InstallMultipleProtocolInterfaces (
281 &gEfiUgaDrawProtocolGuid
,
283 &gEfiGraphicsOutputProtocolGuid
,
284 &Private
->GraphicsOutput
,
288 Status
= gBS
->InstallMultipleProtocolInterfaces (
290 &gEfiUgaDrawProtocolGuid
,
297 if (FeaturePcdGet (PcdSupportGop
)) {
298 Status
= CirrusLogic5430GraphicsOutputConstructor (Private
);
299 ASSERT_EFI_ERROR (Status
);
301 Status
= gBS
->InstallMultipleProtocolInterfaces (
303 &gEfiGraphicsOutputProtocolGuid
,
304 &Private
->GraphicsOutput
,
310 // This driver must support eithor GOP or UGA or both.
313 Status
= EFI_UNSUPPORTED
;
319 if (EFI_ERROR (Status
)) {
321 if (Private
->PciIo
) {
323 // Restore original PCI attributes
325 Private
->PciIo
->Attributes (
327 EfiPciIoAttributeOperationSet
,
328 Private
->OriginalPciAttributes
,
333 // Close the PCI I/O Protocol
337 &gEfiPciIoProtocolGuid
,
338 This
->DriverBindingHandle
,
343 gBS
->FreePool (Private
);
351 CirrusLogic5430ControllerDriverStop
353 TODO: This - add argument and description to function comment
354 TODO: Controller - add argument and description to function comment
355 TODO: NumberOfChildren - add argument and description to function comment
356 TODO: ChildHandleBuffer - add argument and description to function comment
357 TODO: EFI_SUCCESS - add return value to function comment
361 CirrusLogic5430ControllerDriverStop (
362 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
363 IN EFI_HANDLE Controller
,
364 IN UINTN NumberOfChildren
,
365 IN EFI_HANDLE
*ChildHandleBuffer
368 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
369 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
372 CIRRUS_LOGIC_5430_PRIVATE_DATA
*Private
;
374 if (FeaturePcdGet (PcdSupportUga
)) {
375 Status
= gBS
->OpenProtocol (
377 &gEfiUgaDrawProtocolGuid
,
379 This
->DriverBindingHandle
,
381 EFI_OPEN_PROTOCOL_GET_PROTOCOL
383 if (EFI_ERROR (Status
)) {
387 // Get our private context information
389 Private
= CIRRUS_LOGIC_5430_PRIVATE_DATA_FROM_UGA_DRAW_THIS (UgaDraw
);
390 CirrusLogic5430UgaDrawDestructor (Private
);
392 if (FeaturePcdGet (PcdSupportGop
)) {
393 CirrusLogic5430GraphicsOutputDestructor (Private
);
395 // Remove the UGA and GOP protocol interface from the system
397 Status
= gBS
->UninstallMultipleProtocolInterfaces (
399 &gEfiUgaDrawProtocolGuid
,
401 &gEfiGraphicsOutputProtocolGuid
,
402 &Private
->GraphicsOutput
,
407 // Remove the UGA Draw interface from the system
409 Status
= gBS
->UninstallMultipleProtocolInterfaces (
411 &gEfiUgaDrawProtocolGuid
,
417 Status
= gBS
->OpenProtocol (
419 &gEfiGraphicsOutputProtocolGuid
,
420 (VOID
**) &GraphicsOutput
,
421 This
->DriverBindingHandle
,
423 EFI_OPEN_PROTOCOL_GET_PROTOCOL
425 if (EFI_ERROR (Status
)) {
430 // Get our private context information
432 Private
= CIRRUS_LOGIC_5430_PRIVATE_DATA_FROM_GRAPHICS_OUTPUT_THIS (GraphicsOutput
);
434 CirrusLogic5430GraphicsOutputDestructor (Private
);
436 // Remove the GOP protocol interface from the system
438 Status
= gBS
->UninstallMultipleProtocolInterfaces (
440 &gEfiUgaDrawProtocolGuid
,
442 &gEfiGraphicsOutputProtocolGuid
,
443 &Private
->GraphicsOutput
,
448 if (EFI_ERROR (Status
)) {
453 // Restore original PCI attributes
455 Private
->PciIo
->Attributes (
457 EfiPciIoAttributeOperationSet
,
458 Private
->OriginalPciAttributes
,
463 // Close the PCI I/O Protocol
467 &gEfiPciIoProtocolGuid
,
468 This
->DriverBindingHandle
,
473 // Free our instance data
475 gBS
->FreePool (Private
);
481 CirrusLogic5430UgaDrawDestructor
483 TODO: Private - add argument and description to function comment
484 TODO: EFI_SUCCESS - add return value to function comment
487 CirrusLogic5430UgaDrawDestructor (
488 CIRRUS_LOGIC_5430_PRIVATE_DATA
*Private
495 TODO: Add function description
497 @param Private TODO: add argument description
498 @param Address TODO: add argument description
499 @param Data TODO: add argument description
501 TODO: add return values
506 CIRRUS_LOGIC_5430_PRIVATE_DATA
*Private
,
511 Private
->PciIo
->Io
.Write (
514 EFI_PCI_IO_PASS_THROUGH_BAR
,
522 TODO: Add function description
524 @param Private TODO: add argument description
525 @param Address TODO: add argument description
526 @param Data TODO: add argument description
528 TODO: add return values
533 CIRRUS_LOGIC_5430_PRIVATE_DATA
*Private
,
538 Private
->PciIo
->Io
.Write (
541 EFI_PCI_IO_PASS_THROUGH_BAR
,
549 TODO: Add function description
551 @param Private TODO: add argument description
552 @param Address TODO: add argument description
554 TODO: add return values
559 CIRRUS_LOGIC_5430_PRIVATE_DATA
*Private
,
565 Private
->PciIo
->Io
.Read (
568 EFI_PCI_IO_PASS_THROUGH_BAR
,
577 TODO: Add function description
579 @param Private TODO: add argument description
580 @param Address TODO: add argument description
582 TODO: add return values
587 CIRRUS_LOGIC_5430_PRIVATE_DATA
*Private
,
593 Private
->PciIo
->Io
.Read (
596 EFI_PCI_IO_PASS_THROUGH_BAR
,
605 TODO: Add function description
607 @param Private TODO: add argument description
608 @param Index TODO: add argument description
609 @param Red TODO: add argument description
610 @param Green TODO: add argument description
611 @param Blue TODO: add argument description
613 TODO: add return values
618 CIRRUS_LOGIC_5430_PRIVATE_DATA
*Private
,
625 outb (Private
, PALETTE_INDEX_REGISTER
, (UINT8
) Index
);
626 outb (Private
, PALETTE_DATA_REGISTER
, (UINT8
) (Red
>> 2));
627 outb (Private
, PALETTE_DATA_REGISTER
, (UINT8
) (Green
>> 2));
628 outb (Private
, PALETTE_DATA_REGISTER
, (UINT8
) (Blue
>> 2));
632 TODO: Add function description
634 @param Private TODO: add argument description
636 TODO: add return values
641 CIRRUS_LOGIC_5430_PRIVATE_DATA
*Private
650 for (RedIndex
= 0; RedIndex
< 8; RedIndex
++) {
651 for (GreenIndex
= 0; GreenIndex
< 8; GreenIndex
++) {
652 for (BlueIndex
= 0; BlueIndex
< 4; BlueIndex
++) {
653 SetPaletteColor (Private
, Index
, (UINT8
) (RedIndex
<< 5), (UINT8
) (GreenIndex
<< 5), (UINT8
) (BlueIndex
<< 6));
661 TODO: Add function description
663 @param Private TODO: add argument description
665 TODO: add return values
671 CIRRUS_LOGIC_5430_PRIVATE_DATA
*Private
677 Private
->PciIo
->Mem
.Write (
679 EfiPciIoWidthFillUint32
,
688 TODO: Add function description
690 @param Private TODO: add argument description
692 TODO: add return values
697 CIRRUS_LOGIC_5430_PRIVATE_DATA
*Private
,
708 for (Y
= 0; Y
< ScreenHeight
; Y
++) {
709 for (X
= 0; X
< ScreenWidth
; X
++) {
710 Color
= (UINT8
) (256 * (X
+ Y
) / (ScreenWidth
+ ScreenHeight
));
711 Private
->LineBuffer
[X
] = Color
;
714 Private
->PciIo
->Mem
.Write (
718 Offset
+ (Y
* ScreenWidth
),
726 TODO: Add function description
728 @param Private TODO: add argument description
729 @param ModeData TODO: add argument description
731 TODO: add return values
735 InitializeGraphicsMode (
736 CIRRUS_LOGIC_5430_PRIVATE_DATA
*Private
,
737 CIRRUS_LOGIC_5430_VIDEO_MODES
*ModeData
743 outw (Private
, SEQ_ADDRESS_REGISTER
, 0x1206);
744 outw (Private
, SEQ_ADDRESS_REGISTER
, 0x0012);
746 for (Index
= 0; Index
< 15; Index
++) {
747 outw (Private
, SEQ_ADDRESS_REGISTER
, ModeData
->SeqSettings
[Index
]);
750 outb (Private
, SEQ_ADDRESS_REGISTER
, 0x0f);
751 Byte
= (UINT8
) ((inb (Private
, SEQ_DATA_REGISTER
) & 0xc7) ^ 0x30);
752 outb (Private
, SEQ_DATA_REGISTER
, Byte
);
754 outb (Private
, MISC_OUTPUT_REGISTER
, ModeData
->MiscSetting
);
755 outw (Private
, GRAPH_ADDRESS_REGISTER
, 0x0506);
756 outw (Private
, SEQ_ADDRESS_REGISTER
, 0x0300);
757 outw (Private
, CRTC_ADDRESS_REGISTER
, 0x2011);
759 for (Index
= 0; Index
< 28; Index
++) {
760 outw (Private
, CRTC_ADDRESS_REGISTER
, (UINT16
) ((ModeData
->CrtcSettings
[Index
] << 8) | Index
));
763 for (Index
= 0; Index
< 9; Index
++) {
764 outw (Private
, GRAPH_ADDRESS_REGISTER
, (UINT16
) ((GraphicsController
[Index
] << 8) | Index
));
767 inb (Private
, INPUT_STATUS_1_REGISTER
);
769 for (Index
= 0; Index
< 21; Index
++) {
770 outb (Private
, ATT_ADDRESS_REGISTER
, (UINT8
) Index
);
771 outb (Private
, ATT_ADDRESS_REGISTER
, AttributeController
[Index
]);
774 outb (Private
, ATT_ADDRESS_REGISTER
, 0x20);
776 outw (Private
, GRAPH_ADDRESS_REGISTER
, 0x0009);
777 outw (Private
, GRAPH_ADDRESS_REGISTER
, 0x000a);
778 outw (Private
, GRAPH_ADDRESS_REGISTER
, 0x000b);
779 outb (Private
, DAC_PIXEL_MASK_REGISTER
, 0xff);
781 SetDefaultPalette (Private
);
782 ClearScreen (Private
);
787 InitializeCirrusLogic5430 (
788 IN EFI_HANDLE ImageHandle
,
789 IN EFI_SYSTEM_TABLE
*SystemTable
794 Status
= EfiLibInstallDriverBindingComponentName2 (
797 &gCirrusLogic5430DriverBinding
,
799 &gCirrusLogic5430ComponentName
,
800 &gCirrusLogic5430ComponentName2
802 ASSERT_EFI_ERROR (Status
);
805 // Install EFI Driver Supported EFI Version Protocol required for
806 // EFI drivers that are on PCI and other plug in cards.
808 gCirrusLogic5430DriverSupportedEfiVersion
.FirmwareVersion
= PcdGet32 (PcdDriverSupportedEfiVersion
);
809 Status
= gBS
->InstallMultipleProtocolInterfaces (
811 &gEfiDriverSupportedEfiVersionProtocolGuid
,
812 &gCirrusLogic5430DriverSupportedEfiVersion
,
815 ASSERT_EFI_ERROR (Status
);