"Das U-Boot" Source Tree
at master 249 lines 5.8 kB view raw
1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * Copyright (c) 2015 Google, Inc 4 * (C) Copyright 2015 5 * Bernecker & Rainer Industrieelektronik GmbH - http://www.br-automation.com 6 * (C) Copyright 2023 Dzmitry Sankouski <dsankouski@gmail.com> 7 */ 8 9#include <video.h> 10#include <video_console.h> 11#include <dm.h> 12#include <video_font.h> 13#include "vidconsole_internal.h" 14 15/** 16 * console_set_font() - prepare vidconsole for chosen font. 17 * 18 * @dev vidconsole device 19 * @fontdata pointer to font data struct 20 */ 21static int console_set_font(struct udevice *dev, struct video_fontdata *fontdata) 22{ 23 struct console_simple_priv *priv = dev_get_priv(dev); 24 struct vidconsole_priv *vc_priv = dev_get_uclass_priv(dev); 25 struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent); 26 27 debug("console_simple: setting %s font\n", fontdata->name); 28 debug("width: %d\n", fontdata->width); 29 debug("byte width: %d\n", fontdata->byte_width); 30 debug("height: %d\n", fontdata->height); 31 32 priv->fontdata = fontdata; 33 vc_priv->x_charsize = fontdata->width; 34 vc_priv->y_charsize = fontdata->height; 35 if (vid_priv->rot % 2) { 36 vc_priv->cols = vid_priv->ysize / fontdata->width; 37 vc_priv->rows = vid_priv->xsize / fontdata->height; 38 vc_priv->xsize_frac = VID_TO_POS(vid_priv->ysize); 39 } else { 40 vc_priv->cols = vid_priv->xsize / fontdata->width; 41 vc_priv->rows = vid_priv->ysize / fontdata->height; 42 } 43 44 return 0; 45} 46 47int check_bpix_support(int bpix) 48{ 49 if (bpix == VIDEO_BPP8 && CONFIG_IS_ENABLED(VIDEO_BPP8)) 50 return 0; 51 else if (bpix == VIDEO_BPP16 && CONFIG_IS_ENABLED(VIDEO_BPP16)) 52 return 0; 53 else if (bpix == VIDEO_BPP32 && CONFIG_IS_ENABLED(VIDEO_BPP32)) 54 return 0; 55 else 56 return -ENOSYS; 57} 58 59inline void fill_pixel_and_goto_next(void **dstp, u32 value, int pbytes, int step) 60{ 61 u8 *dst_byte = *dstp; 62 63 if (pbytes == 4) { 64 u32 *dst = *dstp; 65 *dst = value; 66 } 67 if (pbytes == 2) { 68 u16 *dst = *dstp; 69 *dst = value; 70 } 71 if (pbytes == 1) { 72 u8 *dst = *dstp; 73 *dst = value; 74 } 75 *dstp = dst_byte + step; 76} 77 78int fill_char_vertically(uchar *pfont, void **line, struct video_priv *vid_priv, 79 struct video_fontdata *fontdata, bool direction) 80{ 81 int step, line_step, pbytes, bitcount, width_remainder, ret; 82 void *dst; 83 84 ret = check_bpix_support(vid_priv->bpix); 85 if (ret) 86 return ret; 87 88 pbytes = VNBYTES(vid_priv->bpix); 89 if (direction) { 90 step = -pbytes; 91 line_step = -vid_priv->line_length; 92 } else { 93 step = pbytes; 94 line_step = vid_priv->line_length; 95 } 96 97 width_remainder = fontdata->width % 8; 98 for (int row = 0; row < fontdata->height; row++) { 99 uchar bits; 100 101 bitcount = 8; 102 dst = *line; 103 for (int col = 0; col < fontdata->byte_width; col++) { 104 if (width_remainder) { 105 bool is_last_col = (fontdata->byte_width - col == 1); 106 107 if (is_last_col) 108 bitcount = width_remainder; 109 } 110 bits = pfont[col]; 111 112 for (int bit = 0; bit < bitcount; bit++) { 113 u32 value = (bits & 0x80) ? 114 vid_priv->colour_fg : 115 vid_priv->colour_bg; 116 117 fill_pixel_and_goto_next(&dst, 118 value, 119 pbytes, 120 step 121 ); 122 bits <<= 1; 123 } 124 } 125 *line += line_step; 126 pfont += fontdata->byte_width; 127 } 128 return ret; 129} 130 131int fill_char_horizontally(uchar *pfont, void **line, struct video_priv *vid_priv, 132 struct video_fontdata *fontdata, bool direction) 133{ 134 int step, line_step, pbytes, bitcount = 8, width_remainder, ret; 135 void *dst; 136 u8 mask; 137 138 ret = check_bpix_support(vid_priv->bpix); 139 if (ret) 140 return ret; 141 142 pbytes = VNBYTES(vid_priv->bpix); 143 if (direction) { 144 step = -pbytes; 145 line_step = vid_priv->line_length; 146 } else { 147 step = pbytes; 148 line_step = -vid_priv->line_length; 149 } 150 151 width_remainder = fontdata->width % 8; 152 for (int col = 0; col < fontdata->byte_width; col++) { 153 mask = 0x80; 154 if (width_remainder) { 155 bool is_last_col = (fontdata->byte_width - col == 1); 156 157 if (is_last_col) 158 bitcount = width_remainder; 159 } 160 for (int bit = 0; bit < bitcount; bit++) { 161 dst = *line; 162 for (int row = 0; row < fontdata->height; row++) { 163 u32 value = (pfont[row * fontdata->byte_width + col] 164 & mask) ? vid_priv->colour_fg : vid_priv->colour_bg; 165 166 fill_pixel_and_goto_next(&dst, 167 value, 168 pbytes, 169 step 170 ); 171 } 172 *line += line_step; 173 mask >>= 1; 174 } 175 } 176 return ret; 177} 178 179int draw_cursor_vertically(void **line, struct video_priv *vid_priv, 180 uint height, bool direction) 181{ 182 int step, line_step, pbytes, ret; 183 uint value; 184 void *dst; 185 186 ret = check_bpix_support(vid_priv->bpix); 187 if (ret) 188 return ret; 189 190 pbytes = VNBYTES(vid_priv->bpix); 191 if (direction) { 192 step = -pbytes; 193 line_step = -vid_priv->line_length; 194 } else { 195 step = pbytes; 196 line_step = vid_priv->line_length; 197 } 198 199 value = vid_priv->colour_fg; 200 201 for (int row = 0; row < height; row++) { 202 dst = *line; 203 for (int col = 0; col < VIDCONSOLE_CURSOR_WIDTH; col++) 204 fill_pixel_and_goto_next(&dst, value, pbytes, step); 205 *line += line_step; 206 } 207 return ret; 208} 209 210int console_probe(struct udevice *dev) 211{ 212 return console_set_font(dev, fonts); 213} 214 215const char *console_simple_get_font_size(struct udevice *dev, uint *sizep) 216{ 217 struct console_simple_priv *priv = dev_get_priv(dev); 218 219 *sizep = priv->fontdata->width; 220 221 return priv->fontdata->name; 222} 223 224int console_simple_get_font(struct udevice *dev, int seq, struct vidfont_info *info) 225{ 226 info->name = fonts[seq].name; 227 228 return info->name ? 0 : -ENOENT; 229} 230 231int console_simple_select_font(struct udevice *dev, const char *name, uint size) 232{ 233 struct video_fontdata *font; 234 235 if (!name) { 236 if (fonts->name) 237 console_set_font(dev, fonts); 238 return 0; 239 } 240 241 for (font = fonts; font->name; font++) { 242 if (!strcmp(name, font->name)) { 243 console_set_font(dev, font); 244 return 0; 245 } 246 }; 247 printf("no such font: %s, make sure it's name has <width>x<height> format\n", name); 248 return -ENOENT; 249}