audk/ArmPlatformPkg/Library/HdLcd/HdLcd.c

175 lines
4.7 KiB
C

/** @file
This file contains the platform independent parts of HdLcd
Copyright (c) 2011-2018, ARM Ltd. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include <Library/DebugLib.h>
#include <Library/IoLib.h>
#include <Library/LcdHwLib.h>
#include <Library/LcdPlatformLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/PcdLib.h>
#include "HdLcd.h"
#define BYTES_PER_PIXEL 4
/** Initialize display.
@param[in] VramBaseAddress Address of the framebuffer.
@retval EFI_SUCCESS Display initialization successful.
**/
EFI_STATUS
LcdInitialize (
IN EFI_PHYSICAL_ADDRESS VramBaseAddress
)
{
// Disable the controller
MmioWrite32 (HDLCD_REG_COMMAND, HDLCD_DISABLE);
// Disable all interrupts
MmioWrite32 (HDLCD_REG_INT_MASK, 0);
// Define start of the VRAM. This never changes for any graphics mode
MmioWrite32 (HDLCD_REG_FB_BASE, (UINT32)VramBaseAddress);
// Setup various registers that never change
MmioWrite32 (HDLCD_REG_BUS_OPTIONS, (4 << 8) | HDLCD_BURST_8);
MmioWrite32 (HDLCD_REG_POLARITIES, HDLCD_DEFAULT_POLARITIES);
MmioWrite32 (
HDLCD_REG_PIXEL_FORMAT,
HDLCD_LITTLE_ENDIAN | HDLCD_4BYTES_PER_PIXEL
);
return EFI_SUCCESS;
}
/** Set requested mode of the display.
@param[in] ModeNumber Display mode number.
@retval EFI_SUCCESS Display mode set successfully.
@retval !(EFI_SUCCESS) Other errors.
**/
EFI_STATUS
LcdSetMode (
IN UINT32 ModeNumber
)
{
EFI_STATUS Status;
SCAN_TIMINGS *Horizontal;
SCAN_TIMINGS *Vertical;
EFI_GRAPHICS_PIXEL_FORMAT PixelFormat;
EFI_GRAPHICS_OUTPUT_MODE_INFORMATION ModeInfo;
// Set the video mode timings and other relevant information
Status = LcdPlatformGetTimings (
ModeNumber,
&Horizontal,
&Vertical
);
if (EFI_ERROR (Status)) {
ASSERT_EFI_ERROR (Status);
return Status;
}
ASSERT (Horizontal != NULL);
ASSERT (Vertical != NULL);
// Get the pixel format information.
Status = LcdPlatformQueryMode (ModeNumber, &ModeInfo);
if (EFI_ERROR (Status)) {
ASSERT_EFI_ERROR (Status);
return Status;
}
// By default PcdArmHdLcdSwapBlueRedSelect is set to false
// However on the Juno platform HW lines for BLUE and RED are swapped
// Therefore PcdArmHdLcdSwapBlueRedSelect is set to TRUE for the Juno platform
PixelFormat = FixedPcdGetBool (PcdArmHdLcdSwapBlueRedSelect)
? PixelRedGreenBlueReserved8BitPerColor
: PixelBlueGreenRedReserved8BitPerColor;
if (ModeInfo.PixelFormat == PixelFormat) {
MmioWrite32 (HDLCD_REG_RED_SELECT, (8 << 8) | 16);
MmioWrite32 (HDLCD_REG_BLUE_SELECT, (8 << 8) | 0);
} else {
MmioWrite32 (HDLCD_REG_BLUE_SELECT, (8 << 8) | 16);
MmioWrite32 (HDLCD_REG_RED_SELECT, (8 << 8) | 0);
}
MmioWrite32 (HDLCD_REG_GREEN_SELECT, (8 << 8) | 8);
// Disable the controller
MmioWrite32 (HDLCD_REG_COMMAND, HDLCD_DISABLE);
// Update the frame buffer information with the new settings
MmioWrite32 (
HDLCD_REG_FB_LINE_LENGTH,
Horizontal->Resolution * BYTES_PER_PIXEL
);
MmioWrite32 (
HDLCD_REG_FB_LINE_PITCH,
Horizontal->Resolution * BYTES_PER_PIXEL
);
MmioWrite32 (HDLCD_REG_FB_LINE_COUNT, Vertical->Resolution - 1);
// Set the vertical timing information
MmioWrite32 (HDLCD_REG_V_SYNC, Vertical->Sync);
MmioWrite32 (HDLCD_REG_V_BACK_PORCH, Vertical->BackPorch);
MmioWrite32 (HDLCD_REG_V_DATA, Vertical->Resolution - 1);
MmioWrite32 (HDLCD_REG_V_FRONT_PORCH, Vertical->FrontPorch);
// Set the horizontal timing information
MmioWrite32 (HDLCD_REG_H_SYNC, Horizontal->Sync);
MmioWrite32 (HDLCD_REG_H_BACK_PORCH, Horizontal->BackPorch);
MmioWrite32 (HDLCD_REG_H_DATA, Horizontal->Resolution - 1);
MmioWrite32 (HDLCD_REG_H_FRONT_PORCH, Horizontal->FrontPorch);
// Enable the controller
MmioWrite32 (HDLCD_REG_COMMAND, HDLCD_ENABLE);
return EFI_SUCCESS;
}
/** De-initializes the display.
**/
VOID
LcdShutdown (
VOID
)
{
// Disable the controller
MmioWrite32 (HDLCD_REG_COMMAND, HDLCD_DISABLE);
}
/** Check for presence of HDLCD.
@retval EFI_SUCCESS Returns success if platform implements a HDLCD
controller.
@retval EFI_NOT_FOUND HDLCD display controller not found on the
platform.
**/
EFI_STATUS
LcdIdentify (
VOID
)
{
if ((MmioRead32 (HDLCD_REG_VERSION) >> 16) == HDLCD_PRODUCT_ID) {
return EFI_SUCCESS;
}
return EFI_NOT_FOUND;
}