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