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