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