extern_init = <1>;
/* power step: type,index,value,delay(ms) */
power_on_step = <
- 0 0 0 20
+ 0 1 0 200
2 0 0 0
0xff 0 0 0>;
power_off_step = <
- 2 0 0 100
- 0 0 0 100
+ 2 0 0 0
+ 0 0 0 20
+ 0 1 1 100
0xff 0 0 0>;
backlight_index = <0>;
};
check_state = <0x04 /* check_reg */
3>; /* check_cnt */
mipi_attr = <4 /*lane_num*/
- 300 /*bit_rate_max(MHz)*/
+ 400 /*bit_rate_max(MHz)*/
0 /*factor(*100, default 0 for auto)*/
1 /*operation_mode_init(0=video, 1=command)*/
0 /*operation_mode_display(0=video, 1=command)*/
extern_init = <2>;
/* power step: type,index,value,delay(ms) */
power_on_step = <
+ 0 1 0 200
0 0 1 20
0 0 0 10
0 0 1 20
2 0 0 0
0xff 0 0 0>;
power_off_step = <
- 2 0 0 50
- 0 0 0 100
+ 2 0 0 0
+ 0 0 0 20
+ 0 1 1 100
0xff 0 0 0>;
backlight_index = <0>;
};
}
}
-void lcd_clk_config_print(void)
+int lcd_clk_config_print(char *buf, int offset)
{
struct aml_lcd_drv_s *lcd_drv = aml_lcd_get_driver();
+ int n, len = 0;
+ n = lcd_debug_info_len(len + offset);
switch (lcd_drv->data->chip_type) {
case LCD_CHIP_G12A:
- LCDPR("lcd clk config:\n"
- "clk_path %d\n"
- "pll_m: %d\n"
- "pll_n: %d\n"
- "pll_frac: 0x%03x\n"
- "pll_fvco: %dkHz\n"
- "pll_od: %d\n"
- "pll_out: %dkHz\n"
- "xd: %d\n"
- "fout: %dkHz\n"
- "ss_level: %d\n\n",
- lcd_drv->lcd_clk_path,
- clk_conf.pll_m, clk_conf.pll_n,
- clk_conf.pll_frac, clk_conf.pll_fvco,
- clk_conf.pll_od1_sel, clk_conf.pll_fout,
- clk_conf.xd, clk_conf.fout, clk_conf.ss_level);
+ if (lcd_drv->lcd_clk_path) {
+ len += snprintf((buf+len), n,
+ "lcd clk config:\n"
+ "clk_path %d\n"
+ "pll_m: %d\n"
+ "pll_n: %d\n"
+ "pll_frac: 0x%03x\n"
+ "pll_fvco: %dkHz\n"
+ "pll_od: %d\n"
+ "pll_out: %dkHz\n"
+ "xd: %d\n"
+ "fout: %dkHz\n"
+ "ss_level: %d\n\n",
+ lcd_drv->lcd_clk_path,
+ clk_conf.pll_m, clk_conf.pll_n,
+ clk_conf.pll_frac, clk_conf.pll_fvco,
+ clk_conf.pll_od1_sel, clk_conf.pll_fout,
+ clk_conf.xd, clk_conf.fout, clk_conf.ss_level);
+ } else {
+ len += snprintf((buf+len), n,
+ "lcd clk config:\n"
+ "clk_path %d\n"
+ "pll_m: %d\n"
+ "pll_n: %d\n"
+ "pll_frac: 0x%03x\n"
+ "pll_fvco: %dkHz\n"
+ "pll_od1: %d\n"
+ "pll_od2: %d\n"
+ "pll_od3: %d\n"
+ "pll_out: %dkHz\n"
+ "div_sel: %s(index %d)\n"
+ "xd: %d\n"
+ "fout: %dkHz\n"
+ "ss_level: %d\n\n",
+ lcd_drv->lcd_clk_path,
+ clk_conf.pll_m, clk_conf.pll_n,
+ clk_conf.pll_frac, clk_conf.pll_fvco,
+ clk_conf.pll_od1_sel, clk_conf.pll_od2_sel,
+ clk_conf.pll_od3_sel, clk_conf.pll_fout,
+ lcd_clk_div_sel_table[clk_conf.div_sel],
+ clk_conf.div_sel, clk_conf.xd,
+ clk_conf.fout, clk_conf.ss_level);
+ }
break;
case LCD_CHIP_AXG:
- LCDPR("lcd clk config:\n"
+ len += snprintf((buf+len), n,
+ "lcd clk config:\n"
"pll_m: %d\n"
"pll_n: %d\n"
"pll_frac: 0x%03x\n"
clk_conf.xd, clk_conf.fout, clk_conf.ss_level);
break;
default:
- LCDPR("lcd clk config:\n"
+ len += snprintf((buf+len), n,
+ "lcd clk config:\n"
+ "pll_mode: %d\n"
"pll_m: %d\n"
"pll_n: %d\n"
"pll_frac: 0x%03x\n"
"div_sel: %s(index %d)\n"
"xd: %d\n"
"fout: %dkHz\n"
- "ss_level: %d\n"
- "pll_mode: %d\n\n",
- clk_conf.pll_m, clk_conf.pll_n,
+ "ss_level: %d\n\n",
+ clk_conf.pll_mode, clk_conf.pll_m, clk_conf.pll_n,
clk_conf.pll_frac, clk_conf.pll_fvco,
clk_conf.pll_od1_sel, clk_conf.pll_od2_sel,
clk_conf.pll_od3_sel, clk_conf.pll_fout,
lcd_clk_div_sel_table[clk_conf.div_sel],
clk_conf.div_sel, clk_conf.xd,
- clk_conf.fout, clk_conf.ss_level,
- clk_conf.pll_mode);
+ clk_conf.fout, clk_conf.ss_level);
break;
}
+
+ return len;
}
static void lcd_clk_config_chip_init(void)
return ret;
}
+#define PLL_WAIT_LOCK_CNT_G12A 1000
+static int lcd_pll_wait_lock_g12a(int path)
+{
+ unsigned int pll_ctrl, pll_ctrl3, pll_ctrl6;
+ unsigned int pll_lock;
+ int wait_loop = PLL_WAIT_LOCK_CNT_G12A; /* 200 */
+ int ret = 0;
+
+ if (path) {
+ pll_ctrl = HHI_GP0_PLL_CNTL0_G12A;
+ pll_ctrl3 = HHI_GP0_PLL_CNTL3_G12A;
+ pll_ctrl6 = HHI_GP0_PLL_CNTL6_G12A;
+ } else {
+ pll_ctrl = HHI_HDMI_PLL_CNTL;
+ pll_ctrl3 = HHI_HDMI_PLL_CNTL4;
+ pll_ctrl6 = HHI_HDMI_PLL_CNTL7;
+ }
+ do {
+ udelay(50);
+ pll_lock = lcd_hiu_getb(pll_ctrl, 31, 1);
+ wait_loop--;
+ } while ((pll_lock != 1) && (wait_loop > 0));
+
+ if (pll_lock == 1) {
+ goto pll_lock_end_g12a;
+ } else {
+ LCDPR("path: %d, pll try 1, lock: %d\n", path, pll_lock);
+ lcd_hiu_setb(pll_ctrl3, 1, 31, 1);
+ wait_loop = PLL_WAIT_LOCK_CNT_G12A;
+ do {
+ udelay(50);
+ pll_lock = lcd_hiu_getb(pll_ctrl, 31, 1);
+ wait_loop--;
+ } while ((pll_lock != 1) && (wait_loop > 0));
+ }
+
+ if (pll_lock == 1) {
+ goto pll_lock_end_g12a;
+ } else {
+ LCDPR("path: %d, pll try 2, lock: %d\n", path, pll_lock);
+ lcd_hiu_write(pll_ctrl6, 0x55540000);
+ wait_loop = PLL_WAIT_LOCK_CNT_G12A;
+ do {
+ udelay(50);
+ pll_lock = lcd_hiu_getb(pll_ctrl, 31, 1);
+ wait_loop--;
+ } while ((pll_lock != 1) && (wait_loop > 0));
+ }
+
+ if (pll_lock != 1)
+ ret = -1;
+
+pll_lock_end_g12a:
+ LCDPR("%s: path=%d, pll_lock=%d, wait_loop=%d\n",
+ __func__, path, pll_lock, (PLL_WAIT_LOCK_CNT_G12A - wait_loop));
+ return ret;
+}
+
static void lcd_set_pll_ss_gxtvbb(struct lcd_clk_config_s *cConf)
{
if ((cConf->pll_fvco >= 5500000) && (cConf->pll_fvco <= 6000000)) {
pll_ctrl1 = (cConf->pll_frac << 0);
if (cConf->pll_frac) {
pll_ctrl |= (1 << 27);
- pll_ctrl3 = 0x6a295c00;
+ pll_ctrl3 = 0x6a285c00;
pll_ctrl4 = 0x65771290;
- pll_ctrl6 = 0x54540000;
+ pll_ctrl6 = 0x56540000;
} else {
- pll_ctrl3 = 0x08691c00;
+ pll_ctrl3 = 0x48681c00;
pll_ctrl4 = 0x33771290;
- pll_ctrl6 = 0x50540000;
+ pll_ctrl6 = 0x56540000;
}
lcd_hiu_write(HHI_GP0_PLL_CNTL0_G12A, pll_ctrl);
udelay(100);
lcd_hiu_setb(HHI_GP0_PLL_CNTL0_G12A, 0, LCD_PLL_RST_GP0_G12A, 1);
- ret = lcd_pll_wait_lock(HHI_GP0_PLL_CNTL0_G12A, LCD_PLL_LOCK_GP0_G12A);
+ ret = lcd_pll_wait_lock_g12a(1);
if (ret)
LCDERR("gp0_pll lock failed\n");
pll_ctrl2 = (cConf->pll_frac << 0);
if (cConf->pll_frac) {
pll_ctrl |= (1 << 27);
- pll_ctrl4 = 0x6a29dc00;
+ pll_ctrl4 = 0x6a285c00;
pll_ctrl5 = 0x65771290;
- pll_ctrl7 = 0x54540000;
+ pll_ctrl7 = 0x56540000;
} else {
- pll_ctrl4 = 0x0a691c00;
+ pll_ctrl4 = 0x48681c00;
pll_ctrl5 = 0x33771290;
- pll_ctrl7 = 0x50540000;
+ pll_ctrl7 = 0x56540000;
}
lcd_hiu_write(HHI_HDMI_PLL_CNTL, pll_ctrl);
udelay(100);
lcd_hiu_setb(HHI_HDMI_PLL_CNTL, 0, LCD_PLL_RST_HPLL_G12A, 1);
- ret = lcd_pll_wait_lock(HHI_HDMI_PLL_CNTL, LCD_PLL_LOCK_HPLL_G12A);
+ ret = lcd_pll_wait_lock_g12a(0);
if (ret)
LCDERR("hpll lock failed\n");
/* ******** api ******** */
extern int meson_clk_measure(unsigned int clk_mux);
+extern int lcd_debug_info_len(int num);
+
extern struct lcd_clk_config_s *get_lcd_clk_config(void);
extern int lcd_clk_path_change(int sel);
-extern void lcd_clk_config_print(void);
+extern int lcd_clk_config_print(char *buf, int offset);
extern int lcd_encl_clk_msr(void);
extern void lcd_pll_reset(void);
extern char *lcd_get_spread_spectrum(void);
}
}
-static int lcd_debug_info_len(int num)
+int lcd_debug_info_len(int num)
{
int ret = 0;
static ssize_t lcd_debug_clk_show(struct class *class,
struct class_attribute *attr, char *buf)
{
- lcd_clk_config_print();
- return sprintf(buf, "\n");
+ char *print_buf;
+ int n = 0;
+
+ print_buf = kcalloc(PR_BUF_MAX, sizeof(char), GFP_KERNEL);
+ if (print_buf == NULL)
+ return sprintf(buf, "%s: buf malloc error\n", __func__);
+
+ lcd_clk_config_print(print_buf, 0);
+
+ n = sprintf(buf, "%s\n", print_buf);
+ kfree(print_buf);
+
+ return n;
}
static ssize_t lcd_debug_clk_store(struct class *class,
LCDPR("failed to get check_state\n");
pconf->lcd_control.mipi_config->check_en = 0;
} else {
- pconf->lcd_control.mipi_config->check_en = 1;
- pconf->lcd_control.mipi_config->check_reg =
- (unsigned char)(para[0]);
- pconf->lcd_control.mipi_config->check_cnt =
- (unsigned char)(para[1]);
+ if (para[0] == 0xffff) {
+ pconf->lcd_control.mipi_config->check_en = 0;
+ } else {
+ pconf->lcd_control.mipi_config->check_en = 1;
+ pconf->lcd_control.mipi_config->check_reg =
+ (unsigned char)(para[0]);
+ pconf->lcd_control.mipi_config->check_cnt =
+ (unsigned char)(para[1]);
+ }
}
ret = of_property_read_u32_array(child, "mipi_attr",
temp = ((1000000 * 100) / (dconf->bit_rate / 1000)) * 8;
pr_info("MIPI DSI DPHY timing (unit: ns)\n"
" UI: %d.%02d\n"
+ " LP TESC: %d\n"
" LP LPX: %d\n"
" LP TA_SURE: %d\n"
" LP TA_GO: %d\n"
" CLK PREPARE: %d\n"
" CLK PRE: %d\n"
" INIT: %d\n"
- " WAKEUP: %d\n\n",
+ " WAKEUP: %d\n"
+ " state_change: %d\n\n",
(temp / 8 / 100), ((temp / 8) % 100),
+ (temp * dsi_phy_config.lp_tesc / 100),
(temp * dsi_phy_config.lp_lpx / 100),
(temp * dsi_phy_config.lp_ta_sure / 100),
(temp * dsi_phy_config.lp_ta_go / 100),
(temp * dsi_phy_config.clk_prepare / 100),
(temp * dsi_phy_config.clk_pre / 100),
(temp * dsi_phy_config.init / 100),
- (temp * dsi_phy_config.wakeup / 100));
+ (temp * dsi_phy_config.wakeup / 100),
+ dsi_phy_config.state_change);
}
static void mipi_dsi_video_print_info(struct dsi_config_s *dconf)
{
unsigned int dpi_data_format, venc_data_width;
unsigned int lane_num, vid_mode_type;
- enum tv_enc_lcd_type_e output_type;
unsigned int temp;
struct dsi_config_s *dconf;
dpi_data_format = dconf->dpi_data_format;
lane_num = (unsigned int)(dconf->lane_num);
vid_mode_type = (unsigned int)(dconf->video_mode_type);
- output_type = dconf->venc_fmt;
/* ----------------------------------------------------- */
/* Standard Configuration for Video Mode Operation */
/* ----------------------------------------------------- */
/* 1, Configure Lane number and phy stop wait time */
- if ((output_type != TV_ENC_LCD240x160_dsi) &&
- (output_type != TV_ENC_LCD1920x1200p) &&
- (output_type != TV_ENC_LCD2560x1600) &&
- (output_type != TV_ENC_LCD768x1024p)) {
+ if (dsi_phy_config.state_change == 2) {
dsi_host_write(MIPI_DSI_DWC_PHY_IF_CFG_OS,
(0x28 << BIT_PHY_STOP_WAIT_TIME) |
((lane_num-1) << BIT_N_LANES));
dsi_host_write(MIPI_DSI_DWC_MODE_CFG_OS, operation_mode);
/* Phy Timer */
- if ((output_type != TV_ENC_LCD240x160_dsi) &&
- (output_type != TV_ENC_LCD1920x1200p) &&
- (output_type != TV_ENC_LCD2560x1600) &&
- (output_type != TV_ENC_LCD768x1024p)) {
+ if (dsi_phy_config.state_change == 2)
dsi_host_write(MIPI_DSI_DWC_PHY_TMR_CFG_OS, 0x03320000);
- } else {
+ else
dsi_host_write(MIPI_DSI_DWC_PHY_TMR_CFG_OS, 0x090f0000);
- }
- /* Configure DPHY Parameters */
- if ((output_type != TV_ENC_LCD240x160_dsi) &&
- (output_type != TV_ENC_LCD1920x1200p) &&
- (output_type != TV_ENC_LCD2560x1600) &&
- (output_type != TV_ENC_LCD768x1024p)) {
+ if (dsi_phy_config.state_change == 2)
dsi_host_write(MIPI_DSI_DWC_PHY_TMR_LPCLK_CFG_OS, 0x870025);
- } else {
+ else
dsi_host_write(MIPI_DSI_DWC_PHY_TMR_LPCLK_CFG_OS, 0x260017);
- }
}
/* *************************************************************
static void mipi_dsi_phy_config(struct dsi_phy_s *dphy, unsigned int dsi_ui)
{
- unsigned int temp, t_ui;
+ unsigned int temp, t_ui, t_req;
t_ui = (1000000 * 100) / (dsi_ui / 1000); /* 0.01ns*100 */
temp = t_ui * 8; /* lane_byte cycle time */
dphy->init = (DPHY_TIME_INIT(t_ui) + temp - 1) / temp;
dphy->wakeup = (DPHY_TIME_WAKEUP(t_ui) + temp - 1) / temp;
+ /* check dphy spec: (unit: ns) */
+ if ((temp * dsi_phy_config.lp_tesc / 100) <= 100)
+ LCDERR("lp_tesc timing error\n");
+ if ((temp * dsi_phy_config.lp_lpx / 100) <= 50)
+ LCDERR("lp_lpx timing error\n");
+ if ((temp * dsi_phy_config.hs_exit / 100) <= 100)
+ LCDERR("hs_exit timing error\n");
+ t_req = ((t_ui > (60 * 100 / 4)) ?
+ (8 * t_ui) : ((60 * 100) + 4 * t_ui));
+ if ((temp * dsi_phy_config.hs_trail / 100) <= ((t_req + 50) / 100))
+ LCDERR("hs_trail timing error\n");
+ t_req = temp * dsi_phy_config.hs_prepare / 100;
+ if ((t_req <= (40 + (t_ui * 4 / 100))) ||
+ (t_req >= (85 + (t_ui * 6 / 100))))
+ LCDERR("hs_prepare timing error\n");
+ t_req = 145 + (t_ui * 10 / 100);
+ if (((temp * dsi_phy_config.hs_zero / 100) +
+ (temp * dsi_phy_config.hs_prepare / 100)) <= t_req)
+ LCDERR("hs_zero timing error\n");
+ if ((temp * dsi_phy_config.init / 100) <= 100000)
+ LCDERR("init timing error\n");
+ if ((temp * dsi_phy_config.wakeup / 100) <= 1000000)
+ LCDERR("wakeup timing error\n");
+
if (lcd_debug_print_flag) {
LCDPR("%s:\n"
"lp_tesc = 0x%02x\n"
/* Venc resolution format */
switch (dconf->phy_stop_wait) {
case 1: /* standard */
- dconf->venc_fmt = TV_ENC_LCD768x1024p;
+ dsi_phy_config.state_change = 1;
break;
case 2: /* slow */
- dconf->venc_fmt = TV_ENC_LCD1280x720;
+ dsi_phy_config.state_change = 2;
break;
case 0: /* auto */
default:
if ((pconf->lcd_basic.h_active != 240) &&
(pconf->lcd_basic.h_active != 768) &&
(pconf->lcd_basic.h_active != 1920) &&
- (pconf->lcd_basic.h_active != 2560))
- dconf->venc_fmt = TV_ENC_LCD1280x720;
- else
- dconf->venc_fmt = TV_ENC_LCD768x1024p;
+ (pconf->lcd_basic.h_active != 2560)) {
+ dsi_phy_config.state_change = 2;
+ } else {
+ dsi_phy_config.state_change = 1;
+ }
break;
}
}
unsigned int clk_pre;
unsigned int init;
unsigned int wakeup;
+
+ unsigned int state_change;
};
struct dsi_vid_s {
unsigned int venc_data_width;
unsigned int dpi_data_format;
- unsigned int venc_fmt;
unsigned char *dsi_init_on;
unsigned char *dsi_init_off;