From adf50234c8e8b15204501bca6327392d67301660 Mon Sep 17 00:00:00 2001 From: Girish Pathak Date: Tue, 26 Sep 2017 21:15:29 +0100 Subject: ARM/VExpressPkg: New DP500/DP550/DP650 platform library This change adds LcdPlatformLib implementation for Arm Mali DP500/DP500/DP650 display processors for models (with DP550 support). NOTE: Versions for actual hardware are liable to require extra handling for clock input changes, etc. Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Girish Pathak Signed-off-by: Evan Lloyd Reviewed-by: Leif Lindholm --- Platform/ARM/VExpressPkg/ArmVExpressPkg.dec | 3 +- .../Library/ArmMaliDpLib/ArmMaliDpLib.c | 387 +++++++++++++++++++++ .../Library/ArmMaliDpLib/ArmMaliDpLib.inf | 43 +++ .../Library/ArmVExpressLibRTSM/ArmVExpressLib.inf | 3 + .../Library/ArmVExpressLibRTSM/RTSMMem.c | 12 +- 5 files changed, 446 insertions(+), 2 deletions(-) create mode 100644 Platform/ARM/VExpressPkg/Library/ArmMaliDpLib/ArmMaliDpLib.c create mode 100644 Platform/ARM/VExpressPkg/Library/ArmMaliDpLib/ArmMaliDpLib.inf diff --git a/Platform/ARM/VExpressPkg/ArmVExpressPkg.dec b/Platform/ARM/VExpressPkg/ArmVExpressPkg.dec index 695553a9..ac775403 100644 --- a/Platform/ARM/VExpressPkg/ArmVExpressPkg.dec +++ b/Platform/ARM/VExpressPkg/ArmVExpressPkg.dec @@ -1,7 +1,7 @@ #/** @file # Arm Versatile Express package. # -# Copyright (c) 2012-2015, ARM Limited. All rights reserved. +# Copyright (c) 2012-2018, ARM Limited. All rights reserved. # # This program and the accompanying materials are licensed and made available # under the terms and conditions of the BSD License which accompanies this @@ -51,6 +51,7 @@ gArmVExpressTokenSpaceGuid.PcdPL111LcdVideoModeOscId|1|UINT32|0x00000003 gArmVExpressTokenSpaceGuid.PcdHdLcdVideoModeOscId|0|UINT32|0x00000005 + gArmVExpressTokenSpaceGuid.PcdArmMaliDpMaxMode|0|UINT32|0x00000008 # # Device path of block device on which Fastboot will flash partitions diff --git a/Platform/ARM/VExpressPkg/Library/ArmMaliDpLib/ArmMaliDpLib.c b/Platform/ARM/VExpressPkg/Library/ArmMaliDpLib/ArmMaliDpLib.c new file mode 100644 index 00000000..04ad341d --- /dev/null +++ b/Platform/ARM/VExpressPkg/Library/ArmMaliDpLib/ArmMaliDpLib.c @@ -0,0 +1,387 @@ +/** @file + + The file contains Arm Mali DP platform specific implementation. + + Copyright (c) 2017-2018, Arm Limited. All rights reserved. + + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include +#include +#include +#include +#include +#include +#include +#include + +/** Check an address is within 40 bits. + + The ARM Mali DP framebuffer address size can not be wider than 40 bits +**/ +#define DP_VALID_BASE_ADDR(Address) ((Address >> 40) == 0) + +typedef struct { + UINT32 OscFreq; + SCAN_TIMINGS Horizontal; + SCAN_TIMINGS Vertical; +} DISPLAY_MODE; + +/** The display modes implemented by this driver. + + On Models, the OSC frequencies (listed for each mode below) are not used. + However these frequencies are useful on hardware plaforms where related + clock (or PLL) settings are based on these pixel clocks. + + Since the clock settings are defined externally, the driver must + communicate pixel clock frequencies to relevant modules + responsible for setting clocks. e.g. SCP. +**/ +STATIC DISPLAY_MODE mDisplayModes[] = { + { + // Mode 0 : VGA : 640 x 480 x 24 bpp. + VGA_OSC_FREQUENCY, + {VGA_H_RES_PIXELS, VGA_H_SYNC, VGA_H_BACK_PORCH, VGA_H_FRONT_PORCH}, + {VGA_V_RES_PIXELS, VGA_V_SYNC, VGA_V_BACK_PORCH, VGA_V_FRONT_PORCH} + }, + { + // Mode 1 : WVGA : 800 x 480 x 24 bpp. + WVGA_OSC_FREQUENCY, + {WVGA_H_RES_PIXELS, WVGA_H_SYNC, WVGA_H_BACK_PORCH, WVGA_H_FRONT_PORCH}, + {WVGA_V_RES_PIXELS, WVGA_V_SYNC, WVGA_V_BACK_PORCH, WVGA_V_FRONT_PORCH} + }, + { + // Mode 2 : SVGA : 800 x 600 x 24 bpp. + SVGA_OSC_FREQUENCY, + {SVGA_H_RES_PIXELS, SVGA_H_SYNC, SVGA_H_BACK_PORCH, SVGA_H_FRONT_PORCH}, + {SVGA_V_RES_PIXELS, SVGA_V_SYNC, SVGA_V_BACK_PORCH, SVGA_V_FRONT_PORCH} + }, + { + // Mode 3 : QHD : 960 x 540 x 24 bpp. + QHD_OSC_FREQUENCY, + {QHD_H_RES_PIXELS, QHD_H_SYNC, QHD_H_BACK_PORCH, QHD_H_FRONT_PORCH}, + {QHD_V_RES_PIXELS, QHD_V_SYNC, QHD_V_BACK_PORCH, QHD_V_FRONT_PORCH} + }, + { + // Mode 4 : WSVGA : 1024 x 600 x 24 bpp. + WSVGA_OSC_FREQUENCY, + {WSVGA_H_RES_PIXELS, WSVGA_H_SYNC, WSVGA_H_BACK_PORCH, WSVGA_H_FRONT_PORCH}, + {WSVGA_V_RES_PIXELS, WSVGA_V_SYNC, WSVGA_V_BACK_PORCH, WSVGA_V_FRONT_PORCH} + }, + { + // Mode 5 : XGA : 1024 x 768 x 24 bpp. + XGA_OSC_FREQUENCY, + {XGA_H_RES_PIXELS, XGA_H_SYNC, XGA_H_BACK_PORCH, XGA_H_FRONT_PORCH}, + {XGA_V_RES_PIXELS, XGA_V_SYNC, XGA_V_BACK_PORCH, XGA_V_FRONT_PORCH} + }, + { + // Mode 6 : HD : 1280 x 720 x 24 bpp. + HD720_OSC_FREQUENCY, + {HD720_H_RES_PIXELS, HD720_H_SYNC, HD720_H_BACK_PORCH, HD720_H_FRONT_PORCH}, + {HD720_V_RES_PIXELS, HD720_V_SYNC, HD720_V_BACK_PORCH, HD720_V_FRONT_PORCH} + }, + { + // Mode 7 : WXGA : 1280 x 800 x 24 bpp. + WXGA_OSC_FREQUENCY, + {WXGA_H_RES_PIXELS, WXGA_H_SYNC, WXGA_H_BACK_PORCH, WXGA_H_FRONT_PORCH}, + {WXGA_V_RES_PIXELS, WXGA_V_SYNC, WXGA_V_BACK_PORCH, WXGA_V_FRONT_PORCH} + }, + { // Mode 8 : SXGA : 1280 x 1024 x 24 bpp. + SXGA_OSC_FREQUENCY, + {SXGA_H_RES_PIXELS, SXGA_H_SYNC, SXGA_H_BACK_PORCH, SXGA_H_FRONT_PORCH}, + {SXGA_V_RES_PIXELS, SXGA_V_SYNC, SXGA_V_BACK_PORCH, SXGA_V_FRONT_PORCH} + }, + { // Mode 9 : WSXGA+ : 1680 x 1050 x 24 bpp. + WSXGA_OSC_FREQUENCY, + {WSXGA_H_RES_PIXELS, WSXGA_H_SYNC, WSXGA_H_BACK_PORCH, WSXGA_H_FRONT_PORCH}, + {WSXGA_V_RES_PIXELS,WSXGA_V_SYNC, WSXGA_V_BACK_PORCH, WSXGA_V_FRONT_PORCH} + }, + { + // Mode 10 : HD : 1920 x 1080 x 24 bpp. + HD_OSC_FREQUENCY, + {HD_H_RES_PIXELS, HD_H_SYNC, HD_H_BACK_PORCH, HD_H_FRONT_PORCH}, + {HD_V_RES_PIXELS, HD_V_SYNC, HD_V_BACK_PORCH, HD_V_FRONT_PORCH} + } +}; + +/** If PcdArmMaliDpMaxMode is 0, platform supports full range of modes + else platform supports modes from 0 to PcdArmMaliDpMaxMode - 1 +**/ +STATIC CONST UINT32 mMaxMode = ((FixedPcdGet32 (PcdArmMaliDpMaxMode) != 0) + ? FixedPcdGet32 (PcdArmMaliDpMaxMode) + : sizeof (mDisplayModes) / sizeof (DISPLAY_MODE)); + +/** Platform related initialization function. + + @param[in] Handle Handle to the instance of the device. + + @retval EFI_SUCCESS Initialization of platform library successful. + @retval EFI_UNSUPPORTED PcdGopPixelFormat must be + PixelRedGreenBlueReserved8BitPerColor OR + PixelBlueGreenRedReserved8BitPerColor + any other format is not supported. +**/ +EFI_STATUS +LcdPlatformInitializeDisplay ( + IN EFI_HANDLE Handle + ) +{ + EFI_GRAPHICS_PIXEL_FORMAT PixelFormat; + + (VOID)Handle; + + // PixelBitMask and PixelBltOnly pixel formats are not supported + PixelFormat = FixedPcdGet32 (PcdGopPixelFormat); + if (PixelFormat != PixelRedGreenBlueReserved8BitPerColor && + PixelFormat != PixelBlueGreenRedReserved8BitPerColor) { + + ASSERT (PixelFormat == PixelRedGreenBlueReserved8BitPerColor || + PixelFormat == PixelBlueGreenRedReserved8BitPerColor); + return EFI_UNSUPPORTED; + } + + return EFI_SUCCESS; +} + +/* Internal helper function to allocate memory if memory is not already + reserved for framebuffer + + @param[in] VramSize Requested framebuffer size in bytes. + @param[out] VramBaseAddress Pointer to memory allocated for framebuffer. + + @retval EFI_SUCCESS Framebuffer memory allocated successfully. + @retval EFI_UNSUPPORTED Allocated address wider than 40 bits. + @retval !EFI_SUCCESS Other errors. +**/ +STATIC +EFI_STATUS +GetVram ( + IN UINTN VramSize, + OUT EFI_PHYSICAL_ADDRESS * VramBaseAddress + ) +{ + EFI_STATUS Status; + EFI_CPU_ARCH_PROTOCOL *Cpu; + + *VramBaseAddress = FixedPcdGet64 (PcdArmLcdDdrFrameBufferBase); + + // Check if memory is already reserved for the framebuffer. + if (*VramBaseAddress != 0) { + // ARM Mali DP framebuffer base address can not be wider than 40 bits. + if (!DP_VALID_BASE_ADDR (*VramBaseAddress)) { + ASSERT (DP_VALID_BASE_ADDR (*VramBaseAddress)); + Status = EFI_UNSUPPORTED; + } else { + Status = EFI_SUCCESS; + } + } else { + // If not already reserved, attempt to allocate the VRAM from the DRAM. + Status = gBS->AllocatePages ( + AllocateAnyPages, + EfiReservedMemoryType, + EFI_SIZE_TO_PAGES (VramSize), + VramBaseAddress + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "ArmMaliDpLib: Failed to allocate framebuffer.\n")); + ASSERT_EFI_ERROR (Status); + return Status; + } + + // ARM Mali DP framebuffer base address can not be wider than 40 bits. + if (!DP_VALID_BASE_ADDR (*VramBaseAddress)) { + gBS->FreePages (*VramBaseAddress, EFI_SIZE_TO_PAGES (VramSize)); + ASSERT (DP_VALID_BASE_ADDR (*VramBaseAddress)); + return EFI_UNSUPPORTED; + } + + // Ensure the Cpu architectural protocol is already installed + Status = gBS->LocateProtocol ( + &gEfiCpuArchProtocolGuid, + NULL, + (VOID **)&Cpu + ); + if (!EFI_ERROR (Status)) { + // The VRAM is inside the DRAM, which is cacheable. + // Mark the VRAM as write-combining (uncached) and non-executable. + Status = Cpu->SetMemoryAttributes ( + Cpu, + *VramBaseAddress, + VramSize, + EFI_MEMORY_WC | EFI_MEMORY_XP + ); + } + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + gBS->FreePages (*VramBaseAddress, EFI_SIZE_TO_PAGES (VramSize)); + } + } + + return Status; +} + +/** Allocate VRAM memory in DRAM for the framebuffer + (unless it is reserved already). + + The allocated address can be used to set the framebuffer as a base buffer + address for any layer of the ARM Mali DP. + + @param[out] VramBaseAddress A pointer to the framebuffer address. + @param[out] VramSize A pointer to the size of the frame + buffer in bytes + + @retval EFI_SUCCESS Framebuffer memory allocation success. + @retval EFI_UNSUPPORTED Allocated address wider than 40 bits + @retval !EFI_SUCCESS Other errors. +**/ +EFI_STATUS +LcdPlatformGetVram ( + OUT EFI_PHYSICAL_ADDRESS * VramBaseAddress, + OUT UINTN * VramSize + ) +{ + ASSERT (VramBaseAddress != NULL); + ASSERT (VramSize != NULL); + + // Set the VRAM size. + *VramSize = (UINTN)FixedPcdGet32 (PcdArmLcdDdrFrameBufferSize); + + return GetVram (*VramSize, VramBaseAddress); +} + +/** Return total number of modes supported. + + Note: Valid mode numbers are 0 to MaxMode - 1 + See Section 12.9 of the UEFI Specification 2.7 + + @retval UINT32 Mode Number. +**/ +UINT32 +LcdPlatformGetMaxMode (VOID) +{ + return mMaxMode; +} + +/** Set the requested display mode. + + @param[in] ModeNumber Mode Number. + + @retval EFI_SUCCESS Mode set successful. + @retval EFI_INVALID_PARAMETER Requested mode not found. +**/ +EFI_STATUS +LcdPlatformSetMode ( + IN UINT32 ModeNumber + ) +{ + if (ModeNumber >= mMaxMode) { + ASSERT (ModeNumber < mMaxMode); + return EFI_INVALID_PARAMETER; + } + + // On models, platform specific clock/mux settings are not required. + // Display controller specific settings for Mali DP are done in LcdSetMode. + return EFI_SUCCESS; +} + +/** Return information for the requested mode number. + + @param[in] ModeNumber Mode Number. + @param[out] Info Pointer for returned mode information + (on success). + + @retval EFI_SUCCESS Display mode information of the requested + mode returned successfully. + @retval EFI_INVALID_PARAMETER Requested mode not found. +**/ +EFI_STATUS +LcdPlatformQueryMode ( + IN UINT32 ModeNumber, + OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION * Info + ) +{ + if (ModeNumber >= mMaxMode) { + ASSERT (ModeNumber < mMaxMode); + return EFI_INVALID_PARAMETER; + } + + ASSERT (Info != NULL); + + Info->Version = 0; + Info->HorizontalResolution = mDisplayModes[ModeNumber].Horizontal.Resolution; + Info->VerticalResolution = mDisplayModes[ModeNumber].Vertical.Resolution; + Info->PixelsPerScanLine = mDisplayModes[ModeNumber].Horizontal.Resolution; + + Info->PixelFormat = FixedPcdGet32 (PcdGopPixelFormat); + + return EFI_SUCCESS; +} + +/** Return the display timing information for the requested mode number. + + @param[in] ModeNumber Mode Number. + + @param[out] Horizontal Pointer to horizontal timing parameters. + (Resolution, Sync, Back porch, Front porch) + @param[out] Vertical Pointer to vertical timing parameters. + (Resolution, Sync, Back porch, Front porch) + + @retval EFI_SUCCESS Display timing information of the requested + mode returned successfully. + @retval EFI_INVALID_PARAMETER Requested mode not found. +**/ +EFI_STATUS +LcdPlatformGetTimings ( + IN UINT32 ModeNumber, + OUT SCAN_TIMINGS ** Horizontal, + OUT SCAN_TIMINGS ** Vertical + ) +{ + ASSERT (Horizontal != NULL); + ASSERT (Vertical != NULL); + + if (ModeNumber >= mMaxMode) { + ASSERT (ModeNumber < mMaxMode); + return EFI_INVALID_PARAMETER; + } + + *Horizontal = &mDisplayModes[ModeNumber].Horizontal; + *Vertical = &mDisplayModes[ModeNumber].Vertical; + + return EFI_SUCCESS; +} + +/** Return bits per pixel information for a mode number. + + @param[in] ModeNumber Mode Number. + @param[out] Bpp Pointer to bits per pixel information. + + @retval EFI_SUCCESS Bits per pixel information of the display + mode returned successfully. + @retval EFI_INVALID_PARAMETER Requested mode not found. +**/ +EFI_STATUS +LcdPlatformGetBpp ( + IN UINT32 ModeNumber, + OUT LCD_BPP * Bpp + ) +{ + ASSERT (Bpp != NULL); + // Check valid ModeNumber. + if (ModeNumber >= mMaxMode) { + ASSERT (ModeNumber < mMaxMode); + return EFI_INVALID_PARAMETER; + } + + *Bpp = LCD_BITS_PER_PIXEL_24; + + return EFI_SUCCESS; +} diff --git a/Platform/ARM/VExpressPkg/Library/ArmMaliDpLib/ArmMaliDpLib.inf b/Platform/ARM/VExpressPkg/Library/ArmMaliDpLib/ArmMaliDpLib.inf new file mode 100644 index 00000000..78f7d307 --- /dev/null +++ b/Platform/ARM/VExpressPkg/Library/ArmMaliDpLib/ArmMaliDpLib.inf @@ -0,0 +1,43 @@ +#/** @file +# Component description file for ArmMaliDpLib module +# +# Copyright (c) 2017-2018, Arm Limited. All rights reserved. +# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +#**/ + +[Defines] + INF_VERSION = 0x00010019 + BASE_NAME = ArmMaliDpLib + FILE_GUID = 36C47FED-2F3F-49C7-89CE-31B13F0431D8 + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = LcdPlatformLib + +[Sources.common] + ArmMaliDpLib.c + +[Packages] + ArmPlatformPkg/ArmPlatformPkg.dec + MdePkg/MdePkg.dec + Platform/ARM/VExpressPkg/ArmVExpressPkg.dec + +[LibraryClasses] + BaseLib + +[FixedPcd.common] + gArmPlatformTokenSpaceGuid.PcdArmLcdDdrFrameBufferBase + gArmPlatformTokenSpaceGuid.PcdArmLcdDdrFrameBufferSize + gArmPlatformTokenSpaceGuid.PcdGopPixelFormat + + # MaxMode must be one number higher than the actual max mode, + # i.e. for actual maximum mode 2, set the value to 3. + # See Section 12.9 of the UEFI Specification 2.7 + gArmVExpressTokenSpaceGuid.PcdArmMaliDpMaxMode + diff --git a/Platform/ARM/VExpressPkg/Library/ArmVExpressLibRTSM/ArmVExpressLib.inf b/Platform/ARM/VExpressPkg/Library/ArmVExpressLibRTSM/ArmVExpressLib.inf index b025abd9..53898c5e 100644 --- a/Platform/ARM/VExpressPkg/Library/ArmVExpressLibRTSM/ArmVExpressLib.inf +++ b/Platform/ARM/VExpressPkg/Library/ArmVExpressLibRTSM/ArmVExpressLib.inf @@ -57,5 +57,8 @@ gArmPlatformTokenSpaceGuid.PcdArmLcdDdrFrameBufferBase gArmPlatformTokenSpaceGuid.PcdArmLcdDdrFrameBufferSize + gArmPlatformTokenSpaceGuid.PcdArmMaliDpBase + gArmPlatformTokenSpaceGuid.PcdArmMaliDpMemoryRegionLength + [Ppis] gArmMpCoreInfoPpiGuid diff --git a/Platform/ARM/VExpressPkg/Library/ArmVExpressLibRTSM/RTSMMem.c b/Platform/ARM/VExpressPkg/Library/ArmVExpressLibRTSM/RTSMMem.c index 1d5fefc2..c8eefa0c 100644 --- a/Platform/ARM/VExpressPkg/Library/ArmVExpressLibRTSM/RTSMMem.c +++ b/Platform/ARM/VExpressPkg/Library/ArmVExpressLibRTSM/RTSMMem.c @@ -20,8 +20,10 @@ #include #include +#define DP_BASE_DESCRIPTOR ((FixedPcdGet64 (PcdArmMaliDpBase) != 0) ? 1 : 0) + // Number of Virtual Memory Map Descriptors -#define MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS 9 +#define MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS (9 + DP_BASE_DESCRIPTOR) // DDR attributes #define DDR_ATTRIBUTES_CACHED ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK @@ -157,6 +159,14 @@ ArmPlatformGetVirtualMemoryMap ( VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED; } + if (FixedPcdGet64 (PcdArmMaliDpBase) != 0) { + // DP500/DP550/DP650 peripheral memory region + VirtualMemoryTable[++Index].PhysicalBase = FixedPcdGet64 (PcdArmMaliDpBase); + VirtualMemoryTable[Index].VirtualBase = FixedPcdGet64 (PcdArmMaliDpBase); + VirtualMemoryTable[Index].Length = FixedPcdGet32 (PcdArmMaliDpMemoryRegionLength); + VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE; + } + // Map sparse memory region if present if (HasSparseMemory) { VirtualMemoryTable[++Index].PhysicalBase = SparseMemoryBase; -- cgit v1.2.3