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