fbcon: Increase maximum font width x height to 64 x 128

By using bitmaps we actually support whatever size we would want, but
the console currently limits fonts to 64x128 (which gives 60x16 text on
4k screens), so we don't need more for now, and we can easily increase
later.

Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
Signed-off-by: Helge Deller <deller@gmx.de>
This commit is contained in:
Samuel Thibault 2024-03-16 01:10:21 +01:00 committed by Helge Deller
parent bc87bb342f
commit 152609795d
12 changed files with 89 additions and 45 deletions

View File

@ -252,7 +252,7 @@ static int __init efi_earlycon_setup(struct earlycon_device *device,
if (si->lfb_depth != 32)
return -ENODEV;
font = get_default_font(xres, yres, -1, -1);
font = get_default_font(xres, yres, NULL, NULL);
if (!font)
return -ENODEV;

View File

@ -622,8 +622,13 @@ static int arkfb_set_par(struct fb_info *info)
info->tileops = NULL;
/* in 4bpp supports 8p wide tiles only, any tiles otherwise */
info->pixmap.blit_x = (bpp == 4) ? (1 << (8 - 1)) : (~(u32)0);
info->pixmap.blit_y = ~(u32)0;
if (bpp == 4) {
bitmap_zero(info->pixmap.blit_x, FB_MAX_BLIT_WIDTH);
set_bit(8 - 1, info->pixmap.blit_x);
} else {
bitmap_fill(info->pixmap.blit_x, FB_MAX_BLIT_WIDTH);
}
bitmap_fill(info->pixmap.blit_y, FB_MAX_BLIT_HEIGHT);
offset_value = (info->var.xres_virtual * bpp) / 64;
screen_size = info->var.yres_virtual * info->fix.line_length;
@ -635,8 +640,10 @@ static int arkfb_set_par(struct fb_info *info)
info->tileops = &arkfb_tile_ops;
/* supports 8x16 tiles only */
info->pixmap.blit_x = 1 << (8 - 1);
info->pixmap.blit_y = 1 << (16 - 1);
bitmap_zero(info->pixmap.blit_x, FB_MAX_BLIT_WIDTH);
set_bit(8 - 1, info->pixmap.blit_x);
bitmap_zero(info->pixmap.blit_y, FB_MAX_BLIT_HEIGHT);
set_bit(16 - 1, info->pixmap.blit_y);
offset_value = info->var.xres_virtual / 16;
screen_size = (info->var.xres_virtual * info->var.yres_virtual) / 64;

View File

@ -2485,12 +2485,12 @@ static int fbcon_set_font(struct vc_data *vc, struct console_font *font,
h > FBCON_SWAP(info->var.rotate, info->var.yres, info->var.xres))
return -EINVAL;
if (font->width > 32 || font->height > 32)
if (font->width > FB_MAX_BLIT_WIDTH || font->height > FB_MAX_BLIT_HEIGHT)
return -EINVAL;
/* Make sure drawing engine can handle the font */
if (!(info->pixmap.blit_x & BIT(font->width - 1)) ||
!(info->pixmap.blit_y & BIT(font->height - 1)))
if (!test_bit(font->width - 1, info->pixmap.blit_x) ||
!test_bit(font->height - 1, info->pixmap.blit_y))
return -EINVAL;
/* Make sure driver can handle the font length */
@ -3084,8 +3084,8 @@ void fbcon_get_requirement(struct fb_info *info,
vc = vc_cons[i].d;
if (vc && vc->vc_mode == KD_TEXT &&
info->node == con2fb_map[i]) {
caps->x |= 1 << (vc->vc_font.width - 1);
caps->y |= 1 << (vc->vc_font.height - 1);
set_bit(vc->vc_font.width - 1, caps->x);
set_bit(vc->vc_font.height - 1, caps->y);
charcnt = vc->vc_font.charcount;
if (caps->len < charcnt)
caps->len = charcnt;
@ -3096,8 +3096,10 @@ void fbcon_get_requirement(struct fb_info *info,
if (vc && vc->vc_mode == KD_TEXT &&
info->node == con2fb_map[fg_console]) {
caps->x = 1 << (vc->vc_font.width - 1);
caps->y = 1 << (vc->vc_font.height - 1);
bitmap_zero(caps->x, FB_MAX_BLIT_WIDTH);
set_bit(vc->vc_font.width - 1, caps->x);
bitmap_zero(caps->y, FB_MAX_BLIT_HEIGHT);
set_bit(vc->vc_font.height - 1, caps->y);
caps->len = vc->vc_font.charcount;
}
}

View File

@ -212,8 +212,8 @@ static int fb_check_caps(struct fb_info *info, struct fb_var_screeninfo *var,
fbcon_get_requirement(info, &caps);
info->fbops->fb_get_caps(info, &fbcaps, var);
if (((fbcaps.x ^ caps.x) & caps.x) ||
((fbcaps.y ^ caps.y) & caps.y) ||
if (!bitmap_subset(caps.x, fbcaps.x, FB_MAX_BLIT_WIDTH) ||
!bitmap_subset(caps.y, fbcaps.y, FB_MAX_BLIT_HEIGHT) ||
(fbcaps.len < caps.len))
err = -EINVAL;
@ -420,11 +420,11 @@ static int do_register_framebuffer(struct fb_info *fb_info)
}
fb_info->pixmap.offset = 0;
if (!fb_info->pixmap.blit_x)
fb_info->pixmap.blit_x = ~(u32)0;
if (bitmap_empty(fb_info->pixmap.blit_x, FB_MAX_BLIT_WIDTH))
bitmap_fill(fb_info->pixmap.blit_x, FB_MAX_BLIT_WIDTH);
if (!fb_info->pixmap.blit_y)
fb_info->pixmap.blit_y = ~(u32)0;
if (bitmap_empty(fb_info->pixmap.blit_y, FB_MAX_BLIT_HEIGHT))
bitmap_fill(fb_info->pixmap.blit_y, FB_MAX_BLIT_HEIGHT);
if (!fb_info->modelist.prev || !fb_info->modelist.next)
INIT_LIST_HEAD(&fb_info->modelist);

View File

@ -354,12 +354,19 @@ void svga_get_caps(struct fb_info *info, struct fb_blit_caps *caps,
{
if (var->bits_per_pixel == 0) {
/* can only support 256 8x16 bitmap */
caps->x = 1 << (8 - 1);
caps->y = 1 << (16 - 1);
bitmap_zero(caps->x, FB_MAX_BLIT_WIDTH);
set_bit(8 - 1, caps->x);
bitmap_zero(caps->y, FB_MAX_BLIT_HEIGHT);
set_bit(16 - 1, caps->y);
caps->len = 256;
} else {
caps->x = (var->bits_per_pixel == 4) ? 1 << (8 - 1) : ~(u32)0;
caps->y = ~(u32)0;
if (var->bits_per_pixel == 4) {
bitmap_zero(caps->x, FB_MAX_BLIT_WIDTH);
set_bit(8 - 1, caps->x);
} else {
bitmap_fill(caps->x, FB_MAX_BLIT_WIDTH);
}
bitmap_fill(caps->y, FB_MAX_BLIT_HEIGHT);
caps->len = ~(u32)0;
}
}

View File

@ -617,8 +617,13 @@ static int s3fb_set_par(struct fb_info *info)
info->tileops = NULL;
/* in 4bpp supports 8p wide tiles only, any tiles otherwise */
info->pixmap.blit_x = (bpp == 4) ? (1 << (8 - 1)) : (~(u32)0);
info->pixmap.blit_y = ~(u32)0;
if (bpp == 4) {
bitmap_zero(info->pixmap.blit_x, FB_MAX_BLIT_WIDTH);
set_bit(8 - 1, info->pixmap.blit_x);
} else {
bitmap_fill(info->pixmap.blit_x, FB_MAX_BLIT_WIDTH);
}
bitmap_fill(info->pixmap.blit_y, FB_MAX_BLIT_HEIGHT);
offset_value = (info->var.xres_virtual * bpp) / 64;
screen_size = info->var.yres_virtual * info->fix.line_length;
@ -630,8 +635,10 @@ static int s3fb_set_par(struct fb_info *info)
info->tileops = fasttext ? &s3fb_fast_tile_ops : &s3fb_tile_ops;
/* supports 8x16 tiles only */
info->pixmap.blit_x = 1 << (8 - 1);
info->pixmap.blit_y = 1 << (16 - 1);
bitmap_zero(info->pixmap.blit_x, FB_MAX_BLIT_WIDTH);
set_bit(8 - 1, info->pixmap.blit_x);
bitmap_zero(info->pixmap.blit_y, FB_MAX_BLIT_HEIGHT);
set_bit(16 - 1, info->pixmap.blit_y);
offset_value = info->var.xres_virtual / 16;
screen_size = (info->var.xres_virtual * info->var.yres_virtual) / 64;

View File

@ -1353,7 +1353,11 @@ static int vga16fb_probe(struct platform_device *dev)
info->var = vga16fb_defined;
info->fix = vga16fb_fix;
/* supports rectangles with widths of multiples of 8 */
info->pixmap.blit_x = 1 << 7 | 1 << 15 | 1 << 23 | 1 << 31;
bitmap_zero(info->pixmap.blit_x, FB_MAX_BLIT_WIDTH);
set_bit(8 - 1, info->pixmap.blit_x);
set_bit(16 - 1, info->pixmap.blit_x);
set_bit(24 - 1, info->pixmap.blit_x);
set_bit(32 - 1, info->pixmap.blit_x);
info->flags = FBINFO_HWACCEL_YPAN;
i = (info->var.bits_per_pixel == 8) ? 256 : 16;

View File

@ -390,8 +390,13 @@ static int vt8623fb_set_par(struct fb_info *info)
info->tileops = NULL;
/* in 4bpp supports 8p wide tiles only, any tiles otherwise */
info->pixmap.blit_x = (bpp == 4) ? (1 << (8 - 1)) : (~(u32)0);
info->pixmap.blit_y = ~(u32)0;
if (bpp == 4) {
bitmap_zero(info->pixmap.blit_x, FB_MAX_BLIT_WIDTH);
set_bit(8 - 1, info->pixmap.blit_x);
} else {
bitmap_fill(info->pixmap.blit_x, FB_MAX_BLIT_WIDTH);
}
bitmap_fill(info->pixmap.blit_y, FB_MAX_BLIT_HEIGHT);
offset_value = (info->var.xres_virtual * bpp) / 64;
fetch_value = ((info->var.xres * bpp) / 128) + 4;
@ -408,8 +413,10 @@ static int vt8623fb_set_par(struct fb_info *info)
info->tileops = &vt8623fb_tile_ops;
/* supports 8x16 tiles only */
info->pixmap.blit_x = 1 << (8 - 1);
info->pixmap.blit_y = 1 << (16 - 1);
bitmap_zero(info->pixmap.blit_x, FB_MAX_BLIT_WIDTH);
set_bit(8 - 1, info->pixmap.blit_x);
bitmap_zero(info->pixmap.blit_y, FB_MAX_BLIT_HEIGHT);
set_bit(16 - 1, info->pixmap.blit_y);
offset_value = info->var.xres_virtual / 16;
fetch_value = (info->var.xres / 8) + 8;

View File

@ -529,7 +529,7 @@ sti_select_fbfont(struct sti_cooked_rom *cooked_rom, const char *fbfont_name)
if (fbfont_name && strlen(fbfont_name))
fbfont = find_font(fbfont_name);
if (!fbfont)
fbfont = get_default_font(1024,768, ~(u32)0, ~(u32)0);
fbfont = get_default_font(1024, 768, NULL, NULL);
if (!fbfont)
return NULL;

View File

@ -143,9 +143,13 @@ struct fb_event {
void *data;
};
/* Enough for the VT console needs, see its max_font_width/height */
#define FB_MAX_BLIT_WIDTH 64
#define FB_MAX_BLIT_HEIGHT 128
struct fb_blit_caps {
u32 x;
u32 y;
DECLARE_BITMAP(x, FB_MAX_BLIT_WIDTH);
DECLARE_BITMAP(y, FB_MAX_BLIT_HEIGHT);
u32 len;
u32 flags;
};
@ -192,10 +196,12 @@ struct fb_pixmap {
u32 scan_align; /* alignment per scanline */
u32 access_align; /* alignment per read/write (bits) */
u32 flags; /* see FB_PIXMAP_* */
u32 blit_x; /* supported bit block dimensions (1-32)*/
u32 blit_y; /* Format: blit_x = 1 << (width - 1) */
/* blit_y = 1 << (height - 1) */
/* if 0, will be set to 0xffffffff (all)*/
/* supported bit block dimensions */
/* Format: test_bit(width - 1, blit_x) */
/* test_bit(height - 1, blit_y) */
/* if zero, will be set to full (all) */
DECLARE_BITMAP(blit_x, FB_MAX_BLIT_WIDTH);
DECLARE_BITMAP(blit_y, FB_MAX_BLIT_HEIGHT);
/* access methods */
void (*writeio)(struct fb_info *info, void __iomem *dst, void *src, unsigned int size);
void (*readio) (struct fb_info *info, void *dst, void __iomem *src, unsigned int size);

View File

@ -57,7 +57,8 @@ extern const struct font_desc *find_font(const char *name);
/* Get the default font for a specific screen size */
extern const struct font_desc *get_default_font(int xres, int yres,
u32 font_w, u32 font_h);
unsigned long *font_w,
unsigned long *font_h);
/* Max. length for the name of a predefined font */
#define MAX_FONT_NAME 32

View File

@ -96,18 +96,21 @@ EXPORT_SYMBOL(find_font);
* get_default_font - get default font
* @xres: screen size of X
* @yres: screen size of Y
* @font_w: bit array of supported widths (1 - 32)
* @font_h: bit array of supported heights (1 - 32)
* @font_w: bit array of supported widths (1 - FB_MAX_BLIT_WIDTH)
* @font_h: bit array of supported heights (1 - FB_MAX_BLIT_HEIGHT)
*
* Get the default font for a specified screen size.
* Dimensions are in pixels.
*
* font_w or font_h being NULL means all values are supported.
*
* Returns %NULL if no font is found, or a pointer to the
* chosen font.
*
*/
const struct font_desc *get_default_font(int xres, int yres, u32 font_w,
u32 font_h)
const struct font_desc *get_default_font(int xres, int yres,
unsigned long *font_w,
unsigned long *font_h)
{
int i, c, cc, res;
const struct font_desc *f, *g;
@ -135,8 +138,8 @@ const struct font_desc *get_default_font(int xres, int yres, u32 font_w,
if (res > 20)
c += 20 - res;
if ((font_w & (1U << (f->width - 1))) &&
(font_h & (1U << (f->height - 1))))
if ((!font_w || test_bit(f->width - 1, font_w)) &&
(!font_h || test_bit(f->height - 1, font_h)))
c += 1000;
if (c > cc) {