2 * drivers/video/rockchip/lcdc/rk3188_lcdc.c
4 * Copyright (C) 2013 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.
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.
17 #include <linux/module.h>
18 #include <linux/kernel.h>
19 #include <linux/errno.h>
20 #include <linux/string.h>
22 #include <linux/slab.h>
23 #include <linux/device.h>
24 #include <linux/delay.h>
25 #include <linux/init.h>
26 #include <linux/interrupt.h>
27 #include <linux/platform_device.h>
28 #include <linux/clk.h>
29 #include <asm/div64.h>
30 #include <asm/uaccess.h>
31 #include "../../../arch/arm/mach-rockchip/cpu.h"
32 #include "../../../arch/arm/mach-rockchip/iomap.h"
33 #include "../../../arch/arm/mach-rockchip/grf.h"
35 #include "rk3188_lcdc.h"
37 #if defined(CONFIG_HAS_EARLYSUSPEND)
38 #include <linux/earlysuspend.h>
41 static int dbg_thresd;
42 module_param(dbg_thresd, int, S_IRUGO | S_IWUSR);
44 #define DBG(level, x...) do { \
45 if (unlikely(dbg_thresd >= level)) \
46 printk(KERN_INFO x); } while (0)
48 //#define WAIT_FOR_SYNC 1
50 static int rk3188_lcdc_get_id(u32 phy_base)
52 if (cpu_is_rk319x()) {
53 if (phy_base == 0xffc40000)
55 else if (phy_base == 0xffc50000)
59 } else if (cpu_is_rk3188()) {
60 if (phy_base == 0x1010c000)
62 else if (phy_base == 0x1010e000)
66 } else if (cpu_is_rk3026()) {
67 if (phy_base == 0x1010e000)
69 else if (phy_base == 0x01110000)
74 pr_err("un supported platform \n");
80 static int rk3188_lcdc_set_lut(struct rk_lcdc_driver *dev_drv)
85 struct lcdc_device *lcdc_dev = container_of(dev_drv,
89 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_DSP_LUT_EN, v_DSP_LUT_EN(0));
90 lcdc_cfg_done(lcdc_dev);
92 for (i = 0; i < 256; i++) {
93 v = dev_drv->cur_screen->dsp_lut[i];
94 c = lcdc_dev->dsp_lut_addr_base + i;
98 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_DSP_LUT_EN, v_DSP_LUT_EN(1));
104 static int rk3188_lcdc_clk_enable(struct lcdc_device *lcdc_dev)
107 if (!lcdc_dev->clk_on) {
108 clk_prepare_enable(lcdc_dev->hclk);
109 clk_prepare_enable(lcdc_dev->dclk);
110 clk_prepare_enable(lcdc_dev->aclk);
111 //clk_enable(lcdc_dev->pd);
112 spin_lock(&lcdc_dev->reg_lock);
113 lcdc_dev->clk_on = 1;
114 spin_unlock(&lcdc_dev->reg_lock);
120 static int rk3188_lcdc_clk_disable(struct lcdc_device *lcdc_dev)
122 if (lcdc_dev->clk_on) {
123 spin_lock(&lcdc_dev->reg_lock);
124 lcdc_dev->clk_on = 0;
125 spin_unlock(&lcdc_dev->reg_lock);
127 clk_disable_unprepare(lcdc_dev->dclk);
128 clk_disable_unprepare(lcdc_dev->hclk);
129 clk_disable_unprepare(lcdc_dev->aclk);
130 //clk_disable(lcdc_dev->pd);
136 static void rk3188_lcdc_reg_dump(struct lcdc_device *lcdc_dev)
138 int *cbase = (int *)lcdc_dev->regs;
139 int *regsbak = (int *)lcdc_dev->regsbak;
142 printk("back up reg:\n");
143 for (i = 0; i <= (0x90 >> 4); i++) {
144 for (j = 0; j < 4; j++)
145 printk("%08x ", *(regsbak + i * 4 + j));
149 printk("lcdc reg:\n");
150 for (i = 0; i <= (0x90 >> 4); i++) {
151 for (j = 0; j < 4; j++)
152 printk("%08x ", readl_relaxed(cbase + i * 4 + j));
158 static void rk3188_lcdc_read_reg_defalut_cfg(struct lcdc_device
163 struct rk_lcdc_win *win0 = lcdc_dev->driver.win[0];
164 struct rk_lcdc_win *win1 = lcdc_dev->driver.win[1];
166 spin_lock(&lcdc_dev->reg_lock);
167 for (reg = 0; reg < REG_CFG_DONE; reg += 4) {
168 value = lcdc_readl(lcdc_dev, reg);
171 lcdc_dev->standby = (value & m_LCDC_STANDBY) >> 17;
172 win0->state = (value & m_WIN0_EN) >> 0;
173 win1->state = (value & m_WIN1_EN) >> 1;
174 if (lcdc_dev->id == 0)
175 lcdc_dev->atv_layer_cnt = win0->state;
177 lcdc_dev->atv_layer_cnt = win1->state;
178 win0->swap_rb = (value & m_WIN0_RB_SWAP) >> 15;
179 win1->swap_rb = (value & m_WIN1_RB_SWAP) >> 19;
180 win0->fmt_cfg = (value & m_WIN0_FORMAT) >> 3;
181 win1->fmt_cfg = (value & m_WIN1_FORMAT) >> 6;
183 case WIN0_SCL_FACTOR_YRGB:
184 win0->scale_yrgb_x = (value >> 0) & 0xffff;
185 win0->scale_yrgb_y = (value >> 16) & 0xffff;
187 case WIN0_SCL_FACTOR_CBR:
188 win0->scale_cbcr_x = (value >> 0) & 0xffff;
189 win0->scale_cbcr_y = (value >> 16) & 0xffff;
192 win0->xact = (((value >> 0) & 0x1fff) + 1);
193 win0->yact = (((value >> 16) & 0x1fff) + 1);
196 win0->dsp_stx = (value >> 0) & 0xfff;
197 win0->dsp_sty = (value >> 16) & 0xfff;
200 win0->xsize = (((value >> 0) & 0x7ff) + 1);
201 win0->ysize = (((value >> 16) & 0x7ff) + 1);
204 win0->vir_stride = (value >> 0) & 0x1fff;
205 win1->vir_stride = (value) & 0x1fff0000;
208 win0->y_addr = value >> 0;
211 win0->uv_addr = value >> 0;
214 win1->xsize = (((value >> 0) & 0x7ff) + 1);
215 win1->ysize = (((value >> 16) & 0x7ff) + 1);
218 win1->dsp_stx = (value >> 0) & 0xfff;
219 win1->dsp_sty = (value >> 16) & 0xfff;
222 win1->y_addr = value >> 0;
225 DBG(2, "%s:uncare reg\n", __func__);
229 spin_unlock(&lcdc_dev->reg_lock);
232 /********do basic init*********/
233 static int rk3188_lcdc_pre_init(struct rk_lcdc_driver *dev_drv)
236 struct lcdc_device *lcdc_dev = container_of(dev_drv,
241 if (lcdc_dev->pre_init)
244 if (lcdc_dev->id == 0) {
245 //lcdc_dev->pd = clk_get(NULL,"pd_lcdc0");
246 lcdc_dev->hclk = clk_get(NULL, "g_h_lcdc0");
247 lcdc_dev->aclk = clk_get(NULL, "aclk_lcdc0");
248 lcdc_dev->dclk = clk_get(NULL, "dclk_lcdc0");
249 } else if (lcdc_dev->id == 1) {
250 //lcdc_dev->pd = clk_get(NULL,"pd_lcdc1");
251 lcdc_dev->hclk = clk_get(NULL, "g_h_lcdc1");
252 lcdc_dev->aclk = clk_get(NULL, "aclk_lcdc1");
253 lcdc_dev->dclk = clk_get(NULL, "dclk_lcdc1");
255 dev_err(lcdc_dev->dev, "invalid lcdc device!\n");
258 if (IS_ERR(lcdc_dev->pd) || (IS_ERR(lcdc_dev->aclk)) ||
259 (IS_ERR(lcdc_dev->dclk)) || (IS_ERR(lcdc_dev->hclk))) {
260 dev_err(lcdc_dev->dev, "failed to get lcdc%d clk source\n",
264 /*uboot display has enabled lcdc in boot */
265 if (!support_uboot_display()) {
266 rk_disp_pwr_enable(dev_drv);
267 rk3188_lcdc_clk_enable(lcdc_dev);
269 lcdc_dev->clk_on = 1;
272 rk3188_lcdc_read_reg_defalut_cfg(lcdc_dev);
274 if (lcdc_dev->id == 0) {
275 if (lcdc_dev->pwr18 == true) {
276 v = 0x40004000; /*bit14: 1,1.8v;0,3.3v*/
277 writel_relaxed(v, RK_GRF_VIRT + RK3188_GRF_IO_CON4);
280 writel_relaxed(v, RK_GRF_VIRT + RK3188_GRF_IO_CON4);
284 if (lcdc_dev->id == 1) {
285 if (lcdc_dev->pwr18 == true) {
286 v = 0x80008000; /*bit14: 1,1.8v;0,3.3v*/
287 writel_relaxed(v, RK_GRF_VIRT + RK3188_GRF_IO_CON4);
290 writel_relaxed(v, RK_GRF_VIRT + RK3188_GRF_IO_CON4);
292 pinctrl_select_state(lcdc_dev->dev->pins->p,
293 lcdc_dev->dev->pins->default_state);
296 lcdc_set_bit(lcdc_dev, SYS_CTRL, m_AUTO_GATING_EN);
297 lcdc_cfg_done(lcdc_dev);
298 lcdc_dev->pre_init = true;
303 static void rk3188_lcdc_deint(struct lcdc_device *lcdc_dev)
306 spin_lock(&lcdc_dev->reg_lock);
307 if (likely(lcdc_dev->clk_on)) {
308 lcdc_dev->clk_on = 0;
309 lcdc_msk_reg(lcdc_dev, INT_STATUS, m_FS_INT_CLEAR,
311 mask = m_HS_INT_EN | m_FS_INT_EN | m_LF_INT_EN |
313 val = v_HS_INT_EN(0) | v_FS_INT_EN(0) |
314 v_LF_INT_EN(0) | v_BUS_ERR_INT_EN(0);
315 lcdc_msk_reg(lcdc_dev, INT_STATUS, mask, val);
316 lcdc_set_bit(lcdc_dev, SYS_CTRL, m_LCDC_STANDBY);
317 lcdc_cfg_done(lcdc_dev);
318 spin_unlock(&lcdc_dev->reg_lock);
320 spin_unlock(&lcdc_dev->reg_lock);
326 static int rk3188_lcdc_alpha_cfg(struct lcdc_device *lcdc_dev)
330 enum data_format win0_format = lcdc_dev->driver.win[0]->format;
331 enum data_format win1_format = lcdc_dev->driver.win[1]->format;
333 int win0_alpha_en = ((win0_format == ARGB888)
334 || (win0_format == ABGR888)) ? 1 : 0;
335 int win1_alpha_en = ((win1_format == ARGB888)
336 || (win1_format == ABGR888)) ? 1 : 0;
337 u32 *_pv = (u32 *) lcdc_dev->regsbak;
338 _pv += (DSP_CTRL0 >> 2);
339 win0_top = ((*_pv) & (m_WIN0_TOP)) >> 8;
341 if (win0_top && (lcdc_dev->atv_layer_cnt >= 2) && (win0_alpha_en)) {
342 lcdc_msk_reg(lcdc_dev, ALPHA_CTRL, m_WIN0_ALPHA_EN |
343 m_WIN1_ALPHA_EN, v_WIN0_ALPHA_EN(1) |
345 mask = m_WIN0_ALPHA_MODE | m_ALPHA_MODE_SEL0 | m_ALPHA_MODE_SEL1;
346 val = v_WIN0_ALPHA_MODE(1) | v_ALPHA_MODE_SEL0(1) | v_ALPHA_MODE_SEL1(0);
347 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, mask, val);
348 } else if ((!win0_top) && (lcdc_dev->atv_layer_cnt >= 2)
349 && (win1_alpha_en)) {
350 mask = m_WIN0_ALPHA_EN | m_WIN1_ALPHA_EN;
351 val = v_WIN0_ALPHA_EN(0) | v_WIN1_ALPHA_EN(1);
352 lcdc_msk_reg(lcdc_dev, ALPHA_CTRL, mask, val);
354 mask = m_WIN1_ALPHA_MODE | m_ALPHA_MODE_SEL0 | m_ALPHA_MODE_SEL1;
355 val = v_WIN1_ALPHA_MODE(1) | v_ALPHA_MODE_SEL0(1) | v_ALPHA_MODE_SEL1(0);
356 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, mask, val);
358 mask = m_WIN0_ALPHA_EN | m_WIN1_ALPHA_EN;
359 val = v_WIN0_ALPHA_EN(0) | v_WIN1_ALPHA_EN(0);
360 lcdc_msk_reg(lcdc_dev, ALPHA_CTRL, mask, val);
366 static int rk3188_lcdc_reg_update(struct rk_lcdc_driver *dev_drv)
368 struct lcdc_device *lcdc_dev =
369 container_of(dev_drv, struct lcdc_device, driver);
370 struct rk_lcdc_win *win0 = lcdc_dev->driver.win[0];
371 struct rk_lcdc_win *win1 = lcdc_dev->driver.win[1];
375 spin_lock(&lcdc_dev->reg_lock);
376 if (likely(lcdc_dev->clk_on)) {
377 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_LCDC_STANDBY,
378 v_LCDC_STANDBY(lcdc_dev->standby));
379 lcdc_msk_reg(lcdc_dev, SYS_CTRL,
380 m_WIN0_EN | m_WIN1_EN | m_WIN0_RB_SWAP |
382 v_WIN0_EN(win0->state) | v_WIN1_EN(win1->state) |
383 v_WIN0_RB_SWAP(win0->swap_rb) |
384 v_WIN1_RB_SWAP(win1->swap_rb));
385 lcdc_writel(lcdc_dev, WIN0_SCL_FACTOR_YRGB,
386 v_X_SCL_FACTOR(win0->scale_yrgb_x) |
387 v_Y_SCL_FACTOR(win0->scale_yrgb_y));
388 lcdc_writel(lcdc_dev, WIN0_SCL_FACTOR_CBR,
389 v_X_SCL_FACTOR(win0->scale_cbcr_x) |
390 v_Y_SCL_FACTOR(win0->scale_cbcr_y));
391 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_WIN0_FORMAT, v_WIN0_FORMAT(win0->fmt_cfg));
392 lcdc_writel(lcdc_dev, WIN0_ACT_INFO, v_ACT_WIDTH(win0->xact) |
393 v_ACT_HEIGHT(win0->yact));
394 lcdc_writel(lcdc_dev, WIN0_DSP_ST, v_DSP_STX(win0->dsp_stx) |
395 v_DSP_STY(win0->dsp_sty));
396 lcdc_writel(lcdc_dev, WIN0_DSP_INFO, v_DSP_WIDTH(win0->xsize) |
397 v_DSP_HEIGHT(win0->ysize));
398 lcdc_msk_reg(lcdc_dev, WIN_VIR, m_WIN0_VIR,
399 v_WIN0_VIR_VAL(win0->vir_stride));
400 lcdc_writel(lcdc_dev, WIN0_YRGB_MST0, win0->y_addr);
401 lcdc_writel(lcdc_dev, WIN0_CBR_MST0, win0->uv_addr);
402 lcdc_writel(lcdc_dev, WIN1_DSP_INFO, v_DSP_WIDTH(win1->xsize) |
403 v_DSP_HEIGHT(win1->ysize));
404 lcdc_writel(lcdc_dev, WIN1_DSP_ST, v_DSP_STX(win1->dsp_stx) |
405 v_DSP_STY(win1->dsp_sty));
406 lcdc_msk_reg(lcdc_dev, WIN_VIR, m_WIN1_VIR, win1->vir_stride);
407 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_WIN1_FORMAT,
408 v_WIN1_FORMAT(win1->fmt_cfg));
409 lcdc_writel(lcdc_dev, WIN1_MST, win1->y_addr);
410 rk3188_lcdc_alpha_cfg(lcdc_dev);
411 lcdc_cfg_done(lcdc_dev);
414 spin_unlock(&lcdc_dev->reg_lock);
415 if (dev_drv->wait_fs) {
416 spin_lock_irqsave(&dev_drv->cpl_lock, flags);
417 init_completion(&dev_drv->frame_done);
418 spin_unlock_irqrestore(&dev_drv->cpl_lock, flags);
419 timeout = wait_for_completion_timeout(&dev_drv->frame_done,
421 (dev_drv->cur_screen->ft +
423 if (!timeout && (!dev_drv->frame_done.done)) {
424 dev_warn(lcdc_dev->dev, "wait for new frame start time out!\n");
428 DBG(2, "%s for lcdc%d\n", __func__, lcdc_dev->id);
433 static int rk3188_lcdc_reg_restore(struct lcdc_device *lcdc_dev)
435 memcpy((u8 *) lcdc_dev->regs, (u8 *) lcdc_dev->regsbak, 0x84);
440 static int rk3188_load_screen(struct rk_lcdc_driver *dev_drv, bool initscreen)
445 struct lcdc_device *lcdc_dev =
446 container_of(dev_drv, struct lcdc_device, driver);
447 struct rk_screen *screen = dev_drv->cur_screen;
448 u16 right_margin = screen->mode.right_margin;
449 u16 left_margin = screen->mode.left_margin;
450 u16 lower_margin = screen->mode.lower_margin;
451 u16 upper_margin = screen->mode.upper_margin;
452 u16 x_res = screen->mode.xres;
453 u16 y_res = screen->mode.yres;
456 spin_lock(&lcdc_dev->reg_lock);
457 if (likely(lcdc_dev->clk_on)) {
458 switch (screen->face) {
461 mask = m_DITHER_DOWN_EN | m_DITHER_DOWN_MODE |
463 val = v_DITHER_DOWN_EN(1) | v_DITHER_DOWN_MODE(0) |
464 v_DITHER_DOWN_SEL(1);
465 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, mask, val);
469 mask = m_DITHER_DOWN_EN | m_DITHER_DOWN_MODE |
471 val = v_DITHER_DOWN_EN(1) | v_DITHER_DOWN_MODE(1) |
472 v_DITHER_DOWN_SEL(1);
473 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, mask, val);
477 mask = m_DITHER_DOWN_EN | m_DITHER_DOWN_MODE |
479 val = v_DITHER_DOWN_EN(1) | v_DITHER_DOWN_MODE(0) |
480 v_DITHER_DOWN_SEL(1);
481 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, mask, val);
485 mask = m_DITHER_DOWN_EN | m_DITHER_DOWN_MODE |
487 val = v_DITHER_DOWN_EN(1) | v_DITHER_DOWN_MODE(1) |
488 v_DITHER_DOWN_SEL(1);
489 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, mask, val);
493 mask = m_DITHER_DOWN_EN | m_DITHER_UP_EN;
494 val = v_DITHER_DOWN_EN(0) | v_DITHER_UP_EN(0);
495 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, mask, val);
498 dev_err(lcdc_dev->dev, "un supported interface!\n");
502 mask = m_DSP_OUT_FORMAT | m_HSYNC_POL | m_VSYNC_POL |
503 m_DEN_POL | m_DCLK_POL;
504 val = v_DSP_OUT_FORMAT(face) | v_HSYNC_POL(screen->pin_hsync) |
505 v_VSYNC_POL(screen->pin_vsync) | v_DEN_POL(screen->pin_den) |
506 v_DCLK_POL(screen->pin_dclk);
507 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, mask, val);
509 mask = m_BG_COLOR | m_DSP_BG_SWAP | m_DSP_RB_SWAP |
510 m_DSP_RG_SWAP | m_DSP_DELTA_SWAP |
511 m_DSP_DUMMY_SWAP | m_BLANK_EN;
512 val = v_BG_COLOR(0x000000) | v_DSP_BG_SWAP(screen->swap_gb) |
513 v_DSP_RB_SWAP(screen->swap_rb) | v_DSP_RG_SWAP(screen->
515 v_DSP_DELTA_SWAP(screen->
516 swap_delta) | v_DSP_DUMMY_SWAP(screen->
518 v_BLANK_EN(0) | v_BLACK_EN(0);
519 lcdc_msk_reg(lcdc_dev, DSP_CTRL1, mask, val);
521 v_HSYNC(screen->mode.hsync_len) | v_HORPRD(screen->mode.
526 lcdc_writel(lcdc_dev, DSP_HTOTAL_HS_END, val);
527 val = v_HAEP(screen->mode.hsync_len + left_margin + x_res) |
528 v_HASP(screen->mode.hsync_len + left_margin);
529 lcdc_writel(lcdc_dev, DSP_HACT_ST_END, val);
532 v_VSYNC(screen->mode.vsync_len) | v_VERPRD(screen->mode.
537 lcdc_writel(lcdc_dev, DSP_VTOTAL_VS_END, val);
539 val = v_VAEP(screen->mode.vsync_len + upper_margin + y_res) |
540 v_VASP(screen->mode.vsync_len + screen->mode.upper_margin);
541 lcdc_writel(lcdc_dev, DSP_VACT_ST_END, val);
543 spin_unlock(&lcdc_dev->reg_lock);
545 ret = clk_set_rate(lcdc_dev->dclk, screen->mode.pixclock);
547 dev_err(dev_drv->dev, "set lcdc%d dclk failed\n", lcdc_dev->id);
549 div_u64(1000000000000llu, clk_get_rate(lcdc_dev->dclk));
550 lcdc_dev->driver.pixclock = lcdc_dev->pixclock;
552 fps = rk_fb_calc_fps(screen, lcdc_dev->pixclock);
553 screen->ft = 1000 / fps;
554 dev_info(lcdc_dev->dev, "%s: dclk:%lu>>fps:%d ",
555 lcdc_dev->driver.name, clk_get_rate(lcdc_dev->dclk), fps);
563 /*enable layer,open:1,enable;0 disable*/
564 static int win0_open(struct lcdc_device *lcdc_dev, bool open)
566 spin_lock(&lcdc_dev->reg_lock);
567 if (likely(lcdc_dev->clk_on)) {
569 if (!lcdc_dev->atv_layer_cnt) {
570 dev_info(lcdc_dev->dev, "wakeup from standby!\n");
571 lcdc_dev->standby = 0;
573 lcdc_dev->atv_layer_cnt++;
574 } else if ((lcdc_dev->atv_layer_cnt > 0) && (!open)) {
575 lcdc_dev->atv_layer_cnt--;
577 lcdc_dev->driver.win[0]->state = open;
578 if (!lcdc_dev->atv_layer_cnt) {
579 dev_info(lcdc_dev->dev, "no layer is used,go to standby!\n");
580 lcdc_dev->standby = 1;
583 spin_unlock(&lcdc_dev->reg_lock);
588 static int win1_open(struct lcdc_device *lcdc_dev, bool open)
590 spin_lock(&lcdc_dev->reg_lock);
591 if (likely(lcdc_dev->clk_on)) {
593 if (!lcdc_dev->atv_layer_cnt) {
594 dev_info(lcdc_dev->dev, "wakeup from standby!\n");
595 lcdc_dev->standby = 0;
597 lcdc_dev->atv_layer_cnt++;
598 } else if ((lcdc_dev->atv_layer_cnt > 0) && (!open)) {
599 lcdc_dev->atv_layer_cnt--;
601 lcdc_dev->driver.win[1]->state = open;
603 /*if no layer used,disable lcdc*/
604 if (!lcdc_dev->atv_layer_cnt) {
605 dev_info(lcdc_dev->dev, "no layer is used,go to standby!\n");
606 lcdc_dev->standby = 1;
609 spin_unlock(&lcdc_dev->reg_lock);
614 static int rk3188_lcdc_open(struct rk_lcdc_driver *dev_drv, int win_id,
617 struct lcdc_device *lcdc_dev = container_of(dev_drv,
618 struct lcdc_device, driver);
620 /*enable clk,when first layer open */
621 if ((open) && (!lcdc_dev->atv_layer_cnt)) {
622 rk3188_lcdc_pre_init(dev_drv);
623 rk3188_lcdc_clk_enable(lcdc_dev);
624 rk3188_lcdc_reg_restore(lcdc_dev);
625 rk3188_load_screen(dev_drv, 1);
626 spin_lock(&lcdc_dev->reg_lock);
627 if (dev_drv->cur_screen->dsp_lut)
628 rk3188_lcdc_set_lut(dev_drv);
629 spin_unlock(&lcdc_dev->reg_lock);
633 win0_open(lcdc_dev, open);
634 else if (win_id == 1)
635 win1_open(lcdc_dev, open);
637 dev_err(lcdc_dev->dev, "invalid win id:%d\n", win_id);
639 /*when all layer closed,disable clk */
640 if ((!open) && (!lcdc_dev->atv_layer_cnt)) {
641 lcdc_msk_reg(lcdc_dev, INT_STATUS,
642 m_FS_INT_CLEAR, v_FS_INT_CLEAR(1));
643 rk3188_lcdc_reg_update(dev_drv);
644 rk3188_lcdc_clk_disable(lcdc_dev);
650 static int win0_set_par(struct lcdc_device *lcdc_dev,
651 struct rk_screen *screen, struct rk_lcdc_win *win)
653 u32 xact, yact, xvir, yvir, xpos, ypos;
654 u32 ScaleYrgbX = 0x1000;
655 u32 ScaleYrgbY = 0x1000;
656 u32 ScaleCbrX = 0x1000;
657 u32 ScaleCbrY = 0x1000;
659 char fmt[9] = "NULL";
664 xpos = win->xpos + screen->mode.left_margin + screen->mode.hsync_len;
665 ypos = win->ypos + screen->mode.upper_margin + screen->mode.vsync_len;
667 ScaleYrgbX = CalScale(xact, win->xsize);
668 ScaleYrgbY = CalScale(yact, win->ysize);
669 switch (win->format) {
683 ScaleCbrX = CalScale((xact / 2), win->xsize);
684 ScaleCbrY = CalScale(yact, win->ysize);
688 ScaleCbrX = CalScale(xact / 2, win->xsize);
689 ScaleCbrY = CalScale(yact / 2, win->ysize);
693 ScaleCbrX = CalScale(xact, win->xsize);
694 ScaleCbrY = CalScale(yact, win->ysize);
697 dev_err(lcdc_dev->driver.dev, "%s:un supported format!\n",
702 DBG(1, "lcdc%d>>%s\n>>format:%s>>>xact:%d>>yact:%d>>xsize:%d>>ysize:%d\n"
703 ">>xvir:%d>>yvir:%d>>xpos:%d>>ypos:%d>>\n", lcdc_dev->id,
704 __func__, get_format_string(win->format, fmt), xact,
705 yact, win->xsize, win->ysize, xvir, yvir, xpos, ypos);
707 spin_lock(&lcdc_dev->reg_lock);
708 if (likely(lcdc_dev->clk_on)) {
709 win->scale_yrgb_x = ScaleYrgbX;
710 win->scale_yrgb_y = ScaleYrgbY;
711 win->scale_cbcr_x = ScaleCbrX;
712 win->scale_cbcr_y = ScaleCbrY;
713 win->fmt_cfg = fmt_cfg;
716 switch (win->format) {
719 win->vir_stride = v_ARGB888_VIRWIDTH(xvir);
723 win->vir_stride = v_ARGB888_VIRWIDTH(xvir);
727 win->vir_stride = v_RGB888_VIRWIDTH(xvir);
731 win->vir_stride = v_RGB565_VIRWIDTH(xvir);
737 win->vir_stride = v_YUV_VIRWIDTH(xvir);
741 dev_err(lcdc_dev->driver.dev,
742 "%s:un supported format!\n", __func__);
747 spin_unlock(&lcdc_dev->reg_lock);
753 static int win1_set_par(struct lcdc_device *lcdc_dev,
754 struct rk_screen *screen, struct rk_lcdc_win *win)
756 u32 xact, yact, xvir, yvir, xpos, ypos;
758 char fmt[9] = "NULL";
763 xpos = win->xpos + screen->mode.left_margin + screen->mode.hsync_len;
764 ypos = win->ypos + screen->mode.upper_margin + screen->mode.vsync_len;
766 DBG(1, "lcdc%d>>%s>>format:%s>>>xact:%d>>yact:%d>>xsize:%d>>ysize:%d\n"
767 ">>xvir:%d>>yvir:%d>>xpos:%d>>ypos:%d>>\n", lcdc_dev->id,
768 __func__, get_format_string(win->format, fmt), xact, yact,
769 win->xsize, win->ysize, xvir, yvir, xpos, ypos);
771 spin_lock(&lcdc_dev->reg_lock);
772 if (likely(lcdc_dev->clk_on)) {
775 switch (win->format) {
779 win->vir_stride = v_WIN1_ARGB888_VIRWIDTH(xvir);
784 win->vir_stride = v_WIN1_ARGB888_VIRWIDTH(xvir);
790 win->vir_stride = v_WIN1_RGB888_VIRWIDTH(xvir);
795 win->vir_stride = v_WIN1_RGB565_VIRWIDTH(xvir);
799 dev_err(lcdc_dev->driver.dev,
800 "%s:un supported format!\n", __func__);
803 win->fmt_cfg = fmt_cfg;
806 spin_unlock(&lcdc_dev->reg_lock);
811 static int rk3188_lcdc_set_par(struct rk_lcdc_driver *dev_drv, int win_id)
813 struct lcdc_device *lcdc_dev =
814 container_of(dev_drv, struct lcdc_device, driver);
815 struct rk_lcdc_win *win = NULL;
816 struct rk_screen *screen = dev_drv->cur_screen;
819 dev_err(dev_drv->dev, "screen is null!\n");
823 win = dev_drv->win[0];
824 win0_set_par(lcdc_dev, screen, win);
825 } else if (win_id == 1) {
826 win = dev_drv->win[1];
827 win1_set_par(lcdc_dev, screen, win);
829 dev_err(dev_drv->dev, "unsupported win number:%d\n", win_id);
836 static int win0_display(struct lcdc_device *lcdc_dev,
837 struct rk_lcdc_win *win)
841 y_addr = win->smem_start + win->y_offset;
842 uv_addr = win->cbr_start + win->c_offset;
843 DBG(2, "lcdc%d>>%s:y_addr:0x%x>>uv_addr:0x%x\n",
844 lcdc_dev->id, __func__, y_addr, uv_addr);
846 spin_lock(&lcdc_dev->reg_lock);
847 if (likely(lcdc_dev->clk_on)) {
848 win->y_addr = y_addr;
849 win->uv_addr = uv_addr;
851 spin_unlock(&lcdc_dev->reg_lock);
857 static int win1_display(struct lcdc_device *lcdc_dev,
858 struct rk_lcdc_win *win)
862 y_addr = win->smem_start + win->y_offset;
863 uv_addr = win->cbr_start + win->c_offset;
864 DBG(2, "lcdc%d>>%s>>y_addr:0x%x>>uv_addr:0x%x\n",
865 lcdc_dev->id, __func__, y_addr, uv_addr);
867 spin_lock(&lcdc_dev->reg_lock);
868 if (likely(lcdc_dev->clk_on))
869 win->y_addr = y_addr;
870 spin_unlock(&lcdc_dev->reg_lock);
875 static int rk3188_lcdc_pan_display(struct rk_lcdc_driver *dev_drv, int win_id)
877 struct lcdc_device *lcdc_dev = container_of(dev_drv,
878 struct lcdc_device, driver);
879 struct rk_lcdc_win *win = NULL;
880 struct rk_screen *screen = dev_drv->cur_screen;
882 #if defined(WAIT_FOR_SYNC)
887 dev_err(dev_drv->dev, "screen is null!\n");
891 win = dev_drv->win[0];
892 win0_display(lcdc_dev, win);
893 } else if (win_id == 1) {
894 win = dev_drv->win[1];
895 win1_display(lcdc_dev, win);
897 dev_err(dev_drv->dev, "invalid win number:%d!\n", win_id);
901 /*this is the first frame of the system ,enable frame start interrupt */
902 if ((dev_drv->first_frame)) {
903 dev_drv->first_frame = 0;
904 mask = m_HS_INT_CLEAR | m_HS_INT_EN | m_FS_INT_CLEAR |
905 m_FS_INT_EN | m_LF_INT_EN | m_LF_INT_CLEAR |
906 m_LF_INT_NUM | m_BUS_ERR_INT_CLEAR | m_BUS_ERR_INT_EN;
907 val = v_FS_INT_CLEAR(1) | v_FS_INT_EN(1) | v_HS_INT_CLEAR(1) |
908 v_HS_INT_EN(0) | v_LF_INT_CLEAR(1) | v_LF_INT_EN(1) |
909 v_LF_INT_NUM(screen->mode.vsync_len + screen->mode.upper_margin +
910 screen->mode.yres -1);
911 lcdc_msk_reg(lcdc_dev, INT_STATUS, mask, val);
912 lcdc_cfg_done(lcdc_dev);
914 #if defined(WAIT_FOR_SYNC)
915 spin_lock_irqsave(&dev_drv->cpl_lock, flags);
916 init_completion(&dev_drv->frame_done);
917 spin_unlock_irqrestore(&dev_drv->cpl_lock, flags);
918 timeout = wait_for_completion_timeout(&dev_drv->frame_done,
919 msecs_to_jiffies(dev_drv->
922 if (!timeout && (!dev_drv->frame_done.done)) {
923 dev_info(dev_drv->dev, "wait for new frame start time out!\n");
930 static int rk3188_lcdc_blank(struct rk_lcdc_driver *dev_drv,
931 int win_id, int blank_mode)
933 struct lcdc_device *lcdc_dev =
934 container_of(dev_drv, struct lcdc_device, driver);
936 spin_lock(&lcdc_dev->reg_lock);
937 if (likely(lcdc_dev->clk_on)) {
938 switch (blank_mode) {
939 case FB_BLANK_UNBLANK:
940 lcdc_msk_reg(lcdc_dev, DSP_CTRL1, m_BLANK_EN,
943 case FB_BLANK_NORMAL:
944 lcdc_msk_reg(lcdc_dev, DSP_CTRL1, m_BLANK_EN,
948 lcdc_msk_reg(lcdc_dev, DSP_CTRL1, m_BLANK_EN,
952 lcdc_cfg_done(lcdc_dev);
955 spin_unlock(&lcdc_dev->reg_lock);
957 dev_info(dev_drv->dev, "blank mode:%d\n", blank_mode);
962 static int rk3188_lcdc_ioctl(struct rk_lcdc_driver *dev_drv, unsigned int cmd,
963 unsigned long arg, int win_id)
965 struct lcdc_device *lcdc_dev = container_of(dev_drv,
970 void __user *argp = (void __user *)arg;
971 struct color_key_cfg clr_key_cfg;
974 case RK_FBIOGET_PANEL_SIZE:
975 panel_size[0] = lcdc_dev->screen->mode.xres;
976 panel_size[1] = lcdc_dev->screen->mode.yres;
977 if (copy_to_user(argp, panel_size, 8))
980 case RK_FBIOPUT_COLOR_KEY_CFG:
981 if (copy_from_user(&clr_key_cfg, argp,
982 sizeof(struct color_key_cfg)))
984 lcdc_writel(lcdc_dev, WIN0_COLOR_KEY,
985 clr_key_cfg.win0_color_key_cfg);
986 lcdc_writel(lcdc_dev, WIN1_COLOR_KEY,
987 clr_key_cfg.win1_color_key_cfg);
996 static int rk3188_lcdc_early_suspend(struct rk_lcdc_driver *dev_drv)
999 struct lcdc_device *lcdc_dev =
1000 container_of(dev_drv, struct lcdc_device, driver);
1002 if (dev_drv->screen0->standby)
1003 dev_drv->screen0->standby(1);
1004 if (dev_drv->screen_ctr_info->io_disable)
1005 dev_drv->screen_ctr_info->io_disable();
1007 spin_lock(&lcdc_dev->reg_lock);
1008 if (likely(lcdc_dev->clk_on)) {
1009 lcdc_msk_reg(lcdc_dev, INT_STATUS, m_FS_INT_CLEAR,
1011 lcdc_msk_reg(lcdc_dev, DSP_CTRL1, m_DSP_OUT_ZERO,
1013 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_LCDC_STANDBY,
1015 lcdc_cfg_done(lcdc_dev);
1016 spin_unlock(&lcdc_dev->reg_lock);
1018 spin_unlock(&lcdc_dev->reg_lock);
1021 rk3188_lcdc_clk_disable(lcdc_dev);
1022 #if defined(CONFIG_ARCH_RK3026)
1023 int gpio_dclk = iomux_mode_to_gpio(LCDC0_DCLK);
1024 int ret = gpio_request(gpio_dclk, NULL);
1025 if (unlikely(ret < 0)) {
1026 dev_info(dev_drv->dev, "Failed to request gpio:lcdc dclk\n");
1029 gpio_direction_output(gpio_dclk, GPIO_LOW);
1034 static int rk3188_lcdc_early_resume(struct rk_lcdc_driver *dev_drv)
1036 struct lcdc_device *lcdc_dev =
1037 container_of(dev_drv, struct lcdc_device, driver);
1041 #if defined(CONFIG_ARCH_RK3026)
1042 int gpio_dclk = iomux_mode_to_gpio(LCDC0_DCLK);
1043 gpio_free(gpio_dclk);
1044 iomux_set(LCDC0_DCLK);
1046 if (dev_drv->screen_ctr_info->io_enable)
1047 dev_drv->screen_ctr_info->io_enable();
1049 if (lcdc_dev->atv_layer_cnt) {
1050 rk3188_lcdc_clk_enable(lcdc_dev);
1051 rk3188_lcdc_reg_restore(lcdc_dev);
1053 spin_lock(&lcdc_dev->reg_lock);
1054 if (dev_drv->cur_screen->dsp_lut) {
1055 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_DSP_LUT_EN,
1057 lcdc_cfg_done(lcdc_dev);
1059 for (i = 0; i < 256; i++) {
1060 v = dev_drv->cur_screen->dsp_lut[i];
1061 c = lcdc_dev->dsp_lut_addr_base + i;
1062 writel_relaxed(v, c);
1064 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_DSP_LUT_EN,
1068 lcdc_msk_reg(lcdc_dev, DSP_CTRL1, m_DSP_OUT_ZERO,
1070 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_LCDC_STANDBY,
1072 lcdc_cfg_done(lcdc_dev);
1074 spin_unlock(&lcdc_dev->reg_lock);
1077 if (dev_drv->screen0->standby)
1078 dev_drv->screen0->standby(0);
1083 static int rk3188_lcdc_get_win_state(struct rk_lcdc_driver *dev_drv, int win_id)
1088 static int rk3188_lcdc_ovl_mgr(struct rk_lcdc_driver *dev_drv, int swap,
1091 struct lcdc_device *lcdc_dev =
1092 container_of(dev_drv, struct lcdc_device, driver);
1094 spin_lock(&lcdc_dev->reg_lock);
1095 if (lcdc_dev->clk_on) {
1097 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_WIN0_TOP,
1101 ovl = lcdc_read_bit(lcdc_dev, DSP_CTRL0, m_WIN0_TOP);
1106 spin_unlock(&lcdc_dev->reg_lock);
1111 static ssize_t rk3188_lcdc_get_disp_info(struct rk_lcdc_driver *dev_drv,
1112 char *buf, int win_id)
1114 struct lcdc_device *lcdc_dev = container_of(dev_drv,
1119 char format_w0[9] = "NULL";
1120 char format_w1[9] = "NULL";
1121 char status_w0[9] = "NULL";
1122 char status_w1[9] = "NULL";
1123 u32 fmt_id, act_info, dsp_info, dsp_st, factor;
1124 u16 xvir_w0, x_act_w0, y_act_w0, x_dsp_w0, y_dsp_w0;
1125 u16 x_st_w0, y_st_w0, x_factor, y_factor;
1126 u16 xvir_w1, x_dsp_w1, y_dsp_w1, x_st_w1, y_st_w1;
1127 u16 x_scale, y_scale, ovl;
1128 spin_lock(&lcdc_dev->reg_lock);
1129 if (lcdc_dev->clk_on) {
1130 fmt_id = lcdc_readl(lcdc_dev, SYS_CTRL);
1131 ovl = lcdc_read_bit(lcdc_dev, DSP_CTRL0, m_WIN0_TOP);
1132 switch ((fmt_id & m_WIN0_FORMAT) >> 3) {
1134 strcpy(format_w0, "ARGB888");
1137 strcpy(format_w0, "RGB888");
1140 strcpy(format_w0, "RGB565");
1143 strcpy(format_w0, "YCbCr420");
1146 strcpy(format_w0, "YCbCr422");
1149 strcpy(format_w0, "YCbCr444");
1152 strcpy(format_w0, "invalid\n");
1156 switch ((fmt_id & m_WIN1_FORMAT) >> 6) {
1158 strcpy(format_w1, "ARGB888");
1161 strcpy(format_w1, "RGB888");
1164 strcpy(format_w1, "RGB565");
1167 strcpy(format_w1, "8bpp");
1170 strcpy(format_w1, "4bpp");
1173 strcpy(format_w1, "2bpp");
1176 strcpy(format_w1, "1bpp");
1179 strcpy(format_w1, "invalid\n");
1183 if (fmt_id & m_WIN0_EN)
1184 strcpy(status_w0, "enabled");
1186 strcpy(status_w0, "disabled");
1188 if ((fmt_id & m_WIN1_EN) >> 1)
1189 strcpy(status_w1, "enabled");
1191 strcpy(status_w1, "disabled");
1193 xvir_w0 = lcdc_readl(lcdc_dev, WIN_VIR) & 0x1fff;
1194 act_info = lcdc_readl(lcdc_dev, WIN0_ACT_INFO);
1195 dsp_info = lcdc_readl(lcdc_dev, WIN0_DSP_INFO);
1196 dsp_st = lcdc_readl(lcdc_dev, WIN0_DSP_ST);
1197 factor = lcdc_readl(lcdc_dev, WIN0_SCL_FACTOR_YRGB);
1198 x_act_w0 = (act_info & 0x1fff) + 1;
1199 y_act_w0 = ((act_info >> 16) & 0x1fff) + 1;
1200 x_dsp_w0 = (dsp_info & 0x7ff) + 1;
1201 y_dsp_w0 = ((dsp_info >> 16) & 0x7ff) + 1;
1202 x_st_w0 = dsp_st & 0xffff;
1203 y_st_w0 = dsp_st >> 16;
1204 x_factor = factor & 0xffff;
1205 y_factor = factor >> 16;
1206 x_scale = 4096 * 100 / x_factor;
1207 y_scale = 4096 * 100 / y_factor;
1208 xvir_w1 = (lcdc_readl(lcdc_dev, WIN_VIR) >> 16) & 0x1fff;
1209 dsp_info = lcdc_readl(lcdc_dev, WIN1_DSP_INFO);
1210 dsp_st = lcdc_readl(lcdc_dev, WIN1_DSP_ST);
1211 x_dsp_w1 = (dsp_info & 0x7ff) + 1;
1212 y_dsp_w1 = ((dsp_info >> 16) & 0x7ff) + 1;
1213 x_st_w1 = dsp_st & 0xffff;
1214 y_st_w1 = dsp_st >> 16;
1216 spin_unlock(&lcdc_dev->reg_lock);
1219 spin_unlock(&lcdc_dev->reg_lock);
1220 return snprintf(buf, PAGE_SIZE,
1232 "YRGB buffer addr:0x%08x\n"
1233 "CBR buffer addr:0x%08x\n\n"
1241 "YRGB buffer addr:0x%08x\n"
1256 lcdc_readl(lcdc_dev, WIN0_YRGB_MST0),
1257 lcdc_readl(lcdc_dev, WIN0_CBR_MST0),
1265 lcdc_readl(lcdc_dev, WIN1_MST),
1266 ovl ? "win0 on the top of win1\n" :
1267 "win1 on the top of win0\n");
1270 static int rk3188_lcdc_fps_mgr(struct rk_lcdc_driver *dev_drv, int fps,
1273 struct lcdc_device *lcdc_dev =
1274 container_of(dev_drv, struct lcdc_device, driver);
1275 struct rk_screen *screen = dev_drv->cur_screen;
1280 u32 x_total, y_total;
1282 ft = div_u64(1000000000000llu, fps);
1284 screen->mode.upper_margin + screen->mode.lower_margin +
1285 screen->mode.yres + screen->mode.vsync_len;
1287 screen->mode.left_margin + screen->mode.right_margin +
1288 screen->mode.xres + screen->mode.hsync_len;
1289 dev_drv->pixclock = div_u64(ft, x_total * y_total);
1290 dotclk = div_u64(1000000000000llu, dev_drv->pixclock);
1291 ret = clk_set_rate(lcdc_dev->dclk, dotclk);
1294 pixclock = div_u64(1000000000000llu, clk_get_rate(lcdc_dev->dclk));
1295 dev_drv->pixclock = lcdc_dev->pixclock = pixclock;
1296 fps = rk_fb_calc_fps(lcdc_dev->screen, pixclock);
1297 screen->ft = 1000 / fps; /*one frame time in ms */
1300 dev_info(dev_drv->dev, "%s:dclk:%lu,fps:%d\n", __func__,
1301 clk_get_rate(lcdc_dev->dclk), fps);
1306 static int rk3188_fb_win_remap(struct rk_lcdc_driver *dev_drv,
1307 enum fb_win_map_order order)
1309 mutex_lock(&dev_drv->fb_win_id_mutex);
1310 if (order == FB_DEFAULT_ORDER)
1311 order = FB0_WIN0_FB1_WIN1_FB2_WIN2;
1312 dev_drv->fb2_win_id = order / 100;
1313 dev_drv->fb1_win_id = (order / 10) % 10;
1314 dev_drv->fb0_win_id = order % 10;
1315 mutex_unlock(&dev_drv->fb_win_id_mutex);
1320 static int rk3188_lcdc_get_win_id(struct rk_lcdc_driver *dev_drv,
1324 mutex_lock(&dev_drv->fb_win_id_mutex);
1325 if (!strcmp(id, "fb0") || !strcmp(id, "fb2"))
1326 win_id = dev_drv->fb0_win_id;
1327 else if (!strcmp(id, "fb1") || !strcmp(id, "fb3"))
1328 win_id = dev_drv->fb1_win_id;
1329 mutex_unlock(&dev_drv->fb_win_id_mutex);
1334 static int rk3188_set_dsp_lut(struct rk_lcdc_driver *dev_drv, int *lut)
1341 struct lcdc_device *lcdc_dev =
1342 container_of(dev_drv, struct lcdc_device, driver);
1343 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_DSP_LUT_EN, v_DSP_LUT_EN(0));
1344 lcdc_cfg_done(lcdc_dev);
1346 if (dev_drv->cur_screen->dsp_lut) {
1347 for (i = 0; i < 256; i++) {
1348 v = dev_drv->cur_screen->dsp_lut[i] = lut[i];
1349 c = lcdc_dev->dsp_lut_addr_base + i;
1350 writel_relaxed(v, c);
1354 dev_err(dev_drv->dev, "no buffer to backup lut data!\n");
1357 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_DSP_LUT_EN, v_DSP_LUT_EN(1));
1358 lcdc_cfg_done(lcdc_dev);
1363 static int rk3188_lcdc_dpi_open(struct rk_lcdc_driver *dev_drv, bool open)
1365 struct lcdc_device *lcdc_dev =
1366 container_of(dev_drv, struct lcdc_device, driver);
1367 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_DIRECT_PATCH_EN,
1368 v_DIRECT_PATCH_EN(open));
1369 lcdc_cfg_done(lcdc_dev);
1373 static int rk3188_lcdc_dpi_win_sel(struct rk_lcdc_driver *dev_drv, int win_id)
1375 struct lcdc_device *lcdc_dev = container_of(dev_drv,
1376 struct lcdc_device, driver);
1377 lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_DIRECT_PATH_LAY_SEL,
1378 v_DIRECT_PATH_LAY_SEL(win_id));
1379 lcdc_cfg_done(lcdc_dev);
1384 static int rk3188_lcdc_dpi_status(struct rk_lcdc_driver *dev_drv)
1386 struct lcdc_device *lcdc_dev =
1387 container_of(dev_drv, struct lcdc_device, driver);
1388 int ovl = lcdc_read_bit(lcdc_dev, SYS_CTRL, m_DIRECT_PATCH_EN);
1392 int rk3188_lcdc_poll_vblank(struct rk_lcdc_driver *dev_drv)
1394 struct lcdc_device *lcdc_dev =
1395 container_of(dev_drv, struct lcdc_device, driver);
1399 if (lcdc_dev->clk_on) {
1400 int_reg = lcdc_readl(lcdc_dev, INT_STATUS);
1401 if (int_reg & m_LF_INT_STA) {
1402 lcdc_msk_reg(lcdc_dev, INT_STATUS, m_LF_INT_CLEAR,
1404 ret = RK_LF_STATUS_FC;
1406 ret = RK_LF_STATUS_FR;
1408 ret = RK_LF_STATUS_NC;
1414 static struct rk_lcdc_win lcdc_win[] = {
1423 .support_3d = false,
1427 static struct rk_lcdc_drv_ops lcdc_drv_ops = {
1428 .open = rk3188_lcdc_open,
1429 .load_screen = rk3188_load_screen,
1430 .set_par = rk3188_lcdc_set_par,
1431 .pan_display = rk3188_lcdc_pan_display,
1432 .lcdc_reg_update = rk3188_lcdc_reg_update,
1433 .blank = rk3188_lcdc_blank,
1434 .ioctl = rk3188_lcdc_ioctl,
1435 .suspend = rk3188_lcdc_early_suspend,
1436 .resume = rk3188_lcdc_early_resume,
1437 .get_win_state = rk3188_lcdc_get_win_state,
1438 .ovl_mgr = rk3188_lcdc_ovl_mgr,
1439 .get_disp_info = rk3188_lcdc_get_disp_info,
1440 .fps_mgr = rk3188_lcdc_fps_mgr,
1441 .fb_get_win_id = rk3188_lcdc_get_win_id,
1442 .fb_win_remap = rk3188_fb_win_remap,
1443 .set_dsp_lut = rk3188_set_dsp_lut,
1444 .poll_vblank = rk3188_lcdc_poll_vblank,
1445 .dpi_open = rk3188_lcdc_dpi_open,
1446 .dpi_win_sel = rk3188_lcdc_dpi_win_sel,
1447 .dpi_status = rk3188_lcdc_dpi_status,
1450 static irqreturn_t rk3188_lcdc_isr(int irq, void *dev_id)
1452 struct lcdc_device *lcdc_dev =
1453 (struct lcdc_device *)dev_id;
1454 ktime_t timestamp = ktime_get();
1455 u32 int_reg = lcdc_readl(lcdc_dev, INT_STATUS);
1457 if (int_reg & m_FS_INT_STA) {
1458 timestamp = ktime_get();
1459 lcdc_msk_reg(lcdc_dev, INT_STATUS, m_FS_INT_CLEAR,
1461 if (lcdc_dev->driver.wait_fs) {
1462 spin_lock(&(lcdc_dev->driver.cpl_lock));
1463 complete(&(lcdc_dev->driver.frame_done));
1464 spin_unlock(&(lcdc_dev->driver.cpl_lock));
1466 lcdc_dev->driver.vsync_info.timestamp = timestamp;
1467 wake_up_interruptible_all(&lcdc_dev->driver.vsync_info.wait);
1469 } else if (int_reg & m_LF_INT_STA) {
1470 lcdc_msk_reg(lcdc_dev, INT_STATUS, m_LF_INT_CLEAR,
1476 #if defined(CONFIG_PM)
1477 static int rk3188_lcdc_suspend(struct platform_device *pdev, pm_message_t state)
1482 static int rk3188_lcdc_resume(struct platform_device *pdev)
1487 #define rk3188_lcdc_suspend NULL
1488 #define rk3188_lcdc_resume NULL
1491 static int rk3188_lcdc_parse_dt(struct lcdc_device *lcdc_dev)
1493 struct device_node *np = lcdc_dev->dev->of_node;
1495 if (of_property_read_u32(np, "rockchip,prop", &val))
1496 lcdc_dev->prop = PRMRY; /*default set it as primary */
1498 lcdc_dev->prop = val;
1500 if (of_property_read_u32(np, "rockchip,pwr18", &val))
1501 lcdc_dev->pwr18 = false; /*default set it as 3.xv power supply */
1503 lcdc_dev->pwr18 = (val ? true : false);
1507 static int rk3188_lcdc_probe(struct platform_device *pdev)
1509 struct lcdc_device *lcdc_dev = NULL;
1510 struct rk_lcdc_driver *dev_drv;
1511 struct device *dev = &pdev->dev;
1512 struct resource *res;
1513 struct device_node *np = pdev->dev.of_node;
1517 /*if the primary lcdc has not registered ,the extend
1518 lcdc register later */
1519 of_property_read_u32(np, "rockchip,prop", &prop);
1520 if (prop == EXTEND) {
1521 if (!is_prmry_rk_lcdc_registered())
1522 return -EPROBE_DEFER;
1524 lcdc_dev = devm_kzalloc(dev,
1525 sizeof(struct lcdc_device), GFP_KERNEL);
1527 dev_err(&pdev->dev, "rk3188 lcdc device kmalloc fail!");
1530 platform_set_drvdata(pdev, lcdc_dev);
1531 lcdc_dev->dev = dev;
1532 rk3188_lcdc_parse_dt(lcdc_dev);
1533 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1534 lcdc_dev->reg_phy_base = res->start;
1535 lcdc_dev->len = resource_size(res);
1536 lcdc_dev->regs = devm_ioremap_resource(dev, res);
1537 if (IS_ERR(lcdc_dev->regs))
1538 return PTR_ERR(lcdc_dev->regs);
1540 lcdc_dev->regsbak = devm_kzalloc(dev, lcdc_dev->len, GFP_KERNEL);
1541 if (IS_ERR(lcdc_dev->regsbak))
1542 return PTR_ERR(lcdc_dev->regsbak);
1543 lcdc_dev->dsp_lut_addr_base = (lcdc_dev->regs + DSP_LUT_ADDR);
1544 lcdc_dev->id = rk3188_lcdc_get_id(lcdc_dev->reg_phy_base);
1545 if (lcdc_dev->id < 0) {
1546 dev_err(&pdev->dev, "no such lcdc device!\n");
1549 dev_set_name(lcdc_dev->dev, "lcdc%d", lcdc_dev->id);
1550 dev_drv = &lcdc_dev->driver;
1552 dev_drv->prop = prop;
1553 dev_drv->id = lcdc_dev->id;
1554 dev_drv->ops = &lcdc_drv_ops;
1555 dev_drv->num_win = ARRAY_SIZE(lcdc_win);
1556 spin_lock_init(&lcdc_dev->reg_lock);
1558 lcdc_dev->irq = platform_get_irq(pdev, 0);
1559 if (lcdc_dev->irq < 0) {
1560 dev_err(&pdev->dev, "cannot find IRQ for lcdc%d\n",
1565 ret = devm_request_irq(dev, lcdc_dev->irq, rk3188_lcdc_isr,
1566 IRQF_DISABLED, dev_name(dev), lcdc_dev);
1568 dev_err(&pdev->dev, "cannot requeset irq %d - err %d\n",
1569 lcdc_dev->irq, ret);
1573 ret = rk_fb_register(dev_drv, lcdc_win, lcdc_dev->id);
1575 dev_err(dev, "register fb for lcdc%d failed!\n", lcdc_dev->id);
1578 dev_info(dev, "lcdc%d probe ok\n", lcdc_dev->id);
1583 static int rk3188_lcdc_remove(struct platform_device *pdev)
1589 static void rk3188_lcdc_shutdown(struct platform_device *pdev)
1591 struct lcdc_device *lcdc_dev = platform_get_drvdata(pdev);
1593 rk3188_lcdc_deint(lcdc_dev);
1594 rk_disp_pwr_disable(&lcdc_dev->driver);
1597 #if defined(CONFIG_OF)
1598 static const struct of_device_id rk3188_lcdc_dt_ids[] = {
1599 {.compatible = "rockchip,rk3188-lcdc",},
1604 static struct platform_driver rk3188_lcdc_driver = {
1605 .probe = rk3188_lcdc_probe,
1606 .remove = rk3188_lcdc_remove,
1608 .name = "rk3188-lcdc",
1609 .owner = THIS_MODULE,
1610 .of_match_table = of_match_ptr(rk3188_lcdc_dt_ids),
1612 .suspend = rk3188_lcdc_suspend,
1613 .resume = rk3188_lcdc_resume,
1614 .shutdown = rk3188_lcdc_shutdown,
1617 static int __init rk3188_lcdc_module_init(void)
1619 return platform_driver_register(&rk3188_lcdc_driver);
1622 static void __exit rk3188_lcdc_module_exit(void)
1624 platform_driver_unregister(&rk3188_lcdc_driver);
1627 fs_initcall(rk3188_lcdc_module_init);
1628 module_exit(rk3188_lcdc_module_exit);