diff options
Diffstat (limited to 'ArmPlatformPkg')
13 files changed, 2341 insertions, 9 deletions
diff --git a/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-CTA9x4.dsc b/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-CTA9x4.dsc index 628c4077cb..0d6a028ebd 100644 --- a/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-CTA9x4.dsc +++ b/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-CTA9x4.dsc @@ -104,6 +104,7 @@ ArmPlatformSysConfigLib|ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressSysConfigLib/ArmVExpressSysConfigLib.inf NorFlashPlatformLib|ArmPlatformPkg/ArmVExpressPkg/Library/NorFlashArmVExpressLib/NorFlashArmVExpressLib.inf + LcdPlatformLib|ArmPlatformPkg/ArmVExpressPkg/Library/PL111LcdArmVExpressLib/PL111LcdArmVExpressLib.inf # # Assume everything is fixed at build @@ -414,15 +415,6 @@ gArmTokenSpaceGuid.PcdFdtDP|L"" # - # ARM PL111 Colour LCD Controller - # - gArmVExpressTokenSpaceGuid.PcdPL111RegistersBaseMotherboard|0x1001F000 - gArmVExpressTokenSpaceGuid.PcdPL111RegistersBaseDaughterboard|0x10020000 - gArmVExpressTokenSpaceGuid.PcdPL111VRamBaseMotherboard|0x4C000000 - gArmVExpressTokenSpaceGuid.PcdPL111VRamBaseDaughterboard|0x64000000 - gArmVExpressTokenSpaceGuid.PcdPL111VRamSize|0x800000 - - # # ARM L2x0 PCDs # gArmTokenSpaceGuid.PcdL2x0ControllerBase|0x1E00A000 @@ -496,6 +488,7 @@ ArmPkg/Drivers/PL390Gic/PL390GicDxe.inf ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.inf ArmPlatformPkg/Drivers/SP804TimerDxe/SP804TimerDxe.inf + ArmPlatformPkg/Drivers/LcdGraphicsOutputDxe/PL111LcdGraphicsOutputDxe.inf # # Semi-hosting filesystem diff --git a/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-CTA9x4.fdf b/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-CTA9x4.fdf index 1932df4677..e1571e0a18 100644 --- a/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-CTA9x4.fdf +++ b/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-CTA9x4.fdf @@ -161,6 +161,7 @@ READ_LOCK_STATUS = TRUE INF ArmPkg/Drivers/PL390Gic/PL390GicDxe.inf INF ArmPlatformPkg/Drivers/SP804TimerDxe/SP804TimerDxe.inf INF ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.inf + INF ArmPlatformPkg/Drivers/LcdGraphicsOutputDxe/PL111LcdGraphicsOutputDxe.inf # # Semi-hosting filesystem diff --git a/ArmPlatformPkg/ArmVExpressPkg/ArmVExpressPkg.dec b/ArmPlatformPkg/ArmVExpressPkg/ArmVExpressPkg.dec index db2ae55e07..307e672cd0 100644 --- a/ArmPlatformPkg/ArmVExpressPkg/ArmVExpressPkg.dec +++ b/ArmPlatformPkg/ArmVExpressPkg/ArmVExpressPkg.dec @@ -41,3 +41,10 @@ [PcdsFeatureFlag.common] [PcdsFixedAtBuild.common] + # + # MaxMode must be one number higher than the actual max mode, + # i.e. for actual maximum mode 2, set the value to 3. + # + # For a list of mode numbers look in LcdArmVExpress.c + # + gArmVExpressTokenSpaceGuid.PcdPL111MaxMode|3|UINT32|0x00000003 diff --git a/ArmPlatformPkg/ArmVExpressPkg/Include/Platform/CTA9x4/ArmPlatform.h b/ArmPlatformPkg/ArmVExpressPkg/Include/Platform/CTA9x4/ArmPlatform.h index 3dc622ecc3..1b64392b2e 100644 --- a/ArmPlatformPkg/ArmVExpressPkg/Include/Platform/CTA9x4/ArmPlatform.h +++ b/ArmPlatformPkg/ArmVExpressPkg/Include/Platform/CTA9x4/ArmPlatform.h @@ -54,6 +54,8 @@ // DRAM
#define ARM_VE_DRAM_BASE 0x60000000
#define ARM_VE_DRAM_SZ 0x40000000
+// Inside the DRAM we allocate a section for the VRAM (Video RAM)
+#define LCD_VRAM_CORE_TILE_BASE 0x64000000
// External AXI between daughterboards (Logic Tile)
#define ARM_VE_EXT_AXI_BASE 0xE0000000
@@ -97,6 +99,14 @@ //#define ARM_VE_L2x0_CTLR_BASE 0x1E00A000
/***********************************************************************************
+ Select between Motherboard and Core Tile peripherals
+************************************************************************************/
+
+// Specify which PL111 to use
+//#define PL111_CLCD_BASE PL111_CLCD_MOTHERBOARD_BASE
+#define PL111_CLCD_BASE PL111_CLCD_CORE_TILE_BASE
+
+/***********************************************************************************
Peripherals' misc settings
************************************************************************************/
@@ -117,6 +127,9 @@ #define ARM_VE_DECPROT_BIT_SMC_TZASC_LOCK (1 << 5)
+// PL111 Lcd
+#define PL111_CLCD_CORE_TILE_VIDEO_MODE_OSC_ID 1
+
/***********************************************************************************
// Interrupt Map
************************************************************************************/
diff --git a/ArmPlatformPkg/ArmVExpressPkg/Library/PL111LcdArmVExpressLib/PL111LcdArmVExpress.c b/ArmPlatformPkg/ArmVExpressPkg/Library/PL111LcdArmVExpressLib/PL111LcdArmVExpress.c new file mode 100644 index 0000000000..6ae5da9997 --- /dev/null +++ b/ArmPlatformPkg/ArmVExpressPkg/Library/PL111LcdArmVExpressLib/PL111LcdArmVExpress.c @@ -0,0 +1,336 @@ +/** @file
+
+ Copyright (c) 2011, ARM Ltd. All rights reserved.<BR>
+ 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 <PiDxe.h>
+
+#include <Library/ArmPlatformSysConfigLib.h>
+#include <Library/IoLib.h>
+#include <Library/PcdLib.h>
+#include <Library/DebugLib.h>
+#include <Library/LcdPlatformLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+
+#include <Protocol/Cpu.h>
+
+#include <ArmPlatform.h>
+
+#define PL111_CLCD_SITE ARM_VE_DAUGHTERBOARD_1_SITE
+
+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_STATUS
+LcdPlatformInitializeDisplay (
+ VOID
+ ) {
+ // Set the FPGA multiplexer to select the video output from the motherboard or the daughterboard
+ return ArmPlatformSysConfigSet (SYS_CFG_MUXFPGA, PL111_CLCD_SITE);
+}
+
+EFI_STATUS
+LcdPlatformGetVram (
+ OUT EFI_PHYSICAL_ADDRESS* VramBaseAddress,
+ OUT UINTN* VramSize
+ )
+{
+ EFI_STATUS Status;
+ EFI_CPU_ARCH_PROTOCOL *Cpu;
+
+ // 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;
+ }
+
+ // Ensure the Cpu architectural protocol is already installed
+ Status = gBS->LocateProtocol (&gEfiCpuArchProtocolGuid, NULL, (VOID **)&Cpu);
+ ASSERT_EFI_ERROR(Status);
+
+ // Mark the VRAM as un-cachable. The VRAM is inside the DRAM, which is cachable.
+ Status = Cpu->SetMemoryAttributes(Cpu, *VramBaseAddress, *VramSize, EFI_MEMORY_UC);
+ ASSERT_EFI_ERROR(Status);
+ if (EFI_ERROR(Status)) {
+ gBS->FreePool(VramBaseAddress);
+ 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(PcdPL111MaxMode));
+}
+
+EFI_STATUS
+LcdPlatformSetMode (
+ IN UINT32 ModeNumber
+ )
+{
+ EFI_STATUS Status;
+ UINT32 LcdSite;
+ UINT32 OscillatorId;
+ SYS_CONFIG_FUNCTION Function;
+
+ 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 = PL111_CLCD_CORE_TILE_VIDEO_MODE_OSC_ID;
+ 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;
+ }
+
+ // 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/ArmPlatformPkg/ArmVExpressPkg/Library/PL111LcdArmVExpressLib/PL111LcdArmVExpressLib.inf b/ArmPlatformPkg/ArmVExpressPkg/Library/PL111LcdArmVExpressLib/PL111LcdArmVExpressLib.inf new file mode 100644 index 0000000000..6edca3ba09 --- /dev/null +++ b/ArmPlatformPkg/ArmVExpressPkg/Library/PL111LcdArmVExpressLib/PL111LcdArmVExpressLib.inf @@ -0,0 +1,47 @@ +#/** @file +# +# Component discription file for ArmVeGraphicsDxe module +# +# Copyright (c) 2011, ARM Ltd. All rights reserved.<BR> +# 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 = 0x00010005 + BASE_NAME = PL111LcdArmVExpressLib + FILE_GUID = b7f06f20-496f-11e0-a8e8-0002a5d5c51b + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + LIBRARY_CLASS = LcdPlatformLib + +[Sources.common] + PL111LcdArmVExpress.c + +[Packages] + MdePkg/MdePkg.dec + ArmPlatformPkg/ArmVExpressPkg/ArmVExpressPkg.dec + ArmPlatformPkg/ArmPlatformPkg.dec + +[LibraryClasses] + BaseLib + ArmPlatformSysConfigLib + +[Guids] + +[Protocols] + +[FeaturePcd] + +[FixedPcd.common] + gArmVExpressTokenSpaceGuid.PcdPL111MaxMode + +[Pcd.common] + +[Depex] diff --git a/ArmPlatformPkg/Drivers/LcdGraphicsOutputDxe/LcdGraphicsOutputBlt.c b/ArmPlatformPkg/Drivers/LcdGraphicsOutputDxe/LcdGraphicsOutputBlt.c new file mode 100644 index 0000000000..679ccc8256 --- /dev/null +++ b/ArmPlatformPkg/Drivers/LcdGraphicsOutputDxe/LcdGraphicsOutputBlt.c @@ -0,0 +1,885 @@ +/** @file + + Copyright (c) 2011, ARM Ltd. All rights reserved.<BR> + 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 <PiDxe.h> +#include <Library/PcdLib.h> +#include <Library/DebugLib.h> +#include <Library/BaseMemoryLib.h> +#include <Library/DevicePathLib.h> +#include <Library/UefiBootServicesTableLib.h> +#include <Library/UefiRuntimeServicesTableLib.h> +#include <Library/MemoryAllocationLib.h> + +#include <Guid/GlobalVariable.h> + +#include <ArmPlatform.h> +#include "LcdGraphicsOutputDxe.h" + +extern BOOLEAN mDisplayInitialized; + +// +// Function Definitions +// + +STATIC +EFI_STATUS +VideoCopyNoHorizontalOverlap ( + IN UINTN BitsPerPixel, + IN volatile VOID *FrameBufferBase, + IN UINT32 HorizontalResolution, + IN UINTN SourceX, + IN UINTN SourceY, + IN UINTN DestinationX, + IN UINTN DestinationY, + IN UINTN Width, + IN UINTN Height +) +{ + EFI_STATUS Status = EFI_SUCCESS; + UINTN SourceLine; + UINTN DestinationLine; + UINTN WidthInBytes; + UINTN LineCount; + INTN Step; + VOID *SourceAddr; + VOID *DestinationAddr; + + if( DestinationY <= SourceY ) { + // scrolling up (or horizontally but without overlap) + SourceLine = SourceY; + DestinationLine = DestinationY; + Step = 1; + } else { + // scrolling down + SourceLine = SourceY + Height; + DestinationLine = DestinationY + Height; + Step = -1; + } + + switch (BitsPerPixel) { + + case LCD_BITS_PER_PIXEL_24: + + WidthInBytes = Width * 4; + + for( LineCount = 0; LineCount < Height; LineCount++ ) { + // Update the start addresses of source & destination using 32bit pointer arithmetic + SourceAddr = (VOID *)((UINT32 *)FrameBufferBase + SourceLine * HorizontalResolution + SourceX ); + DestinationAddr = (VOID *)((UINT32 *)FrameBufferBase + DestinationLine * HorizontalResolution + DestinationX); + + // Copy the entire line Y from video ram to the temp buffer + CopyMem( DestinationAddr, SourceAddr, WidthInBytes); + + // Update the line numbers + SourceLine += Step; + DestinationLine += Step; + } + break; + + case LCD_BITS_PER_PIXEL_16_555: + case LCD_BITS_PER_PIXEL_16_565: + case LCD_BITS_PER_PIXEL_12_444: + + WidthInBytes = Width * 2; + + for( LineCount = 0; LineCount < Height; LineCount++ ) { + // Update the start addresses of source & destination using 16bit pointer arithmetic + SourceAddr = (VOID *)((UINT16 *)FrameBufferBase + SourceLine * HorizontalResolution + SourceX ); + DestinationAddr = (VOID *)((UINT16 *)FrameBufferBase + DestinationLine * HorizontalResolution + DestinationX); + + // Copy the entire line Y from video ram to the temp buffer + CopyMem( DestinationAddr, SourceAddr, WidthInBytes); + + // Update the line numbers + SourceLine += Step; + DestinationLine += Step; + } + break; + + 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: + // Can't handle this case + DEBUG((DEBUG_ERROR, "ArmVeGraphics_Blt: EfiBltVideoToVideo: INVALID Number of Bits Per Pixel: %d\n", BitsPerPixel)); + Status = EFI_INVALID_PARAMETER; + goto EXIT; + // break; + + } + + EXIT: + return Status; +} + +STATIC +EFI_STATUS +VideoCopyHorizontalOverlap ( + IN UINTN BitsPerPixel, + IN volatile VOID *FrameBufferBase, + UINT32 HorizontalResolution, + IN UINTN SourceX, + IN UINTN SourceY, + IN UINTN DestinationX, + IN UINTN DestinationY, + IN UINTN Width, + IN UINTN Height +) +{ + EFI_STATUS Status = EFI_SUCCESS; + + UINT32 *PixelBuffer32bit; + UINT32 *SourcePixel32bit; + UINT32 *DestinationPixel32bit; + + UINT16 *PixelBuffer16bit; + UINT16 *SourcePixel16bit; + UINT16 *DestinationPixel16bit; + + UINT32 SourcePixelY; + UINT32 DestinationPixelY; + UINTN SizeIn32Bits; + UINTN SizeIn16Bits; + + switch (BitsPerPixel) { + + case LCD_BITS_PER_PIXEL_24: + // Allocate a temporary buffer + + PixelBuffer32bit = (UINT32 *) AllocatePool((Height * Width) * sizeof(UINT32)); + + if (PixelBuffer32bit == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto EXIT; + } + + SizeIn32Bits = Width * 4; + + // Copy from the video ram (source region) to a temp buffer + for (SourcePixelY = SourceY, DestinationPixel32bit = PixelBuffer32bit; + SourcePixelY < SourceY + Height; + SourcePixelY++, DestinationPixel32bit += Width) + { + // Update the start address of line Y (source) + SourcePixel32bit = (UINT32 *)FrameBufferBase + SourcePixelY * HorizontalResolution + SourceX; + + // Copy the entire line Y from video ram to the temp buffer + CopyMem( (VOID *)DestinationPixel32bit, (CONST VOID *)SourcePixel32bit, SizeIn32Bits); + } + + // Copy from the temp buffer to the video ram (destination region) + for (DestinationPixelY = DestinationY, SourcePixel32bit = PixelBuffer32bit; + DestinationPixelY < DestinationY + Height; + DestinationPixelY++, SourcePixel32bit += Width) + { + // Update the start address of line Y (target) + DestinationPixel32bit = (UINT32 *)FrameBufferBase + DestinationPixelY * HorizontalResolution + DestinationX; + + // Copy the entire line Y from the temp buffer to video ram + CopyMem( (VOID *)DestinationPixel32bit, (CONST VOID *)SourcePixel32bit, SizeIn32Bits); + } + + // Free up the allocated memory + FreePool((VOID *) PixelBuffer32bit); + + break; + + + case LCD_BITS_PER_PIXEL_16_555: + case LCD_BITS_PER_PIXEL_16_565: + case LCD_BITS_PER_PIXEL_12_444: + // Allocate a temporary buffer + PixelBuffer16bit = (UINT16 *) AllocatePool((Height * Width) * sizeof(UINT16)); + + if (PixelBuffer16bit == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto EXIT; + } + + // Access each pixel inside the source area of the Video Memory and copy it to the temp buffer + + SizeIn16Bits = Width * 2; + + for (SourcePixelY = SourceY, DestinationPixel16bit = PixelBuffer16bit; + SourcePixelY < SourceY + Height; + SourcePixelY++, DestinationPixel16bit += Width) + { + // Calculate the source address: + SourcePixel16bit = (UINT16 *)FrameBufferBase + SourcePixelY * HorizontalResolution + SourceX; + + // Copy the entire line Y from Video to the temp buffer + CopyMem( (VOID *)DestinationPixel16bit, (CONST VOID *)SourcePixel16bit, SizeIn16Bits); + } + + // Copy from the temp buffer into the destination area of the Video Memory + + for (DestinationPixelY = DestinationY, SourcePixel16bit = PixelBuffer16bit; + DestinationPixelY < DestinationY + Height; + DestinationPixelY++, SourcePixel16bit += Width) + { + // Calculate the target address: + DestinationPixel16bit = (UINT16 *)FrameBufferBase + (DestinationPixelY * HorizontalResolution + DestinationX); + + // Copy the entire line Y from the temp buffer to Video + CopyMem( (VOID *)DestinationPixel16bit, (CONST VOID *)SourcePixel16bit, SizeIn16Bits); + } + + // Free the allocated memory + FreePool((VOID *) PixelBuffer16bit); + + break; + + + 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: + // Can't handle this case + DEBUG((DEBUG_ERROR, "ArmVeGraphics_Blt: EfiBltVideoToVideo: INVALID Number of Bits Per Pixel: %d\n", BitsPerPixel)); + Status = EFI_INVALID_PARAMETER; + goto EXIT; + // break; + + } + +EXIT: + return Status; +} + +STATIC +EFI_STATUS +BltVideoFill ( + IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This, + IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL *EfiSourcePixel, OPTIONAL + IN UINTN SourceX, + IN UINTN SourceY, + IN UINTN DestinationX, + IN UINTN DestinationY, + IN UINTN Width, + IN UINTN Height, + IN UINTN Delta OPTIONAL // Number of BYTES in a row of the BltBuffer + ) +{ + EFI_PIXEL_BITMASK* PixelInformation; + EFI_STATUS Status; + UINT32 HorizontalResolution; + LCD_BPP BitsPerPixel; + VOID *FrameBufferBase; + VOID *DestinationAddr; + UINT16 *DestinationPixel16bit; + UINT16 Pixel16bit; + UINT32 DestinationPixelX; + UINT32 DestinationLine; + UINTN WidthInBytes; + + Status = EFI_SUCCESS; + PixelInformation = &This->Mode->Info->PixelInformation; + FrameBufferBase = (UINTN *)((UINTN)(This->Mode->FrameBufferBase)); + HorizontalResolution = This->Mode->Info->HorizontalResolution; + + LcdPlatformGetBpp (This->Mode->Mode,&BitsPerPixel); + + switch (BitsPerPixel) { + case LCD_BITS_PER_PIXEL_24: + WidthInBytes = Width * 4; + + // Copy the SourcePixel into every pixel inside the target rectangle + for (DestinationLine = DestinationY; + DestinationLine < DestinationY + Height; + DestinationLine++) + { + // Calculate the target address using 32bit pointer arithmetic: + DestinationAddr = (VOID *)((UINT32 *)FrameBufferBase + DestinationLine * HorizontalResolution + DestinationX); + + // Fill the entire line + SetMemN( DestinationAddr, WidthInBytes, *((UINTN *)EfiSourcePixel)); + } + break; + + case LCD_BITS_PER_PIXEL_16_555: + // Convert the EFI pixel at the start of the BltBuffer(0,0) into a video display pixel + Pixel16bit = (UINT16) ( + ( (EfiSourcePixel->Red << 7) & PixelInformation->RedMask ) + | ( (EfiSourcePixel->Green << 2) & PixelInformation->GreenMask ) + | ( (EfiSourcePixel->Blue >> 3) & PixelInformation->BlueMask ) +// | ( 0 & PixelInformation->ReservedMask ) + ); + + // Copy the SourcePixel into every pixel inside the target rectangle + for (DestinationLine = DestinationY; + DestinationLine < DestinationY + Height; + DestinationLine++) + { + for (DestinationPixelX = DestinationX; + DestinationPixelX < DestinationX + Width; + DestinationPixelX++) + { + // Calculate the target address: + DestinationPixel16bit = (UINT16 *)FrameBufferBase + DestinationLine * HorizontalResolution + DestinationPixelX; + + // Copy the pixel into the new target + *DestinationPixel16bit = Pixel16bit; + } + } + break; + + case LCD_BITS_PER_PIXEL_16_565: + // Convert the EFI pixel at the start of the BltBuffer(0,0) into a video display pixel + Pixel16bit = (UINT16) ( + ( (EfiSourcePixel->Red << 8) & PixelInformation->RedMask ) + | ( (EfiSourcePixel->Green << 3) & PixelInformation->GreenMask ) + | ( (EfiSourcePixel->Blue >> 3) & PixelInformation->BlueMask ) + ); + + // Copy the SourcePixel into every pixel inside the target rectangle + for (DestinationLine = DestinationY; + DestinationLine < DestinationY + Height; + DestinationLine++) + { + for (DestinationPixelX = DestinationX; + DestinationPixelX < DestinationX + Width; + DestinationPixelX++) + { + // Calculate the target address: + DestinationPixel16bit = (UINT16 *)FrameBufferBase + DestinationLine * HorizontalResolution + DestinationPixelX; + + // Copy the pixel into the new target + *DestinationPixel16bit = Pixel16bit; + } + } + break; + + case LCD_BITS_PER_PIXEL_12_444: + // Convert the EFI pixel at the start of the BltBuffer(0,0) into a video display pixel + Pixel16bit = (UINT16) ( + ( (EfiSourcePixel->Red >> 4) & PixelInformation->RedMask ) + | ( (EfiSourcePixel->Green ) & PixelInformation->GreenMask ) + | ( (EfiSourcePixel->Blue << 4) & PixelInformation->BlueMask ) + ); + + // Copy the SourcePixel into every pixel inside the target rectangle + for (DestinationLine = DestinationY; + DestinationLine < DestinationY + Height; + DestinationLine++) + { + for (DestinationPixelX = DestinationX; + DestinationPixelX < DestinationX + Width; + DestinationPixelX++) + { + // Calculate the target address: + DestinationPixel16bit = (UINT16 *)FrameBufferBase + DestinationLine * HorizontalResolution + DestinationPixelX; + + // Copy the pixel into the new target + *DestinationPixel16bit = Pixel16bit; + } + } + break; + + 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: + // Can't handle this case + DEBUG((DEBUG_ERROR, "LcdGraphicsBlt: EfiBltVideoFill: INVALID Number of Bits Per Pixel: %d\n", BitsPerPixel)); + Status = EFI_INVALID_PARAMETER; + break; + } + + return Status; +} + +STATIC +EFI_STATUS +BltVideoToBltBuffer ( + IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This, + IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer, OPTIONAL + IN UINTN SourceX, + IN UINTN SourceY, + IN UINTN DestinationX, + IN UINTN DestinationY, + IN UINTN Width, + IN UINTN Height, + IN UINTN Delta OPTIONAL // Number of BYTES in a row of the BltBuffer + ) +{ + EFI_STATUS Status; + UINT32 HorizontalResolution; + LCD_BPP BitsPerPixel; + EFI_PIXEL_BITMASK *PixelInformation; + EFI_GRAPHICS_OUTPUT_BLT_PIXEL *EfiDestinationPixel; + VOID *FrameBufferBase; + VOID *SourceAddr; + VOID *DestinationAddr; + UINT16 *SourcePixel16bit; + UINT16 Pixel16bit; + UINT32 SourcePixelX; + UINT32 SourceLine; + UINT32 DestinationPixelX; + UINT32 DestinationLine; + UINT32 BltBufferHorizontalResolution; + UINTN WidthInBytes; + + Status = EFI_SUCCESS; + PixelInformation = &This->Mode->Info->PixelInformation; + HorizontalResolution = This->Mode->Info->HorizontalResolution; + FrameBufferBase = (UINTN *)((UINTN)(This->Mode->FrameBufferBase)); + + if(( Delta != 0 ) && ( Delta != Width * sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL))) { + // Delta is not zero and it is different from the width. + // Divide it by the size of a pixel to find out the buffer's horizontal resolution. + BltBufferHorizontalResolution = (UINT32) (Delta / sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL)); + } else { + BltBufferHorizontalResolution = Width; + } + + LcdPlatformGetBpp (This->Mode->Mode,&BitsPerPixel); + + switch (BitsPerPixel) { + case LCD_BITS_PER_PIXEL_24: + WidthInBytes = Width * 4; + + // Access each line inside the Video Memory + for (SourceLine = SourceY, DestinationLine = DestinationY; + SourceLine < SourceY + Height; + SourceLine++, DestinationLine++) + { + // Calculate the source and target addresses using 32bit pointer arithmetic: + SourceAddr = (VOID *)((UINT32 *)FrameBufferBase + SourceLine * HorizontalResolution + SourceX ); + DestinationAddr = (VOID *)((UINT32 *)BltBuffer + DestinationLine * BltBufferHorizontalResolution + DestinationX); + + // Copy the entire line + CopyMem( DestinationAddr, SourceAddr, WidthInBytes); + } + break; + + case LCD_BITS_PER_PIXEL_16_555: + // Access each pixel inside the Video Memory + for (SourceLine = SourceY, DestinationLine = DestinationY; + SourceLine < SourceY + Height; + SourceLine++, DestinationLine++) + { + for (SourcePixelX = SourceX, DestinationPixelX = DestinationX; + SourcePixelX < SourceX + Width; + SourcePixelX++, DestinationPixelX++) + { + // Calculate the source and target addresses: + SourcePixel16bit = (UINT16 *)FrameBufferBase + SourceLine * HorizontalResolution + SourcePixelX; + EfiDestinationPixel = BltBuffer + DestinationLine * BltBufferHorizontalResolution + DestinationPixelX; + + // Snapshot the pixel from the video buffer once, to speed up the operation. + // If we were dereferencing the pointer, as it is volatile, we would perform 3 memory read operations. + Pixel16bit = *SourcePixel16bit; + + // Copy the pixel into the new target + EfiDestinationPixel->Red = (UINT8) ( (Pixel16bit & PixelInformation->RedMask ) >> 7 ); + EfiDestinationPixel->Green = (UINT8) ( (Pixel16bit & PixelInformation->GreenMask ) >> 2); + EfiDestinationPixel->Blue = (UINT8) ( (Pixel16bit & PixelInformation->BlueMask ) << 3 ); + // EfiDestinationPixel->Reserved = (UINT8) 0; + } + } + break; + + case LCD_BITS_PER_PIXEL_16_565: + // Access each pixel inside the Video Memory + for (SourceLine = SourceY, DestinationLine = DestinationY; + SourceLine < SourceY + Height; + SourceLine++, DestinationLine++) + { + for (SourcePixelX = SourceX, DestinationPixelX = DestinationX; + SourcePixelX < SourceX + Width; + SourcePixelX++, DestinationPixelX++) + { + // Calculate the source and target addresses: + SourcePixel16bit = (UINT16 *)FrameBufferBase + SourceLine * HorizontalResolution + SourcePixelX; + EfiDestinationPixel = BltBuffer + DestinationLine * BltBufferHorizontalResolution + DestinationPixelX; + + // Snapshot the pixel from the video buffer once, to speed up the operation. + // If we were dereferencing the pointer, as it is volatile, we would perform 3 memory read operations. + Pixel16bit = *SourcePixel16bit; + + // Copy the pixel into the new target + // There is no info for the Reserved byte, so we set it to zero + EfiDestinationPixel->Red = (UINT8) ( (Pixel16bit & PixelInformation->RedMask ) >> 8 ); + EfiDestinationPixel->Green = (UINT8) ( (Pixel16bit & PixelInformation->GreenMask ) >> 3); + EfiDestinationPixel->Blue = (UINT8) ( (Pixel16bit & PixelInformation->BlueMask ) << 3 ); + // EfiDestinationPixel->Reserved = (UINT8) 0; + } + } + break; + + case LCD_BITS_PER_PIXEL_12_444: + // Access each pixel inside the Video Memory + for (SourceLine = SourceY, DestinationLine = DestinationY; + SourceLine < SourceY + Height; + SourceLine++, DestinationLine++) + { + for (SourcePixelX = SourceX, DestinationPixelX = DestinationX; + SourcePixelX < SourceX + Width; + SourcePixelX++, DestinationPixelX++) + { + // Calculate the source and target addresses: + SourcePixel16bit = (UINT16 *)FrameBufferBase + SourceLine * HorizontalResolution + SourcePixelX; + EfiDestinationPixel = BltBuffer + DestinationLine * BltBufferHorizontalResolution + DestinationPixelX; + + // Snapshot the pixel from the video buffer once, to speed up the operation. + // If we were dereferencing the pointer, as it is volatile, we would perform 3 memory read operations. + Pixel16bit = *SourcePixel16bit; + + // Copy the pixel into the new target + EfiDestinationPixel->Red = (UINT8) ( (Pixel16bit & PixelInformation->RedMask ) >> 4 ); + EfiDestinationPixel->Green = (UINT8) ( (Pixel16bit & PixelInformation->GreenMask ) ); + EfiDestinationPixel->Blue = (UINT8) ( (Pixel16bit & PixelInformation->BlueMask ) << 4 ); + // EfiDestinationPixel->Reserved = (UINT8) 0; + } + } + break; + + 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: + // Can't handle this case + DEBUG((DEBUG_ERROR, "LcdGraphicsBlt: EfiBltVideoToBltBuffer: INVALID Number of Bits Per Pixel: %d\n", BitsPerPixel)); + Status = EFI_INVALID_PARAMETER; + break; + } + return Status; +} + +STATIC +EFI_STATUS +BltBufferToVideo ( + IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This, + IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer, OPTIONAL + IN UINTN SourceX, + IN UINTN SourceY, + IN UINTN DestinationX, + IN UINTN DestinationY, + IN UINTN Width, + IN UINTN Height, + IN UINTN Delta OPTIONAL // Number of BYTES in a row of the BltBuffer + ) +{ + EFI_STATUS Status; + UINT32 HorizontalResolution; + LCD_BPP BitsPerPixel; + EFI_PIXEL_BITMASK *PixelInformation; + EFI_GRAPHICS_OUTPUT_BLT_PIXEL *EfiSourcePixel; + VOID *FrameBufferBase; + VOID *SourceAddr; + VOID *DestinationAddr; + UINT16 *DestinationPixel16bit; + UINT32 SourcePixelX; + UINT32 SourceLine; + UINT32 DestinationPixelX; + UINT32 DestinationLine; + UINT32 BltBufferHorizontalResolution; + UINTN WidthInBytes; + + Status = EFI_SUCCESS; + PixelInformation = &This->Mode->Info->PixelInformation; + HorizontalResolution = This->Mode->Info->HorizontalResolution; + FrameBufferBase = (UINTN *)((UINTN)(This->Mode->FrameBufferBase)); + + if(( Delta != 0 ) && ( Delta != Width * sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL))) { + // Delta is not zero and it is different from the width. + // Divide it by the size of a pixel to find out the buffer's horizontal resolution. + BltBufferHorizontalResolution = (UINT32) (Delta / sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL)); + } else { + BltBufferHorizontalResolution = Width; + } + + LcdPlatformGetBpp (This->Mode->Mode,&BitsPerPixel); + + switch (BitsPerPixel) { + case LCD_BITS_PER_PIXEL_24: + WidthInBytes = Width * 4; + + // Access each pixel inside the BltBuffer Memory + for (SourceLine = SourceY, DestinationLine = DestinationY; + SourceLine < SourceY + Height; + SourceLine++, DestinationLine++) + { + // Calculate the source and target addresses using 32bit pointer arithmetic: + SourceAddr = (VOID *)((UINT32 *)BltBuffer + SourceLine * BltBufferHorizontalResolution + SourceX ); + DestinationAddr = (VOID *)((UINT32 *)FrameBufferBase + DestinationLine * HorizontalResolution + DestinationX); + + // Copy the entire row Y + CopyMem( DestinationAddr, SourceAddr, WidthInBytes); + } + break; + + case LCD_BITS_PER_PIXEL_16_555: + // Access each pixel inside the BltBuffer Memory + for (SourceLine = SourceY, DestinationLine = DestinationY; + SourceLine < SourceY + Height; + SourceLine++, DestinationLine++) { + + for (SourcePixelX = SourceX, DestinationPixelX = DestinationX; + SourcePixelX < SourceX + Width; + SourcePixelX++, DestinationPixelX++) + { + // Calculate the source and target addresses: + EfiSourcePixel = BltBuffer + SourceLine * BltBufferHorizontalResolution + SourcePixelX; + DestinationPixel16bit = (UINT16 *)FrameBufferBase + DestinationLine * HorizontalResolution + DestinationPixelX; + + // Copy the pixel into the new target + // Only the most significant bits will be copied across: + // To convert from 8 bits to 5 bits per pixel we throw away the 3 least significant bits + *DestinationPixel16bit = (UINT16) ( + ( (EfiSourcePixel->Red << 7) & PixelInformation->RedMask ) + | ( (EfiSourcePixel->Green << 2) & PixelInformation->GreenMask ) + | ( (EfiSourcePixel->Blue >> 3) & PixelInformation->BlueMask ) + // | ( 0 & PixelInformation->ReservedMask ) + ); + } + } + break; + + case LCD_BITS_PER_PIXEL_16_565: + // Access each pixel inside the BltBuffer Memory + for (SourceLine = SourceY, DestinationLine = DestinationY; + SourceLine < SourceY + Height; + SourceLine++, DestinationLine++) { + + for (SourcePixelX = SourceX, DestinationPixelX = DestinationX; + SourcePixelX < SourceX + Width; + SourcePixelX++, DestinationPixelX++) + { + // Calculate the source and target addresses: + EfiSourcePixel = BltBuffer + SourceLine * BltBufferHorizontalResolution + SourcePixelX; + DestinationPixel16bit = (UINT16 *)FrameBufferBase + DestinationLine * HorizontalResolution + DestinationPixelX; + + // Copy the pixel into the new target + // Only the most significant bits will be copied across: + // To convert from 8 bits to 5 or 6 bits per pixel we throw away the 3 or 2 least significant bits + // There is no room for the Reserved byte so we ignore that completely + *DestinationPixel16bit = (UINT16) ( + ( (EfiSourcePixel->Red << 8) & PixelInformation->RedMask ) + | ( (EfiSourcePixel->Green << 3) & PixelInformation->GreenMask ) + | ( (EfiSourcePixel->Blue >> 3) & PixelInformation->BlueMask ) + ); + } + } + break; + + case LCD_BITS_PER_PIXEL_12_444: + // Access each pixel inside the BltBuffer Memory + for (SourceLine = SourceY, DestinationLine = DestinationY; + SourceLine < SourceY + Height; + SourceLine++, DestinationLine++) { + + for (SourcePixelX = SourceX, DestinationPixelX = DestinationX; + SourcePixelX < SourceX + Width; + SourcePixelX++, DestinationPixelX++) + { + // Calculate the source and target addresses: + EfiSourcePixel = BltBuffer + SourceLine * BltBufferHorizontalResolution + SourcePixelX; + DestinationPixel16bit = (UINT16 *)FrameBufferBase + DestinationLine * HorizontalResolution + DestinationPixelX; + + // Copy the pixel into the new target + // Only the most significant bits will be copied across: + // To convert from 8 bits to 5 bits per pixel we throw away the 3 least significant bits + *DestinationPixel16bit = (UINT16) ( + ( (EfiSourcePixel->Red << 4) & PixelInformation->RedMask ) + | ( (EfiSourcePixel->Green ) & PixelInformation->GreenMask ) + | ( (EfiSourcePixel->Blue >> 4) & PixelInformation->BlueMask ) + // | ( 0 & PixelInformation->ReservedMask ) + ); + } + } + break; + + 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: + // Can't handle this case + DEBUG((DEBUG_ERROR, "LcdGraphicsBlt: EfiBltBufferToVideo: INVALID Number of Bits Per Pixel: %d\n", BitsPerPixel)); + Status = EFI_INVALID_PARAMETER; + break; + } + return Status; +} + +STATIC +EFI_STATUS +BltVideoToVideo ( + IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This, + IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer, OPTIONAL + IN UINTN SourceX, + IN UINTN SourceY, + IN UINTN DestinationX, + IN UINTN DestinationY, + IN UINTN Width, + IN UINTN Height, + IN UINTN Delta OPTIONAL // Number of BYTES in a row of the BltBuffer + ) +{ + EFI_STATUS Status; + UINT32 HorizontalResolution; + LCD_BPP BitsPerPixel; + VOID *FrameBufferBase; + + HorizontalResolution = This->Mode->Info->HorizontalResolution; + FrameBufferBase = (UINTN *)((UINTN)(This->Mode->FrameBufferBase)); + + // + // BltVideo to BltVideo: + // + // Source is the Video Memory, + // Destination is the Video Memory + + LcdPlatformGetBpp (This->Mode->Mode,&BitsPerPixel); + FrameBufferBase = (UINTN *)((UINTN)(This->Mode->FrameBufferBase)); + + // The UEFI spec currently states: + // "There is no limitation on the overlapping of the source and destination rectangles" + // Therefore, we must be careful to avoid overwriting the source data + if( SourceY == DestinationY ) { + // Copying within the same height, e.g. horizontal shift + if( SourceX == DestinationX ) { + // Nothing to do + Status = EFI_SUCCESS; + } else if( ((SourceX>DestinationX)?(SourceX - DestinationX):(DestinationX - SourceX)) < Width ) { + // There is overlap + Status = VideoCopyHorizontalOverlap (BitsPerPixel, FrameBufferBase, HorizontalResolution, SourceX, SourceY, DestinationX, DestinationY, Width, Height ); + } else { + // No overlap + Status = VideoCopyNoHorizontalOverlap (BitsPerPixel, FrameBufferBase, HorizontalResolution, SourceX, SourceY, DestinationX, DestinationY, Width, Height ); + } + } else { + // Copying from different heights + Status = VideoCopyNoHorizontalOverlap (BitsPerPixel, FrameBufferBase, HorizontalResolution, SourceX, SourceY, DestinationX, DestinationY, Width, Height ); + } + + return Status; +} + +/*************************************** + * GraphicsOutput Protocol function, mapping to + * EFI_GRAPHICS_OUTPUT_PROTOCOL.Blt + * + * PRESUMES: 1 pixel = 4 bytes (32bits) + * ***************************************/ +EFI_STATUS +EFIAPI +LcdGraphicsBlt ( + IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This, + IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer, OPTIONAL + IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation, + IN UINTN SourceX, + IN UINTN SourceY, + IN UINTN DestinationX, + IN UINTN DestinationY, + IN UINTN Width, + IN UINTN Height, + IN UINTN Delta OPTIONAL // Number of BYTES in a row of the BltBuffer + ) +{ + EFI_STATUS Status; + UINT32 HorizontalResolution; + UINT32 VerticalResolution; + LCD_INSTANCE* Instance; + + Instance = LCD_INSTANCE_FROM_GOP_THIS(This); + + // Setup the hardware if not already done + if (!mDisplayInitialized) { + Status = InitializeDisplay (Instance); + if (EFI_ERROR(Status)) { + goto EXIT; + } + } + + HorizontalResolution = This->Mode->Info->HorizontalResolution; + VerticalResolution = This->Mode->Info->VerticalResolution; + + DEBUG((DEBUG_INFO, "LcdGraphicsBlt (BltOperation:%d,DestX:%d,DestY:%d,Width:%d,Height:%d) res(%d,%d)\n", + BltOperation,DestinationX,DestinationY,Width,Height,HorizontalResolution,VerticalResolution)); + + // Check we have reasonable parameters + if (Width == 0 || Height == 0) { + DEBUG((DEBUG_ERROR, "LcdGraphicsBlt: ERROR - Invalid dimension: Zero size area.\n" )); + Status = EFI_INVALID_PARAMETER; + goto EXIT; + } + + if ((BltOperation == EfiBltVideoFill) || (BltOperation == EfiBltBufferToVideo) || (BltOperation == EfiBltVideoToBltBuffer)) { + ASSERT( BltBuffer != NULL); + } + + /*if ((DestinationX >= HorizontalResolution) || (DestinationY >= VerticalResolution)) { + DEBUG((DEBUG_ERROR, "LcdGraphicsBlt: ERROR - Invalid destination.\n" )); + Status = EFI_INVALID_PARAMETER; + goto EXIT; + }*/ + + // If we are reading data out of the video buffer, check that the source area is within the display limits + if ((BltOperation == EfiBltVideoToBltBuffer) || (BltOperation == EfiBltVideoToVideo)) { + if ((SourceY + Height > VerticalResolution) || (SourceX + Width > HorizontalResolution)) { + DEBUG((DEBUG_INFO, "LcdGraphicsBlt: ERROR - Invalid source resolution.\n" )); + DEBUG((DEBUG_INFO, " - SourceY=%d + Height=%d > VerticalResolution=%d.\n", SourceY, Height, VerticalResolution )); + DEBUG((DEBUG_INFO, " - SourceX=%d + Width=%d > HorizontalResolution=%d.\n", SourceX, Width, HorizontalResolution )); + Status = EFI_INVALID_PARAMETER; + goto EXIT; + } + } + + // If we are writing data into the video buffer, that the destination area is within the display limits + if ((BltOperation == EfiBltVideoFill) || (BltOperation == EfiBltBufferToVideo) || (BltOperation == EfiBltVideoToVideo)) { + if ((DestinationY + Height > VerticalResolution) || (DestinationX + Width > HorizontalResolution)) { + DEBUG((DEBUG_INFO, "LcdGraphicsBlt: ERROR - Invalid destination resolution.\n" )); + DEBUG((DEBUG_INFO, " - DestinationY=%d + Height=%d > VerticalResolution=%d.\n", DestinationY, Height, VerticalResolution )); + DEBUG((DEBUG_INFO, " - DestinationX=%d + Width=%d > HorizontalResolution=%d.\n", DestinationX, Width, HorizontalResolution )); + Status = EFI_INVALID_PARAMETER; + goto EXIT; + } + } + + // + // Perform the Block Transfer Operation + // + + switch (BltOperation) { + case EfiBltVideoFill: + Status = BltVideoFill (This, BltBuffer, SourceX, SourceY, DestinationX, DestinationY, Width, Height, Delta); + break; + + case EfiBltVideoToBltBuffer: + Status = BltVideoToBltBuffer (This, BltBuffer, SourceX, SourceY, DestinationX, DestinationY, Width, Height, Delta); + break; + + case EfiBltBufferToVideo: + Status = BltBufferToVideo (This, BltBuffer, SourceX, SourceY, DestinationX, DestinationY, Width, Height, Delta); + break; + + case EfiBltVideoToVideo: + Status = BltVideoToVideo (This, BltBuffer, SourceX, SourceY, DestinationX, DestinationY, Width, Height, Delta); + break; + + case EfiGraphicsOutputBltOperationMax: + default: + DEBUG((DEBUG_ERROR, "LcdGraphicsBlt: Invalid Operation\n")); + Status = EFI_INVALID_PARAMETER; + break; + } + +EXIT: + return Status; +} diff --git a/ArmPlatformPkg/Drivers/LcdGraphicsOutputDxe/LcdGraphicsOutputDxe.c b/ArmPlatformPkg/Drivers/LcdGraphicsOutputDxe/LcdGraphicsOutputDxe.c new file mode 100644 index 0000000000..a4ab6a68f5 --- /dev/null +++ b/ArmPlatformPkg/Drivers/LcdGraphicsOutputDxe/LcdGraphicsOutputDxe.c @@ -0,0 +1,379 @@ +/** @file + + Copyright (c) 2011, ARM Ltd. All rights reserved.<BR> + 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 <PiDxe.h> +#include <Library/PcdLib.h> +#include <Library/DebugLib.h> +#include <Library/BaseMemoryLib.h> +#include <Library/DevicePathLib.h> +#include <Library/UefiBootServicesTableLib.h> +#include <Library/UefiRuntimeServicesTableLib.h> +#include <Library/MemoryAllocationLib.h> + +#include <Guid/GlobalVariable.h> + +#include <ArmPlatform.h> +#include "LcdGraphicsOutputDxe.h" + +/********************************************************************** + * + * This file implements the Graphics Output protocol on ArmVersatileExpress + * using the Lcd controller + * + **********************************************************************/ + +// +// Global variables +// + +BOOLEAN mDisplayInitialized = FALSE; + +LCD_INSTANCE mLcdTemplate = { + LCD_INSTANCE_SIGNATURE, + NULL, // Handle + { // ModeInfo + 0, // Version + 0, // HorizontalResolution + 0, // VerticalResolution + PixelBltOnly, // PixelFormat + 0, // PixelInformation + 0, // PixelsPerScanLine + }, + { + 0, // MaxMode; + 0, // Mode; + NULL, // Info; + 0, // SizeOfInfo; + 0, // FrameBufferBase; + 0 // FrameBufferSize; + }, + { // Gop + LcdGraphicsQueryMode, // QueryMode + LcdGraphicsSetMode, // SetMode + LcdGraphicsBlt, // Blt + NULL // *Mode + }, + { // DevicePath + { + { + HARDWARE_DEVICE_PATH, HW_VENDOR_DP, + (UINT8) (sizeof(VENDOR_DEVICE_PATH)), + (UINT8) ((sizeof(VENDOR_DEVICE_PATH)) >> 8), + }, + // Hardware Device Path for Lcd + EFI_CALLER_ID_GUID // Use the driver's GUID + }, + + { + END_DEVICE_PATH_TYPE, + END_ENTIRE_DEVICE_PATH_SUBTYPE, + sizeof(EFI_DEVICE_PATH_PROTOCOL), + 0 + } + }, + (EFI_EVENT) NULL // ExitBootServicesEvent +}; + +EFI_STATUS +LcdInstanceContructor ( + OUT LCD_INSTANCE** NewInstance + ) +{ + LCD_INSTANCE* Instance; + + Instance = AllocateCopyPool (sizeof(LCD_INSTANCE), &mLcdTemplate); + if (Instance == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + Instance->Gop.Mode = &Instance->Mode; + Instance->Gop.Mode->MaxMode = LcdPlatformGetMaxMode (); + Instance->Mode.Info = &Instance->ModeInfo; + + *NewInstance = Instance; + return EFI_SUCCESS; +} + +// +// Function Definitions +// + +EFI_STATUS +InitializeDisplay ( + IN LCD_INSTANCE* Instance + ) +{ + EFI_STATUS Status = EFI_SUCCESS; + EFI_PHYSICAL_ADDRESS VramBaseAddress; + UINTN VramSize; + + Status = LcdPlatformGetVram (&VramBaseAddress, &VramSize); + if (EFI_ERROR(Status)) { + return Status; + } + + // Setup the LCD + Status = LcdInitialize (VramBaseAddress); + if (EFI_ERROR(Status)) { + goto EXIT_ERROR_LCD_SHUTDOWN; + } + + Status = LcdPlatformInitializeDisplay (); + if (EFI_ERROR(Status)) { + goto EXIT_ERROR_LCD_SHUTDOWN; + } + + // Setup all the relevant mode information + Instance->Gop.Mode->SizeOfInfo = sizeof(EFI_GRAPHICS_OUTPUT_MODE_INFORMATION); + Instance->Gop.Mode->FrameBufferBase = VramBaseAddress; + Instance->Gop.Mode->FrameBufferSize = VramSize; + + // Set the flag before changing the mode, to avoid infinite loops + mDisplayInitialized = TRUE; + + // All is ok, so don't deal with any errors + goto EXIT; + +EXIT_ERROR_LCD_SHUTDOWN: + DEBUG((DEBUG_ERROR, "InitializeDisplay: ERROR - Can not initialise the display. Exit Status=%r\n", Status)); + LcdShutdown (); + +EXIT: + return Status; +} + +EFI_STATUS +EFIAPI +LcdGraphicsOutputDxeInitialize ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status = EFI_SUCCESS; + LCD_INSTANCE* Instance; + + Status = LcdInstanceContructor (&Instance); + if (EFI_ERROR(Status)) { + goto EXIT; + } + + // Install the Graphics Output Protocol and the Device Path + Status = gBS->InstallMultipleProtocolInterfaces( + &Instance->Handle, + &gEfiGraphicsOutputProtocolGuid, &Instance->Gop, + &gEfiDevicePathProtocolGuid, &Instance->DevicePath, + NULL + ); + + if (EFI_ERROR(Status)) { + DEBUG((DEBUG_ERROR, "GraphicsOutputDxeInitialize: Can not install the protocol. Exit Status=%r\n", Status)); + goto EXIT; + } + + // Register for an ExitBootServicesEvent + // When ExitBootServices starts, this function here will make sure that the graphics driver will shut down properly, + // i.e. it will free up all allocated memory and perform any necessary hardware re-configuration. + Status = gBS->CreateEvent ( + EVT_SIGNAL_EXIT_BOOT_SERVICES, + TPL_NOTIFY, + LcdGraphicsExitBootServicesEvent, NULL, + &Instance->ExitBootServicesEvent + ); + + if (EFI_ERROR(Status)) { + DEBUG((DEBUG_ERROR, "GraphicsOutputDxeInitialize: Can not install the ExitBootServicesEvent handler. Exit Status=%r\n", Status)); + goto EXIT_ERROR_UNINSTALL_PROTOCOL; + } + + // To get here, everything must be fine, so just exit + goto EXIT; + +EXIT_ERROR_UNINSTALL_PROTOCOL: + /* The following function could return an error message, + * however, to get here something must have gone wrong already, + * so preserve the original error, i.e. don't change + * the Status variable, even it fails to uninstall the protocol. + */ + gBS->UninstallMultipleProtocolInterfaces ( + Instance->Handle, + &gEfiGraphicsOutputProtocolGuid, &Instance->Gop, // Uninstall Graphics Output protocol + &gEfiDevicePathProtocolGuid, &Instance->DevicePath, // Uninstall device path + NULL + ); + +EXIT: + return Status; + +} + +/*************************************** + * This function should be called + * on Event: ExitBootServices + * to free up memory, stop the driver + * and uninstall the protocols + ***************************************/ +VOID +LcdGraphicsExitBootServicesEvent ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + //TODO: Implement me +} + +/*************************************** + * GraphicsOutput Protocol function, mapping to + * EFI_GRAPHICS_OUTPUT_PROTOCOL.QueryMode + ***************************************/ +EFI_STATUS +EFIAPI +LcdGraphicsQueryMode ( + IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This, + IN UINT32 ModeNumber, + OUT UINTN *SizeOfInfo, + OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION **Info + ) +{ + EFI_STATUS Status = EFI_SUCCESS; + LCD_INSTANCE *Instance; + + Instance = LCD_INSTANCE_FROM_GOP_THIS(This); + + // Setup the hardware if not already done + if( !mDisplayInitialized ) { + Status = InitializeDisplay(Instance); + if (EFI_ERROR(Status)) { + goto EXIT; + } + } + + // Error checking + if ( (This == NULL) || (Info == NULL) || (SizeOfInfo == NULL) || (ModeNumber >= This->Mode->MaxMode) ) { + DEBUG((DEBUG_ERROR, "LcdGraphicsQueryMode: ERROR - For mode number %d : Invalid Parameter.\n", ModeNumber )); + Status = EFI_INVALID_PARAMETER; + goto EXIT; + } + + *Info = AllocatePool (sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION)); + if (*Info == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto EXIT; + } + + *SizeOfInfo = sizeof( EFI_GRAPHICS_OUTPUT_MODE_INFORMATION); + + Status = LcdPlatformQueryMode (ModeNumber,*Info); + if (EFI_ERROR(Status)) { + FreePool(*Info); + } + +EXIT: + return Status; +} + +/*************************************** + * GraphicsOutput Protocol function, mapping to + * EFI_GRAPHICS_OUTPUT_PROTOCOL.SetMode + ***************************************/ +EFI_STATUS +EFIAPI +LcdGraphicsSetMode ( + IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This, + IN UINT32 ModeNumber + ) +{ + EFI_STATUS Status = EFI_SUCCESS; + EFI_GRAPHICS_OUTPUT_BLT_PIXEL FillColour; + LCD_INSTANCE* Instance; + + Instance = LCD_INSTANCE_FROM_GOP_THIS (This); + + // Setup the hardware if not already done + if(!mDisplayInitialized) { + Status = InitializeDisplay (Instance); + if (EFI_ERROR(Status)) { + goto EXIT; + } + } + + // Check if this mode is supported + if( ModeNumber >= This->Mode->MaxMode ) { + DEBUG((DEBUG_ERROR, "LcdGraphicsSetMode: ERROR - Unsupported mode number %d .\n", ModeNumber )); + Status = EFI_UNSUPPORTED; + goto EXIT; + } + + // Set the oscillator frequency to support the new mode + Status = LcdPlatformSetMode (ModeNumber); + if (EFI_ERROR(Status)) { + Status = EFI_DEVICE_ERROR; + goto EXIT; + } + + // Update the UEFI mode information + This->Mode->Mode = ModeNumber; + LcdPlatformQueryMode (ModeNumber,&Instance->ModeInfo); + + // Set the hardware to the new mode + Status = LcdSetMode (ModeNumber); + if (EFI_ERROR(Status)) { + Status = EFI_DEVICE_ERROR; + goto EXIT; + } + + // The UEFI spec requires that we now clear the visible portions of the output display to black. + + // Set the fill colour to black + SetMem (&FillColour, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0x0); + + // Fill the entire visible area with the same colour. + Status = This->Blt ( + This, + &FillColour, + EfiBltVideoFill, + 0, + 0, + 0, + 0, + This->Mode->Info->HorizontalResolution, + This->Mode->Info->VerticalResolution, + 0); + +EXIT: + return Status; +} + +UINTN +GetBytesPerPixel ( + IN LCD_BPP Bpp + ) +{ + switch(Bpp) { + case LCD_BITS_PER_PIXEL_24: + return 4; + + case LCD_BITS_PER_PIXEL_16_565: + case LCD_BITS_PER_PIXEL_16_555: + case LCD_BITS_PER_PIXEL_12_444: + return 2; + + case LCD_BITS_PER_PIXEL_8: + case LCD_BITS_PER_PIXEL_4: + case LCD_BITS_PER_PIXEL_2: + case LCD_BITS_PER_PIXEL_1: + return 1; + + default: + return 0; + } +} diff --git a/ArmPlatformPkg/Drivers/LcdGraphicsOutputDxe/LcdGraphicsOutputDxe.h b/ArmPlatformPkg/Drivers/LcdGraphicsOutputDxe/LcdGraphicsOutputDxe.h new file mode 100644 index 0000000000..8886bed7cb --- /dev/null +++ b/ArmPlatformPkg/Drivers/LcdGraphicsOutputDxe/LcdGraphicsOutputDxe.h @@ -0,0 +1,124 @@ +/** @file
+
+ Copyright (c) 2011, ARM Ltd. All rights reserved.<BR>
+ 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.
+
+**/
+
+#ifndef __ARM_VE_GRAPHICS_DXE_H__
+#define __ARM_VE_GRAPHICS_DXE_H__
+
+
+#include <Base.h>
+#include <Library/UefiLib.h>
+#include <Protocol/DevicePath.h>
+
+#include <Library/LcdPlatformLib.h>
+
+//
+// Device structures
+//
+typedef struct {
+ VENDOR_DEVICE_PATH Guid;
+ EFI_DEVICE_PATH_PROTOCOL End;
+} LCD_GRAPHICS_DEVICE_PATH;
+
+typedef struct {
+ UINTN Signature;
+ EFI_HANDLE Handle;
+ EFI_GRAPHICS_OUTPUT_MODE_INFORMATION ModeInfo;
+ EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE Mode;
+ EFI_GRAPHICS_OUTPUT_PROTOCOL Gop;
+ LCD_GRAPHICS_DEVICE_PATH DevicePath;
+ EFI_EVENT ExitBootServicesEvent;
+} LCD_INSTANCE;
+
+#define LCD_INSTANCE_SIGNATURE SIGNATURE_32('l', 'c', 'd', '0')
+
+#define LCD_INSTANCE_FROM_GOP_THIS(a) CR (a, LCD_INSTANCE, Gop, LCD_INSTANCE_SIGNATURE)
+
+//
+// Function Prototypes
+//
+
+VOID
+LcdGraphicsExitBootServicesEvent (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+);
+
+EFI_STATUS
+EFIAPI
+LcdGraphicsQueryMode (
+ IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This,
+ IN UINT32 ModeNumber,
+ OUT UINTN *SizeOfInfo,
+ OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION **Info
+);
+
+EFI_STATUS
+EFIAPI
+LcdGraphicsSetMode (
+ IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This,
+ IN UINT32 ModeNumber
+);
+
+EFI_STATUS
+EFIAPI
+LcdGraphicsBlt (
+ IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This,
+ IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer, OPTIONAL
+ IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation,
+ IN UINTN SourceX,
+ IN UINTN SourceY,
+ IN UINTN DestinationX,
+ IN UINTN DestinationY,
+ IN UINTN Width,
+ IN UINTN Height,
+ IN UINTN Delta OPTIONAL
+);
+
+UINTN
+GetBytesPerPixel (
+ IN LCD_BPP Bpp
+ );
+
+EFI_STATUS
+EFIAPI
+GraphicsOutputDxeInitialize (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+);
+
+EFI_STATUS
+InitializeDisplay (
+ IN LCD_INSTANCE* Instance
+);
+
+EFI_STATUS
+LcdIndentify (
+ VOID
+);
+
+EFI_STATUS
+LcdInitialize (
+ EFI_PHYSICAL_ADDRESS VramBaseAddress
+);
+
+EFI_STATUS
+LcdSetMode (
+ IN UINT32 ModeNumber
+);
+
+VOID
+LcdShutdown (
+ VOID
+);
+
+#endif /* __ARM_VE_GRAPHICS_DXE_H__ */
diff --git a/ArmPlatformPkg/Drivers/LcdGraphicsOutputDxe/PL111Lcd.c b/ArmPlatformPkg/Drivers/LcdGraphicsOutputDxe/PL111Lcd.c new file mode 100644 index 0000000000..c92dd3d7ed --- /dev/null +++ b/ArmPlatformPkg/Drivers/LcdGraphicsOutputDxe/PL111Lcd.c @@ -0,0 +1,140 @@ +/** @file PL111Lcd.c
+
+ Copyright (c) 2011, ARM Ltd. All rights reserved.<BR>
+ 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 <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/LcdPlatformLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PcdLib.h>
+
+#include <Drivers/PL111Lcd.h>
+
+#include "LcdGraphicsOutputDxe.h"
+
+/**********************************************************************
+ *
+ * This file contains all the bits of the PL111 that are
+ * platform independent.
+ *
+ **********************************************************************/
+
+EFI_STATUS
+PL111Indentify (
+ VOID
+ )
+{
+ // Check if this is a PrimeCell Peripheral
+ if ( ( MmioRead8( PL111_REG_CLCD_P_CELL_ID_0 ) != 0x0D )
+ || ( MmioRead8( PL111_REG_CLCD_P_CELL_ID_1 ) != 0xF0 )
+ || ( MmioRead8( PL111_REG_CLCD_P_CELL_ID_2 ) != 0x05 )
+ || ( MmioRead8( PL111_REG_CLCD_P_CELL_ID_3 ) != 0xB1 ) ) {
+ return EFI_NOT_FOUND;
+ }
+
+ // Check if this PrimeCell Peripheral is the PL111 LCD
+ if ( ( MmioRead8( PL111_REG_CLCD_PERIPH_ID_0 ) != 0x11 )
+ || ( MmioRead8( PL111_REG_CLCD_PERIPH_ID_1 ) != 0x11 )
+ || ( (MmioRead8( PL111_REG_CLCD_PERIPH_ID_2 ) & 0xF) != 0x04 )
+ || ( MmioRead8( PL111_REG_CLCD_PERIPH_ID_3 ) != 0x00 ) ) {
+ return EFI_NOT_FOUND;
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+LcdInitialize (
+ IN EFI_PHYSICAL_ADDRESS VramBaseAddress
+ )
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+
+ // Check if the PL111 is fitted on this motherboard
+ Status = PL111Indentify();
+ if (EFI_ERROR( Status )) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ // Define start of the VRAM. This never changes for any graphics mode
+ MmioWrite32(PL111_REG_LCD_UP_BASE, (UINT32) VramBaseAddress);
+ MmioWrite32(PL111_REG_LCD_LP_BASE, 0); // We are not using a double buffer
+
+ // Disable all interrupts from the PL111
+ MmioWrite32(PL111_REG_LCD_IMSC, 0);
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+LcdSetMode (
+ IN UINT32 ModeNumber
+ )
+{
+ EFI_STATUS Status;
+ UINT32 HRes;
+ UINT32 HSync;
+ UINT32 HBackPorch;
+ UINT32 HFrontPorch;
+ UINT32 VRes;
+ UINT32 VSync;
+ UINT32 VBackPorch;
+ UINT32 VFrontPorch;
+ UINT32 LcdControl;
+ LCD_BPP LcdBpp;
+
+ // Set the video mode timings and other relevant information
+ Status = LcdPlatformGetTimings (ModeNumber,
+ &HRes,&HSync,&HBackPorch,&HFrontPorch,
+ &VRes,&VSync,&VBackPorch,&VFrontPorch);
+ ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR( Status )) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ Status = LcdPlatformGetBpp (ModeNumber,&LcdBpp);
+ ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR( Status )) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ // Disable the CLCD_LcdEn bit
+ LcdControl = MmioRead32( PL111_REG_LCD_CONTROL);
+ MmioWrite32(PL111_REG_LCD_CONTROL, LcdControl & ~1);
+
+ // Set Timings
+ MmioWrite32 (PL111_REG_LCD_TIMING_0, HOR_AXIS_PANEL(HBackPorch, HFrontPorch, HSync, HRes));
+ MmioWrite32 (PL111_REG_LCD_TIMING_1, VER_AXIS_PANEL(VBackPorch, VFrontPorch, VSync, VRes));
+ MmioWrite32 (PL111_REG_LCD_TIMING_2, CLK_SIG_POLARITY(HRes));
+ MmioWrite32 (PL111_REG_LCD_TIMING_3, 0);
+
+ // PL111_REG_LCD_CONTROL
+ LcdControl = PL111_CTRL_LCD_EN | PL111_CTRL_LCD_BPP(LcdBpp) | PL111_CTRL_LCD_TFT | PL111_CTRL_BGR;
+ MmioWrite32(PL111_REG_LCD_CONTROL, LcdControl);
+
+ // Turn on power to the LCD Panel
+ LcdControl |= PL111_CTRL_LCD_PWR;
+ MmioWrite32(PL111_REG_LCD_CONTROL, LcdControl);
+
+ return EFI_SUCCESS;
+}
+
+VOID
+LcdShutdown (
+ VOID
+ )
+{
+ // Nothing to do in terms of hardware.
+ // We could switch off the monitor display if required
+
+ //TODO: ImplementMe
+}
diff --git a/ArmPlatformPkg/Drivers/LcdGraphicsOutputDxe/PL111LcdGraphicsOutputDxe.inf b/ArmPlatformPkg/Drivers/LcdGraphicsOutputDxe/PL111LcdGraphicsOutputDxe.inf new file mode 100644 index 0000000000..ae571d8d83 --- /dev/null +++ b/ArmPlatformPkg/Drivers/LcdGraphicsOutputDxe/PL111LcdGraphicsOutputDxe.inf @@ -0,0 +1,60 @@ +#/** @file +# +# Component discription file for ArmVeGraphicsDxe module +# +# Copyright (c) 2011, ARM Ltd. All rights reserved.<BR> +# 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 = 0x00010005 + BASE_NAME = PL111LcdGraphicsDxe + FILE_GUID = 407B4008-BF5B-11DF-9547-CF16E0D72085 + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + ENTRY_POINT = LcdGraphicsOutputDxeInitialize + +[Sources.common] + LcdGraphicsOutputDxe.c + LcdGraphicsOutputBlt.c + PL111Lcd.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + ArmPkg/ArmPkg.dec + ArmPlatformPkg/ArmVExpressPkg/ArmVExpressPkg.dec + ArmPlatformPkg/ArmPlatformPkg.dec + +[LibraryClasses] + ArmLib + UefiLib + BaseLib + DebugLib + TimerLib + UefiDriverEntryPoint + UefiBootServicesTableLib + IoLib + BaseMemoryLib + LcdPlatformLib + +[Guids] + +[Protocols] + gEfiDevicePathProtocolGuid + gEfiGraphicsOutputProtocolGuid + +[FixedPcd.common] + +[Pcd.common] + + +[Depex] + gEfiCpuArchProtocolGuid diff --git a/ArmPlatformPkg/Include/Drivers/PL111Lcd.h b/ArmPlatformPkg/Include/Drivers/PL111Lcd.h new file mode 100644 index 0000000000..80d563976d --- /dev/null +++ b/ArmPlatformPkg/Include/Drivers/PL111Lcd.h @@ -0,0 +1,142 @@ +/** @file PL111Lcd.h + + Copyright (c) 2011, ARM Ltd. All rights reserved.<BR> + 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. + + **/ + +#ifndef _PL111LCD_H__ +#define _PL111LCD_H__ + +#include <ArmPlatform.h> + +/********************************************************************** + * + * This header file contains all the bits of the PL111 that are + * platform independent. + * + **********************************************************************/ + +// Controller Register Offsets +#define PL111_REG_LCD_TIMING_0 (PL111_CLCD_BASE + 0x000) +#define PL111_REG_LCD_TIMING_1 (PL111_CLCD_BASE + 0x004) +#define PL111_REG_LCD_TIMING_2 (PL111_CLCD_BASE + 0x008) +#define PL111_REG_LCD_TIMING_3 (PL111_CLCD_BASE + 0x00C) +#define PL111_REG_LCD_UP_BASE (PL111_CLCD_BASE + 0x010) +#define PL111_REG_LCD_LP_BASE (PL111_CLCD_BASE + 0x014) +#define PL111_REG_LCD_CONTROL (PL111_CLCD_BASE + 0x018) +#define PL111_REG_LCD_IMSC (PL111_CLCD_BASE + 0x01C) +#define PL111_REG_LCD_RIS (PL111_CLCD_BASE + 0x020) +#define PL111_REG_LCD_MIS (PL111_CLCD_BASE + 0x024) +#define PL111_REG_LCD_ICR (PL111_CLCD_BASE + 0x028) +#define PL111_REG_LCD_UP_CURR (PL111_CLCD_BASE + 0x02C) +#define PL111_REG_LCD_LP_CURR (PL111_CLCD_BASE + 0x030) +#define PL111_REG_LCD_PALETTE (PL111_CLCD_BASE + 0x200) + +// Identification Register Offsets +#define PL111_REG_CLCD_PERIPH_ID_0 (PL111_CLCD_BASE + 0xFE0) +#define PL111_REG_CLCD_PERIPH_ID_1 (PL111_CLCD_BASE + 0xFE4) +#define PL111_REG_CLCD_PERIPH_ID_2 (PL111_CLCD_BASE + 0xFE8) +#define PL111_REG_CLCD_PERIPH_ID_3 (PL111_CLCD_BASE + 0xFEC) +#define PL111_REG_CLCD_P_CELL_ID_0 (PL111_CLCD_BASE + 0xFF0) +#define PL111_REG_CLCD_P_CELL_ID_1 (PL111_CLCD_BASE + 0xFF4) +#define PL111_REG_CLCD_P_CELL_ID_2 (PL111_CLCD_BASE + 0xFF8) +#define PL111_REG_CLCD_P_CELL_ID_3 (PL111_CLCD_BASE + 0xFFC) + +/**********************************************************************/ + +// Register components (register bits) + +// This should make life easier to program specific settings in the different registers +// by simplifying the setting up of the individual bits of each register +// and then assembling the final register value. + +/**********************************************************************/ + +// Register: PL111_REG_LCD_TIMING_0 +#define HOR_AXIS_PANEL(hbp,hfp,hsw,hor_res) (UINT32)(((UINT32)(hbp) << 24) | ((UINT32)(hfp) << 16) | ((UINT32)(hsw) << 8) | (((UINT32)((hor_res)/16)-1) << 2)) + +// Register: PL111_REG_LCD_TIMING_1 +#define VER_AXIS_PANEL(vbp,vfp,vsw,ver_res) (UINT32)(((UINT32)(vbp) << 24) | ((UINT32)(vfp) << 16) | ((UINT32)(vsw) << 10) | ((ver_res)-1)) + +// Register: PL111_REG_LCD_TIMING_2 +#define PL111_BIT_SHIFT_PCD_HI 27 +#define PL111_BIT_SHIFT_BCD 26 +#define PL111_BIT_SHIFT_CPL 16 +#define PL111_BIT_SHIFT_IOE 14 +#define PL111_BIT_SHIFT_IPC 13 +#define PL111_BIT_SHIFT_IHS 12 +#define PL111_BIT_SHIFT_IVS 11 +#define PL111_BIT_SHIFT_ACB 6 +#define PL111_BIT_SHIFT_CLKSEL 5 +#define PL111_BIT_SHIFT_PCD_LO 0 + +#define PL111_BCD (1 << 26) +#define PL111_IPC (1 << 13) +#define PL111_IHS (1 << 12) +#define PL111_IVS (1 << 11) + +#define CLK_SIG_POLARITY(hor_res) (UINT32)(PL111_BCD | PL111_IPC | PL111_IHS | PL111_IVS | (((hor_res)-1) << 16)) + +// Register: PL111_REG_LCD_TIMING_3 +#define PL111_BIT_SHIFT_LEE 16 +#define PL111_BIT_SHIFT_LED 0 + +#define PL111_CTRL_WATERMARK (1 << 16) +#define PL111_CTRL_LCD_V_COMP (1 << 12) +#define PL111_CTRL_LCD_PWR (1 << 11) +#define PL111_CTRL_BEPO (1 << 10) +#define PL111_CTRL_BEBO (1 << 9) +#define PL111_CTRL_BGR (1 << 8) +#define PL111_CTRL_LCD_DUAL (1 << 7) +#define PL111_CTRL_LCD_MONO_8 (1 << 6) +#define PL111_CTRL_LCD_TFT (1 << 5) +#define PL111_CTRL_LCD_BW (1 << 4) +#define PL111_CTRL_LCD_1BPP (0 << 1) +#define PL111_CTRL_LCD_2BPP (1 << 1) +#define PL111_CTRL_LCD_4BPP (2 << 1) +#define PL111_CTRL_LCD_8BPP (3 << 1) +#define PL111_CTRL_LCD_16BPP (4 << 1) +#define PL111_CTRL_LCD_24BPP (5 << 1) +#define PL111_CTRL_LCD_16BPP_565 (6 << 1) +#define PL111_CTRL_LCD_12BPP_444 (7 << 1) +#define PL111_CTRL_LCD_BPP(Bpp) ((Bpp) << 1) +#define PL111_CTRL_LCD_EN 1 + +/**********************************************************************/ + +// Register: PL111_REG_LCD_TIMING_0 +#define PL111_LCD_TIMING_0_HBP(hbp) (((hbp) & 0xFF) << 24) +#define PL111_LCD_TIMING_0_HFP(hfp) (((hfp) & 0xFF) << 16) +#define PL111_LCD_TIMING_0_HSW(hsw) (((hsw) & 0xFF) << 8) +#define PL111_LCD_TIMING_0_PPL(ppl) (((hsw) & 0x3F) << 2) + +// Register: PL111_REG_LCD_TIMING_1 +#define PL111_LCD_TIMING_1_VBP(vbp) (((vbp) & 0xFF) << 24) +#define PL111_LCD_TIMING_1_VFP(vfp) (((vfp) & 0xFF) << 16) +#define PL111_LCD_TIMING_1_VSW(vsw) (((vsw) & 0x3F) << 10) +#define PL111_LCD_TIMING_1_LPP(lpp) ((lpp) & 0xFC) + +// Register: PL111_REG_LCD_TIMING_2 +#define PL111_BIT_MASK_PCD_HI 0xF8000000 +#define PL111_BIT_MASK_BCD 0x04000000 +#define PL111_BIT_MASK_CPL 0x03FF0000 +#define PL111_BIT_MASK_IOE 0x00004000 +#define PL111_BIT_MASK_IPC 0x00002000 +#define PL111_BIT_MASK_IHS 0x00001000 +#define PL111_BIT_MASK_IVS 0x00000800 +#define PL111_BIT_MASK_ACB 0x000007C0 +#define PL111_BIT_MASK_CLKSEL 0x00000020 +#define PL111_BIT_MASK_PCD_LO 0x0000001F + +// Register: PL111_REG_LCD_TIMING_3 +#define PL111_BIT_MASK_LEE 0x00010000 +#define PL111_BIT_MASK_LED 0x0000007F + +#endif /* _PL111LCD_H__ */ diff --git a/ArmPlatformPkg/Include/Library/LcdPlatformLib.h b/ArmPlatformPkg/Include/Library/LcdPlatformLib.h new file mode 100644 index 0000000000..93afa6322e --- /dev/null +++ b/ArmPlatformPkg/Include/Library/LcdPlatformLib.h @@ -0,0 +1,205 @@ +/** @file
+
+ Copyright (c) 2011, ARM Ltd. All rights reserved.<BR>
+ 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.
+
+ **/
+
+#ifndef __LCDPLATFORMLIB_H
+#define __LCDPLATFORMLIB_H
+
+#include <Protocol/GraphicsOutput.h>
+
+#define LCD_VRAM_SIZE SIZE_8MB
+
+//
+// Modes definitions
+//
+#define VGA 0
+#define SVGA 1
+#define XGA 2
+#define SXGA 3
+#define UXGA 4
+#define HD 5
+
+//
+// VGA Mode: 640 x 480
+//
+#define VGA_H_RES_PIXELS 640
+#define VGA_V_RES_PIXELS 480
+#define VGA_OSC_FREQUENCY 23750000 /* 0x016A6570 */
+
+#define VGA_H_SYNC ( 80 - 1)
+#define VGA_H_FRONT_PORCH ( 16 - 1)
+#define VGA_H_BACK_PORCH ( 64 - 1)
+
+#define VGA_V_SYNC ( 4 - 1)
+#define VGA_V_FRONT_PORCH ( 3 - 1)
+#define VGA_V_BACK_PORCH ( 13 - 1)
+
+//
+// SVGA Mode: 800 x 600
+//
+#define SVGA_H_RES_PIXELS 800
+#define SVGA_V_RES_PIXELS 600
+#define SVGA_OSC_FREQUENCY 38250000 /* 0x0247A610 */
+
+#define SVGA_H_SYNC ( 80 - 1)
+#define SVGA_H_FRONT_PORCH ( 32 - 1)
+#define SVGA_H_BACK_PORCH (112 - 1)
+
+#define SVGA_V_SYNC ( 4 - 1)
+#define SVGA_V_FRONT_PORCH ( 3 - 1)
+#define SVGA_V_BACK_PORCH ( 17 - 1)
+
+//
+// XGA Mode: 1024 x 768
+//
+#define XGA_H_RES_PIXELS 1024
+#define XGA_V_RES_PIXELS 768
+#define XGA_OSC_FREQUENCY 63500000 /* 0x03C8EEE0 */
+
+#define XGA_H_SYNC (104 - 1)
+#define XGA_H_FRONT_PORCH ( 48 - 1)
+#define XGA_H_BACK_PORCH (152 - 1)
+
+#define XGA_V_SYNC ( 4 - 1)
+#define XGA_V_FRONT_PORCH ( 3 - 1)
+#define XGA_V_BACK_PORCH ( 23 - 1)
+
+//
+// SXGA Mode: 1280 x 1024
+//
+#define SXGA_H_RES_PIXELS 1280
+#define SXGA_V_RES_PIXELS 1024
+#define SXGA_OSC_FREQUENCY 109000000 /* 0x067F3540 */
+
+#define SXGA_H_SYNC (136 - 1)
+#define SXGA_H_FRONT_PORCH ( 80 - 1)
+#define SXGA_H_BACK_PORCH (216 - 1)
+
+#define SXGA_V_SYNC ( 7 - 1)
+#define SXGA_V_FRONT_PORCH ( 3 - 1)
+#define SXGA_V_BACK_PORCH ( 29 - 1)
+
+//
+// UXGA Mode: 1600 x 1200
+//
+#define UXGA_H_RES_PIXELS 1600
+#define UXGA_V_RES_PIXELS 1200
+#define UXGA_OSC_FREQUENCY 161000000 /* 0x0998AA40 */
+
+#define UXGA_H_SYNC (168 - 1)
+#define UXGA_H_FRONT_PORCH (112 - 1)
+#define UXGA_H_BACK_PORCH (280 - 1)
+
+#define UXGA_V_SYNC ( 4 - 1)
+#define UXGA_V_FRONT_PORCH ( 3 - 1)
+#define UXGA_V_BACK_PORCH ( 38 - 1)
+
+//
+// HD Mode: 1920 x 1080
+//
+#define HD_H_RES_PIXELS 1920
+#define HD_V_RES_PIXELS 1080
+#define HD_OSC_FREQUENCY 173000000 /* 0x0A4FC540 */
+
+#define HD_H_SYNC (200 - 1)
+#define HD_H_FRONT_PORCH (128 - 1)
+#define HD_H_BACK_PORCH (328 - 1)
+
+#define HD_V_SYNC ( 5 - 1)
+#define HD_V_FRONT_PORCH ( 3 - 1)
+#define HD_V_BACK_PORCH ( 32 - 1)
+
+//
+// Colour Masks
+//
+
+#define LCD_24BPP_RED_MASK 0x00FF0000
+#define LCD_24BPP_GREEN_MASK 0x0000FF00
+#define LCD_24BPP_BLUE_MASK 0x000000FF
+#define LCD_24BPP_RESERVED_MASK 0xFF000000
+
+#define LCD_16BPP_555_RED_MASK 0x00007C00
+#define LCD_16BPP_555_GREEN_MASK 0x000003E0
+#define LCD_16BPP_555_BLUE_MASK 0x0000001F
+#define LCD_16BPP_555_RESERVED_MASK 0x00000000
+
+#define LCD_16BPP_565_RED_MASK 0x0000F800
+#define LCD_16BPP_565_GREEN_MASK 0x000007E0
+#define LCD_16BPP_565_BLUE_MASK 0x0000001F
+#define LCD_16BPP_565_RESERVED_MASK 0x00008000
+
+#define LCD_12BPP_444_RED_MASK 0x00000F00
+#define LCD_12BPP_444_GREEN_MASK 0x000000F0
+#define LCD_12BPP_444_BLUE_MASK 0x0000000F
+#define LCD_12BPP_444_RESERVED_MASK 0x0000F000
+
+
+// The enumeration indexes maps the PL111 LcdBpp values used in the LCD Control Register
+typedef enum {
+ LCD_BITS_PER_PIXEL_1 = 0,
+ LCD_BITS_PER_PIXEL_2,
+ LCD_BITS_PER_PIXEL_4,
+ LCD_BITS_PER_PIXEL_8,
+ LCD_BITS_PER_PIXEL_16_555,
+ LCD_BITS_PER_PIXEL_24,
+ LCD_BITS_PER_PIXEL_16_565,
+ LCD_BITS_PER_PIXEL_12_444
+} LCD_BPP;
+
+
+EFI_STATUS
+LcdPlatformInitializeDisplay (
+ VOID
+ );
+
+EFI_STATUS
+LcdPlatformGetVram (
+ OUT EFI_PHYSICAL_ADDRESS* VramBaseAddress,
+ OUT UINTN* VramSize
+ );
+
+UINT32
+LcdPlatformGetMaxMode (
+ VOID
+ );
+
+EFI_STATUS
+LcdPlatformSetMode (
+ IN UINT32 ModeNumber
+ );
+
+EFI_STATUS
+LcdPlatformQueryMode (
+ IN UINT32 ModeNumber,
+ OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info
+ );
+
+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
+ );
+
+EFI_STATUS
+LcdPlatformGetBpp (
+ IN UINT32 ModeNumber,
+ OUT LCD_BPP* Bpp
+ );
+
+#endif
|