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