rk3036 lcdc: commit driver code, just pass compiling.
[firefly-linux-kernel-4.4.55.git] / drivers / video / rockchip / rk_drm_fb.c
1 /*
2  * drivers/video/rockchip/rk_fb.c
3  *
4  * Copyright (C) ROCKCHIP, Inc.
5  * Author:yzq<yxj@rock-chips.com>
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 #include <linux/module.h>
17 #include <linux/kernel.h>
18 #include <linux/errno.h>
19 #include <linux/string.h>
20 #include <linux/mm.h>
21 #include <linux/slab.h>
22 #include <linux/delay.h>
23 #include <linux/device.h>
24 #include <linux/kthread.h>
25 #include <linux/fb.h>
26 #include <linux/init.h>
27 #include <asm/div64.h>
28 #include <linux/uaccess.h>
29 #include <linux/rk_fb.h>
30 #include <linux/linux_logo.h>
31 #include <linux/dma-mapping.h>
32 #include <drm/drm_os_linux.h>
33 #include <linux/of_gpio.h>
34 #ifdef CONFIG_OF
35 #include <linux/of.h>
36 #include <linux/of_gpio.h>
37 #include <video/of_display_timing.h>
38 #include <video/display_timing.h>
39 #include <dt-bindings/rkfb/rk_fb.h>
40 #endif
41
42 #include <linux/display-sys.h>
43 #include "rk_drm_fb.h"
44 __weak int support_uboot_display(void)
45 {
46         return 0;
47 }
48 static struct platform_device *drm_fb_pdev;
49 static struct rk_fb_trsm_ops *trsm_lvds_ops;
50 static struct rk_fb_trsm_ops *trsm_edp_ops;
51 static struct rk_fb_trsm_ops *trsm_mipi_ops;
52 static struct rk_display_device *disp_hdmi_devices;
53 void rk_drm_display_register(struct rk_display_ops *extend_ops, void *displaydata,int type)
54 {
55         switch(type) {
56                 case SCREEN_HDMI:
57                         disp_hdmi_devices = kzalloc(sizeof(struct rk_display_device), GFP_KERNEL);
58                         disp_hdmi_devices->priv_data = displaydata;
59                         disp_hdmi_devices->ops = extend_ops;
60                         break;
61                 default:
62                         printk(KERN_WARNING "%s:un supported extend display:%d!\n",
63                         __func__, type);
64                 break;
65         }
66 }
67 int rk_fb_trsm_ops_register(struct rk_fb_trsm_ops *ops, int type)
68 {
69         switch (type) {
70         case SCREEN_RGB:
71         case SCREEN_LVDS:
72         case SCREEN_DUAL_LVDS:
73                 trsm_lvds_ops = ops;
74                 break;
75         case SCREEN_EDP:
76                 trsm_edp_ops = ops;
77                 break;
78         case SCREEN_MIPI:
79         case SCREEN_DUAL_MIPI:
80                 trsm_mipi_ops = ops;
81                 break;
82         default:
83                 printk(KERN_WARNING "%s:un supported transmitter:%d!\n",
84                         __func__, type);
85                 break;
86         }
87         return 0;
88 }
89
90 struct rk_display_device *rk_drm_extend_display_get(int type)
91 {
92         struct rk_display_device *extend_display = NULL;
93         switch (type) {
94                 case SCREEN_HDMI:
95                         if(disp_hdmi_devices)
96                                 extend_display = disp_hdmi_devices;
97                         else
98                                 printk(KERN_WARNING "%s:screen hdmi ops is NULL!\n",__func__);
99                         break;
100                 default:
101                         printk(KERN_WARNING "%s:un supported extend display:%d!\n",
102                         __func__, type);
103                         break;
104         }
105         return extend_display;
106 }
107 #if 0
108 struct void *get_extend_drv(void)
109 {
110         struct rk_display_device *extend_display = rk_drm_extend_display_get(SCREEN_HDMI);
111         return extend_display->priv_data;
112 }
113 #endif
114 struct rk_fb_trsm_ops *rk_fb_trsm_ops_get(int type)
115 {
116         struct rk_fb_trsm_ops *ops;
117         switch (type) {
118         case SCREEN_RGB:
119         case SCREEN_LVDS:
120         case SCREEN_DUAL_LVDS:
121                 ops = trsm_lvds_ops;
122                 break;
123         case SCREEN_EDP:
124                 ops = trsm_edp_ops;
125                 break;
126         case SCREEN_MIPI:
127         case SCREEN_DUAL_MIPI:
128                 ops = trsm_mipi_ops;
129                 break;
130         default:
131                 ops = NULL;
132                 printk(KERN_WARNING "%s:un supported transmitter:%d!\n",
133                         __func__, type);
134                 break;
135         }
136         return ops;
137 }
138 /* rk display power control parse from dts
139  *
140 */
141 int rk_disp_pwr_ctr_parse_dt(struct rk_lcdc_driver *dev_drv)
142 {
143         struct device_node *root  = of_get_child_by_name(dev_drv->dev->of_node,
144                                 "power_ctr");
145         struct device_node *child;
146         struct rk_disp_pwr_ctr_list *pwr_ctr;
147         struct list_head *pos;
148         enum of_gpio_flags flags;
149         u32 val = 0;
150         u32 debug = 0;
151         u32 mirror = 0;
152         int ret;
153
154         INIT_LIST_HEAD(&dev_drv->pwrlist_head);
155         if (!root) {
156                 dev_err(dev_drv->dev, "can't find power_ctr node for lcdc%d\n",dev_drv->id);
157                 return -ENODEV;
158         }
159
160         for_each_child_of_node(root, child) {
161                 pwr_ctr = kmalloc(sizeof(struct rk_disp_pwr_ctr_list), GFP_KERNEL);
162                 strcpy(pwr_ctr->pwr_ctr.name, child->name);
163                 if (!of_property_read_u32(child, "rockchip,power_type", &val)) {
164                         if (val == GPIO) {
165                                 pwr_ctr->pwr_ctr.type = GPIO;
166                                 pwr_ctr->pwr_ctr.gpio = of_get_gpio_flags(child, 0, &flags);
167                                 if (!gpio_is_valid(pwr_ctr->pwr_ctr.gpio)) {
168                                         dev_err(dev_drv->dev, "%s ivalid gpio\n", child->name);
169                                         return -EINVAL;
170                                 }
171                                 pwr_ctr->pwr_ctr.atv_val = !(flags & OF_GPIO_ACTIVE_LOW);
172                                 ret = gpio_request(pwr_ctr->pwr_ctr.gpio,child->name);
173                                 if (ret) {
174                                         dev_err(dev_drv->dev, "request %s gpio fail:%d\n",
175                                                 child->name,ret);
176                                 }
177
178                         } else {
179                                 pwr_ctr->pwr_ctr.type = REGULATOR;
180
181                         }
182                 };
183                 of_property_read_u32(child, "rockchip,delay", &val);
184                 pwr_ctr->pwr_ctr.delay = val;
185                 list_add_tail(&pwr_ctr->list, &dev_drv->pwrlist_head);
186         }
187
188         of_property_read_u32(root, "rockchip,mirror", &mirror);
189
190         if (mirror == NO_MIRROR) {
191                 dev_drv->screen0->x_mirror = 0;
192                 dev_drv->screen0->y_mirror = 0;
193         } else if (mirror == X_MIRROR) {
194                 dev_drv->screen0->x_mirror = 1;
195                 dev_drv->screen0->y_mirror = 0;
196         } else if (mirror == Y_MIRROR) {
197                 dev_drv->screen0->x_mirror = 0;
198                 dev_drv->screen0->y_mirror = 1;
199         } else if(mirror == X_Y_MIRROR) {
200                 dev_drv->screen0->x_mirror = 1;
201                 dev_drv->screen0->y_mirror = 1;
202         }
203
204         of_property_read_u32(root, "rockchip,debug", &debug);
205
206         if (debug) {
207                 list_for_each(pos, &dev_drv->pwrlist_head) {
208                         pwr_ctr = list_entry(pos, struct rk_disp_pwr_ctr_list, list);
209                         printk(KERN_INFO "pwr_ctr_name:%s\n"
210                                          "pwr_type:%s\n"
211                                          "gpio:%d\n"
212                                          "atv_val:%d\n"
213                                          "delay:%d\n\n",
214                                          pwr_ctr->pwr_ctr.name,
215                                          (pwr_ctr->pwr_ctr.type == GPIO) ? "gpio" : "regulator",
216                                          pwr_ctr->pwr_ctr.gpio,
217                                          pwr_ctr->pwr_ctr.atv_val,
218                                          pwr_ctr->pwr_ctr.delay);
219                 }
220         }
221
222         return 0;
223
224 }
225
226 int rk_fb_video_mode_from_timing(const struct display_timing *dt, 
227                                 struct rk_screen *screen)
228 {
229         screen->mode.pixclock = dt->pixelclock.typ;
230         screen->mode.left_margin = dt->hback_porch.typ;
231         screen->mode.right_margin = dt->hfront_porch.typ;
232         screen->mode.xres = dt->hactive.typ;
233         screen->mode.hsync_len = dt->hsync_len.typ;
234         screen->mode.upper_margin = dt->vback_porch.typ;
235         screen->mode.lower_margin = dt->vfront_porch.typ;
236         screen->mode.yres = dt->vactive.typ;
237         screen->mode.vsync_len = dt->vsync_len.typ;
238         screen->type = dt->screen_type;
239         screen->lvds_format = dt->lvds_format;
240         screen->face = dt->face;
241
242         if (dt->flags & DISPLAY_FLAGS_PIXDATA_POSEDGE)
243                 screen->pin_dclk = 1;
244         else
245                 screen->pin_dclk = 0;
246         if(dt->flags & DISPLAY_FLAGS_HSYNC_HIGH)
247                 screen->pin_hsync = 1;
248         else
249                 screen->pin_hsync = 0;
250         if(dt->flags & DISPLAY_FLAGS_VSYNC_HIGH)
251                 screen->pin_vsync = 1;
252         else
253                 screen->pin_vsync = 0;
254         if(dt->flags & DISPLAY_FLAGS_DE_HIGH)
255                 screen->pin_den = 1;
256         else
257                 screen->pin_den = 0;
258         
259         return 0;
260         
261 }
262
263 int rk_fb_prase_timing_dt(struct device_node *np, struct rk_screen *screen)
264 {
265         struct display_timings *disp_timing;
266         struct display_timing *dt;
267         disp_timing = of_get_display_timings(np);
268         if (!disp_timing) {
269                 pr_err("parse display timing err\n");
270                 return -EINVAL;
271         }
272         dt = display_timings_get(disp_timing, 0);
273         rk_fb_video_mode_from_timing(dt, screen);
274         printk(KERN_ERR "dclk:%d\n"
275                          "hactive:%d\n"
276                          "hback_porch:%d\n"
277                          "hfront_porch:%d\n"
278                          "hsync_len:%d\n"
279                          "vactive:%d\n"
280                          "vback_porch:%d\n"
281                          "vfront_porch:%d\n"
282                          "vsync_len:%d\n"
283                          "screen_type:%d\n"
284                          "lvds_format:%d\n"
285                          "face:%d\n",
286                         dt->pixelclock.typ,
287                         dt->hactive.typ,
288                         dt->hback_porch.typ,
289                         dt->hfront_porch.typ,
290                         dt->hsync_len.typ,
291                         dt->vactive.typ,
292                         dt->vback_porch.typ,
293                         dt->vfront_porch.typ,
294                         dt->vsync_len.typ,
295                         dt->screen_type,
296                         dt->lvds_format,
297                         dt->face);
298         return 0;
299
300 }
301 static int init_lcdc_win(struct rk_lcdc_driver *dev_drv, struct rk_lcdc_win *def_win)
302 {
303         int i;
304         int lcdc_win_num = dev_drv->lcdc_win_num;
305         for (i = 0; i < lcdc_win_num; i++) {
306                 struct rk_lcdc_win *win = NULL;
307                 win =  kzalloc(sizeof(struct rk_lcdc_win), GFP_KERNEL);
308                 if (!win) {
309                         dev_err(dev_drv->dev, "kzmalloc for win fail!");
310                         return   -ENOMEM;
311                 }
312
313                 strcpy(win->name, def_win[i].name);
314                 win->id = def_win[i].id;
315                 win->support_3d = def_win[i].support_3d;
316                 dev_drv->win[i] = win;
317         }
318
319         return 0;
320 }
321
322 static int init_lcdc_device_driver(struct rk_drm_screen_private *screen_priv,
323                                         struct rk_lcdc_win *def_win, int index)
324 {
325         struct rk_drm_private *rk_drm_priv = platform_get_drvdata(drm_fb_pdev);
326         struct rk_lcdc_driver *dev_drv = screen_priv->lcdc_dev_drv;
327         struct rk_screen *screen1 = NULL;
328         struct rk_screen *screen = devm_kzalloc(dev_drv->dev,
329                                 sizeof(struct rk_screen), GFP_KERNEL);
330         if (!screen) {
331                 dev_err(dev_drv->dev, "malloc screen for lcdc%d fail!",
332                                         dev_drv->id);
333                 goto fail_screen;
334         }
335         
336         screen->screen_id = 0;
337         screen->lcdc_id = dev_drv->id;
338         screen->overscan.left = 100;
339         screen->overscan.top = 100;
340         screen->overscan.right = 100;
341         screen->overscan.bottom = 100;
342         dev_drv->screen0 = screen;
343         dev_drv->cur_screen = screen;
344         /* devie use one lcdc + rk61x scaler for dual display*/
345         if (rk_drm_priv->disp_mode == ONE_DUAL) {
346                 screen1 = devm_kzalloc(dev_drv->dev,
347                                                 sizeof(struct rk_screen), GFP_KERNEL);
348                 if (screen1) {
349                         dev_err(dev_drv->dev, "malloc screen1 for lcdc%d fail!",
350                                                 dev_drv->id);
351                         goto fail_screen1;
352                 }
353                 screen1->screen_id = 1;
354                 screen1->lcdc_id = 1;
355                 dev_drv->screen1 = screen1;
356         }
357         sprintf(dev_drv->name, "lcdc%d", dev_drv->id);
358         init_lcdc_win(dev_drv, def_win);
359         init_completion(&dev_drv->frame_done);
360         spin_lock_init(&dev_drv->cpl_lock);
361         mutex_init(&dev_drv->fb_win_id_mutex);
362         dev_drv->ops->fb_win_remap(dev_drv, FB_DEFAULT_ORDER);
363         dev_drv->first_frame = 1;
364         rk_disp_pwr_ctr_parse_dt(dev_drv);
365         if (dev_drv->prop == PRMRY) {
366                 rk_fb_set_prmry_screen(screen);
367                 rk_fb_get_prmry_screen(screen);
368                 dev_drv->trsm_ops = rk_fb_trsm_ops_get(screen->type);
369         }
370
371         return 0;
372
373 fail_screen1:
374         devm_kfree(dev_drv->dev,screen);
375 fail_screen:
376         
377         return -ENOMEM;
378 }
379 int rk_disp_pwr_enable(struct rk_lcdc_driver *dev_drv)
380 {
381         struct list_head *pos;
382         struct rk_disp_pwr_ctr_list *pwr_ctr_list;
383         struct pwr_ctr *pwr_ctr;
384         if (list_empty(&dev_drv->pwrlist_head))
385                 return 0;
386         list_for_each(pos, &dev_drv->pwrlist_head) {
387                 pwr_ctr_list = list_entry(pos, struct rk_disp_pwr_ctr_list, list);
388                 pwr_ctr = &pwr_ctr_list->pwr_ctr;
389                 if (pwr_ctr->type == GPIO) {
390                         gpio_direction_output(pwr_ctr->gpio,pwr_ctr->atv_val);
391                         mdelay(pwr_ctr->delay);
392                 }
393         }
394
395         return 0;
396 }
397 int  rk_fb_calc_fps(struct rk_screen * screen, u32 pixclock)
398 {
399         int x, y;
400         unsigned long long hz;
401         if (!screen) {
402                 printk(KERN_ERR "%s:null screen!\n", __func__);
403                 return 0;
404         }
405         x = screen->mode.xres + screen->mode.left_margin + screen->mode.right_margin +
406             screen->mode.hsync_len;
407         y = screen->mode.yres + screen->mode.upper_margin + screen->mode.lower_margin +
408             screen->mode.vsync_len;
409
410         hz = 1000000000000ULL;  /* 1e12 picoseconds per second */
411
412         hz += (x * y) / 2;
413         do_div(hz, x * y);      /* divide by x * y with rounding */
414
415         hz += pixclock / 2;
416         do_div(hz, pixclock);   /* divide by pixclock with rounding */
417
418         return hz;
419 }
420
421 char *get_format_string(enum data_format format, char *fmt)
422 {
423         if (!fmt)
424                 return NULL;
425         switch (format) {
426         case ARGB888:
427                 strcpy(fmt, "ARGB888");
428                 break;
429         case RGB888:
430                 strcpy(fmt, "RGB888");
431                 break;
432         case RGB565:
433                 strcpy(fmt, "RGB565");
434                 break;
435         case YUV420:
436                 strcpy(fmt, "YUV420");
437                 break;
438         case YUV422:
439                 strcpy(fmt, "YUV422");
440                 break;
441         case YUV444:
442                 strcpy(fmt, "YUV444");
443                 break;
444         case XRGB888:
445                 strcpy(fmt, "XRGB888");
446                 break;
447         case XBGR888:
448                 strcpy(fmt, "XBGR888");
449                 break;
450         case ABGR888:
451                 strcpy(fmt, "XBGR888");
452                 break;
453         default:
454                 strcpy(fmt, "invalid");
455                 break;
456         }
457
458         return fmt;
459
460 }
461 int rk_disp_pwr_disable(struct rk_lcdc_driver *dev_drv)
462 {
463         struct list_head *pos;
464         struct rk_disp_pwr_ctr_list *pwr_ctr_list;
465         struct pwr_ctr *pwr_ctr;
466         if (list_empty(&dev_drv->pwrlist_head))
467                 return 0;
468         list_for_each(pos, &dev_drv->pwrlist_head) {
469                 pwr_ctr_list = list_entry(pos, struct rk_disp_pwr_ctr_list, list);
470                 pwr_ctr = &pwr_ctr_list->pwr_ctr;
471                 if (pwr_ctr->type == GPIO) {
472                         gpio_set_value(pwr_ctr->gpio,pwr_ctr->atv_val);
473                 }
474         }
475
476         return 0;
477 }
478 /********************************
479 *check if the primary lcdc has registerd,
480 the primary lcdc mas register first
481 *********************************/
482 bool is_prmry_rk_lcdc_registered(void)
483 {
484         struct rk_drm_private *rk_drm_priv = platform_get_drvdata(drm_fb_pdev);
485         if (rk_drm_priv->screen_priv[0].lcdc_dev_drv)
486                 return  true;
487         else
488                 return false;
489
490
491 }
492 static void rk_fb_update_regs_handler(struct kthread_work *work)
493 {
494         struct rk_lcdc_driver * dev_drv =
495                         container_of(work, struct rk_lcdc_driver, update_regs_work);
496         struct rk_fb_reg_data *data, *next;
497 #if 0
498         //struct list_head saved_list;
499         mutex_lock(&dev_drv->update_regs_list_lock);
500         saved_list = dev_drv->update_regs_list;
501         list_replace_init(&dev_drv->update_regs_list, &saved_list);
502         mutex_unlock(&dev_drv->update_regs_list_lock);
503         
504         list_for_each_entry_safe(data, next, &saved_list, list) {
505                 //rk_fb_update_reg(dev_drv,data);
506                 list_del(&data->list);
507                 kfree(data);
508         }
509 #endif
510 }
511 static int rk_fb_wait_for_vsync_thread(void *data)
512 {
513         struct rk_lcdc_driver  *dev_drv = data;
514         struct rk_drm_private *rk_drm_priv = platform_get_drvdata(drm_fb_pdev);
515         struct rk_drm_screen_private *drm_screen_priv = NULL;
516         struct rk_drm_display *drm_display = NULL;
517
518         if(dev_drv->prop == PRMRY)
519                 drm_screen_priv = &rk_drm_priv->screen_priv[0];
520         else if(dev_drv->prop == EXTEND)
521                 drm_screen_priv = &rk_drm_priv->screen_priv[1];
522         if(drm_screen_priv == NULL)
523                 return -1;
524         drm_display = &drm_screen_priv->drm_disp;
525
526         while (!kthread_should_stop()) {
527                 ktime_t timestamp = dev_drv->vsync_info.timestamp;
528                 int ret = wait_event_interruptible(dev_drv->vsync_info.wait,
529                         !ktime_equal(timestamp, dev_drv->vsync_info.timestamp) &&
530                         (dev_drv->vsync_info.active || dev_drv->vsync_info.irq_stop));
531 #if 1
532                 if(atomic_read(&drm_screen_priv->wait_vsync_done)){
533                         atomic_set(&drm_screen_priv->wait_vsync_done,0);
534                         DRM_WAKEUP(&drm_screen_priv->wait_vsync_queue);
535                 }
536                 if(!ret && drm_display->event_call_back)
537                         drm_display->event_call_back(drm_display,0,RK_DRM_CALLBACK_VSYNC);
538 #endif
539         }
540
541         return 0;
542 }
543
544 static void rk_drm_irq_handle(struct rk_lcdc_driver *dev_drv)
545 {
546         struct rk_drm_private *rk_drm_priv = platform_get_drvdata(drm_fb_pdev);
547         struct rk_drm_screen_private *drm_screen_priv = NULL;
548         struct rk_drm_display *drm_display = NULL;
549         if(dev_drv->prop == PRMRY)
550                 drm_screen_priv = &rk_drm_priv->screen_priv[0];
551         else if(dev_drv->prop == EXTEND)
552                 drm_screen_priv = &rk_drm_priv->screen_priv[1];
553         if(drm_screen_priv == NULL)
554                 return -1;
555         drm_display = &drm_screen_priv->drm_disp;
556         if(atomic_read(&drm_screen_priv->wait_vsync_done)){
557                         atomic_set(&drm_screen_priv->wait_vsync_done,0);
558                         DRM_WAKEUP(&drm_screen_priv->wait_vsync_queue);
559         }
560
561         if(drm_display->event_call_back)
562                         drm_display->event_call_back(drm_display,0,RK_DRM_CALLBACK_VSYNC);
563 }
564 int rk_fb_register(struct rk_lcdc_driver *dev_drv,
565                 struct rk_lcdc_win *win, int id)
566 {
567         struct rk_drm_private *rk_drm_priv = platform_get_drvdata(drm_fb_pdev);
568         struct rk_drm_display *drm_display = NULL;
569         struct rk_drm_screen_private *drm_screen_priv = NULL;
570         int i=0;
571
572         if (rk_drm_priv->num_screen == RK30_MAX_LCDC_SUPPORT)
573                 return -ENXIO;
574         for (i = 0; i < RK_DRM_MAX_SCREEN_NUM; i++) {
575                 if (!rk_drm_priv->screen_priv[i].lcdc_dev_drv) 
576                         break;
577         }
578         rk_drm_priv->num_screen++;
579         drm_screen_priv = &rk_drm_priv->screen_priv[i]; 
580         drm_screen_priv->lcdc_dev_drv = dev_drv;
581         drm_screen_priv->lcdc_dev_drv->id = id;
582
583         init_lcdc_device_driver(drm_screen_priv,win,i);
584         dev_drv->irq_call_back = rk_drm_irq_handle;
585         
586         drm_display = &drm_screen_priv->drm_disp;
587         drm_display->num_win = dev_drv->lcdc_win_num;
588         atomic_set(&drm_screen_priv->wait_vsync_done, 1);
589         DRM_INIT_WAITQUEUE(&drm_screen_priv->wait_vsync_queue);
590         if(dev_drv->prop == PRMRY){
591                 struct fb_modelist *modelist_new;
592                 struct fb_modelist *modelist;
593                 struct fb_videomode *mode;
594                 drm_display->modelist = kmalloc(sizeof(struct list_head),GFP_KERNEL);
595                 INIT_LIST_HEAD(drm_display->modelist);
596                 modelist_new = kmalloc(sizeof(struct fb_modelist),
597                                   GFP_KERNEL);
598                 drm_display->screen_type = RK_DRM_PRIMARY_SCREEN;
599                 drm_display->num_videomode = 1;
600                 drm_display->best_mode = 0;
601                 drm_display->is_connected = 1;
602                 memcpy(&modelist_new->mode,&dev_drv->cur_screen->mode,sizeof(struct fb_videomode));
603
604         //      printk("---->yzq mode xres=%d yres=%d \n",modelist_new->mode.xres,modelist_new->mode.yres);
605                 list_add_tail(&modelist_new->list,drm_display->modelist);
606
607                 modelist = list_first_entry(drm_display->modelist, struct fb_modelist, list);
608                 mode=&modelist->mode;
609         //      printk("---->yzq 1mode xres=%d yres=%d \n",mode->xres,mode->yres);
610
611         }else if(dev_drv->prop == EXTEND){
612                 struct list_head *modelist;
613                 drm_screen_priv->ex_display = rk_drm_extend_display_get(SCREEN_HDMI);
614         //      printk("------>yzq ex_display=%x\n",drm_screen_priv->ex_display);
615                 drm_display->screen_type = RK_DRM_EXTEND_SCREEN;
616                 drm_display->is_connected = 0;
617 #if 0
618                 drm_screen_priv->ex_display->ops->getmodelist(drm_screen_priv->ex_display,&modelist);
619
620                 memcpy(&drm_display->modelist,modelist,sizeof(struct list_head));
621                 drm_display->is_connected = drm_screen_priv->ex_display->ops->getstatus(drm_screen_priv->ex_display);
622 #endif
623         }
624         if (1){//dev_drv->prop == PRMRY) {
625                 init_waitqueue_head(&dev_drv->vsync_info.wait);
626                 dev_drv->vsync_info.thread = kthread_run(rk_fb_wait_for_vsync_thread,
627                                 dev_drv, "fb-vsync");
628                 if (dev_drv->vsync_info.thread == ERR_PTR(-ENOMEM)) {
629                         printk( "failed to run vsync thread\n");
630                         dev_drv->vsync_info.thread = NULL;
631                 }
632                 dev_drv->vsync_info.active = 1;
633
634                 mutex_init(&dev_drv->output_lock);
635
636                 INIT_LIST_HEAD(&dev_drv->update_regs_list);
637                 mutex_init(&dev_drv->update_regs_list_lock);
638                 init_kthread_worker(&dev_drv->update_regs_worker);
639
640                 dev_drv->update_regs_thread = kthread_run(kthread_worker_fn,
641                                 &dev_drv->update_regs_worker, "rk-fb");
642                 if (IS_ERR(dev_drv->update_regs_thread)) {
643                         int err = PTR_ERR(dev_drv->update_regs_thread);
644                         dev_drv->update_regs_thread = NULL;
645
646                         printk("failed to run update_regs thread\n");
647                         return err;
648                 }
649                 init_kthread_work(&dev_drv->update_regs_work, rk_fb_update_regs_handler);
650
651                 dev_drv->timeline = sw_sync_timeline_create("fb-timeline");                     dev_drv->timeline_max = 1;
652         }
653         return 0;
654 }
655 int rk_fb_unregister(struct rk_lcdc_driver *dev_drv)
656
657 {
658         struct rk_drm_private *rk_drm_priv = platform_get_drvdata(drm_fb_pdev);
659         int i = 0;
660
661         return 0;
662 }
663
664 struct rk_drm_display *rk_drm_get_info(int screen_type)
665 {
666         struct rk_drm_private *rk_drm_priv = platform_get_drvdata(drm_fb_pdev);
667         int i=0;
668         for( i=0; i<rk_drm_priv->num_screen; i++){
669                 if(rk_drm_priv->screen_priv[i].drm_disp.screen_type == screen_type)
670                         break;
671         }
672         if(i==rk_drm_priv->num_screen){
673                 printk("--->%s can not find match DISPLAY_TYPE %d\n",__func__,screen_type);
674                 return NULL;
675         }
676         
677         return &rk_drm_priv->screen_priv[i].drm_disp;
678 }
679
680 static int rk_drm_screen_blank(struct rk_drm_display *drm_disp)
681 {
682 //      struct rk_drm_private *rk_drm_priv = platform_get_drvdata(drm_fb_pdev);
683         struct rk_drm_screen_private *drm_screen_priv =
684                 container_of(drm_disp, struct rk_drm_screen_private, drm_disp);
685         struct rk_lcdc_driver *lcdc_dev = drm_screen_priv->lcdc_dev_drv;
686
687         lcdc_dev->ops->blank(lcdc_dev, 0,drm_disp->enable?FB_BLANK_UNBLANK:FB_BLANK_NORMAL);
688
689         return 0;
690 }
691
692 int rk_fb_disp_scale(u8 scale_x, u8 scale_y, u8 lcdc_id)
693 {
694         return 0;
695 }
696 /**********************************************************************
697 this is for hdmi
698 name: lcdc device name ,lcdc0 , lcdc1
699 ***********************************************************************/
700 struct rk_lcdc_driver *rk_get_lcdc_drv(char *name)
701 {
702         struct rk_drm_private *rk_drm_priv = platform_get_drvdata(drm_fb_pdev);
703         int i = 0;
704         for (i = 0; i < rk_drm_priv->num_screen; i++) {
705                 if (!strcmp(rk_drm_priv->screen_priv[i].lcdc_dev_drv->name, name))
706                         break;
707         }
708         return rk_drm_priv->screen_priv[i].lcdc_dev_drv;
709
710 }
711 int rk_fb_switch_screen(struct rk_screen *screen , int enable, int lcdc_id)
712 {
713         struct rk_drm_private *rk_drm_priv = platform_get_drvdata(drm_fb_pdev);
714         struct rk_lcdc_driver *dev_drv = NULL;
715         struct rk_drm_display *drm_disp = NULL;
716         char name[6];
717         int i;
718         
719         sprintf(name, "lcdc%d", lcdc_id);
720
721         if (rk_drm_priv->disp_mode != DUAL) {
722                 dev_drv = rk_drm_priv->screen_priv[0].lcdc_dev_drv;
723         } else {
724
725                 for (i = 0; i < rk_drm_priv->num_screen; i++) {
726                         if (rk_drm_priv->screen_priv[i].lcdc_dev_drv->prop == EXTEND) {
727                                 drm_disp = &rk_drm_priv->screen_priv[i].drm_disp;
728                                 dev_drv = rk_drm_priv->screen_priv[i].lcdc_dev_drv;
729                                 break;
730                         }
731                 }
732
733                 if (i == rk_drm_priv->num_screen) {
734                         printk(KERN_ERR "%s driver not found!", name);
735                         return -ENODEV;
736                 }
737         }
738         printk("hdmi %s lcdc%d\n", enable ? "connect to" : "remove from", dev_drv->id);
739
740
741         if(enable && !drm_disp->is_connected ){
742                 struct list_head *modelist;
743                 struct fb_modelist *modelist1;
744                 struct fb_videomode *mode;
745                 struct rk_display_device *ex_display = rk_drm_priv->screen_priv[i].ex_display;
746                 memcpy(dev_drv->cur_screen, screen, sizeof(struct rk_screen));
747                 if(ex_display == NULL)
748                         ex_display = rk_drm_extend_display_get(SCREEN_HDMI);
749                 rk_drm_priv->screen_priv[i].ex_display = ex_display;
750                 ex_display->ops->getmodelist(ex_display,&modelist);
751                 
752                 drm_disp->modelist = modelist;
753
754                 drm_disp->is_connected = true;
755                 drm_disp->event_call_back(drm_disp,0,RK_DRM_CALLBACK_HOTPLUG);
756         }else{
757 //      printk("----->yzq %s %d \n",__func__,__LINE__);
758                 drm_disp->is_connected = false;
759                 drm_disp->event_call_back(drm_disp,0,RK_DRM_CALLBACK_HOTPLUG);
760 //      printk("----->yzq %s %d \n",__func__,__LINE__);
761         }
762
763
764 }
765 static int rk_drm_screen_videomode_set(struct rk_drm_display *drm_disp)
766 {
767 //      struct rk_drm_private *rk_drm_priv = platform_get_drvdata(drm_fb_pdev);
768         struct rk_drm_screen_private *drm_screen_priv =
769                 container_of(drm_disp, struct rk_drm_screen_private, drm_disp);
770         struct rk_lcdc_driver *lcdc_dev = drm_screen_priv->lcdc_dev_drv;
771         struct fb_videomode *mode = drm_disp->mode;
772         if(!mode){
773                 printk(KERN_ERR"-->%s fb_video mode is NULL",__func__);
774                 return -1;
775         }
776
777 //      printk("----->yzq %s %d xres=%d yres=%d refresh=%d \n",__func__,__LINE__,mode->xres,mode->yres,mode->refresh);
778         if(lcdc_dev->prop == PRMRY){
779                 if(mode != &lcdc_dev->cur_screen->mode)
780                         memcpy(&lcdc_dev->cur_screen->mode,mode,sizeof(struct fb_videomode));
781
782         }else{
783                 struct rk_display_device *ex_display = drm_screen_priv->ex_display;
784                 if(ex_display == NULL)
785                         ex_display = rk_drm_extend_display_get(SCREEN_HDMI);
786
787         //      printk("------>yzq ex_display=%x\n",ex_display);
788                 if(ex_display == NULL){
789                         printk(KERN_ERR"-->%s can not find extend display ops\n",__func__);
790                         return -1;
791                 }
792                 ex_display->ops->setmode(ex_display, mode);
793         }
794         if(!lcdc_dev->atv_layer_cnt)
795                 lcdc_dev->ops->open(lcdc_dev, 0,true);
796
797         lcdc_dev->ops->ovl_mgr(lcdc_dev, 3210, 1);
798         lcdc_dev->ops->load_screen(lcdc_dev,1);
799
800         return 0;
801 }
802
803 static int rk_drm_win_commit(struct rk_drm_display *drm_disp,unsigned int win_id)
804 {
805 //      struct rk_drm_private *rk_drm_priv = platform_get_drvdata(drm_fb_pdev);
806         struct rk_drm_screen_private *drm_screen_priv =
807                 container_of(drm_disp, struct rk_drm_screen_private, drm_disp);
808         struct rk_lcdc_driver *lcdc_dev = drm_screen_priv->lcdc_dev_drv;
809
810         unsigned int i=0,j=0;
811         for( i=1; i < RK_DRM_WIN_MASK; i=i<<1){
812                 if(i&win_id ){
813                         struct rk_lcdc_win *lcdc_win = lcdc_dev->win[j];
814                         struct rk_win_data *drm_win= &drm_disp->win[j];
815                         if(!lcdc_win && !drm_win){
816                                 printk(KERN_ERR"---->%s can not find display win%d\n",__func__,j);
817                                 return -1;
818                         }
819                         lcdc_win->format = drm_win->format;
820                         lcdc_win->area[0].xpos = drm_win->xpos;
821                         lcdc_win->area[0].ypos = drm_win->ypos;
822                         lcdc_win->area[0].xsize = drm_win->xsize;
823                         lcdc_win->area[0].ysize = drm_win->ysize;
824                         lcdc_win->area[0].xact = drm_win->xact;
825                         lcdc_win->area[0].yact = drm_win->yact;
826                         lcdc_win->area[0].xvir = drm_win->xvir;
827                         lcdc_win->area[0].y_vir_stride = drm_win->xvir;
828                         lcdc_win->area[0].smem_start = drm_win->yrgb_addr;
829                         lcdc_win->area[0].cbr_start = drm_win->uv_addr;
830                         lcdc_win->alpha_en = 1;
831                         if(lcdc_win->state != drm_win->enabled){
832                                 lcdc_dev->ops->open(lcdc_dev, j,drm_win->enabled?true:false);
833                         }
834                         lcdc_dev->ops->set_par(lcdc_dev,j);
835                         lcdc_dev->ops->pan_display(lcdc_dev,j);
836                 }
837                 j++;
838         }
839         return 0;
840 }
841
842 static int rk_drm_display_commit(struct rk_drm_display *drm_disp)
843 {
844 //      struct rk_drm_private *rk_drm_priv = platform_get_drvdata(drm_fb_pdev);
845         struct rk_drm_screen_private *drm_screen_priv =
846                 container_of(drm_disp, struct rk_drm_screen_private, drm_disp);
847         struct rk_lcdc_driver *lcdc_dev = drm_screen_priv->lcdc_dev_drv;
848         lcdc_dev->ops->lcdc_reg_update(lcdc_dev);
849         return 0;
850 }
851
852 int rk_drm_disp_handle(struct rk_drm_display *drm_disp,unsigned int win_id,unsigned int cmd_id)
853 {
854 //      struct rk_drm_private *rk_drm_priv = platform_get_drvdata(drm_fb_pdev);
855         struct rk_drm_screen_private *drm_screen_priv =
856                 container_of(drm_disp, struct rk_drm_screen_private, drm_disp);
857         int i=0;
858         for( i=1; i<RK_DRM_CMD_MASK; i=i<<1){
859                 switch(i&cmd_id){
860                         case RK_DRM_SCREEN_SET:
861                                 rk_drm_screen_videomode_set(drm_disp);
862                                 break;
863                         case RK_DRM_SCREEN_BLANK:
864                                 rk_drm_screen_blank(drm_disp);
865                                 break;
866                         case RK_DRM_WIN_COMMIT:
867                                 rk_drm_win_commit(drm_disp, win_id);
868                                 break;
869                         case RK_DRM_DISPLAY_COMMIT:
870                                 if(win_id & i){
871                                         if (!wait_event_timeout(drm_screen_priv->wait_vsync_queue,
872                                                                 !atomic_read(&drm_screen_priv->wait_vsync_done),
873                                                                 DRM_HZ/20))
874                                                 printk("wait frame timed out.\n");
875                                 }
876
877                                 rk_drm_display_commit(drm_disp);
878                                 if(win_id & i){
879                                         atomic_set(&drm_screen_priv->wait_vsync_done,1);
880                                 }
881                 }
882                         
883         }
884         return 0;
885 }
886
887 struct rk_drm_display *rk_drm_get_diplay(int screen_type)
888 {
889         struct rk_drm_private *rk_drm_priv = platform_get_drvdata(drm_fb_pdev);
890         int i=0;
891         for( i=0; i < rk_drm_priv->num_screen; i++){
892                 if(rk_drm_priv->screen_priv[i].drm_disp.screen_type == screen_type)
893                         return &rk_drm_priv->screen_priv[i].drm_disp;
894         }
895
896         return NULL;
897 }
898
899
900 static int rk_drm_fb_probe(struct platform_device *pdev)
901 {
902         struct rk_drm_private  *rk_drm_priv= NULL;
903         struct device_node *np = pdev->dev.of_node;
904         u32 mode;
905
906         if (!np) {
907                 dev_err(&pdev->dev, "Missing device tree node.\n");
908                 return -EINVAL;
909         }
910
911         rk_drm_priv= devm_kzalloc(&pdev->dev, sizeof(struct rk_drm_private), GFP_KERNEL);
912         if (!rk_drm_priv) {
913                 dev_err(&pdev->dev, "kmalloc for rk_drm_priv fail!");
914                 return  -ENOMEM;
915         }
916         platform_set_drvdata(pdev, rk_drm_priv);
917
918         if (!of_property_read_u32(np, "rockchip,disp-mode", &mode)) {
919                 rk_drm_priv->disp_mode = mode;
920         } else {
921                 dev_err(&pdev->dev, "no disp-mode node found!");
922                 return -ENODEV;
923         }
924         dev_set_name(&pdev->dev, "rockchip-drmfb");
925
926         drm_fb_pdev = pdev;
927         dev_info(&pdev->dev, "rockchip drm framebuffer driver probe\n");
928         return 0;
929 }
930
931 static int rk_drm_fb_remove(struct platform_device *pdev)
932 {
933         struct rk_drm_private  *rk_drm_priv = platform_get_drvdata(pdev);
934         kfree(rk_drm_priv);
935         platform_set_drvdata(pdev, NULL);
936         return 0;
937 }
938
939 static void rk_drm_fb_shutdown(struct platform_device *pdev)
940 {
941         return;
942 }
943
944
945 static const struct of_device_id rk_drm_fb_dt_ids[] = {
946         { .compatible = "rockchip,rk-fb", },
947         {}
948 };
949
950 static struct platform_driver rk_drm_fb_driver = {
951         .probe          = rk_drm_fb_probe,
952         .remove         = rk_drm_fb_remove,
953         .driver         = {
954                 .name   = "rk-fb",
955                 .owner  = THIS_MODULE,
956                 .of_match_table = of_match_ptr(rk_drm_fb_dt_ids),
957         },
958         .shutdown   = rk_drm_fb_shutdown,
959 };
960
961 static int __init rk_drm_fb_init(void)
962 {
963         return platform_driver_register(&rk_drm_fb_driver);
964 }
965
966 static void __exit rk_drm_fb_exit(void)
967 {
968         platform_driver_unregister(&rk_drm_fb_driver);
969 }
970
971 fs_initcall(rk_drm_fb_init);
972 module_exit(rk_drm_fb_exit);