]> git.proxmox.com Git - mirror_edk2.git/blob - EdkModulePkg/Bus/Pci/CirrusLogic/Dxe/CirrusLogic5430UgaDraw.c
Update comments to conform to the new, Doxygen friendly, coding standard. These...
[mirror_edk2.git] / EdkModulePkg / Bus / Pci / CirrusLogic / Dxe / CirrusLogic5430UgaDraw.c
1 /** @file
2 This file produces the graphics abstration of UGA Draw. It is called by
3 CirrusLogic5430.c file which deals with the EFI 1.1 driver model.
4 This file just does graphics.
5
6 Copyright (c) 2006, Intel Corporation
7 All rights reserved. This program and the accompanying materials
8 are licensed and made available under the terms and conditions of the BSD License
9 which accompanies this distribution. The full text of the license may be found at
10 http://opensource.org/licenses/bsd-license.php
11
12 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
13 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
14
15 **/
16
17 #include "CirrusLogic5430.h"
18
19 ///
20 /// Video Mode structure
21 ///
22 typedef struct {
23 UINT32 Width;
24 UINT32 Height;
25 UINT32 ColorDepth;
26 UINT32 RefreshRate;
27 UINT8 *CrtcSettings;
28 UINT16 *SeqSettings;
29 UINT8 MiscSetting;
30 } CIRRUS_LOGIC_5430_VIDEO_MODES;
31
32 ///
33 /// Generic Attribute Controller Register Settings
34 ///
35 static UINT8 AttributeController[21] = {
36 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
37 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
38 0x41, 0x00, 0x0F, 0x00, 0x00
39 };
40
41 ///
42 /// Generic Graphics Controller Register Settings
43 ///
44 static UINT8 GraphicsController[9] = {
45 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, 0xFF
46 };
47
48 //
49 // 640 x 480 x 256 color @ 60 Hertz
50 //
51 static UINT8 Crtc_640_480_256_60[28] = {
52 0x5d, 0x4f, 0x50, 0x82, 0x53, 0x9f, 0x00, 0x3e,
53 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
54 0xe1, 0x83, 0xdf, 0x50, 0x00, 0xe7, 0x04, 0xe3,
55 0xff, 0x00, 0x00, 0x22
56 };
57
58 static UINT16 Seq_640_480_256_60[15] = {
59 0x0100, 0x0101, 0x0f02, 0x0003, 0x0e04, 0x1107, 0x0008, 0x4a0b,
60 0x5b0c, 0x450d, 0x7e0e, 0x2b1b, 0x2f1c, 0x301d, 0x331e
61 };
62
63 //
64 // 800 x 600 x 256 color @ 60 Hertz
65 //
66 static UINT8 Crtc_800_600_256_60[28] = {
67 0x7F, 0x63, 0x64, 0x80, 0x6B, 0x1B, 0x72, 0xF0,
68 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
69 0x58, 0x8C, 0x57, 0x64, 0x00, 0x5F, 0x91, 0xE3,
70 0xFF, 0x00, 0x00, 0x22
71 };
72
73 static UINT16 Seq_800_600_256_60[15] = {
74 0x0100, 0x0101, 0x0f02, 0x0003, 0x0e04, 0x1107, 0x0008, 0x4a0b,
75 0x5b0c, 0x450d, 0x510e, 0x2b1b, 0x2f1c, 0x301d, 0x3a1e
76 };
77
78 //
79 // 1024 x 768 x 256 color @ 60 Hertz
80 //
81 static UINT8 Crtc_1024_768_256_60[28] = {
82 0xA3, 0x7F, 0x80, 0x86, 0x85, 0x96, 0x24, 0xFD,
83 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
84 0x02, 0x88, 0xFF, 0x80, 0x00, 0x00, 0x24, 0xE3,
85 0xFF, 0x4A, 0x00, 0x22
86 };
87
88 static UINT16 Seq_1024_768_256_60[15] = {
89 0x0100, 0x0101, 0x0f02, 0x0003, 0x0e04, 0x1107, 0x0008, 0x4a0b,
90 0x5b0c, 0x450d, 0x760e, 0x2b1b, 0x2f1c, 0x301d, 0x341e
91 };
92
93 ///
94 /// Table of supported video modes
95 ///
96 static CIRRUS_LOGIC_5430_VIDEO_MODES CirrusLogic5430VideoModes[] = {
97 { 640, 480, 8, 60, Crtc_640_480_256_60, Seq_640_480_256_60, 0xe3 },
98 { 800, 600, 8, 60, Crtc_800_600_256_60, Seq_800_600_256_60, 0xef },
99 { 1024, 768, 8, 60, Crtc_1024_768_256_60, Seq_1024_768_256_60, 0xef }
100 };
101
102 //
103 // Local Function Prototypes
104 //
105 VOID
106 InitializeGraphicsMode (
107 CIRRUS_LOGIC_5430_PRIVATE_DATA *Private,
108 CIRRUS_LOGIC_5430_VIDEO_MODES *ModeData
109 );
110
111 VOID
112 SetPaletteColor (
113 CIRRUS_LOGIC_5430_PRIVATE_DATA *Private,
114 UINTN Index,
115 UINT8 Red,
116 UINT8 Green,
117 UINT8 Blue
118 );
119
120 VOID
121 SetDefaultPalette (
122 CIRRUS_LOGIC_5430_PRIVATE_DATA *Private
123 );
124
125 STATIC
126 VOID
127 ClearScreen (
128 CIRRUS_LOGIC_5430_PRIVATE_DATA *Private
129 );
130
131 VOID
132 DrawLogo (
133 CIRRUS_LOGIC_5430_PRIVATE_DATA *Private
134 );
135
136 VOID
137 outb (
138 CIRRUS_LOGIC_5430_PRIVATE_DATA *Private,
139 UINTN Address,
140 UINT8 Data
141 );
142
143 VOID
144 outw (
145 CIRRUS_LOGIC_5430_PRIVATE_DATA *Private,
146 UINTN Address,
147 UINT16 Data
148 );
149
150 UINT8
151 inb (
152 CIRRUS_LOGIC_5430_PRIVATE_DATA *Private,
153 UINTN Address
154 );
155
156 UINT16
157 inw (
158 CIRRUS_LOGIC_5430_PRIVATE_DATA *Private,
159 UINTN Address
160 );
161
162 //
163 // UGA Draw Protocol Member Functions
164 //
165 /**
166 TODO: Add function description
167
168 @param This TODO: add argument description
169 @param HorizontalResolution TODO: add argument description
170 @param VerticalResolution TODO: add argument description
171 @param ColorDepth TODO: add argument description
172 @param RefreshRate TODO: add argument description
173
174 @retval EFI_NOT_STARTED TODO: Add description for return value
175 @retval EFI_INVALID_PARAMETER TODO: Add description for return value
176 @retval EFI_SUCCESS TODO: Add description for return value
177
178 **/
179 EFI_STATUS
180 EFIAPI
181 CirrusLogic5430UgaDrawGetMode (
182 IN EFI_UGA_DRAW_PROTOCOL *This,
183 OUT UINT32 *HorizontalResolution,
184 OUT UINT32 *VerticalResolution,
185 OUT UINT32 *ColorDepth,
186 OUT UINT32 *RefreshRate
187 )
188 {
189 CIRRUS_LOGIC_5430_PRIVATE_DATA *Private;
190
191 Private = CIRRUS_LOGIC_5430_PRIVATE_DATA_FROM_UGA_DRAW_THIS (This);
192
193 if (Private->HardwareNeedsStarting) {
194 return EFI_NOT_STARTED;
195 }
196
197 if ((HorizontalResolution == NULL) ||
198 (VerticalResolution == NULL) ||
199 (ColorDepth == NULL) ||
200 (RefreshRate == NULL)) {
201 return EFI_INVALID_PARAMETER;
202 }
203
204 *HorizontalResolution = Private->ModeData[Private->CurrentMode].HorizontalResolution;
205 *VerticalResolution = Private->ModeData[Private->CurrentMode].VerticalResolution;
206 *ColorDepth = Private->ModeData[Private->CurrentMode].ColorDepth;
207 *RefreshRate = Private->ModeData[Private->CurrentMode].RefreshRate;
208
209 return EFI_SUCCESS;
210 }
211
212 /**
213 TODO: Add function description
214
215 @param This TODO: add argument description
216 @param HorizontalResolution TODO: add argument description
217 @param VerticalResolution TODO: add argument description
218 @param ColorDepth TODO: add argument description
219 @param RefreshRate TODO: add argument description
220
221 @retval EFI_OUT_OF_RESOURCES TODO: Add description for return value
222 @retval EFI_SUCCESS TODO: Add description for return value
223 @retval EFI_NOT_FOUND TODO: Add description for return value
224
225 **/
226 EFI_STATUS
227 EFIAPI
228 CirrusLogic5430UgaDrawSetMode (
229 IN EFI_UGA_DRAW_PROTOCOL *This,
230 IN UINT32 HorizontalResolution,
231 IN UINT32 VerticalResolution,
232 IN UINT32 ColorDepth,
233 IN UINT32 RefreshRate
234 )
235 {
236 CIRRUS_LOGIC_5430_PRIVATE_DATA *Private;
237 UINTN Index;
238
239 Private = CIRRUS_LOGIC_5430_PRIVATE_DATA_FROM_UGA_DRAW_THIS (This);
240
241 for (Index = 0; Index < Private->MaxMode; Index++) {
242
243 if (HorizontalResolution != Private->ModeData[Index].HorizontalResolution) {
244 continue;
245 }
246
247 if (VerticalResolution != Private->ModeData[Index].VerticalResolution) {
248 continue;
249 }
250
251 if (ColorDepth != Private->ModeData[Index].ColorDepth) {
252 continue;
253 }
254
255 if (RefreshRate != Private->ModeData[Index].RefreshRate) {
256 continue;
257 }
258
259 if (Private->LineBuffer) {
260 gBS->FreePool (Private->LineBuffer);
261 }
262
263 Private->LineBuffer = NULL;
264 Private->LineBuffer = AllocatePool (HorizontalResolution);
265 if (Private->LineBuffer == NULL) {
266 return EFI_OUT_OF_RESOURCES;
267 }
268
269 InitializeGraphicsMode (Private, &CirrusLogic5430VideoModes[Index]);
270
271 Private->CurrentMode = Index;
272
273 Private->HardwareNeedsStarting = FALSE;
274
275 return EFI_SUCCESS;
276 }
277
278 return EFI_NOT_FOUND;
279 }
280
281 /**
282 TODO: Add function description
283
284 @param This TODO: add argument description
285 @param BltBuffer TODO: add argument description
286 @param BltOperation TODO: add argument description
287 @param SourceX TODO: add argument description
288 @param SourceY TODO: add argument description
289 @param DestinationX TODO: add argument description
290 @param DestinationY TODO: add argument description
291 @param Width TODO: add argument description
292 @param Height TODO: add argument description
293 @param Delta TODO: add argument description
294
295 @retval EFI_INVALID_PARAMETER TODO: Add description for return value
296 @retval EFI_INVALID_PARAMETER TODO: Add description for return value
297 @retval EFI_INVALID_PARAMETER TODO: Add description for return value
298 @retval EFI_INVALID_PARAMETER TODO: Add description for return value
299 @retval EFI_INVALID_PARAMETER TODO: Add description for return value
300 @retval EFI_INVALID_PARAMETER TODO: Add description for return value
301 @retval EFI_SUCCESS TODO: Add description for return value
302
303 **/
304 EFI_STATUS
305 EFIAPI
306 CirrusLogic5430UgaDrawBlt (
307 IN EFI_UGA_DRAW_PROTOCOL *This,
308 IN EFI_UGA_PIXEL *BltBuffer, OPTIONAL
309 IN EFI_UGA_BLT_OPERATION BltOperation,
310 IN UINTN SourceX,
311 IN UINTN SourceY,
312 IN UINTN DestinationX,
313 IN UINTN DestinationY,
314 IN UINTN Width,
315 IN UINTN Height,
316 IN UINTN Delta
317 )
318 {
319 CIRRUS_LOGIC_5430_PRIVATE_DATA *Private;
320 EFI_TPL OriginalTPL;
321 UINTN DstY;
322 UINTN SrcY;
323 EFI_UGA_PIXEL *Blt;
324 UINTN X;
325 UINT8 Pixel;
326 UINT32 WidePixel;
327 UINTN ScreenWidth;
328 UINTN Offset;
329 UINTN SourceOffset;
330
331 Private = CIRRUS_LOGIC_5430_PRIVATE_DATA_FROM_UGA_DRAW_THIS (This);
332
333 if ((BltOperation < 0) || (BltOperation >= EfiUgaBltMax)) {
334 return EFI_INVALID_PARAMETER;
335 }
336
337 if (Width == 0 || Height == 0) {
338 return EFI_INVALID_PARAMETER;
339 }
340
341 //
342 // If Delta is zero, then the entire BltBuffer is being used, so Delta
343 // is the number of bytes in each row of BltBuffer. Since BltBuffer is Width pixels size,
344 // the number of bytes in each row can be computed.
345 //
346 if (Delta == 0) {
347 Delta = Width * sizeof (EFI_UGA_PIXEL);
348 }
349
350 //
351 // We need to fill the Virtual Screen buffer with the blt data.
352 // The virtual screen is upside down, as the first row is the bootom row of
353 // the image.
354 //
355
356 //
357 // Make sure the SourceX, SourceY, DestinationX, DestinationY, Width, and Height parameters
358 // are valid for the operation and the current screen geometry.
359 //
360 if (BltOperation == EfiUgaVideoToBltBuffer) {
361 //
362 // Video to BltBuffer: Source is Video, destination is BltBuffer
363 //
364 if (SourceY + Height > Private->ModeData[Private->CurrentMode].VerticalResolution) {
365 return EFI_INVALID_PARAMETER;
366 }
367
368 if (SourceX + Width > Private->ModeData[Private->CurrentMode].HorizontalResolution) {
369 return EFI_INVALID_PARAMETER;
370 }
371 } else {
372 //
373 // BltBuffer to Video: Source is BltBuffer, destination is Video
374 //
375 if (DestinationY + Height > Private->ModeData[Private->CurrentMode].VerticalResolution) {
376 return EFI_INVALID_PARAMETER;
377 }
378
379 if (DestinationX + Width > Private->ModeData[Private->CurrentMode].HorizontalResolution) {
380 return EFI_INVALID_PARAMETER;
381 }
382 }
383 //
384 // We have to raise to TPL Notify, so we make an atomic write the frame buffer.
385 // We would not want a timer based event (Cursor, ...) to come in while we are
386 // doing this operation.
387 //
388 OriginalTPL = gBS->RaiseTPL (EFI_TPL_NOTIFY);
389
390 switch (BltOperation) {
391 case EfiUgaVideoToBltBuffer:
392 //
393 // Video to BltBuffer: Source is Video, destination is BltBuffer
394 //
395 for (SrcY = SourceY, DstY = DestinationY; DstY < (Height + DestinationY); SrcY++, DstY++) {
396
397 Offset = (SrcY * Private->ModeData[Private->CurrentMode].HorizontalResolution) + SourceX;
398 if (((Offset & 0x03) == 0) && ((Width & 0x03) == 0)) {
399 Private->PciIo->Mem.Read (
400 Private->PciIo,
401 EfiPciIoWidthUint32,
402 0,
403 Offset,
404 Width >> 2,
405 Private->LineBuffer
406 );
407 } else {
408 Private->PciIo->Mem.Read (
409 Private->PciIo,
410 EfiPciIoWidthUint8,
411 0,
412 Offset,
413 Width,
414 Private->LineBuffer
415 );
416 }
417
418 for (X = 0; X < Width; X++) {
419 Blt = (EFI_UGA_PIXEL *) ((UINT8 *) BltBuffer + (DstY * Delta) + (DestinationX + X) * sizeof (EFI_UGA_PIXEL));
420
421 Blt->Red = (UINT8) (Private->LineBuffer[X] & 0xe0);
422 Blt->Green = (UINT8) ((Private->LineBuffer[X] & 0x1c) << 3);
423 Blt->Blue = (UINT8) ((Private->LineBuffer[X] & 0x03) << 6);
424 }
425 }
426 break;
427
428 case EfiUgaVideoToVideo:
429 //
430 // Perform hardware acceleration for Video to Video operations
431 //
432 ScreenWidth = Private->ModeData[Private->CurrentMode].HorizontalResolution;
433 SourceOffset = (SourceY * Private->ModeData[Private->CurrentMode].HorizontalResolution) + (SourceX);
434 Offset = (DestinationY * Private->ModeData[Private->CurrentMode].HorizontalResolution) + (DestinationX);
435
436 outw (Private, GRAPH_ADDRESS_REGISTER, 0x0000);
437 outw (Private, GRAPH_ADDRESS_REGISTER, 0x0010);
438 outw (Private, GRAPH_ADDRESS_REGISTER, 0x0012);
439 outw (Private, GRAPH_ADDRESS_REGISTER, 0x0014);
440
441 outw (Private, GRAPH_ADDRESS_REGISTER, 0x0001);
442 outw (Private, GRAPH_ADDRESS_REGISTER, 0x0011);
443 outw (Private, GRAPH_ADDRESS_REGISTER, 0x0013);
444 outw (Private, GRAPH_ADDRESS_REGISTER, 0x0015);
445
446 outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) (((Width << 8) & 0xff00) | 0x20));
447 outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((Width & 0xff00) | 0x21));
448 outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) (((Height << 8) & 0xff00) | 0x22));
449 outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((Height & 0xff00) | 0x23));
450 outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) (((ScreenWidth << 8) & 0xff00) | 0x24));
451 outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((ScreenWidth & 0xff00) | 0x25));
452 outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) (((ScreenWidth << 8) & 0xff00) | 0x26));
453 outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((ScreenWidth & 0xff00) | 0x27));
454 outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((((Offset) << 8) & 0xff00) | 0x28));
455 outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((((Offset) >> 0) & 0xff00) | 0x29));
456 outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((((Offset) >> 8) & 0xff00) | 0x2a));
457 outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((((SourceOffset) << 8) & 0xff00) | 0x2c));
458 outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((((SourceOffset) >> 0) & 0xff00) | 0x2d));
459 outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((((SourceOffset) >> 8) & 0xff00) | 0x2e));
460 outw (Private, GRAPH_ADDRESS_REGISTER, 0x002f);
461 outw (Private, GRAPH_ADDRESS_REGISTER, 0x0030);
462 outw (Private, GRAPH_ADDRESS_REGISTER, 0x0d32);
463 outw (Private, GRAPH_ADDRESS_REGISTER, 0x0033);
464 outw (Private, GRAPH_ADDRESS_REGISTER, 0x0034);
465 outw (Private, GRAPH_ADDRESS_REGISTER, 0x0035);
466
467 outw (Private, GRAPH_ADDRESS_REGISTER, 0x0231);
468
469 outb (Private, GRAPH_ADDRESS_REGISTER, 0x31);
470 while ((inb (Private, GRAPH_DATA_REGISTER) & 0x01) == 0x01)
471 ;
472 break;
473
474 case EfiUgaVideoFill:
475 Blt = BltBuffer;
476 Pixel = (UINT8) ((Blt->Red & 0xe0) | ((Blt->Green >> 3) & 0x1c) | ((Blt->Blue >> 6) & 0x03));
477 WidePixel = (Pixel << 8) | Pixel;
478 WidePixel = (WidePixel << 16) | WidePixel;
479
480 if (DestinationX == 0 && Width == Private->ModeData[Private->CurrentMode].HorizontalResolution) {
481 Offset = DestinationY * Private->ModeData[Private->CurrentMode].HorizontalResolution;
482 if (((Offset & 0x03) == 0) && (((Width * Height) & 0x03) == 0)) {
483 Private->PciIo->Mem.Write (
484 Private->PciIo,
485 EfiPciIoWidthFillUint32,
486 0,
487 Offset,
488 (Width * Height) >> 2,
489 &WidePixel
490 );
491 } else {
492 Private->PciIo->Mem.Write (
493 Private->PciIo,
494 EfiPciIoWidthFillUint8,
495 0,
496 Offset,
497 Width * Height,
498 &Pixel
499 );
500 }
501 } else {
502 for (SrcY = SourceY, DstY = DestinationY; SrcY < (Height + SourceY); SrcY++, DstY++) {
503 Offset = (DstY * Private->ModeData[Private->CurrentMode].HorizontalResolution) + DestinationX;
504 if (((Offset & 0x03) == 0) && ((Width & 0x03) == 0)) {
505 Private->PciIo->Mem.Write (
506 Private->PciIo,
507 EfiPciIoWidthFillUint32,
508 0,
509 Offset,
510 Width >> 2,
511 &WidePixel
512 );
513 } else {
514 Private->PciIo->Mem.Write (
515 Private->PciIo,
516 EfiPciIoWidthFillUint8,
517 0,
518 Offset,
519 Width,
520 &Pixel
521 );
522 }
523 }
524 }
525 break;
526
527 case EfiUgaBltBufferToVideo:
528 for (SrcY = SourceY, DstY = DestinationY; SrcY < (Height + SourceY); SrcY++, DstY++) {
529
530 for (X = 0; X < Width; X++) {
531 Blt = (EFI_UGA_PIXEL *) ((UINT8 *) BltBuffer + (SrcY * Delta) + (SourceX + X) * sizeof (EFI_UGA_PIXEL));
532 Private->LineBuffer[X] = (UINT8) ((Blt->Red & 0xe0) | ((Blt->Green >> 3) & 0x1c) | ((Blt->Blue >> 6) & 0x03));
533 }
534
535 Offset = (DstY * Private->ModeData[Private->CurrentMode].HorizontalResolution) + DestinationX;
536
537 if (((Offset & 0x03) == 0) && ((Width & 0x03) == 0)) {
538 Private->PciIo->Mem.Write (
539 Private->PciIo,
540 EfiPciIoWidthUint32,
541 0,
542 Offset,
543 Width >> 2,
544 Private->LineBuffer
545 );
546 } else {
547 Private->PciIo->Mem.Write (
548 Private->PciIo,
549 EfiPciIoWidthUint8,
550 0,
551 Offset,
552 Width,
553 Private->LineBuffer
554 );
555 }
556 }
557 break;
558
559 default:
560 break;
561 }
562
563 gBS->RestoreTPL (OriginalTPL);
564
565 return EFI_SUCCESS;
566 }
567
568 //
569 // Construction and Destruction functions
570 //
571
572 /**
573 CirrusLogic5430UgaDrawConstructor
574
575 TODO: Private - add argument and description to function comment
576 TODO: EFI_SUCCESS - add return value to function comment
577 **/
578 EFI_STATUS
579 CirrusLogic5430UgaDrawConstructor (
580 CIRRUS_LOGIC_5430_PRIVATE_DATA *Private
581 )
582 {
583 EFI_UGA_DRAW_PROTOCOL *UgaDraw;
584 UINTN Index;
585
586 //
587 // Fill in Private->UgaDraw protocol
588 //
589 UgaDraw = &Private->UgaDraw;
590
591 UgaDraw->GetMode = CirrusLogic5430UgaDrawGetMode;
592 UgaDraw->SetMode = CirrusLogic5430UgaDrawSetMode;
593 UgaDraw->Blt = CirrusLogic5430UgaDrawBlt;
594
595 //
596 // Initialize the private data
597 //
598 Private->MaxMode = CIRRUS_LOGIC_5430_UGA_DRAW_MODE_COUNT;
599 Private->CurrentMode = 0;
600 for (Index = 0; Index < Private->MaxMode; Index++) {
601 Private->ModeData[Index].HorizontalResolution = CirrusLogic5430VideoModes[Index].Width;
602 Private->ModeData[Index].VerticalResolution = CirrusLogic5430VideoModes[Index].Height;
603 Private->ModeData[Index].ColorDepth = 32;
604 Private->ModeData[Index].RefreshRate = CirrusLogic5430VideoModes[Index].RefreshRate;
605 }
606
607 Private->HardwareNeedsStarting = TRUE;
608 Private->LineBuffer = NULL;
609
610 //
611 // Initialize the hardware
612 //
613 UgaDraw->SetMode (
614 UgaDraw,
615 Private->ModeData[Private->CurrentMode].HorizontalResolution,
616 Private->ModeData[Private->CurrentMode].VerticalResolution,
617 Private->ModeData[Private->CurrentMode].ColorDepth,
618 Private->ModeData[Private->CurrentMode].RefreshRate
619 );
620 DrawLogo (Private);
621
622 return EFI_SUCCESS;
623 }
624
625 /**
626 CirrusLogic5430UgaDrawDestructor
627
628 TODO: Private - add argument and description to function comment
629 TODO: EFI_SUCCESS - add return value to function comment
630 **/
631 EFI_STATUS
632 CirrusLogic5430UgaDrawDestructor (
633 CIRRUS_LOGIC_5430_PRIVATE_DATA *Private
634 )
635 {
636 return EFI_SUCCESS;
637 }
638
639 /**
640 TODO: Add function description
641
642 @param Private TODO: add argument description
643 @param Address TODO: add argument description
644 @param Data TODO: add argument description
645
646 TODO: add return values
647
648 **/
649 VOID
650 outb (
651 CIRRUS_LOGIC_5430_PRIVATE_DATA *Private,
652 UINTN Address,
653 UINT8 Data
654 )
655 {
656 Private->PciIo->Io.Write (
657 Private->PciIo,
658 EfiPciIoWidthUint8,
659 EFI_PCI_IO_PASS_THROUGH_BAR,
660 Address,
661 1,
662 &Data
663 );
664 }
665
666 /**
667 TODO: Add function description
668
669 @param Private TODO: add argument description
670 @param Address TODO: add argument description
671 @param Data TODO: add argument description
672
673 TODO: add return values
674
675 **/
676 VOID
677 outw (
678 CIRRUS_LOGIC_5430_PRIVATE_DATA *Private,
679 UINTN Address,
680 UINT16 Data
681 )
682 {
683 Private->PciIo->Io.Write (
684 Private->PciIo,
685 EfiPciIoWidthUint16,
686 EFI_PCI_IO_PASS_THROUGH_BAR,
687 Address,
688 1,
689 &Data
690 );
691 }
692
693 /**
694 TODO: Add function description
695
696 @param Private TODO: add argument description
697 @param Address TODO: add argument description
698
699 TODO: add return values
700
701 **/
702 UINT8
703 inb (
704 CIRRUS_LOGIC_5430_PRIVATE_DATA *Private,
705 UINTN Address
706 )
707 {
708 UINT8 Data;
709
710 Private->PciIo->Io.Read (
711 Private->PciIo,
712 EfiPciIoWidthUint8,
713 EFI_PCI_IO_PASS_THROUGH_BAR,
714 Address,
715 1,
716 &Data
717 );
718 return Data;
719 }
720
721 /**
722 TODO: Add function description
723
724 @param Private TODO: add argument description
725 @param Address TODO: add argument description
726
727 TODO: add return values
728
729 **/
730 UINT16
731 inw (
732 CIRRUS_LOGIC_5430_PRIVATE_DATA *Private,
733 UINTN Address
734 )
735 {
736 UINT16 Data;
737
738 Private->PciIo->Io.Read (
739 Private->PciIo,
740 EfiPciIoWidthUint16,
741 EFI_PCI_IO_PASS_THROUGH_BAR,
742 Address,
743 1,
744 &Data
745 );
746 return Data;
747 }
748
749 /**
750 TODO: Add function description
751
752 @param Private TODO: add argument description
753 @param Index TODO: add argument description
754 @param Red TODO: add argument description
755 @param Green TODO: add argument description
756 @param Blue TODO: add argument description
757
758 TODO: add return values
759
760 **/
761 VOID
762 SetPaletteColor (
763 CIRRUS_LOGIC_5430_PRIVATE_DATA *Private,
764 UINTN Index,
765 UINT8 Red,
766 UINT8 Green,
767 UINT8 Blue
768 )
769 {
770 outb (Private, PALETTE_INDEX_REGISTER, (UINT8) Index);
771 outb (Private, PALETTE_DATA_REGISTER, (UINT8) (Red >> 2));
772 outb (Private, PALETTE_DATA_REGISTER, (UINT8) (Green >> 2));
773 outb (Private, PALETTE_DATA_REGISTER, (UINT8) (Blue >> 2));
774 }
775
776 /**
777 TODO: Add function description
778
779 @param Private TODO: add argument description
780
781 TODO: add return values
782
783 **/
784 VOID
785 SetDefaultPalette (
786 CIRRUS_LOGIC_5430_PRIVATE_DATA *Private
787 )
788 {
789 UINTN Index;
790 UINTN RedIndex;
791 UINTN GreenIndex;
792 UINTN BlueIndex;
793
794 Index = 0;
795 for (RedIndex = 0; RedIndex < 8; RedIndex++) {
796 for (GreenIndex = 0; GreenIndex < 8; GreenIndex++) {
797 for (BlueIndex = 0; BlueIndex < 4; BlueIndex++) {
798 SetPaletteColor (Private, Index, (UINT8) (RedIndex << 5), (UINT8) (GreenIndex << 5), (UINT8) (BlueIndex << 6));
799 Index++;
800 }
801 }
802 }
803 }
804
805 /**
806 TODO: Add function description
807
808 @param Private TODO: add argument description
809
810 TODO: add return values
811
812 **/
813 STATIC
814 VOID
815 ClearScreen (
816 CIRRUS_LOGIC_5430_PRIVATE_DATA *Private
817 )
818 {
819 UINT32 Color;
820
821 Color = 0;
822 Private->PciIo->Mem.Write (
823 Private->PciIo,
824 EfiPciIoWidthFillUint32,
825 0,
826 0,
827 0x100000 >> 2,
828 &Color
829 );
830 }
831
832 /**
833 TODO: Add function description
834
835 @param Private TODO: add argument description
836
837 TODO: add return values
838
839 **/
840 VOID
841 DrawLogo (
842 CIRRUS_LOGIC_5430_PRIVATE_DATA *Private
843 )
844 {
845 UINTN Offset;
846 UINTN X;
847 UINTN Y;
848 UINTN ScreenWidth;
849 UINTN ScreenHeight;
850 UINT8 Color;
851
852 ScreenWidth = Private->ModeData[Private->CurrentMode].HorizontalResolution;
853 ScreenHeight = Private->ModeData[Private->CurrentMode].VerticalResolution;
854
855 Offset = 0;
856 for (Y = 0; Y < ScreenHeight; Y++) {
857 for (X = 0; X < ScreenWidth; X++) {
858 Color = (UINT8) (256 * (X + Y) / (ScreenWidth + ScreenHeight));
859 Private->LineBuffer[X] = Color;
860 }
861
862 Private->PciIo->Mem.Write (
863 Private->PciIo,
864 EfiPciIoWidthUint32,
865 0,
866 Offset + (Y * ScreenWidth),
867 ScreenWidth >> 2,
868 Private->LineBuffer
869 );
870 }
871 }
872
873 /**
874 TODO: Add function description
875
876 @param Private TODO: add argument description
877 @param ModeData TODO: add argument description
878
879 TODO: add return values
880
881 **/
882 VOID
883 InitializeGraphicsMode (
884 CIRRUS_LOGIC_5430_PRIVATE_DATA *Private,
885 CIRRUS_LOGIC_5430_VIDEO_MODES *ModeData
886 )
887 {
888 UINT8 Byte;
889 UINTN Index;
890
891 outw (Private, SEQ_ADDRESS_REGISTER, 0x1206);
892 outw (Private, SEQ_ADDRESS_REGISTER, 0x0012);
893
894 for (Index = 0; Index < 15; Index++) {
895 outw (Private, SEQ_ADDRESS_REGISTER, ModeData->SeqSettings[Index]);
896 }
897
898 outb (Private, SEQ_ADDRESS_REGISTER, 0x0f);
899 Byte = (UINT8) ((inb (Private, SEQ_DATA_REGISTER) & 0xc7) ^ 0x30);
900 outb (Private, SEQ_DATA_REGISTER, Byte);
901
902 outb (Private, MISC_OUTPUT_REGISTER, ModeData->MiscSetting);
903 outw (Private, GRAPH_ADDRESS_REGISTER, 0x0506);
904 outw (Private, SEQ_ADDRESS_REGISTER, 0x0300);
905 outw (Private, CRTC_ADDRESS_REGISTER, 0x2011);
906
907 for (Index = 0; Index < 28; Index++) {
908 outw (Private, CRTC_ADDRESS_REGISTER, (UINT16) ((ModeData->CrtcSettings[Index] << 8) | Index));
909 }
910
911 for (Index = 0; Index < 9; Index++) {
912 outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((GraphicsController[Index] << 8) | Index));
913 }
914
915 inb (Private, INPUT_STATUS_1_REGISTER);
916
917 for (Index = 0; Index < 21; Index++) {
918 outb (Private, ATT_ADDRESS_REGISTER, (UINT8) Index);
919 outb (Private, ATT_ADDRESS_REGISTER, AttributeController[Index]);
920 }
921
922 outb (Private, ATT_ADDRESS_REGISTER, 0x20);
923
924 outw (Private, GRAPH_ADDRESS_REGISTER, 0x0009);
925 outw (Private, GRAPH_ADDRESS_REGISTER, 0x000a);
926 outw (Private, GRAPH_ADDRESS_REGISTER, 0x000b);
927 outb (Private, DAC_PIXEL_MASK_REGISTER, 0xff);
928
929 SetDefaultPalette (Private);
930 ClearScreen (Private);
931 }