Revert "rk fb: new framework test ok at rk3188"
[firefly-linux-kernel-4.4.55.git] / drivers / video / rockchip / rk_fb.c
1 /*
2  * drivers/video/rockchip/rk_fb.c
3  *
4  * Copyright (C) ROCKCHIP, Inc.
5  *Author:yxj<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
33
34 #if defined(CONFIG_RK_HDMI)
35 #include "hdmi/rk_hdmi.h"
36 #endif
37
38 #ifdef CONFIG_OF
39 #include <linux/of.h>
40 #include <linux/of_gpio.h>
41 #include <video/of_display_timing.h>
42 #include <video/display_timing.h>
43 #include <dt-bindings/rkfb/rk_fb.h>
44 #endif
45
46 #if defined(CONFIG_ION_ROCKCHIP)
47 #include <linux/rockchip_ion.h>
48 #endif
49
50
51 static int hdmi_switch_complete;
52 static struct platform_device *fb_pdev;
53
54
55 #if defined(CONFIG_FB_MIRRORING)
56 int (*video_data_to_mirroring)(struct fb_info *info, u32 yuv_phy[2]);
57 EXPORT_SYMBOL(video_data_to_mirroring);
58 #endif
59
60
61
62
63 /* rk display power control parse from dts
64  *
65 */
66 int rk_disp_pwr_ctr_parse_dt(struct rk_lcdc_driver *dev_drv)
67 {
68         struct device_node *root  = of_parse_phandle(dev_drv->dev->of_node,
69                                 "power_ctr", 0);
70         struct device_node *child;
71         struct rk_disp_pwr_ctr_list *pwr_ctr;
72         struct list_head *pos;
73         enum of_gpio_flags flags;
74         u32 val = 0;
75         u32 debug = 0;
76         int ret;
77
78         INIT_LIST_HEAD(&dev_drv->pwrlist_head);
79         if (!root) {
80                 dev_err(dev_drv->dev, "can't find power_ctr node for lcdc%d\n",dev_drv->id);
81                 return -ENODEV;
82         }
83
84         for_each_child_of_node(root, child) {
85                 pwr_ctr = kmalloc(sizeof(struct rk_disp_pwr_ctr_list), GFP_KERNEL);
86                 strcpy(pwr_ctr->pwr_ctr.name, child->name);
87                 if (!of_property_read_u32(child, "rockchip,power_type", &val)) {
88                         if (val == GPIO) {
89                                 pwr_ctr->pwr_ctr.type = GPIO;
90                                 pwr_ctr->pwr_ctr.gpio = of_get_gpio_flags(child, 0, &flags);
91                                 if (!gpio_is_valid(pwr_ctr->pwr_ctr.gpio)) {
92                                         dev_err(dev_drv->dev, "%s ivalid gpio\n", child->name);
93                                         return -EINVAL;
94                                 }
95                                 pwr_ctr->pwr_ctr.atv_val = !(flags & OF_GPIO_ACTIVE_LOW);
96                                 ret = gpio_request(pwr_ctr->pwr_ctr.gpio,child->name);
97                                 if (ret) {
98                                         dev_err(dev_drv->dev, "request %s gpio fail:%d\n",
99                                                 child->name,ret);
100                                 }
101
102                         } else {
103                                 pwr_ctr->pwr_ctr.type = REGULATOR;
104
105                         }
106                 };
107                 of_property_read_u32(child, "rockchip,delay", &val);
108                 pwr_ctr->pwr_ctr.delay = val;
109                 list_add_tail(&pwr_ctr->list, &dev_drv->pwrlist_head);
110         }
111
112         of_property_read_u32(root, "rockchip,debug", &debug);
113
114         if (debug) {
115                 list_for_each(pos, &dev_drv->pwrlist_head) {
116                         pwr_ctr = list_entry(pos, struct rk_disp_pwr_ctr_list, list);
117                         printk(KERN_INFO "pwr_ctr_name:%s\n"
118                                          "pwr_type:%s\n"
119                                          "gpio:%d\n"
120                                          "atv_val:%d\n"
121                                          "delay:%d\n\n",
122                                          pwr_ctr->pwr_ctr.name,
123                                          (pwr_ctr->pwr_ctr.type == GPIO) ? "gpio" : "regulator",
124                                          pwr_ctr->pwr_ctr.gpio,
125                                          pwr_ctr->pwr_ctr.atv_val,
126                                          pwr_ctr->pwr_ctr.delay);
127                 }
128         }
129
130         return 0;
131
132 }
133
134 int rk_disp_pwr_enable(struct rk_lcdc_driver *dev_drv)
135 {
136         struct list_head *pos;
137         struct rk_disp_pwr_ctr_list *pwr_ctr_list;
138         struct pwr_ctr *pwr_ctr;
139         if (list_empty(&dev_drv->pwrlist_head))
140                 return 0;
141         list_for_each(pos, &dev_drv->pwrlist_head) {
142                 pwr_ctr_list = list_entry(pos, struct rk_disp_pwr_ctr_list, list);
143                 pwr_ctr = &pwr_ctr_list->pwr_ctr;
144                 if (pwr_ctr->type == GPIO) {
145                         gpio_direction_output(pwr_ctr->gpio,pwr_ctr->atv_val);
146                         mdelay(pwr_ctr->delay);
147                 }
148         }
149
150         return 0;
151 }
152
153 int rk_disp_pwr_disable(struct rk_lcdc_driver *dev_drv)
154 {
155         struct list_head *pos;
156         struct rk_disp_pwr_ctr_list *pwr_ctr_list;
157         struct pwr_ctr *pwr_ctr;
158         if (list_empty(&dev_drv->pwrlist_head))
159                 return 0;
160         list_for_each(pos, &dev_drv->pwrlist_head) {
161                 pwr_ctr_list = list_entry(pos, struct rk_disp_pwr_ctr_list, list);
162                 pwr_ctr = &pwr_ctr_list->pwr_ctr;
163                 if (pwr_ctr->type == GPIO) {
164                         gpio_set_value(pwr_ctr->gpio,pwr_ctr->atv_val);
165                 }
166         }
167
168         return 0;
169 }
170
171 int rk_fb_video_mode_from_timing(const struct display_timing *dt, 
172                                 struct rk_screen *screen)
173 {
174         screen->mode.pixclock = dt->pixelclock.typ;
175         screen->mode.left_margin = dt->hback_porch.typ;
176         screen->mode.right_margin = dt->hfront_porch.typ;
177         screen->mode.xres = dt->hactive.typ;
178         screen->mode.hsync_len = dt->hsync_len.typ;
179         screen->mode.upper_margin = dt->vback_porch.typ;
180         screen->mode.lower_margin = dt->vfront_porch.typ;
181         screen->mode.yres = dt->vactive.typ;
182         screen->mode.vsync_len = dt->vsync_len.typ;
183         screen->type = dt->screen_type;
184         screen->lvds_format = dt->lvds_format;
185         screen->face = dt->face;
186         if (dt->flags & DISPLAY_FLAGS_PIXDATA_POSEDGE)
187                 screen->pin_dclk = 1;
188         else
189                 screen->pin_dclk = 0;
190         if(dt->flags & DISPLAY_FLAGS_HSYNC_HIGH)
191                 screen->pin_hsync = 1;
192         else
193                 screen->pin_hsync = 0;
194         if(dt->flags & DISPLAY_FLAGS_VSYNC_HIGH)
195                 screen->pin_vsync = 1;
196         else
197                 screen->pin_vsync = 0;
198         if(dt->flags & DISPLAY_FLAGS_DE_HIGH)
199                 screen->pin_den = 1;
200         else
201                 screen->pin_den = 0;
202         
203         return 0;
204         
205 }
206 int rk_disp_prase_timing_dt(struct rk_lcdc_driver *dev_drv)
207 {
208         struct display_timings *disp_timing;
209         struct display_timing *dt;
210         struct rk_screen *screen = dev_drv->cur_screen;
211         disp_timing = of_get_display_timings(dev_drv->dev->of_node);
212         if (!disp_timing) {
213                 dev_err(dev_drv->dev, "parse display timing err\n");
214                 return -EINVAL;
215         }
216         dt = display_timings_get(disp_timing, 0);
217         rk_fb_video_mode_from_timing(dt, screen);
218         printk(KERN_DEBUG "dclk:%d\n"
219                          "hactive:%d\n"
220                          "hback_porch:%d\n"
221                          "hfront_porch:%d\n"
222                          "hsync_len:%d\n"
223                          "vactive:%d\n"
224                          "vback_porch:%d\n"
225                          "vfront_porch:%d\n"
226                          "vsync_len:%d\n",
227                         dt->pixelclock.typ,
228                         dt->hactive.typ,
229                         dt->hback_porch.typ,
230                         dt->hfront_porch.typ,
231                         dt->hsync_len.typ,
232                         dt->vactive.typ,
233                         dt->vback_porch.typ,
234                         dt->vfront_porch.typ,
235                         dt->vsync_len.typ);
236         return 0;
237
238 }
239
240 int  rk_fb_calc_fps(struct rk_screen * screen, u32 pixclock)
241 {
242         int x, y;
243         unsigned long long hz;
244         if (!screen) {
245                 printk(KERN_ERR "%s:null screen!\n", __func__);
246                 return 0;
247         }
248         x = screen->mode.xres + screen->mode.left_margin + screen->mode.right_margin +
249             screen->mode.hsync_len;
250         y = screen->mode.yres + screen->mode.upper_margin + screen->mode.lower_margin +
251             screen->mode.vsync_len;
252
253         hz = 1000000000000ULL;  /* 1e12 picoseconds per second */
254
255         hz += (x * y) / 2;
256         do_div(hz, x * y);      /* divide by x * y with rounding */
257
258         hz += pixclock / 2;
259         do_div(hz, pixclock);   /* divide by pixclock with rounding */
260
261         return hz;
262 }
263
264 char *get_format_string(enum data_format format, char *fmt)
265 {
266         if (!fmt)
267                 return NULL;
268         switch (format) {
269         case ARGB888:
270                 strcpy(fmt, "ARGB888");
271                 break;
272         case RGB888:
273                 strcpy(fmt, "RGB888");
274                 break;
275         case RGB565:
276                 strcpy(fmt, "RGB565");
277                 break;
278         case YUV420:
279                 strcpy(fmt, "YUV420");
280                 break;
281         case YUV422:
282                 strcpy(fmt, "YUV422");
283                 break;
284         case YUV444:
285                 strcpy(fmt, "YUV444");
286                 break;
287         case XRGB888:
288                 strcpy(fmt, "XRGB888");
289                 break;
290         case XBGR888:
291                 strcpy(fmt, "XBGR888");
292                 break;
293         case ABGR888:
294                 strcpy(fmt, "XBGR888");
295                 break;
296         default:
297                 strcpy(fmt, "invalid");
298                 break;
299         }
300
301         return fmt;
302
303 }
304
305
306
307 /**********************************************************************
308 this is for hdmi
309 name: lcdc device name ,lcdc0 , lcdc1
310 ***********************************************************************/
311 struct rk_lcdc_driver *rk_get_lcdc_drv(char *name)
312 {
313         struct rk_fb *inf =  platform_get_drvdata(fb_pdev);
314         int i = 0;
315         for (i = 0; i < inf->num_lcdc; i++) {
316                 if (!strcmp(inf->lcdc_dev_drv[i]->name, name))
317                         break;
318         }
319         return inf->lcdc_dev_drv[i];
320
321 }
322
323 static struct rk_lcdc_driver *rk_get_prmry_lcdc_drv(void)
324 {
325         struct rk_fb *inf = NULL;
326         struct rk_lcdc_driver *dev_drv = NULL;
327         int i = 0;
328
329         if (likely(fb_pdev))
330                 inf = platform_get_drvdata(fb_pdev);
331         else
332                 return NULL;
333
334         for (i = 0; i < inf->num_lcdc; i++) {
335                 if (inf->lcdc_dev_drv[i]->prop ==  PRMRY) {
336                         dev_drv = inf->lcdc_dev_drv[i];
337                         break;
338                 }
339         }
340
341         return dev_drv;
342 }
343
344
345 int rk_fb_get_prmry_screen_ft(void)
346 {
347         struct rk_lcdc_driver *dev_drv = rk_get_prmry_lcdc_drv();
348         uint32_t htotal, vtotal, pix_total, ft_us, dclk_mhz;
349
350         if (unlikely(!dev_drv))
351                 return 0;
352
353         dclk_mhz = dev_drv->pixclock/(1000*1000);
354
355         htotal = (dev_drv->cur_screen->mode.upper_margin + dev_drv->cur_screen->mode.lower_margin +
356                 dev_drv->cur_screen->mode.yres + dev_drv->cur_screen->mode.vsync_len);
357         vtotal = (dev_drv->cur_screen->mode.left_margin + dev_drv->cur_screen->mode.right_margin +
358                 dev_drv->cur_screen->mode.xres + dev_drv->cur_screen->mode.hsync_len);
359         pix_total = htotal*vtotal;
360         ft_us = pix_total / dclk_mhz;
361
362         return ft_us;
363 }
364
365 static struct rk_lcdc_driver  *rk_get_extend_lcdc_drv(void)
366 {
367         struct rk_fb *inf = NULL;
368         struct rk_lcdc_driver *dev_drv = NULL;
369         int i = 0;
370
371         if (likely(fb_pdev))
372                 inf = platform_get_drvdata(fb_pdev);
373         else
374                 return NULL;
375
376         for (i = 0; i < inf->num_lcdc; i++) {
377                 if (inf->lcdc_dev_drv[i]->prop == EXTEND) {
378                         dev_drv = inf->lcdc_dev_drv[i];
379                         break;
380                 }
381         }
382
383         return dev_drv;
384 }
385
386 int rk_fb_get_prmry_screen(struct rk_screen *screen)
387 {
388         struct rk_lcdc_driver *dev_drv = rk_get_prmry_lcdc_drv();
389         memcpy(screen, dev_drv->screen0, sizeof(struct rk_screen));
390         return 0;
391         
392
393 }
394
395 u32 rk_fb_get_prmry_screen_pixclock(void)
396 {
397         struct rk_lcdc_driver *dev_drv = rk_get_prmry_lcdc_drv();
398         return dev_drv->pixclock;
399 }
400
401 int rk_fb_poll_prmry_screen_vblank(void)
402 {
403         struct rk_lcdc_driver *dev_drv = rk_get_prmry_lcdc_drv();
404         if (likely(dev_drv)) {
405                 if (dev_drv->ops->poll_vblank)
406                         return dev_drv->ops->poll_vblank(dev_drv);
407                 else
408                         return RK_LF_STATUS_NC;
409         } else
410                 return RK_LF_STATUS_NC;
411 }
412
413 bool rk_fb_poll_wait_frame_complete(void)
414 {
415         uint32_t timeout = RK_LF_MAX_TIMEOUT;
416         if (rk_fb_poll_prmry_screen_vblank() == RK_LF_STATUS_NC)
417                 return false;
418
419         while (!(rk_fb_poll_prmry_screen_vblank() == RK_LF_STATUS_FR)  &&  --timeout);
420         while (!(rk_fb_poll_prmry_screen_vblank() == RK_LF_STATUS_FC)  &&  --timeout);
421
422         return true;
423 }
424 static int rk_fb_open(struct fb_info *info, int user)
425 {
426         struct rk_lcdc_driver *dev_drv = (struct rk_lcdc_driver *)info->par;
427         int win_id;
428
429         win_id = dev_drv->ops->fb_get_win_id(dev_drv, info->fix.id);
430         if (dev_drv->win[win_id]->state)
431                 return 0;    /* if this win aready opened ,no need to reopen*/
432         else
433                 dev_drv->ops->open(dev_drv, win_id, 1);
434         return 0;
435 }
436
437 static int  get_extend_fb_id(struct fb_info *info)
438 {
439         int fb_id = 0;
440         char *id = info->fix.id;
441         struct rk_lcdc_driver *dev_drv = (struct rk_lcdc_driver *)info->par;
442         if (!strcmp(id, "fb0"))
443                 fb_id = 0;
444         else if (!strcmp(id, "fb1"))
445                 fb_id = 1;
446         else if (!strcmp(id, "fb2") && (dev_drv->num_win > 2))
447                 fb_id = 2;
448         return fb_id;
449 }
450
451 static int rk_fb_close(struct fb_info *info, int user)
452 {
453         struct rk_lcdc_driver *dev_drv = (struct rk_lcdc_driver *)info->par;
454         struct rk_lcdc_win *win = NULL;
455         int win_id = dev_drv->ops->fb_get_win_id(dev_drv, info->fix.id);
456         if (win_id >= 0) {
457                 win = dev_drv->win[win_id];
458                 info->fix.smem_start = win->reserved;
459
460                 info->var.xres = dev_drv->screen0->mode.xres;
461                 info->var.yres = dev_drv->screen0->mode.yres;
462                 info->var.grayscale |= (info->var.xres<<8) + (info->var.yres<<20);
463 #if defined(CONFIG_LOGO_LINUX_BMP)
464                 info->var.bits_per_pixel = 32;
465 #else
466                 info->var.bits_per_pixel = 16;
467 #endif
468                 info->fix.line_length  = (info->var.xres)*(info->var.bits_per_pixel>>3);
469                 info->var.xres_virtual = info->var.xres;
470                 info->var.yres_virtual = info->var.yres;
471                 info->var.width =  dev_drv->screen0->width;
472                 info->var.height = dev_drv->screen0->height;
473                 info->var.pixclock = dev_drv->pixclock;
474                 info->var.left_margin = dev_drv->screen0->mode.left_margin;
475                 info->var.right_margin = dev_drv->screen0->mode.right_margin;
476                 info->var.upper_margin = dev_drv->screen0->mode.upper_margin;
477                 info->var.lower_margin = dev_drv->screen0->mode.lower_margin;
478                 info->var.vsync_len = dev_drv->screen0->mode.vsync_len;
479                 info->var.hsync_len = dev_drv->screen0->mode.hsync_len;
480         }
481
482         return 0;
483 }
484
485
486 #if defined(CONFIG_RK29_IPP)
487 static int get_ipp_format(int fmt)
488 {
489         int ipp_fmt = IPP_XRGB_8888;
490         switch (fmt) {
491         case HAL_PIXEL_FORMAT_RGBX_8888:
492         case HAL_PIXEL_FORMAT_RGBA_8888:
493         case HAL_PIXEL_FORMAT_BGRA_8888:
494         case HAL_PIXEL_FORMAT_RGB_888:
495                 ipp_fmt = IPP_XRGB_8888;
496                 break;
497         case HAL_PIXEL_FORMAT_RGB_565:
498                 ipp_fmt = IPP_RGB_565;
499                 break;
500         case HAL_PIXEL_FORMAT_YCbCr_422_SP:
501                 ipp_fmt = IPP_Y_CBCR_H2V1;
502                 break;
503         case HAL_PIXEL_FORMAT_YCrCb_NV12:
504                 ipp_fmt = IPP_Y_CBCR_H2V2;
505                 break;
506         case HAL_PIXEL_FORMAT_YCrCb_444:
507                 ipp_fmt = IPP_Y_CBCR_H1V1;
508                 break;
509         default:
510                 ipp_fmt = IPP_IMGTYPE_LIMIT;
511                 break;
512         }
513
514         return ipp_fmt;
515 }
516
517 static void ipp_win_check(int *dst_w, int *dst_h, int *dst_vir_w,
518                                 int rotation, int fmt)
519 {
520         int align16 = 2;
521         int align64 = 8;
522
523
524         if (fmt == IPP_XRGB_8888) {
525                 align16 = 1;
526                 align64 = 2;
527         } else if (fmt == IPP_RGB_565) {
528                 align16 = 1;
529                 align64 = 4;
530         } else {
531                 align16 = 2;
532                 align64 = 8;
533         }
534         align16 -= 1;  /*for YUV, 1*/
535         align64 -= 1;  /*for YUV, 7*/
536
537         if (rotation == IPP_ROT_0) {
538                 if (fmt > IPP_RGB_565) {
539                         if ((*dst_w & 1) != 0)
540                                 *dst_w = *dst_w+1;
541                         if ((*dst_h & 1) != 0)
542                                 *dst_h = *dst_h+1;
543                         if (*dst_vir_w < *dst_w)
544                                 *dst_vir_w = *dst_w;
545                 }
546         } else {
547
548                 if ((*dst_w & align64) != 0)
549                         *dst_w = (*dst_w+align64)&(~align64);
550                 if ((fmt > IPP_RGB_565) && ((*dst_h & 1) == 1))
551                         *dst_h = *dst_h+1;
552                 if (*dst_vir_w < *dst_w)
553                         *dst_vir_w = *dst_w;
554         }
555
556 }
557
558 static void fb_copy_by_ipp(struct fb_info *dst_info,
559                 struct fb_info *src_info, int offset)
560 {
561         struct rk29_ipp_req ipp_req;
562         uint32_t  rotation = 0;
563         int dst_w, dst_h, dst_vir_w;
564         int ipp_fmt;
565         u8 data_format = (dst_info->var.nonstd)&0xff;
566
567         memset(&ipp_req, 0, sizeof(struct rk29_ipp_req));
568 #if defined(CONFIG_FB_ROTATE)
569         int orientation = 270 - CONFIG_ROTATE_ORIENTATION;
570         switch (orientation) {
571         case 0:
572                 rotation = IPP_ROT_0;
573                 break;
574         case 90:
575                 rotation = IPP_ROT_90;
576                 break;
577         case 180:
578                 rotation = IPP_ROT_180;
579                 break;
580         case 270:
581                 rotation = IPP_ROT_270;
582                 break;
583         default:
584                 rotation = IPP_ROT_270;
585                 break;
586
587         }
588 #endif
589
590         dst_w = dst_info->var.xres;
591         dst_h = dst_info->var.yres;
592         dst_vir_w = dst_info->var.xres_virtual;
593         ipp_fmt = get_ipp_format(data_format);
594         ipp_win_check(&dst_w, &dst_h, &dst_vir_w, rotation, ipp_fmt);
595         ipp_req.src0.YrgbMst = src_info->fix.smem_start + offset;
596         ipp_req.src0.w = src_info->var.xres;
597         ipp_req.src0.h = src_info->var.yres;
598         ipp_req.src_vir_w = src_info->var.xres_virtual;
599         ipp_req.src0.fmt = ipp_fmt;
600
601         ipp_req.dst0.YrgbMst = dst_info->fix.smem_start + offset;
602         ipp_req.dst0.w = dst_w;
603         ipp_req.dst0.h = dst_h;
604         ipp_req.dst_vir_w = dst_vir_w;
605         ipp_req.dst0.fmt = ipp_fmt;
606
607
608         ipp_req.timeout = 100;
609         ipp_req.flag = rotation;
610         ipp_blit_sync(&ipp_req);
611
612 }
613
614 #endif
615
616
617 static int rk_fb_rotate(struct fb_info *dst_info,
618                                 struct fb_info *src_info, int offset)
619 {
620         #if defined(CONFIG_RK29_IPP)
621                 fb_copy_by_ipp(dst_info, src_info, offset);
622         #else
623                 return -1;
624         #endif
625                 return 0;
626 }
627 static int rk_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
628 {
629         struct rk_fb *rk_fb = dev_get_drvdata(info->device);
630         struct rk_lcdc_driver *dev_drv  = (struct rk_lcdc_driver *)info->par;
631         struct fb_fix_screeninfo *fix = &info->fix;
632         struct fb_info *extend_info = NULL;
633         struct rk_lcdc_driver *extend_dev_drv = NULL;
634         int win_id = 0, extend_win_id = 0;
635         struct rk_lcdc_win *extend_win = NULL;
636         struct rk_lcdc_win *win = NULL;
637         int fb_id = 0;
638
639
640         u32 xoffset = var->xoffset;
641         u32 yoffset = var->yoffset;
642         u32 xvir = var->xres_virtual;
643         u8 data_format = var->nonstd&0xff;
644
645         win_id = dev_drv->ops->fb_get_win_id(dev_drv, info->fix.id);
646         if (win_id < 0)
647                 return  -ENODEV;
648         else
649                 win = dev_drv->win[win_id];
650
651         if (rk_fb->disp_mode == DUAL) {
652                 fb_id = get_extend_fb_id(info);
653                 extend_info = rk_fb->fb[(rk_fb->num_fb>>1) + fb_id];
654                 extend_dev_drv  = (struct rk_lcdc_driver *)extend_info->par;
655                 extend_win_id = dev_drv->ops->fb_get_win_id(extend_dev_drv,
656                                                 extend_info->fix.id);
657                 extend_win = extend_dev_drv->win[extend_win_id];
658         }
659
660         switch (win->format) {
661         case XBGR888:
662         case ARGB888:
663         case ABGR888:
664                 win->y_offset = (yoffset*xvir + xoffset)*4;
665                 break;
666         case  RGB888:
667                 win->y_offset = (yoffset*xvir + xoffset)*3;
668                 break;
669         case RGB565:
670                 win->y_offset = (yoffset*xvir + xoffset)*2;
671                 break;
672         case  YUV422:
673                 win->y_offset = yoffset*xvir + xoffset;
674                 win->c_offset = win->y_offset;
675                 break;
676         case  YUV420:
677                 win->y_offset = yoffset*xvir + xoffset;
678                 win->c_offset = (yoffset>>1)*xvir + xoffset;
679                 break;
680         case  YUV444:
681                 win->y_offset = yoffset*xvir + xoffset;
682                 win->c_offset = yoffset*2*xvir + (xoffset<<1);
683                 break;
684         default:
685                 printk(KERN_ERR "%s un supported format:0x%x\n",
686                         __func__, data_format);
687                 return -EINVAL;
688         }
689         win->smem_start = fix->smem_start;
690         win->cbr_start = fix->mmio_start;
691         dev_drv->ops->pan_display(dev_drv, win_id);
692         if (rk_fb->disp_mode == DUAL) {
693                 if (extend_win->state && (hdmi_switch_complete)) {
694                         extend_win->y_offset = win->y_offset;
695                 #if defined(CONFIG_FB_ROTATE) || !defined(CONFIG_THREE_FB_BUFFER)
696                         rk_fb_rotate(extend_info, info, win->y_offset);
697                 #endif
698                         extend_dev_drv->ops->pan_display(extend_dev_drv, extend_win_id);
699                 }
700         }
701
702         #ifdef  CONFIG_FB_MIRRORING
703         if (video_data_to_mirroring)
704                 video_data_to_mirroring(info, NULL);
705         #endif
706         return 0;
707 }
708
709 static int rk_fb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
710 {
711         struct rk_fb *rk_fb = dev_get_drvdata(info->device);
712         struct rk_lcdc_driver *dev_drv = (struct rk_lcdc_driver *)info->par;
713         struct fb_fix_screeninfo *fix = &info->fix;
714         int fb_id = 0, extend_win_id = 0;
715         struct fb_info *extend_info = NULL;
716         struct rk_lcdc_driver *extend_dev_drv = NULL;
717         struct rk_lcdc_win *extend_win = NULL;
718         struct rk_lcdc_win *win;
719         int enable; /* enable fb:1 enable;0 disable*/
720         int ovl;   /*overlay:0 win1 on the top of win0;1,win0 on the top of win1*/
721         int num_buf; /*buffer_number*/
722         int ret;
723
724         int  win_id = dev_drv->ops->fb_get_win_id(dev_drv, info->fix.id);
725         
726         void __user *argp = (void __user *)arg;
727
728         win = dev_drv->win[win_id];
729         if (rk_fb->disp_mode == DUAL) {
730                 fb_id = get_extend_fb_id(info);
731                 extend_info = rk_fb->fb[(rk_fb->num_fb>>1) + fb_id];
732                 extend_dev_drv  = (struct rk_lcdc_driver *)extend_info->par;
733                 extend_win_id = dev_drv->ops->fb_get_win_id(extend_dev_drv,
734                                                 extend_info->fix.id);
735                 extend_win = extend_dev_drv->win[extend_win_id];
736         }
737
738         switch (cmd) {
739         case RK_FBIOSET_YUV_ADDR:
740         {
741                 u32 yuv_phy[2];
742                 if (copy_from_user(yuv_phy, argp, 8))
743                         return -EFAULT;
744                 fix->smem_start = yuv_phy[0];
745                 fix->mmio_start = yuv_phy[1];
746                 break;
747         }
748         case RK_FBIOSET_ENABLE:
749                 if (copy_from_user(&enable, argp, sizeof(enable)))
750                         return -EFAULT;
751                 dev_drv->ops->open(dev_drv, win_id, enable);
752                 break;
753         case RK_FBIOGET_ENABLE:
754                 enable = dev_drv->ops->get_win_state(dev_drv, win_id);
755                 if (copy_to_user(argp, &enable, sizeof(enable)))
756                         return -EFAULT;
757                 break;
758         case RK_FBIOSET_OVERLAY_STATE:
759                 if (copy_from_user(&ovl, argp, sizeof(ovl)))
760                         return -EFAULT;
761                 dev_drv->ops->ovl_mgr(dev_drv, ovl, 1);
762                 break;
763         case RK_FBIOGET_OVERLAY_STATE:
764                 ovl = dev_drv->ops->ovl_mgr(dev_drv, 0, 0);
765                 if (copy_to_user(argp, &ovl, sizeof(ovl)))
766                         return -EFAULT;
767                 break;
768         case RK_FBIOPUT_NUM_BUFFERS:
769                 if (copy_from_user(&num_buf, argp, sizeof(num_buf)))
770                         return -EFAULT;
771                 dev_drv->num_buf = num_buf;
772                 break;
773         case RK_FBIOSET_VSYNC_ENABLE:
774                 if (copy_from_user(&enable, argp, sizeof(enable)))
775                         return -EFAULT;
776                 dev_drv->vsync_info.active = enable;
777                 break;
778 #if defined(CONFIG_ION_ROCKCHIP)
779         case RK_FBIOSET_DMABUF_FD:
780         {
781                 int usr_fd;
782                 struct ion_handle *hdl;
783                 ion_phys_addr_t phy_addr;
784                 size_t len;
785                 if (copy_from_user(&usr_fd, argp, sizeof(usr_fd)))
786                         return -EFAULT;
787                 hdl = ion_import_dma_buf(rk_fb->ion_client, usr_fd);
788                 ion_phys(rk_fb->ion_client, hdl, &phy_addr, &len);
789                 fix->smem_start = phy_addr;
790                 break;
791         }
792         case RK_FBIOGET_DMABUF_FD:
793         {
794                 int fd = ion_share_dma_buf_fd(rk_fb->ion_client, win->ion_hdl);
795                 if (fd < 0) {
796                         dev_err(info->dev, "ion_share_dma_buf_fd failed\n");
797                         return fd;
798
799                 }
800                 if (copy_to_user(argp, &fd, sizeof(fd)))
801                         return -EFAULT;
802                 break;
803         }
804 #endif
805         case RK_FBIOSET_CONFIG_DONE:
806                 ret = copy_from_user(&(dev_drv->wait_fs), argp, sizeof(dev_drv->wait_fs));
807                 if (dev_drv->ops->lcdc_reg_update)
808                         dev_drv->ops->lcdc_reg_update(dev_drv);
809                 if (rk_fb->disp_mode == DUAL) {
810                         if (extend_win->state && (hdmi_switch_complete)) {
811                                 if (rk_fb->num_fb >= 2) {
812                                         if (extend_dev_drv->ops->lcdc_reg_update)
813                                                 extend_dev_drv->ops->lcdc_reg_update(extend_dev_drv);
814                                 }
815                         }
816                 }
817                 break;
818         default:
819                 dev_drv->ops->ioctl(dev_drv, cmd, arg, win_id);
820                 break;
821         }
822         
823         return 0;
824 }
825
826 static int rk_fb_blank(int blank_mode, struct fb_info *info)
827 {
828         struct rk_lcdc_driver *dev_drv = (struct rk_lcdc_driver *)info->par;
829         struct fb_fix_screeninfo *fix = &info->fix;
830         int win_id;
831
832         win_id = dev_drv->ops->fb_get_win_id(dev_drv, fix->id);
833         if (win_id < 0)
834                 return  -ENODEV;
835 #if defined(CONFIG_RK_HDMI)
836         struct rk_fb *rk_fb = dev_get_drvdata(info->device);
837         if ((rk_fb->disp_mode == ONE_DUAL) && (hdmi_get_hotplug() == HDMI_HPD_ACTIVED)) {
838                 printk(KERN_INFO "hdmi is connect , not blank lcdc\n");
839         } else
840 #endif
841         {
842                 dev_drv->ops->blank(dev_drv, win_id, blank_mode);
843         }
844         return 0;
845 }
846
847 static int rk_fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
848 {
849
850         if ((0 == var->xres_virtual) || (0 == var->yres_virtual) ||
851                 (0 == var->xres) || (0 == var->yres) || (var->xres < 16) ||
852                 ((16 != var->bits_per_pixel) && (32 != var->bits_per_pixel))) {
853                 dev_err(info->dev, "%s check var fail 1:\n"
854                                 "xres_vir:%d>>yres_vir:%d\n"
855                                 "xres:%d>>yres:%d\n"
856                                 "bits_per_pixel:%d\n",
857                                 info->fix.id,
858                                 var->xres_virtual,
859                                 var->yres_virtual,
860                                 var->xres,
861                                 var->yres,
862                                 var->bits_per_pixel);
863                 return -EINVAL;
864         }
865
866         if (((var->xoffset+var->xres) > var->xres_virtual) ||
867                 ((var->yoffset+var->yres) > (var->yres_virtual))) {
868                 dev_err(info->dev, "%s check_var fail 2:\n"
869                                 "xoffset:%d>>xres:%d>>xres_vir:%d\n"
870                                 "yoffset:%d>>yres:%d>>yres_vir:%d\n",
871                                 info->fix.id,
872                                 var->xoffset,
873                                 var->xres,
874                                 var->xres_virtual,
875                                 var->yoffset,
876                                 var->yres,
877                                 var->yres_virtual);
878                 return -EINVAL;
879         }
880
881         return 0;
882 }
883
884 static ssize_t rk_fb_read(struct fb_info *info, char __user *buf,
885                            size_t count, loff_t *ppos)
886 {
887         unsigned long p = *ppos;
888         u8 *buffer, *dst;
889         u8 __iomem *src;
890         int c, cnt = 0, err = 0;
891         unsigned long total_size;
892         struct rk_lcdc_driver *dev_drv = (struct rk_lcdc_driver *)info->par;
893         struct rk_lcdc_win *win = NULL;
894         int win_id = 0;
895
896         win_id = dev_drv->ops->fb_get_win_id(dev_drv, info->fix.id);
897         if (win_id < 0)
898                 return  -ENODEV;
899         else
900                 win = dev_drv->win[win_id];
901
902         if (win->format == RGB565)
903                 total_size = win->xact*win->yact<<1; /*only read the current frame buffer*/
904         else
905                 total_size = win->xact*win->yact<<2;
906
907
908         if (p >= total_size)
909                 return 0;
910
911         if (count >= total_size)
912                 count = total_size;
913
914         if (count + p > total_size)
915                 count = total_size - p;
916
917         buffer = kmalloc((count > PAGE_SIZE) ? PAGE_SIZE : count,
918                          GFP_KERNEL);
919         if (!buffer)
920                 return -ENOMEM;
921
922         src = (u8 __iomem *) (info->screen_base + p + win->y_offset);
923
924         while (count) {
925                 c  = (count > PAGE_SIZE) ? PAGE_SIZE : count;
926                 dst = buffer;
927                 fb_memcpy_fromfb(dst, src, c);
928                 dst += c;
929                 src += c;
930
931                 if (copy_to_user(buf, buffer, c)) {
932                         err = -EFAULT;
933                         break;
934                 }
935                 *ppos += c;
936                 buf += c;
937                 cnt += c;
938                 count -= c;
939         }
940
941         kfree(buffer);
942
943         return (err) ? err : cnt;
944 }
945
946 static ssize_t rk_fb_write(struct fb_info *info, const char __user *buf,
947                             size_t count, loff_t *ppos)
948 {
949         unsigned long p = *ppos;
950         u8 *buffer, *src;
951         u8 __iomem *dst;
952         int c, cnt = 0, err = 0;
953         unsigned long total_size;
954         struct rk_lcdc_driver *dev_drv = (struct rk_lcdc_driver *)info->par;
955         struct rk_lcdc_win *win = NULL;
956         int win_id = 0;
957
958         win_id = dev_drv->ops->fb_get_win_id(dev_drv, info->fix.id);
959         if (win_id < 0)
960                 return  -ENODEV;
961         else
962                 win = dev_drv->win[win_id];
963
964         if (win->format == RGB565)
965                 total_size = win->xact*win->yact<<1; /*write the current frame buffer*/
966         else
967                 total_size = win->xact*win->yact<<2;
968
969         if (p > total_size)
970                 return -EFBIG;
971
972         if (count > total_size) {
973                 err = -EFBIG;
974                 count = total_size;
975         }
976
977         if (count + p > total_size) {
978                 if (!err)
979                         err = -ENOSPC;
980
981                 count = total_size - p;
982         }
983
984         buffer = kmalloc((count > PAGE_SIZE) ? PAGE_SIZE : count,
985                          GFP_KERNEL);
986         if (!buffer)
987                 return -ENOMEM;
988
989         dst = (u8 __iomem *) (info->screen_base + p + win->y_offset);
990
991         while (count) {
992                 c = (count > PAGE_SIZE) ? PAGE_SIZE : count;
993                 src = buffer;
994
995                 if (copy_from_user(src, buf, c)) {
996                         err = -EFAULT;
997                         break;
998                 }
999
1000                 fb_memcpy_tofb(dst, src, c);
1001                 dst += c;
1002                 src += c;
1003                 *ppos += c;
1004                 buf += c;
1005                 cnt += c;
1006                 count -= c;
1007         }
1008
1009         kfree(buffer);
1010
1011         return (cnt) ? cnt : err;
1012
1013 }
1014
1015 static int rk_fb_set_par(struct fb_info *info)
1016 {
1017         struct fb_var_screeninfo *var = &info->var;
1018         struct fb_fix_screeninfo *fix = &info->fix;
1019         struct rk_lcdc_driver *dev_drv = (struct rk_lcdc_driver *)info->par;
1020         struct rk_fb *rk_fb = dev_get_drvdata(info->device);
1021         int fb_id, extend_win_id = 0;
1022         struct fb_info *extend_info = NULL;
1023         struct rk_lcdc_driver *extend_dev_drv = NULL;
1024         struct rk_lcdc_win *extend_win = NULL;
1025         struct rk_lcdc_win *win = NULL;
1026         struct rk_screen *screen = dev_drv->cur_screen;
1027         int win_id = 0;
1028         u32 cblen = 0, crlen = 0;
1029         u16 xsize = 0, ysize = 0;                 /*winx display window height/width --->LCDC_WINx_DSP_INFO*/
1030         u32 xoffset = var->xoffset;             /* offset from virtual to visible*/
1031         u32 yoffset = var->yoffset;
1032         u16 xpos = (var->nonstd>>8) & 0xfff;   /*visiable pos in panel*/
1033         u16 ypos = (var->nonstd>>20) & 0xfff;
1034         u32 xvir = var->xres_virtual;
1035         u32 yvir = var->yres_virtual;
1036         u8 data_format = var->nonstd&0xff;
1037
1038
1039
1040         var->pixclock = dev_drv->pixclock;
1041         win_id = dev_drv->ops->fb_get_win_id(dev_drv, info->fix.id);
1042         if (win_id < 0)
1043                 return  -ENODEV;
1044         else
1045                 win = dev_drv->win[win_id];
1046
1047         if (rk_fb->disp_mode == DUAL) {
1048                 fb_id = get_extend_fb_id(info);
1049                 extend_info = rk_fb->fb[(rk_fb->num_fb>>1) + fb_id];
1050                 extend_dev_drv  = (struct rk_lcdc_driver *)extend_info->par;
1051                 extend_win_id = dev_drv->ops->fb_get_win_id(extend_dev_drv,
1052                                         extend_info->fix.id);
1053                 extend_win = extend_dev_drv->win[extend_win_id];
1054         }
1055         if (var->grayscale>>8) { /*if the application has specific the horizontal and vertical display size*/
1056                 xsize = (var->grayscale>>8) & 0xfff;
1057                 ysize = (var->grayscale>>20) & 0xfff;
1058         } else  { /*ohterwise  full  screen display*/
1059                 xsize = screen->mode.xres;
1060                 ysize = screen->mode.yres;
1061         }
1062
1063 /*this is for device like rk2928 ,whic have one lcdc but two display outputs*/
1064 /*save winameter set by android*/
1065 if (rk_fb->disp_mode != DUAL) {
1066         if (screen->screen_id == 0) {
1067
1068                 dev_drv->screen0->xsize = xsize;
1069                 dev_drv->screen0->ysize = ysize;
1070                 dev_drv->screen0->xpos  = xpos;
1071                 dev_drv->screen0->ypos = ypos;
1072         } else {
1073                 xsize = dev_drv->screen1->xsize;
1074                 ysize = dev_drv->screen1->ysize;
1075                 xpos = dev_drv->screen1->xpos;
1076                 ypos = dev_drv->screen1->ypos;
1077         }
1078 }
1079
1080 #if 1
1081         switch (data_format) {
1082         case HAL_PIXEL_FORMAT_RGBX_8888:
1083                 win->format = XBGR888;
1084                 fix->line_length = 4 * xvir;
1085                 win->y_offset = (yoffset*xvir + xoffset)*4;
1086                 break;
1087         case HAL_PIXEL_FORMAT_RGBA_8888:
1088                 win->format = ABGR888;
1089                 fix->line_length = 4 * xvir;
1090                 win->y_offset = (yoffset*xvir + xoffset)*4;
1091                 break;
1092         case HAL_PIXEL_FORMAT_BGRA_8888:
1093                 win->format = ARGB888;
1094                 fix->line_length = 4 * xvir;
1095                 win->y_offset = (yoffset*xvir + xoffset)*4;
1096                 break;
1097         case HAL_PIXEL_FORMAT_RGB_888:
1098                 win->format = RGB888;
1099                 fix->line_length = 3 * xvir;
1100                 win->y_offset = (yoffset*xvir + xoffset)*3;
1101                 break;
1102         case HAL_PIXEL_FORMAT_RGB_565:
1103                 win->format = RGB565;
1104                 fix->line_length = 2 * xvir;
1105                 win->y_offset = (yoffset*xvir + xoffset)*2;
1106                 break;
1107         case HAL_PIXEL_FORMAT_YCbCr_422_SP:
1108                 win->format = YUV422;
1109                 fix->line_length = xvir;
1110                 cblen = crlen = (xvir*yvir)>>1;
1111                 win->y_offset = yoffset*xvir + xoffset;
1112                 win->c_offset = win->y_offset;
1113                 break;
1114         case HAL_PIXEL_FORMAT_YCrCb_NV12:
1115                 win->format = YUV420;
1116                 fix->line_length = xvir;
1117                 cblen = crlen = (xvir*yvir)>>2;
1118                 win->y_offset = yoffset*xvir + xoffset;
1119                 win->c_offset = (yoffset>>1)*xvir + xoffset;
1120                 break;
1121         case HAL_PIXEL_FORMAT_YCrCb_444:
1122                 win->format = 5;
1123                 fix->line_length = xvir<<2;
1124                 win->y_offset = yoffset*xvir + xoffset;
1125                 win->c_offset = yoffset*2*xvir + (xoffset<<1);
1126                 cblen = crlen = (xvir*yvir);
1127                 break;
1128         default:
1129                 printk(KERN_ERR "%s:un supported format:0x%x\n", __func__, data_format);
1130                 return -EINVAL;
1131         }
1132 #else
1133         switch (var->bits_per_pixel) {
1134         case 32:
1135                 win->format = ARGB888;
1136                 fix->line_length = 4 * xvir;
1137                 win->y_offset = (yoffset*xvir + xoffset)*4;
1138                 break;
1139         case 16:
1140                 win->format = RGB565;
1141                 fix->line_length = 2 * xvir;
1142                 win->y_offset = (yoffset*xvir + xoffset)*2;
1143                 break;
1144
1145         }
1146 #endif
1147
1148         win->xpos = xpos;
1149         win->ypos = ypos;
1150         win->xsize = xsize;
1151         win->ysize = ysize;
1152
1153         win->smem_start = fix->smem_start;
1154         win->cbr_start = fix->mmio_start;
1155         win->xact = var->xres;              /*winx active window height,is a wint of vir*/
1156         win->yact = var->yres;
1157         win->xvir =  var->xres_virtual;    /*virtual resolution  stride --->LCDC_WINx_VIR*/
1158         win->yvir =  var->yres_virtual;
1159         if (rk_fb->disp_mode == DUAL) {
1160                 if (extend_win->state && (hdmi_switch_complete)) {
1161                         if (info != extend_info) {
1162                                 if (win->xact < win->yact) {
1163                                         extend_win->xact = win->yact;
1164                                         extend_win->yact = win->xact;
1165                                         extend_win->xvir = win->yact;
1166                                         extend_info->var.xres = var->yres;
1167                                         extend_info->var.yres = var->xres;
1168                                         extend_info->var.xres_virtual = var->yres;
1169                                 } else {
1170                                         extend_win->xact = win->xact;
1171                                         extend_win->yact = win->yact;
1172                                         extend_win->xvir = win->xvir;
1173                                         extend_info->var.xres = var->xres;
1174                                         extend_info->var.yres = var->yres;
1175                                         extend_info->var.xres_virtual = var->xres_virtual;
1176                                 }
1177                                 extend_win->format = win->format;
1178                                 extend_info->var.nonstd &= 0xffffff00;
1179                                 extend_info->var.nonstd |= data_format;
1180                                 extend_dev_drv->ops->set_par(extend_dev_drv, extend_win_id);
1181                         }
1182                 }
1183         }
1184         dev_drv->ops->set_par(dev_drv, win_id);
1185
1186         return 0;
1187 }
1188
1189 static inline unsigned int chan_to_field(unsigned int chan,
1190                                          struct fb_bitfield *bf)
1191 {
1192         chan &= 0xffff;
1193         chan >>= 16 - bf->length;
1194         return chan << bf->offset;
1195 }
1196
1197 static int fb_setcolreg(unsigned regno,
1198                                unsigned red, unsigned green, unsigned blue,
1199                                unsigned transp, struct fb_info *info)
1200 {
1201         unsigned int val;
1202
1203         switch (info->fix.visual) {
1204         case FB_VISUAL_TRUECOLOR:
1205                 /* true-colour, use pseudo-palette */
1206                 if (regno < 16) {
1207                         u32 *pal = info->pseudo_palette;
1208                         val  = chan_to_field(red,   &info->var.red);
1209                         val |= chan_to_field(green, &info->var.green);
1210                         val |= chan_to_field(blue,  &info->var.blue);
1211                         pal[regno] = val;
1212                 }
1213                 break;
1214         default:
1215                 return -1;      /* unknown type */
1216         }
1217
1218         return 0;
1219 }
1220
1221 static struct fb_ops fb_ops = {
1222         .owner          = THIS_MODULE,
1223         .fb_open        = rk_fb_open,
1224         .fb_release     = rk_fb_close,
1225         .fb_check_var   = rk_fb_check_var,
1226         .fb_set_par     = rk_fb_set_par,
1227         .fb_blank       = rk_fb_blank,
1228         .fb_ioctl       = rk_fb_ioctl,
1229         .fb_pan_display = rk_pan_display,
1230         .fb_read        = rk_fb_read,
1231         .fb_write       = rk_fb_write,
1232         .fb_setcolreg   = fb_setcolreg,
1233         .fb_fillrect    = cfb_fillrect,
1234         .fb_copyarea    = cfb_copyarea,
1235         .fb_imageblit   = cfb_imageblit,
1236 };
1237
1238
1239
1240 static struct fb_var_screeninfo def_var = {
1241 #if defined(CONFIG_LOGO_LINUX_BMP)
1242         .red            = {16, 8, 0},
1243         .green          = {8, 8, 0},
1244         .blue           = {0, 8, 0},
1245         .transp         = {0, 0, 0},
1246         .nonstd         = HAL_PIXEL_FORMAT_BGRA_8888,
1247 #else
1248         .red            = {11, 5, 0},
1249         .green          = {5, 6, 0},
1250         .blue           = {0, 5, 0},
1251         .transp         = {0, 0, 0},
1252         .nonstd         = HAL_PIXEL_FORMAT_RGB_565,   /*(ypos<<20+xpos<<8+format) format*/
1253 #endif
1254         .grayscale      = 0,  /*(ysize<<20+xsize<<8)*/
1255         .activate       = FB_ACTIVATE_NOW,
1256         .accel_flags    = 0,
1257         .vmode          = FB_VMODE_NONINTERLACED,
1258 };
1259
1260 static struct fb_fix_screeninfo def_fix = {
1261         .type            = FB_TYPE_PACKED_PIXELS,
1262         .type_aux        = 0,
1263         .xpanstep        = 1,
1264         .ypanstep        = 1,
1265         .ywrapstep       = 0,
1266         .accel           = FB_ACCEL_NONE,
1267         .visual          = FB_VISUAL_TRUECOLOR,
1268
1269 };
1270
1271
1272 static int rk_fb_wait_for_vsync_thread(void *data)
1273 {
1274         struct rk_lcdc_driver  *dev_drv = data;
1275         struct rk_fb *rk_fb =  platform_get_drvdata(fb_pdev);
1276         struct fb_info *fbi = rk_fb->fb[0];
1277
1278         while (!kthread_should_stop()) {
1279                 ktime_t timestamp = dev_drv->vsync_info.timestamp;
1280                 int ret = wait_event_interruptible(dev_drv->vsync_info.wait,
1281                         !ktime_equal(timestamp, dev_drv->vsync_info.timestamp) &&
1282                         (dev_drv->vsync_info.active || dev_drv->vsync_info.irq_stop));
1283
1284                 if (!ret)
1285                         sysfs_notify(&fbi->dev->kobj, NULL, "vsync");
1286         }
1287
1288         return 0;
1289 }
1290
1291 static ssize_t rk_fb_vsync_show(struct device *dev,
1292                 struct device_attribute *attr, char *buf)
1293 {
1294         struct fb_info *fbi = dev_get_drvdata(dev);
1295         struct rk_lcdc_driver *dev_drv = (struct rk_lcdc_driver *)fbi->par;
1296         return scnprintf(buf, PAGE_SIZE, "%llu\n",
1297                         ktime_to_ns(dev_drv->vsync_info.timestamp));
1298 }
1299
1300 static DEVICE_ATTR(vsync, S_IRUGO, rk_fb_vsync_show, NULL);
1301
1302
1303 /*****************************************************************
1304 this two function is for other module that in the kernel which
1305 need show image directly through fb
1306 fb_id:we have 4 fb here,default we use fb0 for ui display
1307 *******************************************************************/
1308 struct fb_info *rk_get_fb(int fb_id)
1309 {
1310         struct rk_fb *inf =  platform_get_drvdata(fb_pdev);
1311         struct fb_info *fb = inf->fb[fb_id];
1312         return fb;
1313 }
1314 EXPORT_SYMBOL(rk_get_fb);
1315
1316 void rk_direct_fb_show(struct fb_info *fbi)
1317 {
1318         rk_fb_set_par(fbi);
1319         rk_pan_display(&fbi->var, fbi);
1320 }
1321 EXPORT_SYMBOL(rk_direct_fb_show);
1322
1323
1324 static int set_xact_yact_for_hdmi(struct fb_var_screeninfo *pmy_var,
1325                                         struct fb_var_screeninfo *hdmi_var)
1326 {
1327         if (pmy_var->xres < pmy_var->yres) {  /*vertical  lcd screen*/
1328                 hdmi_var->xres = pmy_var->yres;
1329                 hdmi_var->yres = pmy_var->xres;
1330                 hdmi_var->xres_virtual = pmy_var->yres;
1331         } else {
1332                 hdmi_var->xres = pmy_var->xres;
1333                 hdmi_var->yres = pmy_var->yres;
1334                 hdmi_var->xres_virtual = pmy_var->xres_virtual;
1335         }
1336
1337         return 0;
1338
1339 }
1340 int rk_fb_dpi_open(bool open)
1341 {
1342         struct rk_lcdc_driver *dev_drv = NULL;
1343         dev_drv = rk_get_prmry_lcdc_drv();
1344         dev_drv->ops->dpi_open(dev_drv, open);
1345
1346         return 0;
1347 }
1348 int rk_fb_dpi_win_sel(int win_id)
1349 {
1350         struct rk_lcdc_driver *dev_drv = NULL;
1351         dev_drv = rk_get_prmry_lcdc_drv();
1352         dev_drv->ops->dpi_win_sel(dev_drv, win_id);
1353
1354         return 0;
1355 }
1356 int rk_fb_dpi_status(void)
1357 {
1358         int ret;
1359         struct rk_lcdc_driver *dev_drv = NULL;
1360         dev_drv = rk_get_prmry_lcdc_drv();
1361         ret = dev_drv->ops->dpi_status(dev_drv);
1362
1363         return ret;
1364 }
1365
1366 /******************************************
1367 *function:this function will be called by hdmi,when
1368 *             hdmi plug in/out
1369 *screen: the screen attached to hdmi
1370 *enable: 1,hdmi plug in,0,hdmi plug out
1371 *lcdc_id: the lcdc id the hdmi attached ,0 or 1
1372 ******************************************/
1373 int rk_fb_switch_screen(struct rk_screen *screen , int enable, int lcdc_id)
1374 {
1375         struct rk_fb *rk_fb =  platform_get_drvdata(fb_pdev);
1376         struct fb_info *info = NULL;
1377         struct rk_lcdc_driver *dev_drv = NULL;
1378         struct fb_var_screeninfo *hdmi_var    = NULL;
1379         struct fb_var_screeninfo *pmy_var = NULL;      /*var for primary screen*/
1380         struct fb_info *pmy_info = NULL;
1381         struct fb_fix_screeninfo *pmy_fix = NULL;
1382         int i;
1383         struct fb_fix_screeninfo *hdmi_fix    = NULL;
1384         char name[6];
1385         int ret;
1386         int win_id;
1387
1388         if (rk_fb->disp_mode != DUAL)
1389                 rk29_backlight_set(0);
1390
1391         sprintf(name, "lcdc%d", lcdc_id);
1392
1393         if (rk_fb->disp_mode != DUAL) {
1394                 dev_drv = rk_fb->lcdc_dev_drv[0];
1395         } else {
1396
1397                 for (i = 0; i < rk_fb->num_lcdc; i++) {
1398                         if (rk_fb->lcdc_dev_drv[i]->prop == EXTEND) {
1399                                 dev_drv = rk_fb->lcdc_dev_drv[i];
1400                                 break;
1401                         }
1402                 }
1403
1404                 if (i == rk_fb->num_lcdc) {
1405                         printk(KERN_ERR "%s driver not found!", name);
1406                         return -ENODEV;
1407                 }
1408         }
1409         printk("hdmi %s lcdc%d\n", enable ? "connect to" : "remove from", dev_drv->id);
1410
1411         if (rk_fb->num_lcdc == 1)
1412                 info = rk_fb->fb[0];
1413         else if (rk_fb->num_lcdc == 2)
1414                 info = rk_fb->fb[dev_drv->num_win]; /*the main fb of lcdc1*/
1415
1416         if (dev_drv->screen1) { /*device like rk2928 ,have only one lcdc but two outputs*/
1417                 if (enable) {
1418                         memcpy(dev_drv->screen1, screen, sizeof(struct rk_screen));
1419                         dev_drv->screen1->lcdc_id = 0; /*connect screen1 to output interface 0*/
1420                         dev_drv->screen1->screen_id = 1;
1421                         dev_drv->screen0->lcdc_id = 1; /*connect screen0 to output interface 1*/
1422                         dev_drv->cur_screen = dev_drv->screen1;
1423                         dev_drv->screen0->ext_screen = dev_drv->screen1;
1424                         if (dev_drv->screen0->sscreen_get) {
1425                                 dev_drv->screen0->sscreen_get(dev_drv->screen0,
1426                                         dev_drv->cur_screen->hdmi_resolution);
1427                         }
1428
1429
1430                 } else {
1431                         dev_drv->screen1->lcdc_id = 1; /*connect screen1 to output interface 1*/
1432                         dev_drv->screen0->lcdc_id = 0; /*connect screen0 to output interface 0*/
1433                         dev_drv->cur_screen = dev_drv->screen0;
1434                         dev_drv->screen_ctr_info->set_screen_info(dev_drv->cur_screen,
1435                                         dev_drv->screen_ctr_info->lcd_info);
1436                 }
1437         } else{
1438                 if (enable)
1439                         memcpy(dev_drv->cur_screen, screen, sizeof(struct rk_screen));
1440         }
1441
1442
1443         win_id = dev_drv->ops->fb_get_win_id(dev_drv, info->fix.id);
1444
1445         if (!enable && !dev_drv->screen1) { /*only double lcdc device need to close*/
1446                 if (dev_drv->win[win_id]->state)
1447                         dev_drv->ops->open(dev_drv, win_id, enable); /*disable the win which attached to this fb*/
1448                 hdmi_switch_complete = 0;
1449
1450                 return 0;
1451         }
1452
1453         hdmi_var = &info->var;
1454         hdmi_fix = &info->fix;
1455         if (rk_fb->disp_mode  == DUAL) {
1456                 if (likely(rk_fb->num_lcdc == 2)) {
1457                         pmy_var = &rk_fb->fb[0]->var;
1458                         pmy_fix = &rk_fb->fb[0]->fix;
1459                         set_xact_yact_for_hdmi(pmy_var, hdmi_var);
1460                         hdmi_var->nonstd &= 0xffffff00;
1461                         hdmi_var->nonstd |= (pmy_var->nonstd & 0xff); /*use the same format as primary screen*/
1462                 } else {
1463                         printk(KERN_WARNING "%s>>only one lcdc,dual display no supported!", __func__);
1464                 }
1465         }
1466         hdmi_var->grayscale &= 0xff;
1467         hdmi_var->grayscale |= (dev_drv->cur_screen->mode.xres<<8) + (dev_drv->cur_screen->mode.yres<<20);
1468         if (dev_drv->screen1) { /*device like rk2928,whic have one lcdc but two outputs*/
1469         /*      info->var.nonstd &= 0xff;
1470                 info->var.nonstd |= (dev_drv->cur_screen->mode.xpos<<8) + (dev_drv->cur_screen->mode.ypos<<20);
1471                 info->var.grayscale &= 0xff;
1472                 info->var.grayscale |= (dev_drv->cur_screen->mode.x_res<<8) + (dev_drv->cur_screen->mode.y_res<<20);*/
1473                 dev_drv->screen1->xsize = dev_drv->cur_screen->mode.xres;
1474                 dev_drv->screen1->ysize = dev_drv->cur_screen->mode.yres;
1475                 dev_drv->screen1->xpos = 0;
1476                 dev_drv->screen1->ypos = 0;
1477         }
1478
1479         ret = info->fbops->fb_open(info, 1);
1480         dev_drv->ops->load_screen(dev_drv, 1);
1481         ret = info->fbops->fb_set_par(info);
1482         if (dev_drv->ops->lcdc_hdmi_process)
1483                 dev_drv->ops->lcdc_hdmi_process(dev_drv, enable);
1484
1485         if (rk_fb->disp_mode == DUAL) {
1486                 if (likely(rk_fb->num_lcdc == 2)) {
1487                         pmy_info = rk_fb->fb[0];
1488                         pmy_info->fbops->fb_pan_display(pmy_var, pmy_info);
1489                 } else {
1490                         printk(KERN_WARNING "%s>>only one lcdc,dual display no supported!", __func__);
1491                 }
1492         } else {
1493                 info->fbops->fb_pan_display(hdmi_var, info);
1494         }
1495         info->fbops->fb_ioctl(info, RK_FBIOSET_CONFIG_DONE, 0);
1496         if (dev_drv->screen1) {
1497                 if (dev_drv->screen0->sscreen_set) {
1498                         dev_drv->ops->blank(dev_drv, 0, FB_BLANK_NORMAL);
1499                         msleep(100);
1500                         dev_drv->screen0->sscreen_set(dev_drv->screen0, enable);
1501                         dev_drv->ops->blank(dev_drv, 0, FB_BLANK_UNBLANK);
1502                 }
1503         }
1504
1505         if (rk_fb->disp_mode != DUAL)
1506                 rk29_backlight_set(1);
1507         hdmi_switch_complete = enable;
1508         return 0;
1509
1510 }
1511
1512
1513
1514
1515 /******************************************
1516 function:this function current only called by hdmi for
1517         scale the display
1518 scale_x: scale rate of x resolution
1519 scale_y: scale rate of y resolution
1520 lcdc_id: the lcdc id the hdmi attached ,0 or 1
1521 ******************************************/
1522
1523 int rk_fb_disp_scale(u8 scale_x, u8 scale_y, u8 lcdc_id)
1524 {
1525         struct rk_fb *inf =  platform_get_drvdata(fb_pdev);
1526         struct fb_info *info = NULL;
1527         struct fb_var_screeninfo *var = NULL;
1528         struct rk_lcdc_driver *dev_drv = NULL;
1529         u16 screen_x, screen_y;
1530         u16 xpos, ypos;
1531         u16 xsize, ysize;
1532         char name[6];
1533         int i = 0;
1534         sprintf(name, "lcdc%d", lcdc_id);
1535
1536 #if defined(CONFIG_ONE_LCDC_DUAL_OUTPUT_INF)
1537         dev_drv = inf->lcdc_dev_drv[0];
1538 #else
1539         for (i = 0; i < inf->num_lcdc; i++) {
1540                 if (inf->lcdc_dev_drv[i]->prop == EXTEND) {
1541                         dev_drv = inf->lcdc_dev_drv[i];
1542                         break;
1543                 }
1544         }
1545
1546         if (i == inf->num_lcdc) {
1547                 printk(KERN_ERR "%s driver not found!", name);
1548                 return -ENODEV;
1549
1550         }
1551 #endif
1552         if (inf->num_lcdc == 1)
1553                 info = inf->fb[0];
1554         else if (inf->num_lcdc == 2)
1555                 info = inf->fb[dev_drv->num_win];
1556
1557         var = &info->var;
1558         screen_x = dev_drv->cur_screen->mode.xres;
1559         screen_y = dev_drv->cur_screen->mode.yres;
1560
1561 #if defined(CONFIG_ONE_LCDC_DUAL_OUTPUT_INF) || defined(CONFIG_NO_DUAL_DISP)
1562         if (dev_drv->cur_screen->screen_id == 1) {
1563                 dev_drv->cur_screen->xpos = (screen_x-screen_x*scale_x/100)>>1;
1564                 dev_drv->cur_screen->ypos = (screen_y-screen_y*scale_y/100)>>1;
1565                 dev_drv->cur_screen->xsize = screen_x*scale_x/100;
1566                 dev_drv->cur_screen->ysize = screen_y*scale_y/100;
1567         } else
1568 #endif
1569         {
1570                 xpos = (screen_x-screen_x*scale_x/100)>>1;
1571                 ypos = (screen_y-screen_y*scale_y/100)>>1;
1572                 xsize = screen_x*scale_x/100;
1573                 ysize = screen_y*scale_y/100;
1574                 var->nonstd &= 0xff;
1575                 var->nonstd |= (xpos<<8) + (ypos<<20);
1576                 var->grayscale &= 0xff;
1577                 var->grayscale |= (xsize<<8) + (ysize<<20);
1578         }
1579
1580         info->fbops->fb_set_par(info);
1581         info->fbops->fb_ioctl(info, RK_FBIOSET_CONFIG_DONE, 0);
1582         return 0;
1583
1584
1585 }
1586
1587 static int rk_fb_alloc_buffer(struct fb_info *fbi, int fb_id)
1588 {
1589         struct rk_fb *rk_fb = platform_get_drvdata(fb_pdev);
1590         struct rk_lcdc_driver *dev_drv = (struct rk_lcdc_driver *)fbi->par;
1591         struct rk_lcdc_win *win = NULL;
1592         int win_id;
1593         int ret = 0;
1594         unsigned long fb_mem_size;
1595 #if defined(CONFIG_ION_ROCKCHIP)
1596         struct ion_handle *handle;
1597         ion_phys_addr_t phy_addr;
1598         size_t len;
1599 #else
1600         dma_addr_t fb_mem_phys;
1601         void *fb_mem_virt;
1602 #endif
1603         win_id = dev_drv->ops->fb_get_win_id(dev_drv, fbi->fix.id);
1604         if (win_id < 0)
1605                 return  -ENODEV;
1606         else
1607                 win = dev_drv->win[win_id];
1608
1609         if (!strcmp(fbi->fix.id, "fb0")) {
1610                 fb_mem_size = 3 * (fbi->var.xres * fbi->var.yres) << 2;
1611                 fb_mem_size = ALIGN(fb_mem_size, SZ_1M);
1612 #if defined(CONFIG_ION_ROCKCHIP)
1613                 handle = ion_alloc(rk_fb->ion_client, (size_t)fb_mem_size, 0, ION_HEAP(ION_CMA_HEAP_ID), 0);
1614                 if (IS_ERR(handle)) {
1615                         dev_err(fbi->device, "failed to ion_alloc:%ld\n",PTR_ERR(handle));
1616                         return -ENOMEM;
1617                 }
1618                 win->ion_hdl = handle;
1619                 fbi->screen_base = ion_map_kernel(rk_fb->ion_client, handle);
1620                 ion_phys(rk_fb->ion_client, handle, &phy_addr, &len);
1621                 fbi->fix.smem_start = phy_addr;
1622                 fbi->fix.smem_len = len;        
1623 #else
1624
1625                 fb_mem_virt = dma_alloc_writecombine(fbi->dev, fb_mem_size, &fb_mem_phys,
1626                         GFP_KERNEL);
1627                 if (!fb_mem_virt) {
1628                         pr_err("%s: Failed to allocate framebuffer\n", __func__);
1629                         return -ENOMEM;
1630                 }
1631                 fbi->fix.smem_len = fb_mem_size;
1632                 fbi->fix.smem_start = fb_mem_phys;
1633                 fbi->screen_base = fb_mem_virt;
1634 #endif
1635                 memset(fbi->screen_base, 0, fbi->fix.smem_len);
1636                 printk(KERN_INFO "fb%d:phy:%lx>>vir:%p>>len:0x%x\n", fb_id,
1637                 fbi->fix.smem_start, fbi->screen_base, fbi->fix.smem_len);
1638         } else {
1639 #if defined(CONFIG_FB_ROTATE) || !defined(CONFIG_THREE_FB_BUFFER)
1640                 res = platform_get_resource_byname(fb_pdev,
1641                         IORESOURCE_MEM, "fb2 buf");
1642                 if (res == NULL) {
1643                         dev_err(&fb_pdev->dev, "failed to get win0 memory \n");
1644                         ret = -ENOENT;
1645                 }
1646                 fbi->fix.smem_start = res->start;
1647                 fbi->fix.smem_len = res->end - res->start + 1;
1648                 mem = request_mem_region(res->start, resource_size(res),
1649                         fb_pdev->name);
1650                 fbi->screen_base = ioremap(res->start, fbi->fix.smem_len);
1651                 memset(fbi->screen_base, 0, fbi->fix.smem_len);
1652 #else    /*three buffer no need to copy*/
1653                 fbi->fix.smem_start = rk_fb->fb[0]->fix.smem_start;
1654                 fbi->fix.smem_len   = rk_fb->fb[0]->fix.smem_len;
1655                 fbi->screen_base    = rk_fb->fb[0]->screen_base;
1656 #endif
1657                 printk(KERN_INFO "fb%d:phy:%lx>>vir:%p>>len:0x%x\n", fb_id,
1658                         fbi->fix.smem_start, fbi->screen_base, fbi->fix.smem_len);
1659         }
1660
1661         fbi->screen_size = fbi->fix.smem_len;
1662         win_id = dev_drv->ops->fb_get_win_id(dev_drv, fbi->fix.id);
1663         if (win_id >= 0) {
1664                 win = dev_drv->win[win_id];
1665                 win->reserved = fbi->fix.smem_start;
1666         }
1667
1668         return ret;
1669 }
1670
1671 static int rk_release_fb_buffer(struct fb_info *fbi)
1672 {
1673         if (!strcmp(fbi->fix.id, "fb1") || !strcmp(fbi->fix.id, "fb3"))  /*buffer for fb1 and fb3 are alloc by android*/
1674                 return 0;
1675         iounmap(fbi->screen_base);
1676         release_mem_region(fbi->fix.smem_start, fbi->fix.smem_len);
1677         return 0;
1678
1679 }
1680 static int init_lcdc_win(struct rk_lcdc_driver *dev_drv, struct rk_lcdc_win *def_win)
1681 {
1682         int i;
1683         int num_win = dev_drv->num_win;
1684         for (i = 0; i < num_win; i++) {
1685                 struct rk_lcdc_win *win = NULL;
1686                 win =  kzalloc(sizeof(struct rk_lcdc_win), GFP_KERNEL);
1687                 if (!win) {
1688                         dev_err(dev_drv->dev, "kzmalloc for win fail!");
1689                         return   -ENOMEM;
1690                 }
1691
1692                 strcpy(win->name, def_win->name);
1693                 win->id = def_win->id;
1694                 win->support_3d = def_win->support_3d;
1695                 dev_drv->win[i] = win;
1696         }
1697
1698         return 0;
1699 }
1700
1701
1702 static int init_lcdc_device_driver(struct rk_fb *rk_fb,
1703                                         struct rk_lcdc_win *def_win, int index)
1704 {
1705         struct rk_lcdc_driver *dev_drv = rk_fb->lcdc_dev_drv[index];
1706         struct rk_screen *screen = devm_kzalloc(dev_drv->dev,
1707                                 sizeof(struct rk_screen), GFP_KERNEL);
1708         if (!screen) {
1709                 dev_err(dev_drv->dev, "malloc screen for lcdc%d fail!",
1710                                         dev_drv->id);
1711                 return -ENOMEM;
1712         }
1713         
1714         screen->screen_id = 0;
1715         screen->lcdc_id = dev_drv->id;
1716         dev_drv->screen0 = screen;
1717         dev_drv->cur_screen = screen;
1718         /* devie use one lcdc + rk61x scaler for dual display*/
1719         if (rk_fb->disp_mode == ONE_DUAL) {
1720                 struct rk_screen *screen1 = devm_kzalloc(dev_drv->dev,
1721                                                 sizeof(struct rk_screen), GFP_KERNEL);
1722                 if (screen1) {
1723                         dev_err(dev_drv->dev, "malloc screen1 for lcdc%d fail!",
1724                                                 dev_drv->id);
1725                         return -ENOMEM;
1726                 }
1727                 screen1->screen_id = 1;
1728                 screen1->lcdc_id = 1;
1729                 dev_drv->screen1 = screen1;
1730         }
1731         sprintf(dev_drv->name, "lcdc%d", dev_drv->id);
1732         init_lcdc_win(dev_drv, def_win);
1733         init_completion(&dev_drv->frame_done);
1734         spin_lock_init(&dev_drv->cpl_lock);
1735         mutex_init(&dev_drv->fb_win_id_mutex);
1736         dev_drv->ops->fb_win_remap(dev_drv, FB_DEFAULT_ORDER);
1737         dev_drv->first_frame = 1;
1738         rk_disp_pwr_ctr_parse_dt(dev_drv);
1739         rk_disp_prase_timing_dt(dev_drv);
1740
1741         return 0;
1742 }
1743
1744 #ifdef CONFIG_LOGO_LINUX_BMP
1745 static struct linux_logo *bmp_logo;
1746 static int fb_prewine_bmp_logo(struct fb_info *info, int rotate)
1747 {
1748         bmp_logo = fb_find_logo(24);
1749         if (bmp_logo == NULL) {
1750                 printk(KERN_INFO "%s error\n", __func__);
1751                 return 0;
1752         }
1753         return 1;
1754 }
1755
1756 static void fb_show_bmp_logo(struct fb_info *info, int rotate)
1757 {
1758         unsigned char *src = bmp_logo->data;
1759         unsigned char *dst = info->screen_base;
1760         int i;
1761         unsigned int Needwidth = (*(src-24)<<8) | (*(src-23));
1762         unsigned int Needheight = (*(src-22)<<8) | (*(src-21));
1763
1764         for (i = 0; i < Needheight; i++)
1765                 memcpy(dst+info->var.xres*i*4,
1766                         src+bmp_logo->width*i*4, Needwidth*4);
1767
1768 }
1769 #endif
1770
1771 /********************************
1772 *check if the primary lcdc has registerd,
1773 the primary lcdc mas register first
1774 *********************************/
1775 bool is_prmry_rk_lcdc_registered(void)
1776 {
1777         struct rk_fb *rk_fb = platform_get_drvdata(fb_pdev);
1778         if (rk_fb->lcdc_dev_drv[0])
1779                 return  true;
1780         else
1781                 return false;
1782
1783
1784 }
1785 int rk_fb_register(struct rk_lcdc_driver *dev_drv,
1786                                 struct rk_lcdc_win *win, int id)
1787 {
1788         struct rk_fb *rk_fb = platform_get_drvdata(fb_pdev);
1789         struct fb_info *fbi;
1790         int i = 0, ret = 0, index = 0;
1791
1792         if (rk_fb->num_lcdc == RK30_MAX_LCDC_SUPPORT)
1793                 return -ENXIO;
1794
1795         for (i = 0; i < RK30_MAX_LCDC_SUPPORT; i++) {
1796                 if (!rk_fb->lcdc_dev_drv[i]) {
1797                         rk_fb->lcdc_dev_drv[i] = dev_drv;
1798                         rk_fb->lcdc_dev_drv[i]->id = id;
1799                         rk_fb->num_lcdc++;
1800                         break;
1801                 }
1802         }
1803
1804         index = i;
1805         init_lcdc_device_driver(rk_fb, win, index);
1806         dev_drv->fb_index_base = rk_fb->num_fb;
1807         for (i = 0; i < dev_drv->num_win; i++) {
1808                 fbi = framebuffer_alloc(0, &fb_pdev->dev);
1809                 if (!fbi) {
1810                         dev_err(&fb_pdev->dev, "fb framebuffer_alloc fail!");
1811                         ret = -ENOMEM;
1812                 }
1813                 fbi->par = dev_drv;
1814                 fbi->var = def_var;
1815                 fbi->fix = def_fix;
1816                 sprintf(fbi->fix.id, "fb%d", rk_fb->num_fb);
1817                 fb_videomode_to_var(&fbi->var, &dev_drv->cur_screen->mode);
1818                 fbi->var.grayscale |= (fbi->var.xres<<8) + (fbi->var.yres<<20);
1819 #if defined(CONFIG_LOGO_LINUX_BMP)
1820                 fbi->var.bits_per_pixel = 32;
1821 #else
1822                 fbi->var.bits_per_pixel = 16;
1823 #endif
1824                 fbi->fix.line_length  = (fbi->var.xres)*(fbi->var.bits_per_pixel>>3);
1825                 fbi->var.width = dev_drv->cur_screen->width;
1826                 fbi->var.height = dev_drv->cur_screen->height;
1827                 fbi->var.pixclock = dev_drv->pixclock;
1828                 fbi->fbops = &fb_ops;
1829                 fbi->flags = FBINFO_FLAG_DEFAULT;
1830                 fbi->pseudo_palette = dev_drv->win[i]->pseudo_pal;
1831                 if (i == 0) /* only alloc memory for main fb*/
1832                         rk_fb_alloc_buffer(fbi, rk_fb->num_fb);
1833                 ret = register_framebuffer(fbi);
1834                 if (ret < 0) {
1835                         dev_err(&fb_pdev->dev, "%s fb%d register_framebuffer fail!\n",
1836                                         __func__, rk_fb->num_fb);
1837                         return ret;
1838                 }
1839                 rkfb_create_sysfs(fbi);
1840                 rk_fb->fb[rk_fb->num_fb] = fbi;
1841                 dev_info(&fb_pdev->dev, "rockchip framebuffer registerd:%s\n",
1842                                         fbi->fix.id);
1843                 rk_fb->num_fb++;
1844
1845                 if (i == 0) {
1846                         init_waitqueue_head(&dev_drv->vsync_info.wait);
1847                         ret = device_create_file(fbi->dev, &dev_attr_vsync);
1848                         if (ret)
1849                                 dev_err(fbi->dev, "failed to create vsync file\n");
1850                         dev_drv->vsync_info.thread = kthread_run(rk_fb_wait_for_vsync_thread,
1851                                                                 dev_drv, "fb-vsync");
1852                         if (dev_drv->vsync_info.thread == ERR_PTR(-ENOMEM)) {
1853                                 dev_err(fbi->dev, "failed to run vsync thread\n");
1854                                 dev_drv->vsync_info.thread = NULL;
1855                         }
1856                         dev_drv->vsync_info.active = 1;
1857                 }
1858
1859         }
1860
1861  /*show logo for primary display device*/
1862 #if !defined(CONFIG_FRAMEBUFFER_CONSOLE) && defined(CONFIG_LOGO)
1863 if (dev_drv->prop == PRMRY) {
1864         struct fb_info *main_fbi = rk_fb->fb[0];
1865         main_fbi->fbops->fb_open(main_fbi, 1);
1866         main_fbi->fbops->fb_set_par(main_fbi);
1867 #if  defined(CONFIG_LOGO_LINUX_BMP)
1868         if (fb_prewine_bmp_logo(main_fbi, FB_ROTATE_UR)) {
1869                 fb_set_cmap(&main_fbi->cmap, main_fbi);
1870                 fb_show_bmp_logo(main_fbi, FB_ROTATE_UR);
1871                 main_fbi->fbops->fb_pan_display(&main_fbi->var, main_fbi);
1872         }
1873 #else
1874         if (fb_prepare_logo(main_fbi, FB_ROTATE_UR)) {
1875                 fb_set_cmap(&main_fbi->cmap, main_fbi);
1876                 fb_show_logo(main_fbi, FB_ROTATE_UR);
1877                 main_fbi->fbops->fb_pan_display(&main_fbi->var, main_fbi);
1878         }
1879 #endif
1880         main_fbi->fbops->fb_ioctl(main_fbi, RK_FBIOSET_CONFIG_DONE, 0);
1881 }
1882 #endif
1883         return 0;
1884
1885
1886 }
1887
1888 int rk_fb_unregister(struct rk_lcdc_driver *dev_drv)
1889 {
1890
1891         struct rk_fb *fb_inf = platform_get_drvdata(fb_pdev);
1892         struct fb_info *fbi;
1893         int fb_index_base = dev_drv->fb_index_base;
1894         int fb_num = dev_drv->num_win;
1895         int i = 0;
1896
1897         if (fb_inf->lcdc_dev_drv[i]->vsync_info.thread) {
1898                 fb_inf->lcdc_dev_drv[i]->vsync_info.irq_stop = 1;
1899                 kthread_stop(fb_inf->lcdc_dev_drv[i]->vsync_info.thread);
1900         }
1901
1902         for (i = 0; i < fb_num; i++)
1903                 kfree(dev_drv->win[i]);
1904
1905         for (i = fb_index_base; i < (fb_index_base+fb_num); i++) {
1906                 fbi = fb_inf->fb[i];
1907                 unregister_framebuffer(fbi);
1908                 /*rk_release_fb_buffer(fbi);*/
1909                 framebuffer_release(fbi);
1910         }
1911         fb_inf->lcdc_dev_drv[dev_drv->id] = NULL;
1912         fb_inf->num_lcdc--;
1913
1914         return 0;
1915 }
1916
1917
1918
1919 #if defined(CONFIG_HAS_EARLYSUSPEND)
1920 struct suspend_info {
1921         struct early_suspend early_suspend;
1922         struct rk_fb *inf;
1923 };
1924
1925 static void rkfb_early_suspend(struct early_suspend *h)
1926 {
1927         struct suspend_info *info = container_of(h, struct suspend_info,
1928                                                 early_suspend);
1929         struct rk_fb *inf = info->inf;
1930         int i;
1931         for (i = 0; i < inf->num_lcdc; i++) {
1932                 if (!inf->lcdc_dev_drv[i])
1933                         continue;
1934                 inf->lcdc_dev_drv[i]->suspend(inf->lcdc_dev_drv[i]);
1935         }
1936 }
1937 static void rkfb_early_resume(struct early_suspend *h)
1938 {
1939         struct suspend_info *info = container_of(h, struct suspend_info,
1940                                                 early_suspend);
1941         struct rk_fb *inf = info->inf;
1942         int i;
1943         for (i = 0; i < inf->num_lcdc; i++) {
1944                 if (!inf->lcdc_dev_drv[i])
1945                         continue;
1946                 inf->lcdc_dev_drv[i]->resume(inf->lcdc_dev_drv[i]);
1947         }
1948
1949 }
1950
1951
1952
1953 static struct suspend_info suspend_info = {
1954         .early_suspend.suspend = rkfb_early_suspend,
1955         .early_suspend.resume = rkfb_early_resume,
1956         .early_suspend.level = EARLY_SUSPEND_LEVEL_DISABLE_FB,
1957 };
1958 #endif
1959
1960 static int rk_fb_probe(struct platform_device *pdev)
1961 {
1962         struct rk_fb *rk_fb = NULL;
1963         struct device_node *np = pdev->dev.of_node;
1964         u32 mode;
1965
1966         if (!np) {
1967                 dev_err(&pdev->dev, "Missing device tree node.\n");
1968                 return -EINVAL;
1969         }
1970
1971         rk_fb = devm_kzalloc(&pdev->dev, sizeof(struct rk_fb), GFP_KERNEL);
1972         if (!rk_fb) {
1973                 dev_err(&pdev->dev, "kmalloc for rk fb fail!");
1974                 return  -ENOMEM;
1975         }
1976         platform_set_drvdata(pdev, rk_fb);
1977
1978         if (!of_property_read_u32(np, "rockchip,disp-mode", &mode)) {
1979                 rk_fb->disp_mode = mode;
1980
1981         } else {
1982                 dev_err(&pdev->dev, "no disp-mode node found!");
1983                 return -ENODEV;
1984         }
1985         dev_set_name(&pdev->dev, "rockchip-fb");
1986 #if defined(CONFIG_ION_ROCKCHIP)
1987         rk_fb->ion_client = rockchip_ion_client_create("rk_fb");
1988         if (IS_ERR(rk_fb->ion_client)) {
1989                 dev_err(&pdev->dev, "failed to create ion client for rk fb");
1990                 return PTR_ERR(rk_fb->ion_client);
1991         } else {
1992                 dev_info(&pdev->dev, "rk fb ion client create success!\n");
1993         }
1994 #endif
1995
1996 #if defined(CONFIG_HAS_EARLYSUSPEND)
1997         suspend_info.inf = rk_fb;
1998         register_early_suspend(&suspend_info.early_suspend);
1999 #endif
2000         fb_pdev = pdev;
2001         dev_info(&pdev->dev, "rockchip framebuffer driver probe\n");
2002         return 0;
2003 }
2004
2005 static int rk_fb_remove(struct platform_device *pdev)
2006 {
2007         struct rk_fb *rk_fb = platform_get_drvdata(pdev);
2008         kfree(rk_fb);
2009         platform_set_drvdata(pdev, NULL);
2010         return 0;
2011 }
2012
2013 static void rk_fb_shutdown(struct platform_device *pdev)
2014 {
2015         struct rk_fb *rk_fb = platform_get_drvdata(pdev);
2016         int i;
2017         for (i = 0; i < rk_fb->num_lcdc; i++) {
2018                 if (!rk_fb->lcdc_dev_drv[i])
2019                         continue;
2020
2021         }
2022
2023 #if     defined(CONFIG_HAS_EARLYSUSPEND)
2024         unregister_early_suspend(&suspend_info.early_suspend);
2025 #endif
2026 }
2027
2028
2029 static const struct of_device_id rkfb_dt_ids[] = {
2030         { .compatible = "rockchip,rk-fb", },
2031         {}
2032 };
2033
2034 static struct platform_driver rk_fb_driver = {
2035         .probe          = rk_fb_probe,
2036         .remove         = rk_fb_remove,
2037         .driver         = {
2038                 .name   = "rk-fb",
2039                 .owner  = THIS_MODULE,
2040                 .of_match_table = of_match_ptr(rkfb_dt_ids),
2041         },
2042         .shutdown   = rk_fb_shutdown,
2043 };
2044
2045 static int __init rk_fb_init(void)
2046 {
2047         return platform_driver_register(&rk_fb_driver);
2048 }
2049
2050 static void __exit rk_fb_exit(void)
2051 {
2052         platform_driver_unregister(&rk_fb_driver);
2053 }
2054
2055 subsys_initcall_sync(rk_fb_init);
2056 module_exit(rk_fb_exit);