tizen 2.4 release
[profile/mobile/platform/kernel/u-boot-tm1.git] / drivers / video / sprdfb / lcd / lcd_st7789v_mcu.c
1 /* drivers/video/sprdfb/lcd_st7789v.c
2  *
3  * Support for st7789v LCD device
4  *
5  * Copyright (C) 2010 Spreadtrum
6  *
7  * This software is licensed under the terms of the GNU General Public
8  * License version 2, as published by the Free Software Foundation, and
9  * may be copied, distributed, and modified under those terms.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  */
16
17 #include <asm/arch/sprd_lcd.h>
18 #include "../sprdfb.h"
19
20 #define printk printf
21
22 #define  LCD_DEBUG
23 #ifdef LCD_DEBUG
24 #define LCD_PRINT printk
25 #else
26 #define LCD_PRINT(...)
27 #endif
28
29 #define ST7789V_BUS_WIDTH_8BIT  // bus_width = 8
30
31 static int32_t st7789v_init(struct panel_spec *self)
32 {
33         send_data_t send_cmd = self->info.mcu->ops->send_cmd;
34         send_data_t send_data = self->info.mcu->ops->send_data;
35
36         LCD_PRINT("st7789v_init\n");
37
38         //Power setting sequence
39         send_cmd(0x11);
40         mdelay(120);
41
42 #if defined(ST7789V_BUS_WIDTH_8BIT)
43     send_cmd(0xDF);
44     send_data(0x5A69);
45     send_data(0x0201);
46
47     send_cmd(0x36);
48     send_data(0x0000);
49
50     send_cmd(0x3a);
51     send_data(0x0500);
52
53     send_cmd(0x35);
54     send_data(0x0000);
55
56     send_cmd(0xd2);
57     send_data(0x4c00);
58
59     send_cmd(0xb2);
60     send_data(0x0404);
61     send_data(0x0033);
62     send_data(0x3300);
63
64     send_cmd(0xC6);
65     send_data(0x0A00);
66
67     send_cmd(0xb8);
68     send_data(0x2A2B);
69     send_data(0x0575);
70
71     send_cmd(0xb7);
72     send_data(0x7500);
73
74     send_cmd(0xbb);
75     send_data(0x1B00);
76
77     send_cmd(0xC2);
78     send_data(0x0100);
79
80     send_cmd(0xC3);
81     send_data(0x0b00);
82
83     send_cmd(0xC4);
84     send_data(0x2000);
85
86     send_cmd(0xd0);
87     send_data(0xa4a1);
88
89     send_cmd(0xE8);
90     send_data(0x8300);
91
92     send_cmd(0xE9);
93     send_data(0x0909);
94     send_data(0x0500);
95
96     send_cmd(0xC0);
97     send_data(0x2500);
98
99     send_cmd(0xb0);
100     send_data(0x00d0);
101
102     send_cmd(0xE0);
103     send_data(0xd00E);
104     send_data(0x1810);
105     send_data(0x0E2A);
106     send_data(0x3E54);
107     send_data(0x4C2B);
108     send_data(0x1716);
109     send_data(0x1D21);
110
111     send_cmd(0XE1);
112     send_data(0xd00E);
113     send_data(0x1710);
114     send_data(0x0E29);
115     send_data(0x3C44);
116     send_data(0x4D2C);
117     send_data(0x1615);
118     send_data(0x1E22);
119
120     send_cmd(0x29);
121 #else // 16/18/24bit
122         send_cmd(0xB7); send_data(0x35);
123         send_cmd(0xBB); send_data(0x1A);
124         send_cmd(0xC2); send_data(0x01);
125         send_cmd(0xC3); send_data(0x0B);
126         send_cmd(0xC4); send_data(0x20);
127         send_cmd(0xD0); send_data(0xA4);send_data(0xA1);
128         send_cmd(0xE8); send_data(0x83);
129         send_cmd(0xE9); send_data(0x09);send_data(0x09);send_data(0x08);
130
131         //Init setting
132         send_cmd(0x36); send_data(0x00);
133         send_cmd(0x35); send_data(0x00);
134         send_cmd(0x3A); send_data(0x05);//0x06: 262k 0x05:65k
135         send_cmd(0xD2); send_data(0x4C);
136         send_cmd(0xB2);send_data(0x0C);send_data(0x0C);send_data(0x00);send_data(0x33);send_data(0x33);
137         send_cmd(0xC6); send_data(0x09);
138
139         //Gamma setting
140         send_cmd(0xE0);
141         send_data(0xD0);
142         send_data(0x02);
143         send_data(0x11);
144         send_data(0x12);
145         send_data(0x12);
146         send_data(0x2A);
147         send_data(0x3D);
148         send_data(0x44);
149         send_data(0x4C);
150         send_data(0x2B);
151         send_data(0x16);
152         send_data(0x14);
153         send_data(0x1E);
154         send_data(0x21);
155
156         send_cmd(0xE1);
157         send_data(0xD0);
158         send_data(0x02);
159         send_data(0x11);
160         send_data(0x11);
161         send_data(0x12);
162         send_data(0x2A);
163         send_data(0x3B);
164         send_data(0x44);
165         send_data(0x4C);
166         send_data(0x2B);
167         send_data(0x16);
168         send_data(0x15);
169         send_data(0x1E);
170         send_data(0x21);
171
172         send_cmd(0x29); //Display On
173 #endif
174
175         LCD_PRINT("st7789v_init: end\n");
176
177         return 0;
178 }
179
180 static int32_t st7789v_set_window(struct panel_spec *self,
181                 uint16_t left, uint16_t top, uint16_t right, uint16_t bottom)
182 {
183         send_data_t send_cmd = self->info.mcu->ops->send_cmd;
184         send_data_t send_data = self->info.mcu->ops->send_data;
185
186         LCD_PRINT("st7789v_set_window\n");
187 #if defined(ST7789V_BUS_WIDTH_8BIT)
188         send_cmd(0x002A); // col
189         send_data(left);
190         send_data(right);
191
192         send_cmd(0x002B); // row
193         send_data(top);
194         send_data(bottom);
195         send_cmd(0x002C);
196 #else // 16/18/24bit
197         send_cmd(0x2A); // col
198         send_data((left >> 8));
199         send_data((left & 0xFF));
200         send_data((right >> 8));
201         send_data((right & 0xFF));
202
203         send_cmd(0x2B); // row
204         send_data((top >> 8));
205         send_data((top & 0xFF));
206         send_data((bottom >> 8));
207         send_data((bottom & 0xFF));
208         send_cmd(0x2C);
209 #endif
210         return 0;
211 }
212
213
214 static int32_t st7789v_invalidate(struct panel_spec *self)
215 {
216         LCD_PRINT("st7789v_invalidate\n");
217
218         return self->ops->panel_set_window(self, 0, 0,
219                         self->width-1, self->height-1);
220 }
221
222 static int32_t st7789v_invalidate_rect(struct panel_spec *self,
223                                 uint16_t left, uint16_t top,
224                                 uint16_t right, uint16_t bottom)
225 {
226
227         LCD_PRINT("st7789v_invalidate_rect : (%d, %d, %d, %d)\n",left, top, right, bottom);
228
229         return self->ops->panel_set_window(self, left, top,
230                         right, bottom);
231 }
232
233 static int32_t st7789v_set_direction(struct panel_spec *self, uint16_t direction)
234 {
235
236         LCD_PRINT("st7789v_set_direction\n");
237         return 0;
238 }
239
240 static int32_t st7789v_enter_sleep(struct panel_spec *self, uint8_t is_sleep)
241 {
242         send_data_t send_cmd = self->info.mcu->ops->send_cmd;
243
244         if(is_sleep) {
245                 //send_cmd(0x10);
246                 mdelay(120);
247         }
248         else {
249                 //send_cmd(0x11);
250                 mdelay(120);
251         }
252         return 0;
253 }
254
255 #define LCD_MTP_ID 0x51a0f0
256 static int32_t st7789v_read_id(struct panel_spec *self)
257 {
258         int32_t read_value = 0;
259         send_data_t send_cmd = self->info.mcu->ops->send_cmd;
260         read_data_t read_data = self->info.mcu->ops->read_data;
261
262         send_cmd(0x04);
263
264 #if defined(ST7789V_BUS_WIDTH_8BIT)
265                 read_value += (read_data() &0xff)<<16;
266                 read_value += read_data();
267 #else
268                 read_data();
269                 read_value += read_data()<< 16;
270                 read_value += read_data()<< 8;
271                 read_value += read_data();
272 #endif
273         LCD_PRINT("st7789v_read_id=%x\n",read_value);
274         if(read_value == LCD_MTP_ID)
275                 read_value = 0x7789;
276
277         return read_value;
278 }
279
280 static struct panel_operations lcd_st7789v_operations = {
281         .panel_init            = st7789v_init,
282         .panel_set_window      = st7789v_set_window,
283         .panel_invalidate      = st7789v_invalidate,
284         //.lcd_invalidate_rect = st7789v_invalidate_rect,
285         .panel_set_direction   = st7789v_set_direction,
286         .panel_enter_sleep     = st7789v_enter_sleep,
287         .panel_readid         = st7789v_read_id,
288 };
289
290 static struct timing_mcu lcd_st7789v_timing[] = {
291         [0] = {    /* read/write register timing (ns) */
292                         .rcss = 45,
293                         .rlpw = 60,
294                         .rhpw = 100,
295                         .wcss = 10,
296                         .wlpw = 28,
297                         .whpw = 28,
298                 },
299         [1] = {        /* read/write gram timing (ns) */
300                         .rcss = 25,  /* 25 ns */
301                         .rlpw = 70,
302                         .rhpw = 70,
303                         .wcss = 10,
304                         .wlpw = 28,
305                         .whpw = 28,
306                 }
307 };
308
309 static struct info_mcu lcd_st7789v_info = {
310         .bus_mode = LCD_BUS_8080,
311         .bus_width = 8,
312         .bpp = 16,
313         .timing = &lcd_st7789v_timing,
314         .ops = NULL,
315 };
316
317 struct panel_spec lcd_panel_st7789v = {
318         .width = 240,
319         .height = 320,
320         .fps  = 60,
321         .type = LCD_MODE_MCU,
322         .direction = LCD_DIRECT_NORMAL,
323         .info = {
324                  .mcu = &lcd_st7789v_info
325                 },
326         .ops = &lcd_st7789v_operations,
327 };