From: yxj Date: Sat, 8 Sep 2012 07:24:43 +0000 (+0800) Subject: rename rk610 lvds config X-Git-Tag: firefly_0821_release~8689 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=f421e972315429ce74e22052ebff41bd4dc1658a;p=firefly-linux-kernel-4.4.55.git rename rk610 lvds config --- diff --git a/drivers/mfd/rk610-core.c b/drivers/mfd/rk610-core.c index e83f2de8823e..daad513a74c8 100755 --- a/drivers/mfd/rk610-core.c +++ b/drivers/mfd/rk610-core.c @@ -28,7 +28,7 @@ #endif static struct i2c_client *rk610_control_client = NULL; -#ifdef CONFIG_RK610_LCD +#ifdef CONFIG_RK610_LVDS extern int rk610_lcd_init(struct rk610_core_info *rk610_core_info); #else int rk610_lcd_init(struct rk610_core_info *rk610_core_info){} diff --git a/drivers/video/display/Kconfig b/drivers/video/display/Kconfig index 98ea0494b6bb..8e8219538e26 100644 --- a/drivers/video/display/Kconfig +++ b/drivers/video/display/Kconfig @@ -22,7 +22,7 @@ config DISPLAY_SUPPORT comment "Display hardware drivers" depends on DISPLAY_SUPPORT source "drivers/video/display/screen/Kconfig" -source "drivers/video/display/lcd/Kconfig" +source "drivers/video/display/transmitter/Kconfig" source "drivers/video/display/tve/Kconfig" endmenu diff --git a/drivers/video/display/Makefile b/drivers/video/display/Makefile index ad3bc7ff7c72..e1e7f14254ba 100644 --- a/drivers/video/display/Makefile +++ b/drivers/video/display/Makefile @@ -4,5 +4,5 @@ display-objs := display-sys.o obj-$(CONFIG_DISPLAY_SUPPORT) += display.o obj-$(CONFIG_DISPLAY_SUPPORT) += screen/ -obj-y += lcd/ -obj-y += tve/ \ No newline at end of file +obj-y += transmitter/ +obj-y += tve/ diff --git a/drivers/video/display/lcd/Kconfig b/drivers/video/display/lcd/Kconfig deleted file mode 100644 index 3d15a66d7974..000000000000 --- a/drivers/video/display/lcd/Kconfig +++ /dev/null @@ -1,6 +0,0 @@ -config RK610_LCD - bool "RK610(Jetta) lcd support" - depends on MFD_RK610 - default y if MFD_RK610 - help - Support Jetta(RK610) to output LCD1 and LVDS. diff --git a/drivers/video/display/lcd/Makefile b/drivers/video/display/lcd/Makefile deleted file mode 100644 index a124d84e794f..000000000000 --- a/drivers/video/display/lcd/Makefile +++ /dev/null @@ -1,4 +0,0 @@ -# -# Makefile for the jetta tv control. -# -obj-$(CONFIG_RK610_LCD) += rk610_lcd.o diff --git a/drivers/video/display/lcd/rk610_lcd.c b/drivers/video/display/lcd/rk610_lcd.c deleted file mode 100644 index 9ffac8db2654..000000000000 --- a/drivers/video/display/lcd/rk610_lcd.c +++ /dev/null @@ -1,414 +0,0 @@ -#include -#include -#include -#include -#include - -#include -#include "rk610_lcd.h" -#include -#include "../../rk29_fb.h" -static struct rk610_lcd_info *g_lcd_inf = NULL; -//static int rk610_scaler_read_p0_reg(struct i2c_client *client, char reg, char *val) -//{ - //return i2c_master_reg8_recv(client, reg, val, 1, 100*1000) > 0? 0: -EINVAL; -//} - -static int rk610_scaler_write_p0_reg(struct i2c_client *client, char reg, char *val) -{ - return i2c_master_reg8_send(client, reg, val, 1, 100*1000) > 0? 0: -EINVAL; -} -static void rk610_scaler_pll_enable(struct i2c_client *client) -{ - char c; - RK610_DBG(&client->dev,"%s \n",__FUNCTION__); - - g_lcd_inf->scl_inf.pll_pwr = ENABLE; - - c = S_PLL_PWR(0)|S_PLL_RESET(0)|S_PLL_BYPASS(0); - rk610_scaler_write_p0_reg(client, S_PLL_CON2, &c); -} -static void rk610_scaler_pll_disable(struct i2c_client *client) -{ - char c; - RK610_DBG(&client->dev,"%s \n",__FUNCTION__); - - g_lcd_inf->scl_inf.pll_pwr = DISABLE; - - c = S_PLL_PWR(1) |S_PLL_RESET(0) |S_PLL_BYPASS(1); - rk610_scaler_write_p0_reg(client, S_PLL_CON2, &c); -} -static void rk610_scaler_enable(struct i2c_client *client) -{ - char c; - bool den_inv = 0,hv_sync_inv = 0,clk_inv = 0; - RK610_DBG(&client->dev,"%s \n",__FUNCTION__); - g_lcd_inf->scl_inf.scl_pwr = ENABLE; - #ifdef CONFIG_HDMI_DUAL_DISP - if(g_lcd_inf->screen !=NULL){ - den_inv = g_lcd_inf->screen->s_den_inv; - hv_sync_inv = g_lcd_inf->screen->s_hv_sync_inv; - clk_inv = g_lcd_inf->screen->s_clk_inv; - } - #endif - c= SCL_BYPASS(0) |SCL_DEN_INV(den_inv) |SCL_H_V_SYNC_INV(hv_sync_inv) |SCL_OUT_CLK_INV(clk_inv) |SCL_ENABLE(ENABLE); - rk610_scaler_write_p0_reg(client, SCL_CON0, &c); -} -static void rk610_scaler_disable(struct i2c_client *client) -{ - char c; - bool den_inv = 0,hv_sync_inv = 0,clk_inv = 0; - RK610_DBG(&client->dev,"%s \n",__FUNCTION__); - - g_lcd_inf->scl_inf.scl_pwr = DISABLE; - #ifdef CONFIG_HDMI_DUAL_DISP - if(g_lcd_inf->screen !=NULL){ - den_inv = g_lcd_inf->screen->s_den_inv; - hv_sync_inv = g_lcd_inf->screen->s_hv_sync_inv; - clk_inv = g_lcd_inf->screen->s_clk_inv; - } - #endif - c= SCL_BYPASS(1) |SCL_DEN_INV(den_inv) |SCL_H_V_SYNC_INV(hv_sync_inv) |SCL_OUT_CLK_INV(clk_inv) |SCL_ENABLE(DISABLE); - rk610_scaler_write_p0_reg(client, SCL_CON0, &c); -} - -static int rk610_output_config(struct i2c_client *client,struct rk29fb_screen *screen,int mode) -{ - char c=0; - RK610_DBG(&client->dev,"%s \n",__FUNCTION__); - if(SCREEN_LVDS == screen->type){ - if(mode == LCD_OUT_SCL || mode == LCD_OUT_BYPASS){ - c = LVDS_OUT_CLK_PIN(0) |LVDS_OUT_CLK_PWR_PIN(1) |LVDS_PLL_PWR_PIN(0) \ - |LVDS_LANE_IN_FORMAT(DATA_D0_MSB) |LVDS_INPUT_SOURCE(FROM_LCD0_OR_SCL) \ - |LVDS_OUTPUT_FORMAT(screen->hw_format) | LVDS_BIASE_PWR(1); - rk610_scaler_write_p0_reg(client, LVDS_CON0, &c); - c = LVDS_OUT_ENABLE(0x0) |LVDS_TX_PWR_ENABLE(0x0); - rk610_scaler_write_p0_reg(client, LVDS_CON1, &c); - } - else{ - c = LVDS_OUT_CLK_PIN(0) |LVDS_OUT_CLK_PWR_PIN(0) |LVDS_PLL_PWR_PIN(1) \ - |LVDS_LANE_IN_FORMAT(DATA_D0_MSB) |LVDS_INPUT_SOURCE(FROM_LCD0_OR_SCL) \ - |LVDS_OUTPUT_FORMAT(screen->hw_format) | LVDS_BIASE_PWR(0); - rk610_scaler_write_p0_reg(client, LVDS_CON0, &c); - c = LVDS_OUT_ENABLE(0xf) |LVDS_TX_PWR_ENABLE(0xf); - rk610_scaler_write_p0_reg(client, LVDS_CON1, &c); - - } - }else if(SCREEN_RGB == screen->type){ - if(mode == LCD_OUT_SCL || mode == LCD_OUT_BYPASS){ - c = LCD1_OUT_ENABLE(LCD1_AS_OUT) | LCD1_OUT_SRC((mode == LCD_OUT_SCL)?LCD1_FROM_SCL : LCD1_FROM_LCD0); - rk610_scaler_write_p0_reg(client, LCD1_CON, &c); - } - else { - c = LCD1_OUT_ENABLE(LCD1_AS_IN); - rk610_scaler_write_p0_reg(client, LCD1_CON, &c); - } - } - return 0; -} -#ifdef CONFIG_HDMI_DUAL_DISP -static int rk610_scaler_pll_set(struct i2c_client *client,struct rk29fb_screen *screen,u32 clkin ) -{ - char c=0; - char M=0,N=0,OD=0; - RK610_DBG(&client->dev,"%s \n",__FUNCTION__); - /***************SET SCALER PLL FROM CLKIN ,DIV 0*/ - if(screen->s_pixclock != 0){ - OD = (screen->s_pixclock)&0x3; - N = (screen->s_pixclock >>4)&0xf; - M = (screen->s_pixclock >>8)&0xff; - }else { - RK610_ERR(&client->dev,"RK610 Scaler pll not support rate \n"); - } - c = S_PLL_FROM_DIV<<3 | S_PLL_DIV(0); - rk610_scaler_write_p0_reg(client, CLOCK_CON0, &c); - - c = S_DIV_N(N)| S_DIV_OD(OD); - rk610_scaler_write_p0_reg(client, S_PLL_CON0, &c); - c = S_DIV_M(M); - rk610_scaler_write_p0_reg(client, S_PLL_CON1, &c); - rk610_scaler_pll_enable(client); - return 0; -} - - -static int scale_hv_factor(struct i2c_client *client ,u32 Hin_act, u32 Hout_act, u32 Vin_act, u32 Vout_act) - { - char c; - u32 hfactor_f,vfactor_f,scl_factor_f; - int hfactor; - int vfactor; - struct scl_hv_info HV2; - hfactor_f = ((Hin_act-1)*4096)/(Hout_act-1); - if(hfactor_f==4096) - {hfactor = 0x1000;} - else if(hfactor_f>(int)hfactor_f) - {hfactor = (int)hfactor_f+1;} - else - {hfactor = (int)hfactor_f;} - - scl_factor_f = Vin_act/Vout_act; - if(scl_factor_f<2) - {vfactor_f = ((Vin_act-1)*4096)/(Vout_act-1);} - else - {vfactor_f = ((Vin_act-2)*4096)/(Vout_act-1);} - if(vfactor_f==4096) - {vfactor = 0x1000;} - else if(vfactor_f>(int)vfactor_f) - {vfactor = (int)vfactor_f+1;} - else - {vfactor = (int)vfactor_f;} - - HV2.scl_h= hfactor; - HV2.scl_v= vfactor; - /* SCL FACTOR */ - c = SCL_H_FACTOR_LSB(HV2.scl_h); - rk610_scaler_write_p0_reg(client, SCL_CON1, &c); - c = SCL_H_FACTOR_MSB(HV2.scl_h); - rk610_scaler_write_p0_reg(client, SCL_CON2, &c); - - c = SCL_V_FACTOR_LSB(HV2.scl_v); - rk610_scaler_write_p0_reg(client, SCL_CON3, &c); - c = SCL_V_FACTOR_MSB(HV2.scl_v); - rk610_scaler_write_p0_reg(client, SCL_CON4, &c); - return 0; - } - -static int rk610_scaler_fator_config(struct i2c_client *client ,struct rk29fb_screen *screen) -{ - switch(screen->hdmi_resolution){ - case HDMI_1920x1080p_60Hz: - case HDMI_1920x1080p_50Hz: - rk610_scaler_pll_set(client,screen,148500000); - /***************set scaler factor********************/ - scale_hv_factor(client,1920,screen->x_res,1080,screen->y_res); - break; - case HDMI_1280x720p_60Hz: - case HDMI_1280x720p_50Hz: - rk610_scaler_pll_set(client,screen,74250000); - /***************set scaler factor********************/ - scale_hv_factor(client,1280,screen->x_res,720,screen->y_res); - break; - case HDMI_720x576p_50Hz_16x9: - case HDMI_720x576p_50Hz_4x3: - rk610_scaler_pll_set(client,screen,27000000); - /***************set scaler factor********************/ - scale_hv_factor(client,720,screen->x_res,576,screen->y_res); - break; - case HDMI_720x480p_60Hz_16x9: - case HDMI_720x480p_60Hz_4x3: - rk610_scaler_pll_set(client,screen,27000000); - /***************set scaler factor********************/ - scale_hv_factor(client,720,screen->x_res,480,screen->y_res); - break; - default : - RK610_ERR(&client->dev,"RK610 not support dual display at hdmi resolution=%d \n",screen->hdmi_resolution); - return -1; - break; - } - return 0; -} -static int rk610_scaler_output_timing_config(struct i2c_client *client,struct rk29fb_screen *screen) -{ - char c; - int h_st = screen->s_hsync_st; - int hs_end = screen->s_hsync_len; - int h_act_st = hs_end + screen->s_left_margin; - int xres = screen->x_res; - int h_act_end = h_act_st + xres; - int h_total = h_act_end + screen->s_right_margin; - int v_st = screen->s_vsync_st; - int vs_end = screen->s_vsync_len; - int v_act_st = vs_end + screen->s_upper_margin; - int yres = screen->y_res; - int v_act_end = v_act_st + yres; - int v_total = v_act_end + screen->s_lower_margin; - - /* SCL display Frame start point */ - c = SCL_DSP_HST_LSB(h_st); - rk610_scaler_write_p0_reg(client, SCL_CON5, &c); - c = SCL_DSP_HST_MSB(h_st); - rk610_scaler_write_p0_reg(client, SCL_CON6, &c); - - c = SCL_DSP_VST_LSB(v_st); - rk610_scaler_write_p0_reg(client, SCL_CON7, &c); - c = SCL_DSP_VST_MSB(v_st); - rk610_scaler_write_p0_reg(client, SCL_CON8, &c); - /* SCL output timing */ - - c = SCL_DSP_HTOTAL_LSB(h_total); - rk610_scaler_write_p0_reg(client, SCL_CON9, &c); - c = SCL_DSP_HTOTAL_MSB(h_total); - rk610_scaler_write_p0_reg(client, SCL_CON10, &c); - - c = SCL_DSP_HS_END(hs_end); - rk610_scaler_write_p0_reg(client, SCL_CON11, &c); - - c = SCL_DSP_HACT_ST_LSB(h_act_st); - rk610_scaler_write_p0_reg(client, SCL_CON12, &c); - c = SCL_DSP_HACT_ST_MSB(h_act_st); - rk610_scaler_write_p0_reg(client, SCL_CON13, &c); - - c = SCL_DSP_HACT_END_LSB(h_act_end); - rk610_scaler_write_p0_reg(client, SCL_CON14, &c); - c = SCL_DSP_HACT_END_MSB(h_act_end); - rk610_scaler_write_p0_reg(client, SCL_CON15, &c); - - c = SCL_DSP_VTOTAL_LSB(v_total); - rk610_scaler_write_p0_reg(client, SCL_CON16, &c); - c = SCL_DSP_VTOTAL_MSB(v_total); - rk610_scaler_write_p0_reg(client, SCL_CON17, &c); - - c = SCL_DSP_VS_END(vs_end); - rk610_scaler_write_p0_reg(client, SCL_CON18, &c); - - c = SCL_DSP_VACT_ST(v_act_st); - rk610_scaler_write_p0_reg(client, SCL_CON19, &c); - - c = SCL_DSP_VACT_END_LSB(v_act_end); - rk610_scaler_write_p0_reg(client, SCL_CON20, &c); - c = SCL_DSP_VACT_END_MSB(v_act_end); - rk610_scaler_write_p0_reg(client, SCL_CON21, &c); - - c = SCL_H_BORD_ST_LSB(h_act_st); - rk610_scaler_write_p0_reg(client, SCL_CON22, &c); - c = SCL_H_BORD_ST_MSB(h_act_st); - rk610_scaler_write_p0_reg(client, SCL_CON23, &c); - - c = SCL_H_BORD_END_LSB(h_act_end); - rk610_scaler_write_p0_reg(client, SCL_CON24, &c); - c = SCL_H_BORD_END_MSB(h_act_end); - rk610_scaler_write_p0_reg(client, SCL_CON25, &c); - - c = SCL_V_BORD_ST(v_act_st); - rk610_scaler_write_p0_reg(client, SCL_CON26, &c); - - c = SCL_V_BORD_END_LSB(v_act_end); - rk610_scaler_write_p0_reg(client, SCL_CON27, &c); - c = SCL_V_BORD_END_MSB(v_act_end); - rk610_scaler_write_p0_reg(client, SCL_CON28, &c); - - return 0; -} -static int rk610_scaler_chg(struct i2c_client *client ,struct rk29fb_screen *screen) -{ - - RK610_DBG(&client->dev,"%s screen->hdmi_resolution=%d\n",__FUNCTION__,screen->hdmi_resolution); - rk610_scaler_fator_config(client,screen); - rk610_scaler_enable(client); - rk610_scaler_output_timing_config(client,screen); - - return 0; - -} -#endif -static int rk610_lcd_scaler_bypass(struct i2c_client *client,bool enable)//enable:0 bypass 1: scale -{ - RK610_DBG(&client->dev,"%s \n",__FUNCTION__); - - rk610_scaler_disable(client); - rk610_scaler_pll_disable(client); - - return 0; -} - -#ifdef CONFIG_HAS_EARLYSUSPEND -static void rk610_lcd_early_suspend(struct early_suspend *h) -{ - struct i2c_client *client = g_lcd_inf->client; - char c; - RK610_DBG(&client->dev,"%s \n",__FUNCTION__); - if(g_lcd_inf->screen != NULL){ - rk610_output_config(client,g_lcd_inf->screen,LCD_OUT_DISABLE); - } - - if(ENABLE == g_lcd_inf->scl_inf.scl_pwr){ - c= SCL_BYPASS(1) |SCL_DEN_INV(0) |SCL_H_V_SYNC_INV(0) |SCL_OUT_CLK_INV(0) |SCL_ENABLE(DISABLE); - rk610_scaler_write_p0_reg(client, SCL_CON0, &c); - } - if(ENABLE == g_lcd_inf->scl_inf.pll_pwr ){ - c = S_PLL_PWR(1) |S_PLL_RESET(0) |S_PLL_BYPASS(1); - rk610_scaler_write_p0_reg(client, S_PLL_CON2, &c); - } -} - -static void rk610_lcd_early_resume(struct early_suspend *h) -{ - struct i2c_client *client = g_lcd_inf->client; - char c; - RK610_DBG(&client->dev,"%s \n",__FUNCTION__); - - if(g_lcd_inf->screen != NULL){ - rk610_output_config(client,g_lcd_inf->screen,g_lcd_inf->disp_mode); - } - if(ENABLE == g_lcd_inf->scl_inf.scl_pwr){ - c= SCL_BYPASS(0) |SCL_DEN_INV(0) |SCL_H_V_SYNC_INV(0) |SCL_OUT_CLK_INV(0) |SCL_ENABLE(ENABLE); - rk610_scaler_write_p0_reg(client, SCL_CON0, &c); - } - if(ENABLE == g_lcd_inf->scl_inf.pll_pwr ){ - c = S_PLL_PWR(1) |S_PLL_RESET(0) |S_PLL_BYPASS(1); - rk610_scaler_write_p0_reg(client, S_PLL_CON2, &c); - } -} -#endif -int rk610_lcd_scaler_set_param(struct rk29fb_screen *screen,bool enable )//enable:0 bypass 1: scale -{ - int ret=0; - struct i2c_client *client = g_lcd_inf->client; - if(client == NULL){ - printk("%s client == NULL FAIL\n",__FUNCTION__); - return -1; - } - if(screen == NULL){ - printk("%s screen == NULL FAIL\n",__FUNCTION__); - return -1; - } - RK610_DBG(&client->dev,"%s \n",__FUNCTION__); - - g_lcd_inf->screen = screen; - -#ifdef CONFIG_HDMI_DUAL_DISP - if(enable == 1){ - g_lcd_inf->disp_mode = LCD_OUT_SCL; - rk610_output_config(client,screen,LCD_OUT_SCL); - ret = rk610_scaler_chg(client,screen); - } - else -#endif - { - g_lcd_inf->disp_mode = LCD_OUT_BYPASS; - rk610_output_config(client,screen,LCD_OUT_BYPASS); - ret = rk610_lcd_scaler_bypass(client,enable); - } - return ret; -} -int rk610_lcd_init(struct rk610_core_info *rk610_core_info) -{ - if(rk610_core_info->client == NULL){ - printk("%s client == NULL FAIL\n",__FUNCTION__); - return -1; - } - RK610_DBG(&rk610_core_info->client->dev,"%s \n",__FUNCTION__); - - g_lcd_inf = kmalloc(sizeof(struct rk610_lcd_info), GFP_KERNEL); - if(!g_lcd_inf) - { - dev_err(&rk610_core_info->client->dev, ">> rk610 inf kmalloc fail!"); - return -ENOMEM; - } - memset(g_lcd_inf, 0, sizeof(struct rk610_lcd_info)); - - g_lcd_inf->client= rk610_core_info->client; - - rk610_core_info->lcd_pdata = (void *)g_lcd_inf; -#ifdef CONFIG_HAS_EARLYSUSPEND - g_lcd_inf->early_suspend.suspend = rk610_lcd_early_suspend; - g_lcd_inf->early_suspend.resume = rk610_lcd_early_resume; - g_lcd_inf->early_suspend.level = EARLY_SUSPEND_LEVEL_DISABLE_FB- 1; - register_early_suspend(&g_lcd_inf->early_suspend); -#endif - g_lcd_inf->scl_inf.pll_pwr = DISABLE; - g_lcd_inf->scl_inf.scl_pwr = DISABLE; - g_lcd_inf->disp_mode = LCD_OUT_BYPASS; - return 0; -} diff --git a/drivers/video/display/lcd/rk610_lcd.h b/drivers/video/display/lcd/rk610_lcd.h deleted file mode 100644 index 8cdeef6e1fa8..000000000000 --- a/drivers/video/display/lcd/rk610_lcd.h +++ /dev/null @@ -1,214 +0,0 @@ -#ifndef _RK610_LCD_H -#define _RK610_LCD_H -#include -#include "../screen/screen.h" -#include -#define ENABLE 1 -#define DISABLE 0 - -/* LVDS config */ -/* LVDS ÍⲿÁ¬Ïß½Ó·¨ */ -/* LVDS_8BIT_1 LVDS_8BIT_2 LVDS_8BIT_3 LVDS_6BIT ----------------------------------------------------------------------- - TX0 R0 R2 R2 R0 - TX1 R1 R3 R3 R1 - TX2 R2 R4 R4 R2 -Y TX3 R3 R5 R5 R3 -0 TX4 R4 R6 R6 R4 - TX6 R5 R7 R7 R5 - TX7 G0 G2 G2 G0 ----------------------------------------------------------------------- - TX8 G1 G3 G3 G1 - TX9 G2 G4 G4 G2 -Y TX12 G3 G5 G5 G3 -1 TX13 G4 G6 G6 G4 - TX14 G5 G7 G7 G5 - TX15 B0 B2 B2 B0 - TX18 B1 B3 B3 B1 ----------------------------------------------------------------------- - TX19 B2 B4 B4 B2 - TX20 B3 B5 B5 B3 - TX21 B4 B6 B6 B4 -Y TX22 B5 B7 B7 B5 -2 TX24 HSYNC HSYNC HSYNC HSYNC - TX25 VSYNC VSYNC VSYNC VSYNC - TX26 ENABLE ENABLE ENABLE ENABLE ----------------------------------------------------------------------- - TX27 R6 R0 GND GND - TX5 R7 R1 GND GND - TX10 G6 G0 GND GND -Y TX11 G7 G1 GND GND -3 TX16 B6 B0 GND GND - TX17 B7 B1 GND GND - TX23 RSVD RSVD RSVD RSVD ----------------------------------------------------------------------- -*/ -#define LVDS_8BIT_1 0x00 -#define LVDS_8BIT_2 0x01 -#define LVDS_8BIT_3 0x10 -#define LVDS_6BIT 0x11 -//LVDS lane input format -#define DATA_D0_MSB 0 -#define DATA_D7_MSB 1 -//LVDS input source -#define FROM_LCD1 0 -#define FROM_LCD0_OR_SCL 1 - -/* LCD1 config */ -#define LCD1_AS_IN 0 -#define LCD1_AS_OUT 1 - -//LCD1 output source -#define LCD1_FROM_LCD0 0 -#define LCD1_FROM_SCL 1 - -//SCALER config -#define NOBYPASS 0 -#define BYPASS 1 - -//SCALER PLL config -#define S_PLL_PWR_ON 0 -#define S_PLL_PWR_DOWN 1 - -/* clock config */ -#define S_PLL_FROM_DIV 0 -#define S_PLL_FROM_CLKIN 1 -#define S_PLL_DIV(x) ((x)&0x7) -/*********S_PLL_CON************/ -//S_PLL_CON0 -#define S_DIV_N(x) (((x)&0xf)<<4) -#define S_DIV_OD(x) (((x)&3)<<0) -//S_PLL_CON1 -#define S_DIV_M(x) ((x)&0xff) -//S_PLL_CON2 -#define S_PLL_UNLOCK (0<<7) //0:unlock 1:pll_lock -#define S_PLL_LOCK (1<<7) //0:unlock 1:pll_lock -#define S_PLL_PWR(x) (((x)&1)<<2) //0:POWER UP 1:POWER DOWN -#define S_PLL_RESET(x) (((x)&1)<<1) //0:normal 1:reset M/N dividers -#define S_PLL_BYPASS(x) (((x)&1)<<0) //0:normal 1:bypass -//LVDS_CON0 -#define LVDS_OUT_CLK_PIN(x) (((x)&1)<<7) //clk enable pin, 0: enable -#define LVDS_OUT_CLK_PWR_PIN(x) (((x)&1)<<6) //clk pwr enable pin, 1: enable -#define LVDS_PLL_PWR_PIN(x) (((x)&1)<<5) //pll pwr enable pin, 0:enable -#define LVDS_BIASE_PWR(x) (((x)&1)<<4) //0: power down 1: normal work -#define LVDS_LANE_IN_FORMAT(x) (((x)&1)<<3) //0: msb on D0 1:msb on D7 -#define LVDS_INPUT_SOURCE(x) (((x)&1)<<2) //0: from lcd1 1:from lcd0 or scaler -#define LVDS_OUTPUT_FORMAT(x) (((x)&3)<<0) //00:8bit format-1 01:8bit format-2 10:8bit format-3 11:6bit format -//LVDS_CON1 -#define LVDS_OUT_ENABLE(x) (((x)&0xf)<<4) //0:output enable 1:output disable -#define LVDS_TX_PWR_ENABLE(x) (((x)&0xf)<<0) //0:working mode 1:power down -//LCD1_CON -#define LCD1_OUT_ENABLE(x) (((x)&1)<<1) //0:lcd1 as input 1:lcd1 as output -#define LCD1_OUT_SRC(x) (((x)&1)<<0) //0:from lcd0 1:from scaler -//SCL_CON0 -#define SCL_BYPASS(x) (((x)&1)<<4) //0:not bypass 1:bypass -#define SCL_DEN_INV(x) (((x)&1)<<3) //scl_den_inv -#define SCL_H_V_SYNC_INV(x) (((x)&1)<<2) //scl_sync_inv -#define SCL_OUT_CLK_INV(x) (((x)&1)<<1) //scl_dclk_inv -#define SCL_ENABLE(x) (((x)&1)<<0) //scaler enable -//SCL_CON1 -#define SCL_H_FACTOR_LSB(x) ((x)&0xff) //scl_h_factor[7:0] -//SCL_CON2 -#define SCL_H_FACTOR_MSB(x) (((x)>>8)&0x3f) //scl_h_factor[13:8] -//SCL_CON3 -#define SCL_V_FACTOR_LSB(x) ((x)&0xff) //scl_v_factor[7:0] -//SCL_CON4 -#define SCL_V_FACTOR_MSB(x) (((x)>>8)&0x3f) //scl_v_factor[13:8] -//SCL_CON5 -#define SCL_DSP_HST_LSB(x) ((x)&0xff) //dsp_frame_hst[7:0] -//SCL_CON6 -#define SCL_DSP_HST_MSB(x) (((x)>>8)&0xf) //dsp_frame_hst[11:8] -//SCL_CON7 -#define SCL_DSP_VST_LSB(x) ((x)&0xff) //dsp_frame_vst[7:0] -//SCL_CON8 -#define SCL_DSP_VST_MSB(x) (((x)>>8)&0xf) //dsp_frame_vst[11:8] -//SCL_CON9 -#define SCL_DSP_HTOTAL_LSB(x) ((x)&0xff) //dsp_frame_htotal[7:0] -//SCL_CON10 -#define SCL_DSP_HTOTAL_MSB(x) (((x)>>8)&0xf) //dsp_frame_htotal[11:8] -//SCL_CON11 -#define SCL_DSP_HS_END(x) ((x)&0xff) //dsp_hs_end -//SCL_CON12 -#define SCL_DSP_HACT_ST_LSB(x) ((x)&0xff) //dsp_hact_st[7:0] -//SCL_CON13 -#define SCL_DSP_HACT_ST_MSB(x) (((x)>>8)&0x3) //dsp_hact_st[9:8] -//SCL_CON14 -#define SCL_DSP_HACT_END_LSB(x) ((x)&0xff) //dsp_hact_end[7:0] -//SCL_CON15 -#define SCL_DSP_HACT_END_MSB(x) (((x)>>8)&0xf) //dsp_frame_htotal[11:8] -//SCL_CON16 -#define SCL_DSP_VTOTAL_LSB(x) ((x)&0xff) //dsp_frame_vtotal[7:0] -//SCL_CON17 -#define SCL_DSP_VTOTAL_MSB(x) (((x)>>8)&0xf) //dsp_frame_vtotal[11:8] -//SCL_CON18 -#define SCL_DSP_VS_END(x) ((x)&0xff) //dsp_vs_end -//SCL_CON19 -#define SCL_DSP_VACT_ST(x) ((x)&0xff) //dsp_vact_st[7:0] -//SCL_CON20 -#define SCL_DSP_VACT_END_LSB(x) ((x)&0xff) //dsp_vact_end[7:0] -//SCL_CON21 -#define SCL_DSP_VACT_END_MSB(x) (((x)>>8)&0xf) //dsp_frame_vtotal[11:8] -//SCL_CON22 -#define SCL_H_BORD_ST_LSB(x) ((x)&0xff) //dsp_hbord_st[7:0] -//SCL_CON23 -#define SCL_H_BORD_ST_MSB(x) (((x)>>8)&0x3) //dsp_hbord_st[9:8] -//SCL_CON24 -#define SCL_H_BORD_END_LSB(x) ((x)&0xff) //dsp_hbord_end[7:0] -//SCL_CON25 -#define SCL_H_BORD_END_MSB(x) (((x)>>8)&0xf) //dsp_hbord_end[11:8] -//SCL_CON26 -#define SCL_V_BORD_ST(x) ((x)&0xff) //dsp_vbord_st[7:0] -//SCL_CON27 -#define SCL_V_BORD_END_LSB(x) ((x)&0xff) //dsp_vbord_end[7:0] -//SCL_CON25 -#define SCL_V_BORD_END_MSB(x) (((x)>>8)&0xf) //dsp_vbord_end[11:8] - -enum { - LCD_OUT_SCL, - LCD_OUT_BYPASS, - LCD_OUT_DISABLE, -}; -struct rk610_pll_info{ - u32 parent_rate; - u32 rate; - int m; - int n; - int od; -}; -struct lcd_mode_inf{ - int h_pw; - int h_bp; - int h_vd; - int h_fp; - int v_pw; - int v_bp; - int v_vd; - int v_fp; - int f_hst; - int f_vst; - struct rk610_pll_info pllclk; -}; -struct scl_hv_info{ - int scl_h ; - int scl_v; - }; - -struct scl_info{ - bool pll_pwr; - bool scl_pwr; - struct scl_hv_info scl_hv; -}; -struct rk610_lcd_info{ - int disp_mode; - - struct rk29fb_screen *screen; - struct scl_info scl_inf; - struct i2c_client *client; - -#ifdef CONFIG_HAS_EARLYSUSPEND - struct early_suspend early_suspend; -#endif -}; -extern int rk610_lcd_init(struct rk610_core_info *rk610_core_info); -extern int rk610_lcd_scaler_set_param(struct rk29fb_screen *screen,bool enable ); -#endif diff --git a/drivers/video/display/screen/lcd_b101ew05.c b/drivers/video/display/screen/lcd_b101ew05.c index b1d9bfef9b96..70bbdca72f27 100755 --- a/drivers/video/display/screen/lcd_b101ew05.c +++ b/drivers/video/display/screen/lcd_b101ew05.c @@ -6,15 +6,15 @@ #include #include "screen.h" -#ifdef CONFIG_RK610_LCD -#include "../lcd/rk610_lcd.h" +#ifdef CONFIG_RK610_LVDS +#include "../transmitter/rk610_lcd.h" #endif /* Base */ -#ifdef CONFIG_RK610_LCD -#define OUT_TYPE SCREEN_LVDS -#define OUT_FORMAT LVDS_8BIT_2 +#ifdef CONFIG_RK610_LVDS +#define OUT_TYPE SCREEN_LVDS +#define OUT_FORMAT LVDS_8BIT_2 #else #define OUT_TYPE SCREEN_RGB #endif @@ -39,12 +39,12 @@ #define LCD_WIDTH 216 #define LCD_HEIGHT 135 /* Other */ -#ifdef CONFIG_RK610_LCD +#ifdef CONFIG_RK610_LVDS #define DCLK_POL 1 #else #define DCLK_POL 0 - #endif + #define SWAP_RB 0 int dsp_lut[256] ={ @@ -124,7 +124,7 @@ void set_lcd_info(struct rk29fb_screen *screen, struct rk29lcd_info *lcd_info ) screen->standby = NULL; screen->dsp_lut = dsp_lut; screen->sscreen_get = NULL;//set_scaler_info; -#ifdef CONFIG_RK610_LCD +#ifdef CONFIG_RK610_LVDS screen->sscreen_set = rk610_lcd_scaler_set_param; #endif } diff --git a/drivers/video/display/screen/lcd_hdmi_1024x768.c b/drivers/video/display/screen/lcd_hdmi_1024x768.c index c4d7ea336dcf..ca64748ed13f 100644 --- a/drivers/video/display/screen/lcd_hdmi_1024x768.c +++ b/drivers/video/display/screen/lcd_hdmi_1024x768.c @@ -6,7 +6,7 @@ #include "screen.h" #include #include "../../rk29_fb.h" -#include "../lcd/rk610_lcd.h" + /* Base */ #define OUT_TYPE SCREEN_LVDS @@ -272,7 +272,7 @@ void set_lcd_info(struct rk29fb_screen *screen, struct rk29lcd_info *lcd_info ) screen->init = NULL; screen->standby = NULL; screen->sscreen_get = set_scaler_info; -#ifdef CONFIG_RK610_LCD +#ifdef CONFIG_RK610_LVDS screen->sscreen_set = rk610_lcd_scaler_set_param; #endif } \ No newline at end of file diff --git a/drivers/video/display/screen/lcd_hdmi_1280x800.c b/drivers/video/display/screen/lcd_hdmi_1280x800.c index 43a3348d968e..a67e852c2b65 100644 --- a/drivers/video/display/screen/lcd_hdmi_1280x800.c +++ b/drivers/video/display/screen/lcd_hdmi_1280x800.c @@ -6,7 +6,7 @@ #include "screen.h" #include #include "../../rk29_fb.h" -#include "../lcd/rk610_lcd.h" +#include "../transmitter/rk610_lcd.h" /* Base */ diff --git a/drivers/video/display/screen/lcd_hdmi_800x480.c b/drivers/video/display/screen/lcd_hdmi_800x480.c index 7f71779938cc..66639130c964 100644 --- a/drivers/video/display/screen/lcd_hdmi_800x480.c +++ b/drivers/video/display/screen/lcd_hdmi_800x480.c @@ -6,7 +6,7 @@ #include "screen.h" #include #include "../../rk29_fb.h" -#include "../lcd/rk610_lcd.h" +#include "../transmitter/rk610_lcd.h" /* Base */ #define OUT_TYPE SCREEN_RGB @@ -269,7 +269,7 @@ void set_lcd_info(struct rk29fb_screen *screen, struct rk29lcd_info *lcd_info ) screen->init = NULL; screen->standby = NULL; screen->sscreen_get = set_scaler_info; -#ifdef CONFIG_RK610_LCD +#ifdef CONFIG_RK610_LVDS screen->sscreen_set = rk610_lcd_scaler_set_param; #endif } diff --git a/drivers/video/display/transmitter/Kconfig b/drivers/video/display/transmitter/Kconfig new file mode 100644 index 000000000000..5565f72d0cf8 --- /dev/null +++ b/drivers/video/display/transmitter/Kconfig @@ -0,0 +1,6 @@ +config RK610_LVDS + bool "RK610(Jetta) lvds transmitter support" + depends on MFD_RK610 + default y if MFD_RK610 + help + Support Jetta(RK610) to output LCD1 and LVDS. diff --git a/drivers/video/display/transmitter/Makefile b/drivers/video/display/transmitter/Makefile new file mode 100644 index 000000000000..75adab5b4151 --- /dev/null +++ b/drivers/video/display/transmitter/Makefile @@ -0,0 +1,4 @@ +# +# Makefile for the jetta tv control. +# +obj-$(CONFIG_RK610_LVDS) += rk610_lcd.o diff --git a/drivers/video/display/transmitter/rk610_lcd.c b/drivers/video/display/transmitter/rk610_lcd.c new file mode 100644 index 000000000000..9ffac8db2654 --- /dev/null +++ b/drivers/video/display/transmitter/rk610_lcd.c @@ -0,0 +1,414 @@ +#include +#include +#include +#include +#include + +#include +#include "rk610_lcd.h" +#include +#include "../../rk29_fb.h" +static struct rk610_lcd_info *g_lcd_inf = NULL; +//static int rk610_scaler_read_p0_reg(struct i2c_client *client, char reg, char *val) +//{ + //return i2c_master_reg8_recv(client, reg, val, 1, 100*1000) > 0? 0: -EINVAL; +//} + +static int rk610_scaler_write_p0_reg(struct i2c_client *client, char reg, char *val) +{ + return i2c_master_reg8_send(client, reg, val, 1, 100*1000) > 0? 0: -EINVAL; +} +static void rk610_scaler_pll_enable(struct i2c_client *client) +{ + char c; + RK610_DBG(&client->dev,"%s \n",__FUNCTION__); + + g_lcd_inf->scl_inf.pll_pwr = ENABLE; + + c = S_PLL_PWR(0)|S_PLL_RESET(0)|S_PLL_BYPASS(0); + rk610_scaler_write_p0_reg(client, S_PLL_CON2, &c); +} +static void rk610_scaler_pll_disable(struct i2c_client *client) +{ + char c; + RK610_DBG(&client->dev,"%s \n",__FUNCTION__); + + g_lcd_inf->scl_inf.pll_pwr = DISABLE; + + c = S_PLL_PWR(1) |S_PLL_RESET(0) |S_PLL_BYPASS(1); + rk610_scaler_write_p0_reg(client, S_PLL_CON2, &c); +} +static void rk610_scaler_enable(struct i2c_client *client) +{ + char c; + bool den_inv = 0,hv_sync_inv = 0,clk_inv = 0; + RK610_DBG(&client->dev,"%s \n",__FUNCTION__); + g_lcd_inf->scl_inf.scl_pwr = ENABLE; + #ifdef CONFIG_HDMI_DUAL_DISP + if(g_lcd_inf->screen !=NULL){ + den_inv = g_lcd_inf->screen->s_den_inv; + hv_sync_inv = g_lcd_inf->screen->s_hv_sync_inv; + clk_inv = g_lcd_inf->screen->s_clk_inv; + } + #endif + c= SCL_BYPASS(0) |SCL_DEN_INV(den_inv) |SCL_H_V_SYNC_INV(hv_sync_inv) |SCL_OUT_CLK_INV(clk_inv) |SCL_ENABLE(ENABLE); + rk610_scaler_write_p0_reg(client, SCL_CON0, &c); +} +static void rk610_scaler_disable(struct i2c_client *client) +{ + char c; + bool den_inv = 0,hv_sync_inv = 0,clk_inv = 0; + RK610_DBG(&client->dev,"%s \n",__FUNCTION__); + + g_lcd_inf->scl_inf.scl_pwr = DISABLE; + #ifdef CONFIG_HDMI_DUAL_DISP + if(g_lcd_inf->screen !=NULL){ + den_inv = g_lcd_inf->screen->s_den_inv; + hv_sync_inv = g_lcd_inf->screen->s_hv_sync_inv; + clk_inv = g_lcd_inf->screen->s_clk_inv; + } + #endif + c= SCL_BYPASS(1) |SCL_DEN_INV(den_inv) |SCL_H_V_SYNC_INV(hv_sync_inv) |SCL_OUT_CLK_INV(clk_inv) |SCL_ENABLE(DISABLE); + rk610_scaler_write_p0_reg(client, SCL_CON0, &c); +} + +static int rk610_output_config(struct i2c_client *client,struct rk29fb_screen *screen,int mode) +{ + char c=0; + RK610_DBG(&client->dev,"%s \n",__FUNCTION__); + if(SCREEN_LVDS == screen->type){ + if(mode == LCD_OUT_SCL || mode == LCD_OUT_BYPASS){ + c = LVDS_OUT_CLK_PIN(0) |LVDS_OUT_CLK_PWR_PIN(1) |LVDS_PLL_PWR_PIN(0) \ + |LVDS_LANE_IN_FORMAT(DATA_D0_MSB) |LVDS_INPUT_SOURCE(FROM_LCD0_OR_SCL) \ + |LVDS_OUTPUT_FORMAT(screen->hw_format) | LVDS_BIASE_PWR(1); + rk610_scaler_write_p0_reg(client, LVDS_CON0, &c); + c = LVDS_OUT_ENABLE(0x0) |LVDS_TX_PWR_ENABLE(0x0); + rk610_scaler_write_p0_reg(client, LVDS_CON1, &c); + } + else{ + c = LVDS_OUT_CLK_PIN(0) |LVDS_OUT_CLK_PWR_PIN(0) |LVDS_PLL_PWR_PIN(1) \ + |LVDS_LANE_IN_FORMAT(DATA_D0_MSB) |LVDS_INPUT_SOURCE(FROM_LCD0_OR_SCL) \ + |LVDS_OUTPUT_FORMAT(screen->hw_format) | LVDS_BIASE_PWR(0); + rk610_scaler_write_p0_reg(client, LVDS_CON0, &c); + c = LVDS_OUT_ENABLE(0xf) |LVDS_TX_PWR_ENABLE(0xf); + rk610_scaler_write_p0_reg(client, LVDS_CON1, &c); + + } + }else if(SCREEN_RGB == screen->type){ + if(mode == LCD_OUT_SCL || mode == LCD_OUT_BYPASS){ + c = LCD1_OUT_ENABLE(LCD1_AS_OUT) | LCD1_OUT_SRC((mode == LCD_OUT_SCL)?LCD1_FROM_SCL : LCD1_FROM_LCD0); + rk610_scaler_write_p0_reg(client, LCD1_CON, &c); + } + else { + c = LCD1_OUT_ENABLE(LCD1_AS_IN); + rk610_scaler_write_p0_reg(client, LCD1_CON, &c); + } + } + return 0; +} +#ifdef CONFIG_HDMI_DUAL_DISP +static int rk610_scaler_pll_set(struct i2c_client *client,struct rk29fb_screen *screen,u32 clkin ) +{ + char c=0; + char M=0,N=0,OD=0; + RK610_DBG(&client->dev,"%s \n",__FUNCTION__); + /***************SET SCALER PLL FROM CLKIN ,DIV 0*/ + if(screen->s_pixclock != 0){ + OD = (screen->s_pixclock)&0x3; + N = (screen->s_pixclock >>4)&0xf; + M = (screen->s_pixclock >>8)&0xff; + }else { + RK610_ERR(&client->dev,"RK610 Scaler pll not support rate \n"); + } + c = S_PLL_FROM_DIV<<3 | S_PLL_DIV(0); + rk610_scaler_write_p0_reg(client, CLOCK_CON0, &c); + + c = S_DIV_N(N)| S_DIV_OD(OD); + rk610_scaler_write_p0_reg(client, S_PLL_CON0, &c); + c = S_DIV_M(M); + rk610_scaler_write_p0_reg(client, S_PLL_CON1, &c); + rk610_scaler_pll_enable(client); + return 0; +} + + +static int scale_hv_factor(struct i2c_client *client ,u32 Hin_act, u32 Hout_act, u32 Vin_act, u32 Vout_act) + { + char c; + u32 hfactor_f,vfactor_f,scl_factor_f; + int hfactor; + int vfactor; + struct scl_hv_info HV2; + hfactor_f = ((Hin_act-1)*4096)/(Hout_act-1); + if(hfactor_f==4096) + {hfactor = 0x1000;} + else if(hfactor_f>(int)hfactor_f) + {hfactor = (int)hfactor_f+1;} + else + {hfactor = (int)hfactor_f;} + + scl_factor_f = Vin_act/Vout_act; + if(scl_factor_f<2) + {vfactor_f = ((Vin_act-1)*4096)/(Vout_act-1);} + else + {vfactor_f = ((Vin_act-2)*4096)/(Vout_act-1);} + if(vfactor_f==4096) + {vfactor = 0x1000;} + else if(vfactor_f>(int)vfactor_f) + {vfactor = (int)vfactor_f+1;} + else + {vfactor = (int)vfactor_f;} + + HV2.scl_h= hfactor; + HV2.scl_v= vfactor; + /* SCL FACTOR */ + c = SCL_H_FACTOR_LSB(HV2.scl_h); + rk610_scaler_write_p0_reg(client, SCL_CON1, &c); + c = SCL_H_FACTOR_MSB(HV2.scl_h); + rk610_scaler_write_p0_reg(client, SCL_CON2, &c); + + c = SCL_V_FACTOR_LSB(HV2.scl_v); + rk610_scaler_write_p0_reg(client, SCL_CON3, &c); + c = SCL_V_FACTOR_MSB(HV2.scl_v); + rk610_scaler_write_p0_reg(client, SCL_CON4, &c); + return 0; + } + +static int rk610_scaler_fator_config(struct i2c_client *client ,struct rk29fb_screen *screen) +{ + switch(screen->hdmi_resolution){ + case HDMI_1920x1080p_60Hz: + case HDMI_1920x1080p_50Hz: + rk610_scaler_pll_set(client,screen,148500000); + /***************set scaler factor********************/ + scale_hv_factor(client,1920,screen->x_res,1080,screen->y_res); + break; + case HDMI_1280x720p_60Hz: + case HDMI_1280x720p_50Hz: + rk610_scaler_pll_set(client,screen,74250000); + /***************set scaler factor********************/ + scale_hv_factor(client,1280,screen->x_res,720,screen->y_res); + break; + case HDMI_720x576p_50Hz_16x9: + case HDMI_720x576p_50Hz_4x3: + rk610_scaler_pll_set(client,screen,27000000); + /***************set scaler factor********************/ + scale_hv_factor(client,720,screen->x_res,576,screen->y_res); + break; + case HDMI_720x480p_60Hz_16x9: + case HDMI_720x480p_60Hz_4x3: + rk610_scaler_pll_set(client,screen,27000000); + /***************set scaler factor********************/ + scale_hv_factor(client,720,screen->x_res,480,screen->y_res); + break; + default : + RK610_ERR(&client->dev,"RK610 not support dual display at hdmi resolution=%d \n",screen->hdmi_resolution); + return -1; + break; + } + return 0; +} +static int rk610_scaler_output_timing_config(struct i2c_client *client,struct rk29fb_screen *screen) +{ + char c; + int h_st = screen->s_hsync_st; + int hs_end = screen->s_hsync_len; + int h_act_st = hs_end + screen->s_left_margin; + int xres = screen->x_res; + int h_act_end = h_act_st + xres; + int h_total = h_act_end + screen->s_right_margin; + int v_st = screen->s_vsync_st; + int vs_end = screen->s_vsync_len; + int v_act_st = vs_end + screen->s_upper_margin; + int yres = screen->y_res; + int v_act_end = v_act_st + yres; + int v_total = v_act_end + screen->s_lower_margin; + + /* SCL display Frame start point */ + c = SCL_DSP_HST_LSB(h_st); + rk610_scaler_write_p0_reg(client, SCL_CON5, &c); + c = SCL_DSP_HST_MSB(h_st); + rk610_scaler_write_p0_reg(client, SCL_CON6, &c); + + c = SCL_DSP_VST_LSB(v_st); + rk610_scaler_write_p0_reg(client, SCL_CON7, &c); + c = SCL_DSP_VST_MSB(v_st); + rk610_scaler_write_p0_reg(client, SCL_CON8, &c); + /* SCL output timing */ + + c = SCL_DSP_HTOTAL_LSB(h_total); + rk610_scaler_write_p0_reg(client, SCL_CON9, &c); + c = SCL_DSP_HTOTAL_MSB(h_total); + rk610_scaler_write_p0_reg(client, SCL_CON10, &c); + + c = SCL_DSP_HS_END(hs_end); + rk610_scaler_write_p0_reg(client, SCL_CON11, &c); + + c = SCL_DSP_HACT_ST_LSB(h_act_st); + rk610_scaler_write_p0_reg(client, SCL_CON12, &c); + c = SCL_DSP_HACT_ST_MSB(h_act_st); + rk610_scaler_write_p0_reg(client, SCL_CON13, &c); + + c = SCL_DSP_HACT_END_LSB(h_act_end); + rk610_scaler_write_p0_reg(client, SCL_CON14, &c); + c = SCL_DSP_HACT_END_MSB(h_act_end); + rk610_scaler_write_p0_reg(client, SCL_CON15, &c); + + c = SCL_DSP_VTOTAL_LSB(v_total); + rk610_scaler_write_p0_reg(client, SCL_CON16, &c); + c = SCL_DSP_VTOTAL_MSB(v_total); + rk610_scaler_write_p0_reg(client, SCL_CON17, &c); + + c = SCL_DSP_VS_END(vs_end); + rk610_scaler_write_p0_reg(client, SCL_CON18, &c); + + c = SCL_DSP_VACT_ST(v_act_st); + rk610_scaler_write_p0_reg(client, SCL_CON19, &c); + + c = SCL_DSP_VACT_END_LSB(v_act_end); + rk610_scaler_write_p0_reg(client, SCL_CON20, &c); + c = SCL_DSP_VACT_END_MSB(v_act_end); + rk610_scaler_write_p0_reg(client, SCL_CON21, &c); + + c = SCL_H_BORD_ST_LSB(h_act_st); + rk610_scaler_write_p0_reg(client, SCL_CON22, &c); + c = SCL_H_BORD_ST_MSB(h_act_st); + rk610_scaler_write_p0_reg(client, SCL_CON23, &c); + + c = SCL_H_BORD_END_LSB(h_act_end); + rk610_scaler_write_p0_reg(client, SCL_CON24, &c); + c = SCL_H_BORD_END_MSB(h_act_end); + rk610_scaler_write_p0_reg(client, SCL_CON25, &c); + + c = SCL_V_BORD_ST(v_act_st); + rk610_scaler_write_p0_reg(client, SCL_CON26, &c); + + c = SCL_V_BORD_END_LSB(v_act_end); + rk610_scaler_write_p0_reg(client, SCL_CON27, &c); + c = SCL_V_BORD_END_MSB(v_act_end); + rk610_scaler_write_p0_reg(client, SCL_CON28, &c); + + return 0; +} +static int rk610_scaler_chg(struct i2c_client *client ,struct rk29fb_screen *screen) +{ + + RK610_DBG(&client->dev,"%s screen->hdmi_resolution=%d\n",__FUNCTION__,screen->hdmi_resolution); + rk610_scaler_fator_config(client,screen); + rk610_scaler_enable(client); + rk610_scaler_output_timing_config(client,screen); + + return 0; + +} +#endif +static int rk610_lcd_scaler_bypass(struct i2c_client *client,bool enable)//enable:0 bypass 1: scale +{ + RK610_DBG(&client->dev,"%s \n",__FUNCTION__); + + rk610_scaler_disable(client); + rk610_scaler_pll_disable(client); + + return 0; +} + +#ifdef CONFIG_HAS_EARLYSUSPEND +static void rk610_lcd_early_suspend(struct early_suspend *h) +{ + struct i2c_client *client = g_lcd_inf->client; + char c; + RK610_DBG(&client->dev,"%s \n",__FUNCTION__); + if(g_lcd_inf->screen != NULL){ + rk610_output_config(client,g_lcd_inf->screen,LCD_OUT_DISABLE); + } + + if(ENABLE == g_lcd_inf->scl_inf.scl_pwr){ + c= SCL_BYPASS(1) |SCL_DEN_INV(0) |SCL_H_V_SYNC_INV(0) |SCL_OUT_CLK_INV(0) |SCL_ENABLE(DISABLE); + rk610_scaler_write_p0_reg(client, SCL_CON0, &c); + } + if(ENABLE == g_lcd_inf->scl_inf.pll_pwr ){ + c = S_PLL_PWR(1) |S_PLL_RESET(0) |S_PLL_BYPASS(1); + rk610_scaler_write_p0_reg(client, S_PLL_CON2, &c); + } +} + +static void rk610_lcd_early_resume(struct early_suspend *h) +{ + struct i2c_client *client = g_lcd_inf->client; + char c; + RK610_DBG(&client->dev,"%s \n",__FUNCTION__); + + if(g_lcd_inf->screen != NULL){ + rk610_output_config(client,g_lcd_inf->screen,g_lcd_inf->disp_mode); + } + if(ENABLE == g_lcd_inf->scl_inf.scl_pwr){ + c= SCL_BYPASS(0) |SCL_DEN_INV(0) |SCL_H_V_SYNC_INV(0) |SCL_OUT_CLK_INV(0) |SCL_ENABLE(ENABLE); + rk610_scaler_write_p0_reg(client, SCL_CON0, &c); + } + if(ENABLE == g_lcd_inf->scl_inf.pll_pwr ){ + c = S_PLL_PWR(1) |S_PLL_RESET(0) |S_PLL_BYPASS(1); + rk610_scaler_write_p0_reg(client, S_PLL_CON2, &c); + } +} +#endif +int rk610_lcd_scaler_set_param(struct rk29fb_screen *screen,bool enable )//enable:0 bypass 1: scale +{ + int ret=0; + struct i2c_client *client = g_lcd_inf->client; + if(client == NULL){ + printk("%s client == NULL FAIL\n",__FUNCTION__); + return -1; + } + if(screen == NULL){ + printk("%s screen == NULL FAIL\n",__FUNCTION__); + return -1; + } + RK610_DBG(&client->dev,"%s \n",__FUNCTION__); + + g_lcd_inf->screen = screen; + +#ifdef CONFIG_HDMI_DUAL_DISP + if(enable == 1){ + g_lcd_inf->disp_mode = LCD_OUT_SCL; + rk610_output_config(client,screen,LCD_OUT_SCL); + ret = rk610_scaler_chg(client,screen); + } + else +#endif + { + g_lcd_inf->disp_mode = LCD_OUT_BYPASS; + rk610_output_config(client,screen,LCD_OUT_BYPASS); + ret = rk610_lcd_scaler_bypass(client,enable); + } + return ret; +} +int rk610_lcd_init(struct rk610_core_info *rk610_core_info) +{ + if(rk610_core_info->client == NULL){ + printk("%s client == NULL FAIL\n",__FUNCTION__); + return -1; + } + RK610_DBG(&rk610_core_info->client->dev,"%s \n",__FUNCTION__); + + g_lcd_inf = kmalloc(sizeof(struct rk610_lcd_info), GFP_KERNEL); + if(!g_lcd_inf) + { + dev_err(&rk610_core_info->client->dev, ">> rk610 inf kmalloc fail!"); + return -ENOMEM; + } + memset(g_lcd_inf, 0, sizeof(struct rk610_lcd_info)); + + g_lcd_inf->client= rk610_core_info->client; + + rk610_core_info->lcd_pdata = (void *)g_lcd_inf; +#ifdef CONFIG_HAS_EARLYSUSPEND + g_lcd_inf->early_suspend.suspend = rk610_lcd_early_suspend; + g_lcd_inf->early_suspend.resume = rk610_lcd_early_resume; + g_lcd_inf->early_suspend.level = EARLY_SUSPEND_LEVEL_DISABLE_FB- 1; + register_early_suspend(&g_lcd_inf->early_suspend); +#endif + g_lcd_inf->scl_inf.pll_pwr = DISABLE; + g_lcd_inf->scl_inf.scl_pwr = DISABLE; + g_lcd_inf->disp_mode = LCD_OUT_BYPASS; + return 0; +} diff --git a/drivers/video/display/transmitter/rk610_lcd.h b/drivers/video/display/transmitter/rk610_lcd.h new file mode 100644 index 000000000000..8cdeef6e1fa8 --- /dev/null +++ b/drivers/video/display/transmitter/rk610_lcd.h @@ -0,0 +1,214 @@ +#ifndef _RK610_LCD_H +#define _RK610_LCD_H +#include +#include "../screen/screen.h" +#include +#define ENABLE 1 +#define DISABLE 0 + +/* LVDS config */ +/* LVDS ÍⲿÁ¬Ïß½Ó·¨ */ +/* LVDS_8BIT_1 LVDS_8BIT_2 LVDS_8BIT_3 LVDS_6BIT +---------------------------------------------------------------------- + TX0 R0 R2 R2 R0 + TX1 R1 R3 R3 R1 + TX2 R2 R4 R4 R2 +Y TX3 R3 R5 R5 R3 +0 TX4 R4 R6 R6 R4 + TX6 R5 R7 R7 R5 + TX7 G0 G2 G2 G0 +---------------------------------------------------------------------- + TX8 G1 G3 G3 G1 + TX9 G2 G4 G4 G2 +Y TX12 G3 G5 G5 G3 +1 TX13 G4 G6 G6 G4 + TX14 G5 G7 G7 G5 + TX15 B0 B2 B2 B0 + TX18 B1 B3 B3 B1 +---------------------------------------------------------------------- + TX19 B2 B4 B4 B2 + TX20 B3 B5 B5 B3 + TX21 B4 B6 B6 B4 +Y TX22 B5 B7 B7 B5 +2 TX24 HSYNC HSYNC HSYNC HSYNC + TX25 VSYNC VSYNC VSYNC VSYNC + TX26 ENABLE ENABLE ENABLE ENABLE +---------------------------------------------------------------------- + TX27 R6 R0 GND GND + TX5 R7 R1 GND GND + TX10 G6 G0 GND GND +Y TX11 G7 G1 GND GND +3 TX16 B6 B0 GND GND + TX17 B7 B1 GND GND + TX23 RSVD RSVD RSVD RSVD +---------------------------------------------------------------------- +*/ +#define LVDS_8BIT_1 0x00 +#define LVDS_8BIT_2 0x01 +#define LVDS_8BIT_3 0x10 +#define LVDS_6BIT 0x11 +//LVDS lane input format +#define DATA_D0_MSB 0 +#define DATA_D7_MSB 1 +//LVDS input source +#define FROM_LCD1 0 +#define FROM_LCD0_OR_SCL 1 + +/* LCD1 config */ +#define LCD1_AS_IN 0 +#define LCD1_AS_OUT 1 + +//LCD1 output source +#define LCD1_FROM_LCD0 0 +#define LCD1_FROM_SCL 1 + +//SCALER config +#define NOBYPASS 0 +#define BYPASS 1 + +//SCALER PLL config +#define S_PLL_PWR_ON 0 +#define S_PLL_PWR_DOWN 1 + +/* clock config */ +#define S_PLL_FROM_DIV 0 +#define S_PLL_FROM_CLKIN 1 +#define S_PLL_DIV(x) ((x)&0x7) +/*********S_PLL_CON************/ +//S_PLL_CON0 +#define S_DIV_N(x) (((x)&0xf)<<4) +#define S_DIV_OD(x) (((x)&3)<<0) +//S_PLL_CON1 +#define S_DIV_M(x) ((x)&0xff) +//S_PLL_CON2 +#define S_PLL_UNLOCK (0<<7) //0:unlock 1:pll_lock +#define S_PLL_LOCK (1<<7) //0:unlock 1:pll_lock +#define S_PLL_PWR(x) (((x)&1)<<2) //0:POWER UP 1:POWER DOWN +#define S_PLL_RESET(x) (((x)&1)<<1) //0:normal 1:reset M/N dividers +#define S_PLL_BYPASS(x) (((x)&1)<<0) //0:normal 1:bypass +//LVDS_CON0 +#define LVDS_OUT_CLK_PIN(x) (((x)&1)<<7) //clk enable pin, 0: enable +#define LVDS_OUT_CLK_PWR_PIN(x) (((x)&1)<<6) //clk pwr enable pin, 1: enable +#define LVDS_PLL_PWR_PIN(x) (((x)&1)<<5) //pll pwr enable pin, 0:enable +#define LVDS_BIASE_PWR(x) (((x)&1)<<4) //0: power down 1: normal work +#define LVDS_LANE_IN_FORMAT(x) (((x)&1)<<3) //0: msb on D0 1:msb on D7 +#define LVDS_INPUT_SOURCE(x) (((x)&1)<<2) //0: from lcd1 1:from lcd0 or scaler +#define LVDS_OUTPUT_FORMAT(x) (((x)&3)<<0) //00:8bit format-1 01:8bit format-2 10:8bit format-3 11:6bit format +//LVDS_CON1 +#define LVDS_OUT_ENABLE(x) (((x)&0xf)<<4) //0:output enable 1:output disable +#define LVDS_TX_PWR_ENABLE(x) (((x)&0xf)<<0) //0:working mode 1:power down +//LCD1_CON +#define LCD1_OUT_ENABLE(x) (((x)&1)<<1) //0:lcd1 as input 1:lcd1 as output +#define LCD1_OUT_SRC(x) (((x)&1)<<0) //0:from lcd0 1:from scaler +//SCL_CON0 +#define SCL_BYPASS(x) (((x)&1)<<4) //0:not bypass 1:bypass +#define SCL_DEN_INV(x) (((x)&1)<<3) //scl_den_inv +#define SCL_H_V_SYNC_INV(x) (((x)&1)<<2) //scl_sync_inv +#define SCL_OUT_CLK_INV(x) (((x)&1)<<1) //scl_dclk_inv +#define SCL_ENABLE(x) (((x)&1)<<0) //scaler enable +//SCL_CON1 +#define SCL_H_FACTOR_LSB(x) ((x)&0xff) //scl_h_factor[7:0] +//SCL_CON2 +#define SCL_H_FACTOR_MSB(x) (((x)>>8)&0x3f) //scl_h_factor[13:8] +//SCL_CON3 +#define SCL_V_FACTOR_LSB(x) ((x)&0xff) //scl_v_factor[7:0] +//SCL_CON4 +#define SCL_V_FACTOR_MSB(x) (((x)>>8)&0x3f) //scl_v_factor[13:8] +//SCL_CON5 +#define SCL_DSP_HST_LSB(x) ((x)&0xff) //dsp_frame_hst[7:0] +//SCL_CON6 +#define SCL_DSP_HST_MSB(x) (((x)>>8)&0xf) //dsp_frame_hst[11:8] +//SCL_CON7 +#define SCL_DSP_VST_LSB(x) ((x)&0xff) //dsp_frame_vst[7:0] +//SCL_CON8 +#define SCL_DSP_VST_MSB(x) (((x)>>8)&0xf) //dsp_frame_vst[11:8] +//SCL_CON9 +#define SCL_DSP_HTOTAL_LSB(x) ((x)&0xff) //dsp_frame_htotal[7:0] +//SCL_CON10 +#define SCL_DSP_HTOTAL_MSB(x) (((x)>>8)&0xf) //dsp_frame_htotal[11:8] +//SCL_CON11 +#define SCL_DSP_HS_END(x) ((x)&0xff) //dsp_hs_end +//SCL_CON12 +#define SCL_DSP_HACT_ST_LSB(x) ((x)&0xff) //dsp_hact_st[7:0] +//SCL_CON13 +#define SCL_DSP_HACT_ST_MSB(x) (((x)>>8)&0x3) //dsp_hact_st[9:8] +//SCL_CON14 +#define SCL_DSP_HACT_END_LSB(x) ((x)&0xff) //dsp_hact_end[7:0] +//SCL_CON15 +#define SCL_DSP_HACT_END_MSB(x) (((x)>>8)&0xf) //dsp_frame_htotal[11:8] +//SCL_CON16 +#define SCL_DSP_VTOTAL_LSB(x) ((x)&0xff) //dsp_frame_vtotal[7:0] +//SCL_CON17 +#define SCL_DSP_VTOTAL_MSB(x) (((x)>>8)&0xf) //dsp_frame_vtotal[11:8] +//SCL_CON18 +#define SCL_DSP_VS_END(x) ((x)&0xff) //dsp_vs_end +//SCL_CON19 +#define SCL_DSP_VACT_ST(x) ((x)&0xff) //dsp_vact_st[7:0] +//SCL_CON20 +#define SCL_DSP_VACT_END_LSB(x) ((x)&0xff) //dsp_vact_end[7:0] +//SCL_CON21 +#define SCL_DSP_VACT_END_MSB(x) (((x)>>8)&0xf) //dsp_frame_vtotal[11:8] +//SCL_CON22 +#define SCL_H_BORD_ST_LSB(x) ((x)&0xff) //dsp_hbord_st[7:0] +//SCL_CON23 +#define SCL_H_BORD_ST_MSB(x) (((x)>>8)&0x3) //dsp_hbord_st[9:8] +//SCL_CON24 +#define SCL_H_BORD_END_LSB(x) ((x)&0xff) //dsp_hbord_end[7:0] +//SCL_CON25 +#define SCL_H_BORD_END_MSB(x) (((x)>>8)&0xf) //dsp_hbord_end[11:8] +//SCL_CON26 +#define SCL_V_BORD_ST(x) ((x)&0xff) //dsp_vbord_st[7:0] +//SCL_CON27 +#define SCL_V_BORD_END_LSB(x) ((x)&0xff) //dsp_vbord_end[7:0] +//SCL_CON25 +#define SCL_V_BORD_END_MSB(x) (((x)>>8)&0xf) //dsp_vbord_end[11:8] + +enum { + LCD_OUT_SCL, + LCD_OUT_BYPASS, + LCD_OUT_DISABLE, +}; +struct rk610_pll_info{ + u32 parent_rate; + u32 rate; + int m; + int n; + int od; +}; +struct lcd_mode_inf{ + int h_pw; + int h_bp; + int h_vd; + int h_fp; + int v_pw; + int v_bp; + int v_vd; + int v_fp; + int f_hst; + int f_vst; + struct rk610_pll_info pllclk; +}; +struct scl_hv_info{ + int scl_h ; + int scl_v; + }; + +struct scl_info{ + bool pll_pwr; + bool scl_pwr; + struct scl_hv_info scl_hv; +}; +struct rk610_lcd_info{ + int disp_mode; + + struct rk29fb_screen *screen; + struct scl_info scl_inf; + struct i2c_client *client; + +#ifdef CONFIG_HAS_EARLYSUSPEND + struct early_suspend early_suspend; +#endif +}; +extern int rk610_lcd_init(struct rk610_core_info *rk610_core_info); +extern int rk610_lcd_scaler_set_param(struct rk29fb_screen *screen,bool enable ); +#endif diff --git a/drivers/video/rk29_fb.c b/drivers/video/rk29_fb.c index c1d1981e871e..5dbe4a581b8f 100644 --- a/drivers/video/rk29_fb.c +++ b/drivers/video/rk29_fb.c @@ -63,7 +63,7 @@ #include "./display/screen/screen.h" #ifdef CONFIG_MFD_RK610 -#include "./display/lcd/rk610_lcd.h" +#include "./display/transmitter/rk610_lcd.h" #endif #define ANDROID_USE_THREE_BUFS 0 //android use three buffers to accelerate UI display in rgb plane #define CURSOR_BUF_SIZE 256 //RK2818 cursor need 256B buf