]> git.sur5r.net Git - u-boot/blob - drivers/video/console_rotate.c
227141d68760a14f0b565347969b5264d5f7d679
[u-boot] / drivers / video / console_rotate.c
1 /*
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
15 static 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
62 static 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
85 static int console_putc_xy_1(struct udevice *dev, uint x_frac, uint y, char ch)
86 {
87         struct vidconsole_priv *vc_priv = dev_get_uclass_priv(dev);
88         struct udevice *vid = dev->parent;
89         struct video_priv *vid_priv = dev_get_uclass_priv(vid);
90         int pbytes = VNBYTES(vid_priv->bpix);
91         int i, col;
92         int mask = 0x80;
93         void *line;
94         uchar *pfont = video_fontdata + ch * VIDEO_FONT_HEIGHT;
95
96         line = vid_priv->fb + (VID_TO_PIXEL(x_frac) + 1) *
97                         vid_priv->line_length - (y + 1) * pbytes;
98         if (x_frac + VID_TO_POS(vc_priv->x_charsize) > vc_priv->xsize_frac)
99                 return -EAGAIN;
100
101         for (col = 0; col < VIDEO_FONT_HEIGHT; col++) {
102                 switch (vid_priv->bpix) {
103 #ifdef CONFIG_VIDEO_BPP8
104                 case VIDEO_BPP8: {
105                         uint8_t *dst = line;
106
107                         for (i = 0; i < VIDEO_FONT_HEIGHT; i++) {
108                                 *dst-- = (pfont[i] & mask) ? vid_priv->colour_fg
109                                         : vid_priv->colour_bg;
110                         }
111                         break;
112                 }
113 #endif
114 #ifdef CONFIG_VIDEO_BPP16
115                 case VIDEO_BPP16: {
116                         uint16_t *dst = line;
117
118                         for (i = 0; i < VIDEO_FONT_HEIGHT; i++) {
119                                 *dst-- = (pfont[i] & mask) ? vid_priv->colour_fg
120                                         : vid_priv->colour_bg;
121                         }
122                         break;
123                 }
124 #endif
125 #ifdef CONFIG_VIDEO_BPP32
126                 case VIDEO_BPP32: {
127                         uint32_t *dst = line;
128
129                         for (i = 0; i < VIDEO_FONT_HEIGHT; i++) {
130                                 *dst-- = (pfont[i] & mask) ? vid_priv->colour_fg
131                                         : vid_priv->colour_bg;
132                         }
133                         break;
134                 }
135 #endif
136                 default:
137                         return -ENOSYS;
138                 }
139                 line += vid_priv->line_length;
140                 mask >>= 1;
141         }
142
143         return VID_TO_POS(VIDEO_FONT_WIDTH);
144 }
145
146
147 static int console_set_row_2(struct udevice *dev, uint row, int clr)
148 {
149         struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent);
150         void *line;
151         int pixels = VIDEO_FONT_HEIGHT * vid_priv->xsize;
152         int i;
153
154         line = vid_priv->fb + vid_priv->ysize * vid_priv->line_length -
155                 (row + 1) * VIDEO_FONT_HEIGHT * vid_priv->line_length;
156         switch (vid_priv->bpix) {
157 #ifdef CONFIG_VIDEO_BPP8
158         case VIDEO_BPP8: {
159                 uint8_t *dst = line;
160
161                 for (i = 0; i < pixels; i++)
162                         *dst++ = clr;
163                 break;
164         }
165 #endif
166 #ifdef CONFIG_VIDEO_BPP16
167         case VIDEO_BPP16: {
168                 uint16_t *dst = line;
169
170                 for (i = 0; i < pixels; i++)
171                         *dst++ = clr;
172                 break;
173         }
174 #endif
175 #ifdef CONFIG_VIDEO_BPP32
176         case VIDEO_BPP32: {
177                 uint32_t *dst = line;
178
179                 for (i = 0; i < pixels; i++)
180                         *dst++ = clr;
181                 break;
182         }
183 #endif
184         default:
185                 return -ENOSYS;
186         }
187
188         return 0;
189 }
190
191 static int console_move_rows_2(struct udevice *dev, uint rowdst, uint rowsrc,
192                                uint count)
193 {
194         struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent);
195         void *dst;
196         void *src;
197         void *end;
198
199         end = vid_priv->fb + vid_priv->ysize * vid_priv->line_length;
200         dst = end - (rowdst + count) * VIDEO_FONT_HEIGHT *
201                 vid_priv->line_length;
202         src = end - (rowsrc + count) * VIDEO_FONT_HEIGHT *
203                 vid_priv->line_length;
204         memmove(dst, src, VIDEO_FONT_HEIGHT * vid_priv->line_length * count);
205
206         return 0;
207 }
208
209 static int console_putc_xy_2(struct udevice *dev, uint x_frac, uint y, char ch)
210 {
211         struct vidconsole_priv *vc_priv = dev_get_uclass_priv(dev);
212         struct udevice *vid = dev->parent;
213         struct video_priv *vid_priv = dev_get_uclass_priv(vid);
214         int i, row;
215         void *line;
216
217         if (x_frac + VID_TO_POS(vc_priv->x_charsize) > vc_priv->xsize_frac)
218                 return -EAGAIN;
219
220         line = vid_priv->fb + (vid_priv->ysize - y - 1) *
221                         vid_priv->line_length +
222                         (vid_priv->xsize - VID_TO_PIXEL(x_frac) -
223                         VIDEO_FONT_WIDTH - 1) * VNBYTES(vid_priv->bpix);
224
225         for (row = 0; row < VIDEO_FONT_HEIGHT; row++) {
226                 uchar bits = video_fontdata[ch * VIDEO_FONT_HEIGHT + row];
227
228                 switch (vid_priv->bpix) {
229 #ifdef CONFIG_VIDEO_BPP8
230                 case VIDEO_BPP8: {
231                         uint8_t *dst = line;
232
233                         for (i = 0; i < VIDEO_FONT_WIDTH; i++) {
234                                 *dst-- = (bits & 0x80) ? vid_priv->colour_fg
235                                         : vid_priv->colour_bg;
236                                 bits <<= 1;
237                         }
238                         break;
239                 }
240 #endif
241 #ifdef CONFIG_VIDEO_BPP16
242                 case VIDEO_BPP16: {
243                         uint16_t *dst = line;
244
245                         for (i = 0; i < VIDEO_FONT_WIDTH; i++) {
246                                 *dst-- = (bits & 0x80) ? vid_priv->colour_fg
247                                         : vid_priv->colour_bg;
248                                 bits <<= 1;
249                         }
250                         break;
251                 }
252 #endif
253 #ifdef CONFIG_VIDEO_BPP32
254                 case VIDEO_BPP32: {
255                         uint32_t *dst = line;
256
257                         for (i = 0; i < VIDEO_FONT_WIDTH; i++) {
258                                 *dst-- = (bits & 0x80) ? vid_priv->colour_fg
259                                         : vid_priv->colour_bg;
260                                 bits <<= 1;
261                         }
262                         break;
263                 }
264 #endif
265                 default:
266                         return -ENOSYS;
267                 }
268                 line -= vid_priv->line_length;
269         }
270
271         return VID_TO_POS(VIDEO_FONT_WIDTH);
272 }
273
274 static int console_set_row_3(struct udevice *dev, uint row, int clr)
275 {
276         struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent);
277         int pbytes = VNBYTES(vid_priv->bpix);
278         void *line;
279         int i, j;
280
281         line = vid_priv->fb + row * VIDEO_FONT_HEIGHT * pbytes;
282         for (j = 0; j < vid_priv->ysize; j++) {
283                 switch (vid_priv->bpix) {
284 #ifdef CONFIG_VIDEO_BPP8
285                 case VIDEO_BPP8: {
286                         uint8_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_BPP16
294                 case VIDEO_BPP16: {
295                         uint16_t *dst = line;
296
297                         for (i = 0; i < VIDEO_FONT_HEIGHT; i++)
298                                 *dst++ = clr;
299                         break;
300                 }
301 #endif
302 #ifdef CONFIG_VIDEO_BPP32
303                 case VIDEO_BPP32: {
304                         uint32_t *dst = line;
305
306                         for (i = 0; i < VIDEO_FONT_HEIGHT; i++)
307                                 *dst++ = clr;
308                         break;
309                 }
310 #endif
311                 default:
312                         return -ENOSYS;
313                 }
314                 line += vid_priv->line_length;
315         }
316
317         return 0;
318 }
319
320 static int console_move_rows_3(struct udevice *dev, uint rowdst, uint rowsrc,
321                                uint count)
322 {
323         struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent);
324         void *dst;
325         void *src;
326         int pbytes = VNBYTES(vid_priv->bpix);
327         int j;
328
329         dst = vid_priv->fb + rowdst * VIDEO_FONT_HEIGHT * pbytes;
330         src = vid_priv->fb + rowsrc * VIDEO_FONT_HEIGHT * pbytes;
331
332         for (j = 0; j < vid_priv->ysize; j++) {
333                 memmove(dst, src, VIDEO_FONT_HEIGHT * pbytes * count);
334                 src += vid_priv->line_length;
335                 dst += vid_priv->line_length;
336         }
337
338         return 0;
339 }
340
341 static int console_putc_xy_3(struct udevice *dev, uint x_frac, uint y, char ch)
342 {
343         struct vidconsole_priv *vc_priv = dev_get_uclass_priv(dev);
344         struct udevice *vid = dev->parent;
345         struct video_priv *vid_priv = dev_get_uclass_priv(vid);
346         int pbytes = VNBYTES(vid_priv->bpix);
347         int i, col;
348         int mask = 0x80;
349         void *line = vid_priv->fb +
350                 (vid_priv->ysize - VID_TO_PIXEL(x_frac) - 1) *
351                 vid_priv->line_length + y * pbytes;
352         uchar *pfont = video_fontdata + ch * VIDEO_FONT_HEIGHT;
353
354         if (x_frac + VID_TO_POS(vc_priv->x_charsize) > vc_priv->xsize_frac)
355                 return -EAGAIN;
356
357         for (col = 0; col < VIDEO_FONT_HEIGHT; col++) {
358                 switch (vid_priv->bpix) {
359 #ifdef CONFIG_VIDEO_BPP8
360                 case VIDEO_BPP8: {
361                         uint8_t *dst = line;
362
363                         for (i = 0; i < VIDEO_FONT_HEIGHT; i++) {
364                                 *dst++ = (pfont[i] & mask) ? vid_priv->colour_fg
365                                         : vid_priv->colour_bg;
366                         }
367                         break;
368                 }
369 #endif
370 #ifdef CONFIG_VIDEO_BPP16
371                 case VIDEO_BPP16: {
372                         uint16_t *dst = line;
373
374                         for (i = 0; i < VIDEO_FONT_HEIGHT; i++) {
375                                 *dst++ = (pfont[i] & mask) ? vid_priv->colour_fg
376                                         : vid_priv->colour_bg;
377                         }
378                         break;
379                 }
380 #endif
381 #ifdef CONFIG_VIDEO_BPP32
382                 case VIDEO_BPP32: {
383                         uint32_t *dst = line;
384
385                         for (i = 0; i < VIDEO_FONT_HEIGHT; i++) {
386                                 *dst++ = (pfont[i] & mask) ? vid_priv->colour_fg
387                                         : vid_priv->colour_bg;
388                         }
389                         break;
390                 }
391 #endif
392                 default:
393                         return -ENOSYS;
394                 }
395                 line -= vid_priv->line_length;
396                 mask >>= 1;
397         }
398
399         return VID_TO_POS(VIDEO_FONT_WIDTH);
400 }
401
402
403 static int console_probe_2(struct udevice *dev)
404 {
405         struct vidconsole_priv *vc_priv = dev_get_uclass_priv(dev);
406         struct udevice *vid_dev = dev->parent;
407         struct video_priv *vid_priv = dev_get_uclass_priv(vid_dev);
408
409         vc_priv->x_charsize = VIDEO_FONT_WIDTH;
410         vc_priv->y_charsize = VIDEO_FONT_HEIGHT;
411         vc_priv->cols = vid_priv->xsize / VIDEO_FONT_WIDTH;
412         vc_priv->rows = vid_priv->ysize / VIDEO_FONT_HEIGHT;
413
414         return 0;
415 }
416
417 static int console_probe_1_3(struct udevice *dev)
418 {
419         struct vidconsole_priv *vc_priv = dev_get_uclass_priv(dev);
420         struct udevice *vid_dev = dev->parent;
421         struct video_priv *vid_priv = dev_get_uclass_priv(vid_dev);
422
423         vc_priv->x_charsize = VIDEO_FONT_WIDTH;
424         vc_priv->y_charsize = VIDEO_FONT_HEIGHT;
425         vc_priv->cols = vid_priv->ysize / VIDEO_FONT_WIDTH;
426         vc_priv->rows = vid_priv->xsize / VIDEO_FONT_HEIGHT;
427         vc_priv->xsize_frac = VID_TO_POS(vid_priv->ysize);
428
429         return 0;
430 }
431
432 struct vidconsole_ops console_ops_1 = {
433         .putc_xy        = console_putc_xy_1,
434         .move_rows      = console_move_rows_1,
435         .set_row        = console_set_row_1,
436 };
437
438 struct vidconsole_ops console_ops_2 = {
439         .putc_xy        = console_putc_xy_2,
440         .move_rows      = console_move_rows_2,
441         .set_row        = console_set_row_2,
442 };
443
444 struct vidconsole_ops console_ops_3 = {
445         .putc_xy        = console_putc_xy_3,
446         .move_rows      = console_move_rows_3,
447         .set_row        = console_set_row_3,
448 };
449
450 U_BOOT_DRIVER(vidconsole_1) = {
451         .name   = "vidconsole1",
452         .id     = UCLASS_VIDEO_CONSOLE,
453         .ops    = &console_ops_1,
454         .probe  = console_probe_1_3,
455 };
456
457 U_BOOT_DRIVER(vidconsole_2) = {
458         .name   = "vidconsole2",
459         .id     = UCLASS_VIDEO_CONSOLE,
460         .ops    = &console_ops_2,
461         .probe  = console_probe_2,
462 };
463
464 U_BOOT_DRIVER(vidconsole_3) = {
465         .name   = "vidconsole3",
466         .id     = UCLASS_VIDEO_CONSOLE,
467         .ops    = &console_ops_3,
468         .probe  = console_probe_1_3,
469 };