3 Copyright (c) 2011-2014, ARM Ltd. All rights reserved.<BR>
4 SPDX-License-Identifier: BSD-2-Clause-Patent
8 #include "LcdGraphicsOutputDxe.h"
10 BOOLEAN mDisplayInitialized
= FALSE
;
12 LCD_MODE LcdModes
[] = {
33 LCD_INSTANCE mLcdTemplate
= {
34 LCD_INSTANCE_SIGNATURE
,
38 0, // HorizontalResolution
39 0, // VerticalResolution
40 PixelBltOnly
, // PixelFormat
46 }, // PixelInformation
47 0, // PixelsPerScanLine
54 0, // FrameBufferBase;
58 LcdGraphicsQueryMode
, // QueryMode
59 LcdGraphicsSetMode
, // SetMode
60 LcdGraphicsBlt
, // Blt
66 HARDWARE_DEVICE_PATH
, HW_VENDOR_DP
,
67 { (UINT8
) (sizeof(VENDOR_DEVICE_PATH
)), (UINT8
) ((sizeof(VENDOR_DEVICE_PATH
)) >> 8) },
69 // Hardware Device Path for Lcd
70 EFI_CALLER_ID_GUID
// Use the driver's GUID
74 END_ENTIRE_DEVICE_PATH_SUBTYPE
,
75 { sizeof(EFI_DEVICE_PATH_PROTOCOL
), 0}
81 LcdInstanceContructor (
82 OUT LCD_INSTANCE
** NewInstance
85 LCD_INSTANCE
* Instance
;
87 Instance
= AllocateCopyPool (sizeof(LCD_INSTANCE
), &mLcdTemplate
);
88 if (Instance
== NULL
) {
89 return EFI_OUT_OF_RESOURCES
;
92 Instance
->Gop
.Mode
= &Instance
->Mode
;
93 Instance
->Mode
.Info
= &Instance
->ModeInfo
;
95 *NewInstance
= Instance
;
101 OUT EFI_PHYSICAL_ADDRESS
* VramBaseAddress
,
106 EFI_CPU_ARCH_PROTOCOL
*Cpu
;
112 // Allocate VRAM from DRAM
113 Status
= gBS
->AllocatePages (AllocateAnyPages
, EfiBootServicesData
, EFI_SIZE_TO_PAGES((MaxSize
)), VramBaseAddress
);
114 if (EFI_ERROR(Status
)) {
118 // Ensure the Cpu architectural protocol is already installed
119 Status
= gBS
->LocateProtocol (&gEfiCpuArchProtocolGuid
, NULL
, (VOID
**)&Cpu
);
120 ASSERT_EFI_ERROR(Status
);
122 // Mark the VRAM as un-cacheable. The VRAM is inside the DRAM, which is cacheable.
123 Status
= Cpu
->SetMemoryAttributes (Cpu
, *VramBaseAddress
, *VramSize
, EFI_MEMORY_UC
);
124 if (EFI_ERROR(Status
)) {
125 gBS
->FreePool (VramBaseAddress
);
134 UINT32 VramBaseAddress
,
138 // Make sure the interface clock is running
139 MmioWrite32 (CM_ICLKEN_DSS
, EN_DSS
);
141 // Stop the functional clocks
142 MmioAnd32 (CM_FCLKEN_DSS
, ~(EN_DSS1
| EN_DSS2
| EN_TV
));
144 // Program the DSS clock divisor
145 MmioWrite32 (CM_CLKSEL_DSS
, 0x1000 | (LcdModes
[ModeNumber
].DssDivisor
));
147 // Start the functional clocks
148 MmioOr32 (CM_FCLKEN_DSS
, (EN_DSS1
| EN_DSS2
| EN_TV
));
150 // Wait for DSS to stabilize
153 // Reset the subsystem
154 MmioWrite32(DSS_SYSCONFIG
, DSS_SOFTRESET
);
155 while (!(MmioRead32 (DSS_SYSSTATUS
) & DSS_RESETDONE
));
157 // Configure LCD parameters
158 MmioWrite32 (DISPC_SIZE_LCD
,
159 ((LcdModes
[ModeNumber
].HorizontalResolution
- 1)
160 | ((LcdModes
[ModeNumber
].VerticalResolution
- 1) << 16))
162 MmioWrite32 (DISPC_TIMING_H
,
163 ( (LcdModes
[ModeNumber
].HSync
- 1)
164 | ((LcdModes
[ModeNumber
].HFrontPorch
- 1) << 8)
165 | ((LcdModes
[ModeNumber
].HBackPorch
- 1) << 20))
167 MmioWrite32 (DISPC_TIMING_V
,
168 ( (LcdModes
[ModeNumber
].VSync
- 1)
169 | ((LcdModes
[ModeNumber
].VFrontPorch
- 1) << 8)
170 | ((LcdModes
[ModeNumber
].VBackPorch
- 1) << 20))
173 // Set the framebuffer to only load frames (no gamma tables)
174 MmioAnd32 (DISPC_CONFIG
, CLEARLOADMODE
);
175 MmioOr32 (DISPC_CONFIG
, LOAD_FRAME_ONLY
);
177 // Divisor for the pixel clock
178 MmioWrite32(DISPC_DIVISOR
, ((1 << 16) | LcdModes
[ModeNumber
].DispcDivisor
) );
180 // Set up the graphics layer
181 MmioWrite32 (DISPC_GFX_PRELD
, 0x2D8);
182 MmioWrite32 (DISPC_GFX_BA0
, VramBaseAddress
);
183 MmioWrite32 (DISPC_GFX_SIZE
,
184 ((LcdModes
[ModeNumber
].HorizontalResolution
- 1)
185 | ((LcdModes
[ModeNumber
].VerticalResolution
- 1) << 16))
188 MmioWrite32(DISPC_GFX_ATTR
, (GFXENABLE
| RGB16
| BURSTSIZE16
));
191 MmioOr32 (DISPC_CONTROL
, (LCDENABLE
| ACTIVEMATRIX
| DATALINES24
| BYPASS_MODE
| LCDENABLESIGNAL
));
192 MmioOr32 (DISPC_CONTROL
, GOLCD
);
198 HwInitializeDisplay (
199 UINTN VramBaseAddress
,
206 EMBEDDED_EXTERNAL_DEVICE
*gTPS65950
;
208 // Enable power lines used by TFP410
209 Status
= gBS
->LocateProtocol (&gEmbeddedExternalDeviceProtocolGuid
, NULL
, (VOID
**)&gTPS65950
);
210 ASSERT_EFI_ERROR (Status
);
212 OldTpl
= gBS
->RaiseTPL(TPL_NOTIFY
);
213 Data
= VAUX_DEV_GRP_P1
;
214 Status
= gTPS65950
->Write (gTPS65950
, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID4
, VPLL2_DEV_GRP
), 1, &Data
);
215 ASSERT_EFI_ERROR(Status
);
217 Data
= VAUX_DEDICATED_18V
;
218 Status
= gTPS65950
->Write (gTPS65950
, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID4
, VPLL2_DEDICATED
), 1, &Data
);
219 ASSERT_EFI_ERROR (Status
);
221 // Power up TFP410 (set GPIO2 on TPS - for BeagleBoard-xM)
222 Status
= gTPS65950
->Read (gTPS65950
, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID2
, GPIODATADIR1
), 1, &Data
);
223 ASSERT_EFI_ERROR (Status
);
225 Status
= gTPS65950
->Write (gTPS65950
, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID2
, GPIODATADIR1
), 1, &Data
);
226 ASSERT_EFI_ERROR (Status
);
229 Status
= gTPS65950
->Write (gTPS65950
, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID2
, SETGPIODATAOUT1
), 1, &Data
);
230 ASSERT_EFI_ERROR (Status
);
232 gBS
->RestoreTPL(OldTpl
);
234 // Power up TFP410 (set GPIO 170 - for older BeagleBoards)
235 MmioAnd32 (GPIO6_BASE
+ GPIO_OE
, ~BIT10
);
236 MmioOr32 (GPIO6_BASE
+ GPIO_SETDATAOUT
, BIT10
);
243 IN LCD_INSTANCE
* Instance
248 EFI_PHYSICAL_ADDRESS VramBaseAddress
;
250 Status
= LcdPlatformGetVram (&VramBaseAddress
, &VramSize
);
251 if (EFI_ERROR (Status
)) {
255 Instance
->Mode
.FrameBufferBase
= VramBaseAddress
;
256 Instance
->Mode
.FrameBufferSize
= VramSize
;
258 Status
= HwInitializeDisplay((UINTN
)VramBaseAddress
, VramSize
);
259 if (!EFI_ERROR (Status
)) {
260 mDisplayInitialized
= TRUE
;
268 LcdGraphicsQueryMode (
269 IN EFI_GRAPHICS_OUTPUT_PROTOCOL
*This
,
270 IN UINT32 ModeNumber
,
271 OUT UINTN
*SizeOfInfo
,
272 OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
**Info
275 LCD_INSTANCE
*Instance
;
277 Instance
= LCD_INSTANCE_FROM_GOP_THIS(This
);
279 if (!mDisplayInitialized
) {
280 InitializeDisplay (Instance
);
284 if ( (This
== NULL
) || (Info
== NULL
) || (SizeOfInfo
== NULL
) || (ModeNumber
>= This
->Mode
->MaxMode
) ) {
285 DEBUG((DEBUG_ERROR
, "LcdGraphicsQueryMode: ERROR - For mode number %d : Invalid Parameter.\n", ModeNumber
));
286 return EFI_INVALID_PARAMETER
;
289 *Info
= AllocateCopyPool(sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
), &Instance
->ModeInfo
);
291 return EFI_OUT_OF_RESOURCES
;
294 *SizeOfInfo
= sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
);
296 (*Info
)->Version
= 0;
297 (*Info
)->HorizontalResolution
= LcdModes
[ModeNumber
].HorizontalResolution
;
298 (*Info
)->VerticalResolution
= LcdModes
[ModeNumber
].VerticalResolution
;
299 (*Info
)->PixelFormat
= PixelBltOnly
;
307 IN EFI_GRAPHICS_OUTPUT_PROTOCOL
*This
,
311 LCD_INSTANCE
*Instance
;
313 Instance
= LCD_INSTANCE_FROM_GOP_THIS(This
);
315 if (ModeNumber
>= Instance
->Mode
.MaxMode
) {
316 return EFI_UNSUPPORTED
;
319 if (!mDisplayInitialized
) {
320 InitializeDisplay (Instance
);
323 DssSetMode((UINT32
)Instance
->Mode
.FrameBufferBase
, ModeNumber
);
325 Instance
->Mode
.Mode
= ModeNumber
;
326 Instance
->ModeInfo
.HorizontalResolution
= LcdModes
[ModeNumber
].HorizontalResolution
;
327 Instance
->ModeInfo
.VerticalResolution
= LcdModes
[ModeNumber
].VerticalResolution
;
334 LcdGraphicsOutputDxeInitialize (
335 IN EFI_HANDLE ImageHandle
,
336 IN EFI_SYSTEM_TABLE
*SystemTable
339 EFI_STATUS Status
= EFI_SUCCESS
;
340 LCD_INSTANCE
* Instance
;
342 Status
= LcdInstanceContructor (&Instance
);
343 if (EFI_ERROR(Status
)) {
347 // Install the Graphics Output Protocol and the Device Path
348 Status
= gBS
->InstallMultipleProtocolInterfaces(
350 &gEfiGraphicsOutputProtocolGuid
, &Instance
->Gop
,
351 &gEfiDevicePathProtocolGuid
, &Instance
->DevicePath
,
355 if (EFI_ERROR(Status
)) {
356 DEBUG((DEBUG_ERROR
, "GraphicsOutputDxeInitialize: Can not install the protocol. Exit Status=%r\n", Status
));
360 // Register for an ExitBootServicesEvent
361 // When ExitBootServices starts, this function here will make sure that the graphics driver will shut down properly,
362 // i.e. it will free up all allocated memory and perform any necessary hardware re-configuration.
363 /*Status = gBS->CreateEvent (
364 EVT_SIGNAL_EXIT_BOOT_SERVICES,
366 LcdGraphicsExitBootServicesEvent, NULL,
367 &Instance->ExitBootServicesEvent
370 if (EFI_ERROR(Status)) {
371 DEBUG((DEBUG_ERROR, "GraphicsOutputDxeInitialize: Can not install the ExitBootServicesEvent handler. Exit Status=%r\n", Status));
372 goto EXIT_ERROR_UNINSTALL_PROTOCOL;
375 // To get here, everything must be fine, so just exit
378 //EXIT_ERROR_UNINSTALL_PROTOCOL:
379 /* The following function could return an error message,
380 * however, to get here something must have gone wrong already,
381 * so preserve the original error, i.e. don't change
382 * the Status variable, even it fails to uninstall the protocol.
384 /* gBS->UninstallMultipleProtocolInterfaces (
386 &gEfiGraphicsOutputProtocolGuid, &Instance->Gop, // Uninstall Graphics Output protocol
387 &gEfiDevicePathProtocolGuid, &Instance->DevicePath, // Uninstall device path