From e2d44970fa71a1413cd3907f5b51aaa2f34f7611 Mon Sep 17 00:00:00 2001 From: xuhuicong Date: Fri, 28 Jun 2013 14:54:55 +0800 Subject: [PATCH] hdmi: rk616: set hdmi polarity invent and time sequence when switch fb resolution to modify display shake --- .../rockchip/hdmi/chips/rk616/rk616_hdmi_hw.c | 50 +++++++++++++++++-- .../rockchip/hdmi/chips/rk616/rk616_hdmi_hw.h | 9 ++-- drivers/video/rockchip/hdmi/rk_hdmi_lcdc.c | 7 +++ drivers/video/rockchip/hdmi/rk_hdmi_task.c | 4 +- 4 files changed, 59 insertions(+), 11 deletions(-) diff --git a/drivers/video/rockchip/hdmi/chips/rk616/rk616_hdmi_hw.c b/drivers/video/rockchip/hdmi/chips/rk616/rk616_hdmi_hw.c index 0c2c24817f2e..55eb1ad9dcb1 100755 --- a/drivers/video/rockchip/hdmi/chips/rk616/rk616_hdmi_hw.c +++ b/drivers/video/rockchip/hdmi/chips/rk616/rk616_hdmi_hw.c @@ -113,7 +113,7 @@ int rk616_hdmi_detect_hotplug(void) #define DDC_BUS_FREQ_H 0x4c #define EDID_BLOCK_SIZE 128 -int rk616_hdmi_read_edid(u8 block, u8 * buf) +int rk616_hdmi_read_edid(int block, u8 * buf) { u32 c = 0; int ret = 0,i; @@ -185,16 +185,57 @@ static void rk616_hdmi_config_avi(unsigned char vic, unsigned char output_color) HDMIWrReg(CONTROL_PACKET_ADDR + i, info[i]); } + +static int rk616_set_polarity(struct mfd_rk616 * rk616, int vic) +{ + u32 val; + int ret; + u32 hdmi_polarity_mask = (3<<14); + switch(vic) + { + + case HDMI_1920x1080p_60Hz: + case HDMI_1920x1080p_50Hz: + case HDMI_1920x1080i_60Hz: + case HDMI_1920x1080i_50Hz: + case HDMI_1280x720p_60Hz: + case HDMI_1280x720p_50Hz: + val = 0xc000; + ret = rk616->write_dev_bits(rk616, CRU_CFGMISC_CON, hdmi_polarity_mask, &val); + break; + + case HDMI_720x576p_50Hz_4_3: + case HDMI_720x576p_50Hz_16_9: + case HDMI_720x480p_60Hz_4_3: + case HDMI_720x480p_60Hz_16_9: + val = 0x0; + ret = rk616->write_dev_bits(rk616, CRU_CFGMISC_CON, hdmi_polarity_mask, &val); + break; + default: + val = 0x0; + ret = rk616->write_dev_bits(rk616, CRU_CFGMISC_CON, hdmi_polarity_mask, &val); + break; + } + return ret; +} + static int rk616_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 == LOWER_PWR) { + rk616_hdmi_set_pwr_mode(NORMAL); + } + + vpara->output_color = VIDEO_OUTPUT_RGB444; if(hdmi->hdcp_power_off_cb) hdmi->hdcp_power_off_cb(); @@ -267,8 +308,9 @@ static int rk616_hdmi_config_video(struct hdmi_video_para *vpara) value = mode->vsync_len; HDMIWrReg(VIDEO_EXT_VDURATION, value & 0xFF); #endif - - if(vpara->output_mode == OUTPUT_HDMI) { + rk616_set_polarity(g_rk616_hdmi, vpara->vic); + + if(vpara->output_mode == OUTPUT_HDMI) { rk616_hdmi_config_avi(vpara->vic, vpara->output_color); hdmi_dbg(hdmi->dev, "[%s] sucess output HDMI.\n", __FUNCTION__); } @@ -426,7 +468,7 @@ int rk616_hdmi_removed(void) void rk616_hdmi_work(void) { u32 interrupt = 0; - int value = 0; + // int value = 0; HDMIRdReg(INTERRUPT_STATUS1,&interrupt); if(interrupt){ diff --git a/drivers/video/rockchip/hdmi/chips/rk616/rk616_hdmi_hw.h b/drivers/video/rockchip/hdmi/chips/rk616/rk616_hdmi_hw.h index 6b8d63b31d2a..ac3af6d8ea73 100755 --- a/drivers/video/rockchip/hdmi/chips/rk616/rk616_hdmi_hw.h +++ b/drivers/video/rockchip/hdmi/chips/rk616/rk616_hdmi_hw.h @@ -280,14 +280,11 @@ enum { g_rk616_hdmi->write_dev(g_rk616_hdmi,(RK616_HDMI_BASE + ((addr)<<2)),&temp); \ }while(0) + #define HDMIMskReg(addr,Msk,val) do{ \ - u32 tkv = 0;\ - u32 temp=0; \ - HDMIRdReg(addr,&temp); \ - tkv = ((val)&(Msk))|(temp&(~Msk)); \ - HDMIWrReg(addr,tkv); \ + u32 temp = val; \ + g_rk616_hdmi->write_dev_bits(g_rk616_hdmi, (RK616_HDMI_BASE + ((addr)<<2)), Msk, &temp); \ }while(0) - extern struct mfd_rk616 *g_rk616_hdmi; extern int rk616_hdmi_initial(void); diff --git a/drivers/video/rockchip/hdmi/rk_hdmi_lcdc.c b/drivers/video/rockchip/hdmi/rk_hdmi_lcdc.c index e20be70c7a7e..d2f1bef1e1b5 100755 --- a/drivers/video/rockchip/hdmi/rk_hdmi_lcdc.c +++ b/drivers/video/rockchip/hdmi/rk_hdmi_lcdc.c @@ -107,6 +107,10 @@ int hdmi_set_info(struct rk29fb_screen *screen, unsigned int vic) screen->hdmi_resolution = hdmi_mode[i].flag; /* Pin polarity */ +#ifdef CONFIG_HDMI_RK616 + screen->pin_hsync = 0; + screen->pin_vsync = 0; +#else if(FB_SYNC_HOR_HIGH_ACT & hdmi_mode[i].sync) screen->pin_hsync = 1; else @@ -115,6 +119,7 @@ int hdmi_set_info(struct rk29fb_screen *screen, unsigned int vic) screen->pin_vsync = 1; else screen->pin_vsync = 0; +#endif screen->pin_den = 0; screen->pin_dclk = DCLK_POL; @@ -509,6 +514,8 @@ int hdmi_switch_fb(struct hdmi *hdmi, int vic) rc = hdmi_set_info(screen, hdmi->vic); if(rc == 0) { + if(hdmi->set_vif) + hdmi->set_vif(screen,0); //turn off vif for jettab rk_fb_switch_screen(screen, 1, hdmi->lcdc->id); rk_fb_disp_scale(hdmi->xscale, hdmi->yscale, hdmi->lcdc->id); if(hdmi->set_vif) diff --git a/drivers/video/rockchip/hdmi/rk_hdmi_task.c b/drivers/video/rockchip/hdmi/rk_hdmi_task.c index df2926a10756..f9f6970e170c 100755 --- a/drivers/video/rockchip/hdmi/rk_hdmi_task.c +++ b/drivers/video/rockchip/hdmi/rk_hdmi_task.c @@ -234,7 +234,9 @@ void hdmi_work(struct work_struct *work) } break; case SYSTEM_CONFIG: - // hdmi->remove(); + #ifdef ONFIG_HDMI_RK616 + hdmi->remove(); + #endif if(hdmi->autoconfig) hdmi->vic = hdmi_find_best_mode(hdmi, 0); else -- 2.34.1