1 #include <linux/string.h>
3 #include <linux/kernel.h>
7 // ---------------------------------------------------------------------------
9 // ---------------------------------------------------------------------------
11 #define FRAME_WIDTH (540)
12 #define FRAME_HEIGHT (960)
14 // ---------------------------------------------------------------------------
16 // ---------------------------------------------------------------------------
18 static LCM_UTIL_FUNCS lcm_util
= {0};
20 #define SET_RESET_PIN(v) (lcm_util.set_reset_pin((v)))
22 #define UDELAY(n) (lcm_util.udelay(n))
23 #define MDELAY(n) (lcm_util.mdelay(n))
24 #define REGFLAG_DELAY 0XFE
25 #define REGFLAG_END_OF_TABLE 0x00 // END OF REGISTERS MARKER
28 // ---------------------------------------------------------------------------
30 // ---------------------------------------------------------------------------
31 #define dsi_set_cmdq_V2(cmd, count, ppara, force_update) lcm_util.dsi_set_cmdq_V2(cmd, count, ppara, force_update)
32 #define dsi_set_cmdq(pdata, queue_size, force_update) lcm_util.dsi_set_cmdq(pdata, queue_size, force_update)
33 #define wrtie_cmd(cmd) lcm_util.dsi_write_cmd(cmd)
34 #define write_regs(addr, pdata, byte_nums) lcm_util.dsi_write_regs(addr, pdata, byte_nums)
35 //#define read_reg lcm_util.dsi_read_reg()
36 #define read_reg_v2(cmd, buffer, buffer_size) lcm_util.dsi_dcs_read_lcm_reg_v2(cmd, buffer, buffer_size)
40 #define LCM_DSI_CMD_MODE
42 struct LCM_setting_table
{
45 unsigned char para_list
[64];
49 static struct LCM_setting_table lcm_initialization_setting
[] = {
54 Data ID will depends on the following rule.
56 count of parameters > 1 => Data ID = 0x39
57 count of parameters = 1 => Data ID = 0x15
58 count of parameters = 0 => Data ID = 0x05
62 {DCS command, count of parameters, {parameter list}}
63 {REGFLAG_DELAY, milliseconds of time, {}},
67 Setting ending by predefined flag
69 {REGFLAG_END_OF_TABLE, 0x00, {}}
73 {0xff,4,{0xAA,0x55,0x25,0x01}},
74 {0xf3,4,{0x02,0x03,0x07,0x15}},
75 {0xF0,5,{0x55,0xAA,0x52,0x08,0x00}},
76 {0xB8,4,{0x01,0x02,0x02,0x02}},
77 {0xBC,3,{0x05,0x05,0x05}},
78 {0xF0,5,{0x55,0xAA,0x52,0x08,0x01}},
79 {0xB0,3,{0x05,0x05,0x05}},
80 {0xB1,3,{0x05,0x05,0x05}},
81 {0xB6,3,{0x44,0x44,0x44}},
82 {0xB7,3,{0x34,0x34,0x34}},
83 {0xB3,3,{0x10,0x10,0x10}},
84 {0xB9,3,{0x34,0x34,0x34}},
85 {0xB4,3,{0x0A,0x0A,0x0A}},
86 {0xBA,3,{0x14,0x14,0x14}},
87 {0xBC,3,{0x00,0xA0,0x00}},
88 {0xBD,3,{0x00,0xA0,0x00}},
90 {0xD1,16,{0x00,0x32,0x00,0x41,0x00,0x54,0x00,0x67,0x00,0x7A,0x00,0x98,0x00,0xB0,0x00,0xDB}} ,
91 {0xD2,16,{0x01,0x01,0x01,0x3F,0x01,0x70,0x01,0xB4,0x01,0xEC,0x01,0xED,0x02,0x1E,0x02,0x51}},
92 {0xD3,16,{0x02,0x6C,0x02,0x8D,0x02,0xA5,0x02,0xC9,0x02,0xEA,0x03,0x19,0x03,0x45,0x03,0x7A}},
93 {0xD4,4,{0x03,0xB0,0x03,0xF4}} ,
94 {0xD5,16,{0x00,0x32,0x00,0x41,0x00,0x54,0x00,0x67,0x00,0x7A,0x00,0x98,0x00,0xB0,0x00,0xDB}} ,
95 {0xD6,16,{0x01,0x01,0x01,0x3F,0x01,0x70,0x01,0xB4,0x01,0xEC,0x01,0xED,0x02,0x1E,0x02,0x51}},
96 {0xD7,16,{0x02,0x6C,0x02,0x8D,0x02,0xA5,0x02,0xC9,0x02,0xEA,0x03,0x19,0x03,0x45,0x03,0x7A}} ,
97 {0xD8,4,{0x03,0xB0,0x03,0xF4}} ,
98 {0xD9,16,{0x00,0x32,0x00,0x41,0x00,0x54,0x00,0x67,0x00,0x7A,0x00,0x98,0x00,0xB0,0x00,0xDB}},
99 {0xDD,16,{0x01,0x01,0x01,0x3F,0x01,0x70,0x01,0xB4,0x01,0xEC,0x01,0xED,0x02,0x1E,0x02,0x51}},
100 {0xDE,16,{0x02,0x6C,0x02,0x8D,0x02,0xA5,0x02,0xC9,0x02,0xEA,0x03,0x19,0x03,0x45,0x03,0x7A}} ,
101 {0xDF,4,{0x03,0xB0,0x03,0xF4}} ,
102 {0xE0,16,{0x00,0x32,0x00,0x41,0x00,0x54,0x00,0x67,0x00,0x7A,0x00,0x98,0x00,0xB0,0x00,0xDB}},
103 {0xE1,16,{0x01,0x01,0x01,0x3F,0x01,0x70,0x01,0xB4,0x01,0xEC,0x01,0xED,0x02,0x1E,0x02,0x51}} ,
104 {0xE2,16,{0x02,0x6C,0x02,0x8D,0x02,0xA5,0x02,0xC9,0x02,0xEA,0x03,0x19,0x03,0x45,0x03,0x7A}} ,
106 {0xE3,4,{0x03,0xB0,0x03,0xF4}} ,
107 {0xE4,16,{0x00,0x32,0x00,0x41,0x00,0x54,0x00,0x67,0x00,0x7A,0x00,0x98,0x00,0xB0,0x00,0xDB}},
108 {0xE5,16,{0x01,0x01,0x01,0x3F,0x01,0x70,0x01,0xB4,0x01,0xEC,0x01,0xED,0x02,0x1E,0x02,0x51}},
109 {0xEA,16,{0x02,0x6C,0x02,0x8D,0x02,0xA5,0x02,0xC9,0x02,0xEA,0x03,0x19,0x03,0x45,0x03,0x7A}} ,
110 {0xEB,4,{0x03,0xB0,0x03,0xF4}} ,
118 // Strongly recommend not to set Sleep out / Display On here. That will cause messed frame to be shown as later the backlight is on.
121 // Setting ending by predefined flag
122 {REGFLAG_END_OF_TABLE
, 0x00, {}}
124 static struct LCM_setting_table lcm_sleep_out_setting
[] = {
127 {REGFLAG_DELAY
, 20, {}},
131 {REGFLAG_DELAY
, 120, {}},
132 {REGFLAG_END_OF_TABLE
, 0x00, {}}
136 static struct LCM_setting_table lcm_sleep_mode_in_setting
[] = {
137 // Display off sequence
139 {REGFLAG_DELAY
, 200, {}},
143 {REGFLAG_DELAY
, 120, {}},
144 {REGFLAG_END_OF_TABLE
, 0x00, {}}
146 static struct LCM_setting_table lcm_compare_id_setting
[] = {
147 // Display off sequence
148 {0xF0, 5, {0x55, 0xaa, 0x52,0x08,0x00}},
149 {REGFLAG_DELAY
, 10, {}},
151 {REGFLAG_END_OF_TABLE
, 0x00, {}}
154 void push_table(struct LCM_setting_table
*table
, unsigned int count
, unsigned char force_update
)
158 for(i
= 0; i
< count
; i
++) {
166 MDELAY(table
[i
].count
);
169 case REGFLAG_END_OF_TABLE
:
173 dsi_set_cmdq_V2(cmd
, table
[i
].count
, table
[i
].para_list
, force_update
);
181 static void init_lcm_registers(void)
183 unsigned int data_array
[16];
185 // ---------------------------------------------------------------------------
186 // LCM Driver Implementations
187 // ---------------------------------------------------------------------------
189 static void lcm_set_util_funcs(const LCM_UTIL_FUNCS
*util
)
191 memcpy(&lcm_util
, util
, sizeof(LCM_UTIL_FUNCS
));
195 static void lcm_get_params(LCM_PARAMS
*params
)
197 memset(params
, 0, sizeof(LCM_PARAMS
));
199 params
->type
= LCM_TYPE_DSI
;
201 params
->width
= FRAME_WIDTH
;
202 params
->height
= FRAME_HEIGHT
;
204 // enable tearing-free
205 params
->dbi
.te_mode
= LCM_DBI_TE_MODE_VSYNC_ONLY
;
206 params
->dbi
.te_edge_polarity
= LCM_POLARITY_RISING
;
208 #if defined(LCM_DSI_CMD_MODE)
209 params
->dsi
.mode
= CMD_MODE
;
211 params
->dsi
.mode
= SYNC_PULSE_VDO_MODE
;
215 /* Command mode setting */
216 params
->dsi
.LANE_NUM
= LCM_TWO_LANE
;
217 //The following defined the fomat for data coming from LCD engine.
218 params
->dsi
.data_format
.color_order
= LCM_COLOR_ORDER_RGB
;
219 params
->dsi
.data_format
.trans_seq
= LCM_DSI_TRANS_SEQ_MSB_FIRST
;
220 params
->dsi
.data_format
.padding
= LCM_DSI_PADDING_ON_LSB
;
221 params
->dsi
.data_format
.format
= LCM_DSI_FORMAT_RGB888
;
223 // Highly depends on LCD driver capability.
224 // Not support in MT6573
226 params
->dsi
.DSI_WMEM_CONTI
=0x3C;
227 params
->dsi
.DSI_RMEM_CONTI
=0x3E;
230 params
->dsi
.packet_size
=256;
232 // Video mode setting
233 params
->dsi
.intermediat_buffer_num
= 2;
235 params
->dsi
.PS
=LCM_PACKED_PS_24BIT_RGB888
;
237 params
->dsi
.vertical_sync_active
= 3;
238 params
->dsi
.vertical_backporch
= 12;
239 params
->dsi
.vertical_frontporch
= 2;
240 params
->dsi
.vertical_active_line
= FRAME_HEIGHT
;
242 params
->dsi
.horizontal_sync_active
= 10;
243 params
->dsi
.horizontal_backporch
= 50;
244 params
->dsi
.horizontal_frontporch
= 50;
245 params
->dsi
.horizontal_active_pixel
= FRAME_WIDTH
;
249 // Bit rate calculation
250 params
->dsi
.pll_div1
=38; // fref=26MHz, fvco=fref*(div1+1) (div1=0~63, fvco=500MHZ~1GHz)
251 params
->dsi
.pll_div2
=1; // div2=0~15: fout=fvo/(2*div2)
256 static void lcm_init(void)
264 push_table(lcm_initialization_setting
, sizeof(lcm_initialization_setting
) / sizeof(struct LCM_setting_table
), 1);
269 static void lcm_suspend(void)
271 //push_table(lcm_sleep_mode_in_setting, sizeof(lcm_sleep_mode_in_setting) / sizeof(struct LCM_setting_table), 1);
275 unsigned int data_array
[2];
277 //data_array[0] = 0x00000504; // Display Off
278 //dsi_set_cmdq(&data_array, 1, 1);
280 data_array
[0] = 0x00280500; // Display Off
281 dsi_set_cmdq(&data_array
, 1, 1);
283 data_array
[0] = 0x00100500; // Sleep In
284 dsi_set_cmdq(&data_array
, 1, 1);
288 printf("zhibin uboot %s\n", __func__
);
290 printk("zhibin kernel %s\n", __func__
);
296 static void lcm_resume(void)
300 printf("zhibin uboot %s\n", __func__
);
302 printk("zhibin kernel %s\n", __func__
);
305 push_table(lcm_sleep_out_setting
, sizeof(lcm_sleep_out_setting
) / sizeof(struct LCM_setting_table
), 1);
310 static void lcm_update(unsigned int x
, unsigned int y
,
311 unsigned int width
, unsigned int height
)
315 unsigned int x1
= x0
+ width
- 1;
316 unsigned int y1
= y0
+ height
- 1;
318 unsigned char x0_MSB
= ((x0
>>8)&0xFF);
319 unsigned char x0_LSB
= (x0
&0xFF);
320 unsigned char x1_MSB
= ((x1
>>8)&0xFF);
321 unsigned char x1_LSB
= (x1
&0xFF);
322 unsigned char y0_MSB
= ((y0
>>8)&0xFF);
323 unsigned char y0_LSB
= (y0
&0xFF);
324 unsigned char y1_MSB
= ((y1
>>8)&0xFF);
325 unsigned char y1_LSB
= (y1
&0xFF);
327 unsigned int data_array
[16];
330 printf("zhibin uboot %s\n", __func__
);
332 printk("zhibin kernel %s\n", __func__
);
335 data_array
[0]= 0x00053902;
336 data_array
[1]= (x1_MSB
<<24)|(x0_LSB
<<16)|(x0_MSB
<<8)|0x2a;
337 data_array
[2]= (x1_LSB
);
338 data_array
[3]= 0x00053902;
339 data_array
[4]= (y1_MSB
<<24)|(y0_LSB
<<16)|(y0_MSB
<<8)|0x2b;
340 data_array
[5]= (y1_LSB
);
341 data_array
[6]= 0x002c3909;
343 dsi_set_cmdq(&data_array
, 7, 0);
346 static unsigned int lcm_compare_id(void)
361 array
[0] = 0x00083700;// read id return two byte,version and id
362 dsi_set_cmdq(array
, 1, 1);
364 read_reg_v2(0x04,buffer
, 3);
366 id0
= buffer
[0]; //should be 0x00
367 id1
= buffer
[1];//should be 0x80
368 id2
= buffer
[2];//should be 0x00
370 printf("zhibin uboot %s\n", __func__
);
371 printf("%s, id0 = 0x%08x\n", __func__
, id0
);//should be 0x00
372 printf("%s, id1 = 0x%08x\n", __func__
, id1
);//should be 0x80
373 printf("%s, id2 = 0x%08x\n", __func__
, id2
);//should be 0x00
375 //printk("zhibin kernel %s\n", __func__);
384 LCM_DRIVER nt35516_qhd_dsi_cmd_tft9k1342_drv
=
386 .name
= "nt35516_dsi_tf",
387 .set_util_funcs
= lcm_set_util_funcs
,
388 .compare_id
= lcm_compare_id
,
389 .get_params
= lcm_get_params
,
391 .suspend
= lcm_suspend
,
392 .resume
= lcm_resume
,
393 #if defined(LCM_DSI_CMD_MODE)
394 .update
= lcm_update
,