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