#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){}
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
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/
+++ /dev/null
-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.
+++ /dev/null
-#
-# Makefile for the jetta tv control.
-#
-obj-$(CONFIG_RK610_LCD) += rk610_lcd.o
+++ /dev/null
-#include <linux/fb.h>\r
-#include <linux/delay.h>\r
-#include <mach/gpio.h>\r
-#include <mach/iomux.h>\r
-#include <mach/board.h>\r
-\r
-#include <linux/hdmi.h>\r
-#include "rk610_lcd.h"\r
-#include <linux/mfd/rk610_core.h>\r
-#include "../../rk29_fb.h"\r
-static struct rk610_lcd_info *g_lcd_inf = NULL;\r
-//static int rk610_scaler_read_p0_reg(struct i2c_client *client, char reg, char *val)\r
-//{\r
- //return i2c_master_reg8_recv(client, reg, val, 1, 100*1000) > 0? 0: -EINVAL;\r
-//}\r
-\r
-static int rk610_scaler_write_p0_reg(struct i2c_client *client, char reg, char *val)\r
-{\r
- return i2c_master_reg8_send(client, reg, val, 1, 100*1000) > 0? 0: -EINVAL;\r
-}\r
-static void rk610_scaler_pll_enable(struct i2c_client *client)\r
-{\r
- char c;\r
- RK610_DBG(&client->dev,"%s \n",__FUNCTION__);\r
-\r
- g_lcd_inf->scl_inf.pll_pwr = ENABLE;\r
- \r
- c = S_PLL_PWR(0)|S_PLL_RESET(0)|S_PLL_BYPASS(0);\r
- rk610_scaler_write_p0_reg(client, S_PLL_CON2, &c);\r
-}\r
-static void rk610_scaler_pll_disable(struct i2c_client *client)\r
-{\r
- char c;\r
- RK610_DBG(&client->dev,"%s \n",__FUNCTION__);\r
- \r
- g_lcd_inf->scl_inf.pll_pwr = DISABLE;\r
-\r
- c = S_PLL_PWR(1) |S_PLL_RESET(0) |S_PLL_BYPASS(1);\r
- rk610_scaler_write_p0_reg(client, S_PLL_CON2, &c);\r
-}\r
-static void rk610_scaler_enable(struct i2c_client *client)\r
-{\r
- char c;\r
- bool den_inv = 0,hv_sync_inv = 0,clk_inv = 0;\r
- RK610_DBG(&client->dev,"%s \n",__FUNCTION__);\r
- g_lcd_inf->scl_inf.scl_pwr = ENABLE;\r
- #ifdef CONFIG_HDMI_DUAL_DISP\r
- if(g_lcd_inf->screen !=NULL){\r
- den_inv = g_lcd_inf->screen->s_den_inv;\r
- hv_sync_inv = g_lcd_inf->screen->s_hv_sync_inv;\r
- clk_inv = g_lcd_inf->screen->s_clk_inv;\r
- }\r
- #endif\r
- 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); \r
- rk610_scaler_write_p0_reg(client, SCL_CON0, &c);\r
-}\r
-static void rk610_scaler_disable(struct i2c_client *client)\r
-{\r
- char c;\r
- bool den_inv = 0,hv_sync_inv = 0,clk_inv = 0;\r
- RK610_DBG(&client->dev,"%s \n",__FUNCTION__);\r
- \r
- g_lcd_inf->scl_inf.scl_pwr = DISABLE;\r
- #ifdef CONFIG_HDMI_DUAL_DISP\r
- if(g_lcd_inf->screen !=NULL){\r
- den_inv = g_lcd_inf->screen->s_den_inv;\r
- hv_sync_inv = g_lcd_inf->screen->s_hv_sync_inv;\r
- clk_inv = g_lcd_inf->screen->s_clk_inv;\r
- }\r
- #endif\r
- 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); \r
- rk610_scaler_write_p0_reg(client, SCL_CON0, &c);\r
-}\r
-\r
-static int rk610_output_config(struct i2c_client *client,struct rk29fb_screen *screen,int mode)\r
-{\r
- char c=0;\r
- RK610_DBG(&client->dev,"%s \n",__FUNCTION__);\r
- if(SCREEN_LVDS == screen->type){\r
- if(mode == LCD_OUT_SCL || mode == LCD_OUT_BYPASS){\r
- c = LVDS_OUT_CLK_PIN(0) |LVDS_OUT_CLK_PWR_PIN(1) |LVDS_PLL_PWR_PIN(0) \\r
- |LVDS_LANE_IN_FORMAT(DATA_D0_MSB) |LVDS_INPUT_SOURCE(FROM_LCD0_OR_SCL) \\r
- |LVDS_OUTPUT_FORMAT(screen->hw_format) | LVDS_BIASE_PWR(1); \r
- rk610_scaler_write_p0_reg(client, LVDS_CON0, &c);\r
- c = LVDS_OUT_ENABLE(0x0) |LVDS_TX_PWR_ENABLE(0x0); \r
- rk610_scaler_write_p0_reg(client, LVDS_CON1, &c);\r
- }\r
- else{\r
- c = LVDS_OUT_CLK_PIN(0) |LVDS_OUT_CLK_PWR_PIN(0) |LVDS_PLL_PWR_PIN(1) \\r
- |LVDS_LANE_IN_FORMAT(DATA_D0_MSB) |LVDS_INPUT_SOURCE(FROM_LCD0_OR_SCL) \\r
- |LVDS_OUTPUT_FORMAT(screen->hw_format) | LVDS_BIASE_PWR(0); \r
- rk610_scaler_write_p0_reg(client, LVDS_CON0, &c);\r
- c = LVDS_OUT_ENABLE(0xf) |LVDS_TX_PWR_ENABLE(0xf); \r
- rk610_scaler_write_p0_reg(client, LVDS_CON1, &c);\r
- \r
- }\r
- }else if(SCREEN_RGB == screen->type){\r
- if(mode == LCD_OUT_SCL || mode == LCD_OUT_BYPASS){\r
- c = LCD1_OUT_ENABLE(LCD1_AS_OUT) | LCD1_OUT_SRC((mode == LCD_OUT_SCL)?LCD1_FROM_SCL : LCD1_FROM_LCD0);\r
- rk610_scaler_write_p0_reg(client, LCD1_CON, &c);\r
- }\r
- else {\r
- c = LCD1_OUT_ENABLE(LCD1_AS_IN);\r
- rk610_scaler_write_p0_reg(client, LCD1_CON, &c);\r
- }\r
- }\r
- return 0;\r
-}\r
-#ifdef CONFIG_HDMI_DUAL_DISP\r
-static int rk610_scaler_pll_set(struct i2c_client *client,struct rk29fb_screen *screen,u32 clkin )\r
-{\r
- char c=0;\r
- char M=0,N=0,OD=0;\r
- RK610_DBG(&client->dev,"%s \n",__FUNCTION__);\r
- /***************SET SCALER PLL FROM CLKIN ,DIV 0*/\r
- if(screen->s_pixclock != 0){\r
- OD = (screen->s_pixclock)&0x3;\r
- N = (screen->s_pixclock >>4)&0xf;\r
- M = (screen->s_pixclock >>8)&0xff;\r
- }else {\r
- RK610_ERR(&client->dev,"RK610 Scaler pll not support rate \n");\r
- }\r
- c = S_PLL_FROM_DIV<<3 | S_PLL_DIV(0);\r
- rk610_scaler_write_p0_reg(client, CLOCK_CON0, &c);\r
- \r
- c = S_DIV_N(N)| S_DIV_OD(OD);\r
- rk610_scaler_write_p0_reg(client, S_PLL_CON0, &c);\r
- c = S_DIV_M(M);\r
- rk610_scaler_write_p0_reg(client, S_PLL_CON1, &c);\r
- rk610_scaler_pll_enable(client);\r
- return 0;\r
-}\r
-\r
-\r
-static int scale_hv_factor(struct i2c_client *client ,u32 Hin_act, u32 Hout_act, u32 Vin_act, u32 Vout_act)\r
- {\r
- char c;\r
- u32 hfactor_f,vfactor_f,scl_factor_f;\r
- int hfactor;\r
- int vfactor;\r
- struct scl_hv_info HV2;\r
- hfactor_f = ((Hin_act-1)*4096)/(Hout_act-1);\r
- if(hfactor_f==4096)\r
- {hfactor = 0x1000;}\r
- else if(hfactor_f>(int)hfactor_f)\r
- {hfactor = (int)hfactor_f+1;}\r
- else\r
- {hfactor = (int)hfactor_f;}\r
- \r
- scl_factor_f = Vin_act/Vout_act;\r
- if(scl_factor_f<2)\r
- {vfactor_f = ((Vin_act-1)*4096)/(Vout_act-1);}\r
- else\r
- {vfactor_f = ((Vin_act-2)*4096)/(Vout_act-1);} \r
- if(vfactor_f==4096)\r
- {vfactor = 0x1000;}\r
- else if(vfactor_f>(int)vfactor_f)\r
- {vfactor = (int)vfactor_f+1;}\r
- else\r
- {vfactor = (int)vfactor_f;}\r
- \r
- HV2.scl_h= hfactor;\r
- HV2.scl_v= vfactor; \r
- /* SCL FACTOR */\r
- c = SCL_H_FACTOR_LSB(HV2.scl_h);\r
- rk610_scaler_write_p0_reg(client, SCL_CON1, &c);\r
- c = SCL_H_FACTOR_MSB(HV2.scl_h);\r
- rk610_scaler_write_p0_reg(client, SCL_CON2, &c);\r
-\r
- c = SCL_V_FACTOR_LSB(HV2.scl_v);\r
- rk610_scaler_write_p0_reg(client, SCL_CON3, &c);\r
- c = SCL_V_FACTOR_MSB(HV2.scl_v);\r
- rk610_scaler_write_p0_reg(client, SCL_CON4, &c);\r
- return 0;\r
- }\r
-\r
-static int rk610_scaler_fator_config(struct i2c_client *client ,struct rk29fb_screen *screen)\r
-{\r
- switch(screen->hdmi_resolution){\r
- case HDMI_1920x1080p_60Hz:\r
- case HDMI_1920x1080p_50Hz:\r
- rk610_scaler_pll_set(client,screen,148500000);\r
- /***************set scaler factor********************/\r
- scale_hv_factor(client,1920,screen->x_res,1080,screen->y_res);\r
- break;\r
- case HDMI_1280x720p_60Hz:\r
- case HDMI_1280x720p_50Hz:\r
- rk610_scaler_pll_set(client,screen,74250000);\r
- /***************set scaler factor********************/\r
- scale_hv_factor(client,1280,screen->x_res,720,screen->y_res);\r
- break;\r
- case HDMI_720x576p_50Hz_16x9:\r
- case HDMI_720x576p_50Hz_4x3:\r
- rk610_scaler_pll_set(client,screen,27000000);\r
- /***************set scaler factor********************/\r
- scale_hv_factor(client,720,screen->x_res,576,screen->y_res);\r
- break;\r
- case HDMI_720x480p_60Hz_16x9:\r
- case HDMI_720x480p_60Hz_4x3:\r
- rk610_scaler_pll_set(client,screen,27000000);\r
- /***************set scaler factor********************/\r
- scale_hv_factor(client,720,screen->x_res,480,screen->y_res);\r
- break;\r
- default :\r
- RK610_ERR(&client->dev,"RK610 not support dual display at hdmi resolution=%d \n",screen->hdmi_resolution); \r
- return -1;\r
- break;\r
- }\r
- return 0;\r
-}\r
-static int rk610_scaler_output_timing_config(struct i2c_client *client,struct rk29fb_screen *screen)\r
-{\r
- char c;\r
- int h_st = screen->s_hsync_st;\r
- int hs_end = screen->s_hsync_len;\r
- int h_act_st = hs_end + screen->s_left_margin;\r
- int xres = screen->x_res;\r
- int h_act_end = h_act_st + xres;\r
- int h_total = h_act_end + screen->s_right_margin;\r
- int v_st = screen->s_vsync_st;\r
- int vs_end = screen->s_vsync_len;\r
- int v_act_st = vs_end + screen->s_upper_margin;\r
- int yres = screen->y_res; \r
- int v_act_end = v_act_st + yres;\r
- int v_total = v_act_end + screen->s_lower_margin;\r
-\r
- /* SCL display Frame start point */\r
- c = SCL_DSP_HST_LSB(h_st);\r
- rk610_scaler_write_p0_reg(client, SCL_CON5, &c);\r
- c = SCL_DSP_HST_MSB(h_st);\r
- rk610_scaler_write_p0_reg(client, SCL_CON6, &c);\r
-\r
- c = SCL_DSP_VST_LSB(v_st);\r
- rk610_scaler_write_p0_reg(client, SCL_CON7, &c);\r
- c = SCL_DSP_VST_MSB(v_st);\r
- rk610_scaler_write_p0_reg(client, SCL_CON8, &c);\r
- /* SCL output timing */\r
-\r
- c = SCL_DSP_HTOTAL_LSB(h_total);\r
- rk610_scaler_write_p0_reg(client, SCL_CON9, &c);\r
- c = SCL_DSP_HTOTAL_MSB(h_total);\r
- rk610_scaler_write_p0_reg(client, SCL_CON10, &c);\r
-\r
- c = SCL_DSP_HS_END(hs_end);\r
- rk610_scaler_write_p0_reg(client, SCL_CON11, &c);\r
-\r
- c = SCL_DSP_HACT_ST_LSB(h_act_st);\r
- rk610_scaler_write_p0_reg(client, SCL_CON12, &c);\r
- c = SCL_DSP_HACT_ST_MSB(h_act_st);\r
- rk610_scaler_write_p0_reg(client, SCL_CON13, &c);\r
-\r
- c = SCL_DSP_HACT_END_LSB(h_act_end);\r
- rk610_scaler_write_p0_reg(client, SCL_CON14, &c);\r
- c = SCL_DSP_HACT_END_MSB(h_act_end);\r
- rk610_scaler_write_p0_reg(client, SCL_CON15, &c);\r
-\r
- c = SCL_DSP_VTOTAL_LSB(v_total);\r
- rk610_scaler_write_p0_reg(client, SCL_CON16, &c);\r
- c = SCL_DSP_VTOTAL_MSB(v_total);\r
- rk610_scaler_write_p0_reg(client, SCL_CON17, &c);\r
-\r
- c = SCL_DSP_VS_END(vs_end);\r
- rk610_scaler_write_p0_reg(client, SCL_CON18, &c);\r
-\r
- c = SCL_DSP_VACT_ST(v_act_st);\r
- rk610_scaler_write_p0_reg(client, SCL_CON19, &c);\r
-\r
- c = SCL_DSP_VACT_END_LSB(v_act_end);\r
- rk610_scaler_write_p0_reg(client, SCL_CON20, &c);\r
- c = SCL_DSP_VACT_END_MSB(v_act_end); \r
- rk610_scaler_write_p0_reg(client, SCL_CON21, &c);\r
- \r
- c = SCL_H_BORD_ST_LSB(h_act_st);\r
- rk610_scaler_write_p0_reg(client, SCL_CON22, &c);\r
- c = SCL_H_BORD_ST_MSB(h_act_st);\r
- rk610_scaler_write_p0_reg(client, SCL_CON23, &c);\r
-\r
- c = SCL_H_BORD_END_LSB(h_act_end);\r
- rk610_scaler_write_p0_reg(client, SCL_CON24, &c);\r
- c = SCL_H_BORD_END_MSB(h_act_end);\r
- rk610_scaler_write_p0_reg(client, SCL_CON25, &c);\r
-\r
- c = SCL_V_BORD_ST(v_act_st);\r
- rk610_scaler_write_p0_reg(client, SCL_CON26, &c);\r
-\r
- c = SCL_V_BORD_END_LSB(v_act_end);\r
- rk610_scaler_write_p0_reg(client, SCL_CON27, &c);\r
- c = SCL_V_BORD_END_MSB(v_act_end);\r
- rk610_scaler_write_p0_reg(client, SCL_CON28, &c);\r
- \r
- return 0;\r
-}\r
-static int rk610_scaler_chg(struct i2c_client *client ,struct rk29fb_screen *screen)\r
-{\r
-\r
- RK610_DBG(&client->dev,"%s screen->hdmi_resolution=%d\n",__FUNCTION__,screen->hdmi_resolution);\r
- rk610_scaler_fator_config(client,screen);\r
- rk610_scaler_enable(client);\r
- rk610_scaler_output_timing_config(client,screen); \r
- \r
- return 0;\r
-\r
-}\r
-#endif\r
-static int rk610_lcd_scaler_bypass(struct i2c_client *client,bool enable)//enable:0 bypass 1: scale\r
-{\r
- RK610_DBG(&client->dev,"%s \n",__FUNCTION__);\r
- \r
- rk610_scaler_disable(client); \r
- rk610_scaler_pll_disable(client);\r
- \r
- return 0;\r
-}\r
-\r
-#ifdef CONFIG_HAS_EARLYSUSPEND\r
-static void rk610_lcd_early_suspend(struct early_suspend *h)\r
-{\r
- struct i2c_client *client = g_lcd_inf->client;\r
- char c;\r
- RK610_DBG(&client->dev,"%s \n",__FUNCTION__);\r
- if(g_lcd_inf->screen != NULL){\r
- rk610_output_config(client,g_lcd_inf->screen,LCD_OUT_DISABLE);\r
- }\r
-\r
- if(ENABLE == g_lcd_inf->scl_inf.scl_pwr){\r
- c= SCL_BYPASS(1) |SCL_DEN_INV(0) |SCL_H_V_SYNC_INV(0) |SCL_OUT_CLK_INV(0) |SCL_ENABLE(DISABLE); \r
- rk610_scaler_write_p0_reg(client, SCL_CON0, &c);\r
- }\r
- if(ENABLE == g_lcd_inf->scl_inf.pll_pwr ){\r
- c = S_PLL_PWR(1) |S_PLL_RESET(0) |S_PLL_BYPASS(1);\r
- rk610_scaler_write_p0_reg(client, S_PLL_CON2, &c);\r
- }\r
-}\r
-\r
-static void rk610_lcd_early_resume(struct early_suspend *h)\r
-{\r
- struct i2c_client *client = g_lcd_inf->client;\r
- char c;\r
- RK610_DBG(&client->dev,"%s \n",__FUNCTION__);\r
-\r
- if(g_lcd_inf->screen != NULL){\r
- rk610_output_config(client,g_lcd_inf->screen,g_lcd_inf->disp_mode);\r
- }\r
- if(ENABLE == g_lcd_inf->scl_inf.scl_pwr){\r
- c= SCL_BYPASS(0) |SCL_DEN_INV(0) |SCL_H_V_SYNC_INV(0) |SCL_OUT_CLK_INV(0) |SCL_ENABLE(ENABLE); \r
- rk610_scaler_write_p0_reg(client, SCL_CON0, &c);\r
- }\r
- if(ENABLE == g_lcd_inf->scl_inf.pll_pwr ){\r
- c = S_PLL_PWR(1) |S_PLL_RESET(0) |S_PLL_BYPASS(1);\r
- rk610_scaler_write_p0_reg(client, S_PLL_CON2, &c);\r
- }\r
-}\r
-#endif\r
-int rk610_lcd_scaler_set_param(struct rk29fb_screen *screen,bool enable )//enable:0 bypass 1: scale\r
-{\r
- int ret=0;\r
- struct i2c_client *client = g_lcd_inf->client;\r
- if(client == NULL){\r
- printk("%s client == NULL FAIL\n",__FUNCTION__);\r
- return -1;\r
- }\r
- if(screen == NULL){\r
- printk("%s screen == NULL FAIL\n",__FUNCTION__);\r
- return -1;\r
- }\r
- RK610_DBG(&client->dev,"%s \n",__FUNCTION__);\r
- \r
- g_lcd_inf->screen = screen;\r
- \r
-#ifdef CONFIG_HDMI_DUAL_DISP\r
- if(enable == 1){\r
- g_lcd_inf->disp_mode = LCD_OUT_SCL;\r
- rk610_output_config(client,screen,LCD_OUT_SCL);\r
- ret = rk610_scaler_chg(client,screen);\r
- }\r
- else \r
-#endif\r
- {\r
- g_lcd_inf->disp_mode = LCD_OUT_BYPASS;\r
- rk610_output_config(client,screen,LCD_OUT_BYPASS);\r
- ret = rk610_lcd_scaler_bypass(client,enable);\r
- }\r
- return ret;\r
-}\r
-int rk610_lcd_init(struct rk610_core_info *rk610_core_info)\r
-{\r
- if(rk610_core_info->client == NULL){\r
- printk("%s client == NULL FAIL\n",__FUNCTION__);\r
- return -1;\r
- }\r
- RK610_DBG(&rk610_core_info->client->dev,"%s \n",__FUNCTION__);\r
-\r
- g_lcd_inf = kmalloc(sizeof(struct rk610_lcd_info), GFP_KERNEL);\r
- if(!g_lcd_inf)\r
- {
- dev_err(&rk610_core_info->client->dev, ">> rk610 inf kmalloc fail!");\r
- return -ENOMEM;\r
- }\r
- memset(g_lcd_inf, 0, sizeof(struct rk610_lcd_info));\r
-\r
- g_lcd_inf->client= rk610_core_info->client;\r
- \r
- rk610_core_info->lcd_pdata = (void *)g_lcd_inf;\r
-#ifdef CONFIG_HAS_EARLYSUSPEND\r
- g_lcd_inf->early_suspend.suspend = rk610_lcd_early_suspend;\r
- g_lcd_inf->early_suspend.resume = rk610_lcd_early_resume;\r
- g_lcd_inf->early_suspend.level = EARLY_SUSPEND_LEVEL_DISABLE_FB- 1;
- register_early_suspend(&g_lcd_inf->early_suspend);\r
-#endif\r
- g_lcd_inf->scl_inf.pll_pwr = DISABLE;\r
- g_lcd_inf->scl_inf.scl_pwr = DISABLE;\r
- g_lcd_inf->disp_mode = LCD_OUT_BYPASS;\r
- return 0;\r
-}\r
+++ /dev/null
-#ifndef _RK610_LCD_H\r
-#define _RK610_LCD_H\r
-#include <linux/mfd/rk610_core.h>\r
-#include "../screen/screen.h"\r
-#include <linux/earlysuspend.h>\r
-#define ENABLE 1\r
-#define DISABLE 0\r
-\r
-/* LVDS config */\r
-/* LVDS ÍⲿÁ¬Ïß½Ó·¨ */\r
-/* LVDS_8BIT_1 LVDS_8BIT_2 LVDS_8BIT_3 LVDS_6BIT\r
-----------------------------------------------------------------------\r
- TX0 R0 R2 R2 R0\r
- TX1 R1 R3 R3 R1\r
- TX2 R2 R4 R4 R2\r
-Y TX3 R3 R5 R5 R3\r
-0 TX4 R4 R6 R6 R4\r
- TX6 R5 R7 R7 R5\r
- TX7 G0 G2 G2 G0\r
-----------------------------------------------------------------------\r
- TX8 G1 G3 G3 G1\r
- TX9 G2 G4 G4 G2\r
-Y TX12 G3 G5 G5 G3\r
-1 TX13 G4 G6 G6 G4\r
- TX14 G5 G7 G7 G5\r
- TX15 B0 B2 B2 B0\r
- TX18 B1 B3 B3 B1\r
-----------------------------------------------------------------------\r
- TX19 B2 B4 B4 B2\r
- TX20 B3 B5 B5 B3\r
- TX21 B4 B6 B6 B4\r
-Y TX22 B5 B7 B7 B5\r
-2 TX24 HSYNC HSYNC HSYNC HSYNC\r
- TX25 VSYNC VSYNC VSYNC VSYNC\r
- TX26 ENABLE ENABLE ENABLE ENABLE\r
----------------------------------------------------------------------- \r
- TX27 R6 R0 GND GND\r
- TX5 R7 R1 GND GND\r
- TX10 G6 G0 GND GND\r
-Y TX11 G7 G1 GND GND\r
-3 TX16 B6 B0 GND GND\r
- TX17 B7 B1 GND GND\r
- TX23 RSVD RSVD RSVD RSVD\r
----------------------------------------------------------------------- \r
-*/\r
-#define LVDS_8BIT_1 0x00\r
-#define LVDS_8BIT_2 0x01\r
-#define LVDS_8BIT_3 0x10\r
-#define LVDS_6BIT 0x11\r
-//LVDS lane input format\r
-#define DATA_D0_MSB 0\r
-#define DATA_D7_MSB 1\r
-//LVDS input source\r
-#define FROM_LCD1 0\r
-#define FROM_LCD0_OR_SCL 1\r
-\r
-/* LCD1 config */\r
-#define LCD1_AS_IN 0\r
-#define LCD1_AS_OUT 1\r
-\r
-//LCD1 output source\r
-#define LCD1_FROM_LCD0 0\r
-#define LCD1_FROM_SCL 1\r
-\r
-//SCALER config\r
-#define NOBYPASS 0\r
-#define BYPASS 1\r
-\r
-//SCALER PLL config\r
-#define S_PLL_PWR_ON 0\r
-#define S_PLL_PWR_DOWN 1\r
-\r
-/* clock config */\r
-#define S_PLL_FROM_DIV 0\r
-#define S_PLL_FROM_CLKIN 1\r
-#define S_PLL_DIV(x) ((x)&0x7)\r
-/*********S_PLL_CON************/\r
-//S_PLL_CON0\r
-#define S_DIV_N(x) (((x)&0xf)<<4)\r
-#define S_DIV_OD(x) (((x)&3)<<0)\r
-//S_PLL_CON1\r
-#define S_DIV_M(x) ((x)&0xff)\r
-//S_PLL_CON2\r
-#define S_PLL_UNLOCK (0<<7) //0:unlock 1:pll_lock\r
-#define S_PLL_LOCK (1<<7) //0:unlock 1:pll_lock\r
-#define S_PLL_PWR(x) (((x)&1)<<2) //0:POWER UP 1:POWER DOWN\r
-#define S_PLL_RESET(x) (((x)&1)<<1) //0:normal 1:reset M/N dividers\r
-#define S_PLL_BYPASS(x) (((x)&1)<<0) //0:normal 1:bypass\r
-//LVDS_CON0\r
-#define LVDS_OUT_CLK_PIN(x) (((x)&1)<<7) //clk enable pin, 0: enable\r
-#define LVDS_OUT_CLK_PWR_PIN(x) (((x)&1)<<6) //clk pwr enable pin, 1: enable \r
-#define LVDS_PLL_PWR_PIN(x) (((x)&1)<<5) //pll pwr enable pin, 0:enable \r
-#define LVDS_BIASE_PWR(x) (((x)&1)<<4) //0: power down 1: normal work\r
-#define LVDS_LANE_IN_FORMAT(x) (((x)&1)<<3) //0: msb on D0 1:msb on D7\r
-#define LVDS_INPUT_SOURCE(x) (((x)&1)<<2) //0: from lcd1 1:from lcd0 or scaler\r
-#define LVDS_OUTPUT_FORMAT(x) (((x)&3)<<0) //00:8bit format-1 01:8bit format-2 10:8bit format-3 11:6bit format \r
-//LVDS_CON1\r
-#define LVDS_OUT_ENABLE(x) (((x)&0xf)<<4) //0:output enable 1:output disable\r
-#define LVDS_TX_PWR_ENABLE(x) (((x)&0xf)<<0) //0:working mode 1:power down\r
-//LCD1_CON\r
-#define LCD1_OUT_ENABLE(x) (((x)&1)<<1) //0:lcd1 as input 1:lcd1 as output\r
-#define LCD1_OUT_SRC(x) (((x)&1)<<0) //0:from lcd0 1:from scaler\r
-//SCL_CON0\r
-#define SCL_BYPASS(x) (((x)&1)<<4) //0:not bypass 1:bypass\r
-#define SCL_DEN_INV(x) (((x)&1)<<3) //scl_den_inv\r
-#define SCL_H_V_SYNC_INV(x) (((x)&1)<<2) //scl_sync_inv\r
-#define SCL_OUT_CLK_INV(x) (((x)&1)<<1) //scl_dclk_inv\r
-#define SCL_ENABLE(x) (((x)&1)<<0) //scaler enable\r
-//SCL_CON1\r
-#define SCL_H_FACTOR_LSB(x) ((x)&0xff) //scl_h_factor[7:0]\r
-//SCL_CON2\r
-#define SCL_H_FACTOR_MSB(x) (((x)>>8)&0x3f) //scl_h_factor[13:8]\r
-//SCL_CON3\r
-#define SCL_V_FACTOR_LSB(x) ((x)&0xff) //scl_v_factor[7:0]\r
-//SCL_CON4\r
-#define SCL_V_FACTOR_MSB(x) (((x)>>8)&0x3f) //scl_v_factor[13:8]\r
-//SCL_CON5\r
-#define SCL_DSP_HST_LSB(x) ((x)&0xff) //dsp_frame_hst[7:0]\r
-//SCL_CON6\r
-#define SCL_DSP_HST_MSB(x) (((x)>>8)&0xf) //dsp_frame_hst[11:8]\r
-//SCL_CON7\r
-#define SCL_DSP_VST_LSB(x) ((x)&0xff) //dsp_frame_vst[7:0]\r
-//SCL_CON8\r
-#define SCL_DSP_VST_MSB(x) (((x)>>8)&0xf) //dsp_frame_vst[11:8]\r
-//SCL_CON9\r
-#define SCL_DSP_HTOTAL_LSB(x) ((x)&0xff) //dsp_frame_htotal[7:0]\r
-//SCL_CON10\r
-#define SCL_DSP_HTOTAL_MSB(x) (((x)>>8)&0xf) //dsp_frame_htotal[11:8]\r
-//SCL_CON11\r
-#define SCL_DSP_HS_END(x) ((x)&0xff) //dsp_hs_end\r
-//SCL_CON12\r
-#define SCL_DSP_HACT_ST_LSB(x) ((x)&0xff) //dsp_hact_st[7:0]\r
-//SCL_CON13\r
-#define SCL_DSP_HACT_ST_MSB(x) (((x)>>8)&0x3) //dsp_hact_st[9:8]\r
-//SCL_CON14\r
-#define SCL_DSP_HACT_END_LSB(x) ((x)&0xff) //dsp_hact_end[7:0]\r
-//SCL_CON15\r
-#define SCL_DSP_HACT_END_MSB(x) (((x)>>8)&0xf) //dsp_frame_htotal[11:8]\r
-//SCL_CON16\r
-#define SCL_DSP_VTOTAL_LSB(x) ((x)&0xff) //dsp_frame_vtotal[7:0]\r
-//SCL_CON17\r
-#define SCL_DSP_VTOTAL_MSB(x) (((x)>>8)&0xf) //dsp_frame_vtotal[11:8]\r
-//SCL_CON18\r
-#define SCL_DSP_VS_END(x) ((x)&0xff) //dsp_vs_end\r
-//SCL_CON19\r
-#define SCL_DSP_VACT_ST(x) ((x)&0xff) //dsp_vact_st[7:0]\r
-//SCL_CON20\r
-#define SCL_DSP_VACT_END_LSB(x) ((x)&0xff) //dsp_vact_end[7:0]\r
-//SCL_CON21\r
-#define SCL_DSP_VACT_END_MSB(x) (((x)>>8)&0xf) //dsp_frame_vtotal[11:8]\r
-//SCL_CON22\r
-#define SCL_H_BORD_ST_LSB(x) ((x)&0xff) //dsp_hbord_st[7:0]\r
-//SCL_CON23\r
-#define SCL_H_BORD_ST_MSB(x) (((x)>>8)&0x3) //dsp_hbord_st[9:8]\r
-//SCL_CON24\r
-#define SCL_H_BORD_END_LSB(x) ((x)&0xff) //dsp_hbord_end[7:0]\r
-//SCL_CON25\r
-#define SCL_H_BORD_END_MSB(x) (((x)>>8)&0xf) //dsp_hbord_end[11:8]\r
-//SCL_CON26\r
-#define SCL_V_BORD_ST(x) ((x)&0xff) //dsp_vbord_st[7:0]\r
-//SCL_CON27\r
-#define SCL_V_BORD_END_LSB(x) ((x)&0xff) //dsp_vbord_end[7:0]\r
-//SCL_CON25\r
-#define SCL_V_BORD_END_MSB(x) (((x)>>8)&0xf) //dsp_vbord_end[11:8]\r
-\r
-enum {\r
- LCD_OUT_SCL,\r
- LCD_OUT_BYPASS,\r
- LCD_OUT_DISABLE,\r
-};\r
-struct rk610_pll_info{\r
- u32 parent_rate;\r
- u32 rate;\r
- int m;\r
- int n;\r
- int od;\r
-};\r
-struct lcd_mode_inf{\r
- int h_pw;\r
- int h_bp;\r
- int h_vd;\r
- int h_fp;\r
- int v_pw;\r
- int v_bp;\r
- int v_vd;\r
- int v_fp;\r
- int f_hst;\r
- int f_vst;\r
- struct rk610_pll_info pllclk;\r
-};\r
-struct scl_hv_info{\r
- int scl_h ;\r
- int scl_v;\r
- };\r
-\r
-struct scl_info{\r
- bool pll_pwr;\r
- bool scl_pwr;\r
- struct scl_hv_info scl_hv;\r
-};\r
-struct rk610_lcd_info{\r
- int disp_mode;\r
- \r
- struct rk29fb_screen *screen;\r
- struct scl_info scl_inf;\r
- struct i2c_client *client;\r
-\r
-#ifdef CONFIG_HAS_EARLYSUSPEND\r
- struct early_suspend early_suspend;
-#endif\r
-};\r
-extern int rk610_lcd_init(struct rk610_core_info *rk610_core_info);\r
-extern int rk610_lcd_scaler_set_param(struct rk29fb_screen *screen,bool enable );\r
-#endif\r
#include <mach/board.h>\r
#include "screen.h"\r
\r
-#ifdef CONFIG_RK610_LCD\r
-#include "../lcd/rk610_lcd.h"\r
+#ifdef CONFIG_RK610_LVDS\r
+#include "../transmitter/rk610_lcd.h"\r
#endif\r
\r
\r
/* Base */\r
-#ifdef CONFIG_RK610_LCD\r
-#define OUT_TYPE SCREEN_LVDS\r
-#define OUT_FORMAT LVDS_8BIT_2\r
+#ifdef CONFIG_RK610_LVDS\r
+#define OUT_TYPE SCREEN_LVDS\r
+#define OUT_FORMAT LVDS_8BIT_2\r
#else\r
#define OUT_TYPE SCREEN_RGB\r
#endif\r
#define LCD_WIDTH 216\r
#define LCD_HEIGHT 135\r
/* Other */\r
-#ifdef CONFIG_RK610_LCD\r
+#ifdef CONFIG_RK610_LVDS\r
#define DCLK_POL 1\r
#else\r
#define DCLK_POL 0\r
-\r
#endif\r
+\r
#define SWAP_RB 0\r
\r
int dsp_lut[256] ={\r
screen->standby = NULL;\r
screen->dsp_lut = dsp_lut;\r
screen->sscreen_get = NULL;//set_scaler_info;\r
-#ifdef CONFIG_RK610_LCD\r
+#ifdef CONFIG_RK610_LVDS\r
screen->sscreen_set = rk610_lcd_scaler_set_param;\r
#endif\r
}\r
#include "screen.h"\r
#include <linux/hdmi.h>\r
#include "../../rk29_fb.h"\r
-#include "../lcd/rk610_lcd.h"\r
+\r
\r
/* Base */\r
#define OUT_TYPE SCREEN_LVDS\r
screen->init = NULL;\r
screen->standby = NULL;\r
screen->sscreen_get = set_scaler_info;\r
-#ifdef CONFIG_RK610_LCD\r
+#ifdef CONFIG_RK610_LVDS\r
screen->sscreen_set = rk610_lcd_scaler_set_param;\r
#endif\r
}
\ No newline at end of file
#include "screen.h"\r
#include <linux/hdmi.h>\r
#include "../../rk29_fb.h"\r
-#include "../lcd/rk610_lcd.h"\r
+#include "../transmitter/rk610_lcd.h"\r
\r
\r
/* Base */\r
#include "screen.h"\r
#include <linux/hdmi.h>\r
#include "../../rk29_fb.h"\r
-#include "../lcd/rk610_lcd.h"\r
+#include "../transmitter/rk610_lcd.h"\r
\r
/* Base */\r
#define OUT_TYPE SCREEN_RGB\r
screen->init = NULL;\r
screen->standby = NULL;\r
screen->sscreen_get = set_scaler_info;\r
-#ifdef CONFIG_RK610_LCD\r
+#ifdef CONFIG_RK610_LVDS\r
screen->sscreen_set = rk610_lcd_scaler_set_param;\r
#endif\r
}\r
--- /dev/null
+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.
--- /dev/null
+#
+# Makefile for the jetta tv control.
+#
+obj-$(CONFIG_RK610_LVDS) += rk610_lcd.o
--- /dev/null
+#include <linux/fb.h>\r
+#include <linux/delay.h>\r
+#include <mach/gpio.h>\r
+#include <mach/iomux.h>\r
+#include <mach/board.h>\r
+\r
+#include <linux/hdmi.h>\r
+#include "rk610_lcd.h"\r
+#include <linux/mfd/rk610_core.h>\r
+#include "../../rk29_fb.h"\r
+static struct rk610_lcd_info *g_lcd_inf = NULL;\r
+//static int rk610_scaler_read_p0_reg(struct i2c_client *client, char reg, char *val)\r
+//{\r
+ //return i2c_master_reg8_recv(client, reg, val, 1, 100*1000) > 0? 0: -EINVAL;\r
+//}\r
+\r
+static int rk610_scaler_write_p0_reg(struct i2c_client *client, char reg, char *val)\r
+{\r
+ return i2c_master_reg8_send(client, reg, val, 1, 100*1000) > 0? 0: -EINVAL;\r
+}\r
+static void rk610_scaler_pll_enable(struct i2c_client *client)\r
+{\r
+ char c;\r
+ RK610_DBG(&client->dev,"%s \n",__FUNCTION__);\r
+\r
+ g_lcd_inf->scl_inf.pll_pwr = ENABLE;\r
+ \r
+ c = S_PLL_PWR(0)|S_PLL_RESET(0)|S_PLL_BYPASS(0);\r
+ rk610_scaler_write_p0_reg(client, S_PLL_CON2, &c);\r
+}\r
+static void rk610_scaler_pll_disable(struct i2c_client *client)\r
+{\r
+ char c;\r
+ RK610_DBG(&client->dev,"%s \n",__FUNCTION__);\r
+ \r
+ g_lcd_inf->scl_inf.pll_pwr = DISABLE;\r
+\r
+ c = S_PLL_PWR(1) |S_PLL_RESET(0) |S_PLL_BYPASS(1);\r
+ rk610_scaler_write_p0_reg(client, S_PLL_CON2, &c);\r
+}\r
+static void rk610_scaler_enable(struct i2c_client *client)\r
+{\r
+ char c;\r
+ bool den_inv = 0,hv_sync_inv = 0,clk_inv = 0;\r
+ RK610_DBG(&client->dev,"%s \n",__FUNCTION__);\r
+ g_lcd_inf->scl_inf.scl_pwr = ENABLE;\r
+ #ifdef CONFIG_HDMI_DUAL_DISP\r
+ if(g_lcd_inf->screen !=NULL){\r
+ den_inv = g_lcd_inf->screen->s_den_inv;\r
+ hv_sync_inv = g_lcd_inf->screen->s_hv_sync_inv;\r
+ clk_inv = g_lcd_inf->screen->s_clk_inv;\r
+ }\r
+ #endif\r
+ 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); \r
+ rk610_scaler_write_p0_reg(client, SCL_CON0, &c);\r
+}\r
+static void rk610_scaler_disable(struct i2c_client *client)\r
+{\r
+ char c;\r
+ bool den_inv = 0,hv_sync_inv = 0,clk_inv = 0;\r
+ RK610_DBG(&client->dev,"%s \n",__FUNCTION__);\r
+ \r
+ g_lcd_inf->scl_inf.scl_pwr = DISABLE;\r
+ #ifdef CONFIG_HDMI_DUAL_DISP\r
+ if(g_lcd_inf->screen !=NULL){\r
+ den_inv = g_lcd_inf->screen->s_den_inv;\r
+ hv_sync_inv = g_lcd_inf->screen->s_hv_sync_inv;\r
+ clk_inv = g_lcd_inf->screen->s_clk_inv;\r
+ }\r
+ #endif\r
+ 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); \r
+ rk610_scaler_write_p0_reg(client, SCL_CON0, &c);\r
+}\r
+\r
+static int rk610_output_config(struct i2c_client *client,struct rk29fb_screen *screen,int mode)\r
+{\r
+ char c=0;\r
+ RK610_DBG(&client->dev,"%s \n",__FUNCTION__);\r
+ if(SCREEN_LVDS == screen->type){\r
+ if(mode == LCD_OUT_SCL || mode == LCD_OUT_BYPASS){\r
+ c = LVDS_OUT_CLK_PIN(0) |LVDS_OUT_CLK_PWR_PIN(1) |LVDS_PLL_PWR_PIN(0) \\r
+ |LVDS_LANE_IN_FORMAT(DATA_D0_MSB) |LVDS_INPUT_SOURCE(FROM_LCD0_OR_SCL) \\r
+ |LVDS_OUTPUT_FORMAT(screen->hw_format) | LVDS_BIASE_PWR(1); \r
+ rk610_scaler_write_p0_reg(client, LVDS_CON0, &c);\r
+ c = LVDS_OUT_ENABLE(0x0) |LVDS_TX_PWR_ENABLE(0x0); \r
+ rk610_scaler_write_p0_reg(client, LVDS_CON1, &c);\r
+ }\r
+ else{\r
+ c = LVDS_OUT_CLK_PIN(0) |LVDS_OUT_CLK_PWR_PIN(0) |LVDS_PLL_PWR_PIN(1) \\r
+ |LVDS_LANE_IN_FORMAT(DATA_D0_MSB) |LVDS_INPUT_SOURCE(FROM_LCD0_OR_SCL) \\r
+ |LVDS_OUTPUT_FORMAT(screen->hw_format) | LVDS_BIASE_PWR(0); \r
+ rk610_scaler_write_p0_reg(client, LVDS_CON0, &c);\r
+ c = LVDS_OUT_ENABLE(0xf) |LVDS_TX_PWR_ENABLE(0xf); \r
+ rk610_scaler_write_p0_reg(client, LVDS_CON1, &c);\r
+ \r
+ }\r
+ }else if(SCREEN_RGB == screen->type){\r
+ if(mode == LCD_OUT_SCL || mode == LCD_OUT_BYPASS){\r
+ c = LCD1_OUT_ENABLE(LCD1_AS_OUT) | LCD1_OUT_SRC((mode == LCD_OUT_SCL)?LCD1_FROM_SCL : LCD1_FROM_LCD0);\r
+ rk610_scaler_write_p0_reg(client, LCD1_CON, &c);\r
+ }\r
+ else {\r
+ c = LCD1_OUT_ENABLE(LCD1_AS_IN);\r
+ rk610_scaler_write_p0_reg(client, LCD1_CON, &c);\r
+ }\r
+ }\r
+ return 0;\r
+}\r
+#ifdef CONFIG_HDMI_DUAL_DISP\r
+static int rk610_scaler_pll_set(struct i2c_client *client,struct rk29fb_screen *screen,u32 clkin )\r
+{\r
+ char c=0;\r
+ char M=0,N=0,OD=0;\r
+ RK610_DBG(&client->dev,"%s \n",__FUNCTION__);\r
+ /***************SET SCALER PLL FROM CLKIN ,DIV 0*/\r
+ if(screen->s_pixclock != 0){\r
+ OD = (screen->s_pixclock)&0x3;\r
+ N = (screen->s_pixclock >>4)&0xf;\r
+ M = (screen->s_pixclock >>8)&0xff;\r
+ }else {\r
+ RK610_ERR(&client->dev,"RK610 Scaler pll not support rate \n");\r
+ }\r
+ c = S_PLL_FROM_DIV<<3 | S_PLL_DIV(0);\r
+ rk610_scaler_write_p0_reg(client, CLOCK_CON0, &c);\r
+ \r
+ c = S_DIV_N(N)| S_DIV_OD(OD);\r
+ rk610_scaler_write_p0_reg(client, S_PLL_CON0, &c);\r
+ c = S_DIV_M(M);\r
+ rk610_scaler_write_p0_reg(client, S_PLL_CON1, &c);\r
+ rk610_scaler_pll_enable(client);\r
+ return 0;\r
+}\r
+\r
+\r
+static int scale_hv_factor(struct i2c_client *client ,u32 Hin_act, u32 Hout_act, u32 Vin_act, u32 Vout_act)\r
+ {\r
+ char c;\r
+ u32 hfactor_f,vfactor_f,scl_factor_f;\r
+ int hfactor;\r
+ int vfactor;\r
+ struct scl_hv_info HV2;\r
+ hfactor_f = ((Hin_act-1)*4096)/(Hout_act-1);\r
+ if(hfactor_f==4096)\r
+ {hfactor = 0x1000;}\r
+ else if(hfactor_f>(int)hfactor_f)\r
+ {hfactor = (int)hfactor_f+1;}\r
+ else\r
+ {hfactor = (int)hfactor_f;}\r
+ \r
+ scl_factor_f = Vin_act/Vout_act;\r
+ if(scl_factor_f<2)\r
+ {vfactor_f = ((Vin_act-1)*4096)/(Vout_act-1);}\r
+ else\r
+ {vfactor_f = ((Vin_act-2)*4096)/(Vout_act-1);} \r
+ if(vfactor_f==4096)\r
+ {vfactor = 0x1000;}\r
+ else if(vfactor_f>(int)vfactor_f)\r
+ {vfactor = (int)vfactor_f+1;}\r
+ else\r
+ {vfactor = (int)vfactor_f;}\r
+ \r
+ HV2.scl_h= hfactor;\r
+ HV2.scl_v= vfactor; \r
+ /* SCL FACTOR */\r
+ c = SCL_H_FACTOR_LSB(HV2.scl_h);\r
+ rk610_scaler_write_p0_reg(client, SCL_CON1, &c);\r
+ c = SCL_H_FACTOR_MSB(HV2.scl_h);\r
+ rk610_scaler_write_p0_reg(client, SCL_CON2, &c);\r
+\r
+ c = SCL_V_FACTOR_LSB(HV2.scl_v);\r
+ rk610_scaler_write_p0_reg(client, SCL_CON3, &c);\r
+ c = SCL_V_FACTOR_MSB(HV2.scl_v);\r
+ rk610_scaler_write_p0_reg(client, SCL_CON4, &c);\r
+ return 0;\r
+ }\r
+\r
+static int rk610_scaler_fator_config(struct i2c_client *client ,struct rk29fb_screen *screen)\r
+{\r
+ switch(screen->hdmi_resolution){\r
+ case HDMI_1920x1080p_60Hz:\r
+ case HDMI_1920x1080p_50Hz:\r
+ rk610_scaler_pll_set(client,screen,148500000);\r
+ /***************set scaler factor********************/\r
+ scale_hv_factor(client,1920,screen->x_res,1080,screen->y_res);\r
+ break;\r
+ case HDMI_1280x720p_60Hz:\r
+ case HDMI_1280x720p_50Hz:\r
+ rk610_scaler_pll_set(client,screen,74250000);\r
+ /***************set scaler factor********************/\r
+ scale_hv_factor(client,1280,screen->x_res,720,screen->y_res);\r
+ break;\r
+ case HDMI_720x576p_50Hz_16x9:\r
+ case HDMI_720x576p_50Hz_4x3:\r
+ rk610_scaler_pll_set(client,screen,27000000);\r
+ /***************set scaler factor********************/\r
+ scale_hv_factor(client,720,screen->x_res,576,screen->y_res);\r
+ break;\r
+ case HDMI_720x480p_60Hz_16x9:\r
+ case HDMI_720x480p_60Hz_4x3:\r
+ rk610_scaler_pll_set(client,screen,27000000);\r
+ /***************set scaler factor********************/\r
+ scale_hv_factor(client,720,screen->x_res,480,screen->y_res);\r
+ break;\r
+ default :\r
+ RK610_ERR(&client->dev,"RK610 not support dual display at hdmi resolution=%d \n",screen->hdmi_resolution); \r
+ return -1;\r
+ break;\r
+ }\r
+ return 0;\r
+}\r
+static int rk610_scaler_output_timing_config(struct i2c_client *client,struct rk29fb_screen *screen)\r
+{\r
+ char c;\r
+ int h_st = screen->s_hsync_st;\r
+ int hs_end = screen->s_hsync_len;\r
+ int h_act_st = hs_end + screen->s_left_margin;\r
+ int xres = screen->x_res;\r
+ int h_act_end = h_act_st + xres;\r
+ int h_total = h_act_end + screen->s_right_margin;\r
+ int v_st = screen->s_vsync_st;\r
+ int vs_end = screen->s_vsync_len;\r
+ int v_act_st = vs_end + screen->s_upper_margin;\r
+ int yres = screen->y_res; \r
+ int v_act_end = v_act_st + yres;\r
+ int v_total = v_act_end + screen->s_lower_margin;\r
+\r
+ /* SCL display Frame start point */\r
+ c = SCL_DSP_HST_LSB(h_st);\r
+ rk610_scaler_write_p0_reg(client, SCL_CON5, &c);\r
+ c = SCL_DSP_HST_MSB(h_st);\r
+ rk610_scaler_write_p0_reg(client, SCL_CON6, &c);\r
+\r
+ c = SCL_DSP_VST_LSB(v_st);\r
+ rk610_scaler_write_p0_reg(client, SCL_CON7, &c);\r
+ c = SCL_DSP_VST_MSB(v_st);\r
+ rk610_scaler_write_p0_reg(client, SCL_CON8, &c);\r
+ /* SCL output timing */\r
+\r
+ c = SCL_DSP_HTOTAL_LSB(h_total);\r
+ rk610_scaler_write_p0_reg(client, SCL_CON9, &c);\r
+ c = SCL_DSP_HTOTAL_MSB(h_total);\r
+ rk610_scaler_write_p0_reg(client, SCL_CON10, &c);\r
+\r
+ c = SCL_DSP_HS_END(hs_end);\r
+ rk610_scaler_write_p0_reg(client, SCL_CON11, &c);\r
+\r
+ c = SCL_DSP_HACT_ST_LSB(h_act_st);\r
+ rk610_scaler_write_p0_reg(client, SCL_CON12, &c);\r
+ c = SCL_DSP_HACT_ST_MSB(h_act_st);\r
+ rk610_scaler_write_p0_reg(client, SCL_CON13, &c);\r
+\r
+ c = SCL_DSP_HACT_END_LSB(h_act_end);\r
+ rk610_scaler_write_p0_reg(client, SCL_CON14, &c);\r
+ c = SCL_DSP_HACT_END_MSB(h_act_end);\r
+ rk610_scaler_write_p0_reg(client, SCL_CON15, &c);\r
+\r
+ c = SCL_DSP_VTOTAL_LSB(v_total);\r
+ rk610_scaler_write_p0_reg(client, SCL_CON16, &c);\r
+ c = SCL_DSP_VTOTAL_MSB(v_total);\r
+ rk610_scaler_write_p0_reg(client, SCL_CON17, &c);\r
+\r
+ c = SCL_DSP_VS_END(vs_end);\r
+ rk610_scaler_write_p0_reg(client, SCL_CON18, &c);\r
+\r
+ c = SCL_DSP_VACT_ST(v_act_st);\r
+ rk610_scaler_write_p0_reg(client, SCL_CON19, &c);\r
+\r
+ c = SCL_DSP_VACT_END_LSB(v_act_end);\r
+ rk610_scaler_write_p0_reg(client, SCL_CON20, &c);\r
+ c = SCL_DSP_VACT_END_MSB(v_act_end); \r
+ rk610_scaler_write_p0_reg(client, SCL_CON21, &c);\r
+ \r
+ c = SCL_H_BORD_ST_LSB(h_act_st);\r
+ rk610_scaler_write_p0_reg(client, SCL_CON22, &c);\r
+ c = SCL_H_BORD_ST_MSB(h_act_st);\r
+ rk610_scaler_write_p0_reg(client, SCL_CON23, &c);\r
+\r
+ c = SCL_H_BORD_END_LSB(h_act_end);\r
+ rk610_scaler_write_p0_reg(client, SCL_CON24, &c);\r
+ c = SCL_H_BORD_END_MSB(h_act_end);\r
+ rk610_scaler_write_p0_reg(client, SCL_CON25, &c);\r
+\r
+ c = SCL_V_BORD_ST(v_act_st);\r
+ rk610_scaler_write_p0_reg(client, SCL_CON26, &c);\r
+\r
+ c = SCL_V_BORD_END_LSB(v_act_end);\r
+ rk610_scaler_write_p0_reg(client, SCL_CON27, &c);\r
+ c = SCL_V_BORD_END_MSB(v_act_end);\r
+ rk610_scaler_write_p0_reg(client, SCL_CON28, &c);\r
+ \r
+ return 0;\r
+}\r
+static int rk610_scaler_chg(struct i2c_client *client ,struct rk29fb_screen *screen)\r
+{\r
+\r
+ RK610_DBG(&client->dev,"%s screen->hdmi_resolution=%d\n",__FUNCTION__,screen->hdmi_resolution);\r
+ rk610_scaler_fator_config(client,screen);\r
+ rk610_scaler_enable(client);\r
+ rk610_scaler_output_timing_config(client,screen); \r
+ \r
+ return 0;\r
+\r
+}\r
+#endif\r
+static int rk610_lcd_scaler_bypass(struct i2c_client *client,bool enable)//enable:0 bypass 1: scale\r
+{\r
+ RK610_DBG(&client->dev,"%s \n",__FUNCTION__);\r
+ \r
+ rk610_scaler_disable(client); \r
+ rk610_scaler_pll_disable(client);\r
+ \r
+ return 0;\r
+}\r
+\r
+#ifdef CONFIG_HAS_EARLYSUSPEND\r
+static void rk610_lcd_early_suspend(struct early_suspend *h)\r
+{\r
+ struct i2c_client *client = g_lcd_inf->client;\r
+ char c;\r
+ RK610_DBG(&client->dev,"%s \n",__FUNCTION__);\r
+ if(g_lcd_inf->screen != NULL){\r
+ rk610_output_config(client,g_lcd_inf->screen,LCD_OUT_DISABLE);\r
+ }\r
+\r
+ if(ENABLE == g_lcd_inf->scl_inf.scl_pwr){\r
+ c= SCL_BYPASS(1) |SCL_DEN_INV(0) |SCL_H_V_SYNC_INV(0) |SCL_OUT_CLK_INV(0) |SCL_ENABLE(DISABLE); \r
+ rk610_scaler_write_p0_reg(client, SCL_CON0, &c);\r
+ }\r
+ if(ENABLE == g_lcd_inf->scl_inf.pll_pwr ){\r
+ c = S_PLL_PWR(1) |S_PLL_RESET(0) |S_PLL_BYPASS(1);\r
+ rk610_scaler_write_p0_reg(client, S_PLL_CON2, &c);\r
+ }\r
+}\r
+\r
+static void rk610_lcd_early_resume(struct early_suspend *h)\r
+{\r
+ struct i2c_client *client = g_lcd_inf->client;\r
+ char c;\r
+ RK610_DBG(&client->dev,"%s \n",__FUNCTION__);\r
+\r
+ if(g_lcd_inf->screen != NULL){\r
+ rk610_output_config(client,g_lcd_inf->screen,g_lcd_inf->disp_mode);\r
+ }\r
+ if(ENABLE == g_lcd_inf->scl_inf.scl_pwr){\r
+ c= SCL_BYPASS(0) |SCL_DEN_INV(0) |SCL_H_V_SYNC_INV(0) |SCL_OUT_CLK_INV(0) |SCL_ENABLE(ENABLE); \r
+ rk610_scaler_write_p0_reg(client, SCL_CON0, &c);\r
+ }\r
+ if(ENABLE == g_lcd_inf->scl_inf.pll_pwr ){\r
+ c = S_PLL_PWR(1) |S_PLL_RESET(0) |S_PLL_BYPASS(1);\r
+ rk610_scaler_write_p0_reg(client, S_PLL_CON2, &c);\r
+ }\r
+}\r
+#endif\r
+int rk610_lcd_scaler_set_param(struct rk29fb_screen *screen,bool enable )//enable:0 bypass 1: scale\r
+{\r
+ int ret=0;\r
+ struct i2c_client *client = g_lcd_inf->client;\r
+ if(client == NULL){\r
+ printk("%s client == NULL FAIL\n",__FUNCTION__);\r
+ return -1;\r
+ }\r
+ if(screen == NULL){\r
+ printk("%s screen == NULL FAIL\n",__FUNCTION__);\r
+ return -1;\r
+ }\r
+ RK610_DBG(&client->dev,"%s \n",__FUNCTION__);\r
+ \r
+ g_lcd_inf->screen = screen;\r
+ \r
+#ifdef CONFIG_HDMI_DUAL_DISP\r
+ if(enable == 1){\r
+ g_lcd_inf->disp_mode = LCD_OUT_SCL;\r
+ rk610_output_config(client,screen,LCD_OUT_SCL);\r
+ ret = rk610_scaler_chg(client,screen);\r
+ }\r
+ else \r
+#endif\r
+ {\r
+ g_lcd_inf->disp_mode = LCD_OUT_BYPASS;\r
+ rk610_output_config(client,screen,LCD_OUT_BYPASS);\r
+ ret = rk610_lcd_scaler_bypass(client,enable);\r
+ }\r
+ return ret;\r
+}\r
+int rk610_lcd_init(struct rk610_core_info *rk610_core_info)\r
+{\r
+ if(rk610_core_info->client == NULL){\r
+ printk("%s client == NULL FAIL\n",__FUNCTION__);\r
+ return -1;\r
+ }\r
+ RK610_DBG(&rk610_core_info->client->dev,"%s \n",__FUNCTION__);\r
+\r
+ g_lcd_inf = kmalloc(sizeof(struct rk610_lcd_info), GFP_KERNEL);\r
+ if(!g_lcd_inf)\r
+ {
+ dev_err(&rk610_core_info->client->dev, ">> rk610 inf kmalloc fail!");\r
+ return -ENOMEM;\r
+ }\r
+ memset(g_lcd_inf, 0, sizeof(struct rk610_lcd_info));\r
+\r
+ g_lcd_inf->client= rk610_core_info->client;\r
+ \r
+ rk610_core_info->lcd_pdata = (void *)g_lcd_inf;\r
+#ifdef CONFIG_HAS_EARLYSUSPEND\r
+ g_lcd_inf->early_suspend.suspend = rk610_lcd_early_suspend;\r
+ g_lcd_inf->early_suspend.resume = rk610_lcd_early_resume;\r
+ g_lcd_inf->early_suspend.level = EARLY_SUSPEND_LEVEL_DISABLE_FB- 1;
+ register_early_suspend(&g_lcd_inf->early_suspend);\r
+#endif\r
+ g_lcd_inf->scl_inf.pll_pwr = DISABLE;\r
+ g_lcd_inf->scl_inf.scl_pwr = DISABLE;\r
+ g_lcd_inf->disp_mode = LCD_OUT_BYPASS;\r
+ return 0;\r
+}\r
--- /dev/null
+#ifndef _RK610_LCD_H\r
+#define _RK610_LCD_H\r
+#include <linux/mfd/rk610_core.h>\r
+#include "../screen/screen.h"\r
+#include <linux/earlysuspend.h>\r
+#define ENABLE 1\r
+#define DISABLE 0\r
+\r
+/* LVDS config */\r
+/* LVDS ÍⲿÁ¬Ïß½Ó·¨ */\r
+/* LVDS_8BIT_1 LVDS_8BIT_2 LVDS_8BIT_3 LVDS_6BIT\r
+----------------------------------------------------------------------\r
+ TX0 R0 R2 R2 R0\r
+ TX1 R1 R3 R3 R1\r
+ TX2 R2 R4 R4 R2\r
+Y TX3 R3 R5 R5 R3\r
+0 TX4 R4 R6 R6 R4\r
+ TX6 R5 R7 R7 R5\r
+ TX7 G0 G2 G2 G0\r
+----------------------------------------------------------------------\r
+ TX8 G1 G3 G3 G1\r
+ TX9 G2 G4 G4 G2\r
+Y TX12 G3 G5 G5 G3\r
+1 TX13 G4 G6 G6 G4\r
+ TX14 G5 G7 G7 G5\r
+ TX15 B0 B2 B2 B0\r
+ TX18 B1 B3 B3 B1\r
+----------------------------------------------------------------------\r
+ TX19 B2 B4 B4 B2\r
+ TX20 B3 B5 B5 B3\r
+ TX21 B4 B6 B6 B4\r
+Y TX22 B5 B7 B7 B5\r
+2 TX24 HSYNC HSYNC HSYNC HSYNC\r
+ TX25 VSYNC VSYNC VSYNC VSYNC\r
+ TX26 ENABLE ENABLE ENABLE ENABLE\r
+---------------------------------------------------------------------- \r
+ TX27 R6 R0 GND GND\r
+ TX5 R7 R1 GND GND\r
+ TX10 G6 G0 GND GND\r
+Y TX11 G7 G1 GND GND\r
+3 TX16 B6 B0 GND GND\r
+ TX17 B7 B1 GND GND\r
+ TX23 RSVD RSVD RSVD RSVD\r
+---------------------------------------------------------------------- \r
+*/\r
+#define LVDS_8BIT_1 0x00\r
+#define LVDS_8BIT_2 0x01\r
+#define LVDS_8BIT_3 0x10\r
+#define LVDS_6BIT 0x11\r
+//LVDS lane input format\r
+#define DATA_D0_MSB 0\r
+#define DATA_D7_MSB 1\r
+//LVDS input source\r
+#define FROM_LCD1 0\r
+#define FROM_LCD0_OR_SCL 1\r
+\r
+/* LCD1 config */\r
+#define LCD1_AS_IN 0\r
+#define LCD1_AS_OUT 1\r
+\r
+//LCD1 output source\r
+#define LCD1_FROM_LCD0 0\r
+#define LCD1_FROM_SCL 1\r
+\r
+//SCALER config\r
+#define NOBYPASS 0\r
+#define BYPASS 1\r
+\r
+//SCALER PLL config\r
+#define S_PLL_PWR_ON 0\r
+#define S_PLL_PWR_DOWN 1\r
+\r
+/* clock config */\r
+#define S_PLL_FROM_DIV 0\r
+#define S_PLL_FROM_CLKIN 1\r
+#define S_PLL_DIV(x) ((x)&0x7)\r
+/*********S_PLL_CON************/\r
+//S_PLL_CON0\r
+#define S_DIV_N(x) (((x)&0xf)<<4)\r
+#define S_DIV_OD(x) (((x)&3)<<0)\r
+//S_PLL_CON1\r
+#define S_DIV_M(x) ((x)&0xff)\r
+//S_PLL_CON2\r
+#define S_PLL_UNLOCK (0<<7) //0:unlock 1:pll_lock\r
+#define S_PLL_LOCK (1<<7) //0:unlock 1:pll_lock\r
+#define S_PLL_PWR(x) (((x)&1)<<2) //0:POWER UP 1:POWER DOWN\r
+#define S_PLL_RESET(x) (((x)&1)<<1) //0:normal 1:reset M/N dividers\r
+#define S_PLL_BYPASS(x) (((x)&1)<<0) //0:normal 1:bypass\r
+//LVDS_CON0\r
+#define LVDS_OUT_CLK_PIN(x) (((x)&1)<<7) //clk enable pin, 0: enable\r
+#define LVDS_OUT_CLK_PWR_PIN(x) (((x)&1)<<6) //clk pwr enable pin, 1: enable \r
+#define LVDS_PLL_PWR_PIN(x) (((x)&1)<<5) //pll pwr enable pin, 0:enable \r
+#define LVDS_BIASE_PWR(x) (((x)&1)<<4) //0: power down 1: normal work\r
+#define LVDS_LANE_IN_FORMAT(x) (((x)&1)<<3) //0: msb on D0 1:msb on D7\r
+#define LVDS_INPUT_SOURCE(x) (((x)&1)<<2) //0: from lcd1 1:from lcd0 or scaler\r
+#define LVDS_OUTPUT_FORMAT(x) (((x)&3)<<0) //00:8bit format-1 01:8bit format-2 10:8bit format-3 11:6bit format \r
+//LVDS_CON1\r
+#define LVDS_OUT_ENABLE(x) (((x)&0xf)<<4) //0:output enable 1:output disable\r
+#define LVDS_TX_PWR_ENABLE(x) (((x)&0xf)<<0) //0:working mode 1:power down\r
+//LCD1_CON\r
+#define LCD1_OUT_ENABLE(x) (((x)&1)<<1) //0:lcd1 as input 1:lcd1 as output\r
+#define LCD1_OUT_SRC(x) (((x)&1)<<0) //0:from lcd0 1:from scaler\r
+//SCL_CON0\r
+#define SCL_BYPASS(x) (((x)&1)<<4) //0:not bypass 1:bypass\r
+#define SCL_DEN_INV(x) (((x)&1)<<3) //scl_den_inv\r
+#define SCL_H_V_SYNC_INV(x) (((x)&1)<<2) //scl_sync_inv\r
+#define SCL_OUT_CLK_INV(x) (((x)&1)<<1) //scl_dclk_inv\r
+#define SCL_ENABLE(x) (((x)&1)<<0) //scaler enable\r
+//SCL_CON1\r
+#define SCL_H_FACTOR_LSB(x) ((x)&0xff) //scl_h_factor[7:0]\r
+//SCL_CON2\r
+#define SCL_H_FACTOR_MSB(x) (((x)>>8)&0x3f) //scl_h_factor[13:8]\r
+//SCL_CON3\r
+#define SCL_V_FACTOR_LSB(x) ((x)&0xff) //scl_v_factor[7:0]\r
+//SCL_CON4\r
+#define SCL_V_FACTOR_MSB(x) (((x)>>8)&0x3f) //scl_v_factor[13:8]\r
+//SCL_CON5\r
+#define SCL_DSP_HST_LSB(x) ((x)&0xff) //dsp_frame_hst[7:0]\r
+//SCL_CON6\r
+#define SCL_DSP_HST_MSB(x) (((x)>>8)&0xf) //dsp_frame_hst[11:8]\r
+//SCL_CON7\r
+#define SCL_DSP_VST_LSB(x) ((x)&0xff) //dsp_frame_vst[7:0]\r
+//SCL_CON8\r
+#define SCL_DSP_VST_MSB(x) (((x)>>8)&0xf) //dsp_frame_vst[11:8]\r
+//SCL_CON9\r
+#define SCL_DSP_HTOTAL_LSB(x) ((x)&0xff) //dsp_frame_htotal[7:0]\r
+//SCL_CON10\r
+#define SCL_DSP_HTOTAL_MSB(x) (((x)>>8)&0xf) //dsp_frame_htotal[11:8]\r
+//SCL_CON11\r
+#define SCL_DSP_HS_END(x) ((x)&0xff) //dsp_hs_end\r
+//SCL_CON12\r
+#define SCL_DSP_HACT_ST_LSB(x) ((x)&0xff) //dsp_hact_st[7:0]\r
+//SCL_CON13\r
+#define SCL_DSP_HACT_ST_MSB(x) (((x)>>8)&0x3) //dsp_hact_st[9:8]\r
+//SCL_CON14\r
+#define SCL_DSP_HACT_END_LSB(x) ((x)&0xff) //dsp_hact_end[7:0]\r
+//SCL_CON15\r
+#define SCL_DSP_HACT_END_MSB(x) (((x)>>8)&0xf) //dsp_frame_htotal[11:8]\r
+//SCL_CON16\r
+#define SCL_DSP_VTOTAL_LSB(x) ((x)&0xff) //dsp_frame_vtotal[7:0]\r
+//SCL_CON17\r
+#define SCL_DSP_VTOTAL_MSB(x) (((x)>>8)&0xf) //dsp_frame_vtotal[11:8]\r
+//SCL_CON18\r
+#define SCL_DSP_VS_END(x) ((x)&0xff) //dsp_vs_end\r
+//SCL_CON19\r
+#define SCL_DSP_VACT_ST(x) ((x)&0xff) //dsp_vact_st[7:0]\r
+//SCL_CON20\r
+#define SCL_DSP_VACT_END_LSB(x) ((x)&0xff) //dsp_vact_end[7:0]\r
+//SCL_CON21\r
+#define SCL_DSP_VACT_END_MSB(x) (((x)>>8)&0xf) //dsp_frame_vtotal[11:8]\r
+//SCL_CON22\r
+#define SCL_H_BORD_ST_LSB(x) ((x)&0xff) //dsp_hbord_st[7:0]\r
+//SCL_CON23\r
+#define SCL_H_BORD_ST_MSB(x) (((x)>>8)&0x3) //dsp_hbord_st[9:8]\r
+//SCL_CON24\r
+#define SCL_H_BORD_END_LSB(x) ((x)&0xff) //dsp_hbord_end[7:0]\r
+//SCL_CON25\r
+#define SCL_H_BORD_END_MSB(x) (((x)>>8)&0xf) //dsp_hbord_end[11:8]\r
+//SCL_CON26\r
+#define SCL_V_BORD_ST(x) ((x)&0xff) //dsp_vbord_st[7:0]\r
+//SCL_CON27\r
+#define SCL_V_BORD_END_LSB(x) ((x)&0xff) //dsp_vbord_end[7:0]\r
+//SCL_CON25\r
+#define SCL_V_BORD_END_MSB(x) (((x)>>8)&0xf) //dsp_vbord_end[11:8]\r
+\r
+enum {\r
+ LCD_OUT_SCL,\r
+ LCD_OUT_BYPASS,\r
+ LCD_OUT_DISABLE,\r
+};\r
+struct rk610_pll_info{\r
+ u32 parent_rate;\r
+ u32 rate;\r
+ int m;\r
+ int n;\r
+ int od;\r
+};\r
+struct lcd_mode_inf{\r
+ int h_pw;\r
+ int h_bp;\r
+ int h_vd;\r
+ int h_fp;\r
+ int v_pw;\r
+ int v_bp;\r
+ int v_vd;\r
+ int v_fp;\r
+ int f_hst;\r
+ int f_vst;\r
+ struct rk610_pll_info pllclk;\r
+};\r
+struct scl_hv_info{\r
+ int scl_h ;\r
+ int scl_v;\r
+ };\r
+\r
+struct scl_info{\r
+ bool pll_pwr;\r
+ bool scl_pwr;\r
+ struct scl_hv_info scl_hv;\r
+};\r
+struct rk610_lcd_info{\r
+ int disp_mode;\r
+ \r
+ struct rk29fb_screen *screen;\r
+ struct scl_info scl_inf;\r
+ struct i2c_client *client;\r
+\r
+#ifdef CONFIG_HAS_EARLYSUSPEND\r
+ struct early_suspend early_suspend;
+#endif\r
+};\r
+extern int rk610_lcd_init(struct rk610_core_info *rk610_core_info);\r
+extern int rk610_lcd_scaler_set_param(struct rk29fb_screen *screen,bool enable );\r
+#endif\r
#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