tizen 2.4 release
[kernel/u-boot-tm1.git] / drivers / video / sprdfb / lcd / lcd_otm8019a_mipi.c
1 /* drivers/video/sprdfb/lcd_otm8019a_mipi.c\r
2  *\r
3  * Support for otm8019a mipi LCD device\r
4  *\r
5  * Copyright (C) 2010 Spreadtrum\r
6  *\r
7  */\r
8 \r
9 #include <asm/arch/sprd_lcd.h>\r
10 #include "../sprdfb.h"\r
11 \r
12 #define printk printf\r
13 \r
14 #define  LCD_DEBUG\r
15 //#define THREE_LANE_SUPPORT\r
16 \r
17 #ifdef LCD_DEBUG\r
18 #define LCD_PRINT printk\r
19 #else\r
20 #define LCD_PRINT(...)\r
21 #endif\r
22 \r
23 #define MAX_DATA   48\r
24 typedef struct LCM_Init_Code_tag {\r
25         unsigned int tag;\r
26         unsigned char data[MAX_DATA];\r
27 }LCM_Init_Code;\r
28 \r
29 typedef struct LCM_force_cmd_code_tag{\r
30         unsigned int datatype;\r
31         LCM_Init_Code real_cmd_code;\r
32 }LCM_Force_Cmd_Code;\r
33 \r
34 #define LCM_TAG_SHIFT 24\r
35 #define LCM_TAG_MASK  ((1 << 24) -1)\r
36 #define LCM_SEND(len) ((1 << LCM_TAG_SHIFT)| len)\r
37 #define LCM_SLEEP(ms) ((2 << LCM_TAG_SHIFT)| ms)\r
38 //#define ARRAY_SIZE(array) ( sizeof(array) / sizeof(array[0]))\r
39 \r
40 #define LCM_TAG_SEND  (1<< 0)\r
41 #define LCM_TAG_SLEEP (1 << 1)\r
42 \r
43 \r
44 static LCM_Force_Cmd_Code rd_prep_code[]={\r
45         {0x37, {LCM_SEND(2), {0x5, 0}}},\r
46 };\r
47 \r
48 static LCM_Init_Code init_data[] = {\r
49         {LCM_SEND(2),{0x00,0x00}},\r
50         {LCM_SEND(6),{4,0,0xFF,0x80,0x19,0x01}},\r
51 \r
52         {LCM_SEND(2),{0x00,0x80}},\r
53         {LCM_SEND(5),{3,0,0xFF,0x80,0x19}},\r
54 \r
55         {LCM_SEND(2),{0x00,0x03}},\r
56         {LCM_SEND(2),{0xFF,0x01}},\r
57 \r
58         {LCM_SEND(2),{0x00,0x00}},\r
59         {LCM_SEND(5),{3,0,0xD8,0x7F,0X7F}},//6f\r
60 \r
61         {LCM_SEND(2),{0x00,0x082}},\r
62         {LCM_SEND(2),{0xC5,0xB0}},\r
63 \r
64         {LCM_SEND(2),{0x00,0xA1}},\r
65         {LCM_SEND(2),{0xC1,0x08}},\r
66 \r
67         {LCM_SEND(2),{0x00,0xA3}},\r
68         {LCM_SEND(2),{0xC0,0x1B}},\r
69 \r
70         {LCM_SEND(2),{0x00,0xB4}},\r
71         {LCM_SEND(2),{0xC0,0x77}},\r
72 \r
73         {LCM_SEND(2),{0x00,0x81}},\r
74         {LCM_SEND(2),{0xC4,0x83}},\r
75 \r
76         {LCM_SEND(2),{0x00,0x90}},\r
77         {LCM_SEND(6),{4,0,0xC5,0x4E,0xA7,0x01}},\r
78 \r
79         {LCM_SEND(2),{0x00,0xB1}},\r
80         {LCM_SEND(2),{0xC5,0xA9}},\r
81 \r
82         {LCM_SEND(2),{0x00,0x00}},\r
83         {LCM_SEND(2),{0xD9,0x17}},\r
84 \r
85         {LCM_SEND(2),{0x00,0x80}},\r
86         {LCM_SEND(2),{0xD8,0x58}},//kai ce\r
87 \r
88 //***************Gamma 2.2********************\r
89         {LCM_SEND(2),{0x00,0x00}},\r
90         {LCM_SEND(23),{21,0,0xE1,0x00,0x06,0x14,0x25,0x3d,0x4e,0x5a,0x8d,0x7c,0x91,0x75,0x64,0x7d,\r
91                 0x69,0x6e,0x67,0x5f,0x55,0x5c,0x02}},\r
92 \r
93         {LCM_SEND(2),{0x00,0x00}},\r
94         {LCM_SEND(23),{21,0,0xE2,0x00,0x06,0x14,0x25,0x3d,0x4e,0x5a,0x8d,0x7b,0x91,0x75,0x64,0x7d,\r
95                 0x69,0x6e,0x67,0x5f,0x55,0x5c,0x02}},\r
96 //******************************************** \r
97 //***************Gamma 2.5********************\r
98         {LCM_SEND(2),{0x00,0x00}},\r
99         {LCM_SEND(23),{21,0,0xE1,0x00,0x02,0x07,0x12,0x22,0x37,0x41,0x78,0x6b,0x85,0x7f,0x6b,0x82,\r
100                 0x6b,0x71,0x69,0x61,0x58,0x4c,0x00}},\r
101 \r
102         {LCM_SEND(2),{0x00,0x00}},\r
103         {LCM_SEND(23),{21,0,0xE2,0x00,0x02,0x07,0x12,0x22,0x37,0x41,0x78,0x6b,0x85,0x7f,0x6b,0x82,\r
104                 0x6b,0x71,0x69,0x61,0x58,0x4c,0x00}},\r
105 //******************************************** \r
106 \r
107         {LCM_SEND(2),{0x00,0xA7}},\r
108         {LCM_SEND(2),{0xB3,0x00}},\r
109 \r
110         {LCM_SEND(2),{0x00,0x92}},\r
111         {LCM_SEND(2),{0xB3,0x45}},\r
112 \r
113         {LCM_SEND(2),{0x00,0x90}},\r
114         {LCM_SEND(2),{0xB3,0x02}},\r
115 \r
116         {LCM_SEND(2),{0x00,0x00}},\r
117         {LCM_SEND(2),{0x36,0x00}},\r
118 \r
119         {LCM_SEND(2),{0x00,0x90}},\r
120         {LCM_SEND(9),{7,0,0xC0,0x00,0x15,0x00,0x00,0x00,0x03}},\r
121 \r
122         {LCM_SEND(2),{0x00,0xA0}},\r
123         {LCM_SEND(2),{0xC1,0xE8}},\r
124 \r
125         {LCM_SEND(2),{0x00,0xA6}},\r
126         {LCM_SEND(6),{4,0,0xC1,0x01,0x00,0x00}},\r
127 \r
128         {LCM_SEND(2),{0x00,0x80}},\r
129         {LCM_SEND(9),{7,0,0xCE,0x87,0x03,0x00,0x86,0x03,0x00}},\r
130         {LCM_SLEEP(2),},\r
131 \r
132         {LCM_SEND(2),{0x00,0x90}},\r
133         {LCM_SEND(9),{7,0,0xCE,0x33,0x54,0x00,0x33,0x55,0x00}},\r
134         {LCM_SLEEP(2),},\r
135 \r
136         {LCM_SEND(2),{0x00,0xA0}},\r
137         {LCM_SEND(17),{15,0,0xCE,0x38,0x03,0x03,0x58,0x00,0x00,0x00,0x38,0x02,0x03,0x59,0x00,0x00,0x00}},\r
138         {LCM_SLEEP(2),},\r
139 \r
140         {LCM_SEND(2),{0x00,0xB0}},\r
141         {LCM_SEND(17),{15,0,0xCE,0x38,0x01,0x03,0x5A,0x00,0x00,0x00,0x38,0x00,0x03,0x5B,0x00,0x00,0x00}},\r
142         {LCM_SLEEP(2),},\r
143 \r
144         {LCM_SEND(2),{0x00,0xC0}},\r
145         {LCM_SEND(17),{15,0,0xCE,0x30,0x00,0x03,0x5C,0x00,0x00,0x00,0x30,0x01,0x03,0x5D,0x00,0x00,0x00}},\r
146         {LCM_SLEEP(2),},\r
147 \r
148         {LCM_SEND(2),{0x00,0xD0}},\r
149         {LCM_SEND(17),{15,0,0xCE,0x38,0x05,0x03,0x5E,0x00,0x00,0x00,0x38,0x04,0x03,0x5F,0x00,0x00,0x00}},\r
150         {LCM_SLEEP(2),},\r
151 \r
152         {LCM_SEND(2),{0x00,0xC0}},\r
153         {LCM_SEND(13),{11,0,0xCF,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x80,0x00,0x09}},\r
154 \r
155         {LCM_SEND(2),{0x00,0xC0}},\r
156         {LCM_SEND(18),{16,0,0xCB,0x00,0x01,0x01,0x01,0x01,0x00,0x00,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x00}},\r
157 \r
158         {LCM_SEND(2),{0x00,0xD0}},\r
159         {LCM_SEND(18),{16,0,0xCB,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x00}},\r
160 \r
161         {LCM_SEND(2),{0x00,0xE0}},\r
162         {LCM_SEND(13),{11,0,0xCB,0x00,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00}},\r
163 \r
164         {LCM_SEND(2),{0x00,0x80}},\r
165         {LCM_SEND(13),{11,0,0xCC,0x00,0x26,0x25,0x02,0x06,0x00,0x00,0x0A,0x0E,0x0C}},\r
166 \r
167         {LCM_SEND(2),{0x00,0x90}},\r
168         {LCM_SEND(18),{16,0,0xCC,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},\r
169 \r
170         {LCM_SEND(2),{0x00,0xA0}},\r
171         {LCM_SEND(18),{16,0,0xCC,0x0f,0x0b,0x0d,0x09,0x00,0x00,0x05,0x01,0x25,0x26,0x00,0x00,0x00,0x00,0x00}},\r
172 \r
173         {LCM_SEND(2),{0x00,0xB0}},\r
174         {LCM_SEND(13),{11,0,0xCC,0x00,0x25,0x26,0x05,0x01,0x00,0x00,0x0D,0x09,0x0B}},\r
175 \r
176         {LCM_SEND(2),{0x00,0xC0}},\r
177         {LCM_SEND(18),{16,0,0xCC,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},\r
178 \r
179         {LCM_SEND(2),{0x00,0xD0}},\r
180         {LCM_SEND(18),{16,0,0xCC,0x10,0x0c,0x0a,0x0e,0x00,0x00,0x02,0x06,0x26,0x25,0x00,0x00,0x00,0x00,0x00}},\r
181 \r
182 //-----------------AUTO SHIFT-------------------\r
183         {LCM_SEND(2),{0x00,0x98}},\r
184         {LCM_SEND(2),{0xC0,0x00}},\r
185         {LCM_SEND(2),{0x00,0xA9}},\r
186         {LCM_SEND(2),{0xC0,0x06}},\r
187         {LCM_SEND(2),{0x00,0xB0}},\r
188         {LCM_SEND(6),{4,0,0xC1,0x20,0x00,0x00}},\r
189         {LCM_SEND(2),{0x00,0xE1}},\r
190         {LCM_SEND(5),{3,0,0xC0,0x40,0x18}},\r
191 //----------------------------------------------\r
192         {LCM_SEND(2),{0x00,0x80}},\r
193         {LCM_SEND(2),{0xC4,0x30}}, //source blanking area=GND\r
194 \r
195         {LCM_SEND(2),{0x00,0x80}},\r
196         {LCM_SEND(5),{3,0,0xC1,0x03,0x33}},\r
197 \r
198         {LCM_SEND(2),{0x00,0x90}},\r
199         {LCM_SEND(2),{0xB6,0xB4}},//command fial\r
200         {LCM_SLEEP(10),},\r
201 \r
202         {LCM_SEND(2),{0x00,0x00}},\r
203         {LCM_SEND(2),{0xfb,0x01}},\r
204 \r
205         {LCM_SEND(2),{0x00,0x00}},\r
206         {LCM_SEND(2),{4,0,0xFF,0xFF,0xFF,0xFF}},\r
207 \r
208         {LCM_SEND(1), {0x11}}, // sleep out\r
209         {LCM_SLEEP(120)},\r
210         {LCM_SEND(1), {0x29}}, // display on\r
211         {LCM_SLEEP(5),}, //30,100\r
212         {LCM_SEND(1), {0x2C}}, // normal on\r
213 };\r
214 \r
215 \r
216 static LCM_Init_Code disp_on =  {LCM_SEND(1), {0x29}};\r
217 static LCM_Init_Code sleep_in =  {LCM_SEND(1), {0x10}};\r
218 static LCM_Init_Code sleep_out =  {LCM_SEND(1), {0x11}};\r
219 \r
220 static int32_t otm8019a_mipi_init(struct panel_spec *self)\r
221 {\r
222         int32_t i;\r
223         LCM_Init_Code *init = init_data;\r
224         unsigned int tag;\r
225 \r
226         mipi_set_cmd_mode_t mipi_set_cmd_mode = self->info.mipi->ops->mipi_set_cmd_mode;\r
227         mipi_gen_write_t mipi_gen_write = self->info.mipi->ops->mipi_gen_write;\r
228         mipi_eotp_set_t mipi_eotp_set = self->info.mipi->ops->mipi_eotp_set;\r
229 \r
230         LCD_PRINT("otm8019a_mipi_init\n");\r
231 \r
232         mipi_set_cmd_mode();\r
233         mipi_eotp_set(1,0);\r
234 \r
235         for(i = 0; i < ARRAY_SIZE(init_data); i++){\r
236                 tag = (init->tag >>24);\r
237                 if(tag & LCM_TAG_SEND){\r
238                         mipi_gen_write(init->data, (init->tag & LCM_TAG_MASK));\r
239                         udelay(20);\r
240                 }else if(tag & LCM_TAG_SLEEP){\r
241                         mdelay((init->tag & LCM_TAG_MASK));\r
242                 }\r
243                 init++;\r
244         }\r
245         mipi_eotp_set(1,1);\r
246         return 0;\r
247 }\r
248 \r
249 static uint32_t otm8019a_readid(struct panel_spec *self)\r
250 {\r
251         /*Jessica TODO: need read id*/\r
252         int32_t i = 0;\r
253         uint32 j =0;\r
254         LCM_Force_Cmd_Code * rd_prepare = rd_prep_code;\r
255         uint8_t read_data[5] = {0};\r
256         int32_t read_rtn = 0;\r
257         unsigned int tag = 0;\r
258 \r
259         mipi_set_cmd_mode_t mipi_set_cmd_mode = self->info.mipi->ops->mipi_set_cmd_mode;\r
260         mipi_force_write_t mipi_force_write = self->info.mipi->ops->mipi_force_write;\r
261         mipi_force_read_t mipi_force_read = self->info.mipi->ops->mipi_force_read;\r
262         mipi_eotp_set_t mipi_eotp_set = self->info.mipi->ops->mipi_eotp_set;\r
263 \r
264         LCD_PRINT("lcd_otm8019a_mipi read id!\n");\r
265         //return 0x8019;\r
266 \r
267         mipi_set_cmd_mode();\r
268         mipi_eotp_set(1,0);\r
269 \r
270         for(j = 0; j < 4; j++){\r
271                 rd_prepare = rd_prep_code;\r
272                 for(i = 0; i < ARRAY_SIZE(rd_prep_code); i++){\r
273                         tag = (rd_prepare->real_cmd_code.tag >> 24);\r
274                         if(tag & LCM_TAG_SEND){\r
275                                 mipi_force_write(rd_prepare->datatype, rd_prepare->real_cmd_code.data, (rd_prepare->real_cmd_code.tag & LCM_TAG_MASK));\r
276                         }else if(tag & LCM_TAG_SLEEP){\r
277                                 mdelay((rd_prepare->real_cmd_code.tag & LCM_TAG_MASK));\r
278                         }\r
279                         rd_prepare++;\r
280                 }\r
281 \r
282                 read_rtn = mipi_force_read(0xa1, 5,(uint8_t *)read_data);\r
283                 LCD_PRINT("lcd_otm8019a_mipi read id 0xa1 value is 0x%x, 0x%x, 0x%x, 0x%x, 0x%x!\n",\r
284                         read_data[0], read_data[1], read_data[2], read_data[3], read_data[4]);\r
285 \r
286                 mipi_eotp_set(1,1);\r
287 \r
288                 if((0x01 == read_data[0])&&(0x8b == read_data[1])&&(0x80 == read_data[2])&&(0x19 == read_data[3])&&(0xff == read_data[4])){\r
289                         LCD_PRINT("lcd_otm8019a_mipi read id success!\n");\r
290                         return 0x8019;\r
291                 }\r
292         }\r
293 \r
294         printk("lcd_otm8019a_mipi identify fail!\n");\r
295         return 0x0;\r
296 }\r
297 \r
298 static struct panel_operations lcd_otm8019a_mipi_operations = {\r
299         .panel_init = otm8019a_mipi_init,\r
300         .panel_readid = otm8019a_readid,\r
301 };\r
302 \r
303 static struct timing_rgb lcd_otm8019a_mipi_timing = {\r
304         .hfp = 48, /*46*/\r
305         .hbp = 48, /*44*/
306         .hsync = 8,
307         .vfp = 16, /*14*/
308         .vbp = 16,
309         .vsync = 8,/* 2*/\r
310 };\r
311 \r
312 static struct info_mipi lcd_otm8019a_mipi_info = {\r
313         .work_mode                              = SPRDFB_MIPI_MODE_VIDEO,\r
314         .video_bus_width                = 24, /*18,16*/\r
315         .lan_number                             = 2,\r
316         .phy_feq                                = 500*1000,\r
317         .h_sync_pol                             = SPRDFB_POLARITY_POS,\r
318         .v_sync_pol                             = SPRDFB_POLARITY_POS,\r
319         .de_pol                                 = SPRDFB_POLARITY_POS,\r
320         .te_pol                                 = SPRDFB_POLARITY_POS,\r
321         .color_mode_pol                 = SPRDFB_POLARITY_NEG,\r
322         .shut_down_pol                  = SPRDFB_POLARITY_NEG,\r
323         .timing                                 = &lcd_otm8019a_mipi_timing,\r
324         .ops                                    = NULL,\r
325 };\r
326 \r
327 struct panel_spec lcd_otm8019a_mipi_spec = {\r
328         .width                                  = 480,\r
329         .height                                 = 854,\r
330         .fps                                    = 60,\r
331         .type                                   = LCD_MODE_DSI,\r
332         .direction                              = LCD_DIRECT_NORMAL,\r
333         .info = {\r
334                 .mipi                           = &lcd_otm8019a_mipi_info\r
335         },\r
336         .ops                                    = &lcd_otm8019a_mipi_operations,\r
337 };\r
338 \r
339 \r
340 \r