]> git.proxmox.com Git - mirror_edk2.git/blame - ArmPlatformPkg/ArmVExpressPkg/Library/HdLcdArmVExpressLib/HdLcdArmVExpress.c
ArmPlatformPkg/HdLcdArmVExpressLib: fix incorrect FreePool () call
[mirror_edk2.git] / ArmPlatformPkg / ArmVExpressPkg / Library / HdLcdArmVExpressLib / HdLcdArmVExpress.c
CommitLineData
295c2eb8 1/**\r
2\r
3 Copyright (c) 2012, ARM Ltd. All rights reserved.\r
3402aac7 4\r
295c2eb8 5 This program and the accompanying materials\r
6 are licensed and made available under the terms and conditions of the BSD License\r
7 which accompanies this distribution. The full text of the license may be found at\r
8 http://opensource.org/licenses/bsd-license.php\r
9\r
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
13**/\r
14\r
15#include <PiDxe.h>\r
16\r
17#include <Library/ArmPlatformSysConfigLib.h>\r
18#include <Library/IoLib.h>\r
19#include <Library/PcdLib.h>\r
20#include <Library/DebugLib.h>\r
21#include <Library/LcdPlatformLib.h>\r
22#include <Library/MemoryAllocationLib.h>\r
23#include <Library/UefiBootServicesTableLib.h>\r
24\r
25#include <Protocol/Cpu.h>\r
26#include <Protocol/EdidDiscovered.h>\r
27#include <Protocol/EdidActive.h>\r
28\r
29#include <ArmPlatform.h>\r
30\r
31typedef struct {\r
32 UINT32 Mode;\r
33 UINT32 HorizontalResolution;\r
34 UINT32 VerticalResolution;\r
35 LCD_BPP Bpp;\r
36 UINT32 OscFreq;\r
37\r
38 // These are used by HDLCD\r
39 UINT32 HSync;\r
40 UINT32 HBackPorch;\r
41 UINT32 HFrontPorch;\r
42 UINT32 VSync;\r
43 UINT32 VBackPorch;\r
44 UINT32 VFrontPorch;\r
45} LCD_RESOLUTION;\r
46\r
47\r
48LCD_RESOLUTION mResolutions[] = {\r
49 { // Mode 0 : VGA : 640 x 480 x 24 bpp\r
50 VGA, VGA_H_RES_PIXELS, VGA_V_RES_PIXELS, LCD_BITS_PER_PIXEL_24, VGA_OSC_FREQUENCY,\r
51 VGA_H_SYNC, VGA_H_BACK_PORCH, VGA_H_FRONT_PORCH,\r
52 VGA_V_SYNC, VGA_V_BACK_PORCH, VGA_V_FRONT_PORCH\r
53 },\r
54 { // Mode 1 : SVGA : 800 x 600 x 24 bpp\r
55 SVGA, SVGA_H_RES_PIXELS, SVGA_V_RES_PIXELS, LCD_BITS_PER_PIXEL_24, SVGA_OSC_FREQUENCY,\r
56 SVGA_H_SYNC, SVGA_H_BACK_PORCH, SVGA_H_FRONT_PORCH,\r
57 SVGA_V_SYNC, SVGA_V_BACK_PORCH, SVGA_V_FRONT_PORCH\r
58 },\r
59 { // Mode 2 : XGA : 1024 x 768 x 24 bpp\r
60 XGA, XGA_H_RES_PIXELS, XGA_V_RES_PIXELS, LCD_BITS_PER_PIXEL_24, XGA_OSC_FREQUENCY,\r
61 XGA_H_SYNC, XGA_H_BACK_PORCH, XGA_H_FRONT_PORCH,\r
62 XGA_V_SYNC, XGA_V_BACK_PORCH, XGA_V_FRONT_PORCH\r
63 },\r
64 { // Mode 3 : SXGA : 1280 x 1024 x 24 bpp\r
65 SXGA, SXGA_H_RES_PIXELS, SXGA_V_RES_PIXELS, LCD_BITS_PER_PIXEL_24, (SXGA_OSC_FREQUENCY/2),\r
66 SXGA_H_SYNC, SXGA_H_BACK_PORCH, SXGA_H_FRONT_PORCH,\r
67 SXGA_V_SYNC, SXGA_V_BACK_PORCH, SXGA_V_FRONT_PORCH\r
68 },\r
69 { // Mode 4 : UXGA : 1600 x 1200 x 24 bpp\r
70 UXGA, UXGA_H_RES_PIXELS, UXGA_V_RES_PIXELS, LCD_BITS_PER_PIXEL_24, (UXGA_OSC_FREQUENCY/2),\r
71 UXGA_H_SYNC, UXGA_H_BACK_PORCH, UXGA_H_FRONT_PORCH,\r
72 UXGA_V_SYNC, UXGA_V_BACK_PORCH, UXGA_V_FRONT_PORCH\r
73 },\r
74 { // Mode 5 : HD : 1920 x 1080 x 24 bpp\r
75 HD, HD_H_RES_PIXELS, HD_V_RES_PIXELS, LCD_BITS_PER_PIXEL_24, (HD_OSC_FREQUENCY/2),\r
76 HD_H_SYNC, HD_H_BACK_PORCH, HD_H_FRONT_PORCH,\r
77 HD_V_SYNC, HD_V_BACK_PORCH, HD_V_FRONT_PORCH\r
78 }\r
79};\r
80\r
81EFI_EDID_DISCOVERED_PROTOCOL mEdidDiscovered = {\r
82 0,\r
83 NULL\r
84};\r
85\r
86EFI_EDID_ACTIVE_PROTOCOL mEdidActive = {\r
87 0,\r
88 NULL\r
89};\r
90\r
91EFI_STATUS\r
92LcdPlatformInitializeDisplay (\r
93 IN EFI_HANDLE Handle\r
94 )\r
95{\r
96 EFI_STATUS Status;\r
97\r
98 // Set the FPGA multiplexer to select the video output from the motherboard or the daughterboard\r
99 Status = ArmPlatformSysConfigSet (SYS_CFG_MUXFPGA, ARM_VE_DAUGHTERBOARD_1_SITE);\r
100 if (EFI_ERROR(Status)) {\r
101 return Status;\r
102 }\r
103\r
104 // Install the EDID Protocols\r
105 Status = gBS->InstallMultipleProtocolInterfaces (\r
106 &Handle,\r
107 &gEfiEdidDiscoveredProtocolGuid, &mEdidDiscovered,\r
108 &gEfiEdidActiveProtocolGuid, &mEdidActive,\r
109 NULL\r
110 );\r
111\r
112 return Status;\r
113}\r
114\r
115EFI_STATUS\r
116LcdPlatformGetVram (\r
117 OUT EFI_PHYSICAL_ADDRESS* VramBaseAddress,\r
118 OUT UINTN* VramSize\r
119 )\r
120{\r
121 EFI_STATUS Status;\r
122 EFI_CPU_ARCH_PROTOCOL *Cpu;\r
123 EFI_ALLOCATE_TYPE AllocationType;\r
124\r
125 // Set the vram size\r
126 *VramSize = LCD_VRAM_SIZE;\r
127\r
128 *VramBaseAddress = (EFI_PHYSICAL_ADDRESS)LCD_VRAM_CORE_TILE_BASE;\r
129\r
130 // Allocate the VRAM from the DRAM so that nobody else uses it.\r
131 if (*VramBaseAddress == 0) {\r
132 AllocationType = AllocateAnyPages;\r
133 } else {\r
134 AllocationType = AllocateAddress;\r
135 }\r
136 Status = gBS->AllocatePages (AllocationType, EfiBootServicesData, EFI_SIZE_TO_PAGES(((UINTN)LCD_VRAM_SIZE)), VramBaseAddress);\r
137 if (EFI_ERROR(Status)) {\r
138 return Status;\r
139 }\r
140\r
141 // Ensure the Cpu architectural protocol is already installed\r
142 Status = gBS->LocateProtocol (&gEfiCpuArchProtocolGuid, NULL, (VOID **)&Cpu);\r
143 ASSERT_EFI_ERROR(Status);\r
144\r
145 // Mark the VRAM as un-cacheable. The VRAM is inside the DRAM, which is cacheable.\r
146 Status = Cpu->SetMemoryAttributes (Cpu, *VramBaseAddress, *VramSize, EFI_MEMORY_UC);\r
147 ASSERT_EFI_ERROR(Status);\r
148 if (EFI_ERROR(Status)) {\r
e87dca69 149 gBS->FreePages (*VramBaseAddress, EFI_SIZE_TO_PAGES (*VramSize));\r
295c2eb8 150 return Status;\r
151 }\r
152\r
153 return EFI_SUCCESS;\r
154}\r
155\r
156UINT32\r
157LcdPlatformGetMaxMode (\r
158 VOID\r
159 )\r
160{\r
161 //\r
162 // The following line will report correctly the total number of graphics modes\r
163 // that could be supported by the graphics driver:\r
164 //\r
165 return (sizeof(mResolutions) / sizeof(LCD_RESOLUTION));\r
166}\r
167\r
168EFI_STATUS\r
169LcdPlatformSetMode (\r
170 IN UINT32 ModeNumber\r
171 )\r
172{\r
173 EFI_STATUS Status;\r
174\r
175 if (ModeNumber >= LcdPlatformGetMaxMode ()) {\r
176 return EFI_INVALID_PARAMETER;\r
177 }\r
178\r
179 // Set the video mode oscillator\r
180 do {\r
181 Status = ArmPlatformSysConfigSetDevice (SYS_CFG_OSC_SITE1, PcdGet32(PcdHdLcdVideoModeOscId), mResolutions[ModeNumber].OscFreq);\r
182 } while (Status == EFI_TIMEOUT);\r
183 if (EFI_ERROR(Status)) {\r
184 ASSERT_EFI_ERROR (Status);\r
185 return Status;\r
186 }\r
187\r
188 // Set the DVI into the new mode\r
189 do {\r
190 Status = ArmPlatformSysConfigSet (SYS_CFG_DVIMODE, mResolutions[ModeNumber].Mode);\r
191 } while (Status == EFI_TIMEOUT);\r
192 if (EFI_ERROR(Status)) {\r
193 ASSERT_EFI_ERROR (Status);\r
194 return Status;\r
195 }\r
196\r
197 // Set the multiplexer\r
198 Status = ArmPlatformSysConfigSet (SYS_CFG_MUXFPGA, ARM_VE_DAUGHTERBOARD_1_SITE);\r
199 if (EFI_ERROR(Status)) {\r
200 ASSERT_EFI_ERROR (Status);\r
201 return Status;\r
202 }\r
203\r
204 return Status;\r
205}\r
206\r
207EFI_STATUS\r
208LcdPlatformQueryMode (\r
209 IN UINT32 ModeNumber,\r
210 OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info\r
211 )\r
212{\r
213 if (ModeNumber >= LcdPlatformGetMaxMode ()) {\r
214 return EFI_INVALID_PARAMETER;\r
215 }\r
216\r
217 Info->Version = 0;\r
218 Info->HorizontalResolution = mResolutions[ModeNumber].HorizontalResolution;\r
219 Info->VerticalResolution = mResolutions[ModeNumber].VerticalResolution;\r
220 Info->PixelsPerScanLine = mResolutions[ModeNumber].HorizontalResolution;\r
221\r
222 switch (mResolutions[ModeNumber].Bpp) {\r
223 case LCD_BITS_PER_PIXEL_24:\r
224 Info->PixelFormat = PixelRedGreenBlueReserved8BitPerColor;\r
225 Info->PixelInformation.RedMask = LCD_24BPP_RED_MASK;\r
226 Info->PixelInformation.GreenMask = LCD_24BPP_GREEN_MASK;\r
227 Info->PixelInformation.BlueMask = LCD_24BPP_BLUE_MASK;\r
228 Info->PixelInformation.ReservedMask = LCD_24BPP_RESERVED_MASK;\r
229 break;\r
230\r
231 case LCD_BITS_PER_PIXEL_16_555:\r
232 case LCD_BITS_PER_PIXEL_16_565:\r
233 case LCD_BITS_PER_PIXEL_12_444:\r
234 case LCD_BITS_PER_PIXEL_8:\r
235 case LCD_BITS_PER_PIXEL_4:\r
236 case LCD_BITS_PER_PIXEL_2:\r
237 case LCD_BITS_PER_PIXEL_1:\r
238 default:\r
239 // These are not supported\r
240 ASSERT(FALSE);\r
241 break;\r
242 }\r
243\r
244 return EFI_SUCCESS;\r
245}\r
246\r
247EFI_STATUS\r
248LcdPlatformGetTimings (\r
249 IN UINT32 ModeNumber,\r
250 OUT UINT32* HRes,\r
251 OUT UINT32* HSync,\r
252 OUT UINT32* HBackPorch,\r
253 OUT UINT32* HFrontPorch,\r
254 OUT UINT32* VRes,\r
255 OUT UINT32* VSync,\r
256 OUT UINT32* VBackPorch,\r
257 OUT UINT32* VFrontPorch\r
258 )\r
259{\r
260 if (ModeNumber >= LcdPlatformGetMaxMode ()) {\r
261 return EFI_INVALID_PARAMETER;\r
262 }\r
263\r
264 *HRes = mResolutions[ModeNumber].HorizontalResolution;\r
265 *HSync = mResolutions[ModeNumber].HSync;\r
266 *HBackPorch = mResolutions[ModeNumber].HBackPorch;\r
267 *HFrontPorch = mResolutions[ModeNumber].HFrontPorch;\r
268 *VRes = mResolutions[ModeNumber].VerticalResolution;\r
269 *VSync = mResolutions[ModeNumber].VSync;\r
270 *VBackPorch = mResolutions[ModeNumber].VBackPorch;\r
271 *VFrontPorch = mResolutions[ModeNumber].VFrontPorch;\r
272\r
273 return EFI_SUCCESS;\r
274}\r
275\r
276EFI_STATUS\r
277LcdPlatformGetBpp (\r
278 IN UINT32 ModeNumber,\r
279 OUT LCD_BPP * Bpp\r
280 )\r
281{\r
282 if (ModeNumber >= LcdPlatformGetMaxMode ()) {\r
283 return EFI_INVALID_PARAMETER;\r
284 }\r
285\r
286 *Bpp = mResolutions[ModeNumber].Bpp;\r
287\r
288 return EFI_SUCCESS;\r
289}\r