1 // SPDX-License-Identifier: GPL-2.0+
3 * Copyright (c) 2015 Google, Inc
5 * Bernecker & Rainer Industrieelektronik GmbH - http://www.br-automation.com
11 #include <video_console.h>
12 #include <video_font.h> /* Get font data, width and height */
14 static int console_set_row_1(struct udevice *dev, uint row, int clr)
16 struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent);
17 int pbytes = VNBYTES(vid_priv->bpix);
21 line = vid_priv->fb + vid_priv->line_length -
22 (row + 1) * VIDEO_FONT_HEIGHT * pbytes;
23 for (j = 0; j < vid_priv->ysize; j++) {
24 switch (vid_priv->bpix) {
26 if (IS_ENABLED(CONFIG_VIDEO_BPP8)) {
29 for (i = 0; i < VIDEO_FONT_HEIGHT; i++)
34 if (IS_ENABLED(CONFIG_VIDEO_BPP16)) {
37 for (i = 0; i < VIDEO_FONT_HEIGHT; i++)
42 if (IS_ENABLED(CONFIG_VIDEO_BPP32)) {
45 for (i = 0; i < VIDEO_FONT_HEIGHT; i++)
52 line += vid_priv->line_length;
58 static int console_move_rows_1(struct udevice *dev, uint rowdst, uint rowsrc,
61 struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent);
64 int pbytes = VNBYTES(vid_priv->bpix);
67 dst = vid_priv->fb + vid_priv->line_length -
68 (rowdst + count) * VIDEO_FONT_HEIGHT * pbytes;
69 src = vid_priv->fb + vid_priv->line_length -
70 (rowsrc + count) * VIDEO_FONT_HEIGHT * pbytes;
72 for (j = 0; j < vid_priv->ysize; j++) {
73 memmove(dst, src, VIDEO_FONT_HEIGHT * pbytes * count);
74 src += vid_priv->line_length;
75 dst += vid_priv->line_length;
81 static int console_putc_xy_1(struct udevice *dev, uint x_frac, uint y, char ch)
83 struct vidconsole_priv *vc_priv = dev_get_uclass_priv(dev);
84 struct udevice *vid = dev->parent;
85 struct video_priv *vid_priv = dev_get_uclass_priv(vid);
86 int pbytes = VNBYTES(vid_priv->bpix);
90 uchar *pfont = video_fontdata + (u8)ch * VIDEO_FONT_HEIGHT;
92 line = vid_priv->fb + (VID_TO_PIXEL(x_frac) + 1) *
93 vid_priv->line_length - (y + 1) * pbytes;
94 if (x_frac + VID_TO_POS(vc_priv->x_charsize) > vc_priv->xsize_frac)
97 for (col = 0; col < VIDEO_FONT_HEIGHT; col++) {
98 switch (vid_priv->bpix) {
100 if (IS_ENABLED(CONFIG_VIDEO_BPP8)) {
103 for (i = 0; i < VIDEO_FONT_HEIGHT; i++) {
104 *dst-- = (pfont[i] & mask) ?
105 vid_priv->colour_fg :
111 if (IS_ENABLED(CONFIG_VIDEO_BPP16)) {
112 uint16_t *dst = line;
114 for (i = 0; i < VIDEO_FONT_HEIGHT; i++) {
115 *dst-- = (pfont[i] & mask) ?
116 vid_priv->colour_fg :
122 if (IS_ENABLED(CONFIG_VIDEO_BPP32)) {
123 uint32_t *dst = line;
125 for (i = 0; i < VIDEO_FONT_HEIGHT; i++) {
126 *dst-- = (pfont[i] & mask) ?
127 vid_priv->colour_fg :
135 line += vid_priv->line_length;
139 return VID_TO_POS(VIDEO_FONT_WIDTH);
143 static int console_set_row_2(struct udevice *dev, uint row, int clr)
145 struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent);
147 int pixels = VIDEO_FONT_HEIGHT * vid_priv->xsize;
150 line = vid_priv->fb + vid_priv->ysize * vid_priv->line_length -
151 (row + 1) * VIDEO_FONT_HEIGHT * vid_priv->line_length;
152 switch (vid_priv->bpix) {
154 if (IS_ENABLED(CONFIG_VIDEO_BPP8)) {
157 for (i = 0; i < pixels; i++)
162 if (IS_ENABLED(CONFIG_VIDEO_BPP16)) {
163 uint16_t *dst = line;
165 for (i = 0; i < pixels; i++)
170 if (IS_ENABLED(CONFIG_VIDEO_BPP32)) {
171 uint32_t *dst = line;
173 for (i = 0; i < pixels; i++)
184 static int console_move_rows_2(struct udevice *dev, uint rowdst, uint rowsrc,
187 struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent);
192 end = vid_priv->fb + vid_priv->ysize * vid_priv->line_length;
193 dst = end - (rowdst + count) * VIDEO_FONT_HEIGHT *
194 vid_priv->line_length;
195 src = end - (rowsrc + count) * VIDEO_FONT_HEIGHT *
196 vid_priv->line_length;
197 memmove(dst, src, VIDEO_FONT_HEIGHT * vid_priv->line_length * count);
202 static int console_putc_xy_2(struct udevice *dev, uint x_frac, uint y, char ch)
204 struct vidconsole_priv *vc_priv = dev_get_uclass_priv(dev);
205 struct udevice *vid = dev->parent;
206 struct video_priv *vid_priv = dev_get_uclass_priv(vid);
210 if (x_frac + VID_TO_POS(vc_priv->x_charsize) > vc_priv->xsize_frac)
213 line = vid_priv->fb + (vid_priv->ysize - y - 1) *
214 vid_priv->line_length +
215 (vid_priv->xsize - VID_TO_PIXEL(x_frac) -
216 VIDEO_FONT_WIDTH - 1) * VNBYTES(vid_priv->bpix);
218 for (row = 0; row < VIDEO_FONT_HEIGHT; row++) {
219 unsigned int idx = (u8)ch * VIDEO_FONT_HEIGHT + row;
220 uchar bits = video_fontdata[idx];
222 switch (vid_priv->bpix) {
224 if (IS_ENABLED(CONFIG_VIDEO_BPP8)) {
227 for (i = 0; i < VIDEO_FONT_WIDTH; i++) {
228 *dst-- = (bits & 0x80) ?
229 vid_priv->colour_fg :
236 if (IS_ENABLED(CONFIG_VIDEO_BPP16)) {
237 uint16_t *dst = line;
239 for (i = 0; i < VIDEO_FONT_WIDTH; i++) {
240 *dst-- = (bits & 0x80) ?
241 vid_priv->colour_fg :
248 if (IS_ENABLED(CONFIG_VIDEO_BPP32)) {
249 uint32_t *dst = line;
251 for (i = 0; i < VIDEO_FONT_WIDTH; i++) {
252 *dst-- = (bits & 0x80) ?
253 vid_priv->colour_fg :
262 line -= vid_priv->line_length;
265 return VID_TO_POS(VIDEO_FONT_WIDTH);
268 static int console_set_row_3(struct udevice *dev, uint row, int clr)
270 struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent);
271 int pbytes = VNBYTES(vid_priv->bpix);
275 line = vid_priv->fb + row * VIDEO_FONT_HEIGHT * pbytes;
276 for (j = 0; j < vid_priv->ysize; j++) {
277 switch (vid_priv->bpix) {
279 if (IS_ENABLED(CONFIG_VIDEO_BPP8)) {
282 for (i = 0; i < VIDEO_FONT_HEIGHT; i++)
287 if (IS_ENABLED(CONFIG_VIDEO_BPP16)) {
288 uint16_t *dst = line;
290 for (i = 0; i < VIDEO_FONT_HEIGHT; i++)
295 if (IS_ENABLED(CONFIG_VIDEO_BPP32)) {
296 uint32_t *dst = line;
298 for (i = 0; i < VIDEO_FONT_HEIGHT; i++)
305 line += vid_priv->line_length;
311 static int console_move_rows_3(struct udevice *dev, uint rowdst, uint rowsrc,
314 struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent);
317 int pbytes = VNBYTES(vid_priv->bpix);
320 dst = vid_priv->fb + rowdst * VIDEO_FONT_HEIGHT * pbytes;
321 src = vid_priv->fb + rowsrc * VIDEO_FONT_HEIGHT * pbytes;
323 for (j = 0; j < vid_priv->ysize; j++) {
324 memmove(dst, src, VIDEO_FONT_HEIGHT * pbytes * count);
325 src += vid_priv->line_length;
326 dst += vid_priv->line_length;
332 static int console_putc_xy_3(struct udevice *dev, uint x_frac, uint y, char ch)
334 struct vidconsole_priv *vc_priv = dev_get_uclass_priv(dev);
335 struct udevice *vid = dev->parent;
336 struct video_priv *vid_priv = dev_get_uclass_priv(vid);
337 int pbytes = VNBYTES(vid_priv->bpix);
340 void *line = vid_priv->fb +
341 (vid_priv->ysize - VID_TO_PIXEL(x_frac) - 1) *
342 vid_priv->line_length + y * pbytes;
343 uchar *pfont = video_fontdata + (u8)ch * VIDEO_FONT_HEIGHT;
345 if (x_frac + VID_TO_POS(vc_priv->x_charsize) > vc_priv->xsize_frac)
348 for (col = 0; col < VIDEO_FONT_HEIGHT; col++) {
349 switch (vid_priv->bpix) {
351 if (IS_ENABLED(CONFIG_VIDEO_BPP8)) {
354 for (i = 0; i < VIDEO_FONT_HEIGHT; i++) {
355 *dst++ = (pfont[i] & mask) ?
356 vid_priv->colour_fg :
362 if (IS_ENABLED(CONFIG_VIDEO_BPP16)) {
363 uint16_t *dst = line;
365 for (i = 0; i < VIDEO_FONT_HEIGHT; i++) {
366 *dst++ = (pfont[i] & mask) ?
367 vid_priv->colour_fg :
373 if (IS_ENABLED(CONFIG_VIDEO_BPP32)) {
374 uint32_t *dst = line;
376 for (i = 0; i < VIDEO_FONT_HEIGHT; i++) {
377 *dst++ = (pfont[i] & mask) ?
378 vid_priv->colour_fg :
386 line -= vid_priv->line_length;
390 return VID_TO_POS(VIDEO_FONT_WIDTH);
394 static int console_probe_2(struct udevice *dev)
396 struct vidconsole_priv *vc_priv = dev_get_uclass_priv(dev);
397 struct udevice *vid_dev = dev->parent;
398 struct video_priv *vid_priv = dev_get_uclass_priv(vid_dev);
400 vc_priv->x_charsize = VIDEO_FONT_WIDTH;
401 vc_priv->y_charsize = VIDEO_FONT_HEIGHT;
402 vc_priv->cols = vid_priv->xsize / VIDEO_FONT_WIDTH;
403 vc_priv->rows = vid_priv->ysize / VIDEO_FONT_HEIGHT;
408 static int console_probe_1_3(struct udevice *dev)
410 struct vidconsole_priv *vc_priv = dev_get_uclass_priv(dev);
411 struct udevice *vid_dev = dev->parent;
412 struct video_priv *vid_priv = dev_get_uclass_priv(vid_dev);
414 vc_priv->x_charsize = VIDEO_FONT_WIDTH;
415 vc_priv->y_charsize = VIDEO_FONT_HEIGHT;
416 vc_priv->cols = vid_priv->ysize / VIDEO_FONT_WIDTH;
417 vc_priv->rows = vid_priv->xsize / VIDEO_FONT_HEIGHT;
418 vc_priv->xsize_frac = VID_TO_POS(vid_priv->ysize);
423 struct vidconsole_ops console_ops_1 = {
424 .putc_xy = console_putc_xy_1,
425 .move_rows = console_move_rows_1,
426 .set_row = console_set_row_1,
429 struct vidconsole_ops console_ops_2 = {
430 .putc_xy = console_putc_xy_2,
431 .move_rows = console_move_rows_2,
432 .set_row = console_set_row_2,
435 struct vidconsole_ops console_ops_3 = {
436 .putc_xy = console_putc_xy_3,
437 .move_rows = console_move_rows_3,
438 .set_row = console_set_row_3,
441 U_BOOT_DRIVER(vidconsole_1) = {
442 .name = "vidconsole1",
443 .id = UCLASS_VIDEO_CONSOLE,
444 .ops = &console_ops_1,
445 .probe = console_probe_1_3,
448 U_BOOT_DRIVER(vidconsole_2) = {
449 .name = "vidconsole2",
450 .id = UCLASS_VIDEO_CONSOLE,
451 .ops = &console_ops_2,
452 .probe = console_probe_2,
455 U_BOOT_DRIVER(vidconsole_3) = {
456 .name = "vidconsole3",
457 .id = UCLASS_VIDEO_CONSOLE,
458 .ops = &console_ops_3,
459 .probe = console_probe_1_3,