//set lcdc according the screen info static int rk3188_load_screen(struct rk_lcdc_device_driver *dev_drv, bool initscreen) { int ret = -EINVAL; int fps; u16 face = 0; struct rk3188_lcdc_device *lcdc_dev = container_of(dev_drv,struct rk3188_lcdc_device,driver); rk_screen *screen = dev_drv->cur_screen; u16 right_margin = screen->right_margin; u16 left_margin = screen->left_margin; u16 lower_margin = screen->lower_margin; u16 upper_margin = screen->upper_margin; u16 x_res = screen->x_res; u16 y_res = screen->y_res; spin_lock(&lcdc_dev->reg_lock); if(likely(lcdc_dev->clk_on)) { if(screen->type==SCREEN_MCU) { printk("MUC¡¡screen not supported now!\n"); return -EINVAL; } switch (screen->face) { case OUT_P565: face = OUT_P565; //dither down to rgb565 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_DITHER_DOWN_EN | m_DITHER_DOWN_MODE | m_DITHER_DOWN_SEL,v_DITHER_DOWN_EN(1) | v_DITHER_DOWN_MODE(0) | v_DITHER_DOWN_SEL(1)); break; case OUT_P666: face = OUT_P666; //dither down to rgb666 lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_DITHER_DOWN_EN | m_DITHER_DOWN_MODE | m_DITHER_DOWN_SEL, v_DITHER_DOWN_EN(1) | v_DITHER_DOWN_MODE(1) | v_DITHER_DOWN_SEL(1)); break; case OUT_D888_P565: face = OUT_P888; lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_DITHER_DOWN_EN | m_DITHER_DOWN_MODE | m_DITHER_DOWN_SEL, v_DITHER_DOWN_EN(1) | v_DITHER_DOWN_MODE(0) | v_DITHER_DOWN_SEL(1)); break; case OUT_D888_P666: face = OUT_P888; lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_DITHER_DOWN_EN | m_DITHER_DOWN_MODE | m_DITHER_DOWN_SEL, v_DITHER_DOWN_EN(1) | v_DITHER_DOWN_MODE(1) | v_DITHER_DOWN_SEL(1)); break; case OUT_P888: face = OUT_P888; break; default: printk("unsupported display output interface!\n"); break; } //use default overlay,set vsyn hsync den dclk polarity lcdc_msk_reg(lcdc_dev, DSP_CTRL0,m_DSP_OUT_FORMAT | m_HSYNC_POL | m_VSYNC_POL | m_DEN_POL |m_DCLK_POL,v_DSP_OUT_FORMAT(face) | v_HSYNC_POL(screen->pin_hsync) | v_VSYNC_POL(screen->pin_vsync) | v_DEN_POL(screen->pin_den) | v_DCLK_POL(screen->pin_dclk)); //set background color to black,set swap according to the screen panel,disable blank mode lcdc_msk_reg(lcdc_dev, DSP_CTRL1, m_BG_COLOR| m_DSP_BG_SWAP | m_DSP_RB_SWAP | m_DSP_RG_SWAP | m_DSP_DELTA_SWAP | m_DSP_DUMMY_SWAP | m_BLANK_EN, v_BG_COLOR(0x000000) | v_DSP_BG_SWAP(screen->swap_gb) | v_DSP_RB_SWAP(screen->swap_rb) | v_DSP_RG_SWAP(screen->swap_rg) | v_DSP_DELTA_SWAP(screen->swap_delta) | v_DSP_DUMMY_SWAP(screen->swap_dumy) | v_BLANK_EN(0) | v_BLACK_EN(0)); lcdc_writel(lcdc_dev,DSP_HTOTAL_HS_END,v_HSYNC(screen->hsync_len) | v_HORPRD(screen->hsync_len + left_margin + x_res + right_margin)); lcdc_writel(lcdc_dev,DSP_HACT_ST_END,v_HAEP(screen->hsync_len + left_margin + x_res) | v_HASP(screen->hsync_len + left_margin)); lcdc_writel(lcdc_dev,DSP_VTOTAL_VS_END, v_VSYNC(screen->vsync_len) | v_VERPRD(screen->vsync_len + upper_margin + y_res + lower_margin)); lcdc_writel(lcdc_dev,DSP_VACT_ST_END,v_VAEP(screen->vsync_len + upper_margin+y_res)| v_VASP(screen->vsync_len + screen->upper_margin)); } spin_unlock(&lcdc_dev->reg_lock); ret = clk_set_rate(lcdc_dev->dclk, screen->pixclock); if(ret) { dev_err(dev_drv->dev,"set lcdc%d dclk failed\n",lcdc_dev->id); } lcdc_dev->driver.pixclock = lcdc_dev->pixclock = div_u64(1000000000000llu, clk_get_rate(lcdc_dev->dclk)); fps = rk_fb_calc_fps(screen,lcdc_dev->pixclock); screen->ft = 1000/fps; printk("%s: dclk:%lu>>fps:%d ",lcdc_dev->driver.name,clk_get_rate(lcdc_dev->dclk),fps); if(screen->init) { screen->init(); } if(screen->sscreen_set) { screen->sscreen_set(screen,!initscreen); } dev_info(dev_drv->dev,"%s for lcdc%d ok!\n",__func__,lcdc_dev->id); return 0; }
int rk_lcdc_load_screen(vidinfo_t *vid) { struct lcdc_device *lcdc_dev = &rk32_lcdc; struct rk_screen *screen = lcdc_dev->screen; int face = 0; u32 msk, val; rk_fb_vidinfo_to_screen(vid, screen); if (vid->screen_type == SCREEN_MIPI || vid->screen_type == SCREEN_DUAL_MIPI) { rk32_mipi_enable(vid); if (vid->screen_type == SCREEN_MIPI) { msk = m_MIPI_OUT_EN | m_EDP_OUT_EN | m_HDMI_OUT_EN | m_RGB_OUT_EN; val = v_MIPI_OUT_EN(1); } else { msk = m_MIPI_OUT_EN | m_EDP_OUT_EN | m_HDMI_OUT_EN | m_RGB_OUT_EN | m_DOUB_CHANNEL_EN; val = v_MIPI_OUT_EN(1) | v_DOUB_CHANNEL_EN(1); } } else if (vid->screen_type == SCREEN_EDP) { msk = m_MIPI_OUT_EN | m_EDP_OUT_EN | m_HDMI_OUT_EN | m_RGB_OUT_EN; val = v_EDP_OUT_EN(1); } else if (vid->screen_type == SCREEN_HDMI) { msk = m_MIPI_OUT_EN | m_EDP_OUT_EN | m_HDMI_OUT_EN | m_RGB_OUT_EN; val = v_HDMI_OUT_EN(1); } else if (vid->screen_type == SCREEN_RGB || vid->screen_type == SCREEN_LVDS || vid->screen_type == SCREEN_DUAL_LVDS) { msk = m_MIPI_OUT_EN | m_EDP_OUT_EN | m_HDMI_OUT_EN | m_RGB_OUT_EN; val = v_RGB_OUT_EN(1); } else { msk = m_MIPI_OUT_EN | m_EDP_OUT_EN | m_HDMI_OUT_EN | m_RGB_OUT_EN; val = v_HDMI_OUT_EN(1); } lcdc_msk_reg(lcdc_dev, SYS_CTRL, msk, val); msk = m_DSP_BLACK_EN | m_DSP_BLANK_EN | m_DSP_OUT_ZERO | m_DSP_DCLK_POL | m_DSP_DEN_POL | m_DSP_VSYNC_POL | m_DSP_HSYNC_POL; val = v_DSP_BLACK_EN(0) | v_DSP_BLANK_EN(0) | v_DSP_OUT_ZERO(0) | v_DSP_DCLK_POL(vid->vl_clkp) | v_DSP_DEN_POL(vid->vl_oep) | v_DSP_VSYNC_POL(vid->vl_vsp) | v_DSP_HSYNC_POL(vid->vl_hsp); lcdc_msk_reg(lcdc_dev, DSP_CTRL0, msk, val); switch (vid->lcd_face) { case OUT_P565: face = OUT_P565; msk = m_DITHER_DOWN_EN | m_DITHER_DOWN_MODE; val = v_DITHER_DOWN_EN(1) | v_DITHER_DOWN_MODE(0); break; case OUT_P666: face = OUT_P666; msk = m_DITHER_DOWN_EN | m_DITHER_DOWN_MODE | m_DITHER_DOWN_SEL; val = v_DITHER_DOWN_EN(1) | v_DITHER_DOWN_MODE(1) | v_DITHER_DOWN_SEL(1); break; case OUT_D888_P565: face = OUT_P888; msk = m_DITHER_DOWN_EN | m_DITHER_DOWN_MODE; val = v_DITHER_DOWN_EN(1) | v_DITHER_DOWN_MODE(0); break; case OUT_D888_P666: face = OUT_P888; msk = m_DITHER_DOWN_EN | m_DITHER_DOWN_MODE | m_DITHER_DOWN_SEL; val = v_DITHER_DOWN_EN(1) | v_DITHER_DOWN_MODE(1) | v_DITHER_DOWN_SEL(1); break; case OUT_P888: face = OUT_P888; msk = m_DITHER_DOWN_EN | m_DITHER_UP_EN | m_PRE_DITHER_DOWN_EN; val = v_DITHER_DOWN_EN(0) | v_DITHER_UP_EN(1) | v_PRE_DITHER_DOWN_EN(1); break; case OUT_P101010: face = OUT_P101010; msk = m_DITHER_DOWN_EN | m_DITHER_UP_EN | m_PRE_DITHER_DOWN_EN; val = v_DITHER_DOWN_EN(0) | v_DITHER_UP_EN(1) | v_PRE_DITHER_DOWN_EN(0); break; default: face = vid->lcd_face; msk = m_DITHER_DOWN_EN | m_DITHER_DOWN_MODE | m_DITHER_UP_EN; val = v_DITHER_DOWN_EN(0) | v_DITHER_DOWN_MODE(0) | v_DITHER_UP_EN(1); break; } lcdc_msk_reg(lcdc_dev, DSP_CTRL1, msk, val); if (vid->screen_type == SCREEN_EDP || vid->screen_type == SCREEN_HDMI) face = OUT_P101010; msk = m_DSP_RG_SWAP | m_DSP_RB_SWAP | m_DSP_DELTA_SWAP | m_DSP_FIELD_POL | m_DSP_DUMMY_SWAP | m_DSP_BG_SWAP | m_DSP_OUT_MODE; val = v_DSP_RG_SWAP(0) | v_DSP_RB_SWAP(vid->vl_swap_rb) | v_DSP_DELTA_SWAP(0) | v_DSP_DUMMY_SWAP(0) | v_DSP_FIELD_POL(0) | v_DSP_BG_SWAP(0) | v_DSP_OUT_MODE(face); lcdc_msk_reg(lcdc_dev, DSP_CTRL0, msk, val); lcdc_writel(lcdc_dev, DSP_BG, 0); val = v_DSP_HS_PW(vid->vl_hspw) | v_DSP_HTOTAL(vid->vl_hspw + vid->vl_hbpd + vid->vl_col + vid->vl_hfpd); lcdc_writel(lcdc_dev, DSP_HTOTAL_HS_END, val); val = v_DSP_HACT_END(vid->vl_hspw + vid->vl_hbpd + vid->vl_col) | v_DSP_HACT_ST(vid->vl_hspw + vid->vl_hbpd); lcdc_writel(lcdc_dev, DSP_HACT_ST_END, val); val = v_DSP_VTOTAL(vid->vl_vspw + vid->vl_vbpd + vid->vl_row + vid->vl_vfpd) | v_DSP_VS_PW(vid->vl_vspw); lcdc_writel(lcdc_dev, DSP_VTOTAL_VS_END, val); val = v_DSP_VACT_END(vid->vl_vspw + vid->vl_vbpd + vid->vl_row)| v_DSP_VACT_ST(vid->vl_vspw + vid->vl_vbpd); lcdc_writel(lcdc_dev, DSP_VACT_ST_END, val); val = v_DSP_HACT_END_POST(vid->vl_hspw + vid->vl_hbpd + vid->vl_col) | v_DSP_HACT_ST_POST(vid->vl_hspw + vid->vl_hbpd); lcdc_writel(lcdc_dev, POST_DSP_HACT_INFO, val); val = v_DSP_HACT_END_POST(vid->vl_vspw + vid->vl_vbpd + vid->vl_row)| v_DSP_HACT_ST_POST(vid->vl_vspw + vid->vl_vbpd); lcdc_writel(lcdc_dev, POST_DSP_VACT_INFO, val); lcdc_writel(lcdc_dev, POST_DSP_VACT_INFO_F1, 0); lcdc_writel(lcdc_dev, POST_RESERVED, 0x10001000); lcdc_writel(lcdc_dev, MCU_CTRL, 0); msk = m_DSP_LINE_FLAG_NUM | m_LINE_FLAG_INTR_EN; val = v_DSP_LINE_FLAG_NUM(vid->vl_vspw + vid->vl_vbpd + vid->vl_row) | v_LINE_FLAG_INTR_EN(0); lcdc_msk_reg(lcdc_dev, INTR_CTRL0, msk, val); lcdc_cfg_done(lcdc_dev); if ((vid->screen_type == SCREEN_LVDS) || (vid->screen_type == SCREEN_DUAL_LVDS) || (vid->screen_type == SCREEN_RGB)) { rk32_lvds_en(vid); } else if (vid->screen_type == SCREEN_EDP) { rk32_edp_enable(vid); } else if ((vid->screen_type == SCREEN_MIPI) || (vid->screen_type == SCREEN_DUAL_MIPI)) { rk32_dsi_sync(); } return 0; }