"Das U-Boot" Source Tree
at master 312 lines 9.2 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 <charset.h> 10#include <dm.h> 11#include <video.h> 12#include <video_console.h> 13#include <video_font.h> /* Get font data, width and height */ 14#include "vidconsole_internal.h" 15 16static int console_set_row_1(struct udevice *dev, uint row, int clr) 17{ 18 struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent); 19 struct console_simple_priv *priv = dev_get_priv(dev); 20 struct video_fontdata *fontdata = priv->fontdata; 21 int pbytes = VNBYTES(vid_priv->bpix); 22 void *start, *dst, *line; 23 int i, j; 24 int ret; 25 26 start = vid_priv->fb + vid_priv->line_length - 27 (row + 1) * fontdata->height * pbytes; 28 line = start; 29 for (j = 0; j < vid_priv->ysize; j++) { 30 dst = line; 31 for (i = 0; i < fontdata->height; i++) 32 fill_pixel_and_goto_next(&dst, clr, pbytes, pbytes); 33 line += vid_priv->line_length; 34 } 35 ret = vidconsole_sync_copy(dev, start, line); 36 if (ret) 37 return ret; 38 39 return 0; 40} 41 42static int console_move_rows_1(struct udevice *dev, uint rowdst, uint rowsrc, 43 uint count) 44{ 45 struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent); 46 struct console_simple_priv *priv = dev_get_priv(dev); 47 struct video_fontdata *fontdata = priv->fontdata; 48 int pbytes = VNBYTES(vid_priv->bpix); 49 void *dst; 50 void *src; 51 int j, ret; 52 53 dst = vid_priv->fb + vid_priv->line_length - 54 (rowdst + count) * fontdata->height * pbytes; 55 src = vid_priv->fb + vid_priv->line_length - 56 (rowsrc + count) * fontdata->height * pbytes; 57 58 for (j = 0; j < vid_priv->ysize; j++) { 59 ret = vidconsole_memmove(dev, dst, src, 60 fontdata->height * pbytes * count); 61 if (ret) 62 return ret; 63 src += vid_priv->line_length; 64 dst += vid_priv->line_length; 65 } 66 67 return 0; 68} 69 70static int console_putc_xy_1(struct udevice *dev, uint x_frac, uint y, int cp) 71{ 72 struct vidconsole_priv *vc_priv = dev_get_uclass_priv(dev); 73 struct udevice *vid = dev->parent; 74 struct video_priv *vid_priv = dev_get_uclass_priv(vid); 75 struct console_simple_priv *priv = dev_get_priv(dev); 76 struct video_fontdata *fontdata = priv->fontdata; 77 int pbytes = VNBYTES(vid_priv->bpix); 78 int x, linenum, ret; 79 void *start, *line; 80 u8 ch = console_utf_to_cp437(cp); 81 uchar *pfont = fontdata->video_fontdata + 82 ch * fontdata->char_pixel_bytes; 83 84 if (x_frac + VID_TO_POS(vc_priv->x_charsize) > vc_priv->xsize_frac) 85 return -EAGAIN; 86 linenum = VID_TO_PIXEL(x_frac) + 1; 87 x = y + 1; 88 start = vid_priv->fb + linenum * vid_priv->line_length - x * pbytes; 89 line = start; 90 91 ret = fill_char_horizontally(pfont, &line, vid_priv, fontdata, FLIPPED_DIRECTION); 92 if (ret) 93 return ret; 94 95 /* We draw backwards from 'start, so account for the first line */ 96 ret = vidconsole_sync_copy(dev, start - vid_priv->line_length, line); 97 if (ret) 98 return ret; 99 100 return VID_TO_POS(fontdata->width); 101} 102 103static int console_set_row_2(struct udevice *dev, uint row, int clr) 104{ 105 struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent); 106 struct console_simple_priv *priv = dev_get_priv(dev); 107 struct video_fontdata *fontdata = priv->fontdata; 108 void *start, *line, *dst, *end; 109 int pixels = fontdata->height * vid_priv->xsize; 110 int i, ret; 111 int pbytes = VNBYTES(vid_priv->bpix); 112 113 start = vid_priv->fb + vid_priv->ysize * vid_priv->line_length - 114 (row + 1) * fontdata->height * vid_priv->line_length; 115 line = start; 116 dst = line; 117 for (i = 0; i < pixels; i++) 118 fill_pixel_and_goto_next(&dst, clr, pbytes, pbytes); 119 end = dst; 120 ret = vidconsole_sync_copy(dev, start, end); 121 if (ret) 122 return ret; 123 124 return 0; 125} 126 127static int console_move_rows_2(struct udevice *dev, uint rowdst, uint rowsrc, 128 uint count) 129{ 130 struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent); 131 struct console_simple_priv *priv = dev_get_priv(dev); 132 struct video_fontdata *fontdata = priv->fontdata; 133 void *dst; 134 void *src; 135 void *end; 136 137 end = vid_priv->fb + vid_priv->ysize * vid_priv->line_length; 138 dst = end - (rowdst + count) * fontdata->height * 139 vid_priv->line_length; 140 src = end - (rowsrc + count) * fontdata->height * 141 vid_priv->line_length; 142 vidconsole_memmove(dev, dst, src, 143 fontdata->height * vid_priv->line_length * count); 144 145 return 0; 146} 147 148static int console_putc_xy_2(struct udevice *dev, uint x_frac, uint y, int cp) 149{ 150 struct vidconsole_priv *vc_priv = dev_get_uclass_priv(dev); 151 struct udevice *vid = dev->parent; 152 struct video_priv *vid_priv = dev_get_uclass_priv(vid); 153 struct console_simple_priv *priv = dev_get_priv(dev); 154 struct video_fontdata *fontdata = priv->fontdata; 155 int pbytes = VNBYTES(vid_priv->bpix); 156 int linenum, x, ret; 157 void *start, *line; 158 u8 ch = console_utf_to_cp437(cp); 159 uchar *pfont = fontdata->video_fontdata + 160 ch * fontdata->char_pixel_bytes; 161 162 if (x_frac + VID_TO_POS(vc_priv->x_charsize) > vc_priv->xsize_frac) 163 return -EAGAIN; 164 linenum = vid_priv->ysize - y - 1; 165 x = vid_priv->xsize - VID_TO_PIXEL(x_frac) - 1; 166 start = vid_priv->fb + linenum * vid_priv->line_length + x * pbytes; 167 line = start; 168 169 ret = fill_char_vertically(pfont, &line, vid_priv, fontdata, FLIPPED_DIRECTION); 170 if (ret) 171 return ret; 172 173 /* Add 4 bytes to allow for the first pixel writen */ 174 ret = vidconsole_sync_copy(dev, start + 4, line); 175 if (ret) 176 return ret; 177 178 return VID_TO_POS(fontdata->width); 179} 180 181static int console_set_row_3(struct udevice *dev, uint row, int clr) 182{ 183 struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent); 184 struct console_simple_priv *priv = dev_get_priv(dev); 185 struct video_fontdata *fontdata = priv->fontdata; 186 int pbytes = VNBYTES(vid_priv->bpix); 187 void *start, *dst, *line; 188 int i, j, ret; 189 190 start = vid_priv->fb + row * fontdata->height * pbytes; 191 line = start; 192 for (j = 0; j < vid_priv->ysize; j++) { 193 dst = line; 194 for (i = 0; i < fontdata->height; i++) 195 fill_pixel_and_goto_next(&dst, clr, pbytes, pbytes); 196 line += vid_priv->line_length; 197 } 198 ret = vidconsole_sync_copy(dev, start, line); 199 if (ret) 200 return ret; 201 202 return 0; 203} 204 205static int console_move_rows_3(struct udevice *dev, uint rowdst, uint rowsrc, 206 uint count) 207{ 208 struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent); 209 struct console_simple_priv *priv = dev_get_priv(dev); 210 struct video_fontdata *fontdata = priv->fontdata; 211 int pbytes = VNBYTES(vid_priv->bpix); 212 void *dst; 213 void *src; 214 int j, ret; 215 216 dst = vid_priv->fb + rowdst * fontdata->height * pbytes; 217 src = vid_priv->fb + rowsrc * fontdata->height * pbytes; 218 219 for (j = 0; j < vid_priv->ysize; j++) { 220 ret = vidconsole_memmove(dev, dst, src, 221 fontdata->height * pbytes * count); 222 if (ret) 223 return ret; 224 src += vid_priv->line_length; 225 dst += vid_priv->line_length; 226 } 227 228 return 0; 229} 230 231static int console_putc_xy_3(struct udevice *dev, uint x_frac, uint y, int cp) 232{ 233 struct vidconsole_priv *vc_priv = dev_get_uclass_priv(dev); 234 struct udevice *vid = dev->parent; 235 struct video_priv *vid_priv = dev_get_uclass_priv(vid); 236 struct console_simple_priv *priv = dev_get_priv(dev); 237 struct video_fontdata *fontdata = priv->fontdata; 238 int pbytes = VNBYTES(vid_priv->bpix); 239 int linenum, x, ret; 240 void *start, *line; 241 u8 ch = console_utf_to_cp437(cp); 242 uchar *pfont = fontdata->video_fontdata + 243 ch * fontdata->char_pixel_bytes; 244 245 if (x_frac + VID_TO_POS(vc_priv->x_charsize) > vc_priv->xsize_frac) 246 return -EAGAIN; 247 x = y; 248 linenum = vid_priv->ysize - VID_TO_PIXEL(x_frac) - 1; 249 start = vid_priv->fb + linenum * vid_priv->line_length + y * pbytes; 250 line = start; 251 252 ret = fill_char_horizontally(pfont, &line, vid_priv, fontdata, NORMAL_DIRECTION); 253 if (ret) 254 return ret; 255 /* Add a line to allow for the first pixels writen */ 256 ret = vidconsole_sync_copy(dev, start + vid_priv->line_length, line); 257 if (ret) 258 return ret; 259 260 return VID_TO_POS(fontdata->width); 261} 262 263struct vidconsole_ops console_ops_1 = { 264 .putc_xy = console_putc_xy_1, 265 .move_rows = console_move_rows_1, 266 .set_row = console_set_row_1, 267 .get_font_size = console_simple_get_font_size, 268 .get_font = console_simple_get_font, 269 .select_font = console_simple_select_font, 270}; 271 272struct vidconsole_ops console_ops_2 = { 273 .putc_xy = console_putc_xy_2, 274 .move_rows = console_move_rows_2, 275 .set_row = console_set_row_2, 276 .get_font_size = console_simple_get_font_size, 277 .get_font = console_simple_get_font, 278 .select_font = console_simple_select_font, 279}; 280 281struct vidconsole_ops console_ops_3 = { 282 .putc_xy = console_putc_xy_3, 283 .move_rows = console_move_rows_3, 284 .set_row = console_set_row_3, 285 .get_font_size = console_simple_get_font_size, 286 .get_font = console_simple_get_font, 287 .select_font = console_simple_select_font, 288}; 289 290U_BOOT_DRIVER(vidconsole_1) = { 291 .name = "vidconsole1", 292 .id = UCLASS_VIDEO_CONSOLE, 293 .ops = &console_ops_1, 294 .probe = console_probe, 295 .priv_auto = sizeof(struct console_simple_priv), 296}; 297 298U_BOOT_DRIVER(vidconsole_2) = { 299 .name = "vidconsole2", 300 .id = UCLASS_VIDEO_CONSOLE, 301 .ops = &console_ops_2, 302 .probe = console_probe, 303 .priv_auto = sizeof(struct console_simple_priv), 304}; 305 306U_BOOT_DRIVER(vidconsole_3) = { 307 .name = "vidconsole3", 308 .id = UCLASS_VIDEO_CONSOLE, 309 .ops = &console_ops_3, 310 .probe = console_probe, 311 .priv_auto = sizeof(struct console_simple_priv), 312};