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