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