Skip to content

Commit

Permalink
efi/gop: Allow specifying depth as well as resolution
Browse files Browse the repository at this point in the history
Extend the video mode argument to handle an optional color depth
specification of the form
	video=efifb:<xres>x<yres>[-(rgb|bgr|<bpp>)]

Signed-off-by: Arvind Sankar <nivedita@alum.mit.edu>
Link: https://lore.kernel.org/r/20200320020028.1936003-14-nivedita@alum.mit.edu
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
  • Loading branch information
Arvind Sankar authored and Ard Biesheuvel committed Apr 23, 2020
1 parent d9ff032 commit 9a1663b
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 8 deletions.
8 changes: 5 additions & 3 deletions Documentation/fb/efifb.rst
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,11 @@ mode=n
The EFI stub will set the mode of the display to mode number n if
possible.

<xres>x<yres>
<xres>x<yres>[-(rgb|bgr|<bpp>)]
The EFI stub will search for a display mode that matches the specified
horizontal and vertical resolution, and set the mode of the display to
it if one is found.
horizontal and vertical resolution, and optionally bit depth, and set
the mode of the display to it if one is found. The bit depth can either
"rgb" or "bgr" to match specifically those pixel formats, or a number
for a mode with matching bits per pixel.

Edgar Hucek <gimli@dark-green.com>
48 changes: 43 additions & 5 deletions drivers/firmware/efi/libstub/gop.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ static struct {
u32 mode;
struct {
u32 width, height;
int format;
u8 depth;
} res;
};
} cmdline __efistub_global = { .option = EFI_CMDLINE_NONE };
Expand All @@ -50,19 +52,35 @@ static bool parse_modenum(char *option, char **next)

static bool parse_res(char *option, char **next)
{
u32 w, h;
u32 w, h, d = 0;
int pf = -1;

if (!isdigit(*option))
return false;
w = simple_strtoull(option, &option, 10);
if (*option++ != 'x' || !isdigit(*option))
return false;
h = simple_strtoull(option, &option, 10);
if (*option == '-') {
option++;
if (strstarts(option, "rgb")) {
option += strlen("rgb");
pf = PIXEL_RGB_RESERVED_8BIT_PER_COLOR;
} else if (strstarts(option, "bgr")) {
option += strlen("bgr");
pf = PIXEL_BGR_RESERVED_8BIT_PER_COLOR;
} else if (isdigit(*option))
d = simple_strtoull(option, &option, 10);
else
return false;
}
if (*option && *option++ != ',')
return false;
cmdline.option = EFI_CMDLINE_RES;
cmdline.res.width = w;
cmdline.res.height = h;
cmdline.res.format = pf;
cmdline.res.depth = d;

*next = option;
return true;
Expand Down Expand Up @@ -123,6 +141,18 @@ static u32 choose_mode_modenum(efi_graphics_output_protocol_t *gop)
return cmdline.mode;
}

static u8 pixel_bpp(int pixel_format, efi_pixel_bitmask_t pixel_info)
{
if (pixel_format == PIXEL_BIT_MASK) {
u32 mask = pixel_info.red_mask | pixel_info.green_mask |
pixel_info.blue_mask | pixel_info.reserved_mask;
if (!mask)
return 0;
return __fls(mask) - __ffs(mask) + 1;
} else
return 32;
}

static u32 choose_mode_res(efi_graphics_output_protocol_t *gop)
{
efi_status_t status;
Expand All @@ -133,16 +163,21 @@ static u32 choose_mode_res(efi_graphics_output_protocol_t *gop)

u32 max_mode, cur_mode;
int pf;
efi_pixel_bitmask_t pi;
u32 m, w, h;

mode = efi_table_attr(gop, mode);

cur_mode = efi_table_attr(mode, mode);
info = efi_table_attr(mode, info);
w = info->horizontal_resolution;
h = info->vertical_resolution;
pf = info->pixel_format;
pi = info->pixel_information;
w = info->horizontal_resolution;
h = info->vertical_resolution;

if (w == cmdline.res.width && h == cmdline.res.height)
if (w == cmdline.res.width && h == cmdline.res.height &&
(cmdline.res.format < 0 || cmdline.res.format == pf) &&
(!cmdline.res.depth || cmdline.res.depth == pixel_bpp(pf, pi)))
return cur_mode;

max_mode = efi_table_attr(mode, max_mode);
Expand All @@ -157,14 +192,17 @@ static u32 choose_mode_res(efi_graphics_output_protocol_t *gop)
continue;

pf = info->pixel_format;
pi = info->pixel_information;
w = info->horizontal_resolution;
h = info->vertical_resolution;

efi_bs_call(free_pool, info);

if (pf == PIXEL_BLT_ONLY || pf >= PIXEL_FORMAT_MAX)
continue;
if (w == cmdline.res.width && h == cmdline.res.height)
if (w == cmdline.res.width && h == cmdline.res.height &&
(cmdline.res.format < 0 || cmdline.res.format == pf) &&
(!cmdline.res.depth || cmdline.res.depth == pixel_bpp(pf, pi)))
return m;
}

Expand Down

0 comments on commit 9a1663b

Please sign in to comment.