tizen 2.4 release
[kernel/u-boot-tm1.git] / drivers / video / sprdfb / lcd / lcd_ssd2075_mipi.c
1 /* drivers/video/sprdfb/lcd_ssd2075_mipi.c\r
2  *\r
3  * Support for ssd2075 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/sprd_lcd.h>\r
18 #include "../sprdfb.h"\r
19 \r
20 #define printk printf\r
21 \r
22 #define  LCD_DEBUG\r
23 #ifdef LCD_DEBUG\r
24 #define LCD_PRINT printk\r
25 #else\r
26 #define LCD_PRINT(...)\r
27 #endif\r
28 \r
29 #define MAX_DATA   48\r
30 \r
31 typedef struct LCM_Init_Code_tag {\r
32         unsigned int tag;\r
33         unsigned char data[MAX_DATA];\r
34 }LCM_Init_Code;\r
35 \r
36 typedef struct LCM_force_cmd_code_tag{\r
37         unsigned int datatype;\r
38         LCM_Init_Code real_cmd_code;\r
39 }LCM_Force_Cmd_Code;\r
40 \r
41 #define LCM_TAG_SHIFT 24\r
42 #define LCM_TAG_MASK  ((1 << 24) -1)\r
43 #define LCM_SEND(len) ((1 << LCM_TAG_SHIFT)| len)\r
44 #define LCM_SLEEP(ms) ((2 << LCM_TAG_SHIFT)| ms)\r
45 //#define ARRAY_SIZE(array) ( sizeof(array) / sizeof(array[0]))\r
46 \r
47 #define LCM_TAG_SEND  (1<< 0)\r
48 #define LCM_TAG_SLEEP (1 << 1)\r
49 \r
50 static LCM_Init_Code init_data[] = {\r
51  {LCM_SEND(2),{0xE1,0x93}},\r
52  {LCM_SEND(2),{0xB3,0x00}},\r
53  //5inchGIP\r
54  {LCM_SEND(7),{5,0,0xB6,0x16,0x0F,0x00,0x77}}, //0x00\r
55  {LCM_SEND(11),{9,0,0xB8,0x00,0x06,0x08,0x00,0x07,0x09,0x23,0x04}},\r
56  {LCM_SEND(9),{7,0,0xB9,0x04,0x08,0x22,0xFF,0xFF,0x0F}},\r
57  {LCM_SEND(11),{9,0,0xBA,0x0E,0x0E,0x10,0x10,0x0A,0x0A,0x0C,0x0C}},\r
58  {LCM_SEND(11),{9,0,0xBB,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1}},\r
59  {LCM_SEND(11),{9,0,0xBC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},\r
60  {LCM_SEND(11),{9,0,0xBD,0x0F,0x0F,0x11,0x11,0x0B,0x0B,0x0D,0x0D}},\r
61  {LCM_SEND(11),{9,0,0xBE,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1,0xA1}},\r
62  {LCM_SEND(11),{9,0,0xBF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},\r
63  {LCM_SEND(6),{4,0,0xB1,0x06,0x44,0x10}},\r
64  {LCM_SEND(8),{6,0,0xE0,0x11,0x02,0x04,0x00,0x01}},\r
65 \r
66  //Gamma2.2\r
67  #if 1\r
68  {LCM_SEND(9),{7,0,0xD0,0x00,0x00,0x0E,0x0F,0x14,0x20}},\r
69  {LCM_SEND(8),{6,0,0xD1,0x1A,0x37,0x29,0x1B,0x08}},\r
70  {LCM_SEND(9),{7,0,0xD2,0x00,0x00,0x0E,0x0F,0x14,0x20}},\r
71  {LCM_SEND(8),{6,0,0xD3,0x1A,0x37,0x29,0x1B,0x08}},\r
72  {LCM_SEND(9),{7,0,0xD4,0x00,0x00,0x0E,0x0F,0x14,0x20}},\r
73  {LCM_SEND(8),{6,0,0xD5,0x1A,0x37,0x29,0x1B,0x08}},\r
74  {LCM_SEND(9),{7,0,0xD6,0x00,0x00,0x0E,0x0F,0x14,0x20}},\r
75  {LCM_SEND(8),{6,0,0xD7,0x1A,0x37,0x29,0x1B,0x08}},\r
76  {LCM_SEND(9),{7,0,0xD8,0x00,0x00,0x0E,0x0F,0x14,0x20}},\r
77  {LCM_SEND(8),{6,0,0xD9,0x1A,0x37,0x29,0x1B,0x08}},\r
78  {LCM_SEND(9),{7,0,0xDA,0x00,0x00,0x0E,0x0F,0x14,0x20}},\r
79  {LCM_SEND(8),{6,0,0xDB,0x1A,0x37,0x29,0x1B,0x08}},\r
80  #else\r
81  {LCM_SEND(9),{7,0,0xD0,0x00,0x00,0x1E,0x27,0x2D,0x35}},\r
82  {LCM_SEND(8),{6,0,0xD1,0x2D,0x27,0x1A,0x1B,0x0A}},\r
83  {LCM_SEND(9),{7,0,0xD2,0x00,0x00,0x1E,0x27,0x2D,0x35}},\r
84  {LCM_SEND(8),{6,0,0xD3,0x2D,0x27,0x1A,0x1B,0x0A}},\r
85  {LCM_SEND(9),{7,0,0xD4,0x00,0x00,0x1E,0x27,0x2D,0x35}},\r
86  {LCM_SEND(8),{6,0,0xD5,0x26,0x2B,0x23,0x1B,0x0A}},\r
87  {LCM_SEND(9),{7,0,0xD6,0x00,0x00,0x1E,0x27,0x2D,0x35}},\r
88  {LCM_SEND(8),{6,0,0xD7,0x2D,0x27,0x1A,0x1B,0x0A}},\r
89  {LCM_SEND(9),{7,0,0xD8,0x00,0x00,0x1E,0x27,0x2D,0x35}},\r
90  {LCM_SEND(8),{6,0,0xD9,0x2D,0x27,0x1A,0x1B,0x0A}},\r
91  {LCM_SEND(9),{7,0,0xDA,0x00,0x00,0x1E,0x27,0x2D,0x35}},\r
92  {LCM_SEND(8),{6,0,0xDB,0x2D,0x27,0x1A,0x1B,0x0A}},\r
93  #endif\r
94 \r
95  {LCM_SEND(7),{5,0,0x70,0xD8,0x00,0xFF,0x80}},\r
96  {LCM_SEND(2),{0xFF,0x01}},\r
97 \r
98  {LCM_SEND(5),{3,0,0xC6,0xCC,0x33}},//77->CC\r
99  {LCM_SEND(5),{3,0,0xDE,0x9D,0x30}},\r
100  {LCM_SEND(2),{0x14,0x00}},\r
101 \r
102  {LCM_SEND(2),{0xE9,0x07}},\r
103  {LCM_SEND(5),{3,0,0xED,0x60,0x10}},\r
104  {LCM_SEND(2),{0xEC,0x12}},\r
105  {LCM_SEND(7),{5,0,0xCD,0x77,0x7B,0x34,0x08}},\r
106  {LCM_SEND(10),{8,0,0xC3,0x03,0x0D,0x34,0x05,0x01,0x44,0x54}},\r
107  {LCM_SEND(8),{6,0,0xC4,0x02,0x03,0x3D,0x3D,0x5A}}, // Vcom\r
108  {LCM_SEND(6),{4,0,0xCB,0xDF,0x80,0x00}},\r
109  {LCM_SEND(6),{4,0,0xEA,0x15,0x28,0x00}},\r
110  {LCM_SEND(7),{5,0,0xF0,0x38,0x00,0x00,0x00}},\r
111  {LCM_SEND(6),{4,0,0xC9,0x60,0x00,0x82}},\r
112  {LCM_SEND(11),{9,0,0xB5,0x00,0x05,0x05,0x1E,0x04,0x40,0x20,0xFC}},\r
113  {LCM_SEND(2),{0x36,0x0B}},//08->0B rotate 180\r
114  {LCM_SEND(2),{0x3A,0x70}},\r
115  {LCM_SEND(1),{0x11}},\r
116  {LCM_SLEEP(120)},\r
117  {LCM_SEND(1),{0x29}},\r
118  };\r
119 \r
120 \r
121 static LCM_Init_Code disp_on =  {LCM_SEND(1), {0x29}};\r
122 \r
123 static LCM_Init_Code sleep_in =  {LCM_SEND(1), {0x10}};\r
124 \r
125 static LCM_Init_Code sleep_out =  {LCM_SEND(1), {0x11}};\r
126 \r
127 static int32_t ssd2075_mipi_init(struct panel_spec *self)\r
128 {\r
129         int32_t i;\r
130         LCM_Init_Code *init = init_data;\r
131         unsigned int tag;\r
132 \r
133         mipi_set_cmd_mode_t mipi_set_cmd_mode = self->info.mipi->ops->mipi_set_cmd_mode;\r
134         mipi_gen_write_t mipi_gen_write = self->info.mipi->ops->mipi_gen_write;\r
135         mipi_eotp_set_t mipi_eotp_set = self->info.mipi->ops->mipi_eotp_set;\r
136 \r
137         LCD_PRINT("lcd_ssd2075_init\n");\r
138 \r
139         mipi_set_cmd_mode();\r
140         mipi_eotp_set(1,0);\r
141 \r
142         for(i = 0; i < ARRAY_SIZE(init_data); i++){\r
143                 tag = (init->tag >>24);\r
144                 if(tag & LCM_TAG_SEND){\r
145                         mipi_gen_write(init->data, (init->tag & LCM_TAG_MASK));\r
146                         udelay(20);\r
147                 }else if(tag & LCM_TAG_SLEEP){\r
148                         mdelay((init->tag & LCM_TAG_MASK));\r
149                 }\r
150                 init++;\r
151         }\r
152         mipi_eotp_set(1,1);\r
153 \r
154         return 0;\r
155 }\r
156 \r
157 static uint32_t ssd2075_readid(struct panel_spec *self)\r
158 {\r
159         int32_t i = 0;\r
160         uint32 j =0;\r
161         uint8_t read_data[10] = {0};\r
162         int32_t read_rtn = 0;\r
163         uint8_t param[2] = {0};\r
164         mipi_set_cmd_mode_t mipi_set_cmd_mode = self->info.mipi->ops->mipi_set_cmd_mode;\r
165         mipi_force_write_t mipi_force_write = self->info.mipi->ops->mipi_force_write;\r
166         mipi_force_read_t mipi_force_read = self->info.mipi->ops->mipi_force_read;\r
167         mipi_eotp_set_t mipi_eotp_set = self->info.mipi->ops->mipi_eotp_set;\r
168 \r
169         LCD_PRINT("lcd_ssd2075_mipi read id!\n");\r
170         mipi_set_cmd_mode();\r
171         mipi_eotp_set(1,0);\r
172 \r
173         for(j = 0; j < 4; j++){\r
174                 param[0] = 0x0a;\r
175                 param[1] = 0x00;\r
176                 mipi_force_write(0x37, param, 2);\r
177                 read_rtn = mipi_force_read(0xA1,10,(uint8_t *)read_data);\r
178                 LCD_PRINT("lcd_ssd2075_mipi read id 0xA1 value is 0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x!\n", read_data[0], read_data[1], \\r
179                 read_data[2], read_data[3],read_data[4], read_data[5],read_data[6], read_data[7],read_data[8], read_data[9]);\r
180 \r
181                 if((0x20 == read_data[0])&&(0x75 == read_data[1])){\r
182                         LCD_PRINT("lcd_ssd2075_mipi read id success!\n");\r
183                         mipi_eotp_set(1,1);\r
184                         return 0x2075;\r
185                 }\r
186         }\r
187         mipi_eotp_set(1,1);\r
188 \r
189         return 0;\r
190 }\r
191 \r
192 static struct panel_operations lcd_ssd2075_mipi_operations = {\r
193         .panel_init = ssd2075_mipi_init,\r
194         .panel_readid = ssd2075_readid,\r
195 };\r
196 \r
197 static struct timing_rgb lcd_ssd2075_mipi_timing = {\r
198         .hfp =50,\r
199         .hbp = 36,\r
200         .hsync =16,\r
201         .vfp = 12,\r
202         .vbp = 14,\r
203         .vsync = 2,\r
204 };\r
205 \r
206 \r
207 static struct info_mipi lcd_ssd2075_mipi_info = {\r
208         .work_mode  = SPRDFB_MIPI_MODE_VIDEO,\r
209         .video_bus_width = 24, /*18,16*/\r
210         .lan_number =   4,\r
211         .phy_feq =500*1000,\r
212         .h_sync_pol = SPRDFB_POLARITY_POS,\r
213         .v_sync_pol = SPRDFB_POLARITY_POS,\r
214         .de_pol = SPRDFB_POLARITY_POS,\r
215         .te_pol = SPRDFB_POLARITY_POS,\r
216         .color_mode_pol = SPRDFB_POLARITY_NEG,\r
217         .shut_down_pol = SPRDFB_POLARITY_NEG,\r
218         .timing = &lcd_ssd2075_mipi_timing,\r
219         .ops = NULL,\r
220 };\r
221 \r
222 struct panel_spec lcd_ssd2075_mipi_spec = {\r
223         .width = 720,\r
224         .height = 1280,\r
225         .fps = 60,\r
226         .type = LCD_MODE_DSI,\r
227         .direction = LCD_DIRECT_NORMAL,\r
228         .is_need_reset = 1,     /*need reset after the former panel init*/\r
229         .info = {\r
230                 .mipi = &lcd_ssd2075_mipi_info\r
231         },\r
232         .ops = &lcd_ssd2075_mipi_operations,\r
233 };\r