int rk30_hdmi_config_video(struct hdmi_video_para *vpara) { int value; struct fb_videomode *mode; hdmi_dbg(hdmi->dev, "[%s]\n", __FUNCTION__); if(vpara == NULL) { hdmi_err(hdmi->dev, "[%s] input parameter error\n", __FUNCTION__); return -1; } if(hdmi->pwr_mode == PWR_SAVE_MODE_E) rk30_hdmi_set_pwr_mode(PWR_SAVE_MODE_D); if(hdmi->pwr_mode == PWR_SAVE_MODE_D || hdmi->pwr_mode == PWR_SAVE_MODE_A) rk30_hdmi_set_pwr_mode(PWR_SAVE_MODE_B); if(hdmi->hdcp_power_off_cb) hdmi->hdcp_power_off_cb(); // Input video mode is RGB24bit, Data enable signal from external HDMIMskReg(value, AV_CTRL1, m_INPUT_VIDEO_MODE | m_DE_SIGNAL_SELECT, \ v_INPUT_VIDEO_MODE(vpara->input_mode) | EXTERNAL_DE) HDMIMskReg(value, VIDEO_CTRL1, m_VIDEO_OUTPUT_MODE | m_VIDEO_INPUT_DEPTH | m_VIDEO_INPUT_COLOR_MODE, \ v_VIDEO_OUTPUT_MODE(vpara->output_color) | v_VIDEO_INPUT_DEPTH(VIDEO_INPUT_DEPTH_8BIT) | vpara->input_color) HDMIWrReg(DEEP_COLOR_MODE, 0x20); // color space convert rk30_hdmi_config_csc(vpara); // Set HDMI Mode HDMIWrReg(HDCP_CTRL, v_HDMI_DVI(vpara->output_mode)); // Set ext video mode = (struct fb_videomode *)hdmi_vic_to_videomode(vpara->vic); if(mode == NULL) { hdmi_err(hdmi->dev, "[%s] not found vic %d\n", __FUNCTION__, vpara->vic); return -ENOENT; } hdmi->tmdsclk = mode->pixclock; if( (vpara->vic == HDMI_720x480p_60Hz_4_3) || (vpara->vic == HDMI_720x480p_60Hz_16_9) ) value = v_VSYNC_OFFSET(6); else value = v_VSYNC_OFFSET(0); value |= v_EXT_VIDEO_ENABLE(1) | v_INTERLACE(mode->vmode); if(mode->sync & FB_SYNC_HOR_HIGH_ACT) value |= v_HSYNC_POLARITY(1); if(mode->sync & FB_SYNC_VERT_HIGH_ACT) value |= v_VSYNC_POLARITY(1); HDMIWrReg(EXT_VIDEO_PARA, value); value = mode->left_margin + mode->xres + mode->right_margin + mode->hsync_len; HDMIWrReg(EXT_VIDEO_PARA_HTOTAL_L, value & 0xFF); HDMIWrReg(EXT_VIDEO_PARA_HTOTAL_H, (value >> 8) & 0xFF); value = mode->left_margin + mode->right_margin + mode->hsync_len; HDMIWrReg(EXT_VIDEO_PARA_HBLANK_L, value & 0xFF); HDMIWrReg(EXT_VIDEO_PARA_HBLANK_H, (value >> 8) & 0xFF); value = mode->left_margin + mode->hsync_len; HDMIWrReg(EXT_VIDEO_PARA_HDELAY_L, value & 0xFF); HDMIWrReg(EXT_VIDEO_PARA_HDELAY_H, (value >> 8) & 0xFF); value = mode->hsync_len; HDMIWrReg(EXT_VIDEO_PARA_HSYNCWIDTH_L, value & 0xFF); HDMIWrReg(EXT_VIDEO_PARA_HSYNCWIDTH_H, (value >> 8) & 0xFF); value = mode->upper_margin + mode->yres + mode->lower_margin + mode->vsync_len; HDMIWrReg(EXT_VIDEO_PARA_VTOTAL_L, value & 0xFF); HDMIWrReg(EXT_VIDEO_PARA_VTOTAL_H, (value >> 8) & 0xFF); value = mode->upper_margin + mode->vsync_len + mode->lower_margin; HDMIWrReg(EXT_VIDEO_PARA_VBLANK_L, value & 0xFF); if(vpara->vic == HDMI_720x480p_60Hz_4_3 || vpara->vic == HDMI_720x480p_60Hz_16_9) value = 42; else value = mode->upper_margin + mode->vsync_len; HDMIWrReg(EXT_VIDEO_PARA_VDELAY, value & 0xFF); value = mode->vsync_len; HDMIWrReg(EXT_VIDEO_PARA_VSYNCWIDTH, value & 0xFF); if(vpara->output_mode == OUTPUT_HDMI) { rk30_hdmi_config_avi(vpara->vic, vpara->output_color); hdmi_dbg(hdmi->dev, "[%s] sucess output HDMI.\n", __FUNCTION__); } else { hdmi_dbg(hdmi->dev, "[%s] sucess output DVI.\n", __FUNCTION__); } rk30_hdmi_config_phy(vpara->vic); rk30_hdmi_control_output(0); return 0; }
int rk610_hdmi_sys_config_video(struct hdmi *hdmi, int vic, int input_color, int output_color) { char value; struct fb_videomode *mode; // Diable HDCP if(rk610_hdmi->hdcp_power_off_cb) rk610_hdmi->hdcp_power_off_cb(); // Diable video and audio output HDMIWrReg(AV_MUTE, v_AUDIO_MUTE(1) | v_VIDEO_MUTE(1)); // Input video mode is SDR RGB24bit, Data enable signal from external HDMIWrReg(VIDEO_CONTRL1, v_VIDEO_INPUT_FORMAT(VIDEO_INPUT_SDR_RGB444) | v_DE_EXTERNAL); HDMIWrReg(VIDEO_CONTRL2, v_VIDEO_INPUT_BITS(VIDEO_INPUT_8BITS) | (output_color & 0xFF)); // Set HDMI Mode HDMIWrReg(HDCP_CTRL, v_HDMI_DVI(hdmi->edid.is_hdmi)); // Enable or disalbe color space convert if(input_color != output_color) { value = v_SOF_DISABLE | v_CSC_ENABLE; } else value = v_SOF_DISABLE; HDMIWrReg(VIDEO_CONTRL3, value); #if 1 HDMIWrReg(VIDEO_TIMING_CTL, 0); mode = (struct fb_videomode *)ext_hdmi_vic_to_videomode(vic); if(mode == NULL) { hdmi_dbg(hdmi->dev, "[%s] not found vic %d\n", __FUNCTION__, vic); return -ENOENT; } rk610_hdmi->frequency = mode->pixclock; #else // Set ext video value = v_EXTERANL_VIDEO(1) | v_INETLACE(mode->vmode); if(mode->sync & FB_SYNC_HOR_HIGH_ACT) value |= v_HSYNC_POLARITY(1); if(mode->sync & FB_SYNC_VERT_HIGH_ACT) value |= v_VSYNC_POLARITY(1); HDMIWrReg(VIDEO_TIMING_CTL, value); value = mode->left_margin + mode->xres + mode->right_margin + mode->hsync_len; HDMIWrReg(VIDEO_EXT_HTOTAL_L, value & 0xFF); HDMIWrReg(VIDEO_EXT_HTOTAL_H, (value >> 8) & 0xFF); value = mode->left_margin + mode->right_margin + mode->hsync_len; HDMIWrReg(VIDEO_EXT_HBLANK_L, value & 0xFF); HDMIWrReg(VIDEO_EXT_HBLANK_H, (value >> 8) & 0xFF); value = mode->left_margin + mode->hsync_len; HDMIWrReg(VIDEO_EXT_HDELAY_L, value & 0xFF); HDMIWrReg(VIDEO_EXT_HDELAY_H, (value >> 8) & 0xFF); value = mode->hsync_len; HDMIWrReg(VIDEO_EXT_HDURATION_L, value & 0xFF); HDMIWrReg(VIDEO_EXT_HDURATION_H, (value >> 8) & 0xFF); value = mode->upper_margin + mode->yres + mode->lower_margin + mode->vsync_len; HDMIWrReg(VIDEO_EXT_VTOTAL_L, value & 0xFF); HDMIWrReg(VIDEO_EXT_VTOTAL_H, (value >> 8) & 0xFF); value = mode->upper_margin + mode->vsync_len + mode->lower_margin; HDMIWrReg(VIDEO_EXT_VBLANK, value & 0xFF); value = mode->upper_margin + mode->vsync_len; HDMIWrReg(VIDEO_EXT_VDELAY, value & 0xFF); value = mode->vsync_len; HDMIWrReg(VIDEO_EXT_VDURATION, value & 0xFF); #endif if(hdmi->edid.is_hdmi) { rk610_hdmi_config_avi(vic, output_color); hdmi_dbg(hdmi->dev, "[%s] sucess output HDMI.\n", __FUNCTION__); } else { hdmi_dbg(hdmi->dev, "[%s] sucess output DVI.\n", __FUNCTION__); } // Power on TMDS HDMIWrReg(PHY_PRE_EMPHASIS, v_PRE_EMPHASIS(0) | v_TMDS_PWRDOWN(0)); // TMDS power on // Enable TMDS value = 0; rk610_hdmi_i2c_read_reg(PHY_DRIVER, &value); value |= v_TX_ENABLE(1); HDMIWrReg(PHY_DRIVER, value); return 0; }
static int rk2928_hdmi_config_video(struct hdmi_video_para *vpara) { int value; struct fb_videomode *mode; hdmi_dbg(hdmi->dev, "[%s]\n", __FUNCTION__); if(vpara == NULL) { hdmi_err(hdmi->dev, "[%s] input parameter error\n", __FUNCTION__); return -1; } if(hdmi->hdcp_power_off_cb) hdmi->hdcp_power_off_cb(); // Diable video and audio output HDMIWrReg(AV_MUTE, v_AUDIO_MUTE(1) | v_VIDEO_MUTE(1)); // Input video mode is SDR RGB24bit, Data enable signal from external HDMIWrReg(VIDEO_CONTRL1, v_VIDEO_INPUT_FORMAT(VIDEO_INPUT_SDR_RGB444) | v_DE_EXTERNAL); HDMIWrReg(VIDEO_CONTRL2, v_VIDEO_INPUT_BITS(VIDEO_INPUT_8BITS) | (vpara->output_color & 0xFF)); // Set HDMI Mode HDMIWrReg(HDCP_CTRL, v_HDMI_DVI(vpara->output_mode)); // Enable or disalbe color space convert if(vpara->input_color != vpara->output_color) { value = v_SOF_DISABLE | v_CSC_ENABLE; } else value = v_SOF_DISABLE; HDMIWrReg(VIDEO_CONTRL3, value); // Set ext video #if 1 HDMIWrReg(VIDEO_TIMING_CTL, 0); mode = (struct fb_videomode *)hdmi_vic_to_videomode(vpara->vic); if(mode == NULL) { hdmi_err(hdmi->dev, "[%s] not found vic %d\n", __FUNCTION__, vpara->vic); return -ENOENT; } hdmi->tmdsclk = mode->pixclock; #else value = v_EXTERANL_VIDEO(1) | v_INETLACE(mode->vmode); if(mode->sync & FB_SYNC_HOR_HIGH_ACT) value |= v_HSYNC_POLARITY(1); if(mode->sync & FB_SYNC_VERT_HIGH_ACT) value |= v_VSYNC_POLARITY(1); HDMIWrReg(VIDEO_TIMING_CTL, value); value = mode->left_margin + mode->xres + mode->right_margin + mode->hsync_len; HDMIWrReg(VIDEO_EXT_HTOTAL_L, value & 0xFF); HDMIWrReg(VIDEO_EXT_HTOTAL_H, (value >> 8) & 0xFF); value = mode->left_margin + mode->right_margin + mode->hsync_len; HDMIWrReg(VIDEO_EXT_HBLANK_L, value & 0xFF); HDMIWrReg(VIDEO_EXT_HBLANK_H, (value >> 8) & 0xFF); value = mode->left_margin + mode->hsync_len; HDMIWrReg(VIDEO_EXT_HDELAY_L, value & 0xFF); HDMIWrReg(VIDEO_EXT_HDELAY_H, (value >> 8) & 0xFF); value = mode->hsync_len; HDMIWrReg(VIDEO_EXT_HDURATION_L, value & 0xFF); HDMIWrReg(VIDEO_EXT_HDURATION_H, (value >> 8) & 0xFF); value = mode->upper_margin + mode->yres + mode->lower_margin + mode->vsync_len; HDMIWrReg(VIDEO_EXT_VTOTAL_L, value & 0xFF); HDMIWrReg(VIDEO_EXT_VTOTAL_H, (value >> 8) & 0xFF); value = mode->upper_margin + mode->vsync_len + mode->lower_margin; HDMIWrReg(VIDEO_EXT_VBLANK, value & 0xFF); if(vpara->vic == HDMI_720x480p_60Hz_4_3 || vpara->vic == HDMI_720x480p_60Hz_16_9) value = 42; else value = mode->upper_margin + mode->vsync_len; HDMIWrReg(VIDEO_EXT_VDELAY, value & 0xFF); value = mode->vsync_len; HDMIWrReg(VIDEO_EXT_VDURATION, value & 0xFF); #endif if(vpara->output_mode == OUTPUT_HDMI) { rk2928_hdmi_config_avi(vpara->vic, vpara->output_color); hdmi_dbg(hdmi->dev, "[%s] sucess output HDMI.\n", __FUNCTION__); } else { hdmi_dbg(hdmi->dev, "[%s] sucess output DVI.\n", __FUNCTION__); } return 0; }
static int rk30_load_screen(struct rk_lcdc_device_driver *dev_drv, bool initscreen) { int ret = -EINVAL; struct rk30_lcdc_device *lcdc_dev = container_of(dev_drv,struct rk30_lcdc_device,driver); rk_screen *screen = dev_drv->cur_screen; u64 ft; int fps; u16 face; u16 mcu_total, mcu_rwstart, mcu_csstart, mcu_rwend, mcu_csend; u16 right_margin = screen->right_margin; u16 lower_margin = screen->lower_margin; u16 x_res = screen->x_res, y_res = screen->y_res; // set the rgb or mcu spin_lock(&lcdc_dev->reg_lock); if(likely(lcdc_dev->clk_on)) { if(screen->type==SCREEN_MCU) { lcdc_msk_reg(lcdc_dev, MCU_CTRL, m_MCU_OUTPUT_SELECT,v_MCU_OUTPUT_SELECT(1)); // set out format and mcu timing mcu_total = (screen->mcu_wrperiod*150*1000)/1000000; if(mcu_total>31) mcu_total = 31; if(mcu_total<3) mcu_total = 3; mcu_rwstart = (mcu_total+1)/4 - 1; mcu_rwend = ((mcu_total+1)*3)/4 - 1; mcu_csstart = (mcu_rwstart>2) ? (mcu_rwstart-3) : (0); mcu_csend = (mcu_rwend>15) ? (mcu_rwend-1) : (mcu_rwend); //DBG(1,">> mcu_total=%d, mcu_rwstart=%d, mcu_csstart=%d, mcu_rwend=%d, mcu_csend=%d \n", // mcu_total, mcu_rwstart, mcu_csstart, mcu_rwend, mcu_csend); // set horizontal & vertical out timing right_margin = x_res/6; screen->pixclock = 150000000; //mcu fix to 150 MHz lcdc_msk_reg(lcdc_dev, MCU_CTRL,m_MCU_CS_ST | m_MCU_CS_END| m_MCU_RW_ST | m_MCU_RW_END | m_MCU_WRITE_PERIOD | m_MCU_HOLDMODE_SELECT | m_MCU_HOLDMODE_FRAME_ST, v_MCU_CS_ST(mcu_csstart) | v_MCU_CS_END(mcu_csend) | v_MCU_RW_ST(mcu_rwstart) | v_MCU_RW_END(mcu_rwend) | v_MCU_WRITE_PERIOD(mcu_total) | v_MCU_HOLDMODE_SELECT((SCREEN_MCU==screen->type)?(1):(0)) | v_MCU_HOLDMODE_FRAME_ST(0)); } switch (screen->face) { case OUT_P565: face = OUT_P565; lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_DITHER_DOWN_EN | m_DITHER_DOWN_MODE, v_DITHER_DOWN_EN(1) | v_DITHER_DOWN_MODE(0)); break; case OUT_P666: face = OUT_P666; lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_DITHER_DOWN_EN | m_DITHER_DOWN_MODE, v_DITHER_DOWN_EN(1) | v_DITHER_DOWN_MODE(1)); break; case OUT_D888_P565: face = OUT_P888; lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_DITHER_DOWN_EN | m_DITHER_DOWN_MODE, v_DITHER_DOWN_EN(1) | v_DITHER_DOWN_MODE(0)); break; case OUT_D888_P666: face = OUT_P888; lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_DITHER_DOWN_EN | m_DITHER_DOWN_MODE, v_DITHER_DOWN_EN(1) | v_DITHER_DOWN_MODE(1)); break; case OUT_P888: face = OUT_P888; lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_DITHER_UP_EN, v_DITHER_UP_EN(1)); lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_DITHER_DOWN_EN | m_DITHER_DOWN_MODE, v_DITHER_DOWN_EN(0) | v_DITHER_DOWN_MODE(0)); break; default: lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_DITHER_UP_EN, v_DITHER_UP_EN(0)); lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_DITHER_DOWN_EN | m_DITHER_DOWN_MODE, v_DITHER_DOWN_EN(0) | v_DITHER_DOWN_MODE(0)); face = screen->face; break; } //use default overlay,set vsyn hsync den dclk polarity lcdc_msk_reg(lcdc_dev, DSP_CTRL0,m_DISPLAY_FORMAT | m_HSYNC_POLARITY | m_VSYNC_POLARITY | m_DEN_POLARITY |m_DCLK_POLARITY,v_DISPLAY_FORMAT(face) | v_HSYNC_POLARITY(screen->pin_hsync) | v_VSYNC_POLARITY(screen->pin_vsync) | v_DEN_POLARITY(screen->pin_den) | v_DCLK_POLARITY(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_OUTPUT_RB_SWAP | m_OUTPUT_RG_SWAP | m_DELTA_SWAP | m_DUMMY_SWAP | m_BLANK_MODE,v_BG_COLOR(0x000000) | v_OUTPUT_RB_SWAP(screen->swap_rb) | v_OUTPUT_RG_SWAP(screen->swap_rg) | v_DELTA_SWAP(screen->swap_delta) | v_DUMMY_SWAP(screen->swap_dumy) | v_BLACK_MODE(0)); lcdc_writel(lcdc_dev, DSP_HTOTAL_HS_END,v_HSYNC(screen->hsync_len) | v_HORPRD(screen->hsync_len + screen->left_margin + x_res + right_margin)); lcdc_writel(lcdc_dev, DSP_HACT_ST_END, v_HAEP(screen->hsync_len + screen->left_margin + x_res) | v_HASP(screen->hsync_len + screen->left_margin)); lcdc_writel(lcdc_dev, DSP_VTOTAL_VS_END, v_VSYNC(screen->vsync_len) | v_VERPRD(screen->vsync_len + screen->upper_margin + y_res + lower_margin)); lcdc_writel(lcdc_dev, DSP_VACT_ST_END, v_VAEP(screen->vsync_len + screen->upper_margin+y_res)| v_VASP(screen->vsync_len + screen->upper_margin)); // let above to take effect lcdc_cfg_done(lcdc_dev); } spin_unlock(&lcdc_dev->reg_lock); ret = clk_set_rate(lcdc_dev->dclk, screen->pixclock); if(ret) { printk(KERN_ERR ">>>>>> 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)); ft = (u64)(screen->upper_margin + screen->lower_margin + screen->y_res +screen->vsync_len)* (screen->left_margin + screen->right_margin + screen->x_res + screen->hsync_len)* (dev_drv->pixclock); // one frame time ,(pico seconds) fps = div64_u64(1000000000000llu,ft); 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(); } printk("%s for lcdc%d ok!\n",__func__,lcdc_dev->id); return 0; }