]> git.proxmox.com Git - mirror_edk2.git/blob - ArmPlatformPkg/ArmVExpressPkg/Library/PL111LcdArmVExpressLib/PL111LcdArmVExpress.c
6ae5da99975e62387a8c7d9ddddd3c3ecef5d060
[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 #define PL111_CLCD_SITE ARM_VE_DAUGHTERBOARD_1_SITE
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_STATUS
129 LcdPlatformInitializeDisplay (
130 VOID
131 ) {
132 // Set the FPGA multiplexer to select the video output from the motherboard or the daughterboard
133 return ArmPlatformSysConfigSet (SYS_CFG_MUXFPGA, PL111_CLCD_SITE);
134 }
135
136 EFI_STATUS
137 LcdPlatformGetVram (
138 OUT EFI_PHYSICAL_ADDRESS* VramBaseAddress,
139 OUT UINTN* VramSize
140 )
141 {
142 EFI_STATUS Status;
143 EFI_CPU_ARCH_PROTOCOL *Cpu;
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(PcdPL111MaxMode));
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 = PL111_CLCD_CORE_TILE_VIDEO_MODE_OSC_ID;
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 // Set the DVI into the new mode
238 Status = ArmPlatformSysConfigSet (SYS_CFG_DVIMODE, mResolutions[ModeNumber].Mode);
239 if (EFI_ERROR(Status)) {
240 ASSERT_EFI_ERROR (Status);
241 return Status;
242 }
243
244 // Set the multiplexer
245 Status = ArmPlatformSysConfigSet (SYS_CFG_MUXFPGA, LcdSite);
246 if (EFI_ERROR(Status)) {
247 ASSERT_EFI_ERROR (Status);
248 return Status;
249 }
250
251 return Status;
252 }
253
254 EFI_STATUS
255 LcdPlatformQueryMode (
256 IN UINT32 ModeNumber,
257 OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info
258 )
259 {
260 if (ModeNumber >= LcdPlatformGetMaxMode ()) {
261 return EFI_INVALID_PARAMETER;
262 }
263
264 Info->Version = 0;
265 Info->HorizontalResolution = mResolutions[ModeNumber].HorizontalResolution;
266 Info->VerticalResolution = mResolutions[ModeNumber].VerticalResolution;
267 Info->PixelsPerScanLine = mResolutions[ModeNumber].HorizontalResolution;
268
269 switch (mResolutions[ModeNumber].Bpp) {
270 case LCD_BITS_PER_PIXEL_24:
271 Info->PixelFormat = PixelRedGreenBlueReserved8BitPerColor;
272 Info->PixelInformation.RedMask = LCD_24BPP_RED_MASK;
273 Info->PixelInformation.GreenMask = LCD_24BPP_GREEN_MASK;
274 Info->PixelInformation.BlueMask = LCD_24BPP_BLUE_MASK;
275 Info->PixelInformation.ReservedMask = LCD_24BPP_RESERVED_MASK;
276 break;
277
278 case LCD_BITS_PER_PIXEL_16_555:
279 case LCD_BITS_PER_PIXEL_16_565:
280 case LCD_BITS_PER_PIXEL_12_444:
281 case LCD_BITS_PER_PIXEL_8:
282 case LCD_BITS_PER_PIXEL_4:
283 case LCD_BITS_PER_PIXEL_2:
284 case LCD_BITS_PER_PIXEL_1:
285 default:
286 // These are not supported
287 ASSERT(FALSE);
288 break;
289 }
290
291 return EFI_SUCCESS;
292 }
293
294 EFI_STATUS
295 LcdPlatformGetTimings (
296 IN UINT32 ModeNumber,
297 OUT UINT32* HRes,
298 OUT UINT32* HSync,
299 OUT UINT32* HBackPorch,
300 OUT UINT32* HFrontPorch,
301 OUT UINT32* VRes,
302 OUT UINT32* VSync,
303 OUT UINT32* VBackPorch,
304 OUT UINT32* VFrontPorch
305 )
306 {
307 if (ModeNumber >= LcdPlatformGetMaxMode ()) {
308 return EFI_INVALID_PARAMETER;
309 }
310
311 *HRes = mResolutions[ModeNumber].HorizontalResolution;
312 *HSync = mResolutions[ModeNumber].HSync;
313 *HBackPorch = mResolutions[ModeNumber].HBackPorch;
314 *HFrontPorch = mResolutions[ModeNumber].HFrontPorch;
315 *VRes = mResolutions[ModeNumber].VerticalResolution;
316 *VSync = mResolutions[ModeNumber].VSync;
317 *VBackPorch = mResolutions[ModeNumber].VBackPorch;
318 *VFrontPorch = mResolutions[ModeNumber].VFrontPorch;
319
320 return EFI_SUCCESS;
321 }
322
323 EFI_STATUS
324 LcdPlatformGetBpp (
325 IN UINT32 ModeNumber,
326 OUT LCD_BPP * Bpp
327 )
328 {
329 if (ModeNumber >= LcdPlatformGetMaxMode ()) {
330 return EFI_INVALID_PARAMETER;
331 }
332
333 *Bpp = mResolutions[ModeNumber].Bpp;
334
335 return EFI_SUCCESS;
336 }