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