From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=2a00:1450:400c:c09::241; helo=mail-wm0-x241.google.com; envelope-from=ard.biesheuvel@linaro.org; receiver=edk2-devel@lists.01.org Received: from mail-wm0-x241.google.com (mail-wm0-x241.google.com [IPv6:2a00:1450:400c:c09::241]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 0476020352A8A for ; Fri, 1 Dec 2017 03:29:07 -0800 (PST) Received: by mail-wm0-x241.google.com with SMTP id r78so2947006wme.5 for ; Fri, 01 Dec 2017 03:33:34 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=oYh/zfjnXYSUyUsBblGWfeNPYRzKybBNZV+evu9MOeI=; b=j3A+WWQK2XU6ivW5liT9RgTBEnKfxeqO78kYo+5ZDM0UikhF986gQ6awqaP5hIdBac dgZK6VlYbZ0yKG5fyR2sywtANNGKHPiBH02D2VWgnv7x8QQp+V9WFPvu/MIGqRU6oCx2 1RZ023FxGQTi8MkKh8daOA7OSQs8qEI2ZTORk= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=oYh/zfjnXYSUyUsBblGWfeNPYRzKybBNZV+evu9MOeI=; b=YmU7hi20rN6y7AkRfxD7yglMC/H01qV9RcRp7OqK5gh9oE29c3GsXZmLRWsUHz0prb vWokm1IZvvrfoR59ms0Xty4sHX7q4vUulJwUyx9YpGrfhHQa3YE+fJpC+SbSQRxLW27Q IvsdW7pK+IrGstOESoazq8LtiWcxWkFH60wd/692lqc7jCgLqcGIg94qD4dHyL+aQApJ bIHII/jC57Apxls9pbRJXfIP7OV/sLeYdLNkG/mK7MkXBUaCj5LFIak4rMq7nHkvKyMX CL6GvM3szb8yd+9M82z/BloAbBIVpu0mX8jY8nKAG7QeftmecbobUrehJgwGa/z6EuBr HoGQ== X-Gm-Message-State: AKGB3mL703ozOGH/esC+P+OyWZqKZDL2FBXPRDQpRaR0C3IUsghxscsM xI4XWRhAOihxyW8vGr6ECpt9fK07Oro= X-Google-Smtp-Source: AGs4zMZTksUpGVqXjoQFN2NWSgpT3odyeoG4gKFpYxQ6hmAnPcuNhTdacbwY+bO3chgFjOesw9k5qA== X-Received: by 10.28.214.145 with SMTP id n139mr1067153wmg.59.1512128012549; Fri, 01 Dec 2017 03:33:32 -0800 (PST) Received: from localhost.localdomain ([105.150.171.234]) by smtp.gmail.com with ESMTPSA id n12sm8150716wrn.76.2017.12.01.03.33.30 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 01 Dec 2017 03:33:31 -0800 (PST) From: Ard Biesheuvel To: edk2-devel@lists.01.org Cc: leif.lindholm@linaro.org, Ard Biesheuvel , Girish Pathak , Evan Lloyd Date: Fri, 1 Dec 2017 11:33:18 +0000 Message-Id: <20171201113321.23642-3-ard.biesheuvel@linaro.org> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20171201113321.23642-1-ard.biesheuvel@linaro.org> References: <20171201113321.23642-1-ard.biesheuvel@linaro.org> Subject: [PATCH edk2-platforms 2/5] Platform/ARM: import PL111 glue library for VExpress X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 01 Dec 2017 11:29:08 -0000 Create a new LcdPlatformLib implementation for PL111 on VExpress, based on the existing code that lives in ArmPlatformPkg. Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Ard Biesheuvel --- Platform/ARM/VExpressPkg/PL111LcdArmVExpressLib/PL111LcdArmVExpress.c | 370 ++++++++++++++++++++ Platform/ARM/VExpressPkg/PL111LcdArmVExpressLib/PL111LcdArmVExpressLib.inf | 44 +++ 2 files changed, 414 insertions(+) diff --git a/Platform/ARM/VExpressPkg/PL111LcdArmVExpressLib/PL111LcdArmVExpress.c b/Platform/ARM/VExpressPkg/PL111LcdArmVExpressLib/PL111LcdArmVExpress.c new file mode 100644 index 000000000000..3f3ceb3d2fa8 --- /dev/null +++ b/Platform/ARM/VExpressPkg/PL111LcdArmVExpressLib/PL111LcdArmVExpress.c @@ -0,0 +1,370 @@ +/** @file + + Copyright (c) 2011-2015, ARM Ltd. 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 + +#include +#include + +#include + +typedef struct { + UINT32 Mode; + UINT32 HorizontalResolution; + UINT32 VerticalResolution; + LCD_BPP Bpp; + UINT32 OscFreq; + + UINT32 HSync; + UINT32 HBackPorch; + UINT32 HFrontPorch; + UINT32 VSync; + UINT32 VBackPorch; + UINT32 VFrontPorch; +} LCD_RESOLUTION; + + +LCD_RESOLUTION mResolutions[] = { + { // Mode 0 : VGA : 640 x 480 x 24 bpp + VGA, VGA_H_RES_PIXELS, VGA_V_RES_PIXELS, LCD_BITS_PER_PIXEL_24, VGA_OSC_FREQUENCY, + VGA_H_SYNC, VGA_H_BACK_PORCH, VGA_H_FRONT_PORCH, + VGA_V_SYNC, VGA_V_BACK_PORCH, VGA_V_FRONT_PORCH + }, + { // Mode 1 : SVGA : 800 x 600 x 24 bpp + SVGA, SVGA_H_RES_PIXELS, SVGA_V_RES_PIXELS, LCD_BITS_PER_PIXEL_24, SVGA_OSC_FREQUENCY, + SVGA_H_SYNC, SVGA_H_BACK_PORCH, SVGA_H_FRONT_PORCH, + SVGA_V_SYNC, SVGA_V_BACK_PORCH, SVGA_V_FRONT_PORCH + }, + { // Mode 2 : XGA : 1024 x 768 x 24 bpp + XGA, XGA_H_RES_PIXELS, XGA_V_RES_PIXELS, LCD_BITS_PER_PIXEL_24, XGA_OSC_FREQUENCY, + XGA_H_SYNC, XGA_H_BACK_PORCH, XGA_H_FRONT_PORCH, + XGA_V_SYNC, XGA_V_BACK_PORCH, XGA_V_FRONT_PORCH + }, + { // Mode 3 : SXGA : 1280 x 1024 x 24 bpp + SXGA, SXGA_H_RES_PIXELS, SXGA_V_RES_PIXELS, LCD_BITS_PER_PIXEL_24, (SXGA_OSC_FREQUENCY/2), + SXGA_H_SYNC, SXGA_H_BACK_PORCH, SXGA_H_FRONT_PORCH, + SXGA_V_SYNC, SXGA_V_BACK_PORCH, SXGA_V_FRONT_PORCH + }, + { // Mode 4 : UXGA : 1600 x 1200 x 24 bpp + UXGA, UXGA_H_RES_PIXELS, UXGA_V_RES_PIXELS, LCD_BITS_PER_PIXEL_24, (UXGA_OSC_FREQUENCY/2), + UXGA_H_SYNC, UXGA_H_BACK_PORCH, UXGA_H_FRONT_PORCH, + UXGA_V_SYNC, UXGA_V_BACK_PORCH, UXGA_V_FRONT_PORCH + }, + { // Mode 5 : HD : 1920 x 1080 x 24 bpp + HD, HD_H_RES_PIXELS, HD_V_RES_PIXELS, LCD_BITS_PER_PIXEL_24, (HD_OSC_FREQUENCY/2), + HD_H_SYNC, HD_H_BACK_PORCH, HD_H_FRONT_PORCH, + HD_V_SYNC, HD_V_BACK_PORCH, HD_V_FRONT_PORCH + }, + { // Mode 6 : VGA : 640 x 480 x 16 bpp (565 Mode) + VGA, VGA_H_RES_PIXELS, VGA_V_RES_PIXELS, LCD_BITS_PER_PIXEL_16_565, VGA_OSC_FREQUENCY, + VGA_H_SYNC, VGA_H_BACK_PORCH, VGA_H_FRONT_PORCH, + VGA_V_SYNC, VGA_V_BACK_PORCH, VGA_V_FRONT_PORCH + }, + { // Mode 7 : SVGA : 800 x 600 x 16 bpp (565 Mode) + SVGA, SVGA_H_RES_PIXELS, SVGA_V_RES_PIXELS, LCD_BITS_PER_PIXEL_16_565, SVGA_OSC_FREQUENCY, + SVGA_H_SYNC, SVGA_H_BACK_PORCH, SVGA_H_FRONT_PORCH, + SVGA_V_SYNC, SVGA_V_BACK_PORCH, SVGA_V_FRONT_PORCH + }, + { // Mode 8 : XGA : 1024 x 768 x 16 bpp (565 Mode) + XGA, XGA_H_RES_PIXELS, XGA_V_RES_PIXELS, LCD_BITS_PER_PIXEL_16_565, XGA_OSC_FREQUENCY, + XGA_H_SYNC, XGA_H_BACK_PORCH, XGA_H_FRONT_PORCH, + XGA_V_SYNC, XGA_V_BACK_PORCH, XGA_V_FRONT_PORCH + }, + { // Mode 9 : VGA : 640 x 480 x 15 bpp + VGA, VGA_H_RES_PIXELS, VGA_V_RES_PIXELS, LCD_BITS_PER_PIXEL_16_555, VGA_OSC_FREQUENCY, + VGA_H_SYNC, VGA_H_BACK_PORCH, VGA_H_FRONT_PORCH, + VGA_V_SYNC, VGA_V_BACK_PORCH, VGA_V_FRONT_PORCH + }, + { // Mode 10 : SVGA : 800 x 600 x 15 bpp + SVGA, SVGA_H_RES_PIXELS, SVGA_V_RES_PIXELS, LCD_BITS_PER_PIXEL_16_555, SVGA_OSC_FREQUENCY, + SVGA_H_SYNC, SVGA_H_BACK_PORCH, SVGA_H_FRONT_PORCH, + SVGA_V_SYNC, SVGA_V_BACK_PORCH, SVGA_V_FRONT_PORCH + }, + { // Mode 11 : XGA : 1024 x 768 x 15 bpp + XGA, XGA_H_RES_PIXELS, XGA_V_RES_PIXELS, LCD_BITS_PER_PIXEL_16_555, XGA_OSC_FREQUENCY, + XGA_H_SYNC, XGA_H_BACK_PORCH, XGA_H_FRONT_PORCH, + XGA_V_SYNC, XGA_V_BACK_PORCH, XGA_V_FRONT_PORCH + }, + { // Mode 12 : XGA : 1024 x 768 x 15 bpp - All the timing info is derived from Linux Kernel Driver Settings + XGA, XGA_H_RES_PIXELS, XGA_V_RES_PIXELS, LCD_BITS_PER_PIXEL_16_555, 63500000, + XGA_H_SYNC, XGA_H_BACK_PORCH, XGA_H_FRONT_PORCH, + XGA_V_SYNC, XGA_V_BACK_PORCH, XGA_V_FRONT_PORCH + }, + { // Mode 13 : VGA : 640 x 480 x 12 bpp (444 Mode) + VGA, VGA_H_RES_PIXELS, VGA_V_RES_PIXELS, LCD_BITS_PER_PIXEL_12_444, VGA_OSC_FREQUENCY, + VGA_H_SYNC, VGA_H_BACK_PORCH, VGA_H_FRONT_PORCH, + VGA_V_SYNC, VGA_V_BACK_PORCH, VGA_V_FRONT_PORCH + }, + { // Mode 14 : SVGA : 800 x 600 x 12 bpp (444 Mode) + SVGA, SVGA_H_RES_PIXELS, SVGA_V_RES_PIXELS, LCD_BITS_PER_PIXEL_12_444, SVGA_OSC_FREQUENCY, + SVGA_H_SYNC, SVGA_H_BACK_PORCH, SVGA_H_FRONT_PORCH, + SVGA_V_SYNC, SVGA_V_BACK_PORCH, SVGA_V_FRONT_PORCH + }, + { // Mode 15 : XGA : 1024 x 768 x 12 bpp (444 Mode) + XGA, XGA_H_RES_PIXELS, XGA_V_RES_PIXELS, LCD_BITS_PER_PIXEL_12_444, XGA_OSC_FREQUENCY, + XGA_H_SYNC, XGA_H_BACK_PORCH, XGA_H_FRONT_PORCH, + XGA_V_SYNC, XGA_V_BACK_PORCH, XGA_V_FRONT_PORCH + } +}; + +EFI_EDID_DISCOVERED_PROTOCOL mEdidDiscovered = { + 0, + NULL +}; + +EFI_EDID_ACTIVE_PROTOCOL mEdidActive = { + 0, + NULL +}; + + +EFI_STATUS +LcdPlatformInitializeDisplay ( + IN EFI_HANDLE Handle + ) +{ + EFI_STATUS Status; + + // Set the FPGA multiplexer to select the video output from the motherboard or the daughterboard + Status = ArmPlatformSysConfigSet (SYS_CFG_MUXFPGA, PL111_CLCD_SITE); + if (!EFI_ERROR(Status)) { + // Install the EDID Protocols + Status = gBS->InstallMultipleProtocolInterfaces( + &Handle, + &gEfiEdidDiscoveredProtocolGuid, &mEdidDiscovered, + &gEfiEdidActiveProtocolGuid, &mEdidActive, + NULL + ); + } + + return Status; +} + +EFI_STATUS +LcdPlatformGetVram ( + OUT EFI_PHYSICAL_ADDRESS* VramBaseAddress, + OUT UINTN* VramSize + ) +{ + EFI_STATUS Status; + + Status = EFI_SUCCESS; + + // Is it on the motherboard or on the daughterboard? + switch(PL111_CLCD_SITE) { + + case ARM_VE_MOTHERBOARD_SITE: + *VramBaseAddress = (EFI_PHYSICAL_ADDRESS) PL111_CLCD_VRAM_MOTHERBOARD_BASE; + *VramSize = LCD_VRAM_SIZE; + break; + + case ARM_VE_DAUGHTERBOARD_1_SITE: + *VramBaseAddress = (EFI_PHYSICAL_ADDRESS) LCD_VRAM_CORE_TILE_BASE; + *VramSize = LCD_VRAM_SIZE; + + // Allocate the VRAM from the DRAM so that nobody else uses it. + Status = gBS->AllocatePages( AllocateAddress, EfiBootServicesData, EFI_SIZE_TO_PAGES(((UINTN)LCD_VRAM_SIZE)), VramBaseAddress); + if (EFI_ERROR(Status)) { + return Status; + } + + // Mark the VRAM as write-combining. The VRAM is inside the DRAM, which is cacheable. + Status = gDS->SetMemorySpaceAttributes (*VramBaseAddress, *VramSize, + EFI_MEMORY_WC); + ASSERT_EFI_ERROR(Status); + if (EFI_ERROR(Status)) { + gBS->FreePages (*VramBaseAddress, EFI_SIZE_TO_PAGES(*VramSize)); + return Status; + } + break; + + default: + // Unsupported site + Status = EFI_UNSUPPORTED; + break; + } + + return Status; +} + +UINT32 +LcdPlatformGetMaxMode ( + VOID + ) +{ + // The following line will report correctly the total number of graphics modes + // supported by the PL111CLCD. + //return (sizeof(mResolutions) / sizeof(CLCD_RESOLUTION)) - 1; + + // However, on some platforms it is desirable to ignore some graphics modes. + // This could be because the specific implementation of PL111 has certain limitations. + + // Set the maximum mode allowed + return (PcdGet32(PcdPL111LcdMaxMode)); +} + +EFI_STATUS +LcdPlatformSetMode ( + IN UINT32 ModeNumber + ) +{ + EFI_STATUS Status; + UINT32 LcdSite; + UINT32 OscillatorId; + SYS_CONFIG_FUNCTION Function; + UINT32 SysId; + + if (ModeNumber >= LcdPlatformGetMaxMode ()) { + return EFI_INVALID_PARAMETER; + } + + LcdSite = PL111_CLCD_SITE; + + switch(LcdSite) { + case ARM_VE_MOTHERBOARD_SITE: + Function = SYS_CFG_OSC; + OscillatorId = PL111_CLCD_MOTHERBOARD_VIDEO_MODE_OSC_ID; + break; + case ARM_VE_DAUGHTERBOARD_1_SITE: + Function = SYS_CFG_OSC_SITE1; + OscillatorId = (UINT32)PcdGet32(PcdPL111LcdVideoModeOscId); + break; + default: + return EFI_UNSUPPORTED; + } + + // Set the video mode oscillator + Status = ArmPlatformSysConfigSetDevice (Function, OscillatorId, mResolutions[ModeNumber].OscFreq); + if (EFI_ERROR(Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + + // The FVP foundation model does not have an LCD. + // On the FVP models the GIC variant in encoded in bits [15:12]. + // Note: The DVI Mode is not modelled by RTSM or FVP models. + SysId = MmioRead32 (ARM_VE_SYS_ID_REG); + if (SysId != ARM_RTSM_SYS_ID) { + // Take out the FVP GIC variant to reduce the permutations. + SysId &= ~ARM_FVP_SYS_ID_VARIANT_MASK; + if (SysId != ARM_FVP_BASE_BOARD_SYS_ID) { + // Set the DVI into the new mode + Status = ArmPlatformSysConfigSet (SYS_CFG_DVIMODE, mResolutions[ModeNumber].Mode); + if (EFI_ERROR(Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + } + } + + // Set the multiplexer + Status = ArmPlatformSysConfigSet (SYS_CFG_MUXFPGA, LcdSite); + if (EFI_ERROR(Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + + return Status; +} + +EFI_STATUS +LcdPlatformQueryMode ( + IN UINT32 ModeNumber, + OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info + ) +{ + if (ModeNumber >= LcdPlatformGetMaxMode ()) { + return EFI_INVALID_PARAMETER; + } + + Info->Version = 0; + Info->HorizontalResolution = mResolutions[ModeNumber].HorizontalResolution; + Info->VerticalResolution = mResolutions[ModeNumber].VerticalResolution; + Info->PixelsPerScanLine = mResolutions[ModeNumber].HorizontalResolution; + + switch (mResolutions[ModeNumber].Bpp) { + case LCD_BITS_PER_PIXEL_24: + Info->PixelFormat = PixelRedGreenBlueReserved8BitPerColor; + Info->PixelInformation.RedMask = LCD_24BPP_RED_MASK; + Info->PixelInformation.GreenMask = LCD_24BPP_GREEN_MASK; + Info->PixelInformation.BlueMask = LCD_24BPP_BLUE_MASK; + Info->PixelInformation.ReservedMask = LCD_24BPP_RESERVED_MASK; + break; + + case LCD_BITS_PER_PIXEL_16_555: + case LCD_BITS_PER_PIXEL_16_565: + case LCD_BITS_PER_PIXEL_12_444: + case LCD_BITS_PER_PIXEL_8: + case LCD_BITS_PER_PIXEL_4: + case LCD_BITS_PER_PIXEL_2: + case LCD_BITS_PER_PIXEL_1: + default: + // These are not supported + ASSERT(FALSE); + break; + } + + return EFI_SUCCESS; +} + +EFI_STATUS +LcdPlatformGetTimings ( + IN UINT32 ModeNumber, + OUT UINT32* HRes, + OUT UINT32* HSync, + OUT UINT32* HBackPorch, + OUT UINT32* HFrontPorch, + OUT UINT32* VRes, + OUT UINT32* VSync, + OUT UINT32* VBackPorch, + OUT UINT32* VFrontPorch + ) +{ + if (ModeNumber >= LcdPlatformGetMaxMode ()) { + return EFI_INVALID_PARAMETER; + } + + *HRes = mResolutions[ModeNumber].HorizontalResolution; + *HSync = mResolutions[ModeNumber].HSync; + *HBackPorch = mResolutions[ModeNumber].HBackPorch; + *HFrontPorch = mResolutions[ModeNumber].HFrontPorch; + *VRes = mResolutions[ModeNumber].VerticalResolution; + *VSync = mResolutions[ModeNumber].VSync; + *VBackPorch = mResolutions[ModeNumber].VBackPorch; + *VFrontPorch = mResolutions[ModeNumber].VFrontPorch; + + return EFI_SUCCESS; +} + +EFI_STATUS +LcdPlatformGetBpp ( + IN UINT32 ModeNumber, + OUT LCD_BPP * Bpp + ) +{ + if (ModeNumber >= LcdPlatformGetMaxMode ()) { + return EFI_INVALID_PARAMETER; + } + + *Bpp = mResolutions[ModeNumber].Bpp; + + return EFI_SUCCESS; +} diff --git a/Platform/ARM/VExpressPkg/PL111LcdArmVExpressLib/PL111LcdArmVExpressLib.inf b/Platform/ARM/VExpressPkg/PL111LcdArmVExpressLib/PL111LcdArmVExpressLib.inf new file mode 100644 index 000000000000..14b63d3c2cc3 --- /dev/null +++ b/Platform/ARM/VExpressPkg/PL111LcdArmVExpressLib/PL111LcdArmVExpressLib.inf @@ -0,0 +1,44 @@ +#/** @file +# +# Component description file for ArmVeGraphicsDxe module +# +# Copyright (c) 2011-2012, ARM Ltd. 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 = 0x0001001A + BASE_NAME = PL111LcdArmVExpressLib + FILE_GUID = 5c60eef8-3c2a-45c0-823a-e0e06ca3c537 + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = LcdPlatformLib + +[Sources.common] + PL111LcdArmVExpress.c + +[Packages] + ArmPlatformPkg/ArmPlatformPkg.dec + MdePkg/MdePkg.dec + Platform/ARM/VExpressPkg/ArmVExpressPkg.dec + +[LibraryClasses] + ArmPlatformSysConfigLib + BaseLib + DxeServicesTableLib + +[Protocols] + gEfiEdidDiscoveredProtocolGuid # PRODUCES + gEfiEdidActiveProtocolGuid # PRODUCES + +[Pcd] + gVExpressTokenSpaceGuid.PcdPL111LcdMaxMode + gVExpressTokenSpaceGuid.PcdPL111LcdVideoModeOscId -- 2.11.0