Merge branch 'master' of git://git.denx.de/u-boot-sunxi
[platform/kernel/u-boot.git] / common / lcd_console_rotation.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * (C) Copyright 2015
4  * Bernecker & Rainer Industrieelektronik GmbH - http://www.br-automation.com
5  */
6
7 #include <common.h>
8 #include <lcd.h>
9 #include <video_font.h>         /* Get font data, width and height */
10
11 static void lcd_putc_xy90(struct console_t *pcons, ushort x, ushort y, char c)
12 {
13         int fg_color = lcd_getfgcolor();
14         int bg_color = lcd_getbgcolor();
15         int col, i;
16
17         fbptr_t *dst = (fbptr_t *)pcons->fbbase +
18                                   (x+1) * pcons->lcdsizex -
19                                   y;
20
21         uchar msk = 0x80;
22         uchar *pfont = video_fontdata + c * VIDEO_FONT_HEIGHT;
23         for (col = 0; col < VIDEO_FONT_WIDTH; ++col) {
24                 for (i = 0; i < VIDEO_FONT_HEIGHT; ++i)
25                         *dst-- = (*(pfont + i) & msk) ? fg_color : bg_color;
26                 msk >>= 1;
27                 dst += (pcons->lcdsizex + VIDEO_FONT_HEIGHT);
28         }
29 }
30
31 static inline void console_setrow90(struct console_t *pcons, u32 row, int clr)
32 {
33         int i, j;
34         fbptr_t *dst = (fbptr_t *)pcons->fbbase +
35                                   pcons->lcdsizex -
36                                   row*VIDEO_FONT_HEIGHT+1;
37
38         for (j = 0; j < pcons->lcdsizey; j++) {
39                 for (i = 0; i < VIDEO_FONT_HEIGHT; i++)
40                         *dst-- = clr;
41                 dst += (pcons->lcdsizex + VIDEO_FONT_HEIGHT);
42         }
43 }
44
45 static inline void console_moverow90(struct console_t *pcons,
46                                       u32 rowdst, u32 rowsrc)
47 {
48         int i, j;
49         fbptr_t *dst = (fbptr_t *)pcons->fbbase +
50                                   pcons->lcdsizex -
51                                   (rowdst*VIDEO_FONT_HEIGHT+1);
52
53         fbptr_t *src = (fbptr_t *)pcons->fbbase +
54                                   pcons->lcdsizex -
55                                   (rowsrc*VIDEO_FONT_HEIGHT+1);
56
57         for (j = 0; j < pcons->lcdsizey; j++) {
58                 for (i = 0; i < VIDEO_FONT_HEIGHT; i++)
59                         *dst-- = *src--;
60                 src += (pcons->lcdsizex + VIDEO_FONT_HEIGHT);
61                 dst += (pcons->lcdsizex + VIDEO_FONT_HEIGHT);
62         }
63 }
64 static void lcd_putc_xy180(struct console_t *pcons, ushort x, ushort y, char c)
65 {
66         int fg_color = lcd_getfgcolor();
67         int bg_color = lcd_getbgcolor();
68         int i, row;
69         fbptr_t *dst = (fbptr_t *)pcons->fbbase +
70                                   pcons->lcdsizex +
71                                   pcons->lcdsizey * pcons->lcdsizex -
72                                   y * pcons->lcdsizex -
73                                   (x+1);
74
75         for (row = 0; row < VIDEO_FONT_HEIGHT; row++) {
76                 uchar bits = video_fontdata[c * VIDEO_FONT_HEIGHT + row];
77
78                 for (i = 0; i < VIDEO_FONT_WIDTH; ++i) {
79                         *dst-- = (bits & 0x80) ? fg_color : bg_color;
80                         bits <<= 1;
81                 }
82                 dst -= (pcons->lcdsizex - VIDEO_FONT_WIDTH);
83         }
84 }
85
86 static inline void console_setrow180(struct console_t *pcons, u32 row, int clr)
87 {
88         int i;
89         fbptr_t *dst = (fbptr_t *)pcons->fbbase +
90                                   (pcons->rows-row-1) * VIDEO_FONT_HEIGHT *
91                                   pcons->lcdsizex;
92
93         for (i = 0; i < (VIDEO_FONT_HEIGHT * pcons->lcdsizex); i++)
94                 *dst++ = clr;
95 }
96
97 static inline void console_moverow180(struct console_t *pcons,
98                                       u32 rowdst, u32 rowsrc)
99 {
100         int i;
101         fbptr_t *dst = (fbptr_t *)pcons->fbbase +
102                                   (pcons->rows-rowdst-1) * VIDEO_FONT_HEIGHT *
103                                   pcons->lcdsizex;
104
105         fbptr_t *src = (fbptr_t *)pcons->fbbase +
106                                   (pcons->rows-rowsrc-1) * VIDEO_FONT_HEIGHT *
107                                   pcons->lcdsizex;
108
109         for (i = 0; i < (VIDEO_FONT_HEIGHT * pcons->lcdsizex); i++)
110                 *dst++ = *src++;
111 }
112
113 static void lcd_putc_xy270(struct console_t *pcons, ushort x, ushort y, char c)
114 {
115         int fg_color = lcd_getfgcolor();
116         int bg_color = lcd_getbgcolor();
117         int i, col;
118         fbptr_t *dst = (fbptr_t *)pcons->fbbase +
119                                   pcons->lcdsizey * pcons->lcdsizex -
120                                   (x+1) * pcons->lcdsizex +
121                                   y;
122
123         uchar msk = 0x80;
124         uchar *pfont = video_fontdata + c * VIDEO_FONT_HEIGHT;
125         for (col = 0; col < VIDEO_FONT_WIDTH; ++col) {
126                 for (i = 0; i < VIDEO_FONT_HEIGHT; ++i)
127                         *dst++ = (*(pfont + i) & msk) ? fg_color : bg_color;
128                 msk >>= 1;
129                 dst -= (pcons->lcdsizex + VIDEO_FONT_HEIGHT);
130         }
131 }
132
133 static inline void console_setrow270(struct console_t *pcons, u32 row, int clr)
134 {
135         int i, j;
136         fbptr_t *dst = (fbptr_t *)pcons->fbbase +
137                                   row*VIDEO_FONT_HEIGHT;
138
139         for (j = 0; j < pcons->lcdsizey; j++) {
140                 for (i = 0; i < VIDEO_FONT_HEIGHT; i++)
141                         *dst++ = clr;
142                 dst += (pcons->lcdsizex - VIDEO_FONT_HEIGHT);
143         }
144 }
145
146 static inline void console_moverow270(struct console_t *pcons,
147                                      u32 rowdst, u32 rowsrc)
148 {
149         int i, j;
150         fbptr_t *dst = (fbptr_t *)pcons->fbbase +
151                                   rowdst*VIDEO_FONT_HEIGHT;
152
153         fbptr_t *src = (fbptr_t *)pcons->fbbase +
154                                   rowsrc*VIDEO_FONT_HEIGHT;
155
156         for (j = 0; j < pcons->lcdsizey; j++) {
157                 for (i = 0; i < VIDEO_FONT_HEIGHT; i++)
158                         *dst++ = *src++;
159                 src += (pcons->lcdsizex - VIDEO_FONT_HEIGHT);
160                 dst += (pcons->lcdsizex - VIDEO_FONT_HEIGHT);
161         }
162 }
163
164 static void console_calc_rowcol_rot(struct console_t *pcons)
165 {
166         if (pcons->lcdrot == 1 || pcons->lcdrot == 3)
167                 console_calc_rowcol(pcons, pcons->lcdsizey, pcons->lcdsizex);
168         else
169                 console_calc_rowcol(pcons, pcons->lcdsizex, pcons->lcdsizey);
170 }
171
172 void lcd_init_console_rot(struct console_t *pcons)
173 {
174         if (pcons->lcdrot == 0) {
175                 return;
176         } else if (pcons->lcdrot == 1) {
177                 pcons->fp_putc_xy = &lcd_putc_xy90;
178                 pcons->fp_console_moverow = &console_moverow90;
179                 pcons->fp_console_setrow = &console_setrow90;
180         } else if (pcons->lcdrot == 2) {
181                 pcons->fp_putc_xy = &lcd_putc_xy180;
182                 pcons->fp_console_moverow = &console_moverow180;
183                 pcons->fp_console_setrow = &console_setrow180;
184         } else if (pcons->lcdrot == 3) {
185                 pcons->fp_putc_xy = &lcd_putc_xy270;
186                 pcons->fp_console_moverow = &console_moverow270;
187                 pcons->fp_console_setrow = &console_setrow270;
188         } else {
189                 printf("%s: invalid framebuffer rotation (%d)!\n",
190                        __func__, pcons->lcdrot);
191                 return;
192         }
193         console_calc_rowcol_rot(pcons);
194 }