Commit | Line | Data |
---|---|---|
6fa3eb70 S |
1 | #ifndef BUILD_LK |
2 | #include <linux/string.h> | |
3 | #endif | |
4 | ||
5 | #include "lcm_drv.h" | |
6 | ||
7 | #ifdef BUILD_LK | |
8 | #include <platform/mt_gpio.h> | |
9 | #elif defined(BUILD_UBOOT) | |
10 | #include <asm/arch/mt_gpio.h> | |
11 | #else | |
12 | #include <mach/mt_gpio.h> | |
13 | #endif | |
14 | // --------------------------------------------------------------------------- | |
15 | // Local Constants | |
16 | // --------------------------------------------------------------------------- | |
17 | ||
18 | #define FRAME_WIDTH (480) | |
19 | #define FRAME_HEIGHT (800) | |
20 | #define LCM_ID (0x69) | |
21 | #define REGFLAG_DELAY 0xAB | |
22 | #define REGFLAG_END_OF_TABLE 0xAA // END OF REGISTERS MARKER | |
23 | ||
24 | #define LCM_ID1 0x00 | |
25 | #define LCM_ID2 0x00 | |
26 | #define LCM_ID3 0x00 | |
27 | ||
28 | #ifndef TRUE | |
29 | #define TRUE 1 | |
30 | #endif | |
31 | ||
32 | #ifndef FALSE | |
33 | #define FALSE 0 | |
34 | #endif | |
35 | ||
36 | //static unsigned int lcm_esd_test = FALSE; ///only for ESD test | |
37 | #define LCM_DSI_CMD_MODE 1 | |
38 | ||
39 | // --------------------------------------------------------------------------- | |
40 | // Local Variables | |
41 | // --------------------------------------------------------------------------- | |
42 | ||
43 | static LCM_UTIL_FUNCS lcm_util = {0}; | |
44 | ||
45 | #define SET_RESET_PIN(v) (lcm_util.set_reset_pin((v))) | |
46 | ||
47 | #define UDELAY(n) (lcm_util.udelay(n)) | |
48 | #define MDELAY(n) (lcm_util.mdelay(n)) | |
49 | ||
50 | ||
51 | // --------------------------------------------------------------------------- | |
52 | // Local Functions | |
53 | // --------------------------------------------------------------------------- | |
54 | ||
55 | #define dsi_set_cmdq_V2(cmd, count, ppara, force_update) lcm_util.dsi_set_cmdq_V2(cmd, count, ppara, force_update) | |
56 | #define dsi_set_cmdq(pdata, queue_size, force_update) lcm_util.dsi_set_cmdq(pdata, queue_size, force_update) | |
57 | #define wrtie_cmd(cmd) lcm_util.dsi_write_cmd(cmd) | |
58 | #define write_regs(addr, pdata, byte_nums) lcm_util.dsi_write_regs(addr, pdata, byte_nums) | |
59 | #define read_reg(cmd) lcm_util.dsi_dcs_read_lcm_reg(cmd) | |
60 | #define read_reg_v2(cmd, buffer, buffer_size) lcm_util.dsi_dcs_read_lcm_reg_v2(cmd, buffer, buffer_size) | |
61 | ||
62 | struct LCM_setting_table { | |
63 | unsigned char cmd; | |
64 | unsigned char count; | |
65 | unsigned char para_list[64]; | |
66 | }; | |
67 | ||
68 | #if 0 | |
69 | static struct LCM_setting_table lcm_initialization_setting[] = { | |
70 | ||
71 | /* | |
72 | Note : | |
73 | ||
74 | Data ID will depends on the following rule. | |
75 | ||
76 | count of parameters > 1 => Data ID = 0x39 | |
77 | count of parameters = 1 => Data ID = 0x15 | |
78 | count of parameters = 0 => Data ID = 0x05 | |
79 | ||
80 | Structure Format : | |
81 | ||
82 | {DCS command, count of parameters, {parameter list}} | |
83 | {REGFLAG_DELAY, milliseconds of time, {}}, | |
84 | ||
85 | ... | |
86 | ||
87 | Setting ending by predefined flag | |
88 | ||
89 | {REGFLAG_END_OF_TABLE, 0x00, {}} | |
90 | */ | |
91 | ||
92 | {0xC2, 1, {0x08}}, | |
93 | {0xFF, 1, {0x00}}, | |
94 | {0xBA, 1, {0x02}}, // 3lane | |
95 | ||
96 | {0x11, 1, {0x00}}, | |
97 | {REGFLAG_DELAY, 120, {}}, | |
98 | ||
99 | // Display ON | |
100 | {0x29, 1, {0x00}}, | |
101 | {REGFLAG_END_OF_TABLE, 0x00, {}}, | |
102 | // Note | |
103 | // Strongly recommend not to set Sleep out / Display On here. That will cause messed frame to be shown as later the backlight is on. | |
104 | ||
105 | ||
106 | // Setting ending by predefined flag | |
107 | {REGFLAG_END_OF_TABLE, 0x00, {}} | |
108 | }; | |
109 | #endif | |
110 | ||
111 | ||
112 | #if 0 | |
113 | static struct LCM_setting_table lcm_set_window[] = { | |
114 | {0x2A, 4, {0x00, 0x00, (FRAME_WIDTH>>8), (FRAME_WIDTH&0xFF)}}, | |
115 | {0x2B, 4, {0x00, 0x00, (FRAME_HEIGHT>>8), (FRAME_HEIGHT&0xFF)}}, | |
116 | {REGFLAG_END_OF_TABLE, 0x00, {}} | |
117 | }; | |
118 | #endif | |
119 | ||
120 | static struct LCM_setting_table lcm_sleep_out_setting[] = { | |
121 | // Sleep Out | |
122 | {0x11, 1, {0x00}}, | |
123 | {REGFLAG_DELAY, 120, {}}, | |
124 | ||
125 | // Display ON | |
126 | {0x29, 1, {0x00}}, | |
127 | {REGFLAG_END_OF_TABLE, 0x00, {}} | |
128 | }; | |
129 | ||
130 | ||
131 | static struct LCM_setting_table lcm_deep_sleep_mode_in_setting[] = { | |
132 | // Display off sequence | |
133 | {0x28, 1, {0x00}}, | |
134 | ||
135 | {REGFLAG_DELAY, 50, {}}, | |
136 | ||
137 | // Sleep Mode On | |
138 | {0x10, 1, {0x00}}, | |
139 | ||
140 | {REGFLAG_DELAY, 100, {}}, | |
141 | ||
142 | {0x4F, 1, {0x01}}, | |
143 | ||
144 | {REGFLAG_END_OF_TABLE, 0x00, {}} | |
145 | }; | |
146 | /* | |
147 | static struct LCM_setting_table lcm_compare_id_setting[] = { | |
148 | // Display off sequence | |
149 | {0xB9, 3, {0xFF, 0x83, 0x69}}, | |
150 | {REGFLAG_DELAY, 10, {}}, | |
151 | ||
152 | // Sleep Mode On | |
153 | // {0xC3, 1, {0xFF}}, | |
154 | ||
155 | {REGFLAG_END_OF_TABLE, 0x00, {}} | |
156 | }; | |
157 | */ | |
158 | #if 0 | |
159 | static struct LCM_setting_table lcm_backlight_level_setting[] = { | |
160 | {0x51, 1, {0xFF}}, | |
161 | {REGFLAG_END_OF_TABLE, 0x00, {}} | |
162 | }; | |
163 | #endif | |
164 | ||
165 | static void push_table(struct LCM_setting_table *table, unsigned int count, unsigned char force_update) | |
166 | { | |
167 | unsigned int i; | |
168 | ||
169 | for(i = 0; i < count; i++) { | |
170 | ||
171 | unsigned cmd; | |
172 | cmd = table[i].cmd; | |
173 | ||
174 | switch (cmd) { | |
175 | ||
176 | case REGFLAG_DELAY : | |
177 | MDELAY(table[i].count); | |
178 | break; | |
179 | ||
180 | case REGFLAG_END_OF_TABLE : | |
181 | break; | |
182 | ||
183 | default: | |
184 | dsi_set_cmdq_V2(cmd, table[i].count, table[i].para_list, force_update); | |
185 | ||
186 | if (cmd != 0xFF && cmd != 0x2C && cmd != 0x3C) { | |
187 | //#if defined(BUILD_UBOOT) | |
188 | // printf("[DISP] - uboot - REG_R(0x%x) = 0x%x. \n", cmd, table[i].para_list[0]); | |
189 | //#endif | |
190 | while(read_reg(cmd) != table[i].para_list[0]); | |
191 | } | |
192 | } | |
193 | ||
194 | } | |
195 | ||
196 | } | |
197 | ||
198 | ||
199 | // --------------------------------------------------------------------------- | |
200 | // LCM Driver Implementations | |
201 | // --------------------------------------------------------------------------- | |
202 | ||
203 | static void lcm_set_util_funcs(const LCM_UTIL_FUNCS *util) | |
204 | { | |
205 | memcpy(&lcm_util, util, sizeof(LCM_UTIL_FUNCS)); | |
206 | } | |
207 | ||
208 | ||
209 | static void lcm_get_params(LCM_PARAMS *params) | |
210 | { | |
211 | memset(params, 0, sizeof(LCM_PARAMS)); | |
212 | ||
213 | params->type = LCM_TYPE_DSI; | |
214 | ||
215 | params->width = FRAME_WIDTH; | |
216 | params->height = FRAME_HEIGHT; | |
217 | ||
218 | #if (LCM_DSI_CMD_MODE) | |
219 | params->dsi.mode = CMD_MODE; | |
220 | #else | |
221 | params->dsi.mode = BURST_VDO_MODE; | |
222 | #endif | |
223 | // DSI | |
224 | /* Command mode setting */ | |
225 | params->dsi.LANE_NUM = LCM_THREE_LANE; | |
226 | //The following defined the fomat for data coming from LCD engine. | |
227 | params->dsi.data_format.format = LCM_DSI_FORMAT_RGB888; | |
228 | ||
229 | params->dsi.PS=LCM_PACKED_PS_24BIT_RGB888; | |
230 | params->dsi.CLK_HS_POST=26; | |
231 | ||
232 | params->dsi.PLL_CLOCK = 286;//dsi clock customization: should config clock value directly | |
233 | } | |
234 | ||
235 | static void lcm_init(void) | |
236 | { | |
237 | //int i; | |
238 | //unsigned char buffer[10]; | |
239 | //unsigned int array[16]; | |
240 | unsigned int data_array[16]; | |
241 | ||
242 | MDELAY(40); | |
243 | SET_RESET_PIN(1); | |
244 | MDELAY(5); | |
245 | ||
246 | data_array[0] = 0x00023902; | |
247 | data_array[1] = 0x0000EEFF; | |
248 | dsi_set_cmdq(data_array, 2, 1); | |
249 | MDELAY(2); | |
250 | data_array[0] = 0x00023902; | |
251 | data_array[1] = 0x00000826; | |
252 | dsi_set_cmdq(data_array, 2, 1); | |
253 | MDELAY(2); | |
254 | data_array[0] = 0x00023902; | |
255 | data_array[1] = 0x00000026; | |
256 | dsi_set_cmdq(data_array, 2, 1); | |
257 | MDELAY(2); | |
258 | data_array[0] = 0x00023902; | |
259 | data_array[1] = 0x000000FF; | |
260 | dsi_set_cmdq(data_array, 2, 1); | |
261 | ||
262 | MDELAY(20); | |
263 | SET_RESET_PIN(0); | |
264 | MDELAY(1); | |
265 | SET_RESET_PIN(1); | |
266 | MDELAY(40); | |
267 | ||
268 | ||
269 | data_array[0]=0x00023902; | |
270 | data_array[1]=0x000008C2;//cmd mode | |
271 | dsi_set_cmdq(data_array, 2, 1); | |
272 | ||
273 | data_array[0]=0x00023902; | |
274 | data_array[1]=0x000002BA;//MIPI lane | |
275 | dsi_set_cmdq(data_array, 2, 1); | |
276 | ||
277 | //{0x44, 2, {((FRAME_HEIGHT/2)>>8), ((FRAME_HEIGHT/2)&0xFF)}}, | |
278 | data_array[0] = 0x00033902; | |
279 | data_array[1] = (((FRAME_HEIGHT/2)&0xFF) << 16) | (((FRAME_HEIGHT/2)>>8) << 8) | 0x44; | |
280 | dsi_set_cmdq(data_array, 2, 1); | |
281 | ||
282 | data_array[0] = 0x00351500;// TE ON | |
283 | dsi_set_cmdq(data_array, 1, 1); | |
284 | //MDELAY(10); | |
285 | ||
286 | data_array[0]=0x00110500; | |
287 | dsi_set_cmdq(data_array, 1, 1); | |
288 | MDELAY(120); | |
289 | ||
290 | data_array[0]=0x00290500; | |
291 | dsi_set_cmdq(data_array, 1, 1); | |
292 | ||
293 | //MDELAY(50); | |
294 | // push_table(lcm_initialization_setting, sizeof(lcm_initialization_setting) / sizeof(struct LCM_setting_table), 1); | |
295 | } | |
296 | ||
297 | ||
298 | static void lcm_suspend(void) | |
299 | { | |
300 | unsigned int data_array[16]; | |
301 | ||
302 | data_array[0]=0x00280500; | |
303 | dsi_set_cmdq(data_array, 1, 1); | |
304 | MDELAY(120); | |
305 | ||
306 | data_array[0]=0x00100500; | |
307 | dsi_set_cmdq(data_array, 1, 1); | |
308 | MDELAY(50); | |
309 | ||
310 | data_array[0]=0x00023902; | |
311 | data_array[1]=0x0000014F; | |
312 | dsi_set_cmdq(data_array, 2, 1); | |
313 | ||
314 | } | |
315 | ||
316 | ||
317 | static void lcm_resume(void) | |
318 | { | |
319 | unsigned int data_array[16]; | |
320 | ||
321 | SET_RESET_PIN(1); | |
322 | MDELAY(10); | |
323 | SET_RESET_PIN(0); | |
324 | MDELAY(10); | |
325 | SET_RESET_PIN(1); | |
326 | MDELAY(50); | |
327 | ||
328 | data_array[0] = 0x00023902; | |
329 | data_array[1] = 0x0000EEFF; | |
330 | dsi_set_cmdq(data_array, 2, 1); | |
331 | MDELAY(2); | |
332 | data_array[0] = 0x00023902; | |
333 | data_array[1] = 0x00000826; | |
334 | dsi_set_cmdq(data_array, 2, 1); | |
335 | MDELAY(2); | |
336 | data_array[0] = 0x00023902; | |
337 | data_array[1] = 0x00000026; | |
338 | dsi_set_cmdq(data_array, 2, 1); | |
339 | MDELAY(2); | |
340 | data_array[0] = 0x00023902; | |
341 | data_array[1] = 0x000000FF; | |
342 | dsi_set_cmdq(data_array, 2, 1); | |
343 | ||
344 | MDELAY(20); | |
345 | SET_RESET_PIN(0); | |
346 | MDELAY(1); | |
347 | SET_RESET_PIN(1); | |
348 | MDELAY(40); | |
349 | ||
350 | data_array[0]=0x00023902; | |
351 | data_array[1]=0x000008C2;//cmd mode | |
352 | //data_array[1]=0x000003C2;//vdo mode | |
353 | dsi_set_cmdq(data_array, 2, 1); | |
354 | ||
355 | data_array[0]=0x00023902; | |
356 | data_array[1]=0x000002BA;//MIPI lane | |
357 | dsi_set_cmdq(data_array, 2, 1); | |
358 | ||
359 | //{0x44, 2, {((FRAME_HEIGHT/2)>>8), ((FRAME_HEIGHT/2)&0xFF)}}, | |
360 | data_array[0] = 0x00033902; | |
361 | data_array[1] = (((FRAME_HEIGHT/2)&0xFF) << 16) | (((FRAME_HEIGHT/2)>>8) << 8) | 0x44; | |
362 | dsi_set_cmdq(data_array, 2, 1); | |
363 | ||
364 | data_array[0] = 0x00351500;// TE ON | |
365 | dsi_set_cmdq(data_array, 1, 1); | |
366 | //MDELAY(10); | |
367 | ||
368 | data_array[0]=0x00110500; | |
369 | dsi_set_cmdq(data_array, 1, 1); | |
370 | MDELAY(120); | |
371 | ||
372 | data_array[0]=0x00290500; | |
373 | dsi_set_cmdq(data_array, 1, 1); | |
374 | ||
375 | } | |
376 | ||
377 | ||
378 | static void lcm_update(unsigned int x, unsigned int y, | |
379 | unsigned int width, unsigned int height) | |
380 | { | |
381 | unsigned int x0 = x; | |
382 | unsigned int y0 = y; | |
383 | unsigned int x1 = x0 + width - 1; | |
384 | unsigned int y1 = y0 + height - 1; | |
385 | ||
386 | unsigned char x0_MSB = ((x0>>8)&0xFF); | |
387 | unsigned char x0_LSB = (x0&0xFF); | |
388 | unsigned char x1_MSB = ((x1>>8)&0xFF); | |
389 | unsigned char x1_LSB = (x1&0xFF); | |
390 | unsigned char y0_MSB = ((y0>>8)&0xFF); | |
391 | unsigned char y0_LSB = (y0&0xFF); | |
392 | unsigned char y1_MSB = ((y1>>8)&0xFF); | |
393 | unsigned char y1_LSB = (y1&0xFF); | |
394 | ||
395 | unsigned int data_array[16]; | |
396 | ||
397 | data_array[0]= 0x00053902; | |
398 | data_array[1]= (x1_MSB<<24)|(x0_LSB<<16)|(x0_MSB<<8)|0x2a; | |
399 | data_array[2]= (x1_LSB); | |
400 | dsi_set_cmdq(data_array, 3, 1); | |
401 | ||
402 | data_array[0]= 0x00053902; | |
403 | data_array[1]= (y1_MSB<<24)|(y0_LSB<<16)|(y0_MSB<<8)|0x2b; | |
404 | data_array[2]= (y1_LSB); | |
405 | dsi_set_cmdq(data_array, 3, 1); | |
406 | ||
407 | data_array[0]= 0x002c3909; | |
408 | dsi_set_cmdq(data_array, 1, 0); | |
409 | ||
410 | } | |
411 | ||
412 | #if 0 | |
413 | static void lcm_setbacklight(unsigned int level) | |
414 | { | |
415 | unsigned int default_level = 145; | |
416 | unsigned int mapped_level = 0; | |
417 | ||
418 | //for LGE backlight IC mapping table | |
419 | if(level > 255) | |
420 | level = 255; | |
421 | ||
422 | if(level >0) | |
423 | mapped_level = default_level+(level)*(255-default_level)/(255); | |
424 | else | |
425 | mapped_level=0; | |
426 | ||
427 | // Refresh value of backlight level. | |
428 | lcm_backlight_level_setting[0].para_list[0] = mapped_level; | |
429 | ||
430 | push_table(lcm_backlight_level_setting, sizeof(lcm_backlight_level_setting) / sizeof(struct LCM_setting_table), 1); | |
431 | } | |
432 | ||
433 | static unsigned int lcm_esd_check(void) | |
434 | { | |
435 | #ifndef BUILD_UBOOT | |
436 | if(lcm_esd_test) | |
437 | { | |
438 | lcm_esd_test = FALSE; | |
439 | return TRUE; | |
440 | } | |
441 | ||
442 | /// please notice: the max return packet size is 1 | |
443 | /// if you want to change it, you can refer to the following marked code | |
444 | /// but read_reg currently only support read no more than 4 bytes.... | |
445 | /// if you need to read more, please let BinHan knows. | |
446 | /* | |
447 | unsigned int data_array[16]; | |
448 | unsigned int max_return_size = 1; | |
449 | ||
450 | data_array[0]= 0x00003700 | (max_return_size << 16); | |
451 | ||
452 | dsi_set_cmdq(&data_array, 1, 1); | |
453 | */ | |
454 | ||
455 | if(read_reg(0xB6) == 0x42) | |
456 | { | |
457 | return FALSE; | |
458 | } | |
459 | else | |
460 | { | |
461 | return TRUE; | |
462 | } | |
463 | #endif | |
464 | } | |
465 | ||
466 | static unsigned int lcm_esd_recover(void) | |
467 | { | |
468 | unsigned char para = 0; | |
469 | ||
470 | SET_RESET_PIN(1); | |
471 | SET_RESET_PIN(0); | |
472 | MDELAY(1); | |
473 | SET_RESET_PIN(1); | |
474 | MDELAY(120); | |
475 | push_table(lcm_initialization_setting, sizeof(lcm_initialization_setting) / sizeof(struct LCM_setting_table), 1); | |
476 | MDELAY(10); | |
477 | push_table(lcm_sleep_out_setting, sizeof(lcm_sleep_out_setting) / sizeof(struct LCM_setting_table), 1); | |
478 | MDELAY(10); | |
479 | dsi_set_cmdq_V2(0x35, 1, ¶, 1); ///enable TE | |
480 | MDELAY(10); | |
481 | ||
482 | return TRUE; | |
483 | } | |
484 | /* | |
485 | static unsigned int lcm_compare_id(void) | |
486 | { | |
487 | unsigned int id1, id2, id3; | |
488 | unsigned char buffer[2]; | |
489 | unsigned int array[16]; | |
490 | ||
491 | SET_RESET_PIN(1); | |
492 | SET_RESET_PIN(0); | |
493 | MDELAY(10); | |
494 | SET_RESET_PIN(1); | |
495 | MDELAY(10); | |
496 | ||
497 | // Set Maximum return byte = 1 | |
498 | array[0] = 0x00013700; | |
499 | dsi_set_cmdq(array, 1, 1); | |
500 | ||
501 | id1 = read_reg(0xDA); | |
502 | id2 = read_reg(0xDB); | |
503 | id2 = read_reg(0xDC); | |
504 | ||
505 | #if defined(BUILD_UBOOT) | |
506 | printf("%s, Module ID = {%x, %x, %x} \n", __func__, id1, id2, id3); | |
507 | #endif | |
508 | ||
509 | return (LCM_ID1 == id1 && LCM_ID2 == id2)?1:0; | |
510 | } | |
511 | */ | |
512 | #endif | |
513 | // --------------------------------------------------------------------------- | |
514 | // Get LCM Driver Hooks | |
515 | // --------------------------------------------------------------------------- | |
516 | LCM_DRIVER nt35590_hd720_dsi_cmd_auo_wvga_lcm_drv = | |
517 | { | |
518 | .name = "nt35590_AUO", | |
519 | .set_util_funcs = lcm_set_util_funcs, | |
520 | .get_params = lcm_get_params, | |
521 | .init = lcm_init, | |
522 | .suspend = lcm_suspend, | |
523 | .resume = lcm_resume, | |
524 | #if (LCM_DSI_CMD_MODE) | |
525 | .update = lcm_update, | |
526 | //.set_backlight = lcm_setbacklight, | |
527 | // .set_pwm = lcm_setpwm, | |
528 | // .get_pwm = lcm_getpwm, | |
529 | //.esd_check = lcm_esd_check, | |
530 | //.esd_recover = lcm_esd_recover, | |
531 | //.compare_id = lcm_compare_id, | |
532 | #endif | |
533 | }; |