Skip to content

Commit 9a1663b

Browse files
nivedita76ardbiesheuvel
authored andcommitted
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: Arvind Sankar <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Ard Biesheuvel <[email protected]>
1 parent d9ff032 commit 9a1663b

File tree

2 files changed

+48
-8
lines changed

2 files changed

+48
-8
lines changed

Documentation/fb/efifb.rst

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,11 @@ mode=n
5050
The EFI stub will set the mode of the display to mode number n if
5151
possible.
5252

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

5860
Edgar Hucek <[email protected]>

drivers/firmware/efi/libstub/gop.c

Lines changed: 43 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ static struct {
2727
u32 mode;
2828
struct {
2929
u32 width, height;
30+
int format;
31+
u8 depth;
3032
} res;
3133
};
3234
} cmdline __efistub_global = { .option = EFI_CMDLINE_NONE };
@@ -50,19 +52,35 @@ static bool parse_modenum(char *option, char **next)
5052

5153
static bool parse_res(char *option, char **next)
5254
{
53-
u32 w, h;
55+
u32 w, h, d = 0;
56+
int pf = -1;
5457

5558
if (!isdigit(*option))
5659
return false;
5760
w = simple_strtoull(option, &option, 10);
5861
if (*option++ != 'x' || !isdigit(*option))
5962
return false;
6063
h = simple_strtoull(option, &option, 10);
64+
if (*option == '-') {
65+
option++;
66+
if (strstarts(option, "rgb")) {
67+
option += strlen("rgb");
68+
pf = PIXEL_RGB_RESERVED_8BIT_PER_COLOR;
69+
} else if (strstarts(option, "bgr")) {
70+
option += strlen("bgr");
71+
pf = PIXEL_BGR_RESERVED_8BIT_PER_COLOR;
72+
} else if (isdigit(*option))
73+
d = simple_strtoull(option, &option, 10);
74+
else
75+
return false;
76+
}
6177
if (*option && *option++ != ',')
6278
return false;
6379
cmdline.option = EFI_CMDLINE_RES;
6480
cmdline.res.width = w;
6581
cmdline.res.height = h;
82+
cmdline.res.format = pf;
83+
cmdline.res.depth = d;
6684

6785
*next = option;
6886
return true;
@@ -123,6 +141,18 @@ static u32 choose_mode_modenum(efi_graphics_output_protocol_t *gop)
123141
return cmdline.mode;
124142
}
125143

144+
static u8 pixel_bpp(int pixel_format, efi_pixel_bitmask_t pixel_info)
145+
{
146+
if (pixel_format == PIXEL_BIT_MASK) {
147+
u32 mask = pixel_info.red_mask | pixel_info.green_mask |
148+
pixel_info.blue_mask | pixel_info.reserved_mask;
149+
if (!mask)
150+
return 0;
151+
return __fls(mask) - __ffs(mask) + 1;
152+
} else
153+
return 32;
154+
}
155+
126156
static u32 choose_mode_res(efi_graphics_output_protocol_t *gop)
127157
{
128158
efi_status_t status;
@@ -133,16 +163,21 @@ static u32 choose_mode_res(efi_graphics_output_protocol_t *gop)
133163

134164
u32 max_mode, cur_mode;
135165
int pf;
166+
efi_pixel_bitmask_t pi;
136167
u32 m, w, h;
137168

138169
mode = efi_table_attr(gop, mode);
139170

140171
cur_mode = efi_table_attr(mode, mode);
141172
info = efi_table_attr(mode, info);
142-
w = info->horizontal_resolution;
143-
h = info->vertical_resolution;
173+
pf = info->pixel_format;
174+
pi = info->pixel_information;
175+
w = info->horizontal_resolution;
176+
h = info->vertical_resolution;
144177

145-
if (w == cmdline.res.width && h == cmdline.res.height)
178+
if (w == cmdline.res.width && h == cmdline.res.height &&
179+
(cmdline.res.format < 0 || cmdline.res.format == pf) &&
180+
(!cmdline.res.depth || cmdline.res.depth == pixel_bpp(pf, pi)))
146181
return cur_mode;
147182

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

159194
pf = info->pixel_format;
195+
pi = info->pixel_information;
160196
w = info->horizontal_resolution;
161197
h = info->vertical_resolution;
162198

163199
efi_bs_call(free_pool, info);
164200

165201
if (pf == PIXEL_BLT_ONLY || pf >= PIXEL_FORMAT_MAX)
166202
continue;
167-
if (w == cmdline.res.width && h == cmdline.res.height)
203+
if (w == cmdline.res.width && h == cmdline.res.height &&
204+
(cmdline.res.format < 0 || cmdline.res.format == pf) &&
205+
(!cmdline.res.depth || cmdline.res.depth == pixel_bpp(pf, pi)))
168206
return m;
169207
}
170208

0 commit comments

Comments
 (0)