2 * drivers/video/rockchip/rk_fb.c
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.
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.
16 #include <linux/module.h>
17 #include <linux/kernel.h>
18 #include <linux/errno.h>
19 #include <linux/string.h>
21 #include <linux/slab.h>
22 #include <linux/delay.h>
23 #include <linux/device.h>
24 #include <linux/kthread.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>
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>
42 #include <linux/display-sys.h>
43 #include "rk_drm_fb.h"
44 __weak int support_uboot_display(void)
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)
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;
62 printk(KERN_WARNING "%s:un supported extend display:%d!\n",
67 int rk_fb_trsm_ops_register(struct rk_fb_trsm_ops *ops, int type)
72 case SCREEN_DUAL_LVDS:
79 case SCREEN_DUAL_MIPI:
83 printk(KERN_WARNING "%s:un supported transmitter:%d!\n",
90 struct rk_display_device *rk_drm_extend_display_get(int type)
92 struct rk_display_device *extend_display = NULL;
96 extend_display = disp_hdmi_devices;
98 printk(KERN_WARNING "%s:screen hdmi ops is NULL!\n",__func__);
101 printk(KERN_WARNING "%s:un supported extend display:%d!\n",
105 return extend_display;
108 struct void *get_extend_drv(void)
110 struct rk_display_device *extend_display = rk_drm_extend_display_get(SCREEN_HDMI);
111 return extend_display->priv_data;
114 struct rk_fb_trsm_ops *rk_fb_trsm_ops_get(int type)
116 struct rk_fb_trsm_ops *ops;
120 case SCREEN_DUAL_LVDS:
127 case SCREEN_DUAL_MIPI:
132 printk(KERN_WARNING "%s:un supported transmitter:%d!\n",
138 /* rk display power control parse from dts
141 int rk_disp_pwr_ctr_parse_dt(struct rk_lcdc_driver *dev_drv)
143 struct device_node *root = of_get_child_by_name(dev_drv->dev->of_node,
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;
154 INIT_LIST_HEAD(&dev_drv->pwrlist_head);
156 dev_err(dev_drv->dev, "can't find power_ctr node for lcdc%d\n",dev_drv->id);
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)) {
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);
171 pwr_ctr->pwr_ctr.atv_val = !(flags & OF_GPIO_ACTIVE_LOW);
172 ret = gpio_request(pwr_ctr->pwr_ctr.gpio,child->name);
174 dev_err(dev_drv->dev, "request %s gpio fail:%d\n",
179 pwr_ctr->pwr_ctr.type = REGULATOR;
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);
188 of_property_read_u32(root, "rockchip,mirror", &mirror);
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;
204 of_property_read_u32(root, "rockchip,debug", &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"
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);
226 int rk_fb_video_mode_from_timing(const struct display_timing *dt,
227 struct rk_screen *screen)
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;
242 if (dt->flags & DISPLAY_FLAGS_PIXDATA_POSEDGE)
243 screen->pin_dclk = 1;
245 screen->pin_dclk = 0;
246 if(dt->flags & DISPLAY_FLAGS_HSYNC_HIGH)
247 screen->pin_hsync = 1;
249 screen->pin_hsync = 0;
250 if(dt->flags & DISPLAY_FLAGS_VSYNC_HIGH)
251 screen->pin_vsync = 1;
253 screen->pin_vsync = 0;
254 if(dt->flags & DISPLAY_FLAGS_DE_HIGH)
263 int rk_fb_prase_timing_dt(struct device_node *np, struct rk_screen *screen)
265 struct display_timings *disp_timing;
266 struct display_timing *dt;
267 disp_timing = of_get_display_timings(np);
269 pr_err("parse display timing err\n");
272 dt = display_timings_get(disp_timing, 0);
273 rk_fb_video_mode_from_timing(dt, screen);
274 printk(KERN_ERR "dclk:%d\n"
289 dt->hfront_porch.typ,
293 dt->vfront_porch.typ,
301 static int init_lcdc_win(struct rk_lcdc_driver *dev_drv, struct rk_lcdc_win *def_win)
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);
309 dev_err(dev_drv->dev, "kzmalloc for win fail!");
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;
322 static int init_lcdc_device_driver(struct rk_drm_screen_private *screen_priv,
323 struct rk_lcdc_win *def_win, int index)
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);
331 dev_err(dev_drv->dev, "malloc screen for lcdc%d fail!",
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);
349 dev_err(dev_drv->dev, "malloc screen1 for lcdc%d fail!",
353 screen1->screen_id = 1;
354 screen1->lcdc_id = 1;
355 dev_drv->screen1 = screen1;
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);
374 devm_kfree(dev_drv->dev,screen);
379 int rk_disp_pwr_enable(struct rk_lcdc_driver *dev_drv)
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))
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);
397 int rk_fb_calc_fps(struct rk_screen * screen, u32 pixclock)
400 unsigned long long hz;
402 printk(KERN_ERR "%s:null screen!\n", __func__);
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;
410 hz = 1000000000000ULL; /* 1e12 picoseconds per second */
413 do_div(hz, x * y); /* divide by x * y with rounding */
416 do_div(hz, pixclock); /* divide by pixclock with rounding */
421 char *get_format_string(enum data_format format, char *fmt)
427 strcpy(fmt, "ARGB888");
430 strcpy(fmt, "RGB888");
433 strcpy(fmt, "RGB565");
436 strcpy(fmt, "YUV420");
439 strcpy(fmt, "YUV422");
442 strcpy(fmt, "YUV444");
445 strcpy(fmt, "XRGB888");
448 strcpy(fmt, "XBGR888");
451 strcpy(fmt, "XBGR888");
454 strcpy(fmt, "invalid");
461 int rk_disp_pwr_disable(struct rk_lcdc_driver *dev_drv)
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))
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);
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)
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)
492 static void rk_fb_update_regs_handler(struct kthread_work *work)
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;
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);
504 list_for_each_entry_safe(data, next, &saved_list, list) {
505 //rk_fb_update_reg(dev_drv,data);
506 list_del(&data->list);
511 static int rk_fb_wait_for_vsync_thread(void *data)
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;
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)
524 drm_display = &drm_screen_priv->drm_disp;
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));
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);
536 if(!ret && drm_display->event_call_back)
537 drm_display->event_call_back(drm_display,0,RK_DRM_CALLBACK_VSYNC);
544 static void rk_drm_irq_handle(struct rk_lcdc_driver *dev_drv)
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)
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);
561 if(drm_display->event_call_back)
562 drm_display->event_call_back(drm_display,0,RK_DRM_CALLBACK_VSYNC);
564 int rk_fb_register(struct rk_lcdc_driver *dev_drv,
565 struct rk_lcdc_win *win, int id)
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;
572 if (rk_drm_priv->num_screen == RK30_MAX_LCDC_SUPPORT)
574 for (i = 0; i < RK_DRM_MAX_SCREEN_NUM; i++) {
575 if (!rk_drm_priv->screen_priv[i].lcdc_dev_drv)
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;
583 init_lcdc_device_driver(drm_screen_priv,win,i);
584 dev_drv->irq_call_back = rk_drm_irq_handle;
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),
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));
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);
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);
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;
618 drm_screen_priv->ex_display->ops->getmodelist(drm_screen_priv->ex_display,&modelist);
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);
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;
632 dev_drv->vsync_info.active = 1;
634 mutex_init(&dev_drv->output_lock);
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);
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;
646 printk("failed to run update_regs thread\n");
649 init_kthread_work(&dev_drv->update_regs_work, rk_fb_update_regs_handler);
651 dev_drv->timeline = sw_sync_timeline_create("fb-timeline"); dev_drv->timeline_max = 1;
655 int rk_fb_unregister(struct rk_lcdc_driver *dev_drv)
658 struct rk_drm_private *rk_drm_priv = platform_get_drvdata(drm_fb_pdev);
664 struct rk_drm_display *rk_drm_get_info(int screen_type)
666 struct rk_drm_private *rk_drm_priv = platform_get_drvdata(drm_fb_pdev);
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)
672 if(i==rk_drm_priv->num_screen){
673 printk("--->%s can not find match DISPLAY_TYPE %d\n",__func__,screen_type);
677 return &rk_drm_priv->screen_priv[i].drm_disp;
680 static int rk_drm_screen_blank(struct rk_drm_display *drm_disp)
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;
687 lcdc_dev->ops->blank(lcdc_dev, 0,drm_disp->enable?FB_BLANK_UNBLANK:FB_BLANK_NORMAL);
692 int rk_fb_disp_scale(u8 scale_x, u8 scale_y, u8 lcdc_id)
696 /**********************************************************************
698 name: lcdc device name ,lcdc0 , lcdc1
699 ***********************************************************************/
700 struct rk_lcdc_driver *rk_get_lcdc_drv(char *name)
702 struct rk_drm_private *rk_drm_priv = platform_get_drvdata(drm_fb_pdev);
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))
708 return rk_drm_priv->screen_priv[i].lcdc_dev_drv;
711 int rk_fb_switch_screen(struct rk_screen *screen , int enable, int lcdc_id)
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;
719 sprintf(name, "lcdc%d", lcdc_id);
721 if (rk_drm_priv->disp_mode != DUAL) {
722 dev_drv = rk_drm_priv->screen_priv[0].lcdc_dev_drv;
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;
733 if (i == rk_drm_priv->num_screen) {
734 printk(KERN_ERR "%s driver not found!", name);
738 printk("hdmi %s lcdc%d\n", enable ? "connect to" : "remove from", dev_drv->id);
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);
752 drm_disp->modelist = modelist;
754 drm_disp->is_connected = true;
755 drm_disp->event_call_back(drm_disp,0,RK_DRM_CALLBACK_HOTPLUG);
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__);
765 static int rk_drm_screen_videomode_set(struct rk_drm_display *drm_disp)
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;
773 printk(KERN_ERR"-->%s fb_video mode is NULL",__func__);
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));
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);
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__);
792 ex_display->ops->setmode(ex_display, mode);
794 if(!lcdc_dev->atv_layer_cnt)
795 lcdc_dev->ops->open(lcdc_dev, 0,true);
797 lcdc_dev->ops->ovl_mgr(lcdc_dev, 3210, 1);
798 lcdc_dev->ops->load_screen(lcdc_dev,1);
803 static int rk_drm_win_commit(struct rk_drm_display *drm_disp,unsigned int win_id)
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;
810 unsigned int i=0,j=0;
811 for( i=1; i < RK_DRM_WIN_MASK; i=i<<1){
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);
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);
834 lcdc_dev->ops->set_par(lcdc_dev,j);
835 lcdc_dev->ops->pan_display(lcdc_dev,j);
842 static int rk_drm_display_commit(struct rk_drm_display *drm_disp)
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);
852 int rk_drm_disp_handle(struct rk_drm_display *drm_disp,unsigned int win_id,unsigned int cmd_id)
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);
858 for( i=1; i<RK_DRM_CMD_MASK; i=i<<1){
860 case RK_DRM_SCREEN_SET:
861 rk_drm_screen_videomode_set(drm_disp);
863 case RK_DRM_SCREEN_BLANK:
864 rk_drm_screen_blank(drm_disp);
866 case RK_DRM_WIN_COMMIT:
867 rk_drm_win_commit(drm_disp, win_id);
869 case RK_DRM_DISPLAY_COMMIT:
871 if (!wait_event_timeout(drm_screen_priv->wait_vsync_queue,
872 !atomic_read(&drm_screen_priv->wait_vsync_done),
874 printk("wait frame timed out.\n");
877 rk_drm_display_commit(drm_disp);
879 atomic_set(&drm_screen_priv->wait_vsync_done,1);
887 struct rk_drm_display *rk_drm_get_diplay(int screen_type)
889 struct rk_drm_private *rk_drm_priv = platform_get_drvdata(drm_fb_pdev);
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;
900 static int rk_drm_fb_probe(struct platform_device *pdev)
902 struct rk_drm_private *rk_drm_priv= NULL;
903 struct device_node *np = pdev->dev.of_node;
907 dev_err(&pdev->dev, "Missing device tree node.\n");
911 rk_drm_priv= devm_kzalloc(&pdev->dev, sizeof(struct rk_drm_private), GFP_KERNEL);
913 dev_err(&pdev->dev, "kmalloc for rk_drm_priv fail!");
916 platform_set_drvdata(pdev, rk_drm_priv);
918 if (!of_property_read_u32(np, "rockchip,disp-mode", &mode)) {
919 rk_drm_priv->disp_mode = mode;
921 dev_err(&pdev->dev, "no disp-mode node found!");
924 dev_set_name(&pdev->dev, "rockchip-drmfb");
927 dev_info(&pdev->dev, "rockchip drm framebuffer driver probe\n");
931 static int rk_drm_fb_remove(struct platform_device *pdev)
933 struct rk_drm_private *rk_drm_priv = platform_get_drvdata(pdev);
935 platform_set_drvdata(pdev, NULL);
939 static void rk_drm_fb_shutdown(struct platform_device *pdev)
945 static const struct of_device_id rk_drm_fb_dt_ids[] = {
946 { .compatible = "rockchip,rk-fb", },
950 static struct platform_driver rk_drm_fb_driver = {
951 .probe = rk_drm_fb_probe,
952 .remove = rk_drm_fb_remove,
955 .owner = THIS_MODULE,
956 .of_match_table = of_match_ptr(rk_drm_fb_dt_ids),
958 .shutdown = rk_drm_fb_shutdown,
961 static int __init rk_drm_fb_init(void)
963 return platform_driver_register(&rk_drm_fb_driver);
966 static void __exit rk_drm_fb_exit(void)
968 platform_driver_unregister(&rk_drm_fb_driver);
971 fs_initcall(rk_drm_fb_init);
972 module_exit(rk_drm_fb_exit);