tizen 2.4 release
[profile/mobile/platform/kernel/u-boot-tm1.git] / drivers / video / sprdfb / lcd / lcd_nt51017_mipi_lvds.c
1 /* drivers/video/sprdfb/lcd_nt51017_mipi_lvds.c
2  *
3  * Support for nt51017 lvds LCD device
4  *
5  * Copyright (C) 2013 Spreadtrum
6  *
7  * This software is licensed under the terms of the GNU General Public
8  * License version 2, as published by the Free Software Foundation, and
9  * may be copied, distributed, and modified under those terms.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  */
16 #include <asm/arch/sprd_lcd.h>
17 //#include <asm/arch/sprd_i2c.h>
18 #include <asm/arch/sci_types.h>
19 #include "sp8830_i2c.h"
20 //#include "sc8830_i2c_cfg.h"
21
22 #include "../sprdfb.h"
23
24 #define printk printf
25
26 //#define  LCD_DEBUG
27 #ifdef LCD_DEBUG
28 #define LCD_PRINT printk
29 #else
30 #define LCD_PRINT(...)
31 #endif
32
33 /***************** Important Macro! *****************/
34 /* For TI! ONLY ONE of the flowing marco can be defined! */
35 //#define LINES_ALL_RIGHT_TI
36 #define LINES_ONLY_CLK_RIGHT_TI
37
38 /* For CHIPONE! ONLY ONE of the flowing marco can be defined! */
39 //#ifdef CONFIG_SHARK_PAD_HW_V102  // 5735A-2 v1.0.2 & 5735C-1 v1.0.0
40 #if 1
41 #define LINES_ALL_WRONG_C1
42 #else  // 5735A-2 v1.0.1
43 #define LINES_ALL_RIGHT_C1
44 #endif
45 /***************** Important Macro! *****************/
46
47 struct bridge_ops {
48         int32_t (*init)(struct panel_spec *self);
49 };
50
51 static struct bridge_ops b_ops = {
52         .init = NULL,
53 };
54
55 #define ARRAY_SIZE(array) ( sizeof(array) / sizeof(array[0]))
56
57 #define I2CID_BRIDGE                2
58 #define I2C_NT50366_ADDR_WRITE      0x9E /* NT50366C 100_1111 0 */
59 #define I2C_NT51017_ADDR_WRITE      0xD0 /* NT51017 110_1000 0 */
60 #define I2C_BRIDGE_ADDR_WRITE0      0x58 /* 0101_100 0 ADDR=Low */
61 #define I2C_BRIDGE_ADDR_WRITE1      0x5A /* 0101_101 0 ADDR=High */
62 #define I2C_BRIDGE_ADDR             I2C_BRIDGE_ADDR_WRITE0
63
64 #define GPIOID_BRIDGE_EN  231
65 #define GPIOID_VDDPWR     232
66 #define GPIOID_ADDR       234 /* should modify pinmap */
67 #define GPIOID_LCDPWR     235
68
69 extern int sprd_gpio_direction_output(struct gpio_chip *chip, unsigned offset, int value);
70 extern int sprd_gpio_request(struct gpio_chip *chip, unsigned offset);
71
72 typedef struct I2C_Init_Code_tag {
73         uint8_t addr;
74         uint8_t val;
75 }I2C_Init_Code;
76
77 static I2C_DEV i2c_dev_bridge = {
78         .id = I2CID_BRIDGE,
79         .freq = 100*1000,
80         .bus = 2,
81         .slave_addr = I2C_BRIDGE_ADDR,
82         .reg_addr_num = 1,
83         .check_ack = 1,
84         .no_stop = 0,
85 };
86
87 const static I2C_Init_Code lvds_init_data_ti[] = {
88         {0x09, 0x00},
89                 {0x0A, 0x03},
90                 {0x0B, 0x18},
91                 {0x0D, 0x00},
92                 {0x10, 0x26},
93                 {0x11, 0x00},
94                 {0x12, 0x31},
95                 {0x13, 0x00},
96 #ifdef LINES_ALL_RIGHT_TI
97                 {0x18, 0x18},/* all the line is right */
98 #elif defined LINES_ONLY_CLK_RIGHT_TI
99         {0x18, 0xF8},/* only clock line is right */
100 #endif
101                 {0x19, 0x0C},/* 0x00 */
102                 {0x1A, 0x03},
103                 {0x1B, 0x00},
104                 {0x20, 0x00},
105                 {0x21, 0x03},
106                 {0x22, 0x00},
107                 {0x23, 0x00},
108                 {0x24, 0x00},
109                 {0x25, 0x00},
110                 {0x26, 0x00},
111                 {0x27, 0x00},
112                 {0x28, 0x20},
113                 {0x29, 0x00},
114                 {0x2A, 0x00},
115                 {0x2B, 0x00},
116                 {0x2C, 0x04},/*0x04*/
117                 {0x2D, 0x00},
118                 {0x2E, 0x00},
119                 {0x2F, 0x00},
120                 {0x30, 0x04},/*0x04*/
121                 {0x31, 0x00},
122                 {0x32, 0x00},
123                 {0x33, 0x00},
124                 {0x34, 0x4C},
125                 {0x35, 0x00},
126                 {0x36, 0x00},
127                 {0x37, 0x00},
128                 {0x38, 0x00},
129                 {0x39, 0x00},
130                 {0x3A, 0x00},
131                 {0x3B, 0x00},
132                 {0x3C, 0x00},
133                 {0x3D, 0x00},
134                 {0x3E, 0x00},
135 };
136 const static I2C_Init_Code lvds_init_data_c1[] = {
137         /*{0x10, 0x4E},add*/
138         {0x20, 0x00},
139                 {0x21, 0x00},
140                 {0x22, 0x43},
141                 {0x23, 0x28},
142                 {0x24, 0x04},
143                 {0x25, 0x4C},
144                 {0x26, 0x00},
145                 {0x27, 0x12},
146         {0x28, 0x04},/*0x02*/
147                 {0x29, 0x13},
148                 {0x2A, 0x01},
149                 {0x34, 0xF0},/*add*/
150                 {0x36, 0x50},/*add*/
151                 {0x86, 0x2B},
152                 {0xB5, 0xA0},
153                 {0x51, 0x20},
154                 {0x56, 0x92},
155                 {0x69, 0x1C},/*0x1F*/
156                 {0x6B, 0x22},
157                 {0x5C, 0xFF},
158                 {0xB6, 0x20},
159 #ifdef LINES_ALL_RIGHT_C1
160         {0x13, 0x10},
161 #elif defined LINES_ONLY_CLK_RIGHT_C1
162         {0x13, 0x1F},
163 #elif defined LINES_ALL_WRONG_C1
164                 {0x13, 0x5F},
165 #endif
166                 /*{0x10, 0x47},add*/
167                 /*{0x2A, 0x31},modify*/
168                 /*{0x2E, 0x40},add*/
169                 /*{0x2F, 0x40},add*/
170                 {0x09, 0x10},
171                 /*{0x7B, 0xF2},*/
172         /*{0x7C, 0xF3},*/
173 };
174
175 /* Init SN65DSI83 */
176 static int32_t sn65dsi83_init(struct panel_spec *self)
177 {
178         int32_t i = 0;
179         int32 handle = 0;
180         uint32 err_code = 0;
181         
182     uint8 ti_pll_en = lvds_init_data_ti[3].val | 0x01;               /* (CSR 0x0D.0) */
183     uint8 ti_soft_reset = lvds_init_data_ti[0].val | 0x01;           /* (CSR 0x09.0) */
184
185         mipi_set_lp_mode_t mipi_set_lp_mode = self->info.mipi->ops->mipi_set_lp_mode;/* u-boot\arch\arm\include\asm\arch\sprd_lcd.h */
186         mipi_set_hs_mode_t mipi_set_hs_mode = self->info.mipi->ops->mipi_set_hs_mode;
187         mipi_set_video_mode_t mipi_set_video_mode = self->info.mipi->ops->mipi_set_video_mode;
188
189         LCD_PRINT("sn65dsi83_init\n");
190         
191     /* step 1 : All DSI into LP11*/
192         mipi_set_lp_mode();
193
194         /* step 2 : Set EN*/
195         sprd_gpio_request(NULL, GPIOID_BRIDGE_EN);
196         sprd_gpio_direction_output(NULL, GPIOID_BRIDGE_EN, 0);
197         mdelay(30);
198         sprd_gpio_direction_output(NULL, GPIOID_BRIDGE_EN, 1);
199
200         /* step 3 : Delay*/
201         mdelay(10);
202
203     /* open i2c */
204     handle = I2C_HAL_Open(&i2c_dev_bridge);
205         
206         /* step 4 : init CSR reg*/
207         for(i=0; i<ARRAY_SIZE(lvds_init_data_ti); i++){
208                 err_code = I2C_HAL_Write(handle, &lvds_init_data_ti[i].addr, &lvds_init_data_ti[i].val, 1);
209                 LCD_PRINT("I2C Write Reg=0x%x, Val=0x%x, WriteBytes=%d\n",lvds_init_data_ti[i].addr, lvds_init_data_ti[i].val,err_code);
210         }
211
212         /* step 5 : Start the DSI video stream */
213         mipi_set_hs_mode();
214         mipi_set_video_mode();
215         mdelay(5);
216
217         /* step 6 : Set the PLL_EN bit(CSR 0x0D.0) */
218         err_code = I2C_HAL_Write(handle, &lvds_init_data_ti[3].addr, &ti_pll_en, 1);
219         LCD_PRINT("I2C Write Reg=0x%x, Val=0x%x, WriteBytes=%d\n",lvds_init_data_ti[3].addr, ti_pll_en,err_code);
220
221         /* step 7 : Wait for the PLL_LOCK bit to be set(CSR 0x0A.7) */
222         mdelay(5);
223     
224         /* step 8 : Set the SOFT_RESET bit (CSR 0x09.0) */
225         err_code = I2C_HAL_Write(handle, &lvds_init_data_ti[0].addr, &ti_soft_reset, 1);
226         LCD_PRINT("I2C Write Reg=0x%x, Val=0x%x, WriteBytes=%d\n",lvds_init_data_ti[0].addr, ti_soft_reset, err_code);
227
228     /* close i2c */
229         I2C_HAL_Close(handle);
230
231     return 0;
232 }
233
234 static int32_t chipone_init(struct panel_spec *self)
235 {
236     int32_t i = 0;
237         int32 handle = 0;
238         uint32 err_code = 0;
239
240     sprd_gpio_request(NULL, GPIOID_BRIDGE_EN);
241         sprd_gpio_direction_output(NULL, GPIOID_BRIDGE_EN, 1);
242     mdelay(10);
243
244     /* open i2c */
245     handle = I2C_HAL_Open(&i2c_dev_bridge);
246         
247         /* init CSR reg*/
248         for(i=0; i<ARRAY_SIZE(lvds_init_data_c1); i++){
249                 err_code = I2C_HAL_Write(handle, &lvds_init_data_c1[i].addr, &lvds_init_data_c1[i].val, 1);
250                 LCD_PRINT("I2C Write Reg=0x%x, Val=0x%x, WriteBytes=%d\n",lvds_init_data_c1[i].addr, lvds_init_data_c1[i].val,err_code);
251         }
252
253     /* close i2c */
254         I2C_HAL_Close(handle);
255
256     return 0;
257 }
258
259 static int32_t get_bridge_info(struct panel_spec *self)
260 {
261         uint8_t reg = 0x00;
262         uint8_t flag = 0xFF;
263         int32 handle = 0;
264         uint32 err_code = 0;
265
266         sprd_gpio_request(NULL, GPIOID_BRIDGE_EN);
267         sprd_gpio_direction_output(NULL, GPIOID_BRIDGE_EN, 0);
268         mdelay(30);
269         sprd_gpio_direction_output(NULL, GPIOID_BRIDGE_EN, 1);
270         mdelay(5);
271
272         sprd_gpio_request(NULL, GPIOID_ADDR);
273         sprd_gpio_direction_output(NULL, GPIOID_ADDR, 0);//drive ADDR to low
274         mdelay(5);
275
276         /* open i2c */
277     handle = I2C_HAL_Open(&i2c_dev_bridge);
278
279         err_code = I2C_HAL_Read(handle, &reg, &flag, 1);
280         if (0 == err_code) {
281                 printf("I2C Read Error! err_code=%d\n", err_code);
282                 return 1;
283         }
284
285         if (0x35 == flag){//TI
286                 b_ops.init = sn65dsi83_init;
287                 printf("sprdfb: MIPI to LVDS bridge is TI SN65DSI83!\n");
288         } else if (0xC1 == flag) {//ChipOne
289                 b_ops.init = chipone_init;
290                 printf("sprdfb: MIPI to LVDS bridge is ChpOne!\n");
291         } else {
292                 printf("sprdfb: Unknown bridge! flag=0x%x\n",flag);
293                 I2C_HAL_Close(handle);
294                 return 1;
295         }
296
297         /* close i2c */
298         I2C_HAL_Close(handle);
299
300         return 0;
301 }
302
303 static int32_t nt51017_mipi_lvds_init(struct panel_spec *self)
304 {       
305         LCD_PRINT("lcd_nt51017_mipi_lvds_init\n");
306
307         if (b_ops.init) {
308                 b_ops.init(self);
309     }
310
311         sprd_gpio_request(NULL, GPIOID_VDDPWR);
312         sprd_gpio_direction_output(NULL, GPIOID_VDDPWR, 1);
313         mdelay(5);
314
315         sprd_gpio_request(NULL, GPIOID_LCDPWR);
316         sprd_gpio_direction_output(NULL, GPIOID_LCDPWR, 1);
317         mdelay(5);
318
319         return 0;
320 }
321
322 static uint32_t nt51017_mipi_lvds_readid(struct panel_spec *self)
323 {
324         LCD_PRINT("nt51017_mipi_lvds_readid\n");
325
326         if(get_bridge_info(self)){
327                 printk("u-boot get bridge info fail!\n");
328                 return 0x00;
329         }
330
331     return 0xC749;/*51017*/
332 }
333
334 static struct panel_operations lcd_nt51017_mipi_lvds_operations = {
335         .panel_init = nt51017_mipi_lvds_init,
336         .panel_readid = nt51017_mipi_lvds_readid,
337 };
338
339 static struct timing_rgb lcd_nt51017_mipi_lvds_timing = {
340         .hfp = 110,  /* unit: pixel */
341         .hbp = 76,
342         .hsync = 4,//4
343         .vfp = 18, /*unit: line*/
344         .vbp = 19,
345         .vsync = 4,
346 };
347
348 static struct info_mipi lcd_nt51017_mipi_lvds_info = {
349         .work_mode  = SPRDFB_MIPI_MODE_VIDEO,
350         .video_bus_width = 24, /*18,16*/
351         .lan_number = 4,
352         .phy_feq = 512*1000,/*494*/
353         .h_sync_pol = SPRDFB_POLARITY_POS,
354         .v_sync_pol = SPRDFB_POLARITY_POS,
355         .de_pol = SPRDFB_POLARITY_POS,
356         .te_pol = SPRDFB_POLARITY_POS,
357         .color_mode_pol = SPRDFB_POLARITY_NEG,
358         .shut_down_pol = SPRDFB_POLARITY_NEG,
359         .timing = &lcd_nt51017_mipi_lvds_timing,
360         .ops = NULL,
361 };
362
363 struct panel_spec lcd_nt51017_mipi_lvds_spec = {
364         //.cap = PANEL_CAP_NOT_TEAR_SYNC,
365         .width = 768,
366         .height = 1024,
367         .fps = 60,
368         .type = LCD_MODE_DSI,
369         .direction = LCD_DIRECT_NORMAL,
370         .info = {
371                 .mipi = &lcd_nt51017_mipi_lvds_info
372         },
373         .ops = &lcd_nt51017_mipi_lvds_operations,
374 };
375
376
377
378