Prepare v2023.10
[platform/kernel/u-boot.git] / drivers / video / console_normal.c
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 <common.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
16 static int console_set_row(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         void *line, *dst, *end;
22         int pixels = fontdata->height * vid_priv->xsize;
23         int ret;
24         int i;
25         int pbytes;
26
27         ret = check_bpix_support(vid_priv->bpix);
28         if (ret)
29                 return ret;
30
31         line = vid_priv->fb + row * fontdata->height * vid_priv->line_length;
32         dst = line;
33         pbytes = VNBYTES(vid_priv->bpix);
34         for (i = 0; i < pixels; i++)
35                 fill_pixel_and_goto_next(&dst, clr, pbytes, pbytes);
36         end = dst;
37
38         ret = vidconsole_sync_copy(dev, line, end);
39         if (ret)
40                 return ret;
41
42         return 0;
43 }
44
45 static int console_move_rows(struct udevice *dev, uint rowdst,
46                              uint rowsrc, uint count)
47 {
48         struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent);
49         struct console_simple_priv *priv = dev_get_priv(dev);
50         struct video_fontdata *fontdata = priv->fontdata;
51         void *dst;
52         void *src;
53         int size;
54         int ret;
55
56         dst = vid_priv->fb + rowdst * fontdata->height * vid_priv->line_length;
57         src = vid_priv->fb + rowsrc * fontdata->height * vid_priv->line_length;
58         size = fontdata->height * vid_priv->line_length * count;
59         ret = vidconsole_memmove(dev, dst, src, size);
60         if (ret)
61                 return ret;
62
63         return 0;
64 }
65
66 static int console_putc_xy(struct udevice *dev, uint x_frac, uint y, char ch)
67 {
68         struct vidconsole_priv *vc_priv = dev_get_uclass_priv(dev);
69         struct udevice *vid = dev->parent;
70         struct video_priv *vid_priv = dev_get_uclass_priv(vid);
71         struct console_simple_priv *priv = dev_get_priv(dev);
72         struct video_fontdata *fontdata = priv->fontdata;
73         int pbytes = VNBYTES(vid_priv->bpix);
74         int x, linenum, ret;
75         void *start, *line;
76         uchar *pfont = fontdata->video_fontdata +
77                         (u8)ch * fontdata->char_pixel_bytes;
78
79         if (x_frac + VID_TO_POS(vc_priv->x_charsize) > vc_priv->xsize_frac)
80                 return -EAGAIN;
81         linenum = y;
82         x = VID_TO_PIXEL(x_frac);
83         start = vid_priv->fb + linenum * vid_priv->line_length + x * pbytes;
84         line = start;
85
86         if (x_frac + VID_TO_POS(vc_priv->x_charsize) > vc_priv->xsize_frac)
87                 return -EAGAIN;
88
89         ret = fill_char_vertically(pfont, &line, vid_priv, fontdata, NORMAL_DIRECTION);
90         if (ret)
91                 return ret;
92
93         ret = vidconsole_sync_copy(dev, start, line);
94         if (ret)
95                 return ret;
96
97         return VID_TO_POS(fontdata->width);
98 }
99
100 struct vidconsole_ops console_ops = {
101         .putc_xy        = console_putc_xy,
102         .move_rows      = console_move_rows,
103         .set_row        = console_set_row,
104         .get_font_size  = console_simple_get_font_size,
105         .get_font       = console_simple_get_font,
106         .select_font    = console_simple_select_font,
107 };
108
109 U_BOOT_DRIVER(vidconsole_normal) = {
110         .name           = "vidconsole0",
111         .id             = UCLASS_VIDEO_CONSOLE,
112         .ops            = &console_ops,
113         .probe          = console_probe,
114         .priv_auto      = sizeof(struct console_simple_priv),
115 };