video: rockchip: mipi: add long packet support for linux-4.4
[firefly-linux-kernel-4.4.55.git] / drivers / video / rockchip / screen / lcd_mipi.c
1 /*
2  * Copyright (C) 2014 ROCKCHIP, Inc.
3  * drivers/video/rockchip/screen/lcd_mipi.c
4  * author: libing@rock-chips.com
5  * create date: 2014-04-10
6  * This software is licensed under the terms of the GNU General Public
7  * License version 2, as published by the Free Software Foundation, and
8  * may be copied, distributed, and modified under those terms.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  */
15
16 #ifndef CONFIG_LCD_MIPI
17 #include <common.h>
18 #endif
19 #ifdef CONFIG_LCD_MIPI
20 #include "../transmitter/mipi_dsi.h"
21 #include <linux/delay.h>
22 #endif
23 #ifdef CONFIG_RK_3288_DSI_UBOOT
24 #include <common.h>
25 #include <asm/io.h>
26 #include <errno.h>
27 #include <malloc.h>
28 #include <fdtdec.h>
29 #include <errno.h>
30 #include <asm/io.h>
31 #include <asm/arch/rkplat.h>
32 #include <lcd.h>
33 #include "../transmitter/mipi_dsi.h"
34 #endif
35
36 #ifdef CONFIG_RK_3288_DSI_UBOOT
37 #define MIPI_SCREEN_DBG(x...)   /* printf(x) */
38 #elif defined CONFIG_LCD_MIPI
39 #define MIPI_SCREEN_DBG(x...)   /* printk(KERN_ERR x) */
40 #else
41 #define MIPI_SCREEN_DBG(x...)
42 #endif
43 #ifdef CONFIG_RK_3288_DSI_UBOOT
44 DECLARE_GLOBAL_DATA_PTR;
45 #define msleep(a) udelay(a * 1000)
46 #define printk(x...)    /* printf(x) */
47 #endif
48 static struct mipi_screen *gmipi_screen;
49
50 static void rk_mipi_screen_pwr_disable(struct mipi_screen *screen)
51 {
52         if (screen->lcd_en_gpio != INVALID_GPIO) {
53                 gpio_direction_output(screen->lcd_en_gpio, !screen->lcd_en_atv_val);
54                 msleep(screen->lcd_en_delay);
55         } else{
56                 MIPI_SCREEN_DBG("lcd_en_gpio is null");
57         }
58
59         if (screen->lcd_rst_gpio != INVALID_GPIO) {
60
61                 gpio_direction_output(screen->lcd_rst_gpio, !screen->lcd_rst_atv_val);
62                 msleep(screen->lcd_rst_delay);
63         } else {
64                 MIPI_SCREEN_DBG("lcd_rst_gpio is null");
65         }
66 }
67
68 static void rk_mipi_screen_pwr_enable(struct mipi_screen *screen)
69 {
70         if (screen->lcd_en_gpio != INVALID_GPIO) {
71                 gpio_direction_output(screen->lcd_en_gpio, !screen->lcd_en_atv_val);
72                 msleep(screen->lcd_en_delay);
73                 gpio_direction_output(screen->lcd_en_gpio, screen->lcd_en_atv_val);
74                 msleep(screen->lcd_en_delay);
75         } else
76                 MIPI_SCREEN_DBG("lcd_en_gpio is null\n");
77
78         if (screen->lcd_rst_gpio != INVALID_GPIO) {
79                 gpio_direction_output(screen->lcd_rst_gpio, !screen->lcd_rst_atv_val);
80                 msleep (screen->lcd_rst_delay);
81                 gpio_direction_output(screen->lcd_rst_gpio, screen->lcd_rst_atv_val);
82                 msleep(screen->lcd_rst_delay);
83         } else
84                 MIPI_SCREEN_DBG("lcd_rst_gpio is null\n");
85 }
86
87 static void rk_mipi_screen_cmd_init(struct mipi_screen *screen)
88 {
89         u8 len, i;
90         u8 *cmds;
91         struct list_head *screen_pos;
92         struct mipi_dcs_cmd_ctr_list  *dcs_cmd;
93 #ifdef CONFIG_RK_3288_DSI_UBOOT
94         cmds = calloc(1, 0x400);
95         if (!cmds) {
96                 printf("request cmds fail!\n");
97                 return;
98         }
99 #endif
100
101 #ifdef CONFIG_LCD_MIPI
102         cmds = kmalloc(0x400, GFP_KERNEL);
103         if (!cmds) {
104                 printk("request cmds fail!\n");
105                 return ;
106         }
107 #endif
108         list_for_each(screen_pos, &screen->cmdlist_head) {
109                 dcs_cmd = list_entry(screen_pos, struct mipi_dcs_cmd_ctr_list, list);
110                 len = dcs_cmd->dcs_cmd.cmd_len + 1;
111                 for (i = 1; i < len ; i++) {
112                         cmds[i] = dcs_cmd->dcs_cmd.cmds[i-1];
113                 }
114                 MIPI_SCREEN_DBG("dcs_cmd.name:%s\n", dcs_cmd->dcs_cmd.name);
115                 if (dcs_cmd->dcs_cmd.type == LPDT) {
116                         cmds[0] = LPDT;
117                         if (dcs_cmd->dcs_cmd.dsi_id == 0) {
118                                 MIPI_SCREEN_DBG("dcs_cmd.dsi_id == 0 line=%d\n", __LINE__);
119                                 dsi_send_packet(0, cmds, len);
120                         } else if (dcs_cmd->dcs_cmd.dsi_id == 1) {
121                                 MIPI_SCREEN_DBG("dcs_cmd.dsi_id == 1 line=%d\n", __LINE__);
122                                 dsi_send_packet(1, cmds, len);
123                         } else if (dcs_cmd->dcs_cmd.dsi_id == 2) {
124                                 MIPI_SCREEN_DBG("dcs_cmd.dsi_id == 2 line=%d\n", __LINE__);
125                                 dsi_send_packet(0, cmds, len);
126                                 dsi_send_packet(1, cmds, len);
127                         } else {
128                                 MIPI_SCREEN_DBG("dsi is err.\n");
129                         }
130                         msleep(dcs_cmd->dcs_cmd.delay);
131                 } else if (dcs_cmd->dcs_cmd.type == HSDT) {
132                         cmds[0] = HSDT;
133                         if (dcs_cmd->dcs_cmd.dsi_id == 0) {
134                                 MIPI_SCREEN_DBG("dcs_cmd.dsi_id == 0 line=%d\n", __LINE__);
135                                 dsi_send_packet(0, cmds, len);
136                         } else if (dcs_cmd->dcs_cmd.dsi_id == 1) {
137                                 MIPI_SCREEN_DBG("dcs_cmd.dsi_id == 1 line=%d\n", __LINE__);
138                                 dsi_send_packet(1, cmds, len);
139                         } else if (dcs_cmd->dcs_cmd.dsi_id == 2) {
140                                 MIPI_SCREEN_DBG("dcs_cmd.dsi_id == 2 line=%d\n", __LINE__);
141                                 dsi_send_packet(0, cmds, len);
142                                 dsi_send_packet(1, cmds, len);
143                         } else {
144                                 MIPI_SCREEN_DBG("dsi is err.");
145                         }
146                         msleep(dcs_cmd->dcs_cmd.delay);
147                 } else
148                         MIPI_SCREEN_DBG("cmd type err.\n");
149                 kfree(dcs_cmd->dcs_cmd.cmds);
150                 dcs_cmd->dcs_cmd.cmds = NULL;
151         }
152
153 #ifdef CONFIG_RK_3288_DSI_UBOOT
154         free(cmds);
155 #endif
156 #ifdef CONFIG_LCD_MIPI
157         kfree(cmds);
158 #endif
159 }
160
161 int rk_mipi_screen(void)
162 {
163         u8 dcs[16] = {0}, rk_dsi_num;
164         rk_dsi_num = gmipi_screen->mipi_dsi_num;
165         if (gmipi_screen->screen_init == 0) {
166                 rk_mipi_screen_pwr_enable(gmipi_screen);
167                 dsi_enable_hs_clk(0, 1);
168                 if (rk_dsi_num == 2) {
169                         dsi_enable_hs_clk(1, 1);
170                 }
171
172                 dsi_enable_video_mode(0, 0);
173                 if (rk_dsi_num == 2) {
174                         dsi_enable_video_mode(1, 0);
175                 }
176
177                 dsi_enable_command_mode(0, 1);
178                 if (rk_dsi_num == 2) {
179                         dsi_enable_command_mode(1, 1);
180                 }
181
182                 dcs[0] = LPDT;
183                 dcs[1] = DTYPE_DCS_SWRITE_0P;
184                 dcs[2] = dcs_exit_sleep_mode;
185                 dsi_send_packet(0, dcs, 3);
186                 if (rk_dsi_num == 2)
187                         dsi_send_packet(1, dcs, 3);
188
189                 msleep(20);
190
191                 dcs[0] = LPDT;
192                 dcs[1] = DTYPE_DCS_SWRITE_0P;
193                 dcs[2] = dcs_set_display_on;
194                 dsi_send_packet(0, dcs, 3);
195                 if (rk_dsi_num == 2)
196                         dsi_send_packet(1, dcs, 3);
197
198                 msleep(20);
199
200                 dsi_enable_command_mode(0, 0);
201                 if (rk_dsi_num == 2) {
202                         dsi_enable_command_mode(1, 0);
203                 }
204
205                 dsi_enable_video_mode(0, 1);
206                 if (rk_dsi_num == 2) {
207                         dsi_enable_video_mode(1, 1);
208                 }
209         } else {
210                 rk_mipi_screen_pwr_enable(gmipi_screen);
211
212                 dsi_enable_hs_clk(0, 1);
213                 if (rk_dsi_num == 2) {
214                         dsi_enable_hs_clk(1, 1);
215                 }
216
217                 dsi_enable_video_mode(0, 0);
218                 if (rk_dsi_num == 2) {
219                         dsi_enable_video_mode(1, 0);
220                 }
221
222                 dsi_enable_command_mode(0, 1);
223                 if (rk_dsi_num == 2) {
224                         dsi_enable_command_mode(1, 1);
225                 }
226
227                 rk_mipi_screen_cmd_init(gmipi_screen);
228
229                 dsi_enable_command_mode(0, 0);
230                 if (rk_dsi_num == 2) {
231                         dsi_enable_command_mode(1, 0);
232                 }
233
234                 dsi_enable_video_mode(0, 1);
235                 if (rk_dsi_num == 2) {
236                         dsi_enable_video_mode(1, 1);
237                 }
238         }
239
240         MIPI_SCREEN_DBG("++++++++++++++++%s:%d\n", __func__, __LINE__);
241         return 0;
242 }
243
244 int rk_mipi_screen_standby(u8 enable)
245 {
246         u8 dcs[16] = {0}, rk_dsi_num;
247         rk_dsi_num = gmipi_screen->mipi_dsi_num;
248
249         if (dsi_is_active(0) != 1)
250                 return -1;
251
252         if (rk_dsi_num == 2)
253                 if ((dsi_is_active(0) != 1) || (dsi_is_active(1) != 1))
254                         return -1;
255
256         if (enable) {
257                 /* below is changeable */
258                 dcs[0] = LPDT;
259                 dcs[1] = DTYPE_DCS_SWRITE_0P;
260                 dcs[2] = dcs_set_display_off;
261                 dsi_send_packet(0, dcs, 3);
262                 if (rk_dsi_num == 2)
263                         dsi_send_packet(1, dcs, 3);
264
265                 msleep(30);
266
267                 dcs[0] = LPDT;
268                 dcs[1] = DTYPE_DCS_SWRITE_0P;
269                 dcs[2] = dcs_enter_sleep_mode;
270                 dsi_send_packet(0, dcs, 3);
271                 if (rk_dsi_num == 2)
272                         dsi_send_packet(1, dcs, 3);
273
274                 msleep(100);
275                 rk_mipi_screen_pwr_disable(gmipi_screen);
276                 MIPI_SCREEN_DBG("++++enable++++++++++++%s:%d\n", __func__, __LINE__);
277         } else {
278                 rk_mipi_screen();
279         }
280         return 0;
281 }
282 #ifdef CONFIG_LCD_MIPI
283 static int rk_mipi_screen_init_dt(struct mipi_screen *screen)
284 {
285         struct device_node *childnode, *grandchildnode, *root;
286         struct mipi_dcs_cmd_ctr_list *dcs_cmd;
287         struct list_head *pos;
288         struct property *prop;
289         enum of_gpio_flags flags;
290         u32 value, i, debug, gpio, ret, length;
291
292         memset(screen, 0, sizeof(*screen));
293
294         INIT_LIST_HEAD(&screen->cmdlist_head);
295
296         childnode = of_find_node_by_name(NULL, "mipi_dsi_init");
297         if (!childnode) {
298                 MIPI_SCREEN_DBG("%s: Can not get child => mipi_init.\n", __func__);
299         } else {
300                 ret = of_property_read_u32(childnode, "rockchip,screen_init", &value);
301                 if (ret) {
302                         MIPI_SCREEN_DBG("%s: Can not read property: screen_init.\n", __func__);
303                 } else {
304                         if ((value != 0) && (value != 1)) {
305                                 printk("err: rockchip,mipi_dsi_init not match.\n");
306                                 return -1;
307                         } else
308                                 screen->screen_init = value ;
309
310                         MIPI_SCREEN_DBG("%s: lcd->screen_init = %d.\n", __func__, screen->screen_init);
311                 }
312
313                 ret = of_property_read_u32(childnode, "rockchip,dsi_lane", &value);
314                 if (ret) {
315                         MIPI_SCREEN_DBG("%s: Can not read property: dsi_lane.\n", __func__);
316                 } else {
317                         screen->dsi_lane = value;
318                         MIPI_SCREEN_DBG("%s: mipi_lcd->dsi_lane = %d.\n", __func__, screen->dsi_lane);
319                 }
320
321                 ret = of_property_read_u32(childnode, "rockchip,dsi_hs_clk", &value);
322                 if (ret) {
323                         MIPI_SCREEN_DBG("%s: Can not read property: dsi_hs_clk.\n", __func__);
324                 } else {
325                         if ((value <= 90) || (value >= 1500)) {
326                                 printk("err: rockchip,hs_tx_clk not match.");
327                                 return -1;
328                         } else {
329                                 screen->hs_tx_clk = value*MHz;
330                         }
331
332                         MIPI_SCREEN_DBG("%s: lcd->screen->hs_tx_clk = %d.\n", __func__, screen->hs_tx_clk);
333                 }
334
335                 ret = of_property_read_u32(childnode, "rockchip,mipi_dsi_num", &value);
336                 if (ret) {
337                         MIPI_SCREEN_DBG("%s: Can not read property: mipi_dsi_num.\n", __func__);
338                 } else {
339                         if ((value != 1) && (value != 2)) {
340                                 printk("err: rockchip,mipi_dsi_num not match.\n");
341                                 return -1;
342                         } else {
343                                 screen->mipi_dsi_num = value ;
344                         }
345
346                         MIPI_SCREEN_DBG("%s: lcd->screen.mipi_dsi_num = %d.\n", __func__, screen->mipi_dsi_num);
347                 }
348         }
349
350         childnode = of_find_node_by_name(NULL, "mipi_power_ctr");
351         if (!childnode) {
352                 screen->lcd_rst_gpio = INVALID_GPIO;
353                 screen->lcd_en_gpio = INVALID_GPIO;
354                 MIPI_SCREEN_DBG("%s: Can not get child => mipi_power_ctr.\n", __func__);
355         } else {
356                 grandchildnode = of_find_node_by_name(childnode, "mipi_lcd_rst");
357                 if (!grandchildnode) {
358                         screen->lcd_rst_gpio = INVALID_GPIO;
359                         MIPI_SCREEN_DBG("%s: Can not read property: mipi_lcd_rst.\n", __func__);
360                 } else {
361                         ret = of_property_read_u32(grandchildnode, "rockchip,delay", &value);
362                         if (ret) {
363                                 MIPI_SCREEN_DBG("%s: Can not read property: delay.\n", __func__);
364                         } else {
365                                 screen->lcd_rst_delay = value;
366                                 MIPI_SCREEN_DBG("%s: lcd->screen->lcd_rst_delay = %d.\n", __func__, screen->lcd_rst_delay);
367                         }
368
369                         gpio = of_get_named_gpio_flags(grandchildnode, "rockchip,gpios", 0, &flags);
370                         if (!gpio_is_valid(gpio)) {
371                                 MIPI_SCREEN_DBG("rest: Can not read property: %s->gpios.\n", __func__);
372                         }
373
374                         ret = gpio_request(gpio, "mipi_lcd_rst");
375                         if (ret) {
376                                 screen->lcd_rst_gpio = INVALID_GPIO;
377                                 MIPI_SCREEN_DBG("request mipi_lcd_rst gpio fail:%d\n", gpio);
378                                 return -1;
379                         }
380
381                         screen->lcd_rst_gpio = gpio;
382                         screen->lcd_rst_atv_val = (flags == GPIO_ACTIVE_HIGH) ? 1:0;
383
384                         MIPI_SCREEN_DBG("lcd->lcd_rst_gpio=%d,dsi->lcd_rst_atv_val=%d\n", screen->lcd_rst_gpio, screen->lcd_rst_atv_val);
385                 }
386
387                 grandchildnode = of_find_node_by_name(childnode, "mipi_lcd_en");
388                 if (!grandchildnode) {
389                         screen->lcd_en_gpio = INVALID_GPIO;
390                         MIPI_SCREEN_DBG("%s: Can not read property: mipi_lcd_en.\n", __func__);
391                 } else {
392                         ret = of_property_read_u32(grandchildnode, "rockchip,delay", &value);
393                         if (ret) {
394                                 MIPI_SCREEN_DBG("%s: Can not read property: mipi_lcd_en-delay.\n", __func__);
395                         } else {
396                                 screen->lcd_en_delay = value;
397                                 MIPI_SCREEN_DBG("%s: lcd->screen.lcd_en_delay = %d.\n", __func__, screen->lcd_en_delay);
398                         }
399
400                         gpio = of_get_named_gpio_flags(grandchildnode, "rockchip,gpios", 0, &flags);
401                         if (!gpio_is_valid(gpio)) {
402                                 MIPI_SCREEN_DBG("rest: Can not read property: %s->gpios.\n", __func__);
403                         }
404
405                         ret = gpio_request(gpio, "mipi_lcd_en");
406                         if (ret) {
407                                 screen->lcd_en_gpio = INVALID_GPIO;
408                                 MIPI_SCREEN_DBG("request mipi_lcd_en gpio fail:%d\n", gpio);
409                                 return -1;
410                         }
411                         screen->lcd_en_gpio = gpio;
412                         screen->lcd_en_atv_val = (flags == GPIO_ACTIVE_HIGH) ? 1:0;
413                         MIPI_SCREEN_DBG("dsi->lcd_en_gpio=%d, dsi->screen.lcd_en_atv_val=%d\n", screen->lcd_en_gpio, screen->lcd_en_atv_val);
414                 }
415         }
416
417         root = of_find_node_by_name(NULL, "screen-on-cmds");
418         if (!root) {
419                 MIPI_SCREEN_DBG("can't find screen-on-cmds node\n");
420         } else {
421                 for_each_child_of_node(root, childnode) {
422                         dcs_cmd = kmalloc(sizeof(struct mipi_dcs_cmd_ctr_list), GFP_KERNEL);
423                         strcpy(dcs_cmd->dcs_cmd.name, childnode->name);
424
425                         dcs_cmd->dcs_cmd.cmds =
426                                 kzalloc(CMD_LEN_MAX, GFP_KERNEL);
427                         if (!dcs_cmd->dcs_cmd.cmds) {
428                                 pr_err("malloc cmds fail!\n");
429                                 return -ENOMEM;
430                         }
431
432                         prop = of_find_property(childnode, "rockchip,cmd", &length);
433                         if (!prop) {
434                                 MIPI_SCREEN_DBG("Can not read property: cmds\n");
435                                 kfree(dcs_cmd->dcs_cmd.cmds);
436                                 dcs_cmd->dcs_cmd.cmds = NULL;
437                                 return -EINVAL;
438                         }
439
440                         if ((length / sizeof(u32)) > CMD_LEN_MAX) {
441                                 /* the length can not longer than the cmds arrary in struct dcs_cmds */
442                                 MIPI_SCREEN_DBG("error: the dcs cmd length is %d, but the max length supported is %d\n",
443                                                 length / sizeof(u32),
444                                                 CMD_LEN_MAX);
445                         }
446                         MIPI_SCREEN_DBG("\n childnode->name =%s:length=%d\n", childnode->name, (length / sizeof(u32)));
447
448                         ret = of_property_read_u32_array(childnode,
449                                                          "rockchip,cmd",
450                                                          dcs_cmd->dcs_cmd.cmds,
451                                                          length / sizeof(u32));
452                         if (ret < 0) {
453                                 MIPI_SCREEN_DBG("%s: Can not read property: %s--->cmds\n", __func__, childnode->name);
454                                 kfree(dcs_cmd->dcs_cmd.cmds);
455                                 dcs_cmd->dcs_cmd.cmds = NULL;
456                                 return ret;
457                         } else {
458                                 dcs_cmd->dcs_cmd.cmd_len =  length / sizeof(u32);
459                         }
460                         ret = of_property_read_u32(childnode, "rockchip,dsi_id", &value);
461                         if (ret) {
462                                 MIPI_SCREEN_DBG("%s: Can not read property: %s--->cmd_type\n", __func__, childnode->name);
463                         } else {
464                                 if (screen->mipi_dsi_num == 1) {
465                                         if (value != 0) {
466                                                 printk("err: rockchip,dsi_id not match.\n");
467                                         } else {
468                                                 dcs_cmd->dcs_cmd.dsi_id = value;
469                                         }
470                                 } else {
471                                         if ((value < 0) || (value > 2))
472                                                 printk("err: rockchip,dsi_id not match.\n");
473                                         else
474                                                 dcs_cmd->dcs_cmd.dsi_id = value;
475                                 }
476                         }
477
478                         ret = of_property_read_u32(childnode, "rockchip,cmd_type", &value);
479                         if (ret) {
480                                 MIPI_SCREEN_DBG("%s: Can not read property: %s--->cmd_type\n", __func__, childnode->name);
481                         } else {
482                                 if ((value != 0) && (value != 1)) {
483                                         printk("err: rockchip, cmd_type not match.\n");
484                                 } else {
485                                         dcs_cmd->dcs_cmd.type = value;
486                                 }
487                         }
488
489                         ret = of_property_read_u32(childnode, "rockchip,cmd_delay", &value);
490                         if (ret)
491                                 MIPI_SCREEN_DBG("%s: Can not read property: %s--->cmd_delay\n", __func__, childnode->name);
492                         else
493                                 dcs_cmd->dcs_cmd.delay = value;
494
495                         list_add_tail(&dcs_cmd->list, &screen->cmdlist_head);
496                 }
497         }
498         ret = of_property_read_u32(root, "rockchip,cmd_debug", &debug);
499         if (ret) {
500                 MIPI_SCREEN_DBG("%s: Can not read property: rockchip,cmd_debug.\n", __func__);
501         } else {
502                 if (debug) {
503                         list_for_each(pos, &screen->cmdlist_head) {
504                                 dcs_cmd = list_entry(pos, struct mipi_dcs_cmd_ctr_list, list);
505                                 printk("\n dcs_name:%s,dcs_type:%d,side_id:%d,cmd_len:%d,delay:%d\n\n",
506                                         dcs_cmd->dcs_cmd.name,
507                                         dcs_cmd->dcs_cmd.type,
508                                         dcs_cmd->dcs_cmd.dsi_id,
509                                         dcs_cmd->dcs_cmd.cmd_len,
510                                         dcs_cmd->dcs_cmd.delay);
511                                 for (i = 0; i < (dcs_cmd->dcs_cmd.cmd_len); i++) {
512                                         printk("[%d]=%02x,", i+1, dcs_cmd->dcs_cmd.cmds[i]);
513                                 }
514                         }
515                 } else {
516                         MIPI_SCREEN_DBG("---close cmd debug---\n");
517                 }
518         }
519         return 0;
520 }
521 #endif
522 int rk_mipi_get_dsi_num(void)
523 {
524         return gmipi_screen->mipi_dsi_num;
525 }
526 #ifdef CONFIG_LCD_MIPI
527 EXPORT_SYMBOL(rk_mipi_get_dsi_num);
528 #endif
529 int rk_mipi_get_dsi_lane(void)
530 {
531         return gmipi_screen->dsi_lane;
532 }
533 #ifdef CONFIG_LCD_MIPI
534 EXPORT_SYMBOL(rk_mipi_get_dsi_lane);
535 #endif
536
537 int rk_mipi_get_dsi_clk(void)
538 {
539         return gmipi_screen->hs_tx_clk;
540 }
541 #ifdef CONFIG_LCD_MIPI
542 EXPORT_SYMBOL(rk_mipi_get_dsi_clk);
543 #endif
544 #ifdef CONFIG_RK_3288_DSI_UBOOT
545 #ifdef CONFIG_OF_LIBFDT
546 static int rk_mipi_screen_init_dt(struct mipi_screen *screen)
547 {
548         struct mipi_dcs_cmd_ctr_list *dcs_cmd;
549         u32 i;
550         int length;
551         int err;
552         int node;
553         const void *blob;
554         struct fdt_gpio_state gpio_val;
555         int noffset;
556
557         INIT_LIST_HEAD(&screen->cmdlist_head);
558
559         blob = gd->fdt_blob; /* getenv_hex("fdtaddr", 0); */
560         node = fdtdec_next_compatible(blob, 0, COMPAT_ROCKCHIP_MIPI_INIT);
561         if (node < 0) {
562                 MIPI_SCREEN_DBG("Can not get node of COMPAT_ROCKCHIP_MIPI_INIT\n");
563         }
564         screen->screen_init = fdtdec_get_int(blob, node, "rockchip,screen_init", -1);
565         if (screen->screen_init < 0) {
566                 MIPI_SCREEN_DBG("Can not get screen_init\n");
567         }
568         screen->dsi_lane = fdtdec_get_int(blob, node, "rockchip,dsi_lane", -1);
569         if (screen->dsi_lane < 0) {
570                 MIPI_SCREEN_DBG("Can not get dsi_lane\n");
571         }
572         screen->hs_tx_clk = fdtdec_get_int(blob, node, "rockchip,dsi_hs_clk", -1);
573         if (screen->hs_tx_clk < 0) {
574                 MIPI_SCREEN_DBG("Can not get dsi_hs_clk\n");
575         } else {
576                 screen->hs_tx_clk = screen->hs_tx_clk*MHZ;
577         }
578         screen->mipi_dsi_num = fdtdec_get_int(blob, node, "rockchip,mipi_dsi_num", -1);
579         if (screen->mipi_dsi_num < 0) {
580                 MIPI_SCREEN_DBG("Can't get mipi_dsi_num\n");
581         }
582 #if 0
583         node = fdtdec_next_compatible(blob, 0, COMPAT_ROCKCHIP_MIPI_PWR);
584         if (node < 0) {
585                 printf("Can not get node of COMPAT_ROCKCHIP_MIPI_PWR\n");
586         }
587 #endif
588
589 #if 0
590 /*get the lcd rst status
591         handle = fdt_getprop_u32_default(blob, "/mipi_power_ctr", "mipi_lcd_rst", -1);
592         node = fdt_node_offset_by_phandle(blob, handle);
593 */
594         node = fdtdec_next_compatible(blob, 0, COMPAT_ROCKCHIP_MIPI_PWR);
595         if (node < 0) {
596                 printf("Can not get node of COMPAT_ROCKCHIP_MIPI_PWR\n");
597         } else {
598                 subnode = fdtdec_next_compatible_subnode(blob, node,
599                                 COMPAT_ROCKCHIP_MIPI_LCD_RST, &depth);
600                 if (subnode <= 0) {
601                         screen->lcd_rst_gpio = INVALID_GPIO;
602                         printf("Can't get pin of mipi_lcd_rst\n");
603                 } else {
604                         err = fdtdec_decode_gpio(blob, subnode, "rockchip,gpios", &gpio_val);
605                         gpio_val.gpio = rk_gpio_base_to_bank(gpio_val.gpio & RK_GPIO_BANK_MASK) | (gpio_val.gpio & RK_GPIO_PIN_MASK);
606                         if (err < 0) {
607                                 screen->lcd_rst_gpio = INVALID_GPIO;
608                                 printf("Can't find GPIO rst\n");
609                         } else {
610                                 screen->lcd_rst_gpio = gpio_val.gpio;
611                                 screen->lcd_rst_atv_val = !(gpio_val.flags & OF_GPIO_ACTIVE_LOW);
612                         }
613                         screen->lcd_rst_delay = fdtdec_get_int(blob, subnode, "rockchip,delay", -1);
614                         if (screen->lcd_rst_delay < 0) {
615                                 printf("Can't get delay of rst delay\n");
616                         }
617                         printf("Get lcd rst gpio and delay successfully!\n");
618                 }
619         }
620 #endif
621         /* get the lcd rst & en status */
622         node = fdtdec_next_compatible(blob, 0, COMPAT_ROCKCHIP_MIPI_PWR);
623         if (node < 0) {
624                 MIPI_SCREEN_DBG("Can not get node of COMPAT_ROCKCHIP_MIPI_PWR\n");
625         } else {
626 #if 0
627                 noffset = fdt_first_subnode(blob, node);
628                 const char *name = fdt_get_name(blob, noffset, NULL);
629                 printf("XJH_DEBUG1:%s\n", name);
630                 noffset = fdt_next_subnode(blob, noffset);
631                 const char *name1 = fdt_get_name(blob, noffset, NULL);
632                 printf("XJH_DEBUG2:%s\n", name1);
633 #endif
634                 for (noffset = fdt_first_subnode(blob, node);
635                 noffset >= 0;
636                 noffset = fdt_next_subnode(blob, noffset)) {
637                         if (0 == fdt_node_check_compatible(blob, noffset, "rockchip,lcd_rst")) {
638                                 err = fdtdec_decode_gpio(blob, noffset, "rockchip,gpios", &gpio_val);
639                                 gpio_val.gpio = rk_gpio_base_to_bank(gpio_val.gpio & RK_GPIO_BANK_MASK) | (gpio_val.gpio & RK_GPIO_PIN_MASK);
640                                 if (err < 0) {
641                                         screen->lcd_rst_gpio = INVALID_GPIO;
642                                         MIPI_SCREEN_DBG("Can't find GPIO rst\n");
643                                 } else {
644                                         screen->lcd_rst_gpio = gpio_val.gpio;
645                                         screen->lcd_rst_atv_val = !(gpio_val.flags & OF_GPIO_ACTIVE_LOW);
646                                 }
647                                 screen->lcd_rst_delay = fdtdec_get_int(blob, noffset, "rockchip,delay", -1);
648                                 if (screen->lcd_rst_delay < 0) {
649                                         MIPI_SCREEN_DBG("Can't get delay of rst delay\n");
650                                 }
651                                 MIPI_SCREEN_DBG("Get lcd rst gpio and delay successfully!\n");
652                         }
653                         if (0 == fdt_node_check_compatible(blob, noffset, "rockchip,lcd_en")) {
654                                 err = fdtdec_decode_gpio(blob, noffset, "rockchip,gpios", &gpio_val);
655                                 gpio_val.gpio = rk_gpio_base_to_bank(gpio_val.gpio & RK_GPIO_BANK_MASK) | (gpio_val.gpio & RK_GPIO_PIN_MASK);
656                                 if (err < 0) {
657                                         screen->lcd_en_gpio = INVALID_GPIO;
658                                         MIPI_SCREEN_DBG("Can't find GPIO en\n");
659                                 } else {
660                                         screen->lcd_en_gpio = gpio_val.gpio;
661                                         screen->lcd_en_atv_val = !(gpio_val.flags & OF_GPIO_ACTIVE_LOW);
662                                 }
663                                 screen->lcd_en_delay = fdtdec_get_int(blob, noffset, "rockchip,delay", -1);
664                                 if (screen->lcd_en_delay < 0) {
665                                         MIPI_SCREEN_DBG("Can't get delay of lcd_en delay\n");
666                                 }
667                                 MIPI_SCREEN_DBG("Get lcd en gpio and delay successfully:delay %d!\n", screen->lcd_en_delay);
668                         }
669                 }
670         }
671
672         /*get the initial command list*/
673         node = fdtdec_next_compatible(blob, 0, COMPAT_ROCKCHIP_MIPI_SONCMDS);
674         if (node < 0) {
675                 MIPI_SCREEN_DBG("Can not get node of COMPAT_ROCKCHIP_MIPI_SONCMDS\n");
676         } else {
677                 for (noffset = fdt_first_subnode(blob, node);
678                 noffset >= 0;
679                 noffset = fdt_next_subnode(blob, noffset)) {
680
681                         MIPI_SCREEN_DBG("build MIPI LCD init cmd tables\n");
682                         /*
683                         subnode = fdtdec_next_compatible_subnode(blob, node,
684                                         COMPAT_ROCKCHIP_MIPI_ONCMDS, &depth);
685                         if (noffset < 0)
686                                 break;
687                         */
688                         dcs_cmd = calloc(1, sizeof(struct mipi_dcs_cmd_ctr_list));
689                         /* node = fdt_node_offset_by_phandle(blob, handle); */
690                         strcpy(dcs_cmd->dcs_cmd.name, fdt_get_name(blob, noffset, NULL));
691                         MIPI_SCREEN_DBG("%s\n", dcs_cmd->dcs_cmd.name);
692                         dcs_cmd->dcs_cmd.type = fdtdec_get_int(blob, noffset, "rockchip,cmd_type", -1);
693                         MIPI_SCREEN_DBG("dcs_cmd.type=%02x\n", dcs_cmd->dcs_cmd.type);
694                         dcs_cmd->dcs_cmd.dsi_id = fdtdec_get_int(blob, noffset, "rockchip,dsi_id", -1);
695                         MIPI_SCREEN_DBG("dcs_cmd.dsi_id=%02x\n", dcs_cmd->dcs_cmd.dsi_id);
696                         fdt_getprop(blob, noffset, "rockchip,cmd", &length);
697                         dcs_cmd->dcs_cmd.cmd_len = length / sizeof(u32) ;
698
699                         dcs_cmd->dcs_cmd.cmds = calloc(1, CMD_LEN_MAX);
700                         if (!dcs_cmd->dcs_cmd.cmds) {
701                                 pr_err("calloc cmds fail!\n");
702                                 return -1;
703                         }
704
705                         err = fdtdec_get_int_array(blob, noffset,
706                                                    "rockchip,cmd",
707                                                    dcs_cmd->dcs_cmd.cmds,
708                                                    dcs_cmd->dcs_cmd.cmd_len);
709                         dcs_cmd->dcs_cmd.delay = fdtdec_get_int(blob, noffset, "rockchip,cmd_delay", -1);
710                         MIPI_SCREEN_DBG("dcs_cmd.delay=%d\n", dcs_cmd->dcs_cmd.delay);
711                         list_add_tail(&dcs_cmd->list, &screen->cmdlist_head);
712                 }
713         }
714         return 0;
715 }
716 #endif /* CONFIG_OF_LIBFDT */
717
718 int rk_mipi_screen_probe(void)
719 {
720         int ret = 0;
721         gmipi_screen = calloc(1, sizeof(struct mipi_screen));
722         if (!gmipi_screen) {
723                 printf("request struct screen fail!\n");
724                 return -ENOMEM;
725         }
726 #ifdef CONFIG_OF_LIBFDT
727         ret = rk_mipi_screen_init_dt(gmipi_screen);
728         if (ret < 0) {
729                 printf(" rk_mipi_screen_init_dt fail!\n");
730                 return -1;
731         }
732 #endif /* CONFIG_OF_LIBFDT */
733
734         MIPI_SCREEN_DBG("---rk_mipi_screen_probe--end\n");
735         return 0;
736 }
737
738 #endif /* CONFIG_RK_3288_DSI_UBOOT */
739 #ifdef CONFIG_LCD_MIPI
740 static int __init rk_mipi_screen_probe(struct platform_device *pdev)
741 {
742         static int ret;
743
744         gmipi_screen = devm_kzalloc(&pdev->dev, sizeof(struct mipi_screen), GFP_KERNEL);
745         if (!gmipi_screen) {
746                 dev_err(&pdev->dev, "request struct screen fail!\n");
747                 return -ENOMEM;
748         }
749
750         ret = rk_mipi_screen_init_dt(gmipi_screen);
751         if (ret < 0) {
752                 dev_err(&pdev->dev, " rk_mipi_screen_init_dt fail!\n");
753                 return -1;
754         }
755
756         MIPI_SCREEN_DBG("---rk_mipi_screen_probe--end\n");
757         return 0;
758 }
759
760 static struct platform_driver mipi_screen_platform_driver = {
761         .driver = {
762                 .name = "rk_mipi_screen",
763         },
764 };
765
766 static int __init rk_mipi_screen_init(void)
767 {
768         platform_device_register_simple("rk_mipi_screen", -1, NULL, 0);
769         return platform_driver_probe(&mipi_screen_platform_driver, rk_mipi_screen_probe);
770 }
771
772 static void __exit rk_mipi_screen_exit(void)
773 {
774         platform_driver_unregister(&mipi_screen_platform_driver);
775 }
776
777 subsys_initcall_sync(rk_mipi_screen_init);
778 module_exit(rk_mipi_screen_exit);
779 #endif