Skip to content

Commit

Permalink
GOP: Support landscape mode (90 degree rotation) on Fydetab
Browse files Browse the repository at this point in the history
  • Loading branch information
Rippanda12 committed Dec 29, 2024
1 parent 8b4c710 commit 08f9cfb
Show file tree
Hide file tree
Showing 5 changed files with 331 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,11 @@
gRK3588TokenSpaceGuid.PcdUsbDpPhy0Supported|TRUE
gRK3588TokenSpaceGuid.PcdDp0LaneMux|{ 0x2, 0x3 }

#
# Landscape graphics output
#
gRockchipTokenSpaceGuid.PcdLcdRotateToLandscape|TRUE

#
# I2S
#
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -830,6 +830,290 @@ BltVideoToVideo (
return Status;
}

STATIC
EFI_STATUS
BltVideoFill90 (
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_STATUS Status;
UINT32 FrameBufferHeight;
VOID *FrameBufferBase;
VOID *DestinationAddr;

Status = EFI_SUCCESS;
FrameBufferBase = (UINTN *)((UINTN)(This->Mode->FrameBufferBase));
FrameBufferHeight = This->Mode->Info->VerticalResolution;

for (UINTN y = 0; y < Height; ++y) {
for (UINTN x = 0; x < Width; ++x) {
DestinationAddr = (VOID *)((UINT32 *)FrameBufferBase + (DestinationX + x) * FrameBufferHeight + (FrameBufferHeight - 1 - (DestinationY + y)));

*(UINT32 *)DestinationAddr = *((UINT32 *)EfiSourcePixel);
}
}

return Status;
}

STATIC
EFI_STATUS
BltVideoToBltBuffer90 (
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 FrameBufferHeight;
VOID *FrameBufferBase;
VOID *SourceAddr;
VOID *DestinationAddr;
UINT32 BltBufferHorizontalResolution;

Status = EFI_SUCCESS;
FrameBufferHeight = This->Mode->Info->VerticalResolution;
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;
}

for (UINTN y = 0; y < Height; ++y) {
for (UINTN x = 0; x < Width; ++x) {
SourceAddr = (VOID *)((UINT32 *)FrameBufferBase + (SourceX + x) * FrameBufferHeight + (FrameBufferHeight - 1 - (SourceY + y)));
DestinationAddr = (VOID *)((UINT32 *)BltBuffer + (DestinationY + y) * BltBufferHorizontalResolution + (DestinationX + x));

*(UINT32 *)DestinationAddr = *(UINT32 *)SourceAddr;
}
}

return Status;
}

STATIC
EFI_STATUS
BltBufferToVideo90 (
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 FrameBufferHeight;
VOID *FrameBufferBase;
VOID *SourceAddr;
VOID *DestinationAddr;
UINT32 BltBufferHorizontalResolution;

Status = EFI_SUCCESS;
FrameBufferHeight = This->Mode->Info->VerticalResolution;
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;
}

for (UINTN y = 0; y < Height; ++y) {
for (UINTN x = 0; x < Width; ++x) {
SourceAddr = (VOID *)((UINT32 *)BltBuffer + (SourceY + y) * BltBufferHorizontalResolution + (SourceX + x));
DestinationAddr = (VOID *)((UINT32 *)FrameBufferBase + (DestinationX + x) * FrameBufferHeight + (FrameBufferHeight - 1 - (DestinationY + y)));

*(UINT32 *)DestinationAddr = *(UINT32 *)SourceAddr;
}
}

return Status;
}

STATIC
EFI_STATUS
VideoCopyNoHorizontalOverlap90 (
IN UINTN BitsPerPixel,
IN volatile VOID *FrameBufferBase,
IN UINT32 VerticalResolution,
IN UINTN SourceX,
IN UINTN SourceY,
IN UINTN DestinationX,
IN UINTN DestinationY,
IN UINTN Width,
IN UINTN Height
)
{
EFI_STATUS Status;
UINTN SourceLine;
UINTN DestinationLine;
UINTN LineCount;
INTN Step;
VOID *SourceAddr;
VOID *DestinationAddr;

Status = EFI_SUCCESS;

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;
}

for (LineCount = 0; LineCount < Height; LineCount++) {
for (UINTN x = 0; x < Width; ++x) {
SourceAddr = (VOID *)((UINT32 *)FrameBufferBase + (SourceX + x) * VerticalResolution + (VerticalResolution - 1 - SourceLine));
DestinationAddr = (VOID *)((UINT32 *)FrameBufferBase + (DestinationX + x) * VerticalResolution + (VerticalResolution - 1 - DestinationLine));

*(UINT32 *)DestinationAddr = *(UINT32 *)SourceAddr;
}

SourceLine += Step;
DestinationLine += Step;
}

return Status;
}

STATIC
EFI_STATUS
VideoCopyHorizontalOverlap90 (
IN UINTN BitsPerPixel,
IN volatile VOID *FrameBufferBase,
IN UINT32 VerticalResolution,
IN UINTN SourceX,
IN UINTN SourceY,
IN UINTN DestinationX,
IN UINTN DestinationY,
IN UINTN Width,
IN UINTN Height
)
{
EFI_STATUS Status;

UINT32 *PixelBuffer32bit;
UINT32 *SourcePixel32bit;
UINT32 *DestinationPixel32bit;

Status = EFI_SUCCESS;

// Allocate a temporary buffer
PixelBuffer32bit = (UINT32 *) AllocatePool((Height * Width) * sizeof(UINT32));

if (PixelBuffer32bit == NULL) {
Status = EFI_OUT_OF_RESOURCES;
goto EXIT;
}

// Copy from the video ram (source region) to a temp buffer
for (UINTN y = 0; y < Height; ++y) {
for (UINTN x = 0; x < Width; ++x) {
SourcePixel32bit = (UINT32 *)FrameBufferBase + (SourceX + x) * VerticalResolution + (VerticalResolution - 1 - (SourceY + y));

PixelBuffer32bit[y * Width + x] = *SourcePixel32bit;
}
}

// Copy from the temp buffer to the video ram (destination region)
for (UINTN y = 0; y < Height; ++y) {
for (UINTN x = 0; x < Width; ++x) {
DestinationPixel32bit = (UINT32 *)FrameBufferBase + (DestinationX + x) * VerticalResolution + (VerticalResolution - 1 - (DestinationY + y));

*DestinationPixel32bit = PixelBuffer32bit[y * Width + x];
}
}

// Free up the allocated memory
FreePool((VOID *) PixelBuffer32bit);

EXIT:
return Status;
}

STATIC
EFI_STATUS
BltVideoToVideo90 (
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 VerticalResolution;
LCD_BPP BitsPerPixel;
VOID *FrameBufferBase;

VerticalResolution = This->Mode->Info->VerticalResolution;
FrameBufferBase = (UINTN *)((UINTN)(This->Mode->FrameBufferBase));

//
// BltVideo to BltVideo:
//
// Source is the Video Memory,
// Destination is the Video Memory

LcdGraphicsGetBpp (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 = VideoCopyHorizontalOverlap90 (BitsPerPixel, FrameBufferBase, VerticalResolution, SourceX, SourceY, DestinationX, DestinationY, Width, Height );
} else {
// No overlap
Status = VideoCopyNoHorizontalOverlap90 (BitsPerPixel, FrameBufferBase, VerticalResolution, SourceX, SourceY, DestinationX, DestinationY, Width, Height );
}
} else {
// Copying from different heights
Status = VideoCopyNoHorizontalOverlap90 (BitsPerPixel, FrameBufferBase, VerticalResolution, SourceX, SourceY, DestinationX, DestinationY, Width, Height );
}

return Status;
}

/***************************************
* GraphicsOutput Protocol function, mapping to
* EFI_GRAPHICS_OUTPUT_PROTOCOL.Blt
Expand Down Expand Up @@ -907,21 +1191,39 @@ LcdGraphicsBlt (
// Perform the Block Transfer Operation
//

BOOLEAN LandscapeMode = FixedPcdGetBool (PcdLcdRotateToLandscape);

switch (BltOperation) {
case EfiBltVideoFill:
Status = BltVideoFill (This, BltBuffer, SourceX, SourceY, DestinationX, DestinationY, Width, Height, Delta);
if (LandscapeMode) {
Status = BltVideoFill90 (This, BltBuffer, SourceX, SourceY, DestinationX, DestinationY, Width, Height, Delta);
} else {
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);
if (LandscapeMode) {
Status = BltVideoToBltBuffer90 (This, BltBuffer, SourceX, SourceY, DestinationX, DestinationY, Width, Height, Delta);
} else {
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);
if (LandscapeMode) {
Status = BltBufferToVideo90 (This, BltBuffer, SourceX, SourceY, DestinationX, DestinationY, Width, Height, Delta);
} else {
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);
if (LandscapeMode) {
Status = BltVideoToVideo90 (This, BltBuffer, SourceX, SourceY, DestinationX, DestinationY, Width, Height, Delta);
} else {
Status = BltVideoToVideo (This, BltBuffer, SourceX, SourceY, DestinationX, DestinationY, Width, Height, Delta);
}
break;

case EfiGraphicsOutputBltOperationMax:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -503,8 +503,15 @@ LcdGraphicsQueryMode (
*SizeOfInfo = sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION);

(*Info)->Version = 0;
(*Info)->HorizontalResolution = mDisplayModes[ModeNumber].Horizontal.Resolution;
(*Info)->VerticalResolution = mDisplayModes[ModeNumber].Vertical.Resolution;

if (FixedPcdGetBool (PcdLcdRotateToLandscape)) {
(*Info)->HorizontalResolution = mDisplayModes[ModeNumber].Vertical.Resolution;
(*Info)->VerticalResolution = mDisplayModes[ModeNumber].Horizontal.Resolution;
} else {
(*Info)->HorizontalResolution = mDisplayModes[ModeNumber].Horizontal.Resolution;
(*Info)->VerticalResolution = mDisplayModes[ModeNumber].Vertical.Resolution;
}

(*Info)->PixelsPerScanLine = mDisplayModes[ModeNumber].Horizontal.Resolution;
(*Info)->PixelFormat = FixedPcdGet32 (PcdLcdPixelFormat);

Expand Down Expand Up @@ -597,8 +604,15 @@ LcdGraphicsSetMode (
This->Mode->Mode = ModeNumber;

Instance->ModeInfo.Version = 0;
Instance->ModeInfo.HorizontalResolution = mDisplayModes[ModeNumber].Horizontal.Resolution;
Instance->ModeInfo.VerticalResolution = mDisplayModes[ModeNumber].Vertical.Resolution;

if (FixedPcdGetBool (PcdLcdRotateToLandscape)) {
Instance->ModeInfo.HorizontalResolution = mDisplayModes[ModeNumber].Vertical.Resolution;
Instance->ModeInfo.VerticalResolution = mDisplayModes[ModeNumber].Horizontal.Resolution;
} else {
Instance->ModeInfo.HorizontalResolution = mDisplayModes[ModeNumber].Horizontal.Resolution;
Instance->ModeInfo.VerticalResolution = mDisplayModes[ModeNumber].Vertical.Resolution;
}

Instance->ModeInfo.PixelsPerScanLine = mDisplayModes[ModeNumber].Horizontal.Resolution;
Instance->ModeInfo.PixelFormat = FixedPcdGet32 (PcdLcdPixelFormat);
Instance->Mode.SizeOfInfo = sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@

[Pcd]
gRockchipTokenSpaceGuid.PcdLcdPixelFormat
gRockchipTokenSpaceGuid.PcdLcdRotateToLandscape

[FeaturePcd]
gArmPlatformTokenSpaceGuid.PcdGopDisableOnExitBootServices
Expand Down
1 change: 1 addition & 0 deletions edk2-rockchip/Silicon/Rockchip/RockchipPkg.dec
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@
gRockchipTokenSpaceGuid.PcdNvStoragePreferSpiFlash|FALSE|BOOLEAN|0x21200009

gRockchipTokenSpaceGuid.PcdLcdPixelFormat|0|UINT32|0x32000001
gRockchipTokenSpaceGuid.PcdLcdRotateToLandscape|FALSE|BOOLEAN|0x32000002
gRockchipTokenSpaceGuid.PcdEdpId|0|UINT32|0x32000003
gRockchipTokenSpaceGuid.PcdHdmiId|0|UINT32|0x32000004
gRockchipTokenSpaceGuid.PcdHdmiDDCI2CPinMux|0|UINT32|0x32000005
Expand Down

0 comments on commit 08f9cfb

Please sign in to comment.