Commit 9a1663bc authored by Arvind Sankar's avatar Arvind Sankar Committed by Ard Biesheuvel

efi/gop: Allow specifying depth as well as resolution

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: default avatarArvind Sankar <nivedita@alum.mit.edu>
Link: https://lore.kernel.org/r/20200320020028.1936003-14-nivedita@alum.mit.eduSigned-off-by: default avatarArd Biesheuvel <ardb@kernel.org>
parent d9ff0323
...@@ -50,9 +50,11 @@ mode=n ...@@ -50,9 +50,11 @@ mode=n
The EFI stub will set the mode of the display to mode number n if The EFI stub will set the mode of the display to mode number n if
possible. possible.
<xres>x<yres> <xres>x<yres>[-(rgb|bgr|<bpp>)]
The EFI stub will search for a display mode that matches the specified 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 horizontal and vertical resolution, and optionally bit depth, and set
it if one is found. 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> Edgar Hucek <gimli@dark-green.com>
...@@ -27,6 +27,8 @@ static struct { ...@@ -27,6 +27,8 @@ static struct {
u32 mode; u32 mode;
struct { struct {
u32 width, height; u32 width, height;
int format;
u8 depth;
} res; } res;
}; };
} cmdline __efistub_global = { .option = EFI_CMDLINE_NONE }; } cmdline __efistub_global = { .option = EFI_CMDLINE_NONE };
...@@ -50,7 +52,8 @@ static bool parse_modenum(char *option, char **next) ...@@ -50,7 +52,8 @@ static bool parse_modenum(char *option, char **next)
static bool parse_res(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)) if (!isdigit(*option))
return false; return false;
...@@ -58,11 +61,26 @@ static bool parse_res(char *option, char **next) ...@@ -58,11 +61,26 @@ static bool parse_res(char *option, char **next)
if (*option++ != 'x' || !isdigit(*option)) if (*option++ != 'x' || !isdigit(*option))
return false; return false;
h = simple_strtoull(option, &option, 10); 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++ != ',') if (*option && *option++ != ',')
return false; return false;
cmdline.option = EFI_CMDLINE_RES; cmdline.option = EFI_CMDLINE_RES;
cmdline.res.width = w; cmdline.res.width = w;
cmdline.res.height = h; cmdline.res.height = h;
cmdline.res.format = pf;
cmdline.res.depth = d;
*next = option; *next = option;
return true; return true;
...@@ -123,6 +141,18 @@ static u32 choose_mode_modenum(efi_graphics_output_protocol_t *gop) ...@@ -123,6 +141,18 @@ static u32 choose_mode_modenum(efi_graphics_output_protocol_t *gop)
return cmdline.mode; 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) static u32 choose_mode_res(efi_graphics_output_protocol_t *gop)
{ {
efi_status_t status; efi_status_t status;
...@@ -133,16 +163,21 @@ static u32 choose_mode_res(efi_graphics_output_protocol_t *gop) ...@@ -133,16 +163,21 @@ static u32 choose_mode_res(efi_graphics_output_protocol_t *gop)
u32 max_mode, cur_mode; u32 max_mode, cur_mode;
int pf; int pf;
efi_pixel_bitmask_t pi;
u32 m, w, h; u32 m, w, h;
mode = efi_table_attr(gop, mode); mode = efi_table_attr(gop, mode);
cur_mode = efi_table_attr(mode, mode); cur_mode = efi_table_attr(mode, mode);
info = efi_table_attr(mode, info); info = efi_table_attr(mode, info);
pf = info->pixel_format;
pi = info->pixel_information;
w = info->horizontal_resolution; w = info->horizontal_resolution;
h = info->vertical_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; return cur_mode;
max_mode = efi_table_attr(mode, max_mode); max_mode = efi_table_attr(mode, max_mode);
...@@ -157,6 +192,7 @@ static u32 choose_mode_res(efi_graphics_output_protocol_t *gop) ...@@ -157,6 +192,7 @@ static u32 choose_mode_res(efi_graphics_output_protocol_t *gop)
continue; continue;
pf = info->pixel_format; pf = info->pixel_format;
pi = info->pixel_information;
w = info->horizontal_resolution; w = info->horizontal_resolution;
h = info->vertical_resolution; h = info->vertical_resolution;
...@@ -164,7 +200,9 @@ static u32 choose_mode_res(efi_graphics_output_protocol_t *gop) ...@@ -164,7 +200,9 @@ static u32 choose_mode_res(efi_graphics_output_protocol_t *gop)
if (pf == PIXEL_BLT_ONLY || pf >= PIXEL_FORMAT_MAX) if (pf == PIXEL_BLT_ONLY || pf >= PIXEL_FORMAT_MAX)
continue; 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; return m;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment