]> git.proxmox.com Git - mirror_edk2.git/blame - ArmPlatformPkg/ArmVExpressPkg/Library/PL111LcdArmVExpressLib/PL111LcdArmVExpress.c
ArmPlatformPkg/LcdPlatformLib: Produce the protocols EFI_EDID_DISCOVERED_PROTOCOL...
[mirror_edk2.git] / ArmPlatformPkg / ArmVExpressPkg / Library / PL111LcdArmVExpressLib / PL111LcdArmVExpress.c
CommitLineData
7d0f2f23 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 <PiDxe.h>\r
15\r
16#include <Library/ArmPlatformSysConfigLib.h>\r
17#include <Library/IoLib.h>\r
18#include <Library/PcdLib.h>\r
19#include <Library/DebugLib.h>\r
20#include <Library/LcdPlatformLib.h>\r
21#include <Library/UefiBootServicesTableLib.h>\r
22\r
23#include <Protocol/Cpu.h>\r
6d8d7363 24#include <Protocol/EdidDiscovered.h>\r
25#include <Protocol/EdidActive.h>\r
7d0f2f23 26\r
27#include <ArmPlatform.h>\r
28\r
7d0f2f23 29typedef struct {\r
30 UINT32 Mode;\r
31 UINT32 HorizontalResolution;\r
32 UINT32 VerticalResolution;\r
33 LCD_BPP Bpp;\r
34 UINT32 OscFreq;\r
35\r
36 UINT32 HSync;\r
37 UINT32 HBackPorch;\r
38 UINT32 HFrontPorch;\r
39 UINT32 VSync;\r
40 UINT32 VBackPorch;\r
41 UINT32 VFrontPorch;\r
42} LCD_RESOLUTION;\r
43\r
44\r
45LCD_RESOLUTION mResolutions[] = {\r
6d8d7363 46 { // Mode 0 : VGA : 640 x 480 x 24 bpp\r
47 VGA, VGA_H_RES_PIXELS, VGA_V_RES_PIXELS, LCD_BITS_PER_PIXEL_24, VGA_OSC_FREQUENCY,\r
48 VGA_H_SYNC, VGA_H_BACK_PORCH, VGA_H_FRONT_PORCH,\r
49 VGA_V_SYNC, VGA_V_BACK_PORCH, VGA_V_FRONT_PORCH\r
50 },\r
51 { // Mode 1 : SVGA : 800 x 600 x 24 bpp\r
52 SVGA, SVGA_H_RES_PIXELS, SVGA_V_RES_PIXELS, LCD_BITS_PER_PIXEL_24, SVGA_OSC_FREQUENCY,\r
53 SVGA_H_SYNC, SVGA_H_BACK_PORCH, SVGA_H_FRONT_PORCH,\r
54 SVGA_V_SYNC, SVGA_V_BACK_PORCH, SVGA_V_FRONT_PORCH\r
55 },\r
56 { // Mode 2 : XGA : 1024 x 768 x 24 bpp\r
57 XGA, XGA_H_RES_PIXELS, XGA_V_RES_PIXELS, LCD_BITS_PER_PIXEL_24, XGA_OSC_FREQUENCY,\r
58 XGA_H_SYNC, XGA_H_BACK_PORCH, XGA_H_FRONT_PORCH,\r
59 XGA_V_SYNC, XGA_V_BACK_PORCH, XGA_V_FRONT_PORCH\r
60 },\r
61 { // Mode 3 : SXGA : 1280 x 1024 x 24 bpp\r
62 SXGA, SXGA_H_RES_PIXELS, SXGA_V_RES_PIXELS, LCD_BITS_PER_PIXEL_24, (SXGA_OSC_FREQUENCY/2),\r
63 SXGA_H_SYNC, SXGA_H_BACK_PORCH, SXGA_H_FRONT_PORCH,\r
64 SXGA_V_SYNC, SXGA_V_BACK_PORCH, SXGA_V_FRONT_PORCH\r
65 },\r
66 { // Mode 4 : UXGA : 1600 x 1200 x 24 bpp\r
67 UXGA, UXGA_H_RES_PIXELS, UXGA_V_RES_PIXELS, LCD_BITS_PER_PIXEL_24, (UXGA_OSC_FREQUENCY/2),\r
68 UXGA_H_SYNC, UXGA_H_BACK_PORCH, UXGA_H_FRONT_PORCH,\r
69 UXGA_V_SYNC, UXGA_V_BACK_PORCH, UXGA_V_FRONT_PORCH\r
70 },\r
71 { // Mode 5 : HD : 1920 x 1080 x 24 bpp\r
72 HD, HD_H_RES_PIXELS, HD_V_RES_PIXELS, LCD_BITS_PER_PIXEL_24, (HD_OSC_FREQUENCY/2),\r
73 HD_H_SYNC, HD_H_BACK_PORCH, HD_H_FRONT_PORCH,\r
74 HD_V_SYNC, HD_V_BACK_PORCH, HD_V_FRONT_PORCH\r
75 },\r
76 { // Mode 6 : VGA : 640 x 480 x 16 bpp (565 Mode)\r
77 VGA, VGA_H_RES_PIXELS, VGA_V_RES_PIXELS, LCD_BITS_PER_PIXEL_16_565, VGA_OSC_FREQUENCY,\r
78 VGA_H_SYNC, VGA_H_BACK_PORCH, VGA_H_FRONT_PORCH,\r
79 VGA_V_SYNC, VGA_V_BACK_PORCH, VGA_V_FRONT_PORCH\r
80 },\r
81 { // Mode 7 : SVGA : 800 x 600 x 16 bpp (565 Mode)\r
82 SVGA, SVGA_H_RES_PIXELS, SVGA_V_RES_PIXELS, LCD_BITS_PER_PIXEL_16_565, SVGA_OSC_FREQUENCY,\r
83 SVGA_H_SYNC, SVGA_H_BACK_PORCH, SVGA_H_FRONT_PORCH,\r
84 SVGA_V_SYNC, SVGA_V_BACK_PORCH, SVGA_V_FRONT_PORCH\r
85 },\r
86 { // Mode 8 : XGA : 1024 x 768 x 16 bpp (565 Mode)\r
87 XGA, XGA_H_RES_PIXELS, XGA_V_RES_PIXELS, LCD_BITS_PER_PIXEL_16_565, XGA_OSC_FREQUENCY,\r
88 XGA_H_SYNC, XGA_H_BACK_PORCH, XGA_H_FRONT_PORCH,\r
89 XGA_V_SYNC, XGA_V_BACK_PORCH, XGA_V_FRONT_PORCH\r
90 },\r
91 { // Mode 9 : VGA : 640 x 480 x 15 bpp\r
92 VGA, VGA_H_RES_PIXELS, VGA_V_RES_PIXELS, LCD_BITS_PER_PIXEL_16_555, VGA_OSC_FREQUENCY,\r
93 VGA_H_SYNC, VGA_H_BACK_PORCH, VGA_H_FRONT_PORCH,\r
94 VGA_V_SYNC, VGA_V_BACK_PORCH, VGA_V_FRONT_PORCH\r
95 },\r
96 { // Mode 10 : SVGA : 800 x 600 x 15 bpp\r
97 SVGA, SVGA_H_RES_PIXELS, SVGA_V_RES_PIXELS, LCD_BITS_PER_PIXEL_16_555, SVGA_OSC_FREQUENCY,\r
98 SVGA_H_SYNC, SVGA_H_BACK_PORCH, SVGA_H_FRONT_PORCH,\r
99 SVGA_V_SYNC, SVGA_V_BACK_PORCH, SVGA_V_FRONT_PORCH\r
100 },\r
101 { // Mode 11 : XGA : 1024 x 768 x 15 bpp\r
102 XGA, XGA_H_RES_PIXELS, XGA_V_RES_PIXELS, LCD_BITS_PER_PIXEL_16_555, XGA_OSC_FREQUENCY,\r
103 XGA_H_SYNC, XGA_H_BACK_PORCH, XGA_H_FRONT_PORCH,\r
104 XGA_V_SYNC, XGA_V_BACK_PORCH, XGA_V_FRONT_PORCH\r
105 },\r
106 { // Mode 12 : XGA : 1024 x 768 x 15 bpp - All the timing info is derived from Linux Kernel Driver Settings\r
107 XGA, XGA_H_RES_PIXELS, XGA_V_RES_PIXELS, LCD_BITS_PER_PIXEL_16_555, 63500000,\r
108 XGA_H_SYNC, XGA_H_BACK_PORCH, XGA_H_FRONT_PORCH,\r
109 XGA_V_SYNC, XGA_V_BACK_PORCH, XGA_V_FRONT_PORCH\r
110 },\r
111 { // Mode 13 : VGA : 640 x 480 x 12 bpp (444 Mode)\r
112 VGA, VGA_H_RES_PIXELS, VGA_V_RES_PIXELS, LCD_BITS_PER_PIXEL_12_444, VGA_OSC_FREQUENCY,\r
113 VGA_H_SYNC, VGA_H_BACK_PORCH, VGA_H_FRONT_PORCH,\r
114 VGA_V_SYNC, VGA_V_BACK_PORCH, VGA_V_FRONT_PORCH\r
115 },\r
116 { // Mode 14 : SVGA : 800 x 600 x 12 bpp (444 Mode)\r
117 SVGA, SVGA_H_RES_PIXELS, SVGA_V_RES_PIXELS, LCD_BITS_PER_PIXEL_12_444, SVGA_OSC_FREQUENCY,\r
118 SVGA_H_SYNC, SVGA_H_BACK_PORCH, SVGA_H_FRONT_PORCH,\r
119 SVGA_V_SYNC, SVGA_V_BACK_PORCH, SVGA_V_FRONT_PORCH\r
120 },\r
121 { // Mode 15 : XGA : 1024 x 768 x 12 bpp (444 Mode)\r
122 XGA, XGA_H_RES_PIXELS, XGA_V_RES_PIXELS, LCD_BITS_PER_PIXEL_12_444, XGA_OSC_FREQUENCY,\r
123 XGA_H_SYNC, XGA_H_BACK_PORCH, XGA_H_FRONT_PORCH,\r
124 XGA_V_SYNC, XGA_V_BACK_PORCH, XGA_V_FRONT_PORCH\r
125 }\r
7d0f2f23 126};\r
127\r
6d8d7363 128EFI_EDID_DISCOVERED_PROTOCOL mEdidDiscovered = {\r
129 0,\r
130 NULL\r
131};\r
132\r
133EFI_EDID_ACTIVE_PROTOCOL mEdidActive = {\r
134 0,\r
135 NULL\r
136};\r
137\r
138\r
7d0f2f23 139EFI_STATUS\r
140LcdPlatformInitializeDisplay (\r
6d8d7363 141 IN EFI_HANDLE Handle\r
142 )\r
143{\r
144 EFI_STATUS Status;\r
145\r
7d0f2f23 146 // Set the FPGA multiplexer to select the video output from the motherboard or the daughterboard\r
6d8d7363 147 Status = ArmPlatformSysConfigSet (SYS_CFG_MUXFPGA, PL111_CLCD_SITE);\r
148 if (!EFI_ERROR(Status)) {\r
149 // Install the EDID Protocols\r
150 Status = gBS->InstallMultipleProtocolInterfaces(\r
151 &Handle,\r
152 &gEfiEdidDiscoveredProtocolGuid, &mEdidDiscovered,\r
153 &gEfiEdidActiveProtocolGuid, &mEdidActive,\r
154 NULL\r
155 );\r
156 }\r
157\r
158 return Status;\r
7d0f2f23 159}\r
160\r
161EFI_STATUS\r
162LcdPlatformGetVram (\r
163 OUT EFI_PHYSICAL_ADDRESS* VramBaseAddress,\r
164 OUT UINTN* VramSize\r
165 )\r
166{\r
167 EFI_STATUS Status;\r
168 EFI_CPU_ARCH_PROTOCOL *Cpu;\r
169\r
11c20f4e 170 Status = EFI_SUCCESS;\r
171\r
7d0f2f23 172 // Is it on the motherboard or on the daughterboard?\r
173 switch(PL111_CLCD_SITE) {\r
174\r
175 case ARM_VE_MOTHERBOARD_SITE:\r
176 *VramBaseAddress = (EFI_PHYSICAL_ADDRESS) PL111_CLCD_VRAM_MOTHERBOARD_BASE;\r
177 *VramSize = LCD_VRAM_SIZE;\r
178 break;\r
179\r
180 case ARM_VE_DAUGHTERBOARD_1_SITE:\r
181 *VramBaseAddress = (EFI_PHYSICAL_ADDRESS) LCD_VRAM_CORE_TILE_BASE;\r
182 *VramSize = LCD_VRAM_SIZE;\r
183\r
184 // Allocate the VRAM from the DRAM so that nobody else uses it.\r
185 Status = gBS->AllocatePages( AllocateAddress, EfiBootServicesData, EFI_SIZE_TO_PAGES(((UINTN)LCD_VRAM_SIZE)), VramBaseAddress);\r
186 if (EFI_ERROR(Status)) {\r
187 return Status;\r
188 }\r
189\r
190 // Ensure the Cpu architectural protocol is already installed\r
191 Status = gBS->LocateProtocol (&gEfiCpuArchProtocolGuid, NULL, (VOID **)&Cpu);\r
192 ASSERT_EFI_ERROR(Status);\r
193\r
194 // Mark the VRAM as un-cachable. The VRAM is inside the DRAM, which is cachable.\r
195 Status = Cpu->SetMemoryAttributes(Cpu, *VramBaseAddress, *VramSize, EFI_MEMORY_UC);\r
196 ASSERT_EFI_ERROR(Status);\r
197 if (EFI_ERROR(Status)) {\r
198 gBS->FreePool(VramBaseAddress);\r
199 return Status;\r
200 }\r
201 break;\r
202\r
203 default:\r
204 // Unsupported site\r
205 Status = EFI_UNSUPPORTED;\r
206 break;\r
207 }\r
208\r
209 return Status;\r
210}\r
211\r
212UINT32\r
213LcdPlatformGetMaxMode (\r
214 VOID\r
215 )\r
216{\r
217 // The following line will report correctly the total number of graphics modes\r
218 // supported by the PL111CLCD.\r
219 //return (sizeof(mResolutions) / sizeof(CLCD_RESOLUTION)) - 1;\r
220\r
221 // However, on some platforms it is desirable to ignore some graphics modes.\r
222 // This could be because the specific implementation of PL111 has certain limitations.\r
223\r
224 // Set the maximum mode allowed\r
5cc45b70 225 return (PcdGet32(PcdPL111LcdMaxMode));\r
7d0f2f23 226}\r
227\r
228EFI_STATUS\r
229LcdPlatformSetMode (\r
230 IN UINT32 ModeNumber\r
231 )\r
232{\r
233 EFI_STATUS Status;\r
234 UINT32 LcdSite;\r
235 UINT32 OscillatorId;\r
236 SYS_CONFIG_FUNCTION Function;\r
237\r
238 if (ModeNumber >= LcdPlatformGetMaxMode ()) {\r
239 return EFI_INVALID_PARAMETER;\r
240 }\r
241\r
242 LcdSite = PL111_CLCD_SITE;\r
243\r
244 switch(LcdSite) {\r
245 case ARM_VE_MOTHERBOARD_SITE:\r
246 Function = SYS_CFG_OSC;\r
247 OscillatorId = PL111_CLCD_MOTHERBOARD_VIDEO_MODE_OSC_ID;\r
248 break;\r
249 case ARM_VE_DAUGHTERBOARD_1_SITE:\r
250 Function = SYS_CFG_OSC_SITE1;\r
5cc45b70 251 OscillatorId = (UINT32)PcdGet32(PcdPL111LcdVideoModeOscId);\r
7d0f2f23 252 break;\r
253 default:\r
254 return EFI_UNSUPPORTED;\r
255 }\r
256\r
257 // Set the video mode oscillator\r
258 Status = ArmPlatformSysConfigSetDevice (Function, OscillatorId, mResolutions[ModeNumber].OscFreq);\r
259 if (EFI_ERROR(Status)) {\r
260 ASSERT_EFI_ERROR (Status);\r
261 return Status;\r
262 }\r
263\r
1ddb209e 264 // On the ARM Versatile Express Model (RTSM) the value of the SysId is equal to 0x225F500.\r
265 // Note: The DVI Mode is not modelled on RTSM\r
266 if (MmioRead32 (ARM_VE_SYS_ID_REG) != 0x225F500) {\r
267 // Set the DVI into the new mode\r
268 Status = ArmPlatformSysConfigSet (SYS_CFG_DVIMODE, mResolutions[ModeNumber].Mode);\r
269 if (EFI_ERROR(Status)) {\r
270 ASSERT_EFI_ERROR (Status);\r
271 return Status;\r
272 }\r
7d0f2f23 273 }\r
274\r
275 // Set the multiplexer\r
276 Status = ArmPlatformSysConfigSet (SYS_CFG_MUXFPGA, LcdSite);\r
277 if (EFI_ERROR(Status)) {\r
278 ASSERT_EFI_ERROR (Status);\r
279 return Status;\r
280 }\r
281\r
282 return Status;\r
283}\r
284\r
285EFI_STATUS\r
286LcdPlatformQueryMode (\r
287 IN UINT32 ModeNumber,\r
288 OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info\r
289 )\r
290{\r
291 if (ModeNumber >= LcdPlatformGetMaxMode ()) {\r
292 return EFI_INVALID_PARAMETER;\r
293 }\r
294\r
295 Info->Version = 0;\r
296 Info->HorizontalResolution = mResolutions[ModeNumber].HorizontalResolution;\r
297 Info->VerticalResolution = mResolutions[ModeNumber].VerticalResolution;\r
298 Info->PixelsPerScanLine = mResolutions[ModeNumber].HorizontalResolution;\r
299\r
300 switch (mResolutions[ModeNumber].Bpp) {\r
301 case LCD_BITS_PER_PIXEL_24:\r
302 Info->PixelFormat = PixelRedGreenBlueReserved8BitPerColor;\r
303 Info->PixelInformation.RedMask = LCD_24BPP_RED_MASK;\r
304 Info->PixelInformation.GreenMask = LCD_24BPP_GREEN_MASK;\r
305 Info->PixelInformation.BlueMask = LCD_24BPP_BLUE_MASK;\r
306 Info->PixelInformation.ReservedMask = LCD_24BPP_RESERVED_MASK;\r
307 break;\r
308\r
309 case LCD_BITS_PER_PIXEL_16_555:\r
310 case LCD_BITS_PER_PIXEL_16_565:\r
311 case LCD_BITS_PER_PIXEL_12_444:\r
312 case LCD_BITS_PER_PIXEL_8:\r
313 case LCD_BITS_PER_PIXEL_4:\r
314 case LCD_BITS_PER_PIXEL_2:\r
315 case LCD_BITS_PER_PIXEL_1:\r
316 default:\r
317 // These are not supported\r
318 ASSERT(FALSE);\r
319 break;\r
320 }\r
321\r
322 return EFI_SUCCESS;\r
323}\r
324\r
325EFI_STATUS\r
326LcdPlatformGetTimings (\r
327 IN UINT32 ModeNumber,\r
328 OUT UINT32* HRes,\r
329 OUT UINT32* HSync,\r
330 OUT UINT32* HBackPorch,\r
331 OUT UINT32* HFrontPorch,\r
332 OUT UINT32* VRes,\r
333 OUT UINT32* VSync,\r
334 OUT UINT32* VBackPorch,\r
335 OUT UINT32* VFrontPorch\r
336 )\r
337{\r
338 if (ModeNumber >= LcdPlatformGetMaxMode ()) {\r
339 return EFI_INVALID_PARAMETER;\r
340 }\r
341\r
342 *HRes = mResolutions[ModeNumber].HorizontalResolution;\r
343 *HSync = mResolutions[ModeNumber].HSync;\r
344 *HBackPorch = mResolutions[ModeNumber].HBackPorch;\r
345 *HFrontPorch = mResolutions[ModeNumber].HFrontPorch;\r
346 *VRes = mResolutions[ModeNumber].VerticalResolution;\r
347 *VSync = mResolutions[ModeNumber].VSync;\r
348 *VBackPorch = mResolutions[ModeNumber].VBackPorch;\r
349 *VFrontPorch = mResolutions[ModeNumber].VFrontPorch;\r
350\r
351 return EFI_SUCCESS;\r
352}\r
353\r
354EFI_STATUS\r
355LcdPlatformGetBpp (\r
356 IN UINT32 ModeNumber,\r
357 OUT LCD_BPP * Bpp\r
358 )\r
359{\r
360 if (ModeNumber >= LcdPlatformGetMaxMode ()) {\r
361 return EFI_INVALID_PARAMETER;\r
362 }\r
363\r
364 *Bpp = mResolutions[ModeNumber].Bpp;\r
365\r
366 return EFI_SUCCESS;\r
367}\r