tizen 2.4 release
[kernel/u-boot-tm1.git] / drivers / video / sc8825fb / lcd_otm_8018b_mipi.c
1 /* drivers/video/sc8825/lcd_otm8018b_mipi.c\r
2  *\r
3  * Support for otm8018b mipi LCD device\r
4  *\r
5  * Copyright (C) 2010 Spreadtrum\r
6  *\r
7  * This software is licensed under the terms of the GNU General Public\r
8  * License version 2, as published by the Free Software Foundation, and\r
9  * may be copied, distributed, and modified under those terms.\r
10  *\r
11  * This program is distributed in the hope that it will be useful,\r
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
14  * GNU General Public License for more details.\r
15  */\r
16 \r
17 #include <asm/arch/tiger_lcd.h>\r
18 \r
19 #define printk printf\r
20 \r
21 //#define  LCD_DEBUG\r
22 #ifdef LCD_DEBUG\r
23 #define LCD_PRINT printk\r
24 #else\r
25 #define LCD_PRINT(...)\r
26 #endif\r
27 \r
28 #define MAX_DATA   48\r
29 \r
30 typedef struct LCM_Init_Code_tag {\r
31         unsigned int tag;\r
32         unsigned char data[MAX_DATA];\r
33 }LCM_Init_Code;\r
34 \r
35 typedef struct LCM_force_cmd_code_tag{\r
36         unsigned int datatype;\r
37         LCM_Init_Code real_cmd_code;\r
38 }LCM_Force_Cmd_Code;\r
39 \r
40 #define LCM_TAG_SHIFT 24\r
41 #define LCM_TAG_MASK  ((1 << 24) -1)\r
42 #define LCM_SEND(len) ((1 << LCM_TAG_SHIFT)| len)\r
43 #define LCM_SLEEP(ms) ((2 << LCM_TAG_SHIFT)| ms)\r
44 //#define ARRAY_SIZE(array) ( sizeof(array) / sizeof(array[0]))\r
45 \r
46 #define LCM_TAG_SEND  (1<< 0)\r
47 #define LCM_TAG_SLEEP (1 << 1)\r
48 \r
49 static LCM_Init_Code init_data[] = {\r
50 #if 1 \r
51 {LCM_SEND(6), {4, 0, 0xff,0x80,0x09,0x01}}, \r
52 \r
53 {LCM_SEND(2), {0x00,0x80}}, \r
54 {LCM_SEND(5), {3, 0, 0xff,0x80,0x09}},\r
55 \r
56 {LCM_SEND(2), {0x00,0x03}}, \r
57 {LCM_SEND(2), {0xFF,0x01}}, \r
58 \r
59 {LCM_SEND(2), {0x00,0xB4}}, \r
60 {LCM_SEND(2), {0xC0,0x10}}, \r
61 \r
62 {LCM_SEND(2), {0x00,0x82}}, \r
63 {LCM_SEND(2), {0xC5,0xA3}}, \r
64 \r
65 {LCM_SEND(2), {0x00,0x90}}, \r
66 {LCM_SEND(5), {3, 0, 0xC5,0xC6,0x76}},\r
67 \r
68 {LCM_SEND(2), {0x00,0x00}}, \r
69 {LCM_SEND(5), {3, 0, 0xD8,0x75,0x73}},\r
70 \r
71 {LCM_SEND(2), {0x00,0x00}}, \r
72 {LCM_SEND(2), {0xD9,0x4E}}, \r
73 \r
74 /*-------------Gamma+ ------*/\r
75 {LCM_SEND(2), {0x00,0x00}},\r
76 {LCM_SEND(19), {17, 0, 0xE1,0x0C,0x0D,0x11,0x10,0x0A,0x1B,0x0B,0x0B,0x00,0x03,0x03,0x05,0x0D,0x24,0x21,0x05}}, \r
77 \r
78 {LCM_SEND(2), {0x00,0x00}},\r
79 {LCM_SEND(19), {17, 0, 0xE2,0x0C,0x0D,0x11,0x12,0x0E,0x1D,0x0B,0x0B,0x00,0x03,0x03,0x05,0x0D,0x25,0x21,0x05}}, \r
80 \r
81 {LCM_SEND(2), {0x00,0x81}}, \r
82 {LCM_SEND(2), {0xC1,0x66}}, \r
83 {LCM_SEND(2), {0x00,0xA1}}, \r
84 {LCM_SEND(2), {0xC1,0x08}}, \r
85 \r
86 {LCM_SEND(2), {0x00,0x89}}, \r
87 {LCM_SEND(2), {0xC4,0x08}}, \r
88 \r
89 {LCM_SEND(2), {0x00,0xA2}}, \r
90 {LCM_SEND(6), {4, 0, 0xC0,0x1B,0x00,0x02}},\r
91 \r
92 {LCM_SEND(2), {0x00,0x81}}, \r
93 {LCM_SEND(2), {0xC4,0x83}}, \r
94 \r
95 {LCM_SEND(2), {0x00,0x92}}, \r
96 {LCM_SEND(2), {0xC5,0x01}}, \r
97 \r
98 {LCM_SEND(2), {0x00,0xB1}}, \r
99 {LCM_SEND(2), {0xC5,0xA9}}, \r
100 \r
101 /*C09x : mck_shift1/mck_shift2/mck_shift3*/\r
102 {LCM_SEND(2), {0x00,0x90}}, \r
103 {LCM_SEND(9), {7, 0, 0xC0,0x00,0x44,0x00,0x00,0x00,0x03}},\r
104 \r
105 /*C1Ax : hs_shift/vs_shift*/\r
106 {LCM_SEND(2), {0x00,0xA6}}, \r
107 {LCM_SEND(6), {4, 0, 0xC1,0x00,0x00,0x00}},\r
108 \r
109 //CE8x : vst1, vst2, vst3, vst4\r
110 {LCM_SEND(2), {0x00,0x80}}, \r
111 {LCM_SEND(15), {13, 0, 0xCE,0x87,0x03,0x00,0x85,0x03,0x00,0x86,0x03,0x00,0x84,0x03,0x00}},\r
112 \r
113 //CEAx : clka1, clka2\r
114 {LCM_SEND(2), {0x00,0xA0}},\r
115 {LCM_SEND(17), {15, 0, 0xCE,0x38,0x03,0x03,0x58,0x00,0x00,0x00,0x38,0x02,0x03,0x59,0x00,0x00,0x00}},\r
116 \r
117 //CEBx : clka3, clka4\r
118 {LCM_SEND(2), {0x00,0xB0}},\r
119 {LCM_SEND(17), {15, 0, 0xCE,0x38,0x01,0x03,0x5A,0x00,0x00,0x00,0x38,0x00,0x03,0x5B,0x00,0x00,0x00}},\r
120 \r
121 //CECx : clkb1, clkb2\r
122 {LCM_SEND(2), {0x00,0xC0}},\r
123 {LCM_SEND(17), {15, 0, 0xCE,0x30,0x00,0x03,0x5C,0x00,0x00,0x00,0x30,0x01,0x03,0x5D,0x00,0x00,0x00}},\r
124 \r
125 //CEDx : clkb3, clkb4\r
126 {LCM_SEND(2), {0x00,0xD0}},\r
127 {LCM_SEND(17), {15, 0, 0xCE,0x30,0x02,0x03,0x5E,0x00,0x00,0x00,0x30,0x03,0x03,0x5F,0x00,0x00,0x00}},\r
128 \r
129 {LCM_SEND(2), {0x00, 0xC7}}, \r
130 {LCM_SEND(2), {0xCF, 0x00}}, \r
131 \r
132 {LCM_SEND(2), {0x00, 0xC9}}, \r
133 {LCM_SEND(2), {0xCF, 0x00}}, \r
134 \r
135 {LCM_SEND(2), {0x00, 0xC4}}, \r
136 {LCM_SEND(9), {7, 0, 0xCB,0x04,0x04,0x04,0x04,0x04,0x04}},\r
137 \r
138 {LCM_SEND(2), {0x00, 0xD9}}, \r
139 {LCM_SEND(9), {7, 0, 0xCB,0x04,0x04,0x04,0x04,0x04,0x04}},\r
140 \r
141 {LCM_SEND(2), {0x00, 0x84}}, \r
142 {LCM_SEND(9), {7, 0, 0xCC,0x0C,0x0A,0x10,0x0E,0x03,0x04}},\r
143 \r
144 {LCM_SEND(2), {0x00,0x9E}}, \r
145 {LCM_SEND(2), {0xCC,0x0B}}, \r
146 \r
147 {LCM_SEND(2), {0x00,0xA0}}, \r
148 {LCM_SEND(8), {6, 0, 0xCC,0x09,0x0F,0x0D,0x01,0x02}},\r
149 \r
150 {LCM_SEND(2), {0x00,0xB4}}, \r
151 {LCM_SEND(9), {7, 0, 0xCC,0x0D,0x0F,0x09,0x0B,0x02,0x01}},\r
152 \r
153 {LCM_SEND(2), {0x00,0xCE}}, \r
154 {LCM_SEND(2), {0xCC,0x0E}}, \r
155 \r
156 {LCM_SEND(2), {0x00,0xD0}}, \r
157 {LCM_SEND(8), {6, 0, 0xCC,0x10,0x0A,0x0C,0x04,0x03}},\r
158 \r
159 {LCM_SEND(2), {0x00,0x00}}, \r
160 {LCM_SEND(2), {0x3A,0x77}}, \r
161 \r
162 {LCM_SEND(2), {0x11, 0x00}}, // sleep out \r
163 {LCM_SLEEP(200),},\r
164 {LCM_SEND(2), {0x29, 0x00}}, // display on \r
165 \r
166 {LCM_SEND(1), {0x2C}}, // normal on \r
167 \r
168 #endif\r
169 \r
170 };\r
171 \r
172 static LCM_Force_Cmd_Code rd_prep_code[]={\r
173         {0x37, {LCM_SEND(2), {0x5, 0}}},\r
174 };\r
175 \r
176 static LCM_Init_Code disp_on =  {LCM_SEND(1), {0x29}};\r
177 \r
178 static LCM_Init_Code sleep_in =  {LCM_SEND(1), {0x10}};\r
179 \r
180 static LCM_Init_Code sleep_out =  {LCM_SEND(1), {0x11}};\r
181 \r
182 static int32_t otm8018b_mipi_init(struct panel_spec *self)\r
183 {\r
184         int32_t i;\r
185         LCM_Init_Code *init = init_data;\r
186         unsigned int tag;\r
187 \r
188         mipi_set_cmd_mode_t mipi_set_cmd_mode = self->info.mipi->ops->mipi_set_cmd_mode;\r
189         mipi_gen_write_t mipi_gen_write = self->info.mipi->ops->mipi_gen_write;\r
190 \r
191         LCD_PRINT("otm8018b_mipi_init\n");\r
192 \r
193         mipi_set_cmd_mode();\r
194 \r
195         for(i = 0; i < ARRAY_SIZE(init_data); i++){\r
196                 tag = (init->tag >>24);\r
197                 if(tag & LCM_TAG_SEND){\r
198                         mipi_gen_write(init->data, (init->tag & LCM_TAG_MASK));\r
199                 }else if(tag & LCM_TAG_SLEEP){\r
200                         udelay((init->tag & LCM_TAG_MASK) * 1000);\r
201                 }\r
202                 init++;\r
203         }\r
204         return 0;\r
205 }\r
206 \r
207 static uint32_t otm8018b_readid(struct panel_spec *self)\r
208 {\r
209         /*Jessica TODO: need read id*/\r
210         int32_t i = 0;\r
211         uint32 j =0;\r
212         LCM_Force_Cmd_Code * rd_prepare = rd_prep_code;\r
213         uint8_t read_data[5] = {0};\r
214         int32_t read_rtn = 0;\r
215         unsigned int tag = 0;\r
216 \r
217         mipi_set_cmd_mode_t mipi_set_cmd_mode = self->info.mipi->ops->mipi_set_cmd_mode;\r
218         mipi_force_write_t mipi_force_write = self->info.mipi->ops->mipi_force_write;\r
219         mipi_force_read_t mipi_force_read = self->info.mipi->ops->mipi_force_read;\r
220 \r
221         printk("lcd_otm8018b_mipi read id!\n");\r
222         mipi_set_cmd_mode();\r
223         for(j = 0; j < 4; j++){\r
224                 rd_prepare = rd_prep_code;\r
225                 for(i = 0; i < ARRAY_SIZE(rd_prep_code); i++){\r
226                         tag = (rd_prepare->real_cmd_code.tag >> 24);\r
227                         if(tag & LCM_TAG_SEND){\r
228                                 mipi_force_write(rd_prepare->datatype, rd_prepare->real_cmd_code.data, (rd_prepare->real_cmd_code.tag & LCM_TAG_MASK));\r
229                         }else if(tag & LCM_TAG_SLEEP){\r
230                                 udelay((rd_prepare->real_cmd_code.tag & LCM_TAG_MASK) * 1000);\r
231                         }\r
232                         rd_prepare++;\r
233                 }\r
234 \r
235                 read_rtn = mipi_force_read(0xa1, 3,(uint8_t *)read_data);\r
236                 printk("lcd_otm8018b_mipi read id 0xa1 value is 0x%x, 0x%x, 0x%x, 0x%x, 0x%x!\n",\r
237                         read_data[0], read_data[1], read_data[2], read_data[3], read_data[4]);\r
238 \r
239                 if((0x01 == read_data[0])&&(0x8b == read_data[1])&&(0x80 == read_data[2])&&(0x09 == read_data[3])&&(0xff == read_data[4])){\r
240                         printk("lcd_otm8018b_mipi read id success!\n");\r
241                         return 0x18;\r
242                 }\r
243         }\r
244 \r
245         printk("lcd_otm8018b_mipi identify fail!\n");\r
246         return 0x0;\r
247 }\r
248 \r
249 static struct panel_operations lcd_otm8018b_mipi_operations = {\r
250         .panel_init = otm8018b_mipi_init,\r
251         .panel_readid = otm8018b_readid,\r
252 };\r
253 \r
254 static struct timing_rgb lcd_otm8018b_mipi_timing = {\r
255         .hfp = 80,  /* unit: pixel */\r
256         .hbp = 80,\r
257         .hsync = 6,\r
258         .vfp = 10, /*unit: line*/\r
259         .vbp = 10,\r
260         .vsync = 6,\r
261 };\r
262 \r
263 static struct info_mipi lcd_otm8018b_mipi_info = {\r
264         .work_mode  = SPRDFB_MIPI_MODE_VIDEO,\r
265         .video_bus_width = 24, /*18,16*/\r
266         .lan_number = 2,\r
267         .phy_feq = 500*1000,\r
268         //.h_sync_pol = SPRDFB_POLARITY_POS,\r
269         //.v_sync_pol = SPRDFB_POLARITY_POS,\r
270         //.de_pol = SPRDFB_POLARITY_POS,\r
271         .te_pol = SPRDFB_POLARITY_POS,\r
272         //.color_mode_pol = SPRDFB_POLARITY_POS,\r
273         //.shut_down_pol = SPRDFB_POLARITY_POS,\r
274         .timing = &lcd_otm8018b_mipi_timing,\r
275         .ops = NULL,\r
276 };\r
277 \r
278 struct panel_spec lcd_otm8018b_mipi_spec = {\r
279         .width = 480,\r
280         .height = 800,\r
281         .type = LCD_MODE_DSI,\r
282         .direction = LCD_DIRECT_NORMAL,\r
283         .info = {\r
284                 .mipi = &lcd_otm8018b_mipi_info\r
285         },\r
286         .ops = &lcd_otm8018b_mipi_operations,\r
287 };\r
288 \r
289 \r