rk_fb & rk3036 lcdc & rk312x lcdc:
authorZheng Yang <zhengyang@rock-chips.com>
Tue, 13 Jan 2015 06:13:06 +0000 (14:13 +0800)
committerZheng Yang <zhengyang@rock-chips.com>
Tue, 13 Jan 2015 06:13:06 +0000 (14:13 +0800)
        1. Modify box display policy, rk_fb_update_reg() need to check yuv420
           format.
        2. When power up in uboot logo mode, if rk_fb_switch_screen input screen
           type is not equal to current screen type, exit uboot logo mode. For
           the case of display interface change happen at the moment of kernel
           initialization.
        3. Fox box, if RK_FBIOSET_YUV_ADDR input address is zero, we close related
           lcdc layer. Because RK_FBIOSET_ENABLE may not be called by application,
           especially at low memory enviorment,such as rk3036 256M ram.

Signed-off-by: Zheng Yang <zhengyang@rock-chips.com>
drivers/video/rockchip/lcdc/rk3036_lcdc.c
drivers/video/rockchip/lcdc/rk312x_lcdc.c
drivers/video/rockchip/rk_fb.c

index da1b70bc5efd2bde0b0ebaf5d205ab91e8922a63..1ff927adcec02f048d9a89de7207157cc1bbcbb0 100755 (executable)
@@ -324,15 +324,23 @@ static void lcdc_layer_update_regs(struct lcdc_device *lcdc_dev,
        } else {
                win->area[0].y_addr = 0;
                win->area[0].uv_addr = 0;
-               if (win->id == 0)
+               if (win->id == 0) {
                        lcdc_msk_reg(lcdc_dev,
                                     SYS_CTRL, m_WIN0_EN, v_WIN0_EN(0));
-               else if (win->id == 1)
+                       lcdc_writel(lcdc_dev, WIN0_YRGB_MST,
+                                   win->area[0].y_addr);
+                       lcdc_writel(lcdc_dev, WIN0_CBR_MST,
+                                   win->area[0].uv_addr);
+               } else if (win->id == 1) {
                        lcdc_msk_reg(lcdc_dev,
                                     SYS_CTRL, m_WIN1_EN, v_WIN1_EN(0));
-               else if (win->id == 2)
+                       lcdc_writel(lcdc_dev, WIN1_MST, win->area[0].y_addr);
+               } else if (win->id == 2) {
                        lcdc_msk_reg(lcdc_dev,
-                                    SYS_CTRL, m_HWC_EN, v_HWC_EN(0));
+                                    SYS_CTRL, m_HWC_EN | m_HWC_LODAD_EN,
+                                    v_HWC_EN(0) | v_HWC_LODAD_EN(0));
+                       lcdc_writel(lcdc_dev, HWC_MST, win->area[0].y_addr);
+               }
        }
        rk3036_lcdc_alpha_cfg(lcdc_dev);
 }
@@ -508,6 +516,9 @@ static int rk3036_lcdc_pre_init(struct rk_lcdc_driver *dev_drv)
 
        /*backup reg config at uboot*/
        rk_lcdc_read_reg_defalut_cfg(lcdc_dev);
+       if (lcdc_readl(lcdc_dev, AXI_BUS_CTRL) & m_TVE_DAC_DCLK_EN)
+               dev_drv->cur_screen->type = SCREEN_TVOUT;
+
        lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_AUTO_GATING_EN,
                     v_AUTO_GATING_EN(0));
        lcdc_cfg_done(lcdc_dev);
@@ -1015,7 +1026,9 @@ static int rk3036_lcdc_ovl_mgr(struct rk_lcdc_driver *dev_drv, int swap,
        int ovl, needswap = 0;
 
        if (!swap) {
-               if (win0->z_order > win1->z_order)
+               if (win0->z_order >= 0 &&
+                   win1->z_order >= 0 &&
+                   win0->z_order > win1->z_order)
                        needswap = 1;
                else
                        needswap = 0;
@@ -1138,7 +1151,6 @@ static int rk3036_lcdc_cfg_done(struct rk_lcdc_driver *dev_drv)
        struct lcdc_device *lcdc_dev =
            container_of(dev_drv, struct lcdc_device, driver);
        int i;
-       unsigned int mask, val;
        struct rk_lcdc_win *win = NULL;
 
        spin_lock(&lcdc_dev->reg_lock);
@@ -1166,30 +1178,8 @@ static int rk3036_lcdc_cfg_done(struct rk_lcdc_driver *dev_drv)
                             v_LCDC_STANDBY(lcdc_dev->standby));
                for (i = 0; i < ARRAY_SIZE(lcdc_win); i++) {
                        win = dev_drv->win[i];
-                       if ((win->state == 0) && (win->last_state == 1)) {
-                               switch (win->id) {
-                               case 0:
-                                       mask =  m_WIN0_EN;
-                                       val  =  v_WIN0_EN(0);
-                                       lcdc_msk_reg(lcdc_dev, SYS_CTRL,
-                                                    mask, val);
-                                       break;
-                               case 1:
-                                       mask =  m_WIN1_EN;
-                                       val  =  v_WIN1_EN(0);
-                                       lcdc_msk_reg(lcdc_dev, SYS_CTRL,
-                                                    mask, val);
-                                       break;
-                               case 2:
-                                       mask =  m_HWC_EN;
-                                       val  =  v_HWC_EN(0);
-                                       lcdc_msk_reg(lcdc_dev, SYS_CTRL,
-                                                    mask, val);
-                                       break;
-                               default:
-                                       break;
-                               }
-                       }
+                       if ((win->state == 0) && (win->last_state == 1))
+                               lcdc_layer_update_regs(lcdc_dev, win);
                        win->last_state = win->state;
                }
                lcdc_cfg_done(lcdc_dev);
index 5d78ced7dc4c340df6df5bcb4eeb38bb8f1639c0..7ef9402610cbf9ed7a09cc9a123ba0221c26273c 100755 (executable)
@@ -507,14 +507,23 @@ static void lcdc_layer_update_regs(struct lcdc_device *lcdc_dev,
        } else {
                win->area[0].y_addr = 0;
                win->area[0].uv_addr = 0;
-               if (win->id == 0)
+               if (win->id == 0) {
                        lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_WIN0_EN,
                                     v_WIN0_EN(0));
-               else if (win->id == 1)
+                       lcdc_writel(lcdc_dev, WIN0_YRGB_MST,
+                                   win->area[0].y_addr);
+                       lcdc_writel(lcdc_dev, WIN0_CBR_MST,
+                                   win->area[0].uv_addr);
+               } else if (win->id == 1) {
                        lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_WIN1_EN,
                                     v_WIN1_EN(0));
-               else if (win->id == 2)
-                       lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_HWC_EN, v_HWC_EN(0));
+                        lcdc_writel(lcdc_dev, WIN1_MST, win->area[0].y_addr);
+               } else if (win->id == 2) {
+                       lcdc_msk_reg(lcdc_dev,
+                                    SYS_CTRL, m_HWC_EN | m_HWC_LODAD_EN,
+                                    v_HWC_EN(0) | v_HWC_LODAD_EN(0));
+                       lcdc_writel(lcdc_dev, HWC_MST, win->area[0].y_addr);
+               }
        }
        rk312x_lcdc_alpha_cfg(lcdc_dev);
 }
@@ -1865,37 +1874,14 @@ static int rk312x_lcdc_cfg_done(struct rk_lcdc_driver *dev_drv)
        struct lcdc_device *lcdc_dev = container_of(dev_drv,
                                                    struct lcdc_device, driver);
        int i;
-       unsigned int mask, val;
        struct rk_lcdc_win *win = NULL;
 
        spin_lock(&lcdc_dev->reg_lock);
        if (lcdc_dev->clk_on) {
                for (i = 0; i < ARRAY_SIZE(lcdc_win); i++) {
                        win = dev_drv->win[i];
-                       if ((win->state == 0) && (win->last_state == 1)) {
-                               switch (win->id) {
-                               case 0:
-                                       mask =  m_WIN0_EN;
-                                       val  =  v_WIN0_EN(0);
-                                       lcdc_msk_reg(lcdc_dev, SYS_CTRL,
-                                                    mask, val);
-                                       break;
-                               case 1:
-                                       mask =  m_WIN1_EN;
-                                       val  =  v_WIN1_EN(0);
-                                       lcdc_msk_reg(lcdc_dev, SYS_CTRL,
-                                                    mask, val);
-                                       break;
-                               case 2:
-                                       mask =  m_HWC_EN;
-                                       val  =  v_HWC_EN(0);
-                                       lcdc_msk_reg(lcdc_dev, SYS_CTRL,
-                                                    mask, val);
-                                       break;
-                               default:
-                                       break;
-                               }
-                       }
+                       if ((win->state == 0) && (win->last_state == 1))
+                               lcdc_layer_update_regs(lcdc_dev, win);
                        win->last_state = win->state;
                }
                lcdc_cfg_done(lcdc_dev);
index 134e1a7e1862cc90229b87970d62a66e4d64feae..4164663db3993845314adf17a3651e6242848eba 100755 (executable)
@@ -1979,8 +1979,7 @@ static void rk_fb_update_reg(struct rk_lcdc_driver *dev_drv,
                }
        }
        dev_drv->ops->ovl_mgr(dev_drv, 0, 1);
-       if (rk_fb->disp_policy == DISPLAY_POLICY_BOX)
-               dev_drv->ops->cfg_done(dev_drv);
+
 #if defined(CONFIG_RK_HDMI)
        if ((rk_fb->disp_mode == DUAL)
            && (hdmi_get_hotplug() == HDMI_HPD_ACTIVED)
@@ -2047,9 +2046,7 @@ ext_win_exit:
                for (i = 0; i < dev_drv->lcdc_win_num; i++) {
                        if (dev_drv->win[i]->state == 1) {
                                if (rk_fb->disp_policy == DISPLAY_POLICY_BOX &&
-                                   (dev_drv->win[i]->area[0].format == YUV420 ||
-                                    dev_drv->win[i]->area[0].format == YUV420_A ||
-                                    !strcmp(dev_drv->win[i]->name, "hwc"))) {
+                                   (!strcmp(dev_drv->win[i]->name, "hwc"))) {
                                        continue;
                                } else {
                                        u32 new_start =
@@ -2059,8 +2056,7 @@ ext_win_exit:
 
                                        if ((rk_fb->disp_policy ==
                                             DISPLAY_POLICY_BOX) &&
-                                           (new_start == 0x0 ||
-                                            dev_drv->suspend_flag))
+                                           (dev_drv->suspend_flag))
                                                continue;
                                        if (unlikely(new_start != reg_start)) {
                                                wait_for_vsync = true;
@@ -2145,7 +2141,7 @@ static int rk_fb_check_config_var(struct rk_fb_area_par *area_par,
        if ((area_par->xpos + area_par->xsize > screen->mode.xres) ||
            (area_par->ypos + area_par->ysize > screen->mode.yres) ||
            (area_par->xsize <= 0) || (area_par->ysize <= 0)) {
-               pr_err("check config var fail 1:\n"
+               pr_warn("check config var fail 1:\n"
                       "xpos=%d,xsize=%d,xres=%d\n"
                       "ypos=%d,ysize=%d,yres=%d\n",
                       area_par->xpos, area_par->xsize, screen->mode.xres,
@@ -2660,6 +2656,7 @@ static int rk_fb_ioctl(struct fb_info *info, unsigned int cmd,
                        if (!usr_fd) {
                                fix->smem_start = 0;
                                fix->mmio_start = 0;
+                               dev_drv->ops->open(dev_drv, win_id, 0);
                                break;
                        }
 
@@ -2709,7 +2706,6 @@ static int rk_fb_ioctl(struct fb_info *info, unsigned int cmd,
 
                                usr_fd = yuv_phy[0];
                                offset = yuv_phy[1] - yuv_phy[0];
-
                                if (!usr_fd) {
                                        fix->smem_start = 0;
                                        fix->mmio_start = 0;
@@ -3571,7 +3567,8 @@ int rk_fb_switch_screen(struct rk_screen *screen, int enable, int lcdc_id)
                if (dev_drv->ops->set_screen_scaler)
                        dev_drv->ops->set_screen_scaler(dev_drv, dev_drv->screen0, 0);
        }
-
+       if (dev_drv->uboot_logo && (screen->type != dev_drv->cur_screen->type))
+               dev_drv->uboot_logo = 0;
        if (!enable) {
                /* if screen type is different, we do not disable lcdc. */
                if (dev_drv->cur_screen->type != screen->type)