tizen 2.4 release
[kernel/u-boot-tm1.git] / drivers / video / sprdfb / lcd / lcd_fl10802_mipi.c
1 /* drivers/video/sc8825/lcd_fl10802_mipi.c\r
2  *\r
3  * Support for fl10802 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  80// 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 \r
52 \r
53 {LCM_SEND(6), {4,0,0xB9,0xF1,0x08,0x01}},\r
54 \r
55 {LCM_SEND(7), {5,0,0xB1,0x22,0x1E,0x1E,0x87}},\r
56 \r
57 {LCM_SEND(2), {0xB2,0x23}},\r
58 \r
59 {LCM_SEND(11), {9,0,0xB3,0x00,0x00,0x06,0x06,0x20,0x20,0x30,0x30}},\r
60 \r
61 {LCM_SEND(20), {18,0,0xBA,0x31,0x00,0x44,0x25,0x91,0x0A,0x00,0x00,0xC1,\r
62                            0x00,0x00,0x00,0x0D,0x02,0x4F,0xB9,0xEE}},\r
63 \r
64 {LCM_SEND(8), {6,0,0xE3,0x09,0x09,0x03,0x03,0x00}},\r
65 \r
66 {LCM_SEND(2), {0xB4,0x00}},\r
67 \r
68 {LCM_SEND(5), {3,0,0xB5,0x09,0x09}},\r
69 \r
70 {LCM_SEND(5), {3,0,0xB6,0x52,0x52}},//0x57\r
71 \r
72 {LCM_SEND(5), {3,0,0xB8,0x64,0x28}},\r
73 \r
74 {LCM_SEND(2), {0xCC,0x00}},\r
75 \r
76 {LCM_SEND(2), {0xBC,0x47}},\r
77 \r
78 {LCM_SEND(54), {52,0,0xE9,0x00,0x00,0x0F,0x03,0x36,0x0A,0x90,0x10,0x01,\r
79                                                                                  0x00,0x37,0x13,0x0A,0x90,0x37,0x00,0x00,0x18,0x00,\r
80                      0x00,0x00,0x25,0x09,0x80,0x40,0x00,0x42,0x60,0x00,\r
81                      0x00,0x00,0x09,0x81,0x50,0x01,0x53,0x70,0x00,0x00,\r
82                      0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\r
83                      0x00,0x00}},\r
84 \r
85 {LCM_SEND(25), {23,0,0xEA,0x94,0x00,0x00,0x00,0x08,0x95,0x10,0x07,0x35,\r
86                            0x10,0x00,0x00,0x00,0x08,0x94,0x00,0x06,0x24,0x00,\r
87                            0x00,0x00,0x00}},\r
88 \r
89 {LCM_SEND(37), {35,0,0xE0,0x00,0x00,0x00,0x09,0x09,0x3F,0x17,0x2C,0x02,\r
90                      0x0C,0x12,0x15,0x18,0x16,0x16,0x12,0x16,0x00,0x00,\r
91                      0x00,0x09,0x09,0x3F,0x17,0x2C,0x02,0x0C,0x12,0x15,\r
92                      0x18,0x16,0x16,0x12,0x16}},\r
93 \r
94 \r
95 \r
96 {LCM_SEND(2), {0x11,0x00}},\r
97 {LCM_SLEEP(120),},\r
98 \r
99 {LCM_SEND(2), {0x29,0x00}},\r
100 {LCM_SLEEP(50),},\r
101 \r
102 };\r
103 \r
104 static LCM_Force_Cmd_Code rd_prep_code[]={\r
105     {0x39,LCM_SEND(6), {4,0,0xb9,0xf1,0x08,0x01}},\r
106     {0x39,LCM_SEND(20), {18,0,0xba,0x31,0x00,0x44,0x25,0xb1,0x0a,0x00,0x00,0xc1,0x00,0x00,0x00,0x0d,0x02,0x5d,0xb5,0xee}},\r
107   \r
108         {0x37,{LCM_SEND(2),{0x3,0}}},\r
109 };\r
110 \r
111 static LCM_Init_Code disp_on =  {LCM_SEND(1), {0x29}};\r
112 \r
113 static LCM_Init_Code sleep_in =  {LCM_SEND(1), {0x10}};\r
114 \r
115 static LCM_Init_Code sleep_out =  {LCM_SEND(1), {0x11}};\r
116 \r
117 static int32_t fl10802_mipi_init(struct panel_spec *self)\r
118 {\r
119         int32_t i;\r
120         LCM_Init_Code *init = init_data;\r
121         unsigned int tag;\r
122 \r
123         mipi_set_cmd_mode_t mipi_set_cmd_mode = self->info.mipi->ops->mipi_set_cmd_mode;\r
124         mipi_gen_write_t mipi_gen_write = self->info.mipi->ops->mipi_gen_write;\r
125         mipi_eotp_set_t mipi_eotp_set = self->info.mipi->ops->mipi_eotp_set;\r
126 \r
127         LCD_PRINT("fl10802_mipi_init\n");\r
128         printf("fl10802_mipi_init\n");\r
129 \r
130         mipi_set_cmd_mode();\r
131         mipi_eotp_set(1,0);\r
132 \r
133         for(i = 0; i < ARRAY_SIZE(init_data); i++){\r
134                 tag = (init->tag >>24);\r
135                 if(tag & LCM_TAG_SEND){\r
136                         mipi_gen_write(init->data, (init->tag & LCM_TAG_MASK));\r
137                         udelay(20);\r
138                 }else if(tag & LCM_TAG_SLEEP){\r
139                         mdelay((init->tag & LCM_TAG_MASK));\r
140                 }\r
141                 init++;\r
142         }\r
143         mipi_eotp_set(1,1);\r
144         return 0;\r
145 }\r
146 \r
147 static uint32_t fl10802_readid(struct panel_spec *self)\r
148 {\r
149                 /*Jessica TODO: need read id*/\r
150                 int32_t i = 0;\r
151                 uint32 j =0;\r
152                 LCM_Force_Cmd_Code * rd_prepare = rd_prep_code;\r
153                 uint8_t read_data[5] = {0};\r
154                 int32_t read_rtn = 0;\r
155                 unsigned int tag = 0;\r
156         \r
157                 mipi_set_cmd_mode_t mipi_set_cmd_mode = self->info.mipi->ops->mipi_set_cmd_mode;\r
158                 mipi_force_write_t mipi_force_write = self->info.mipi->ops->mipi_force_write;\r
159                 mipi_force_read_t mipi_force_read = self->info.mipi->ops->mipi_force_read;\r
160                 mipi_eotp_set_t mipi_eotp_set = self->info.mipi->ops->mipi_eotp_set;\r
161         \r
162                 printk("lcd_fl10802_mipi read id!\n");\r
163                 #if 1\r
164                 //self->info.mipi->ops->mipi_set_lp_mode(); \r
165                 mipi_set_cmd_mode(); \r
166                 mipi_eotp_set(1,0); \r
167                 for(j = 0; j < 4; j++){ \r
168                         rd_prepare = rd_prep_code; \r
169                         for(i = 0; i < ARRAY_SIZE(rd_prep_code); i++){\r
170                                 tag = (rd_prepare->real_cmd_code.tag >> 24); \r
171                                 if(tag & LCM_TAG_SEND){ \r
172                                         mipi_force_write(rd_prepare->datatype, rd_prepare->real_cmd_code.data, (rd_prepare->real_cmd_code.tag & LCM_TAG_MASK)); \r
173                                         udelay(20); \r
174                                 }else if(tag & LCM_TAG_SLEEP){ \r
175                                         udelay((rd_prepare->real_cmd_code.tag & LCM_TAG_MASK) * 1000); \r
176                                 } \r
177                                 rd_prepare++; \r
178                         }\r
179                         read_rtn = mipi_force_read(0x04, 3,(uint8_t *)read_data); \r
180                         printk("lcd_fl10802_mipi read id 0xa1 value is 0x%x, 0x%x, 0x%x!\n", read_data[0], read_data[1], read_data[2]); \r
181                         mipi_eotp_set(1,1); \r
182                         if((0x10 == read_data[0])&&(0x80== read_data[1])&&(0x1A == read_data[2])){ \r
183                                 printk("lcd_fl10802_mipi read id success!\n"); \r
184                                 return 0x1080; \r
185                         }\r
186                 }\r
187         #endif\r
188                 printk("lcd_fl10802_mipi identify fail!\n");\r
189                 //self->info.mipi->ops->mipi_set_hs_mode();\r
190                 return 0x0;\r
191 }\r
192 \r
193 \r
194 static struct panel_operations lcd_fl10802_mipi_operations = {\r
195         .panel_init = fl10802_mipi_init,\r
196         .panel_readid = fl10802_readid,\r
197 };\r
198 \r
199 static struct timing_rgb lcd_fl10802_mipi_timing = {\r
200         .hfp = 80,  /* unit: pixel */\r
201         .hbp = 80,\r
202         .hsync = 10,\r
203         .vfp = 18, /*unit: line*/\r
204         .vbp = 18,\r
205         .vsync = 4,\r
206 };\r
207 \r
208 \r
209 static struct info_mipi lcd_fl10802_mipi_info = {\r
210         .work_mode  = SPRDFB_MIPI_MODE_VIDEO,\r
211         .video_bus_width = 24, /*18,16*/\r
212         .lan_number = 2,\r
213         .phy_feq = 500*1000,\r
214         .h_sync_pol = SPRDFB_POLARITY_POS,\r
215         .v_sync_pol = SPRDFB_POLARITY_POS,\r
216         .de_pol = SPRDFB_POLARITY_POS,\r
217         //.te_pol = SPRDFB_POLARITY_POS,\r
218         .color_mode_pol = SPRDFB_POLARITY_NEG,\r
219         .shut_down_pol = SPRDFB_POLARITY_NEG,\r
220         .timing = &lcd_fl10802_mipi_timing,\r
221         .ops = NULL,\r
222 };\r
223 \r
224 \r
225 struct panel_spec lcd_fl10802_mipi_spec = {\r
226         .width = 480,\r
227         .height = 800,\r
228         .type = LCD_MODE_DSI,\r
229         .fps = 60,\r
230         .direction = LCD_DIRECT_NORMAL,\r
231         .info = {\r
232                 .mipi = &lcd_fl10802_mipi_info\r
233         },\r
234         .ops = &lcd_fl10802_mipi_operations,\r
235 };\r
236 \r
237 \r