tizen 2.4 release
[profile/mobile/platform/kernel/u-boot-tm1.git] / drivers / video / sc8825fb / sprdfb_dispc.c
1 /******************************************************************************
2  ** File Name:    sprdfb_dispc.c                                            *
3  ** Author:                                                           *
4  ** DATE:                                                           *
5  ** Copyright:    2005 Spreatrum, Incoporated. All Rights Reserved.           *
6  ** Description:                                                            *
7  ******************************************************************************/
8 /******************************************************************************
9  **                   Edit    History                                         *
10  **---------------------------------------------------------------------------*
11  ** DATE          NAME            DESCRIPTION                                 *
12  **
13  ******************************************************************************/
14
15 #include <common.h>
16
17 #include <asm/arch/tiger_lcd.h>
18 #include <asm/arch/dispc_reg.h>
19 #include <asm/arch/sc8810_reg_ahb.h>
20 #include <asm/arch/sc8810_reg_global.h>
21
22 #include <asm/arch/regs_global.h>
23
24 #include "sprdfb.h"
25
26
27 #ifdef CONFIG_SC7710G2
28 #define DISPC_SOFT_RST (20)
29 #else
30 #define DISPC_SOFT_RST (2)
31 #endif
32
33 static uint16_t         is_first_frame = 1;
34
35 extern void sprdfb_panel_before_refresh(struct sprdfb_device *dev);
36 extern void sprdfb_panel_after_refresh(struct sprdfb_device *dev);
37 extern void sprdfb_panel_invalidate(struct panel_spec *self);
38 extern void sprdfb_panel_invalidate_rect(struct panel_spec *self,
39                                 uint16_t left, uint16_t top,
40                                 uint16_t right, uint16_t bottom);
41
42 static void __raw_bits_and(unsigned int v, unsigned int a)
43 {
44         __raw_writel((__raw_readl(a) & v), a);
45 }
46
47 static void __raw_bits_or(unsigned int v, unsigned int a)
48 {
49         __raw_writel((__raw_readl(a) | v), a);
50 }
51
52 /* dispc soft reset */
53 static void dispc_reset(void)
54 {
55         FB_PRINT("sprdfb:[%s]\n",__FUNCTION__);
56 #ifdef CONFIG_SC7710G2
57         __raw_writel(__raw_readl(AHB_SOFT2_RST) | (1<<DISPC_SOFT_RST), AHB_SOFT2_RST);
58         udelay(10);
59         __raw_writel(__raw_readl(AHB_SOFT2_RST) & (~(1<<DISPC_SOFT_RST)), AHB_SOFT2_RST);
60 #else
61         __raw_writel(__raw_readl(AHB_SOFT_RST) | (1<<DISPC_SOFT_RST), AHB_SOFT_RST);
62         udelay(10);
63         __raw_writel(__raw_readl(AHB_SOFT_RST) & (~(1<<DISPC_SOFT_RST)), AHB_SOFT_RST);
64 #endif
65 }
66
67 static inline void dispc_set_bg_color(uint32_t bg_color)
68 {
69         FB_PRINT("sprdfb:[%s]\n",__FUNCTION__);
70
71         dispc_write(bg_color, DISPC_BG_COLOR);
72 }
73
74 static inline void dispc_set_osd_ck(uint32_t ck_color)
75 {
76         FB_PRINT("sprdfb:[%s]\n",__FUNCTION__);
77
78         dispc_write(ck_color, DISPC_OSD_CK);
79 }
80
81 static void dispc_dithering_enable(uint16_t enable)
82 {
83         FB_PRINT("sprdfb:[%s]\n",__FUNCTION__);
84
85         if(enable){
86                 dispc_set_bits((1<<6), DISPC_CTRL);
87         }else{
88                 dispc_clear_bits((1<<6), DISPC_CTRL);
89         }
90 }
91
92 static void dispc_set_exp_mode(uint16_t exp_mode)
93 {
94         uint32_t reg_val = dispc_read(DISPC_CTRL);
95
96         FB_PRINT("sprdfb:[%s]\n",__FUNCTION__);
97
98         reg_val &= ~(0x3 << 16);
99         reg_val |= (exp_mode << 16);
100         dispc_write(reg_val, DISPC_CTRL);
101 }
102
103 static void dispc_module_enable(void)
104 {
105         FB_PRINT("sprdfb:[%s]\n",__FUNCTION__);
106
107         /*dispc module enable */
108         dispc_write((1<<0), DISPC_CTRL);
109
110         /*disable dispc INT*/
111         dispc_write(0x0, DISPC_INT_EN);
112
113         /* clear dispc INT */
114         dispc_write(0x1F, DISPC_INT_CLR);
115 }
116
117 static inline int32_t  dispc_set_disp_size(struct sprdfb_device *dev)
118 {
119         uint32_t reg_val;
120
121         FB_PRINT("sprdfb:[%s]\n",__FUNCTION__);
122
123         reg_val = (dev->panel->width& 0xfff) | ((dev->panel->height & 0xfff ) << 16);
124         dispc_write(reg_val, DISPC_SIZE_XY);
125
126         return 0;
127 }
128
129 static void dispc_layer_init(struct sprdfb_device *dev)
130 {
131         uint32_t reg_val = 0;
132
133         FB_PRINT("sprdfb:[%s]\n",__FUNCTION__);
134
135         dispc_clear_bits((1<<0),DISPC_IMG_CTRL);
136         dispc_clear_bits((1<<0),DISPC_OSD_CTRL);
137
138         /******************* OSD layer setting **********************/
139
140         /*enable OSD layer*/
141         reg_val |= (1 << 0);
142
143         /*disable  color key */
144
145         /* alpha mode select  - block alpha*/
146         reg_val |= (1 << 2);
147
148         /* data format */
149         /* RGB565 */
150         reg_val |= (5 << 4);
151         /* B2B3B0B1 */
152         reg_val |= (2 << 8);
153
154         dispc_write(reg_val, DISPC_OSD_CTRL);
155
156         /* OSD layer alpha value */
157         dispc_write(0xff, DISPC_OSD_ALPHA);
158
159         /* OSD layer size */
160         reg_val = ( dev->panel->width& 0xfff) | ((dev->panel->height & 0xfff ) << 16);
161         dispc_write(reg_val, DISPC_OSD_SIZE_XY);
162
163         /* OSD layer start position */
164         dispc_write(0, DISPC_OSD_DISP_XY);
165
166         /* OSD layer pitch */
167         reg_val = ( dev->panel->width & 0xfff) ;
168         dispc_write(reg_val, DISPC_OSD_PITCH);
169
170         /*OSD base address*/
171         dispc_write(dev->smem_start, DISPC_OSD_BASE_ADDR);
172
173         /* OSD color_key value */
174         dispc_set_osd_ck(0x0);
175
176         /* DISPC workplane size */
177         dispc_set_disp_size(dev);
178
179         FB_PRINT("DISPC_OSD_CTRL: 0x%x\n", dispc_read(DISPC_OSD_CTRL));
180         FB_PRINT("DISPC_OSD_ALPHA: 0x%x\n", dispc_read(DISPC_OSD_ALPHA));
181         FB_PRINT("DISPC_OSD_SIZE_XY: 0x%x\n", dispc_read(DISPC_OSD_SIZE_XY));
182         FB_PRINT("DISPC_OSD_DISP_XY: 0x%x\n", dispc_read(DISPC_OSD_DISP_XY));
183         FB_PRINT("DISPC_OSD_PITCH: 0x%x\n", dispc_read(DISPC_OSD_PITCH));
184         FB_PRINT("DISPC_OSD_BASE_ADDR: 0x%x\n", dispc_read(DISPC_OSD_BASE_ADDR));
185 }
186
187 static int32_t sprdfb_dispc_early_init(struct sprdfb_device *dev)
188 {
189         FB_PRINT("sprdfb:[%s]\n", __FUNCTION__);
190 #ifdef CONFIG_SC7710G2
191         //select DISPC clock source
192         __raw_bits_and(~(1<<31), AHB_CTL6);    //pll_src=256M
193         __raw_bits_and(~(1<<30), AHB_CTL6);
194
195         //set DISPC divdior
196         __raw_bits_and(~(1<<29), AHB_CTL6);  //div=0
197         __raw_bits_and(~(1<<28), AHB_CTL6);
198         __raw_bits_and(~(1<<27), AHB_CTL6);
199
200         //select DBI clock source
201         __raw_bits_and(~(1<<26), AHB_CTL6);    //pll_src=256M
202         __raw_bits_and(~(1<<25), AHB_CTL6);
203
204         //set DBI divdior
205         __raw_bits_and(~(1<<24), AHB_CTL6);  //div=0
206         __raw_bits_and(~(1<<23), AHB_CTL6);
207         __raw_bits_and(~(1<<22), AHB_CTL6);
208
209         //select DPI clock source
210         __raw_bits_and(~(1<<21), AHB_CTL6);    //pll_src=384M
211         __raw_bits_and(~(1<<20), AHB_CTL6);
212
213         //set DPI divdior
214         __raw_bits_and(~(1<<19), AHB_CTL6);  //div=10, dpi_clk = pll_src/(10+1)
215         __raw_bits_and(~(1<<18), AHB_CTL6);
216         __raw_bits_and(~(1<<17), AHB_CTL6);
217         __raw_bits_and(~(1<<16), AHB_CTL6);
218         __raw_bits_or((1<<15), AHB_CTL6);
219         __raw_bits_and(~(1<<14), AHB_CTL6);
220         __raw_bits_or((1<<13), AHB_CTL6);
221         __raw_bits_and(~(1<<12), AHB_CTL6);
222
223         //enable DISPC clock
224         __raw_bits_or(1<<0, AHB_CTL6);
225
226         printf("0x2090023c = 0x%x\n", __raw_readl(0x2090023c));
227 #else
228         //select DISPC clock source
229         __raw_bits_and(~(1<<1), AHB_DISPC_CLK);    //pll_src=256M
230         __raw_bits_and(~(1<<2), AHB_DISPC_CLK);
231
232         //set DISPC divdior
233         __raw_bits_and(~(1<<3), AHB_DISPC_CLK);  //div=0
234         __raw_bits_and(~(1<<4), AHB_DISPC_CLK);
235         __raw_bits_and(~(1<<5), AHB_DISPC_CLK);
236
237         //select DBI clock source
238         __raw_bits_and(~(1<<9), AHB_DISPC_CLK);    //pll_src=256M
239         __raw_bits_and(~(1<<10), AHB_DISPC_CLK);
240
241         //set DBI divdior
242         __raw_bits_and(~(1<<11), AHB_DISPC_CLK);  //div=0
243         __raw_bits_and(~(1<<12), AHB_DISPC_CLK);
244         __raw_bits_and(~(1<<13), AHB_DISPC_CLK);
245
246         //select DPI clock source
247         __raw_bits_and(~(1<<17), AHB_DISPC_CLK);    //pll_src=384M
248         __raw_bits_and(~(1<<18), AHB_DISPC_CLK);
249
250         //set DPI divdior
251         __raw_bits_and(~(1<<19), AHB_DISPC_CLK);  //div=10, dpi_clk = pll_src/(10+1)
252         __raw_bits_or((1<<20), AHB_DISPC_CLK);
253         __raw_bits_and(~(1<<21), AHB_DISPC_CLK);
254         __raw_bits_or((1<<22), AHB_DISPC_CLK);
255         __raw_bits_and(~(1<<23), AHB_DISPC_CLK);
256         __raw_bits_and(~(1<<24), AHB_DISPC_CLK);
257         __raw_bits_and(~(1<<25), AHB_DISPC_CLK);
258         __raw_bits_and(~(1<<26), AHB_DISPC_CLK);
259
260         //enable dispc matric clock
261         __raw_bits_or((1<<9), AHB_CTL2);  //core_clock_en
262         __raw_bits_or((1<<11), AHB_CTL2);  //matrix clock en
263
264         //enable DISPC clock
265         __raw_bits_or(1<<22, AHB_CTL0);
266
267         printf("0x20900200 = 0x%x\n", __raw_readl(0x20900200));
268         printf("0x20900208 = 0x%x\n", __raw_readl(0x20900208));
269         printf("0x20900220 = 0x%x\n", __raw_readl(0x20900220));
270 #endif
271
272         dispc_reset();
273         dispc_module_enable();
274         is_first_frame = 1;
275
276         return 0;
277 }
278
279
280 static int32_t sprdfb_dispc_init(struct sprdfb_device *dev)
281 {
282         FB_PRINT("sprdfb:[%s]\n",__FUNCTION__);
283
284         /*set bg color*/
285         dispc_set_bg_color(0xFFFFFFFF);
286         /*enable dithering*/
287         dispc_dithering_enable(1);
288         /*use MSBs as img exp mode*/
289         dispc_set_exp_mode(0x0);
290
291         dispc_layer_init(dev);
292
293         if(SPRDFB_PANEL_IF_DPI == dev->panel_if_type){
294                 if(is_first_frame){
295                         /*set dpi register update only with SW*/
296                         dispc_set_bits((1<<4), DISPC_DPI_CTRL);
297                 }else{
298                         /*set dpi register update with SW & VSYNC*/
299                         dispc_clear_bits((1<<4), DISPC_DPI_CTRL);
300                 }
301                 /*enable dispc update done INT*/
302 //              dispc_write((1<<4), DISPC_INT_EN);
303         }else{
304                 /* enable dispc DONE  INT*/
305 //              dispc_write((1<<0), DISPC_INT_EN);
306         }
307         return 0;
308 }
309
310 static int32_t sprdfb_dispc_uninit(struct sprdfb_device *dev)
311 {
312         FB_PRINT("sprdfb:[%s]\n",__FUNCTION__);
313 #ifdef CONFIG_SC7710G2
314         //disable DISPC clock
315         __raw_bits_and(~(1<<0), AHB_CTL6);
316 #else
317         //disable DISPC clock
318         __raw_bits_and(~(1<<22), AHB_CTL0);
319 #endif
320         return 0;
321 }
322
323 static int32_t sprdfb_dispc_refresh (struct sprdfb_device *dev)
324 {
325         FB_PRINT("sprdfb:[%s]\n",__FUNCTION__);
326         uint32_t i;
327
328         if(SPRDFB_PANEL_IF_DPI != dev->panel_if_type){
329                 sprdfb_panel_invalidate(dev->panel);
330         }
331
332         sprdfb_panel_before_refresh(dev);
333
334         if(SPRDFB_PANEL_IF_DPI == dev->panel_if_type){
335                 //dispc_write(0x0, DISPC_OSD_CTRL);
336                 //dispc_write(0x0, DISPC_BG_COLOR);
337                 /*dpi register update*/
338                 dispc_set_bits((1<<5), DISPC_DPI_CTRL);
339                 if(is_first_frame){
340                         udelay(30);
341                         /*dpi register update with SW and VSync*/
342                         dispc_clear_bits((1<<4), DISPC_DPI_CTRL);
343                         /* start refresh */
344                         dispc_set_bits((1 << 4), DISPC_CTRL);
345                         is_first_frame = 0;
346                 }else{
347                         for(i=0;i<1000;i++){
348                                 if(!(dispc_read(DISPC_INT_RAW) & (0x10))){
349                                         udelay(100);
350                                 }else{
351                                         break;
352                                 }
353                         }
354                         if(i >= 1000){
355                                 FB_PRINT("sprdfb:[%s] wait dispc update  int time out!! (0x%x)\n", __FUNCTION__, dispc_read(DISPC_INT_RAW));
356                         }else{
357                                 FB_PRINT("sprdfb:[%s] got dispc update int (0x%x)\n", __FUNCTION__, dispc_read(DISPC_INT_RAW));
358                         }
359                         dispc_set_bits((1<<5), DISPC_INT_CLR);
360                    }
361         }else{
362                 /* start refresh */
363                 dispc_set_bits((1 << 4), DISPC_CTRL);
364                 for(i=0;i<500;i++){
365                         if(0x1 != (dispc_read(DISPC_INT_RAW) & (1<<0))){
366                                 udelay(1000);
367                         }else{
368                                 break;
369                         }
370                 }
371                 if(i >= 1000){
372                         FB_PRINT("sprdfb:[%s] wait dispc done int time out!! (0x%x)\n", __FUNCTION__, dispc_read(DISPC_INT_RAW));
373                 }else{
374                         FB_PRINT("sprdfb:[%s] got dispc done int (0x%x)\n", __FUNCTION__, dispc_read(DISPC_INT_RAW));
375                 }
376                 dispc_set_bits((1<<0), DISPC_INT_CLR);
377         }
378
379         sprdfb_panel_after_refresh(dev);
380
381         return 0;
382 }
383
384 struct display_ctrl sprdfb_dispc_ctrl = {
385         .name           = "dispc",
386         .early_init             = sprdfb_dispc_early_init,
387         .init                   = sprdfb_dispc_init,
388         .uninit         = sprdfb_dispc_uninit,
389         .refresh                = sprdfb_dispc_refresh,
390 };
391