blob: ebb31d8cd0d1879dda03270bbed143305683ff01 [file] [log] [blame]
Simon Glass87aae882016-01-18 19:52:19 -07001/*
2 * Copyright (c) 2015 Google, Inc
3 * (C) Copyright 2015
4 * Bernecker & Rainer Industrieelektronik GmbH - http://www.br-automation.com
5 *
6 * SPDX-License-Identifier: GPL-2.0+
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
15static int console_set_row_1(struct udevice *dev, uint row, int clr)
16{
17 struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent);
18 int pbytes = VNBYTES(vid_priv->bpix);
19 void *line;
20 int i, j;
21
22 line = vid_priv->fb + vid_priv->line_length -
23 (row + 1) * VIDEO_FONT_HEIGHT * pbytes;
24 for (j = 0; j < vid_priv->ysize; j++) {
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 < VIDEO_FONT_HEIGHT; 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 < VIDEO_FONT_HEIGHT; 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 < VIDEO_FONT_HEIGHT; i++)
49 *dst++ = clr;
50 break;
51 }
52#endif
53 default:
54 return -ENOSYS;
55 }
56 line += vid_priv->line_length;
57 }
58
59 return 0;
60}
61
62static int console_move_rows_1(struct udevice *dev, uint rowdst, uint rowsrc,
63 uint count)
64{
65 struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent);
66 void *dst;
67 void *src;
68 int pbytes = VNBYTES(vid_priv->bpix);
69 int j;
70
71 dst = vid_priv->fb + vid_priv->line_length -
72 (rowdst + count) * VIDEO_FONT_HEIGHT * pbytes;
73 src = vid_priv->fb + vid_priv->line_length -
74 (rowsrc + count) * VIDEO_FONT_HEIGHT * pbytes;
75
76 for (j = 0; j < vid_priv->ysize; j++) {
77 memmove(dst, src, VIDEO_FONT_HEIGHT * pbytes * count);
78 src += vid_priv->line_length;
79 dst += vid_priv->line_length;
80 }
81
82 return 0;
83}
84
85static int console_putc_xy_1(struct udevice *dev, uint x, uint y, char ch)
86{
87 struct udevice *vid = dev->parent;
88 struct video_priv *vid_priv = dev_get_uclass_priv(vid);
89 int pbytes = VNBYTES(vid_priv->bpix);
90 int i, col;
91 int mask = 0x80;
92 void *line = vid_priv->fb + (x + 1) * vid_priv->line_length -
93 (y + 1) * pbytes;
94 uchar *pfont = video_fontdata + ch * VIDEO_FONT_HEIGHT;
95
96 for (col = 0; col < VIDEO_FONT_HEIGHT; col++) {
97 switch (vid_priv->bpix) {
98#ifdef CONFIG_VIDEO_BPP8
99 case VIDEO_BPP8: {
100 uint8_t *dst = line;
101
102 for (i = 0; i < VIDEO_FONT_HEIGHT; i++) {
103 *dst-- = (pfont[i] & mask) ? vid_priv->colour_fg
104 : vid_priv->colour_bg;
105 }
106 break;
107 }
108#endif
109#ifdef CONFIG_VIDEO_BPP16
110 case VIDEO_BPP16: {
111 uint16_t *dst = line;
112
113 for (i = 0; i < VIDEO_FONT_HEIGHT; i++) {
114 *dst-- = (pfont[i] & mask) ? vid_priv->colour_fg
115 : vid_priv->colour_bg;
116 }
117 break;
118 }
119#endif
120#ifdef CONFIG_VIDEO_BPP32
121 case VIDEO_BPP32: {
122 uint32_t *dst = line;
123
124 for (i = 0; i < VIDEO_FONT_HEIGHT; i++) {
125 *dst-- = (pfont[i] & mask) ? vid_priv->colour_fg
126 : vid_priv->colour_bg;
127 }
128 break;
129 }
130#endif
131 default:
132 return -ENOSYS;
133 }
134 line += vid_priv->line_length;
135 mask >>= 1;
136 }
137
138 return 0;
139}
140
141
142static int console_set_row_2(struct udevice *dev, uint row, int clr)
143{
144 struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent);
145 void *line;
146 int pixels = VIDEO_FONT_HEIGHT * vid_priv->xsize;
147 int i;
148
149 line = vid_priv->fb + vid_priv->ysize * vid_priv->line_length -
150 (row + 1) * VIDEO_FONT_HEIGHT * vid_priv->line_length;
151 switch (vid_priv->bpix) {
152#ifdef CONFIG_VIDEO_BPP8
153 case VIDEO_BPP8: {
154 uint8_t *dst = line;
155
156 for (i = 0; i < pixels; i++)
157 *dst++ = clr;
158 break;
159 }
160#endif
161#ifdef CONFIG_VIDEO_BPP16
162 case VIDEO_BPP16: {
163 uint16_t *dst = line;
164
165 for (i = 0; i < pixels; i++)
166 *dst++ = clr;
167 break;
168 }
169#endif
170#ifdef CONFIG_VIDEO_BPP32
171 case VIDEO_BPP32: {
172 uint32_t *dst = line;
173
174 for (i = 0; i < pixels; i++)
175 *dst++ = clr;
176 break;
177 }
178#endif
179 default:
180 return -ENOSYS;
181 }
182
183 return 0;
184}
185
186static int console_move_rows_2(struct udevice *dev, uint rowdst, uint rowsrc,
187 uint count)
188{
189 struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent);
190 void *dst;
191 void *src;
192 void *end;
193
194 end = vid_priv->fb + vid_priv->ysize * vid_priv->line_length;
195 dst = end - (rowdst + count) * VIDEO_FONT_HEIGHT *
196 vid_priv->line_length;
197 src = end - (rowsrc + count) * VIDEO_FONT_HEIGHT *
198 vid_priv->line_length;
199 memmove(dst, src, VIDEO_FONT_HEIGHT * vid_priv->line_length * count);
200
201 return 0;
202}
203
204static int console_putc_xy_2(struct udevice *dev, uint x, uint y, char ch)
205{
206 struct udevice *vid = dev->parent;
207 struct video_priv *vid_priv = dev_get_uclass_priv(vid);
208 int i, row;
209 void *line;
210
211 line = vid_priv->fb + (vid_priv->ysize - y - 1) *
212 vid_priv->line_length +
213 (vid_priv->xsize - x - VIDEO_FONT_WIDTH - 1) *
214 VNBYTES(vid_priv->bpix);
215
216 for (row = 0; row < VIDEO_FONT_HEIGHT; row++) {
217 uchar bits = video_fontdata[ch * VIDEO_FONT_HEIGHT + row];
218
219 switch (vid_priv->bpix) {
220#ifdef CONFIG_VIDEO_BPP8
221 case VIDEO_BPP8: {
222 uint8_t *dst = line;
223
224 for (i = 0; i < VIDEO_FONT_WIDTH; i++) {
225 *dst-- = (bits & 0x80) ? vid_priv->colour_fg
226 : vid_priv->colour_bg;
227 bits <<= 1;
228 }
229 break;
230 }
231#endif
232#ifdef CONFIG_VIDEO_BPP16
233 case VIDEO_BPP16: {
234 uint16_t *dst = line;
235
236 for (i = 0; i < VIDEO_FONT_WIDTH; i++) {
237 *dst-- = (bits & 0x80) ? vid_priv->colour_fg
238 : vid_priv->colour_bg;
239 bits <<= 1;
240 }
241 break;
242 }
243#endif
244#ifdef CONFIG_VIDEO_BPP32
245 case VIDEO_BPP32: {
246 uint32_t *dst = line;
247
248 for (i = 0; i < VIDEO_FONT_WIDTH; i++) {
249 *dst-- = (bits & 0x80) ? vid_priv->colour_fg
250 : vid_priv->colour_bg;
251 bits <<= 1;
252 }
253 break;
254 }
255#endif
256 default:
257 return -ENOSYS;
258 }
259 line -= vid_priv->line_length;
260 }
261
262 return 0;
263}
264
265static int console_set_row_3(struct udevice *dev, uint row, int clr)
266{
267 struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent);
268 int pbytes = VNBYTES(vid_priv->bpix);
269 void *line;
270 int i, j;
271
272 line = vid_priv->fb + row * VIDEO_FONT_HEIGHT * pbytes;
273 for (j = 0; j < vid_priv->ysize; j++) {
274 switch (vid_priv->bpix) {
275#ifdef CONFIG_VIDEO_BPP8
276 case VIDEO_BPP8: {
277 uint8_t *dst = line;
278
279 for (i = 0; i < VIDEO_FONT_HEIGHT; i++)
280 *dst++ = clr;
281 break;
282 }
283#endif
284#ifdef CONFIG_VIDEO_BPP16
285 case VIDEO_BPP16: {
286 uint16_t *dst = line;
287
288 for (i = 0; i < VIDEO_FONT_HEIGHT; i++)
289 *dst++ = clr;
290 break;
291 }
292#endif
293#ifdef CONFIG_VIDEO_BPP32
294 case VIDEO_BPP32: {
295 uint32_t *dst = line;
296
297 for (i = 0; i < VIDEO_FONT_HEIGHT; i++)
298 *dst++ = clr;
299 break;
300 }
301#endif
302 default:
303 return -ENOSYS;
304 }
305 line += vid_priv->line_length;
306 }
307
308 return 0;
309}
310
311static int console_move_rows_3(struct udevice *dev, uint rowdst, uint rowsrc,
312 uint count)
313{
314 struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent);
315 void *dst;
316 void *src;
317 int pbytes = VNBYTES(vid_priv->bpix);
318 int j;
319
320 dst = vid_priv->fb + rowdst * VIDEO_FONT_HEIGHT * pbytes;
321 src = vid_priv->fb + rowsrc * VIDEO_FONT_HEIGHT * pbytes;
322
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;
327 }
328
329 return 0;
330}
331
332static int console_putc_xy_3(struct udevice *dev, uint x, uint y, char ch)
333{
334 struct udevice *vid = dev->parent;
335 struct video_priv *vid_priv = dev_get_uclass_priv(vid);
336 int pbytes = VNBYTES(vid_priv->bpix);
337 int i, col;
338 int mask = 0x80;
339 void *line = vid_priv->fb + (vid_priv->ysize - x - 1) *
340 vid_priv->line_length + y * pbytes;
341 uchar *pfont = video_fontdata + ch * VIDEO_FONT_HEIGHT;
342
343 for (col = 0; col < VIDEO_FONT_HEIGHT; col++) {
344 switch (vid_priv->bpix) {
345#ifdef CONFIG_VIDEO_BPP8
346 case VIDEO_BPP8: {
347 uint8_t *dst = line;
348
349 for (i = 0; i < VIDEO_FONT_HEIGHT; i++) {
350 *dst++ = (pfont[i] & mask) ? vid_priv->colour_fg
351 : vid_priv->colour_bg;
352 }
353 break;
354 }
355#endif
356#ifdef CONFIG_VIDEO_BPP16
357 case VIDEO_BPP16: {
358 uint16_t *dst = line;
359
360 for (i = 0; i < VIDEO_FONT_HEIGHT; i++) {
361 *dst++ = (pfont[i] & mask) ? vid_priv->colour_fg
362 : vid_priv->colour_bg;
363 }
364 break;
365 }
366#endif
367#ifdef CONFIG_VIDEO_BPP32
368 case VIDEO_BPP32: {
369 uint32_t *dst = line;
370
371 for (i = 0; i < VIDEO_FONT_HEIGHT; i++) {
372 *dst++ = (pfont[i] & mask) ? vid_priv->colour_fg
373 : vid_priv->colour_bg;
374 }
375 break;
376 }
377#endif
378 default:
379 return -ENOSYS;
380 }
381 line -= vid_priv->line_length;
382 mask >>= 1;
383 }
384
385 return 0;
386}
387
388
389static int console_probe_1_3(struct udevice *dev)
390{
391 struct vidconsole_priv *priv = dev_get_uclass_priv(dev);
392 struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent);
393
394 priv->cols = vid_priv->ysize / VIDEO_FONT_WIDTH;
395 priv->rows = vid_priv->xsize / VIDEO_FONT_HEIGHT;
396
397 return 0;
398}
399
400struct vidconsole_ops console_ops_1 = {
401 .putc_xy = console_putc_xy_1,
402 .move_rows = console_move_rows_1,
403 .set_row = console_set_row_1,
404};
405
406struct vidconsole_ops console_ops_2 = {
407 .putc_xy = console_putc_xy_2,
408 .move_rows = console_move_rows_2,
409 .set_row = console_set_row_2,
410};
411
412struct vidconsole_ops console_ops_3 = {
413 .putc_xy = console_putc_xy_3,
414 .move_rows = console_move_rows_3,
415 .set_row = console_set_row_3,
416};
417
418U_BOOT_DRIVER(vidconsole_1) = {
419 .name = "vidconsole1",
420 .id = UCLASS_VIDEO_CONSOLE,
421 .ops = &console_ops_1,
422 .probe = console_probe_1_3,
423};
424
425U_BOOT_DRIVER(vidconsole_2) = {
426 .name = "vidconsole2",
427 .id = UCLASS_VIDEO_CONSOLE,
428 .ops = &console_ops_2,
429};
430
431U_BOOT_DRIVER(vidconsole_3) = {
432 .name = "vidconsole3",
433 .id = UCLASS_VIDEO_CONSOLE,
434 .ops = &console_ops_3,
435 .probe = console_probe_1_3,
436};