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