blob: 34ef5a5229426840f0c100e2d5cb30c38ed19adc [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Simon Glass23825a92016-01-18 19:52:18 -07002/*
3 * Copyright (c) 2015 Google, Inc
Dzmitry Sankouskiaea2d2d2023-03-07 13:21:11 +03004 * (C) Copyright 2015
Simon Glass23825a92016-01-18 19:52:18 -07005 * Bernecker & Rainer Industrieelektronik GmbH - http://www.br-automation.com
Dzmitry Sankouskiaea2d2d2023-03-07 13:21:11 +03006 * (C) Copyright 2023 Dzmitry Sankouski <dsankouski@gmail.com>
Simon Glass23825a92016-01-18 19:52:18 -07007 */
8
9#include <common.h>
Janne Grunau5548c362024-03-16 22:50:19 +010010#include <charset.h>
Simon Glass23825a92016-01-18 19:52:18 -070011#include <dm.h>
12#include <video.h>
13#include <video_console.h>
14#include <video_font.h> /* Get font data, width and height */
Dzmitry Sankouskiaea2d2d2023-03-07 13:21:11 +030015#include "vidconsole_internal.h"
Simon Glass23825a92016-01-18 19:52:18 -070016
Dzmitry Sankouskiaea2d2d2023-03-07 13:21:11 +030017static int console_set_row(struct udevice *dev, uint row, int clr)
Simon Glass23825a92016-01-18 19:52:18 -070018{
19 struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent);
Dzmitry Sankouski7fa964a2023-03-07 13:21:14 +030020 struct console_simple_priv *priv = dev_get_priv(dev);
21 struct video_fontdata *fontdata = priv->fontdata;
Dzmitry Sankouskiaea2d2d2023-03-07 13:21:11 +030022 void *line, *dst, *end;
Dzmitry Sankouski7fa964a2023-03-07 13:21:14 +030023 int pixels = fontdata->height * vid_priv->xsize;
Simon Glass03a96ae2020-07-02 21:12:24 -060024 int ret;
Simon Glass6c1ca6b2019-12-20 18:10:34 -070025 int i;
Dzmitry Sankouskiaea2d2d2023-03-07 13:21:11 +030026 int pbytes;
Simon Glass23825a92016-01-18 19:52:18 -070027
Dzmitry Sankouskiaea2d2d2023-03-07 13:21:11 +030028 ret = check_bpix_support(vid_priv->bpix);
29 if (ret)
30 return ret;
Simon Glass23825a92016-01-18 19:52:18 -070031
Dzmitry Sankouski7fa964a2023-03-07 13:21:14 +030032 line = vid_priv->fb + row * fontdata->height * vid_priv->line_length;
Dzmitry Sankouskiaea2d2d2023-03-07 13:21:11 +030033 dst = line;
34 pbytes = VNBYTES(vid_priv->bpix);
35 for (i = 0; i < pixels; i++)
36 fill_pixel_and_goto_next(&dst, clr, pbytes, pbytes);
37 end = dst;
Simon Glass23825a92016-01-18 19:52:18 -070038
Simon Glass03a96ae2020-07-02 21:12:24 -060039 ret = vidconsole_sync_copy(dev, line, end);
40 if (ret)
41 return ret;
Simon Glass23825a92016-01-18 19:52:18 -070042
43 return 0;
44}
45
Dzmitry Sankouskiaea2d2d2023-03-07 13:21:11 +030046static int console_move_rows(struct udevice *dev, uint rowdst,
47 uint rowsrc, uint count)
Simon Glass23825a92016-01-18 19:52:18 -070048{
49 struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent);
Dzmitry Sankouski7fa964a2023-03-07 13:21:14 +030050 struct console_simple_priv *priv = dev_get_priv(dev);
51 struct video_fontdata *fontdata = priv->fontdata;
Simon Glass23825a92016-01-18 19:52:18 -070052 void *dst;
53 void *src;
Simon Glass03a96ae2020-07-02 21:12:24 -060054 int size;
55 int ret;
Simon Glass23825a92016-01-18 19:52:18 -070056
Dzmitry Sankouski7fa964a2023-03-07 13:21:14 +030057 dst = vid_priv->fb + rowdst * fontdata->height * vid_priv->line_length;
58 src = vid_priv->fb + rowsrc * fontdata->height * vid_priv->line_length;
59 size = fontdata->height * vid_priv->line_length * count;
Simon Glass03a96ae2020-07-02 21:12:24 -060060 ret = vidconsole_memmove(dev, dst, src, size);
61 if (ret)
62 return ret;
Simon Glass23825a92016-01-18 19:52:18 -070063
64 return 0;
65}
66
Janne Grunau5548c362024-03-16 22:50:19 +010067static int console_putc_xy(struct udevice *dev, uint x_frac, uint y, int cp)
Simon Glass23825a92016-01-18 19:52:18 -070068{
Simon Glass52c10c52016-01-14 18:10:37 -070069 struct vidconsole_priv *vc_priv = dev_get_uclass_priv(dev);
Simon Glass23825a92016-01-18 19:52:18 -070070 struct udevice *vid = dev->parent;
71 struct video_priv *vid_priv = dev_get_uclass_priv(vid);
Dzmitry Sankouski7fa964a2023-03-07 13:21:14 +030072 struct console_simple_priv *priv = dev_get_priv(dev);
73 struct video_fontdata *fontdata = priv->fontdata;
Dzmitry Sankouskiaea2d2d2023-03-07 13:21:11 +030074 int pbytes = VNBYTES(vid_priv->bpix);
75 int x, linenum, ret;
76 void *start, *line;
Janne Grunau5548c362024-03-16 22:50:19 +010077 u8 ch = console_utf_to_cp437(cp);
Dzmitry Sankouski7fa964a2023-03-07 13:21:14 +030078 uchar *pfont = fontdata->video_fontdata +
Janne Grunau5548c362024-03-16 22:50:19 +010079 ch * fontdata->char_pixel_bytes;
Simon Glass03a96ae2020-07-02 21:12:24 -060080
Dzmitry Sankouskiaea2d2d2023-03-07 13:21:11 +030081 if (x_frac + VID_TO_POS(vc_priv->x_charsize) > vc_priv->xsize_frac)
82 return -EAGAIN;
83 linenum = y;
84 x = VID_TO_PIXEL(x_frac);
85 start = vid_priv->fb + linenum * vid_priv->line_length + x * pbytes;
Simon Glass03a96ae2020-07-02 21:12:24 -060086 line = start;
Simon Glass52c10c52016-01-14 18:10:37 -070087
88 if (x_frac + VID_TO_POS(vc_priv->x_charsize) > vc_priv->xsize_frac)
89 return -EAGAIN;
Simon Glass23825a92016-01-18 19:52:18 -070090
Dzmitry Sankouski7fa964a2023-03-07 13:21:14 +030091 ret = fill_char_vertically(pfont, &line, vid_priv, fontdata, NORMAL_DIRECTION);
Dzmitry Sankouskiaea2d2d2023-03-07 13:21:11 +030092 if (ret)
93 return ret;
Simon Glass23825a92016-01-18 19:52:18 -070094
Simon Glass03a96ae2020-07-02 21:12:24 -060095 ret = vidconsole_sync_copy(dev, start, line);
96 if (ret)
97 return ret;
Simon Glass23825a92016-01-18 19:52:18 -070098
Dzmitry Sankouski7fa964a2023-03-07 13:21:14 +030099 return VID_TO_POS(fontdata->width);
Simon Glass52c10c52016-01-14 18:10:37 -0700100}
101
Simon Glass377f79aa2023-10-01 19:13:21 -0600102static int console_set_cursor_visible(struct udevice *dev, bool visible,
103 uint x, uint y, uint index)
104{
105 struct vidconsole_priv *vc_priv = dev_get_uclass_priv(dev);
106 struct udevice *vid = dev->parent;
107 struct video_priv *vid_priv = dev_get_uclass_priv(vid);
108 struct console_simple_priv *priv = dev_get_priv(dev);
109 struct video_fontdata *fontdata = priv->fontdata;
110 int pbytes = VNBYTES(vid_priv->bpix);
111 void *start, *line;
112
113 /* for now, this is not used outside expo */
114 if (!IS_ENABLED(CONFIG_EXPO))
115 return -ENOSYS;
116
117 x += index * fontdata->width;
118 start = vid_priv->fb + y * vid_priv->line_length + x * pbytes;
119
120 /* place the cursor 1 pixel before the start of the next char */
121 x -= 1;
122
123 line = start;
124 draw_cursor_vertically(&line, vid_priv, vc_priv->y_charsize,
125 NORMAL_DIRECTION);
126
127 return 0;
128}
129
Dzmitry Sankouskiaea2d2d2023-03-07 13:21:11 +0300130struct vidconsole_ops console_ops = {
131 .putc_xy = console_putc_xy,
132 .move_rows = console_move_rows,
133 .set_row = console_set_row,
Dzmitry Sankouskibb165e42023-03-07 13:21:16 +0300134 .get_font_size = console_simple_get_font_size,
135 .get_font = console_simple_get_font,
136 .select_font = console_simple_select_font,
Simon Glass377f79aa2023-10-01 19:13:21 -0600137 .set_cursor_visible = console_set_cursor_visible,
Simon Glass23825a92016-01-18 19:52:18 -0700138};
139
140U_BOOT_DRIVER(vidconsole_normal) = {
Dzmitry Sankouski7fa964a2023-03-07 13:21:14 +0300141 .name = "vidconsole0",
142 .id = UCLASS_VIDEO_CONSOLE,
143 .ops = &console_ops,
144 .probe = console_probe,
145 .priv_auto = sizeof(struct console_simple_priv),
Simon Glass23825a92016-01-18 19:52:18 -0700146};