Merge tag 'u-boot-imx-20190415' of git://git.denx.de/u-boot-imx
[oweals/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 2001-2015
5  * DENX Software Engineering -- wd@denx.de
6  * Compulab Ltd - http://compulab.co.il/
7  * Bernecker & Rainer Industrieelektronik GmbH - http://www.br-automation.com
8  */
9
10 #include <common.h>
11 #include <dm.h>
12 #include <video.h>
13 #include <video_console.h>
14 #include <video_font.h>         /* Get font data, width and height */
15
16 static int console_normal_set_row(struct udevice *dev, uint row, int clr)
17 {
18         struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent);
19         void *line;
20         int pixels = VIDEO_FONT_HEIGHT * vid_priv->xsize;
21         int i;
22
23         line = vid_priv->fb + row * VIDEO_FONT_HEIGHT * vid_priv->line_length;
24         switch (vid_priv->bpix) {
25 #ifdef CONFIG_VIDEO_BPP8
26         case VIDEO_BPP8: {
27                 uint8_t *dst = line;
28
29                 for (i = 0; i < pixels; i++)
30                         *dst++ = clr;
31                 break;
32         }
33 #endif
34 #ifdef CONFIG_VIDEO_BPP16
35         case VIDEO_BPP16: {
36                 uint16_t *dst = line;
37
38                 for (i = 0; i < pixels; i++)
39                         *dst++ = clr;
40                 break;
41         }
42 #endif
43 #ifdef CONFIG_VIDEO_BPP32
44         case VIDEO_BPP32: {
45                 uint32_t *dst = line;
46
47                 for (i = 0; i < pixels; i++)
48                         *dst++ = clr;
49                 break;
50         }
51 #endif
52         default:
53                 return -ENOSYS;
54         }
55
56         return 0;
57 }
58
59 static int console_normal_move_rows(struct udevice *dev, uint rowdst,
60                                      uint rowsrc, uint count)
61 {
62         struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent);
63         void *dst;
64         void *src;
65
66         dst = vid_priv->fb + rowdst * VIDEO_FONT_HEIGHT * vid_priv->line_length;
67         src = vid_priv->fb + rowsrc * VIDEO_FONT_HEIGHT * vid_priv->line_length;
68         memmove(dst, src, VIDEO_FONT_HEIGHT * vid_priv->line_length * count);
69
70         return 0;
71 }
72
73 static int console_normal_putc_xy(struct udevice *dev, uint x_frac, uint y,
74                                   char ch)
75 {
76         struct vidconsole_priv *vc_priv = dev_get_uclass_priv(dev);
77         struct udevice *vid = dev->parent;
78         struct video_priv *vid_priv = dev_get_uclass_priv(vid);
79         int i, row;
80         void *line = vid_priv->fb + y * vid_priv->line_length +
81                 VID_TO_PIXEL(x_frac) * VNBYTES(vid_priv->bpix);
82
83         if (x_frac + VID_TO_POS(vc_priv->x_charsize) > vc_priv->xsize_frac)
84                 return -EAGAIN;
85
86         for (row = 0; row < VIDEO_FONT_HEIGHT; row++) {
87                 unsigned int idx = (u8)ch * VIDEO_FONT_HEIGHT + row;
88                 uchar bits = video_fontdata[idx];
89
90                 switch (vid_priv->bpix) {
91 #ifdef CONFIG_VIDEO_BPP8
92                 case VIDEO_BPP8: {
93                         uint8_t *dst = line;
94
95                         for (i = 0; i < VIDEO_FONT_WIDTH; i++) {
96                                 *dst++ = (bits & 0x80) ? vid_priv->colour_fg
97                                         : vid_priv->colour_bg;
98                                 bits <<= 1;
99                         }
100                         break;
101                 }
102 #endif
103 #ifdef CONFIG_VIDEO_BPP16
104                 case VIDEO_BPP16: {
105                         uint16_t *dst = line;
106
107                         for (i = 0; i < VIDEO_FONT_WIDTH; i++) {
108                                 *dst++ = (bits & 0x80) ? vid_priv->colour_fg
109                                         : vid_priv->colour_bg;
110                                 bits <<= 1;
111                         }
112                         break;
113                 }
114 #endif
115 #ifdef CONFIG_VIDEO_BPP32
116                 case VIDEO_BPP32: {
117                         uint32_t *dst = line;
118
119                         for (i = 0; i < VIDEO_FONT_WIDTH; i++) {
120                                 *dst++ = (bits & 0x80) ? vid_priv->colour_fg
121                                         : vid_priv->colour_bg;
122                                 bits <<= 1;
123                         }
124                         break;
125                 }
126 #endif
127                 default:
128                         return -ENOSYS;
129                 }
130                 line += vid_priv->line_length;
131         }
132
133         return VID_TO_POS(VIDEO_FONT_WIDTH);
134 }
135
136 static int console_normal_probe(struct udevice *dev)
137 {
138         struct vidconsole_priv *vc_priv = dev_get_uclass_priv(dev);
139         struct udevice *vid_dev = dev->parent;
140         struct video_priv *vid_priv = dev_get_uclass_priv(vid_dev);
141
142         vc_priv->x_charsize = VIDEO_FONT_WIDTH;
143         vc_priv->y_charsize = VIDEO_FONT_HEIGHT;
144         vc_priv->cols = vid_priv->xsize / VIDEO_FONT_WIDTH;
145         vc_priv->rows = vid_priv->ysize / VIDEO_FONT_HEIGHT;
146
147         return 0;
148 }
149
150 struct vidconsole_ops console_normal_ops = {
151         .putc_xy        = console_normal_putc_xy,
152         .move_rows      = console_normal_move_rows,
153         .set_row        = console_normal_set_row,
154 };
155
156 U_BOOT_DRIVER(vidconsole_normal) = {
157         .name   = "vidconsole0",
158         .id     = UCLASS_VIDEO_CONSOLE,
159         .ops    = &console_normal_ops,
160         .probe  = console_normal_probe,
161 };