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