Skip to content

Commit

Permalink
Platforms/RPi3: DisplayDxe virtual resolution improvements
Browse files Browse the repository at this point in the history
The Pi GPU decouples requested resolution from actual physical resolution
and can perform scaling of virtual resolutions. This enables platform users
to do something like ask for 1024x768 and get a framebuffer of that size,
regardless of the actual output (which could be a very blurry SDTV).

Specifically, this patch allows selecting which specific virtual
resolutions to enable, thus replacing the old all-or-nothing behaviour
with either all virtual resolutions supported, or just the native one.

This patch also adds enables the common 7" Pi (800x480) screen to be used
at 800x600 resolution, instead of forcing 640x480 as the only usable
resolution.

Signed-off-by: Pete Batard <pete@akeo.ie>
Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>
  • Loading branch information
andreiw authored and Leif Lindholm committed Oct 1, 2019
1 parent c2f593b commit 7775738
Show file tree
Hide file tree
Showing 8 changed files with 125 additions and 33 deletions.
9 changes: 5 additions & 4 deletions Platform/RaspberryPi/RPi3/Drivers/ConfigDxe/ConfigDxe.c
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ SetupVariables (
)
{
UINTN Size;
UINT8 Var8;
UINT32 Var32;
EFI_STATUS Status;

Expand Down Expand Up @@ -180,12 +181,12 @@ SetupVariables (
PcdSet32 (PcdDebugShowUEFIExit, PcdGet32 (PcdDebugShowUEFIExit));
}

Size = sizeof (UINT32);
Status = gRT->GetVariable (L"DisplayEnableVModes",
Size = sizeof (UINT8);
Status = gRT->GetVariable (L"DisplayEnableScaledVModes",
&gConfigDxeFormSetGuid,
NULL, &Size, &Var32);
NULL, &Size, &Var8);
if (EFI_ERROR (Status)) {
PcdSet32 (PcdDisplayEnableVModes, PcdGet32 (PcdDisplayEnableVModes));
PcdSet8 (PcdDisplayEnableScaledVModes, PcdGet8 (PcdDisplayEnableScaledVModes));
}

Size = sizeof (UINT32);
Expand Down
2 changes: 1 addition & 1 deletion Platform/RaspberryPi/RPi3/Drivers/ConfigDxe/ConfigDxe.inf
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@
gRaspberryPiTokenSpaceGuid.PcdMmcDisableMulti
gRaspberryPiTokenSpaceGuid.PcdDebugEnableJTAG
gRaspberryPiTokenSpaceGuid.PcdDebugShowUEFIExit
gRaspberryPiTokenSpaceGuid.PcdDisplayEnableVModes
gRaspberryPiTokenSpaceGuid.PcdDisplayEnableScaledVModes
gRaspberryPiTokenSpaceGuid.PcdDisplayEnableSShot

[FeaturePcd]
Expand Down
17 changes: 13 additions & 4 deletions Platform/RaspberryPi/RPi3/Drivers/ConfigDxe/ConfigDxeHii.uni
Original file line number Diff line number Diff line change
Expand Up @@ -71,10 +71,19 @@
#string STR_DISPLAY_FORM_TITLE #language en-US "Display"
#string STR_DISPLAY_FORM_SUBTITLE #language en-US "UEFI video driver settings"

#string STR_DISPLAY_VMODES_PROMPT #language en-US "Resolutions"
#string STR_DISPLAY_VMODES_HELP #language en-US "Support for non-native modes"
#string STR_DISPLAY_VMODES_ENABLE #language en-US "Also support 640x480, 800x600, 1024x768, 720p and 1080p"
#string STR_DISPLAY_VMODES_DISABLE #language en-US "Only native resolution"
#string STR_DISPLAY_VMODES_640_PROMPT #language en-US "Virtual 640x480"
#string STR_DISPLAY_VMODES_640_HELP #language en-US "Enable scaled 640x480 mode"
#string STR_DISPLAY_VMODES_800_PROMPT #language en-US "Virtual 800x600"
#string STR_DISPLAY_VMODES_800_HELP #language en-US "Enable scaled 800x600 mode"
#string STR_DISPLAY_VMODES_1024_PROMPT #language en-US "Virtual 1024x768"
#string STR_DISPLAY_VMODES_1024_HELP #language en-US "Enable scaled 1024x768 mode"
#string STR_DISPLAY_VMODES_720_PROMPT #language en-US "Virtual 720p"
#string STR_DISPLAY_VMODES_720_HELP #language en-US "Enable scaled 720p mode"
#string STR_DISPLAY_VMODES_1080_PROMPT #language en-US "Virtual 1080p"
#string STR_DISPLAY_VMODES_1080_HELP #language en-US "Enable scaled 1080p mode"

#string STR_DISPLAY_VMODES_REAL_PROMPT #language en-US "Native resolution"
#string STR_DISPLAY_VMODES_REAL_HELP #language en-US "Native resolution"

#string STR_DISPLAY_SSHOT_PROMPT #language en-US "Screenshot Support"
#string STR_DISPLAY_SSHOT_HELP #language en-US "Save screen capture as a BMP on the first writable file system found"
Expand Down
71 changes: 57 additions & 14 deletions Platform/RaspberryPi/RPi3/Drivers/ConfigDxe/ConfigDxeHii.vfr
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,23 @@
#include <Guid/HiiPlatformSetupFormset.h>
#include "ConfigDxeFormSetGuid.h"

#pragma pack(1)
typedef struct {
/*
* 0 - One mode for the boot resolution.
* 1 - Adds additional "typical" resolutions like
* 640x480, 800x600, 1024 x 768, 720p and 1080p.
* One bit for each scaled resolution supported,
* these are ordered exactly like mGopModeData
* in DisplayDxe.
*
* 800x600, 640x480, 1024x768, 720p, 1080p, native.
*/
UINT32 Enable;
} DISPLAY_ENABLE_VMODES_VARSTORE_DATA;
UINT8 v640 : 1;
UINT8 v800 : 1;
UINT8 v1024 : 1;
UINT8 v720p : 1;
UINT8 v1080p : 1;
UINT8 Physical : 1;
} DISPLAY_ENABLE_SCALED_VMODES_VARSTORE_DATA;
#pragma pack()

typedef struct {
/*
Expand Down Expand Up @@ -166,9 +175,9 @@ formset
name = DebugShowUEFIExit,
guid = CONFIGDXE_FORM_SET_GUID;

efivarstore DISPLAY_ENABLE_VMODES_VARSTORE_DATA,
efivarstore DISPLAY_ENABLE_SCALED_VMODES_VARSTORE_DATA,
attribute = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
name = DisplayEnableVModes,
name = DisplayEnableScaledVModes,
guid = CONFIGDXE_FORM_SET_GUID;

efivarstore DISPLAY_ENABLE_SSHOT_VARSTORE_DATA,
Expand Down Expand Up @@ -282,13 +291,47 @@ formset
title = STRING_TOKEN(STR_DISPLAY_FORM_TITLE);
subtitle text = STRING_TOKEN(STR_DISPLAY_FORM_SUBTITLE);

oneof varid = DisplayEnableVModes.Enable,
prompt = STRING_TOKEN(STR_DISPLAY_VMODES_PROMPT),
help = STRING_TOKEN(STR_DISPLAY_VMODES_HELP),
flags = NUMERIC_SIZE_4 | INTERACTIVE | RESET_REQUIRED,
option text = STRING_TOKEN(STR_DISPLAY_VMODES_ENABLE), value = 1, flags = DEFAULT;
option text = STRING_TOKEN(STR_DISPLAY_VMODES_DISABLE), value = 0, flags = 0;
endoneof;
checkbox varid = DisplayEnableScaledVModes.v640,
prompt = STRING_TOKEN(STR_DISPLAY_VMODES_640_PROMPT),
help = STRING_TOKEN(STR_DISPLAY_VMODES_640_HELP),
flags = CHECKBOX_DEFAULT | CHECKBOX_DEFAULT_MFG | RESET_REQUIRED,
default = TRUE,
endcheckbox;

checkbox varid = DisplayEnableScaledVModes.v800,
prompt = STRING_TOKEN(STR_DISPLAY_VMODES_800_PROMPT),
help = STRING_TOKEN(STR_DISPLAY_VMODES_800_HELP),
flags = CHECKBOX_DEFAULT | CHECKBOX_DEFAULT_MFG | RESET_REQUIRED,
default = TRUE,
endcheckbox;

checkbox varid = DisplayEnableScaledVModes.v1024,
prompt = STRING_TOKEN(STR_DISPLAY_VMODES_1024_PROMPT),
help = STRING_TOKEN(STR_DISPLAY_VMODES_1024_HELP),
flags = CHECKBOX_DEFAULT | CHECKBOX_DEFAULT_MFG | RESET_REQUIRED,
default = TRUE,
endcheckbox;

checkbox varid = DisplayEnableScaledVModes.v720p,
prompt = STRING_TOKEN(STR_DISPLAY_VMODES_720_PROMPT),
help = STRING_TOKEN(STR_DISPLAY_VMODES_720_HELP),
flags = CHECKBOX_DEFAULT | CHECKBOX_DEFAULT_MFG | RESET_REQUIRED,
default = TRUE,
endcheckbox;

checkbox varid = DisplayEnableScaledVModes.v1080p,
prompt = STRING_TOKEN(STR_DISPLAY_VMODES_1080_PROMPT),
help = STRING_TOKEN(STR_DISPLAY_VMODES_1080_HELP),
flags = CHECKBOX_DEFAULT | CHECKBOX_DEFAULT_MFG | RESET_REQUIRED,
default = TRUE,
endcheckbox;

checkbox varid = DisplayEnableScaledVModes.Physical,
prompt = STRING_TOKEN(STR_DISPLAY_VMODES_REAL_PROMPT),
help = STRING_TOKEN(STR_DISPLAY_VMODES_REAL_HELP),
flags = CHECKBOX_DEFAULT | CHECKBOX_DEFAULT_MFG | RESET_REQUIRED,
default = TRUE,
endcheckbox;

oneof varid = DisplayEnableSShot.Enable,
prompt = STRING_TOKEN(STR_DISPLAY_SSHOT_PROMPT),
Expand Down
53 changes: 46 additions & 7 deletions Platform/RaspberryPi/RPi3/Drivers/DisplayDxe/DisplayDxe.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,14 @@
#include <Base.h>
#include "DisplayDxe.h"

#define MODE_800_ENABLED BIT0
#define MODE_640_ENABLED BIT1
#define MODE_1024_ENABLED BIT2
#define MODE_720P_ENABLED BIT3
#define MODE_1080P_ENABLED BIT4
#define MODE_NATIVE_ENABLED BIT5
#define JUST_NATIVE_ENABLED MODE_NATIVE_ENABLED
#define ALL_MODES (BIT6 - 1)
#define POS_TO_FB(posX, posY) ((UINT8*) \
((UINTN)This->Mode->FrameBufferBase + \
(posY) * This->Mode->Info->PixelsPerScanLine * \
Expand Down Expand Up @@ -104,7 +112,7 @@ STATIC RASPBERRY_PI_FIRMWARE_PROTOCOL *mFwProtocol;
STATIC EFI_CPU_ARCH_PROTOCOL *mCpu;

STATIC UINTN mLastMode;
STATIC GOP_MODE_DATA mGopModeData[] = {
STATIC GOP_MODE_DATA mGopModeTemplate[] = {
{ 800, 600 }, /* Legacy */
{ 640, 480 }, /* Legacy */
{ 1024, 768 }, /* Legacy */
Expand All @@ -113,6 +121,9 @@ STATIC GOP_MODE_DATA mGopModeData[] = {
{ 0, 0 }, /* Physical */
};

STATIC UINTN mLastMode;
STATIC GOP_MODE_DATA mGopModeData[ARRAY_SIZE (mGopModeTemplate)];

STATIC DISPLAY_DEVICE_PATH mDisplayProtoDevicePath =
{
{
Expand Down Expand Up @@ -446,6 +457,7 @@ DriverStart (
)
{
UINTN Index;
UINTN TempIndex;
EFI_STATUS Status;
VOID *Dummy;

Expand Down Expand Up @@ -473,11 +485,29 @@ DriverStart (
goto Done;
}

PcdSet8 (PcdDisplayEnableScaledVModes,
PcdGet8 (PcdDisplayEnableScaledVModes) & ALL_MODES);

if (PcdGet32 (PcdDisplayEnableVModes)) {
mLastMode = ARRAY_SIZE (mGopModeData) - 1;
} else {
mLastMode = 0;
if (PcdGet8 (PcdDisplayEnableScaledVModes) == 0) {
PcdSet8 (PcdDisplayEnableScaledVModes, JUST_NATIVE_ENABLED);
}

mLastMode = 0;
for (TempIndex = 0, Index = 0;
TempIndex < ARRAY_SIZE (mGopModeTemplate); TempIndex++) {
if ((PcdGet8 (PcdDisplayEnableScaledVModes) & (1 << TempIndex)) != 0) {
DEBUG ((DEBUG_ERROR, "Mode %u: %u x %u present\n",
TempIndex, mGopModeTemplate[TempIndex].Width,
mGopModeTemplate[TempIndex].Height));

CopyMem (&mGopModeData[Index], &mGopModeTemplate[TempIndex],
sizeof (GOP_MODE_DATA));
mLastMode = Index;
Index++;
}
}

if (PcdGet8 (PcdDisplayEnableScaledVModes) == JUST_NATIVE_ENABLED) {
/*
* mBootWidth x mBootHeight may not be sensible,
* so clean it up, since we won't be adding
Expand All @@ -486,11 +516,20 @@ DriverStart (
if (mBootWidth < 640 || mBootHeight < 480) {
mBootWidth = 640;
mBootHeight = 480;
} else if (mBootWidth == 800 && mBootHeight == 480) {
/* The Pi 7" screen is close to 800x600, just pretend it is. */
mBootHeight = 600;
}
}

mGopModeData[mLastMode].Width = mBootWidth;
mGopModeData[mLastMode].Height = mBootHeight;
if ((PcdGet8(PcdDisplayEnableScaledVModes) & MODE_NATIVE_ENABLED) != 0) {
/*
* Adjust actual native res only if native res is enabled
* (so last mode is native res).
*/
mGopModeData[mLastMode].Width = mBootWidth;
mGopModeData[mLastMode].Height = mBootHeight;
}

for (Index = 0; Index <= mLastMode; Index++) {
UINTN FbSize;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@
gRaspberryPiFirmwareProtocolGuid

[Pcd]
gRaspberryPiTokenSpaceGuid.PcdDisplayEnableVModes
gRaspberryPiTokenSpaceGuid.PcdDisplayEnableScaledVModes
gRaspberryPiTokenSpaceGuid.PcdDisplayEnableSShot

[Guids]
Expand Down
2 changes: 1 addition & 1 deletion Platform/RaspberryPi/RPi3/RPi3.dec
Original file line number Diff line number Diff line change
Expand Up @@ -54,5 +54,5 @@
gRaspberryPiTokenSpaceGuid.PcdDebugEnableJTAG|0|UINT32|0x00000014
gRaspberryPiTokenSpaceGuid.PcdDebugShowUEFIExit|0|UINT32|0x00000015
gRaspberryPiTokenSpaceGuid.PcdCustomCpuClock|0|UINT32|0x00000016
gRaspberryPiTokenSpaceGuid.PcdDisplayEnableVModes|0|UINT32|0x00000017
gRaspberryPiTokenSpaceGuid.PcdDisplayEnableScaledVModes|0|UINT8|0x00000017
gRaspberryPiTokenSpaceGuid.PcdDisplayEnableSShot|0|UINT32|0x00000018
2 changes: 1 addition & 1 deletion Platform/RaspberryPi/RPi3/RPi3.dsc
Original file line number Diff line number Diff line change
Expand Up @@ -416,7 +416,7 @@
#
# Display-related.
#
gRaspberryPiTokenSpaceGuid.PcdDisplayEnableVModes|L"DisplayEnableVModes"|gConfigDxeFormSetGuid|0x0|0
gRaspberryPiTokenSpaceGuid.PcdDisplayEnableScaledVModes|L"DisplayEnableScaledVModes"|gConfigDxeFormSetGuid|0x0|0xff
gRaspberryPiTokenSpaceGuid.PcdDisplayEnableSShot|L"DisplayEnableSShot"|gConfigDxeFormSetGuid|0x0|1

#
Expand Down

0 comments on commit 7775738

Please sign in to comment.