]> git.proxmox.com Git - mirror_edk2.git/blame - ArmPlatformPkg/ArmVExpressPkg/Library/PL111LcdArmVExpressLib/PL111LcdArmVExpress.c
ArmPlatformPkg/PL111LcdArmVExpressLib: use write-combine mapping for VRAM
[mirror_edk2.git] / ArmPlatformPkg / ArmVExpressPkg / Library / PL111LcdArmVExpressLib / PL111LcdArmVExpress.c
CommitLineData
7d0f2f23 1/** @file\r
2\r
d0c1d371 3 Copyright (c) 2011-2015, ARM Ltd. All rights reserved.<BR>\r
7d0f2f23 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
a30d5f9f 20#include <Library/DxeServicesTableLib.h>\r
7d0f2f23 21#include <Library/LcdPlatformLib.h>\r
22#include <Library/UefiBootServicesTableLib.h>\r
23\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
7d0f2f23 168\r
11c20f4e 169 Status = EFI_SUCCESS;\r
170\r
7d0f2f23 171 // Is it on the motherboard or on the daughterboard?\r
172 switch(PL111_CLCD_SITE) {\r
173\r
174 case ARM_VE_MOTHERBOARD_SITE:\r
175 *VramBaseAddress = (EFI_PHYSICAL_ADDRESS) PL111_CLCD_VRAM_MOTHERBOARD_BASE;\r
176 *VramSize = LCD_VRAM_SIZE;\r
177 break;\r
178\r
179 case ARM_VE_DAUGHTERBOARD_1_SITE:\r
180 *VramBaseAddress = (EFI_PHYSICAL_ADDRESS) LCD_VRAM_CORE_TILE_BASE;\r
181 *VramSize = LCD_VRAM_SIZE;\r
182\r
183 // Allocate the VRAM from the DRAM so that nobody else uses it.\r
184 Status = gBS->AllocatePages( AllocateAddress, EfiBootServicesData, EFI_SIZE_TO_PAGES(((UINTN)LCD_VRAM_SIZE)), VramBaseAddress);\r
185 if (EFI_ERROR(Status)) {\r
186 return Status;\r
187 }\r
188\r
a30d5f9f
AB
189 // Mark the VRAM as write-combining. The VRAM is inside the DRAM, which is cacheable.\r
190 Status = gDS->SetMemorySpaceAttributes (*VramBaseAddress, *VramSize,\r
191 EFI_MEMORY_WC);\r
7d0f2f23 192 ASSERT_EFI_ERROR(Status);\r
193 if (EFI_ERROR(Status)) {\r
1fe11382 194 gBS->FreePages (*VramBaseAddress, EFI_SIZE_TO_PAGES(*VramSize));\r
7d0f2f23 195 return Status;\r
196 }\r
197 break;\r
198\r
199 default:\r
200 // Unsupported site\r
201 Status = EFI_UNSUPPORTED;\r
202 break;\r
203 }\r
204\r
205 return Status;\r
206}\r
207\r
208UINT32\r
209LcdPlatformGetMaxMode (\r
210 VOID\r
211 )\r
212{\r
213 // The following line will report correctly the total number of graphics modes\r
214 // supported by the PL111CLCD.\r
215 //return (sizeof(mResolutions) / sizeof(CLCD_RESOLUTION)) - 1;\r
216\r
217 // However, on some platforms it is desirable to ignore some graphics modes.\r
218 // This could be because the specific implementation of PL111 has certain limitations.\r
219\r
220 // Set the maximum mode allowed\r
5cc45b70 221 return (PcdGet32(PcdPL111LcdMaxMode));\r
7d0f2f23 222}\r
223\r
224EFI_STATUS\r
225LcdPlatformSetMode (\r
226 IN UINT32 ModeNumber\r
227 )\r
228{\r
229 EFI_STATUS Status;\r
230 UINT32 LcdSite;\r
231 UINT32 OscillatorId;\r
232 SYS_CONFIG_FUNCTION Function;\r
48999d26 233 UINT32 SysId;\r
7d0f2f23 234\r
235 if (ModeNumber >= LcdPlatformGetMaxMode ()) {\r
236 return EFI_INVALID_PARAMETER;\r
237 }\r
238\r
239 LcdSite = PL111_CLCD_SITE;\r
240\r
241 switch(LcdSite) {\r
242 case ARM_VE_MOTHERBOARD_SITE:\r
243 Function = SYS_CFG_OSC;\r
244 OscillatorId = PL111_CLCD_MOTHERBOARD_VIDEO_MODE_OSC_ID;\r
245 break;\r
246 case ARM_VE_DAUGHTERBOARD_1_SITE:\r
247 Function = SYS_CFG_OSC_SITE1;\r
5cc45b70 248 OscillatorId = (UINT32)PcdGet32(PcdPL111LcdVideoModeOscId);\r
7d0f2f23 249 break;\r
250 default:\r
251 return EFI_UNSUPPORTED;\r
252 }\r
253\r
254 // Set the video mode oscillator\r
255 Status = ArmPlatformSysConfigSetDevice (Function, OscillatorId, mResolutions[ModeNumber].OscFreq);\r
256 if (EFI_ERROR(Status)) {\r
257 ASSERT_EFI_ERROR (Status);\r
258 return Status;\r
259 }\r
260\r
48999d26
OM
261 // The FVP foundation model does not have an LCD.\r
262 // On the FVP models the GIC variant in encoded in bits [15:12].\r
263 // Note: The DVI Mode is not modelled by RTSM or FVP models.\r
264 SysId = MmioRead32 (ARM_VE_SYS_ID_REG);\r
265 if (SysId != ARM_RTSM_SYS_ID) {\r
266 // Take out the FVP GIC variant to reduce the permutations.\r
267 SysId &= ~ARM_FVP_SYS_ID_VARIANT_MASK;\r
d0c1d371 268 if (SysId != ARM_FVP_BASE_BOARD_SYS_ID) {\r
48999d26
OM
269 // Set the DVI into the new mode\r
270 Status = ArmPlatformSysConfigSet (SYS_CFG_DVIMODE, mResolutions[ModeNumber].Mode);\r
271 if (EFI_ERROR(Status)) {\r
272 ASSERT_EFI_ERROR (Status);\r
273 return Status;\r
274 }\r
1ddb209e 275 }\r
7d0f2f23 276 }\r
277\r
278 // Set the multiplexer\r
279 Status = ArmPlatformSysConfigSet (SYS_CFG_MUXFPGA, LcdSite);\r
280 if (EFI_ERROR(Status)) {\r
281 ASSERT_EFI_ERROR (Status);\r
282 return Status;\r
283 }\r
284\r
285 return Status;\r
286}\r
287\r
288EFI_STATUS\r
289LcdPlatformQueryMode (\r
290 IN UINT32 ModeNumber,\r
291 OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info\r
292 )\r
293{\r
294 if (ModeNumber >= LcdPlatformGetMaxMode ()) {\r
295 return EFI_INVALID_PARAMETER;\r
296 }\r
297\r
298 Info->Version = 0;\r
299 Info->HorizontalResolution = mResolutions[ModeNumber].HorizontalResolution;\r
300 Info->VerticalResolution = mResolutions[ModeNumber].VerticalResolution;\r
301 Info->PixelsPerScanLine = mResolutions[ModeNumber].HorizontalResolution;\r
302\r
303 switch (mResolutions[ModeNumber].Bpp) {\r
304 case LCD_BITS_PER_PIXEL_24:\r
305 Info->PixelFormat = PixelRedGreenBlueReserved8BitPerColor;\r
306 Info->PixelInformation.RedMask = LCD_24BPP_RED_MASK;\r
307 Info->PixelInformation.GreenMask = LCD_24BPP_GREEN_MASK;\r
308 Info->PixelInformation.BlueMask = LCD_24BPP_BLUE_MASK;\r
309 Info->PixelInformation.ReservedMask = LCD_24BPP_RESERVED_MASK;\r
310 break;\r
311\r
312 case LCD_BITS_PER_PIXEL_16_555:\r
313 case LCD_BITS_PER_PIXEL_16_565:\r
314 case LCD_BITS_PER_PIXEL_12_444:\r
315 case LCD_BITS_PER_PIXEL_8:\r
316 case LCD_BITS_PER_PIXEL_4:\r
317 case LCD_BITS_PER_PIXEL_2:\r
318 case LCD_BITS_PER_PIXEL_1:\r
319 default:\r
320 // These are not supported\r
321 ASSERT(FALSE);\r
322 break;\r
323 }\r
324\r
325 return EFI_SUCCESS;\r
326}\r
327\r
328EFI_STATUS\r
329LcdPlatformGetTimings (\r
330 IN UINT32 ModeNumber,\r
331 OUT UINT32* HRes,\r
332 OUT UINT32* HSync,\r
333 OUT UINT32* HBackPorch,\r
334 OUT UINT32* HFrontPorch,\r
335 OUT UINT32* VRes,\r
336 OUT UINT32* VSync,\r
337 OUT UINT32* VBackPorch,\r
338 OUT UINT32* VFrontPorch\r
339 )\r
340{\r
341 if (ModeNumber >= LcdPlatformGetMaxMode ()) {\r
342 return EFI_INVALID_PARAMETER;\r
343 }\r
344\r
345 *HRes = mResolutions[ModeNumber].HorizontalResolution;\r
346 *HSync = mResolutions[ModeNumber].HSync;\r
347 *HBackPorch = mResolutions[ModeNumber].HBackPorch;\r
348 *HFrontPorch = mResolutions[ModeNumber].HFrontPorch;\r
349 *VRes = mResolutions[ModeNumber].VerticalResolution;\r
350 *VSync = mResolutions[ModeNumber].VSync;\r
351 *VBackPorch = mResolutions[ModeNumber].VBackPorch;\r
352 *VFrontPorch = mResolutions[ModeNumber].VFrontPorch;\r
353\r
354 return EFI_SUCCESS;\r
355}\r
356\r
357EFI_STATUS\r
358LcdPlatformGetBpp (\r
359 IN UINT32 ModeNumber,\r
360 OUT LCD_BPP * Bpp\r
361 )\r
362{\r
363 if (ModeNumber >= LcdPlatformGetMaxMode ()) {\r
364 return EFI_INVALID_PARAMETER;\r
365 }\r
366\r
367 *Bpp = mResolutions[ModeNumber].Bpp;\r
368\r
369 return EFI_SUCCESS;\r
370}\r