From a5c44520bba9ded3f7b71cae865f6ba1554d1bad Mon Sep 17 00:00:00 2001 From: hjc Date: Thu, 9 Oct 2014 16:28:31 +0800 Subject: [PATCH] rk fb: fix change ddr freq lead to system panic when uboot display logo --- drivers/video/rockchip/lcdc/rk312x_lcdc.c | 15 +++--- drivers/video/rockchip/rk_fb.c | 63 ++++++++++++----------- include/linux/rk_fb.h | 1 + 3 files changed, 43 insertions(+), 36 deletions(-) diff --git a/drivers/video/rockchip/lcdc/rk312x_lcdc.c b/drivers/video/rockchip/lcdc/rk312x_lcdc.c index 2b76b708eab8..f3780beec34f 100755 --- a/drivers/video/rockchip/lcdc/rk312x_lcdc.c +++ b/drivers/video/rockchip/lcdc/rk312x_lcdc.c @@ -154,19 +154,22 @@ static int rk312x_lcdc_enable_irq(struct rk_lcdc_driver *dev_drv) u32 mask, val; struct lcdc_device *lcdc_dev = container_of(dev_drv, struct lcdc_device, driver); - struct rk_screen *screen = dev_drv->cur_screen; + /*struct rk_screen *screen = dev_drv->cur_screen;*/ spin_lock(&lcdc_dev->reg_lock); if (likely(lcdc_dev->clk_on)) { mask = m_FS_INT_CLEAR | m_FS_INT_EN | - m_LF_INT_CLEAR | m_LF_INT_EN | m_LF_INT_NUM | + m_LF_INT_CLEAR | m_LF_INT_EN | m_BUS_ERR_INT_CLEAR | m_BUS_ERR_INT_EN; val = v_FS_INT_CLEAR(1) | v_FS_INT_EN(1) | v_LF_INT_CLEAR(1) | v_LF_INT_EN(1) | - v_BUS_ERR_INT_CLEAR(1) | v_BUS_ERR_INT_EN(0) | - v_LF_INT_NUM(screen->mode.vsync_len + + v_BUS_ERR_INT_CLEAR(1) | v_BUS_ERR_INT_EN(0); + #if 0 + mask |= m_LF_INT_NUM; + val |= v_LF_INT_NUM(screen->mode.vsync_len + screen->mode.upper_margin + - screen->mode.yres); + screen->mode.yres) + #endif #ifdef LCDC_IRQ_EMPTY_DEBUG mask |= m_WIN0_EMPTY_INT_EN | m_WIN1_EMPTY_INT_EN; val |= v_WIN0_EMPTY_INT_EN(1) | v_WIN1_EMPTY_INT_EN(1); @@ -1299,7 +1302,7 @@ static int rk312x_lcdc_open(struct rk_lcdc_driver *dev_drv, int win_id, if (dev_drv->iommu_enabled) rk312x_lcdc_mmu_en(dev_drv); if ((support_uboot_display() && (lcdc_dev->prop == PRMRY))) { - rk312x_lcdc_set_dclk(dev_drv); + /*rk312x_lcdc_set_dclk(dev_drv);*/ rk312x_lcdc_enable_irq(dev_drv); } else { rk312x_load_screen(dev_drv, 1); diff --git a/drivers/video/rockchip/rk_fb.c b/drivers/video/rockchip/rk_fb.c index cbd86c8204d8..eda5748ad052 100755 --- a/drivers/video/rockchip/rk_fb.c +++ b/drivers/video/rockchip/rk_fb.c @@ -3390,41 +3390,43 @@ int rk_fb_switch_screen(struct rk_screen *screen, int enable, int lcdc_id) dev_drv->cur_screen->x_mirror = dev_drv->rotate_mode & X_MIRROR; dev_drv->cur_screen->y_mirror = dev_drv->rotate_mode & Y_MIRROR; } - - for (i = 0; i < dev_drv->lcdc_win_num; i++) { - info = rk_fb->fb[dev_drv->fb_index_base + i]; - win_id = dev_drv->ops->fb_get_win_id(dev_drv, info->fix.id); - if (dev_drv->win[win_id]) { - if (rk_fb->disp_mode == DUAL) { - if (dev_drv != pmy_dev_drv && - pmy_dev_drv->win[win_id]) { - dev_drv->win[win_id]->logicalstate = - pmy_dev_drv->win[win_id]->logicalstate; - pmy_info = rk_fb->fb[pmy_dev_drv->fb_index_base + i]; - } - } - if (dev_drv->win[win_id]->logicalstate) { - if (!dev_drv->win[win_id]->state) - dev_drv->ops->open(dev_drv, win_id, 1); - if (!load_screen) { - dev_drv->ops->load_screen(dev_drv, 1); - load_screen = 1; - } - info->var.activate |= FB_ACTIVATE_FORCE; + if (!dev_drv->uboot_logo) { + for (i = 0; i < dev_drv->lcdc_win_num; i++) { + info = rk_fb->fb[dev_drv->fb_index_base + i]; + win_id = dev_drv->ops->fb_get_win_id(dev_drv, info->fix.id); + if (dev_drv->win[win_id]) { if (rk_fb->disp_mode == DUAL) { - rk_fb_update_ext_info(info, pmy_info, 1); - } else if (rk_fb->disp_mode == ONE_DUAL) { - info->var.grayscale &= 0xff; - info->var.grayscale |= - (dev_drv->cur_screen->xsize << 8) + - (dev_drv->cur_screen->ysize << 20); + if (dev_drv != pmy_dev_drv && + pmy_dev_drv->win[win_id]) { + dev_drv->win[win_id]->logicalstate = + pmy_dev_drv->win[win_id]->logicalstate; + pmy_info = rk_fb->fb[pmy_dev_drv->fb_index_base + i]; + } + } + if (dev_drv->win[win_id]->logicalstate) { + if (!dev_drv->win[win_id]->state) + dev_drv->ops->open(dev_drv, win_id, 1); + if (!load_screen) { + dev_drv->ops->load_screen(dev_drv, 1); + load_screen = 1; + } + info->var.activate |= FB_ACTIVATE_FORCE; + if (rk_fb->disp_mode == DUAL) { + rk_fb_update_ext_info(info, pmy_info, 1); + } else if (rk_fb->disp_mode == ONE_DUAL) { + info->var.grayscale &= 0xff; + info->var.grayscale |= + (dev_drv->cur_screen->xsize << 8) + + (dev_drv->cur_screen->ysize << 20); + } + info->fbops->fb_set_par(info); + info->fbops->fb_pan_display(&info->var, info); } - info->fbops->fb_set_par(info); - info->fbops->fb_pan_display(&info->var, info); } } + }else { + dev_drv->uboot_logo = 0; } - hdmi_switch_complete = 1; if (rk_fb->disp_mode == ONE_DUAL) { if (dev_drv->ops->set_screen_scaler) @@ -3923,6 +3925,7 @@ int rk_fb_register(struct rk_lcdc_driver *dev_drv, #endif rk_fb_alloc_buffer(main_fbi, 0); /* only alloc memory for main fb */ + dev_drv->uboot_logo = support_uboot_display(); if (support_uboot_display()) { if (dev_drv->iommu_enabled) rk_fb_copy_from_loader(main_fbi); diff --git a/include/linux/rk_fb.h b/include/linux/rk_fb.h index 161e987a281f..8c5313f9368e 100755 --- a/include/linux/rk_fb.h +++ b/include/linux/rk_fb.h @@ -593,6 +593,7 @@ struct rk_lcdc_driver { struct overscan overscan; struct rk_lcdc_bcsh bcsh; int *hwc_lut; + int uboot_logo; }; /*disp_mode: dual display mode -- 2.34.1