3 Copyright (c) 2011, 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
)),
74 (UINT8
) ((sizeof(VENDOR_DEVICE_PATH
)) >> 8),
76 // Hardware Device Path for Lcd
77 EFI_CALLER_ID_GUID
// Use the driver's GUID
82 END_ENTIRE_DEVICE_PATH_SUBTYPE
,
83 sizeof(EFI_DEVICE_PATH_PROTOCOL
),
90 LcdInstanceContructor (
91 OUT LCD_INSTANCE
** NewInstance
94 LCD_INSTANCE
* Instance
;
96 Instance
= AllocateCopyPool (sizeof(LCD_INSTANCE
), &mLcdTemplate
);
97 if (Instance
== NULL
) {
98 return EFI_OUT_OF_RESOURCES
;
101 Instance
->Gop
.Mode
= &Instance
->Mode
;
102 Instance
->Mode
.Info
= &Instance
->ModeInfo
;
104 *NewInstance
= Instance
;
110 OUT EFI_PHYSICAL_ADDRESS
* VramBaseAddress
,
115 EFI_CPU_ARCH_PROTOCOL
*Cpu
;
121 // Allocate VRAM from DRAM
122 Status
= gBS
->AllocatePages (AllocateAnyPages
, EfiBootServicesData
, EFI_SIZE_TO_PAGES((MaxSize
)), VramBaseAddress
);
123 if (EFI_ERROR(Status
)) {
127 // Ensure the Cpu architectural protocol is already installed
128 Status
= gBS
->LocateProtocol (&gEfiCpuArchProtocolGuid
, NULL
, (VOID
**)&Cpu
);
129 ASSERT_EFI_ERROR(Status
);
131 // Mark the VRAM as un-cacheable. The VRAM is inside the DRAM, which is cacheable.
132 Status
= Cpu
->SetMemoryAttributes (Cpu
, *VramBaseAddress
, *VramSize
, EFI_MEMORY_UC
);
133 if (EFI_ERROR(Status
)) {
134 gBS
->FreePool (VramBaseAddress
);
143 UINT32 VramBaseAddress
,
147 // Make sure the interface clock is running
148 MmioWrite32 (CM_ICLKEN_DSS
, EN_DSS
);
150 // Stop the functional clocks
151 MmioAnd32 (CM_FCLKEN_DSS
, ~(EN_DSS1
| EN_DSS2
| EN_TV
));
153 // Program the DSS clock divisor
154 MmioWrite32 (CM_CLKSEL_DSS
, 0x1000 | (LcdModes
[ModeNumber
].DssDivisor
));
156 // Start the functional clocks
157 MmioOr32 (CM_FCLKEN_DSS
, (EN_DSS1
| EN_DSS2
| EN_TV
));
159 // Wait for DSS to stabilize
162 // Reset the subsystem
163 MmioWrite32(DSS_SYSCONFIG
, DSS_SOFTRESET
);
164 while (!(MmioRead32 (DSS_SYSSTATUS
) & DSS_RESETDONE
));
166 // Configure LCD parameters
167 MmioWrite32 (DISPC_SIZE_LCD
,
168 ((LcdModes
[ModeNumber
].HorizontalResolution
- 1)
169 | ((LcdModes
[ModeNumber
].VerticalResolution
- 1) << 16))
171 MmioWrite32 (DISPC_TIMING_H
,
172 ( (LcdModes
[ModeNumber
].HSync
- 1)
173 | ((LcdModes
[ModeNumber
].HFrontPorch
- 1) << 8)
174 | ((LcdModes
[ModeNumber
].HBackPorch
- 1) << 20))
176 MmioWrite32 (DISPC_TIMING_V
,
177 ( (LcdModes
[ModeNumber
].VSync
- 1)
178 | ((LcdModes
[ModeNumber
].VFrontPorch
- 1) << 8)
179 | ((LcdModes
[ModeNumber
].VBackPorch
- 1) << 20))
182 // Set the framebuffer to only load frames (no gamma tables)
183 MmioAnd32 (DISPC_CONFIG
, CLEARLOADMODE
);
184 MmioOr32 (DISPC_CONFIG
, LOAD_FRAME_ONLY
);
186 // Divisor for the pixel clock
187 MmioWrite32(DISPC_DIVISOR
, ((1 << 16) | LcdModes
[ModeNumber
].DispcDivisor
) );
189 // Set up the graphics layer
190 MmioWrite32 (DISPC_GFX_PRELD
, 0x2D8);
191 MmioWrite32 (DISPC_GFX_BA0
, VramBaseAddress
);
192 MmioWrite32 (DISPC_GFX_SIZE
,
193 ((LcdModes
[ModeNumber
].HorizontalResolution
- 1)
194 | ((LcdModes
[ModeNumber
].VerticalResolution
- 1) << 16))
197 MmioWrite32(DISPC_GFX_ATTR
, (GFXENABLE
| RGB16
| BURSTSIZE16
));
200 MmioOr32 (DISPC_CONTROL
, (LCDENABLE
| ACTIVEMATRIX
| DATALINES24
| BYPASS_MODE
| LCDENABLESIGNAL
));
201 MmioOr32 (DISPC_CONTROL
, GOLCD
);
207 HwInitializeDisplay (
208 UINTN VramBaseAddress
,
215 EMBEDDED_EXTERNAL_DEVICE
*gTPS65950
;
217 // Enable power lines used by TFP410
218 Status
= gBS
->LocateProtocol (&gEmbeddedExternalDeviceProtocolGuid
, NULL
, (VOID
**)&gTPS65950
);
219 ASSERT_EFI_ERROR (Status
);
221 OldTpl
= gBS
->RaiseTPL(TPL_NOTIFY
);
222 Data
= VAUX_DEV_GRP_P1
;
223 Status
= gTPS65950
->Write (gTPS65950
, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID4
, VPLL2_DEV_GRP
), 1, &Data
);
224 ASSERT_EFI_ERROR(Status
);
226 Data
= VAUX_DEDICATED_18V
;
227 Status
= gTPS65950
->Write (gTPS65950
, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID4
, VPLL2_DEDICATED
), 1, &Data
);
228 ASSERT_EFI_ERROR (Status
);
230 // Power up TFP410 (set GPIO2 on TPS - for BeagleBoard-xM)
231 Status
= gTPS65950
->Read (gTPS65950
, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID2
, GPIODATADIR1
), 1, &Data
);
232 ASSERT_EFI_ERROR (Status
);
234 Status
= gTPS65950
->Write (gTPS65950
, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID2
, GPIODATADIR1
), 1, &Data
);
235 ASSERT_EFI_ERROR (Status
);
238 Status
= gTPS65950
->Write (gTPS65950
, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID2
, SETGPIODATAOUT1
), 1, &Data
);
239 ASSERT_EFI_ERROR (Status
);
241 gBS
->RestoreTPL(OldTpl
);
243 // Power up TFP410 (set GPIO 170 - for older BeagleBoards)
244 MmioAnd32 (GPIO6_BASE
+ GPIO_OE
, ~BIT10
);
245 MmioOr32 (GPIO6_BASE
+ GPIO_SETDATAOUT
, BIT10
);
252 IN LCD_INSTANCE
* Instance
257 EFI_PHYSICAL_ADDRESS VramBaseAddress
;
259 Status
= LcdPlatformGetVram (&VramBaseAddress
, &VramSize
);
260 if (EFI_ERROR (Status
)) {
264 Instance
->Mode
.FrameBufferBase
= VramBaseAddress
;
265 Instance
->Mode
.FrameBufferSize
= VramSize
;
267 Status
= HwInitializeDisplay((UINTN
)VramBaseAddress
, VramSize
);
268 if (!EFI_ERROR (Status
)) {
269 mDisplayInitialized
= TRUE
;
277 LcdGraphicsQueryMode (
278 IN EFI_GRAPHICS_OUTPUT_PROTOCOL
*This
,
279 IN UINT32 ModeNumber
,
280 OUT UINTN
*SizeOfInfo
,
281 OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
**Info
284 LCD_INSTANCE
*Instance
;
286 Instance
= LCD_INSTANCE_FROM_GOP_THIS(This
);
288 if (!mDisplayInitialized
) {
289 InitializeDisplay (Instance
);
293 if ( (This
== NULL
) || (Info
== NULL
) || (SizeOfInfo
== NULL
) || (ModeNumber
>= This
->Mode
->MaxMode
) ) {
294 DEBUG((DEBUG_ERROR
, "LcdGraphicsQueryMode: ERROR - For mode number %d : Invalid Parameter.\n", ModeNumber
));
295 return EFI_INVALID_PARAMETER
;
298 *Info
= AllocateCopyPool(sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
), &Instance
->ModeInfo
);
300 return EFI_OUT_OF_RESOURCES
;
303 *SizeOfInfo
= sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
);
305 (*Info
)->Version
= 0;
306 (*Info
)->HorizontalResolution
= LcdModes
[ModeNumber
].HorizontalResolution
;
307 (*Info
)->VerticalResolution
= LcdModes
[ModeNumber
].VerticalResolution
;
308 (*Info
)->PixelFormat
= PixelBltOnly
;
316 IN EFI_GRAPHICS_OUTPUT_PROTOCOL
*This
,
320 LCD_INSTANCE
*Instance
;
322 Instance
= LCD_INSTANCE_FROM_GOP_THIS(This
);
324 if (ModeNumber
>= Instance
->Mode
.MaxMode
) {
325 return EFI_UNSUPPORTED
;
328 if (!mDisplayInitialized
) {
329 InitializeDisplay (Instance
);
332 DssSetMode((UINT32
)Instance
->Mode
.FrameBufferBase
, ModeNumber
);
334 Instance
->Mode
.Mode
= ModeNumber
;
335 Instance
->ModeInfo
.HorizontalResolution
= LcdModes
[ModeNumber
].HorizontalResolution
;
336 Instance
->ModeInfo
.VerticalResolution
= LcdModes
[ModeNumber
].VerticalResolution
;
343 LcdGraphicsOutputDxeInitialize (
344 IN EFI_HANDLE ImageHandle
,
345 IN EFI_SYSTEM_TABLE
*SystemTable
348 EFI_STATUS Status
= EFI_SUCCESS
;
349 LCD_INSTANCE
* Instance
;
351 Status
= LcdInstanceContructor (&Instance
);
352 if (EFI_ERROR(Status
)) {
356 // Install the Graphics Output Protocol and the Device Path
357 Status
= gBS
->InstallMultipleProtocolInterfaces(
359 &gEfiGraphicsOutputProtocolGuid
, &Instance
->Gop
,
360 &gEfiDevicePathProtocolGuid
, &Instance
->DevicePath
,
364 if (EFI_ERROR(Status
)) {
365 DEBUG((DEBUG_ERROR
, "GraphicsOutputDxeInitialize: Can not install the protocol. Exit Status=%r\n", Status
));
369 // Register for an ExitBootServicesEvent
370 // When ExitBootServices starts, this function here will make sure that the graphics driver will shut down properly,
371 // i.e. it will free up all allocated memory and perform any necessary hardware re-configuration.
372 /*Status = gBS->CreateEvent (
373 EVT_SIGNAL_EXIT_BOOT_SERVICES,
375 LcdGraphicsExitBootServicesEvent, NULL,
376 &Instance->ExitBootServicesEvent
379 if (EFI_ERROR(Status)) {
380 DEBUG((DEBUG_ERROR, "GraphicsOutputDxeInitialize: Can not install the ExitBootServicesEvent handler. Exit Status=%r\n", Status));
381 goto EXIT_ERROR_UNINSTALL_PROTOCOL;
384 // To get here, everything must be fine, so just exit
387 //EXIT_ERROR_UNINSTALL_PROTOCOL:
388 /* The following function could return an error message,
389 * however, to get here something must have gone wrong already,
390 * so preserve the original error, i.e. don't change
391 * the Status variable, even it fails to uninstall the protocol.
393 /* gBS->UninstallMultipleProtocolInterfaces (
395 &gEfiGraphicsOutputProtocolGuid, &Instance->Gop, // Uninstall Graphics Output protocol
396 &gEfiDevicePathProtocolGuid, &Instance->DevicePath, // Uninstall device path