b627d48df698b7bae363d67be0d847e4ade2251f
[oweals/u-boot.git] / drivers / video / console_normal.c
1 /*
2  * Copyright (c) 2015 Google, Inc
3  * (C) Copyright 2001-2015
4  * DENX Software Engineering -- wd@denx.de
5  * Compulab Ltd - http://compulab.co.il/
6  * Bernecker & Rainer Industrieelektronik GmbH - http://www.br-automation.com
7  *
8  * SPDX-License-Identifier:     GPL-2.0+
9  */
10
11 #include <common.h>
12 #include <dm.h>
13 #include <video.h>
14 #include <video_console.h>
15 #include <video_font.h>         /* Get font data, width and height */
16
17 static int console_normal_set_row(struct udevice *dev, uint row, int clr)
18 {
19         struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent);
20         void *line;
21         int pixels = VIDEO_FONT_HEIGHT * vid_priv->xsize;
22         int i;
23
24         line = vid_priv->fb + row * VIDEO_FONT_HEIGHT * vid_priv->line_length;
25         switch (vid_priv->bpix) {
26 #ifdef CONFIG_VIDEO_BPP8
27         case VIDEO_BPP8: {
28                 uint8_t *dst = line;
29
30                 for (i = 0; i < pixels; i++)
31                         *dst++ = clr;
32                 break;
33         }
34 #endif
35 #ifdef CONFIG_VIDEO_BPP16
36         case VIDEO_BPP16: {
37                 uint16_t *dst = line;
38
39                 for (i = 0; i < pixels; i++)
40                         *dst++ = clr;
41                 break;
42         }
43 #endif
44 #ifdef CONFIG_VIDEO_BPP32
45         case VIDEO_BPP32: {
46                 uint32_t *dst = line;
47
48                 for (i = 0; i < pixels; i++)
49                         *dst++ = clr;
50                 break;
51         }
52 #endif
53         default:
54                 return -ENOSYS;
55         }
56
57         return 0;
58 }
59
60 static int console_normal_move_rows(struct udevice *dev, uint rowdst,
61                                      uint rowsrc, uint count)
62 {
63         struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent);
64         void *dst;
65         void *src;
66
67         dst = vid_priv->fb + rowdst * VIDEO_FONT_HEIGHT * vid_priv->line_length;
68         src = vid_priv->fb + rowsrc * VIDEO_FONT_HEIGHT * vid_priv->line_length;
69         memmove(dst, src, VIDEO_FONT_HEIGHT * vid_priv->line_length * count);
70
71         return 0;
72 }
73
74 static int console_normal_putc_xy(struct udevice *dev, uint x_frac, uint y,
75                                   char ch)
76 {
77         struct vidconsole_priv *vc_priv = dev_get_uclass_priv(dev);
78         struct udevice *vid = dev->parent;
79         struct video_priv *vid_priv = dev_get_uclass_priv(vid);
80         int i, row;
81         void *line = vid_priv->fb + y * vid_priv->line_length +
82                 VID_TO_PIXEL(x_frac) * VNBYTES(vid_priv->bpix);
83
84         if (x_frac + VID_TO_POS(vc_priv->x_charsize) > vc_priv->xsize_frac)
85                 return -EAGAIN;
86
87         for (row = 0; row < VIDEO_FONT_HEIGHT; row++) {
88                 uchar bits = video_fontdata[ch * VIDEO_FONT_HEIGHT + row];
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 };