tizen 2.4 release
[profile/mobile/platform/kernel/u-boot-tm1.git] / drivers / video / sprdfb / lcd / lcd_jd9161_mipi.c
1 /* drivers/video/sprdfb/lcd_jd9161_mipi.c\r
2  *\r
3  * Support for jd9161 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(6), {4,0,0xBF,0x91,0x61,0xF2}},\r
52         {LCM_SLEEP(1)},\r
53         {LCM_SEND(5), {3,0,0xB3,0x00,0x7F}},//VCOM\r
54         {LCM_SLEEP(1)},\r
55         {LCM_SEND(5), {3,0,0xB4,0x00,0x7F}},//VCOM_R\r
56         {LCM_SLEEP(1)},\r
57         {LCM_SEND(9), {7,0,0xB8,0x00,0xB6,0x01,0x00,0xB6,0x01}},//VGMP, VGSP, VGMN  \r
58         {LCM_SLEEP(1)},         \r
59         {LCM_SEND(6), {4,0,0xBA,0x34,0x23,0x00}},//GIP output volta\r
60         {LCM_SLEEP(1)},\r
61         {LCM_SEND(2), {0xC3,0x02}},//column\r
62         {LCM_SLEEP(1)},\r
63         {LCM_SEND(5), {3,0,0xC4,0x00,0x64}},//TCON\r
64         {LCM_SLEEP(1)},\r
65         {LCM_SEND(12), {10,0,0xC7,0x00,0x01,0x32,0x05,0x65,0x2C,0x13,0xA5,0xA5}},//POWER CTRL\r
66         {LCM_SLEEP(1)},\r
67         //Gamma\r
68         {LCM_SEND(41), {39,0,0xC8,0x74,0x70,0x2C,0x3A,0x1C,0x11,0x17,0x06,0x24,0x29,\r
69                         0x2F,0x55,0x4B,0x5D,0x58,0x61,0x5D,0x57,0x50,\r
70                                   0x74,0x70,0x2C,0x3A,0x1C,0x11,0x17,0x06,0x24,0x29,\r
71                         0x2F,0x55,0x4B,0x5D,0x58,0x61,0x5D,0x57,0x50}},\r
72         {LCM_SLEEP(1)},\r
73         {LCM_SEND(19), {17,0,0xD4,0x1F,0x1E,0x1F,0x00,0x10,0x1F,0x1F,0x04,0x08,0x06,\r
74                         0x0A,0x1F,0x1F,0x1F,0x1F,0x1F}},                                //SET GIP_L\r
75         {LCM_SLEEP(1)},\r
76         {LCM_SEND(19), {17,0,0xD5,0x1F,0x1E,0x1F,0x01,0x11,0x1F,0x1F,0x05,0x09,0x07,\r
77                         0x0B,0x1F,0x1F,0x1F,0x1F,0x1F}},                                //SET GIP_R\r
78         {LCM_SLEEP(1)},\r
79         {LCM_SEND(19), {17,0,0xD6,0x1F,0x1F,0x1E,0x11,0x01,0x1F,0x1F,0x0B,0x07,0x09,\r
80                         0x05,0x1F,0x1F,0x1F,0x1F,0x1F}},                                //SET GIP_GS_L\r
81         {LCM_SLEEP(1)},\r
82         {LCM_SEND(19), {17,0,0xD7,0x1F,0x1F,0x1E,0x10,0x00,0x1F,0x1F,0x0A,0x06,0x08,\r
83                         0x04,0x1F,0x1F,0x1F,0x1F,0x1F}},                                //SET GIP_GS_R\r
84         {LCM_SLEEP(1)},\r
85         {LCM_SEND(23), {21,0,0xD8,0x20,0x02,0x0A,0x10,0x05,0x30,0x01,0x02,0x30,0x01,0x02,0x06,0x70,\r
86                         0x53,0x2C,0x73,0x09,0x06,0x70,0x08}},           //SET GIP1\r
87         {LCM_SLEEP(1)},\r
88         {LCM_SEND(22), {20,0,0xD9,0x00,0x0A,0x0A,0x88,0x00,0x00,0x06,0x7B,0x00,0x00,\r
89                         0x00,0x3B,0x2F,0x1F,0x00,0x00,0x00,0x03,0x7B}},                 //SET GIP2\r
90         {LCM_SLEEP(1)},\r
91         {LCM_SEND(1), {0x11}},//SLP OUT\r
92         {LCM_SLEEP(120)},\r
93         {LCM_SEND(1), {0x29}},//DISP ON\r
94         {LCM_SLEEP(50)},\r
95 \r
96  };\r
97 \r
98 static LCM_Force_Cmd_Code rd_prep_code[]={\r
99         {0x39, {LCM_SEND(6), {4,0,0xBF,0x91,0x61,0xF2}}},\r
100         {0x37, {LCM_SEND(2), {0x3, 0}}},\r
101 };\r
102 \r
103 static LCM_Init_Code disp_on =  {LCM_SEND(1), {0x29}};\r
104 \r
105 static LCM_Init_Code sleep_in =  {LCM_SEND(1), {0x10}};\r
106 \r
107 static LCM_Init_Code sleep_out =  {LCM_SEND(1), {0x11}};\r
108 \r
109 static int32_t jd9161_mipi_init(struct panel_spec *self)\r
110 {\r
111         int32_t i;\r
112         LCM_Init_Code *init = init_data;\r
113         unsigned int tag;\r
114 \r
115         mipi_set_cmd_mode_t mipi_set_cmd_mode = self->info.mipi->ops->mipi_set_cmd_mode;\r
116         mipi_gen_write_t mipi_gen_write = self->info.mipi->ops->mipi_gen_write;\r
117 \r
118          mipi_set_lp_mode_t mipi_set_lp_mode = self->info.mipi->ops->mipi_set_lp_mode;\r
119          mipi_set_hs_mode_t mipi_set_hs_mode = self->info.mipi->ops->mipi_set_hs_mode;\r
120         mipi_eotp_set_t mipi_eotp_set = self->info.mipi->ops->mipi_eotp_set;\r
121         printk("uboot lcd_jd9161_init\n");\r
122 \r
123         //mipi_set_cmd_mode();\r
124 \r
125         mdelay(5);\r
126         mipi_set_lp_mode();\r
127         //mipi_eotp_set(1,0);\r
128         for(i = 0; i < ARRAY_SIZE(init_data); i++){\r
129                 tag = (init->tag >>24);\r
130                 if(tag & LCM_TAG_SEND){\r
131                         mipi_gen_write(init->data, (init->tag & LCM_TAG_MASK));\r
132                         udelay(20);\r
133                 }else if(tag & LCM_TAG_SLEEP){\r
134                         mdelay((init->tag & LCM_TAG_MASK));\r
135                 }\r
136                 init++;\r
137         }\r
138 \r
139         mdelay(5);\r
140         mipi_set_hs_mode();\r
141         return 0;\r
142 }\r
143 \r
144 static uint32_t jd9161_readid(struct panel_spec *self)\r
145 {\r
146         /*Jessica TODO: need read id*/\r
147         int32_t i = 0;\r
148         uint32 j =0;\r
149         LCM_Force_Cmd_Code * rd_prepare = rd_prep_code;\r
150         uint8_t read_data[3] = {0};\r
151         int32_t read_rtn = 0;\r
152         unsigned int tag = 0;\r
153         mipi_set_cmd_mode_t mipi_set_cmd_mode = self->info.mipi->ops->mipi_set_cmd_mode;\r
154         mipi_force_write_t mipi_force_write = self->info.mipi->ops->mipi_force_write;\r
155         mipi_force_read_t mipi_force_read = self->info.mipi->ops->mipi_force_read;\r
156         mipi_set_lp_mode_t mipi_set_lp_mode = self->info.mipi->ops->mipi_set_lp_mode;\r
157         mipi_set_hs_mode_t mipi_set_hs_mode = self->info.mipi->ops->mipi_set_hs_mode;\r
158         mipi_eotp_set_t mipi_eotp_set = self->info.mipi->ops->mipi_eotp_set;\r
159 \r
160         //return 0x6; //cg liyun 20130329\r
161 \r
162         printk("uboot lcd_jd9161_mipi read id!\n");\r
163         #if 1\r
164         mipi_set_lp_mode();\r
165 \r
166         //mipi_set_cmd_mode();\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                                 mdelay((rd_prepare->real_cmd_code.tag & LCM_TAG_MASK));\r
176                         }\r
177                         rd_prepare++;\r
178                 }\r
179                 mdelay(50);\r
180                 read_rtn = mipi_force_read(0x04, 1,(uint8_t *)read_data);\r
181                 printk("lcd_jd9161_mipi read id 0x04 value is 0x%x!\n", read_data[0]);\r
182 \r
183                 if((0x91 == read_data[0])){\r
184                         printk("lcd_jd9161_mipi read id success!\n");\r
185                         return 0x916100;\r
186                 }\r
187         }\r
188 \r
189         mdelay(5);\r
190         mipi_set_hs_mode();\r
191         #endif\r
192         return 0;\r
193 }\r
194 \r
195 static struct panel_operations lcd_jd9161_mipi_operations = {\r
196         .panel_init = jd9161_mipi_init,\r
197         .panel_readid = jd9161_readid,\r
198 };\r
199 \r
200 static struct timing_rgb lcd_jd9161_mipi_timing = {\r
201         .hfp = 20,  /* unit: pixel */// 100\r
202         .hbp = 20,//80\r
203         .hsync = 20,//6\r
204         .vfp = 6, /*unit: line*/\r
205         .vbp = 6,\r
206         .vsync =6, //6,\r
207 };\r
208 \r
209 static struct info_mipi lcd_jd9161_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 = 450*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_jd9161_mipi_timing,\r
221         .ops = NULL,\r
222 };\r
223 \r
224 struct panel_spec lcd_jd9161_mipi_spec = {\r
225         //.cap = PANEL_CAP_NOT_TEAR_SYNC,\r
226         .width = 480,\r
227         .height = 800,\r
228         .fps = 60,\r
229         .type = LCD_MODE_DSI,\r
230         .direction = LCD_DIRECT_NORMAL,\r
231         .info = {\r
232                 .mipi = &lcd_jd9161_mipi_info\r
233         },\r
234         .ops = &lcd_jd9161_mipi_operations,\r
235 };\r
236 \r
237 \r