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
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.
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>
24 #include <Protocol/EdidDiscovered.h>
25 #include <Protocol/EdidActive.h>
27 #include <ArmPlatform.h>
31 UINT32 HorizontalResolution
;
32 UINT32 VerticalResolution
;
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
128 EFI_EDID_DISCOVERED_PROTOCOL mEdidDiscovered
= {
133 EFI_EDID_ACTIVE_PROTOCOL mEdidActive
= {
140 LcdPlatformInitializeDisplay (
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(
152 &gEfiEdidDiscoveredProtocolGuid
, &mEdidDiscovered
,
153 &gEfiEdidActiveProtocolGuid
, &mEdidActive
,
163 OUT EFI_PHYSICAL_ADDRESS
* VramBaseAddress
,
169 Status
= EFI_SUCCESS
;
171 // Is it on the motherboard or on the daughterboard?
172 switch(PL111_CLCD_SITE
) {
174 case ARM_VE_MOTHERBOARD_SITE
:
175 *VramBaseAddress
= (EFI_PHYSICAL_ADDRESS
) PL111_CLCD_VRAM_MOTHERBOARD_BASE
;
176 *VramSize
= LCD_VRAM_SIZE
;
179 case ARM_VE_DAUGHTERBOARD_1_SITE
:
180 *VramBaseAddress
= (EFI_PHYSICAL_ADDRESS
) LCD_VRAM_CORE_TILE_BASE
;
181 *VramSize
= LCD_VRAM_SIZE
;
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
)) {
189 // Mark the VRAM as write-combining. The VRAM is inside the DRAM, which is cacheable.
190 Status
= gDS
->SetMemorySpaceAttributes (*VramBaseAddress
, *VramSize
,
192 ASSERT_EFI_ERROR(Status
);
193 if (EFI_ERROR(Status
)) {
194 gBS
->FreePages (*VramBaseAddress
, EFI_SIZE_TO_PAGES(*VramSize
));
201 Status
= EFI_UNSUPPORTED
;
209 LcdPlatformGetMaxMode (
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;
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.
220 // Set the maximum mode allowed
221 return (PcdGet32(PcdPL111LcdMaxMode
));
232 SYS_CONFIG_FUNCTION Function
;
235 if (ModeNumber
>= LcdPlatformGetMaxMode ()) {
236 return EFI_INVALID_PARAMETER
;
239 LcdSite
= PL111_CLCD_SITE
;
242 case ARM_VE_MOTHERBOARD_SITE
:
243 Function
= SYS_CFG_OSC
;
244 OscillatorId
= PL111_CLCD_MOTHERBOARD_VIDEO_MODE_OSC_ID
;
246 case ARM_VE_DAUGHTERBOARD_1_SITE
:
247 Function
= SYS_CFG_OSC_SITE1
;
248 OscillatorId
= (UINT32
)PcdGet32(PcdPL111LcdVideoModeOscId
);
251 return EFI_UNSUPPORTED
;
254 // Set the video mode oscillator
255 Status
= ArmPlatformSysConfigSetDevice (Function
, OscillatorId
, mResolutions
[ModeNumber
].OscFreq
);
256 if (EFI_ERROR(Status
)) {
257 ASSERT_EFI_ERROR (Status
);
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
);
278 // Set the multiplexer
279 Status
= ArmPlatformSysConfigSet (SYS_CFG_MUXFPGA
, LcdSite
);
280 if (EFI_ERROR(Status
)) {
281 ASSERT_EFI_ERROR (Status
);
289 LcdPlatformQueryMode (
290 IN UINT32 ModeNumber
,
291 OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*Info
294 if (ModeNumber
>= LcdPlatformGetMaxMode ()) {
295 return EFI_INVALID_PARAMETER
;
299 Info
->HorizontalResolution
= mResolutions
[ModeNumber
].HorizontalResolution
;
300 Info
->VerticalResolution
= mResolutions
[ModeNumber
].VerticalResolution
;
301 Info
->PixelsPerScanLine
= mResolutions
[ModeNumber
].HorizontalResolution
;
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
;
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
:
320 // These are not supported
329 LcdPlatformGetTimings (
330 IN UINT32 ModeNumber
,
333 OUT UINT32
* HBackPorch
,
334 OUT UINT32
* HFrontPorch
,
337 OUT UINT32
* VBackPorch
,
338 OUT UINT32
* VFrontPorch
341 if (ModeNumber
>= LcdPlatformGetMaxMode ()) {
342 return EFI_INVALID_PARAMETER
;
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
;
359 IN UINT32 ModeNumber
,
363 if (ModeNumber
>= LcdPlatformGetMaxMode ()) {
364 return EFI_INVALID_PARAMETER
;
367 *Bpp
= mResolutions
[ModeNumber
].Bpp
;