]> git.proxmox.com Git - mirror_edk2.git/blame - Omap35xxPkg/LcdGraphicsOutputDxe/LcdGraphicsOutputDxe.c
MdePkg: Fix bug in CatVSPrint introduced by r17742.
[mirror_edk2.git] / Omap35xxPkg / LcdGraphicsOutputDxe / LcdGraphicsOutputDxe.c
CommitLineData
1e57a462 1/** @file\r
2\r
b0fdce95 3 Copyright (c) 2011-2014, ARM Ltd. All rights reserved.<BR>\r
1e57a462 4 This program and the accompanying materials\r
5 are licensed and made available under the terms and conditions of the BSD License\r
6 which accompanies this distribution. The full text of the license may be found at\r
7 http://opensource.org/licenses/bsd-license.php\r
8\r
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
11\r
12**/\r
13\r
14#include "LcdGraphicsOutputDxe.h"\r
15\r
16BOOLEAN mDisplayInitialized = FALSE;\r
17\r
18LCD_MODE LcdModes[] = {\r
19 {\r
20 0, 640, 480,\r
21 9, 4,\r
22 96, 16, 48,\r
23 2, 10, 33\r
24 },\r
25 {\r
26 1, 800, 600,\r
27 11, 2,\r
28 120, 56, 64,\r
29 5, 37, 22\r
30 },\r
31 {\r
32 2, 1024, 768,\r
33 6, 2,\r
34 96, 16, 48,\r
35 2, 10, 33\r
36 },\r
37};\r
38\r
39LCD_INSTANCE mLcdTemplate = {\r
40 LCD_INSTANCE_SIGNATURE,\r
41 NULL, // Handle\r
42 { // ModeInfo\r
43 0, // Version\r
44 0, // HorizontalResolution\r
45 0, // VerticalResolution\r
46 PixelBltOnly, // PixelFormat\r
47 {\r
48 0xF800, //RedMask;\r
49 0x7E0, //GreenMask;\r
50 0x1F, //BlueMask;\r
51 0x0//ReservedMask\r
52 }, // PixelInformation\r
53 0, // PixelsPerScanLine\r
54 },\r
55 { // Mode\r
56 3, // MaxMode;\r
57 0, // Mode;\r
58 NULL, // Info;\r
59 0, // SizeOfInfo;\r
60 0, // FrameBufferBase;\r
61 0 // FrameBufferSize;\r
62 },\r
63 { // Gop\r
64 LcdGraphicsQueryMode, // QueryMode\r
65 LcdGraphicsSetMode, // SetMode\r
66 LcdGraphicsBlt, // Blt\r
67 NULL // *Mode\r
68 },\r
69 { // DevicePath\r
70 {\r
71 {\r
72 HARDWARE_DEVICE_PATH, HW_VENDOR_DP,\r
b0fdce95 73 { (UINT8) (sizeof(VENDOR_DEVICE_PATH)), (UINT8) ((sizeof(VENDOR_DEVICE_PATH)) >> 8) },\r
1e57a462 74 },\r
75 // Hardware Device Path for Lcd\r
76 EFI_CALLER_ID_GUID // Use the driver's GUID\r
77 },\r
1e57a462 78 {\r
79 END_DEVICE_PATH_TYPE,\r
80 END_ENTIRE_DEVICE_PATH_SUBTYPE,\r
b0fdce95 81 { sizeof(EFI_DEVICE_PATH_PROTOCOL), 0}\r
1e57a462 82 }\r
83 }\r
84};\r
85\r
86EFI_STATUS\r
87LcdInstanceContructor (\r
88 OUT LCD_INSTANCE** NewInstance\r
89 )\r
90{\r
91 LCD_INSTANCE* Instance;\r
92\r
93 Instance = AllocateCopyPool (sizeof(LCD_INSTANCE), &mLcdTemplate);\r
94 if (Instance == NULL) {\r
95 return EFI_OUT_OF_RESOURCES;\r
96 }\r
97\r
98 Instance->Gop.Mode = &Instance->Mode;\r
99 Instance->Mode.Info = &Instance->ModeInfo;\r
100\r
101 *NewInstance = Instance;\r
102 return EFI_SUCCESS;\r
103}\r
104\r
105EFI_STATUS\r
106LcdPlatformGetVram (\r
107 OUT EFI_PHYSICAL_ADDRESS* VramBaseAddress,\r
108 OUT UINTN* VramSize\r
109 )\r
110{\r
111 EFI_STATUS Status;\r
112 EFI_CPU_ARCH_PROTOCOL *Cpu;\r
113 UINTN MaxSize;\r
114\r
115 MaxSize = 0x500000;\r
116 *VramSize = MaxSize;\r
117\r
118 // Allocate VRAM from DRAM\r
119 Status = gBS->AllocatePages (AllocateAnyPages, EfiBootServicesData, EFI_SIZE_TO_PAGES((MaxSize)), VramBaseAddress);\r
120 if (EFI_ERROR(Status)) {\r
121 return Status;\r
122 }\r
123\r
124 // Ensure the Cpu architectural protocol is already installed\r
125 Status = gBS->LocateProtocol (&gEfiCpuArchProtocolGuid, NULL, (VOID **)&Cpu);\r
126 ASSERT_EFI_ERROR(Status);\r
127\r
128 // Mark the VRAM as un-cacheable. The VRAM is inside the DRAM, which is cacheable.\r
129 Status = Cpu->SetMemoryAttributes (Cpu, *VramBaseAddress, *VramSize, EFI_MEMORY_UC);\r
130 if (EFI_ERROR(Status)) {\r
131 gBS->FreePool (VramBaseAddress);\r
132 return Status;\r
133 }\r
134\r
135 return EFI_SUCCESS;\r
136}\r
137\r
138EFI_STATUS\r
139DssSetMode (\r
140 UINT32 VramBaseAddress,\r
141 UINTN ModeNumber\r
142 )\r
143{\r
144 // Make sure the interface clock is running\r
3402aac7 145 MmioWrite32 (CM_ICLKEN_DSS, EN_DSS);\r
1e57a462 146\r
147 // Stop the functional clocks\r
148 MmioAnd32 (CM_FCLKEN_DSS, ~(EN_DSS1 | EN_DSS2 | EN_TV));\r
149\r
150 // Program the DSS clock divisor\r
151 MmioWrite32 (CM_CLKSEL_DSS, 0x1000 | (LcdModes[ModeNumber].DssDivisor));\r
3402aac7 152\r
1e57a462 153 // Start the functional clocks\r
154 MmioOr32 (CM_FCLKEN_DSS, (EN_DSS1 | EN_DSS2 | EN_TV));\r
155\r
156 // Wait for DSS to stabilize\r
157 gBS->Stall(1);\r
158\r
159 // Reset the subsystem\r
160 MmioWrite32(DSS_SYSCONFIG, DSS_SOFTRESET);\r
161 while (!(MmioRead32 (DSS_SYSSTATUS) & DSS_RESETDONE));\r
3402aac7 162\r
1e57a462 163 // Configure LCD parameters\r
164 MmioWrite32 (DISPC_SIZE_LCD,\r
3402aac7 165 ((LcdModes[ModeNumber].HorizontalResolution - 1)\r
1e57a462 166 | ((LcdModes[ModeNumber].VerticalResolution - 1) << 16))\r
167 );\r
168 MmioWrite32 (DISPC_TIMING_H,\r
169 ( (LcdModes[ModeNumber].HSync - 1)\r
170 | ((LcdModes[ModeNumber].HFrontPorch - 1) << 8)\r
171 | ((LcdModes[ModeNumber].HBackPorch - 1) << 20))\r
172 );\r
173 MmioWrite32 (DISPC_TIMING_V,\r
174 ( (LcdModes[ModeNumber].VSync - 1)\r
175 | ((LcdModes[ModeNumber].VFrontPorch - 1) << 8)\r
176 | ((LcdModes[ModeNumber].VBackPorch - 1) << 20))\r
177 );\r
178\r
179 // Set the framebuffer to only load frames (no gamma tables)\r
180 MmioAnd32 (DISPC_CONFIG, CLEARLOADMODE);\r
181 MmioOr32 (DISPC_CONFIG, LOAD_FRAME_ONLY);\r
182\r
183 // Divisor for the pixel clock\r
184 MmioWrite32(DISPC_DIVISOR, ((1 << 16) | LcdModes[ModeNumber].DispcDivisor) );\r
185\r
186 // Set up the graphics layer\r
187 MmioWrite32 (DISPC_GFX_PRELD, 0x2D8);\r
188 MmioWrite32 (DISPC_GFX_BA0, VramBaseAddress);\r
189 MmioWrite32 (DISPC_GFX_SIZE,\r
3402aac7 190 ((LcdModes[ModeNumber].HorizontalResolution - 1)\r
1e57a462 191 | ((LcdModes[ModeNumber].VerticalResolution - 1) << 16))\r
192 );\r
193\r
194 MmioWrite32(DISPC_GFX_ATTR, (GFXENABLE | RGB16 | BURSTSIZE16));\r
195\r
196 // Start it all\r
197 MmioOr32 (DISPC_CONTROL, (LCDENABLE | ACTIVEMATRIX | DATALINES24 | BYPASS_MODE | LCDENABLESIGNAL));\r
198 MmioOr32 (DISPC_CONTROL, GOLCD);\r
199\r
200 return EFI_SUCCESS;\r
201}\r
202\r
203EFI_STATUS\r
204HwInitializeDisplay (\r
205 UINTN VramBaseAddress,\r
206 UINTN VramSize\r
207 )\r
208{\r
209 EFI_STATUS Status;\r
210 UINT8 Data;\r
211 EFI_TPL OldTpl;\r
212 EMBEDDED_EXTERNAL_DEVICE *gTPS65950;\r
213\r
214 // Enable power lines used by TFP410\r
215 Status = gBS->LocateProtocol (&gEmbeddedExternalDeviceProtocolGuid, NULL, (VOID **)&gTPS65950);\r
3402aac7 216 ASSERT_EFI_ERROR (Status);\r
1e57a462 217\r
218 OldTpl = gBS->RaiseTPL(TPL_NOTIFY);\r
219 Data = VAUX_DEV_GRP_P1;\r
220 Status = gTPS65950->Write (gTPS65950, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID4, VPLL2_DEV_GRP), 1, &Data);\r
221 ASSERT_EFI_ERROR(Status);\r
222\r
223 Data = VAUX_DEDICATED_18V;\r
224 Status = gTPS65950->Write (gTPS65950, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID4, VPLL2_DEDICATED), 1, &Data);\r
3402aac7 225 ASSERT_EFI_ERROR (Status);\r
1e57a462 226\r
227 // Power up TFP410 (set GPIO2 on TPS - for BeagleBoard-xM)\r
228 Status = gTPS65950->Read (gTPS65950, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID2, GPIODATADIR1), 1, &Data);\r
229 ASSERT_EFI_ERROR (Status);\r
230 Data |= BIT2;\r
231 Status = gTPS65950->Write (gTPS65950, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID2, GPIODATADIR1), 1, &Data);\r
232 ASSERT_EFI_ERROR (Status);\r
233\r
234 Data = BIT2;\r
235 Status = gTPS65950->Write (gTPS65950, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID2, SETGPIODATAOUT1), 1, &Data);\r
236 ASSERT_EFI_ERROR (Status);\r
237\r
238 gBS->RestoreTPL(OldTpl);\r
239\r
240 // Power up TFP410 (set GPIO 170 - for older BeagleBoards)\r
241 MmioAnd32 (GPIO6_BASE + GPIO_OE, ~BIT10);\r
3402aac7 242 MmioOr32 (GPIO6_BASE + GPIO_SETDATAOUT, BIT10);\r
1e57a462 243\r
244 return EFI_SUCCESS;\r
245}\r
246\r
247EFI_STATUS\r
248InitializeDisplay (\r
249 IN LCD_INSTANCE* Instance\r
250 )\r
251{\r
3402aac7 252 EFI_STATUS Status;\r
1e57a462 253 UINTN VramSize;\r
254 EFI_PHYSICAL_ADDRESS VramBaseAddress;\r
255\r
256 Status = LcdPlatformGetVram (&VramBaseAddress, &VramSize);\r
257 if (EFI_ERROR (Status)) {\r
258 return Status;\r
259 }\r
260\r
261 Instance->Mode.FrameBufferBase = VramBaseAddress;\r
262 Instance->Mode.FrameBufferSize = VramSize;\r
263\r
264 Status = HwInitializeDisplay((UINTN)VramBaseAddress, VramSize);\r
265 if (!EFI_ERROR (Status)) {\r
266 mDisplayInitialized = TRUE;\r
267 }\r
268\r
269 return Status;\r
270}\r
271\r
272EFI_STATUS\r
273EFIAPI\r
274LcdGraphicsQueryMode (\r
275 IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This,\r
91c38d4e
RC
276 IN UINT32 ModeNumber,\r
277 OUT UINTN *SizeOfInfo,\r
278 OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION **Info\r
279 )\r
1e57a462 280{\r
91c38d4e 281 LCD_INSTANCE *Instance;\r
1e57a462 282\r
91c38d4e 283 Instance = LCD_INSTANCE_FROM_GOP_THIS(This);\r
1e57a462 284\r
285 if (!mDisplayInitialized) {\r
286 InitializeDisplay (Instance);\r
287 }\r
288\r
289 // Error checking\r
91c38d4e
RC
290 if ( (This == NULL) || (Info == NULL) || (SizeOfInfo == NULL) || (ModeNumber >= This->Mode->MaxMode) ) {\r
291 DEBUG((DEBUG_ERROR, "LcdGraphicsQueryMode: ERROR - For mode number %d : Invalid Parameter.\n", ModeNumber ));\r
292 return EFI_INVALID_PARAMETER;\r
293 }\r
1e57a462 294\r
295 *Info = AllocateCopyPool(sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION), &Instance->ModeInfo);\r
296 if (*Info == NULL) {\r
297 return EFI_OUT_OF_RESOURCES;\r
298 }\r
299\r
300 *SizeOfInfo = sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION);\r
301\r
302 (*Info)->Version = 0;\r
303 (*Info)->HorizontalResolution = LcdModes[ModeNumber].HorizontalResolution;\r
304 (*Info)->VerticalResolution = LcdModes[ModeNumber].VerticalResolution;\r
305 (*Info)->PixelFormat = PixelBltOnly;\r
306\r
307 return EFI_SUCCESS;\r
308}\r
309\r
310EFI_STATUS\r
311EFIAPI\r
312LcdGraphicsSetMode (\r
313 IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This,\r
91c38d4e
RC
314 IN UINT32 ModeNumber\r
315 )\r
1e57a462 316{\r
91c38d4e 317 LCD_INSTANCE *Instance;\r
1e57a462 318\r
91c38d4e 319 Instance = LCD_INSTANCE_FROM_GOP_THIS(This);\r
1e57a462 320\r
321 if (ModeNumber >= Instance->Mode.MaxMode) {\r
322 return EFI_UNSUPPORTED;\r
323 }\r
324\r
325 if (!mDisplayInitialized) {\r
326 InitializeDisplay (Instance);\r
327 }\r
328\r
329 DssSetMode((UINT32)Instance->Mode.FrameBufferBase, ModeNumber);\r
330\r
331 Instance->Mode.Mode = ModeNumber;\r
332 Instance->ModeInfo.HorizontalResolution = LcdModes[ModeNumber].HorizontalResolution;\r
333 Instance->ModeInfo.VerticalResolution = LcdModes[ModeNumber].VerticalResolution;\r
334\r
335 return EFI_SUCCESS;\r
336}\r
337\r
338EFI_STATUS\r
339EFIAPI\r
340LcdGraphicsOutputDxeInitialize (\r
341 IN EFI_HANDLE ImageHandle,\r
342 IN EFI_SYSTEM_TABLE *SystemTable\r
343 )\r
344{\r
345 EFI_STATUS Status = EFI_SUCCESS;\r
346 LCD_INSTANCE* Instance;\r
347\r
348 Status = LcdInstanceContructor (&Instance);\r
349 if (EFI_ERROR(Status)) {\r
350 goto EXIT;\r
351 }\r
352\r
91c38d4e
RC
353 // Install the Graphics Output Protocol and the Device Path\r
354 Status = gBS->InstallMultipleProtocolInterfaces(\r
355 &Instance->Handle,\r
356 &gEfiGraphicsOutputProtocolGuid, &Instance->Gop,\r
357 &gEfiDevicePathProtocolGuid, &Instance->DevicePath,\r
358 NULL\r
359 );\r
1e57a462 360\r
91c38d4e
RC
361 if (EFI_ERROR(Status)) {\r
362 DEBUG((DEBUG_ERROR, "GraphicsOutputDxeInitialize: Can not install the protocol. Exit Status=%r\n", Status));\r
363 goto EXIT;\r
364 }\r
1e57a462 365\r
366 // Register for an ExitBootServicesEvent\r
91c38d4e
RC
367 // When ExitBootServices starts, this function here will make sure that the graphics driver will shut down properly,\r
368 // i.e. it will free up all allocated memory and perform any necessary hardware re-configuration.\r
369 /*Status = gBS->CreateEvent (\r
370 EVT_SIGNAL_EXIT_BOOT_SERVICES,\r
371 TPL_NOTIFY,\r
372 LcdGraphicsExitBootServicesEvent, NULL,\r
373 &Instance->ExitBootServicesEvent\r
374 );\r
375\r
376 if (EFI_ERROR(Status)) {\r
377 DEBUG((DEBUG_ERROR, "GraphicsOutputDxeInitialize: Can not install the ExitBootServicesEvent handler. Exit Status=%r\n", Status));\r
378 goto EXIT_ERROR_UNINSTALL_PROTOCOL;\r
379 }*/\r
380\r
381 // To get here, everything must be fine, so just exit\r
382 goto EXIT;\r
1e57a462 383\r
384//EXIT_ERROR_UNINSTALL_PROTOCOL:\r
91c38d4e
RC
385 /* The following function could return an error message,\r
386 * however, to get here something must have gone wrong already,\r
387 * so preserve the original error, i.e. don't change\r
388 * the Status variable, even it fails to uninstall the protocol.\r
389 */\r
390 /* gBS->UninstallMultipleProtocolInterfaces (\r
391 Instance->Handle,\r
392 &gEfiGraphicsOutputProtocolGuid, &Instance->Gop, // Uninstall Graphics Output protocol\r
393 &gEfiDevicePathProtocolGuid, &Instance->DevicePath, // Uninstall device path\r
394 NULL\r
395 );*/\r
1e57a462 396\r
397EXIT:\r
91c38d4e 398 return Status;\r
1e57a462 399\r
400}\r