3 Copyright (c) 2011-2014, 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.
14 #include "LcdGraphicsOutputDxe.h"
16 BOOLEAN mDisplayInitialized
= FALSE
;
18 LCD_MODE LcdModes
[] = {
39 LCD_INSTANCE mLcdTemplate
= {
40 LCD_INSTANCE_SIGNATURE
,
44 0, // HorizontalResolution
45 0, // VerticalResolution
46 PixelBltOnly
, // PixelFormat
52 }, // PixelInformation
53 0, // PixelsPerScanLine
60 0, // FrameBufferBase;
64 LcdGraphicsQueryMode
, // QueryMode
65 LcdGraphicsSetMode
, // SetMode
66 LcdGraphicsBlt
, // Blt
72 HARDWARE_DEVICE_PATH
, HW_VENDOR_DP
,
73 { (UINT8
) (sizeof(VENDOR_DEVICE_PATH
)), (UINT8
) ((sizeof(VENDOR_DEVICE_PATH
)) >> 8) },
75 // Hardware Device Path for Lcd
76 EFI_CALLER_ID_GUID
// Use the driver's GUID
80 END_ENTIRE_DEVICE_PATH_SUBTYPE
,
81 { sizeof(EFI_DEVICE_PATH_PROTOCOL
), 0}
87 LcdInstanceContructor (
88 OUT LCD_INSTANCE
** NewInstance
91 LCD_INSTANCE
* Instance
;
93 Instance
= AllocateCopyPool (sizeof(LCD_INSTANCE
), &mLcdTemplate
);
94 if (Instance
== NULL
) {
95 return EFI_OUT_OF_RESOURCES
;
98 Instance
->Gop
.Mode
= &Instance
->Mode
;
99 Instance
->Mode
.Info
= &Instance
->ModeInfo
;
101 *NewInstance
= Instance
;
107 OUT EFI_PHYSICAL_ADDRESS
* VramBaseAddress
,
112 EFI_CPU_ARCH_PROTOCOL
*Cpu
;
118 // Allocate VRAM from DRAM
119 Status
= gBS
->AllocatePages (AllocateAnyPages
, EfiBootServicesData
, EFI_SIZE_TO_PAGES((MaxSize
)), VramBaseAddress
);
120 if (EFI_ERROR(Status
)) {
124 // Ensure the Cpu architectural protocol is already installed
125 Status
= gBS
->LocateProtocol (&gEfiCpuArchProtocolGuid
, NULL
, (VOID
**)&Cpu
);
126 ASSERT_EFI_ERROR(Status
);
128 // Mark the VRAM as un-cacheable. The VRAM is inside the DRAM, which is cacheable.
129 Status
= Cpu
->SetMemoryAttributes (Cpu
, *VramBaseAddress
, *VramSize
, EFI_MEMORY_UC
);
130 if (EFI_ERROR(Status
)) {
131 gBS
->FreePool (VramBaseAddress
);
140 UINT32 VramBaseAddress
,
144 // Make sure the interface clock is running
145 MmioWrite32 (CM_ICLKEN_DSS
, EN_DSS
);
147 // Stop the functional clocks
148 MmioAnd32 (CM_FCLKEN_DSS
, ~(EN_DSS1
| EN_DSS2
| EN_TV
));
150 // Program the DSS clock divisor
151 MmioWrite32 (CM_CLKSEL_DSS
, 0x1000 | (LcdModes
[ModeNumber
].DssDivisor
));
153 // Start the functional clocks
154 MmioOr32 (CM_FCLKEN_DSS
, (EN_DSS1
| EN_DSS2
| EN_TV
));
156 // Wait for DSS to stabilize
159 // Reset the subsystem
160 MmioWrite32(DSS_SYSCONFIG
, DSS_SOFTRESET
);
161 while (!(MmioRead32 (DSS_SYSSTATUS
) & DSS_RESETDONE
));
163 // Configure LCD parameters
164 MmioWrite32 (DISPC_SIZE_LCD
,
165 ((LcdModes
[ModeNumber
].HorizontalResolution
- 1)
166 | ((LcdModes
[ModeNumber
].VerticalResolution
- 1) << 16))
168 MmioWrite32 (DISPC_TIMING_H
,
169 ( (LcdModes
[ModeNumber
].HSync
- 1)
170 | ((LcdModes
[ModeNumber
].HFrontPorch
- 1) << 8)
171 | ((LcdModes
[ModeNumber
].HBackPorch
- 1) << 20))
173 MmioWrite32 (DISPC_TIMING_V
,
174 ( (LcdModes
[ModeNumber
].VSync
- 1)
175 | ((LcdModes
[ModeNumber
].VFrontPorch
- 1) << 8)
176 | ((LcdModes
[ModeNumber
].VBackPorch
- 1) << 20))
179 // Set the framebuffer to only load frames (no gamma tables)
180 MmioAnd32 (DISPC_CONFIG
, CLEARLOADMODE
);
181 MmioOr32 (DISPC_CONFIG
, LOAD_FRAME_ONLY
);
183 // Divisor for the pixel clock
184 MmioWrite32(DISPC_DIVISOR
, ((1 << 16) | LcdModes
[ModeNumber
].DispcDivisor
) );
186 // Set up the graphics layer
187 MmioWrite32 (DISPC_GFX_PRELD
, 0x2D8);
188 MmioWrite32 (DISPC_GFX_BA0
, VramBaseAddress
);
189 MmioWrite32 (DISPC_GFX_SIZE
,
190 ((LcdModes
[ModeNumber
].HorizontalResolution
- 1)
191 | ((LcdModes
[ModeNumber
].VerticalResolution
- 1) << 16))
194 MmioWrite32(DISPC_GFX_ATTR
, (GFXENABLE
| RGB16
| BURSTSIZE16
));
197 MmioOr32 (DISPC_CONTROL
, (LCDENABLE
| ACTIVEMATRIX
| DATALINES24
| BYPASS_MODE
| LCDENABLESIGNAL
));
198 MmioOr32 (DISPC_CONTROL
, GOLCD
);
204 HwInitializeDisplay (
205 UINTN VramBaseAddress
,
212 EMBEDDED_EXTERNAL_DEVICE
*gTPS65950
;
214 // Enable power lines used by TFP410
215 Status
= gBS
->LocateProtocol (&gEmbeddedExternalDeviceProtocolGuid
, NULL
, (VOID
**)&gTPS65950
);
216 ASSERT_EFI_ERROR (Status
);
218 OldTpl
= gBS
->RaiseTPL(TPL_NOTIFY
);
219 Data
= VAUX_DEV_GRP_P1
;
220 Status
= gTPS65950
->Write (gTPS65950
, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID4
, VPLL2_DEV_GRP
), 1, &Data
);
221 ASSERT_EFI_ERROR(Status
);
223 Data
= VAUX_DEDICATED_18V
;
224 Status
= gTPS65950
->Write (gTPS65950
, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID4
, VPLL2_DEDICATED
), 1, &Data
);
225 ASSERT_EFI_ERROR (Status
);
227 // Power up TFP410 (set GPIO2 on TPS - for BeagleBoard-xM)
228 Status
= gTPS65950
->Read (gTPS65950
, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID2
, GPIODATADIR1
), 1, &Data
);
229 ASSERT_EFI_ERROR (Status
);
231 Status
= gTPS65950
->Write (gTPS65950
, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID2
, GPIODATADIR1
), 1, &Data
);
232 ASSERT_EFI_ERROR (Status
);
235 Status
= gTPS65950
->Write (gTPS65950
, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID2
, SETGPIODATAOUT1
), 1, &Data
);
236 ASSERT_EFI_ERROR (Status
);
238 gBS
->RestoreTPL(OldTpl
);
240 // Power up TFP410 (set GPIO 170 - for older BeagleBoards)
241 MmioAnd32 (GPIO6_BASE
+ GPIO_OE
, ~BIT10
);
242 MmioOr32 (GPIO6_BASE
+ GPIO_SETDATAOUT
, BIT10
);
249 IN LCD_INSTANCE
* Instance
254 EFI_PHYSICAL_ADDRESS VramBaseAddress
;
256 Status
= LcdPlatformGetVram (&VramBaseAddress
, &VramSize
);
257 if (EFI_ERROR (Status
)) {
261 Instance
->Mode
.FrameBufferBase
= VramBaseAddress
;
262 Instance
->Mode
.FrameBufferSize
= VramSize
;
264 Status
= HwInitializeDisplay((UINTN
)VramBaseAddress
, VramSize
);
265 if (!EFI_ERROR (Status
)) {
266 mDisplayInitialized
= TRUE
;
274 LcdGraphicsQueryMode (
275 IN EFI_GRAPHICS_OUTPUT_PROTOCOL
*This
,
276 IN UINT32 ModeNumber
,
277 OUT UINTN
*SizeOfInfo
,
278 OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
**Info
281 LCD_INSTANCE
*Instance
;
283 Instance
= LCD_INSTANCE_FROM_GOP_THIS(This
);
285 if (!mDisplayInitialized
) {
286 InitializeDisplay (Instance
);
290 if ( (This
== NULL
) || (Info
== NULL
) || (SizeOfInfo
== NULL
) || (ModeNumber
>= This
->Mode
->MaxMode
) ) {
291 DEBUG((DEBUG_ERROR
, "LcdGraphicsQueryMode: ERROR - For mode number %d : Invalid Parameter.\n", ModeNumber
));
292 return EFI_INVALID_PARAMETER
;
295 *Info
= AllocateCopyPool(sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
), &Instance
->ModeInfo
);
297 return EFI_OUT_OF_RESOURCES
;
300 *SizeOfInfo
= sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
);
302 (*Info
)->Version
= 0;
303 (*Info
)->HorizontalResolution
= LcdModes
[ModeNumber
].HorizontalResolution
;
304 (*Info
)->VerticalResolution
= LcdModes
[ModeNumber
].VerticalResolution
;
305 (*Info
)->PixelFormat
= PixelBltOnly
;
313 IN EFI_GRAPHICS_OUTPUT_PROTOCOL
*This
,
317 LCD_INSTANCE
*Instance
;
319 Instance
= LCD_INSTANCE_FROM_GOP_THIS(This
);
321 if (ModeNumber
>= Instance
->Mode
.MaxMode
) {
322 return EFI_UNSUPPORTED
;
325 if (!mDisplayInitialized
) {
326 InitializeDisplay (Instance
);
329 DssSetMode((UINT32
)Instance
->Mode
.FrameBufferBase
, ModeNumber
);
331 Instance
->Mode
.Mode
= ModeNumber
;
332 Instance
->ModeInfo
.HorizontalResolution
= LcdModes
[ModeNumber
].HorizontalResolution
;
333 Instance
->ModeInfo
.VerticalResolution
= LcdModes
[ModeNumber
].VerticalResolution
;
340 LcdGraphicsOutputDxeInitialize (
341 IN EFI_HANDLE ImageHandle
,
342 IN EFI_SYSTEM_TABLE
*SystemTable
345 EFI_STATUS Status
= EFI_SUCCESS
;
346 LCD_INSTANCE
* Instance
;
348 Status
= LcdInstanceContructor (&Instance
);
349 if (EFI_ERROR(Status
)) {
353 // Install the Graphics Output Protocol and the Device Path
354 Status
= gBS
->InstallMultipleProtocolInterfaces(
356 &gEfiGraphicsOutputProtocolGuid
, &Instance
->Gop
,
357 &gEfiDevicePathProtocolGuid
, &Instance
->DevicePath
,
361 if (EFI_ERROR(Status
)) {
362 DEBUG((DEBUG_ERROR
, "GraphicsOutputDxeInitialize: Can not install the protocol. Exit Status=%r\n", Status
));
366 // Register for an ExitBootServicesEvent
367 // When ExitBootServices starts, this function here will make sure that the graphics driver will shut down properly,
368 // i.e. it will free up all allocated memory and perform any necessary hardware re-configuration.
369 /*Status = gBS->CreateEvent (
370 EVT_SIGNAL_EXIT_BOOT_SERVICES,
372 LcdGraphicsExitBootServicesEvent, NULL,
373 &Instance->ExitBootServicesEvent
376 if (EFI_ERROR(Status)) {
377 DEBUG((DEBUG_ERROR, "GraphicsOutputDxeInitialize: Can not install the ExitBootServicesEvent handler. Exit Status=%r\n", Status));
378 goto EXIT_ERROR_UNINSTALL_PROTOCOL;
381 // To get here, everything must be fine, so just exit
384 //EXIT_ERROR_UNINSTALL_PROTOCOL:
385 /* The following function could return an error message,
386 * however, to get here something must have gone wrong already,
387 * so preserve the original error, i.e. don't change
388 * the Status variable, even it fails to uninstall the protocol.
390 /* gBS->UninstallMultipleProtocolInterfaces (
392 &gEfiGraphicsOutputProtocolGuid, &Instance->Gop, // Uninstall Graphics Output protocol
393 &gEfiDevicePathProtocolGuid, &Instance->DevicePath, // Uninstall device path