Skip to content

EDK2-MSM port for Xiaomi Poco F5 (SM7475 / Marble) (WIP) #424

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .github/workflows/installer.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ jobs:
- fuxi
# sm7325
- lisa

# sm7475
- marble

# Steps represent a sequence of tasks that will be executed as part of the job
steps:
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ jobs:
# sm7325
- mona
- lisa
# sm7475
- marble
# msm8998
- cheeseburger

Expand Down
255 changes: 255 additions & 0 deletions GPLDrivers/QcomPkg/Drivers/SimpleFbDxe/SimpleFbDxe.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,255 @@
/* SimpleFbDxe: Simple FrameBuffer */
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/CacheMaintenanceLib.h>
#include <Library/DebugLib.h>
#include <Library/DxeServicesTableLib.h>
#include <Library/FrameBufferBltLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/PcdLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiLib.h>
#include <PiDxe.h>
#include <Protocol/GraphicsOutput.h>
#include <Uefi.h>

/// Defines
/*
* Convert enum video_log2_bpp to bytes and bits. Note we omit the outer
* brackets to allow multiplication by fractional pixels.
*/
#define VNBYTES(bpix) (1 << (bpix)) / 8
#define VNBITS(bpix) (1 << (bpix))

#define FB_BITS_PER_PIXEL (32)
#define FB_BYTES_PER_PIXEL (FB_BITS_PER_PIXEL / 8)

/*
* Bits per pixel selector. Each value n is such that the bits-per-pixel is
* 2 ^ n
*/
enum video_log2_bpp {
VIDEO_BPP1 = 0,
VIDEO_BPP2,
VIDEO_BPP4,
VIDEO_BPP8,
VIDEO_BPP16,
VIDEO_BPP32,
};

typedef struct {
VENDOR_DEVICE_PATH DisplayDevicePath;
EFI_DEVICE_PATH EndDevicePath;
} DISPLAY_DEVICE_PATH;

DISPLAY_DEVICE_PATH mDisplayDevicePath = {
{{HARDWARE_DEVICE_PATH,
HW_VENDOR_DP,
{
(UINT8)(sizeof(VENDOR_DEVICE_PATH)),
(UINT8)((sizeof(VENDOR_DEVICE_PATH)) >> 8),
}},
EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID},
{END_DEVICE_PATH_TYPE,
END_ENTIRE_DEVICE_PATH_SUBTYPE,
{sizeof(EFI_DEVICE_PATH_PROTOCOL), 0}}};

/// Declares

STATIC FRAME_BUFFER_CONFIGURE *mFrameBufferBltLibConfigure;
STATIC UINTN mFrameBufferBltLibConfigureSize;

STATIC
EFI_STATUS
EFIAPI
DisplayQueryMode(
IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This, IN UINT32 ModeNumber,
OUT UINTN *SizeOfInfo, OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION **Info);

STATIC
EFI_STATUS
EFIAPI
DisplaySetMode(IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This, IN UINT32 ModeNumber);

STATIC
EFI_STATUS
EFIAPI
DisplayBlt(
IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This,
IN 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);

STATIC EFI_GRAPHICS_OUTPUT_PROTOCOL mDisplay = {
DisplayQueryMode, DisplaySetMode, DisplayBlt, NULL};

STATIC
EFI_STATUS
EFIAPI
DisplayQueryMode(
IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This, IN UINT32 ModeNumber,
OUT UINTN *SizeOfInfo, OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION **Info)
{
EFI_STATUS Status;
Status = gBS->AllocatePool(
EfiBootServicesData, sizeof(EFI_GRAPHICS_OUTPUT_MODE_INFORMATION),
(VOID **)Info);

ASSERT_EFI_ERROR(Status);

*SizeOfInfo = sizeof(EFI_GRAPHICS_OUTPUT_MODE_INFORMATION);
(*Info)->Version = This->Mode->Info->Version;
(*Info)->HorizontalResolution = This->Mode->Info->HorizontalResolution;
(*Info)->VerticalResolution = This->Mode->Info->VerticalResolution;
(*Info)->PixelFormat = This->Mode->Info->PixelFormat;
(*Info)->PixelsPerScanLine = This->Mode->Info->PixelsPerScanLine;

return EFI_SUCCESS;
}

STATIC
EFI_STATUS
EFIAPI
DisplaySetMode(IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This, IN UINT32 ModeNumber)
{
return EFI_SUCCESS;
}

STATIC
EFI_STATUS
EFIAPI
DisplayBlt(
IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This,
IN 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)
{

RETURN_STATUS Status;
EFI_TPL Tpl;
//
// We have to raise to TPL_NOTIFY, so we make an atomic write to the frame
// buffer. We would not want a timer based event (Cursor, ...) to come in
// while we are doing this operation.
//
Tpl = gBS->RaiseTPL(TPL_NOTIFY);
Status = FrameBufferBlt(
mFrameBufferBltLibConfigure, BltBuffer, BltOperation, SourceX, SourceY,
DestinationX, DestinationY, Width, Height, Delta);
gBS->RestoreTPL(Tpl);

// zhuowei: hack: flush the cache manually since my memory maps are still
// broken
WriteBackInvalidateDataCacheRange(
(void *)mDisplay.Mode->FrameBufferBase, mDisplay.Mode->FrameBufferSize);
// zhuowei: end hack

return RETURN_ERROR(Status) ? EFI_INVALID_PARAMETER : EFI_SUCCESS;
}

EFI_STATUS
EFIAPI
SimpleFbDxeInitialize(
IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
{

EFI_STATUS Status = EFI_SUCCESS;
EFI_HANDLE hUEFIDisplayHandle = NULL;

/* Retrieve simple frame buffer from pre-SEC bootloader */
DEBUG(
(EFI_D_ERROR,
"SimpleFbDxe: Retrieve MIPI FrameBuffer parameters from PCD\n"));
UINT32 MipiFrameBufferAddr = FixedPcdGet32(PcdMipiFrameBufferAddress);
UINT32 MipiFrameBufferWidth = FixedPcdGet32(PcdMipiFrameBufferWidth);
UINT32 MipiFrameBufferHeight = FixedPcdGet32(PcdMipiFrameBufferHeight);

/* Sanity check */
if (MipiFrameBufferAddr == 0 || MipiFrameBufferWidth == 0 ||
MipiFrameBufferHeight == 0) {
DEBUG((EFI_D_ERROR, "SimpleFbDxe: Invalid FrameBuffer parameters\n"));
return EFI_DEVICE_ERROR;
}

/* Prepare struct */
if (mDisplay.Mode == NULL) {
Status = gBS->AllocatePool(
EfiBootServicesData, sizeof(EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE),
(VOID **)&mDisplay.Mode);

ASSERT_EFI_ERROR(Status);
if (EFI_ERROR(Status))
return Status;

ZeroMem(mDisplay.Mode, sizeof(EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE));
}

if (mDisplay.Mode->Info == NULL) {
Status = gBS->AllocatePool(
EfiBootServicesData, sizeof(EFI_GRAPHICS_OUTPUT_MODE_INFORMATION),
(VOID **)&mDisplay.Mode->Info);

ASSERT_EFI_ERROR(Status);
if (EFI_ERROR(Status))
return Status;

ZeroMem(mDisplay.Mode->Info, sizeof(EFI_GRAPHICS_OUTPUT_MODE_INFORMATION));
}

/* Set information */
mDisplay.Mode->MaxMode = 1;
mDisplay.Mode->Mode = 0;
mDisplay.Mode->Info->Version = 0;

mDisplay.Mode->Info->HorizontalResolution = MipiFrameBufferWidth;
mDisplay.Mode->Info->VerticalResolution = MipiFrameBufferHeight;

/* SimpleFB runs on a8r8g8b8 (VIDEO_BPP32) for DB410c */
UINT32 LineLength = MipiFrameBufferWidth * VNBYTES(VIDEO_BPP32);
UINT32 FrameBufferSize = LineLength * MipiFrameBufferHeight;
EFI_PHYSICAL_ADDRESS FrameBufferAddress = MipiFrameBufferAddr;

mDisplay.Mode->Info->PixelsPerScanLine = MipiFrameBufferWidth;
mDisplay.Mode->Info->PixelFormat = PixelBlueGreenRedReserved8BitPerColor;
mDisplay.Mode->SizeOfInfo = sizeof(EFI_GRAPHICS_OUTPUT_MODE_INFORMATION);
mDisplay.Mode->FrameBufferBase = FrameBufferAddress;
mDisplay.Mode->FrameBufferSize = FrameBufferSize;

//
// Create the FrameBufferBltLib configuration.
//
Status = FrameBufferBltConfigure(
(VOID *)(UINTN)mDisplay.Mode->FrameBufferBase, mDisplay.Mode->Info,
mFrameBufferBltLibConfigure, &mFrameBufferBltLibConfigureSize);
if (Status == RETURN_BUFFER_TOO_SMALL) {
mFrameBufferBltLibConfigure = AllocatePool(mFrameBufferBltLibConfigureSize);
if (mFrameBufferBltLibConfigure != NULL) {
Status = FrameBufferBltConfigure(
(VOID *)(UINTN)mDisplay.Mode->FrameBufferBase, mDisplay.Mode->Info,
mFrameBufferBltLibConfigure, &mFrameBufferBltLibConfigureSize);
}
}
ASSERT_EFI_ERROR(Status);

// zhuowei: clear the screen to black
// UEFI standard requires this, since text is white - see
// OvmfPkg/QemuVideoDxe/Gop.c
ZeroMem((void *)FrameBufferAddress, FrameBufferSize);
// hack: clear cache
WriteBackInvalidateDataCacheRange(
(void *)FrameBufferAddress, FrameBufferSize);
// zhuowei: end

/* Register handle */
Status = gBS->InstallMultipleProtocolInterfaces(
&hUEFIDisplayHandle, &gEfiDevicePathProtocolGuid, &mDisplayDevicePath,
&gEfiGraphicsOutputProtocolGuid, &mDisplay, NULL);

ASSERT_EFI_ERROR(Status);

return Status;
}
51 changes: 51 additions & 0 deletions GPLDrivers/QcomPkg/Drivers/SimpleFbDxe/SimpleFbDxe.inf
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# SimpleFbDxe.inf: Implements Simple FrameBuffer in UEFI.

[Defines]
INF_VERSION = 0x00010005
BASE_NAME = SimpleFbDxe
FILE_GUID = dcfd1e6d-788d-4ffc-8e1b-ca2f75651a92
MODULE_TYPE = DXE_DRIVER
VERSION_STRING = 1.0
ENTRY_POINT = SimpleFbDxeInitialize

[Sources.common]
SimpleFbDxe.c

[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
EmbeddedPkg/EmbeddedPkg.dec
ArmPkg/ArmPkg.dec
Silicon/Qualcomm/QcomPkg/QcomPkg.dec

[LibraryClasses]
BaseLib
ReportStatusCodeLib
UefiLib
UefiBootServicesTableLib
UefiDriverEntryPoint
BaseMemoryLib
DebugLib
PcdLib
FrameBufferBltLib
CacheMaintenanceLib

[Protocols]
gEfiGraphicsOutputProtocolGuid ## PRODUCES
gEfiCpuArchProtocolGuid

[FixedPcd]
gQcomTokenSpaceGuid.PcdMipiFrameBufferAddress
gQcomTokenSpaceGuid.PcdMipiFrameBufferWidth
gQcomTokenSpaceGuid.PcdMipiFrameBufferHeight

[Guids]
gEfiMdeModulePkgTokenSpaceGuid

[Pcd]
gEfiMdeModulePkgTokenSpaceGuid.PcdVideoHorizontalResolution
gEfiMdeModulePkgTokenSpaceGuid.PcdVideoVerticalResolution

[Depex]
gEfiCpuArchProtocolGuid

Loading
Loading