1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun * PXA LCD Controller
3*4882a593Smuzhiyun *
4*4882a593Smuzhiyun * (C) Copyright 2001-2002
5*4882a593Smuzhiyun * Wolfgang Denk, DENX Software Engineering -- wd@denx.de
6*4882a593Smuzhiyun *
7*4882a593Smuzhiyun * SPDX-License-Identifier: GPL-2.0+
8*4882a593Smuzhiyun */
9*4882a593Smuzhiyun
10*4882a593Smuzhiyun /************************************************************************/
11*4882a593Smuzhiyun /* ** HEADER FILES */
12*4882a593Smuzhiyun /************************************************************************/
13*4882a593Smuzhiyun
14*4882a593Smuzhiyun #include <common.h>
15*4882a593Smuzhiyun #include <asm/arch/pxa-regs.h>
16*4882a593Smuzhiyun #include <asm/io.h>
17*4882a593Smuzhiyun #include <lcd.h>
18*4882a593Smuzhiyun #include <linux/types.h>
19*4882a593Smuzhiyun #include <stdarg.h>
20*4882a593Smuzhiyun #include <stdio_dev.h>
21*4882a593Smuzhiyun
22*4882a593Smuzhiyun /* #define DEBUG */
23*4882a593Smuzhiyun
24*4882a593Smuzhiyun #ifdef CONFIG_LCD
25*4882a593Smuzhiyun
26*4882a593Smuzhiyun /*----------------------------------------------------------------------*/
27*4882a593Smuzhiyun /*
28*4882a593Smuzhiyun * Define panel bpp, LCCR0, LCCR3 and panel_info video struct for
29*4882a593Smuzhiyun * your display.
30*4882a593Smuzhiyun */
31*4882a593Smuzhiyun
32*4882a593Smuzhiyun #ifdef CONFIG_PXA_VGA
33*4882a593Smuzhiyun /* LCD outputs connected to a video DAC */
34*4882a593Smuzhiyun # define LCD_BPP LCD_COLOR8
35*4882a593Smuzhiyun
36*4882a593Smuzhiyun /* you have to set lccr0 and lccr3 (including pcd) */
37*4882a593Smuzhiyun # define REG_LCCR0 0x003008f8
38*4882a593Smuzhiyun # define REG_LCCR3 0x0300FF01
39*4882a593Smuzhiyun
40*4882a593Smuzhiyun /* 640x480x16 @ 61 Hz */
41*4882a593Smuzhiyun vidinfo_t panel_info = {
42*4882a593Smuzhiyun .vl_col = 640,
43*4882a593Smuzhiyun .vl_row = 480,
44*4882a593Smuzhiyun .vl_width = 640,
45*4882a593Smuzhiyun .vl_height = 480,
46*4882a593Smuzhiyun .vl_clkp = CONFIG_SYS_HIGH,
47*4882a593Smuzhiyun .vl_oep = CONFIG_SYS_HIGH,
48*4882a593Smuzhiyun .vl_hsp = CONFIG_SYS_HIGH,
49*4882a593Smuzhiyun .vl_vsp = CONFIG_SYS_HIGH,
50*4882a593Smuzhiyun .vl_dp = CONFIG_SYS_HIGH,
51*4882a593Smuzhiyun .vl_bpix = LCD_BPP,
52*4882a593Smuzhiyun .vl_lbw = 0,
53*4882a593Smuzhiyun .vl_splt = 0,
54*4882a593Smuzhiyun .vl_clor = 0,
55*4882a593Smuzhiyun .vl_tft = 1,
56*4882a593Smuzhiyun .vl_hpw = 40,
57*4882a593Smuzhiyun .vl_blw = 56,
58*4882a593Smuzhiyun .vl_elw = 56,
59*4882a593Smuzhiyun .vl_vpw = 20,
60*4882a593Smuzhiyun .vl_bfw = 8,
61*4882a593Smuzhiyun .vl_efw = 8,
62*4882a593Smuzhiyun };
63*4882a593Smuzhiyun #endif /* CONFIG_PXA_VIDEO */
64*4882a593Smuzhiyun
65*4882a593Smuzhiyun /*----------------------------------------------------------------------*/
66*4882a593Smuzhiyun #ifdef CONFIG_SHARP_LM8V31
67*4882a593Smuzhiyun
68*4882a593Smuzhiyun # define LCD_BPP LCD_COLOR8
69*4882a593Smuzhiyun # define LCD_INVERT_COLORS /* Needed for colors to be correct, but why? */
70*4882a593Smuzhiyun
71*4882a593Smuzhiyun /* you have to set lccr0 and lccr3 (including pcd) */
72*4882a593Smuzhiyun # define REG_LCCR0 0x0030087C
73*4882a593Smuzhiyun # define REG_LCCR3 0x0340FF08
74*4882a593Smuzhiyun
75*4882a593Smuzhiyun vidinfo_t panel_info = {
76*4882a593Smuzhiyun .vl_col = 640,
77*4882a593Smuzhiyun .vl_row = 480,
78*4882a593Smuzhiyun .vl_width = 157,
79*4882a593Smuzhiyun .vl_height = 118,
80*4882a593Smuzhiyun .vl_clkp = CONFIG_SYS_HIGH,
81*4882a593Smuzhiyun .vl_oep = CONFIG_SYS_HIGH,
82*4882a593Smuzhiyun .vl_hsp = CONFIG_SYS_HIGH,
83*4882a593Smuzhiyun .vl_vsp = CONFIG_SYS_HIGH,
84*4882a593Smuzhiyun .vl_dp = CONFIG_SYS_HIGH,
85*4882a593Smuzhiyun .vl_bpix = LCD_BPP,
86*4882a593Smuzhiyun .vl_lbw = 0,
87*4882a593Smuzhiyun .vl_splt = 1,
88*4882a593Smuzhiyun .vl_clor = 1,
89*4882a593Smuzhiyun .vl_tft = 0,
90*4882a593Smuzhiyun .vl_hpw = 1,
91*4882a593Smuzhiyun .vl_blw = 3,
92*4882a593Smuzhiyun .vl_elw = 3,
93*4882a593Smuzhiyun .vl_vpw = 1,
94*4882a593Smuzhiyun .vl_bfw = 0,
95*4882a593Smuzhiyun .vl_efw = 0,
96*4882a593Smuzhiyun };
97*4882a593Smuzhiyun #endif /* CONFIG_SHARP_LM8V31 */
98*4882a593Smuzhiyun /*----------------------------------------------------------------------*/
99*4882a593Smuzhiyun #ifdef CONFIG_VOIPAC_LCD
100*4882a593Smuzhiyun
101*4882a593Smuzhiyun # define LCD_BPP LCD_COLOR8
102*4882a593Smuzhiyun # define LCD_INVERT_COLORS
103*4882a593Smuzhiyun
104*4882a593Smuzhiyun /* you have to set lccr0 and lccr3 (including pcd) */
105*4882a593Smuzhiyun # define REG_LCCR0 0x043008f8
106*4882a593Smuzhiyun # define REG_LCCR3 0x0340FF08
107*4882a593Smuzhiyun
108*4882a593Smuzhiyun vidinfo_t panel_info = {
109*4882a593Smuzhiyun .vl_col = 640,
110*4882a593Smuzhiyun .vl_row = 480,
111*4882a593Smuzhiyun .vl_width = 157,
112*4882a593Smuzhiyun .vl_height = 118,
113*4882a593Smuzhiyun .vl_clkp = CONFIG_SYS_HIGH,
114*4882a593Smuzhiyun .vl_oep = CONFIG_SYS_HIGH,
115*4882a593Smuzhiyun .vl_hsp = CONFIG_SYS_HIGH,
116*4882a593Smuzhiyun .vl_vsp = CONFIG_SYS_HIGH,
117*4882a593Smuzhiyun .vl_dp = CONFIG_SYS_HIGH,
118*4882a593Smuzhiyun .vl_bpix = LCD_BPP,
119*4882a593Smuzhiyun .vl_lbw = 0,
120*4882a593Smuzhiyun .vl_splt = 1,
121*4882a593Smuzhiyun .vl_clor = 1,
122*4882a593Smuzhiyun .vl_tft = 1,
123*4882a593Smuzhiyun .vl_hpw = 32,
124*4882a593Smuzhiyun .vl_blw = 144,
125*4882a593Smuzhiyun .vl_elw = 32,
126*4882a593Smuzhiyun .vl_vpw = 2,
127*4882a593Smuzhiyun .vl_bfw = 13,
128*4882a593Smuzhiyun .vl_efw = 30,
129*4882a593Smuzhiyun };
130*4882a593Smuzhiyun #endif /* CONFIG_VOIPAC_LCD */
131*4882a593Smuzhiyun
132*4882a593Smuzhiyun /*----------------------------------------------------------------------*/
133*4882a593Smuzhiyun #ifdef CONFIG_HITACHI_SX14
134*4882a593Smuzhiyun /* Hitachi SX14Q004-ZZA color STN LCD */
135*4882a593Smuzhiyun #define LCD_BPP LCD_COLOR8
136*4882a593Smuzhiyun
137*4882a593Smuzhiyun /* you have to set lccr0 and lccr3 (including pcd) */
138*4882a593Smuzhiyun #define REG_LCCR0 0x00301079
139*4882a593Smuzhiyun #define REG_LCCR3 0x0340FF20
140*4882a593Smuzhiyun
141*4882a593Smuzhiyun vidinfo_t panel_info = {
142*4882a593Smuzhiyun .vl_col = 320,
143*4882a593Smuzhiyun .vl_row = 240,
144*4882a593Smuzhiyun .vl_width = 167,
145*4882a593Smuzhiyun .vl_height = 109,
146*4882a593Smuzhiyun .vl_clkp = CONFIG_SYS_HIGH,
147*4882a593Smuzhiyun .vl_oep = CONFIG_SYS_HIGH,
148*4882a593Smuzhiyun .vl_hsp = CONFIG_SYS_HIGH,
149*4882a593Smuzhiyun .vl_vsp = CONFIG_SYS_HIGH,
150*4882a593Smuzhiyun .vl_dp = CONFIG_SYS_HIGH,
151*4882a593Smuzhiyun .vl_bpix = LCD_BPP,
152*4882a593Smuzhiyun .vl_lbw = 1,
153*4882a593Smuzhiyun .vl_splt = 0,
154*4882a593Smuzhiyun .vl_clor = 1,
155*4882a593Smuzhiyun .vl_tft = 0,
156*4882a593Smuzhiyun .vl_hpw = 1,
157*4882a593Smuzhiyun .vl_blw = 1,
158*4882a593Smuzhiyun .vl_elw = 1,
159*4882a593Smuzhiyun .vl_vpw = 7,
160*4882a593Smuzhiyun .vl_bfw = 0,
161*4882a593Smuzhiyun .vl_efw = 0,
162*4882a593Smuzhiyun };
163*4882a593Smuzhiyun #endif /* CONFIG_HITACHI_SX14 */
164*4882a593Smuzhiyun
165*4882a593Smuzhiyun /*----------------------------------------------------------------------*/
166*4882a593Smuzhiyun #ifdef CONFIG_LMS283GF05
167*4882a593Smuzhiyun
168*4882a593Smuzhiyun # define LCD_BPP LCD_COLOR8
169*4882a593Smuzhiyun /*# define LCD_INVERT_COLORS*/
170*4882a593Smuzhiyun
171*4882a593Smuzhiyun /* you have to set lccr0 and lccr3 (including pcd) */
172*4882a593Smuzhiyun # define REG_LCCR0 0x043008f8
173*4882a593Smuzhiyun # define REG_LCCR3 0x03b00009
174*4882a593Smuzhiyun
175*4882a593Smuzhiyun vidinfo_t panel_info = {
176*4882a593Smuzhiyun .vl_col = 240,
177*4882a593Smuzhiyun .vl_row = 320,
178*4882a593Smuzhiyun .vl_rot = 3,
179*4882a593Smuzhiyun .vl_width = 240,
180*4882a593Smuzhiyun .vl_height = 320,
181*4882a593Smuzhiyun .vl_clkp = CONFIG_SYS_HIGH,
182*4882a593Smuzhiyun .vl_oep = CONFIG_SYS_LOW,
183*4882a593Smuzhiyun .vl_hsp = CONFIG_SYS_LOW,
184*4882a593Smuzhiyun .vl_vsp = CONFIG_SYS_LOW,
185*4882a593Smuzhiyun .vl_dp = CONFIG_SYS_HIGH,
186*4882a593Smuzhiyun .vl_bpix = LCD_BPP,
187*4882a593Smuzhiyun .vl_lbw = 0,
188*4882a593Smuzhiyun .vl_splt = 1,
189*4882a593Smuzhiyun .vl_clor = 1,
190*4882a593Smuzhiyun .vl_tft = 1,
191*4882a593Smuzhiyun .vl_hpw = 4,
192*4882a593Smuzhiyun .vl_blw = 4,
193*4882a593Smuzhiyun .vl_elw = 8,
194*4882a593Smuzhiyun .vl_vpw = 4,
195*4882a593Smuzhiyun .vl_bfw = 4,
196*4882a593Smuzhiyun .vl_efw = 8,
197*4882a593Smuzhiyun };
198*4882a593Smuzhiyun #endif /* CONFIG_LMS283GF05 */
199*4882a593Smuzhiyun
200*4882a593Smuzhiyun /*----------------------------------------------------------------------*/
201*4882a593Smuzhiyun
202*4882a593Smuzhiyun #ifdef CONFIG_ACX517AKN
203*4882a593Smuzhiyun
204*4882a593Smuzhiyun # define LCD_BPP LCD_COLOR8
205*4882a593Smuzhiyun
206*4882a593Smuzhiyun /* you have to set lccr0 and lccr3 (including pcd) */
207*4882a593Smuzhiyun # define REG_LCCR0 0x003008f9
208*4882a593Smuzhiyun # define REG_LCCR3 0x03700006
209*4882a593Smuzhiyun
210*4882a593Smuzhiyun vidinfo_t panel_info = {
211*4882a593Smuzhiyun .vl_col = 320,
212*4882a593Smuzhiyun .vl_row = 320,
213*4882a593Smuzhiyun .vl_width = 320,
214*4882a593Smuzhiyun .vl_height = 320,
215*4882a593Smuzhiyun .vl_clkp = CONFIG_SYS_HIGH,
216*4882a593Smuzhiyun .vl_oep = CONFIG_SYS_LOW,
217*4882a593Smuzhiyun .vl_hsp = CONFIG_SYS_LOW,
218*4882a593Smuzhiyun .vl_vsp = CONFIG_SYS_LOW,
219*4882a593Smuzhiyun .vl_dp = CONFIG_SYS_HIGH,
220*4882a593Smuzhiyun .vl_bpix = LCD_BPP,
221*4882a593Smuzhiyun .vl_lbw = 0,
222*4882a593Smuzhiyun .vl_splt = 1,
223*4882a593Smuzhiyun .vl_clor = 1,
224*4882a593Smuzhiyun .vl_tft = 1,
225*4882a593Smuzhiyun .vl_hpw = 0x04,
226*4882a593Smuzhiyun .vl_blw = 0x1c,
227*4882a593Smuzhiyun .vl_elw = 0x08,
228*4882a593Smuzhiyun .vl_vpw = 0x01,
229*4882a593Smuzhiyun .vl_bfw = 0x07,
230*4882a593Smuzhiyun .vl_efw = 0x08,
231*4882a593Smuzhiyun };
232*4882a593Smuzhiyun #endif /* CONFIG_ACX517AKN */
233*4882a593Smuzhiyun
234*4882a593Smuzhiyun #ifdef CONFIG_ACX544AKN
235*4882a593Smuzhiyun
236*4882a593Smuzhiyun # define LCD_BPP LCD_COLOR16
237*4882a593Smuzhiyun
238*4882a593Smuzhiyun /* you have to set lccr0 and lccr3 (including pcd) */
239*4882a593Smuzhiyun # define REG_LCCR0 0x003008f9
240*4882a593Smuzhiyun # define REG_LCCR3 0x04700007 /* 16bpp */
241*4882a593Smuzhiyun
242*4882a593Smuzhiyun vidinfo_t panel_info = {
243*4882a593Smuzhiyun .vl_col = 320,
244*4882a593Smuzhiyun .vl_row = 320,
245*4882a593Smuzhiyun .vl_width = 320,
246*4882a593Smuzhiyun .vl_height = 320,
247*4882a593Smuzhiyun .vl_clkp = CONFIG_SYS_LOW,
248*4882a593Smuzhiyun .vl_oep = CONFIG_SYS_LOW,
249*4882a593Smuzhiyun .vl_hsp = CONFIG_SYS_LOW,
250*4882a593Smuzhiyun .vl_vsp = CONFIG_SYS_LOW,
251*4882a593Smuzhiyun .vl_dp = CONFIG_SYS_LOW,
252*4882a593Smuzhiyun .vl_bpix = LCD_BPP,
253*4882a593Smuzhiyun .vl_lbw = 0,
254*4882a593Smuzhiyun .vl_splt = 0,
255*4882a593Smuzhiyun .vl_clor = 1,
256*4882a593Smuzhiyun .vl_tft = 1,
257*4882a593Smuzhiyun .vl_hpw = 0x05,
258*4882a593Smuzhiyun .vl_blw = 0x13,
259*4882a593Smuzhiyun .vl_elw = 0x08,
260*4882a593Smuzhiyun .vl_vpw = 0x02,
261*4882a593Smuzhiyun .vl_bfw = 0x07,
262*4882a593Smuzhiyun .vl_efw = 0x05,
263*4882a593Smuzhiyun };
264*4882a593Smuzhiyun #endif /* CONFIG_ACX544AKN */
265*4882a593Smuzhiyun
266*4882a593Smuzhiyun /*----------------------------------------------------------------------*/
267*4882a593Smuzhiyun
268*4882a593Smuzhiyun #ifdef CONFIG_LQ038J7DH53
269*4882a593Smuzhiyun
270*4882a593Smuzhiyun # define LCD_BPP LCD_COLOR8
271*4882a593Smuzhiyun
272*4882a593Smuzhiyun /* you have to set lccr0 and lccr3 (including pcd) */
273*4882a593Smuzhiyun # define REG_LCCR0 0x003008f9
274*4882a593Smuzhiyun # define REG_LCCR3 0x03700004
275*4882a593Smuzhiyun
276*4882a593Smuzhiyun vidinfo_t panel_info = {
277*4882a593Smuzhiyun .vl_col = 320,
278*4882a593Smuzhiyun .vl_row = 480,
279*4882a593Smuzhiyun .vl_width = 320,
280*4882a593Smuzhiyun .vl_height = 480,
281*4882a593Smuzhiyun .vl_clkp = CONFIG_SYS_HIGH,
282*4882a593Smuzhiyun .vl_oep = CONFIG_SYS_LOW,
283*4882a593Smuzhiyun .vl_hsp = CONFIG_SYS_LOW,
284*4882a593Smuzhiyun .vl_vsp = CONFIG_SYS_LOW,
285*4882a593Smuzhiyun .vl_dp = CONFIG_SYS_HIGH,
286*4882a593Smuzhiyun .vl_bpix = LCD_BPP,
287*4882a593Smuzhiyun .vl_lbw = 0,
288*4882a593Smuzhiyun .vl_splt = 1,
289*4882a593Smuzhiyun .vl_clor = 1,
290*4882a593Smuzhiyun .vl_tft = 1,
291*4882a593Smuzhiyun .vl_hpw = 0x04,
292*4882a593Smuzhiyun .vl_blw = 0x20,
293*4882a593Smuzhiyun .vl_elw = 0x01,
294*4882a593Smuzhiyun .vl_vpw = 0x01,
295*4882a593Smuzhiyun .vl_bfw = 0x04,
296*4882a593Smuzhiyun .vl_efw = 0x01,
297*4882a593Smuzhiyun };
298*4882a593Smuzhiyun #endif /* CONFIG_ACX517AKN */
299*4882a593Smuzhiyun
300*4882a593Smuzhiyun /*----------------------------------------------------------------------*/
301*4882a593Smuzhiyun
302*4882a593Smuzhiyun #ifdef CONFIG_LITTLETON_LCD
303*4882a593Smuzhiyun # define LCD_BPP LCD_COLOR8
304*4882a593Smuzhiyun
305*4882a593Smuzhiyun /* you have to set lccr0 and lccr3 (including pcd) */
306*4882a593Smuzhiyun # define REG_LCCR0 0x003008f8
307*4882a593Smuzhiyun # define REG_LCCR3 0x0300FF04
308*4882a593Smuzhiyun
309*4882a593Smuzhiyun vidinfo_t panel_info = {
310*4882a593Smuzhiyun .vl_col = 480,
311*4882a593Smuzhiyun .vl_row = 640,
312*4882a593Smuzhiyun .vl_width = 480,
313*4882a593Smuzhiyun .vl_height = 640,
314*4882a593Smuzhiyun .vl_clkp = CONFIG_SYS_HIGH,
315*4882a593Smuzhiyun .vl_oep = CONFIG_SYS_HIGH,
316*4882a593Smuzhiyun .vl_hsp = CONFIG_SYS_HIGH,
317*4882a593Smuzhiyun .vl_vsp = CONFIG_SYS_HIGH,
318*4882a593Smuzhiyun .vl_dp = CONFIG_SYS_HIGH,
319*4882a593Smuzhiyun .vl_bpix = LCD_BPP,
320*4882a593Smuzhiyun .vl_lbw = 0,
321*4882a593Smuzhiyun .vl_splt = 0,
322*4882a593Smuzhiyun .vl_clor = 0,
323*4882a593Smuzhiyun .vl_tft = 1,
324*4882a593Smuzhiyun .vl_hpw = 9,
325*4882a593Smuzhiyun .vl_blw = 8,
326*4882a593Smuzhiyun .vl_elw = 24,
327*4882a593Smuzhiyun .vl_vpw = 2,
328*4882a593Smuzhiyun .vl_bfw = 2,
329*4882a593Smuzhiyun .vl_efw = 4,
330*4882a593Smuzhiyun };
331*4882a593Smuzhiyun #endif /* CONFIG_LITTLETON_LCD */
332*4882a593Smuzhiyun
333*4882a593Smuzhiyun /*----------------------------------------------------------------------*/
334*4882a593Smuzhiyun
335*4882a593Smuzhiyun static int pxafb_init_mem (void *lcdbase, vidinfo_t *vid);
336*4882a593Smuzhiyun static void pxafb_setup_gpio (vidinfo_t *vid);
337*4882a593Smuzhiyun static void pxafb_enable_controller (vidinfo_t *vid);
338*4882a593Smuzhiyun static int pxafb_init (vidinfo_t *vid);
339*4882a593Smuzhiyun
340*4882a593Smuzhiyun /************************************************************************/
341*4882a593Smuzhiyun /* --------------- PXA chipset specific functions ------------------- */
342*4882a593Smuzhiyun /************************************************************************/
343*4882a593Smuzhiyun
configuration_get_cmap(void)344*4882a593Smuzhiyun ushort *configuration_get_cmap(void)
345*4882a593Smuzhiyun {
346*4882a593Smuzhiyun struct pxafb_info *fbi = &panel_info.pxa;
347*4882a593Smuzhiyun return (ushort *)fbi->palette;
348*4882a593Smuzhiyun }
349*4882a593Smuzhiyun
lcd_ctrl_init(void * lcdbase)350*4882a593Smuzhiyun void lcd_ctrl_init (void *lcdbase)
351*4882a593Smuzhiyun {
352*4882a593Smuzhiyun pxafb_init_mem(lcdbase, &panel_info);
353*4882a593Smuzhiyun pxafb_init(&panel_info);
354*4882a593Smuzhiyun pxafb_setup_gpio(&panel_info);
355*4882a593Smuzhiyun pxafb_enable_controller(&panel_info);
356*4882a593Smuzhiyun }
357*4882a593Smuzhiyun
358*4882a593Smuzhiyun /*----------------------------------------------------------------------*/
359*4882a593Smuzhiyun #if LCD_BPP == LCD_COLOR8
360*4882a593Smuzhiyun void
lcd_setcolreg(ushort regno,ushort red,ushort green,ushort blue)361*4882a593Smuzhiyun lcd_setcolreg (ushort regno, ushort red, ushort green, ushort blue)
362*4882a593Smuzhiyun {
363*4882a593Smuzhiyun struct pxafb_info *fbi = &panel_info.pxa;
364*4882a593Smuzhiyun unsigned short *palette = (unsigned short *)fbi->palette;
365*4882a593Smuzhiyun u_int val;
366*4882a593Smuzhiyun
367*4882a593Smuzhiyun if (regno < fbi->palette_size) {
368*4882a593Smuzhiyun val = ((red << 8) & 0xf800);
369*4882a593Smuzhiyun val |= ((green << 4) & 0x07e0);
370*4882a593Smuzhiyun val |= (blue & 0x001f);
371*4882a593Smuzhiyun
372*4882a593Smuzhiyun #ifdef LCD_INVERT_COLORS
373*4882a593Smuzhiyun palette[regno] = ~val;
374*4882a593Smuzhiyun #else
375*4882a593Smuzhiyun palette[regno] = val;
376*4882a593Smuzhiyun #endif
377*4882a593Smuzhiyun }
378*4882a593Smuzhiyun
379*4882a593Smuzhiyun debug ("setcolreg: reg %2d @ %p: R=%02X G=%02X B=%02X => %04X\n",
380*4882a593Smuzhiyun regno, &palette[regno],
381*4882a593Smuzhiyun red, green, blue,
382*4882a593Smuzhiyun palette[regno]);
383*4882a593Smuzhiyun }
384*4882a593Smuzhiyun #endif /* LCD_COLOR8 */
385*4882a593Smuzhiyun
386*4882a593Smuzhiyun /*----------------------------------------------------------------------*/
lcd_enable(void)387*4882a593Smuzhiyun __weak void lcd_enable(void)
388*4882a593Smuzhiyun {
389*4882a593Smuzhiyun }
390*4882a593Smuzhiyun
391*4882a593Smuzhiyun /************************************************************************/
392*4882a593Smuzhiyun /* ** PXA255 specific routines */
393*4882a593Smuzhiyun /************************************************************************/
394*4882a593Smuzhiyun
395*4882a593Smuzhiyun /*
396*4882a593Smuzhiyun * Calculate fb size for VIDEOLFB_ATAG. Size returned contains fb,
397*4882a593Smuzhiyun * descriptors and palette areas.
398*4882a593Smuzhiyun */
calc_fbsize(void)399*4882a593Smuzhiyun ulong calc_fbsize (void)
400*4882a593Smuzhiyun {
401*4882a593Smuzhiyun ulong size;
402*4882a593Smuzhiyun int line_length = (panel_info.vl_col * NBITS (panel_info.vl_bpix)) / 8;
403*4882a593Smuzhiyun
404*4882a593Smuzhiyun size = line_length * panel_info.vl_row;
405*4882a593Smuzhiyun size += PAGE_SIZE;
406*4882a593Smuzhiyun
407*4882a593Smuzhiyun return size;
408*4882a593Smuzhiyun }
409*4882a593Smuzhiyun
pxafb_init_mem(void * lcdbase,vidinfo_t * vid)410*4882a593Smuzhiyun static int pxafb_init_mem (void *lcdbase, vidinfo_t *vid)
411*4882a593Smuzhiyun {
412*4882a593Smuzhiyun u_long palette_mem_size;
413*4882a593Smuzhiyun struct pxafb_info *fbi = &vid->pxa;
414*4882a593Smuzhiyun int fb_size = vid->vl_row * (vid->vl_col * NBITS (vid->vl_bpix)) / 8;
415*4882a593Smuzhiyun
416*4882a593Smuzhiyun fbi->screen = (u_long)lcdbase;
417*4882a593Smuzhiyun
418*4882a593Smuzhiyun fbi->palette_size = NBITS(vid->vl_bpix) == 8 ? 256 : 16;
419*4882a593Smuzhiyun palette_mem_size = fbi->palette_size * sizeof(u16);
420*4882a593Smuzhiyun
421*4882a593Smuzhiyun debug("palette_mem_size = 0x%08lx\n", (u_long) palette_mem_size);
422*4882a593Smuzhiyun /* locate palette and descs at end of page following fb */
423*4882a593Smuzhiyun fbi->palette = (u_long)lcdbase + fb_size + PAGE_SIZE - palette_mem_size;
424*4882a593Smuzhiyun
425*4882a593Smuzhiyun return 0;
426*4882a593Smuzhiyun }
427*4882a593Smuzhiyun #ifdef CONFIG_CPU_MONAHANS
pxafb_setup_gpio(vidinfo_t * vid)428*4882a593Smuzhiyun static inline void pxafb_setup_gpio (vidinfo_t *vid) {}
429*4882a593Smuzhiyun #else
pxafb_setup_gpio(vidinfo_t * vid)430*4882a593Smuzhiyun static void pxafb_setup_gpio (vidinfo_t *vid)
431*4882a593Smuzhiyun {
432*4882a593Smuzhiyun u_long lccr0;
433*4882a593Smuzhiyun
434*4882a593Smuzhiyun /*
435*4882a593Smuzhiyun * setup is based on type of panel supported
436*4882a593Smuzhiyun */
437*4882a593Smuzhiyun
438*4882a593Smuzhiyun lccr0 = vid->pxa.reg_lccr0;
439*4882a593Smuzhiyun
440*4882a593Smuzhiyun /* 4 bit interface */
441*4882a593Smuzhiyun if ((lccr0 & LCCR0_CMS) && (lccr0 & LCCR0_SDS) && !(lccr0 & LCCR0_DPD))
442*4882a593Smuzhiyun {
443*4882a593Smuzhiyun debug("Setting GPIO for 4 bit data\n");
444*4882a593Smuzhiyun /* bits 58-61 */
445*4882a593Smuzhiyun writel(readl(GPDR1) | (0xf << 26), GPDR1);
446*4882a593Smuzhiyun writel((readl(GAFR1_U) & ~(0xff << 20)) | (0xaa << 20),
447*4882a593Smuzhiyun GAFR1_U);
448*4882a593Smuzhiyun
449*4882a593Smuzhiyun /* bits 74-77 */
450*4882a593Smuzhiyun writel(readl(GPDR2) | (0xf << 10), GPDR2);
451*4882a593Smuzhiyun writel((readl(GAFR2_L) & ~(0xff << 20)) | (0xaa << 20),
452*4882a593Smuzhiyun GAFR2_L);
453*4882a593Smuzhiyun }
454*4882a593Smuzhiyun
455*4882a593Smuzhiyun /* 8 bit interface */
456*4882a593Smuzhiyun else if (((lccr0 & LCCR0_CMS) && ((lccr0 & LCCR0_SDS) || (lccr0 & LCCR0_DPD))) ||
457*4882a593Smuzhiyun (!(lccr0 & LCCR0_CMS) && !(lccr0 & LCCR0_PAS) && !(lccr0 & LCCR0_SDS)))
458*4882a593Smuzhiyun {
459*4882a593Smuzhiyun debug("Setting GPIO for 8 bit data\n");
460*4882a593Smuzhiyun /* bits 58-65 */
461*4882a593Smuzhiyun writel(readl(GPDR1) | (0x3f << 26), GPDR1);
462*4882a593Smuzhiyun writel(readl(GPDR2) | (0x3), GPDR2);
463*4882a593Smuzhiyun
464*4882a593Smuzhiyun writel((readl(GAFR1_U) & ~(0xfff << 20)) | (0xaaa << 20),
465*4882a593Smuzhiyun GAFR1_U);
466*4882a593Smuzhiyun writel((readl(GAFR2_L) & ~0xf) | (0xa), GAFR2_L);
467*4882a593Smuzhiyun
468*4882a593Smuzhiyun /* bits 74-77 */
469*4882a593Smuzhiyun writel(readl(GPDR2) | (0xf << 10), GPDR2);
470*4882a593Smuzhiyun writel((readl(GAFR2_L) & ~(0xff << 20)) | (0xaa << 20),
471*4882a593Smuzhiyun GAFR2_L);
472*4882a593Smuzhiyun }
473*4882a593Smuzhiyun
474*4882a593Smuzhiyun /* 16 bit interface */
475*4882a593Smuzhiyun else if (!(lccr0 & LCCR0_CMS) && ((lccr0 & LCCR0_SDS) || (lccr0 & LCCR0_PAS)))
476*4882a593Smuzhiyun {
477*4882a593Smuzhiyun debug("Setting GPIO for 16 bit data\n");
478*4882a593Smuzhiyun /* bits 58-77 */
479*4882a593Smuzhiyun writel(readl(GPDR1) | (0x3f << 26), GPDR1);
480*4882a593Smuzhiyun writel(readl(GPDR2) | 0x00003fff, GPDR2);
481*4882a593Smuzhiyun
482*4882a593Smuzhiyun writel((readl(GAFR1_U) & ~(0xfff << 20)) | (0xaaa << 20),
483*4882a593Smuzhiyun GAFR1_U);
484*4882a593Smuzhiyun writel((readl(GAFR2_L) & 0xf0000000) | 0x0aaaaaaa, GAFR2_L);
485*4882a593Smuzhiyun }
486*4882a593Smuzhiyun else
487*4882a593Smuzhiyun {
488*4882a593Smuzhiyun printf("pxafb_setup_gpio: unable to determine bits per pixel\n");
489*4882a593Smuzhiyun }
490*4882a593Smuzhiyun }
491*4882a593Smuzhiyun #endif
492*4882a593Smuzhiyun
pxafb_enable_controller(vidinfo_t * vid)493*4882a593Smuzhiyun static void pxafb_enable_controller (vidinfo_t *vid)
494*4882a593Smuzhiyun {
495*4882a593Smuzhiyun debug("Enabling LCD controller\n");
496*4882a593Smuzhiyun
497*4882a593Smuzhiyun /* Sequence from 11.7.10 */
498*4882a593Smuzhiyun writel(vid->pxa.reg_lccr3, LCCR3);
499*4882a593Smuzhiyun writel(vid->pxa.reg_lccr2, LCCR2);
500*4882a593Smuzhiyun writel(vid->pxa.reg_lccr1, LCCR1);
501*4882a593Smuzhiyun writel(vid->pxa.reg_lccr0 & ~LCCR0_ENB, LCCR0);
502*4882a593Smuzhiyun writel(vid->pxa.fdadr0, FDADR0);
503*4882a593Smuzhiyun writel(vid->pxa.fdadr1, FDADR1);
504*4882a593Smuzhiyun writel(readl(LCCR0) | LCCR0_ENB, LCCR0);
505*4882a593Smuzhiyun
506*4882a593Smuzhiyun #ifdef CONFIG_CPU_MONAHANS
507*4882a593Smuzhiyun writel(readl(CKENA) | CKENA_1_LCD, CKENA);
508*4882a593Smuzhiyun #else
509*4882a593Smuzhiyun writel(readl(CKEN) | CKEN16_LCD, CKEN);
510*4882a593Smuzhiyun #endif
511*4882a593Smuzhiyun
512*4882a593Smuzhiyun debug("FDADR0 = 0x%08x\n", readl(FDADR0));
513*4882a593Smuzhiyun debug("FDADR1 = 0x%08x\n", readl(FDADR1));
514*4882a593Smuzhiyun debug("LCCR0 = 0x%08x\n", readl(LCCR0));
515*4882a593Smuzhiyun debug("LCCR1 = 0x%08x\n", readl(LCCR1));
516*4882a593Smuzhiyun debug("LCCR2 = 0x%08x\n", readl(LCCR2));
517*4882a593Smuzhiyun debug("LCCR3 = 0x%08x\n", readl(LCCR3));
518*4882a593Smuzhiyun }
519*4882a593Smuzhiyun
pxafb_init(vidinfo_t * vid)520*4882a593Smuzhiyun static int pxafb_init (vidinfo_t *vid)
521*4882a593Smuzhiyun {
522*4882a593Smuzhiyun struct pxafb_info *fbi = &vid->pxa;
523*4882a593Smuzhiyun
524*4882a593Smuzhiyun debug("Configuring PXA LCD\n");
525*4882a593Smuzhiyun
526*4882a593Smuzhiyun fbi->reg_lccr0 = REG_LCCR0;
527*4882a593Smuzhiyun fbi->reg_lccr3 = REG_LCCR3;
528*4882a593Smuzhiyun
529*4882a593Smuzhiyun debug("vid: vl_col=%d hslen=%d lm=%d rm=%d\n",
530*4882a593Smuzhiyun vid->vl_col, vid->vl_hpw,
531*4882a593Smuzhiyun vid->vl_blw, vid->vl_elw);
532*4882a593Smuzhiyun debug("vid: vl_row=%d vslen=%d um=%d bm=%d\n",
533*4882a593Smuzhiyun vid->vl_row, vid->vl_vpw,
534*4882a593Smuzhiyun vid->vl_bfw, vid->vl_efw);
535*4882a593Smuzhiyun
536*4882a593Smuzhiyun fbi->reg_lccr1 =
537*4882a593Smuzhiyun LCCR1_DisWdth(vid->vl_col) +
538*4882a593Smuzhiyun LCCR1_HorSnchWdth(vid->vl_hpw) +
539*4882a593Smuzhiyun LCCR1_BegLnDel(vid->vl_blw) +
540*4882a593Smuzhiyun LCCR1_EndLnDel(vid->vl_elw);
541*4882a593Smuzhiyun
542*4882a593Smuzhiyun fbi->reg_lccr2 =
543*4882a593Smuzhiyun LCCR2_DisHght(vid->vl_row) +
544*4882a593Smuzhiyun LCCR2_VrtSnchWdth(vid->vl_vpw) +
545*4882a593Smuzhiyun LCCR2_BegFrmDel(vid->vl_bfw) +
546*4882a593Smuzhiyun LCCR2_EndFrmDel(vid->vl_efw);
547*4882a593Smuzhiyun
548*4882a593Smuzhiyun fbi->reg_lccr3 = REG_LCCR3 & ~(LCCR3_HSP | LCCR3_VSP);
549*4882a593Smuzhiyun fbi->reg_lccr3 |= (vid->vl_hsp ? LCCR3_HorSnchL : LCCR3_HorSnchH)
550*4882a593Smuzhiyun | (vid->vl_vsp ? LCCR3_VrtSnchL : LCCR3_VrtSnchH);
551*4882a593Smuzhiyun
552*4882a593Smuzhiyun
553*4882a593Smuzhiyun /* setup dma descriptors */
554*4882a593Smuzhiyun fbi->dmadesc_fblow = (struct pxafb_dma_descriptor *)((unsigned int)fbi->palette - 3*16);
555*4882a593Smuzhiyun fbi->dmadesc_fbhigh = (struct pxafb_dma_descriptor *)((unsigned int)fbi->palette - 2*16);
556*4882a593Smuzhiyun fbi->dmadesc_palette = (struct pxafb_dma_descriptor *)((unsigned int)fbi->palette - 1*16);
557*4882a593Smuzhiyun
558*4882a593Smuzhiyun #define BYTES_PER_PANEL ((fbi->reg_lccr0 & LCCR0_SDS) ? \
559*4882a593Smuzhiyun (vid->vl_col * vid->vl_row * NBITS(vid->vl_bpix) / 8 / 2) : \
560*4882a593Smuzhiyun (vid->vl_col * vid->vl_row * NBITS(vid->vl_bpix) / 8))
561*4882a593Smuzhiyun
562*4882a593Smuzhiyun /* populate descriptors */
563*4882a593Smuzhiyun fbi->dmadesc_fblow->fdadr = (u_long)fbi->dmadesc_fblow;
564*4882a593Smuzhiyun fbi->dmadesc_fblow->fsadr = fbi->screen + BYTES_PER_PANEL;
565*4882a593Smuzhiyun fbi->dmadesc_fblow->fidr = 0;
566*4882a593Smuzhiyun fbi->dmadesc_fblow->ldcmd = BYTES_PER_PANEL;
567*4882a593Smuzhiyun
568*4882a593Smuzhiyun fbi->fdadr1 = (u_long)fbi->dmadesc_fblow; /* only used in dual-panel mode */
569*4882a593Smuzhiyun
570*4882a593Smuzhiyun fbi->dmadesc_fbhigh->fsadr = fbi->screen;
571*4882a593Smuzhiyun fbi->dmadesc_fbhigh->fidr = 0;
572*4882a593Smuzhiyun fbi->dmadesc_fbhigh->ldcmd = BYTES_PER_PANEL;
573*4882a593Smuzhiyun
574*4882a593Smuzhiyun fbi->dmadesc_palette->fsadr = fbi->palette;
575*4882a593Smuzhiyun fbi->dmadesc_palette->fidr = 0;
576*4882a593Smuzhiyun fbi->dmadesc_palette->ldcmd = (fbi->palette_size * 2) | LDCMD_PAL;
577*4882a593Smuzhiyun
578*4882a593Smuzhiyun if( NBITS(vid->vl_bpix) < 12)
579*4882a593Smuzhiyun {
580*4882a593Smuzhiyun /* assume any mode with <12 bpp is palette driven */
581*4882a593Smuzhiyun fbi->dmadesc_palette->fdadr = (u_long)fbi->dmadesc_fbhigh;
582*4882a593Smuzhiyun fbi->dmadesc_fbhigh->fdadr = (u_long)fbi->dmadesc_palette;
583*4882a593Smuzhiyun /* flips back and forth between pal and fbhigh */
584*4882a593Smuzhiyun fbi->fdadr0 = (u_long)fbi->dmadesc_palette;
585*4882a593Smuzhiyun }
586*4882a593Smuzhiyun else
587*4882a593Smuzhiyun {
588*4882a593Smuzhiyun /* palette shouldn't be loaded in true-color mode */
589*4882a593Smuzhiyun fbi->dmadesc_fbhigh->fdadr = (u_long)fbi->dmadesc_fbhigh;
590*4882a593Smuzhiyun fbi->fdadr0 = (u_long)fbi->dmadesc_fbhigh; /* no pal just fbhigh */
591*4882a593Smuzhiyun }
592*4882a593Smuzhiyun
593*4882a593Smuzhiyun debug("fbi->dmadesc_fblow = 0x%lx\n", (u_long)fbi->dmadesc_fblow);
594*4882a593Smuzhiyun debug("fbi->dmadesc_fbhigh = 0x%lx\n", (u_long)fbi->dmadesc_fbhigh);
595*4882a593Smuzhiyun debug("fbi->dmadesc_palette = 0x%lx\n", (u_long)fbi->dmadesc_palette);
596*4882a593Smuzhiyun
597*4882a593Smuzhiyun debug("fbi->dmadesc_fblow->fdadr = 0x%lx\n", fbi->dmadesc_fblow->fdadr);
598*4882a593Smuzhiyun debug("fbi->dmadesc_fbhigh->fdadr = 0x%lx\n", fbi->dmadesc_fbhigh->fdadr);
599*4882a593Smuzhiyun debug("fbi->dmadesc_palette->fdadr = 0x%lx\n", fbi->dmadesc_palette->fdadr);
600*4882a593Smuzhiyun
601*4882a593Smuzhiyun debug("fbi->dmadesc_fblow->fsadr = 0x%lx\n", fbi->dmadesc_fblow->fsadr);
602*4882a593Smuzhiyun debug("fbi->dmadesc_fbhigh->fsadr = 0x%lx\n", fbi->dmadesc_fbhigh->fsadr);
603*4882a593Smuzhiyun debug("fbi->dmadesc_palette->fsadr = 0x%lx\n", fbi->dmadesc_palette->fsadr);
604*4882a593Smuzhiyun
605*4882a593Smuzhiyun debug("fbi->dmadesc_fblow->ldcmd = 0x%lx\n", fbi->dmadesc_fblow->ldcmd);
606*4882a593Smuzhiyun debug("fbi->dmadesc_fbhigh->ldcmd = 0x%lx\n", fbi->dmadesc_fbhigh->ldcmd);
607*4882a593Smuzhiyun debug("fbi->dmadesc_palette->ldcmd = 0x%lx\n", fbi->dmadesc_palette->ldcmd);
608*4882a593Smuzhiyun
609*4882a593Smuzhiyun return 0;
610*4882a593Smuzhiyun }
611*4882a593Smuzhiyun
612*4882a593Smuzhiyun /************************************************************************/
613*4882a593Smuzhiyun /************************************************************************/
614*4882a593Smuzhiyun
615*4882a593Smuzhiyun #endif /* CONFIG_LCD */
616