From ad86eb8b35e8e373e07e9314ab74565aab0f8471 Mon Sep 17 00:00:00 2001 From: "shaochan.liu" Date: Tue, 26 Mar 2019 11:27:02 +0800 Subject: [PATCH] lcd: supposed vlock_m and vlock_farc interface [1/1] PD#TV-3683 Problem: Repeatedly exit HDMI channel cause black screen Solution: 1, support vlock_m and vlock_frac interface 2, optimized clk change and de timing Verify: verify on t962x2-x301 Change-Id: Iddedade08300290853e59b026b3ca1b9939eed79 Signed-off-by: shaochan.liu --- drivers/amlogic/media/vout/lcd/lcd_clk_config.c | 62 ++++++++++++++++++++++ drivers/amlogic/media/vout/lcd/lcd_clk_config.h | 3 +- drivers/amlogic/media/vout/lcd/lcd_clk_ctrl.h | 5 ++ drivers/amlogic/media/vout/lcd/lcd_common.c | 4 +- drivers/amlogic/media/vout/lcd/lcd_debug.c | 2 + .../amlogic/media/vout/lcd/lcd_tablet/lcd_tablet.c | 2 + drivers/amlogic/media/vout/lcd/lcd_tv/lcd_tv.c | 2 + drivers/amlogic/media/vout/vout_serve/vout_serve.c | 2 + include/linux/amlogic/media/vout/lcd/lcd_vout.h | 2 + 9 files changed, 81 insertions(+), 3 deletions(-) diff --git a/drivers/amlogic/media/vout/lcd/lcd_clk_config.c b/drivers/amlogic/media/vout/lcd/lcd_clk_config.c index 8778249..f23d337 100644 --- a/drivers/amlogic/media/vout/lcd/lcd_clk_config.c +++ b/drivers/amlogic/media/vout/lcd/lcd_clk_config.c @@ -2341,6 +2341,68 @@ lcd_pll_reset_end: LCDPR("%s\n", __func__); } +void lcd_vlock_m_update(unsigned int vlock_m) +{ + struct lcd_clk_ctrl_s *table; + int i = 0; + unsigned long flags = 0; + + if (clk_conf.data == NULL) { + LCDERR("%s: clk config data is null\n", __func__); + return; + } + + if (clk_conf.data->pll_ctrl_table == NULL) + return; + + spin_lock_irqsave(&lcd_clk_lock, flags); + vlock_m &= 0xff; + if (lcd_debug_print_flag == 2) + LCDPR("%s,vlcok_m: 0x%x,", __func__, vlock_m); + + table = clk_conf.data->pll_ctrl_table; + while (i < LCD_CLK_CTRL_CNT_MAX) { + if (table[i].flag == LCD_CLK_CTRL_M) { + lcd_hiu_setb(table[i].reg, vlock_m, + table[i].bit, table[i].len); + break; + } + i++; + } + spin_unlock_irqrestore(&lcd_clk_lock, flags); +} + +void lcd_vlock_farc_update(unsigned int vlock_farc) +{ + struct lcd_clk_ctrl_s *table; + int i = 0; + unsigned long flags = 0; + + if (clk_conf.data == NULL) { + LCDERR("%s: clk config data is null\n", __func__); + return; + } + + if (clk_conf.data->pll_ctrl_table == NULL) + return; + + spin_lock_irqsave(&lcd_clk_lock, flags); + vlock_farc &= 0x1ffff; + if (lcd_debug_print_flag == 2) + LCDPR("%s,vlock_farc: 0x%x\n", __func__, vlock_farc); + + table = clk_conf.data->pll_ctrl_table; + while (i < LCD_CLK_CTRL_CNT_MAX) { + if (table[i].flag == LCD_CLK_CTRL_FRAC) { + lcd_hiu_setb(table[i].reg, vlock_farc, + table[i].bit, table[i].len); + break; + } + i++; + } + spin_unlock_irqrestore(&lcd_clk_lock, flags); +} + /* for frame rate change */ void lcd_clk_update(struct lcd_config_s *pconf) { diff --git a/drivers/amlogic/media/vout/lcd/lcd_clk_config.h b/drivers/amlogic/media/vout/lcd/lcd_clk_config.h index f013fd8..487117d 100644 --- a/drivers/amlogic/media/vout/lcd/lcd_clk_config.h +++ b/drivers/amlogic/media/vout/lcd/lcd_clk_config.h @@ -27,7 +27,8 @@ */ #define LCD_CLK_CTRL_EN 0 #define LCD_CLK_CTRL_RST 1 -#define LCD_CLK_CTRL_FRAC 2 +#define LCD_CLK_CTRL_M 2 +#define LCD_CLK_CTRL_FRAC 3 #define LCD_CLK_CTRL_END 0xffff #define LCD_CLK_REG_END 0xffff diff --git a/drivers/amlogic/media/vout/lcd/lcd_clk_ctrl.h b/drivers/amlogic/media/vout/lcd/lcd_clk_ctrl.h index cc52650..041d6b6 100644 --- a/drivers/amlogic/media/vout/lcd/lcd_clk_ctrl.h +++ b/drivers/amlogic/media/vout/lcd/lcd_clk_ctrl.h @@ -386,6 +386,7 @@ struct lcd_clk_ctrl_s pll_ctrl_table_txl[] = { /* flag reg bit len*/ {LCD_CLK_CTRL_EN, HHI_HDMI_PLL_CNTL, LCD_PLL_EN_TXL, 1}, {LCD_CLK_CTRL_RST, HHI_HDMI_PLL_CNTL, LCD_PLL_RST_TXL, 1}, + {LCD_CLK_CTRL_M, HHI_HDMI_PLL_CNTL, LCD_PLL_M_TXL, 9}, {LCD_CLK_CTRL_FRAC, HHI_HDMI_PLL_CNTL2, 0, 12}, {LCD_CLK_CTRL_END, LCD_CLK_REG_END, 0, 0}, }; @@ -394,6 +395,7 @@ struct lcd_clk_ctrl_s pll_ctrl_table_axg[] = { /* flag reg bit len*/ {LCD_CLK_CTRL_EN, HHI_GP0_PLL_CNTL_AXG, LCD_PLL_EN_AXG, 1}, {LCD_CLK_CTRL_RST, HHI_GP0_PLL_CNTL_AXG, LCD_PLL_RST_AXG, 1}, + {LCD_CLK_CTRL_M, HHI_GP0_PLL_CNTL_AXG, LCD_PLL_M_AXG, 9}, {LCD_CLK_CTRL_FRAC, HHI_GP0_PLL_CNTL1_AXG, 0, 12}, {LCD_CLK_CTRL_END, LCD_CLK_REG_END, 0, 0}, }; @@ -402,6 +404,7 @@ struct lcd_clk_ctrl_s pll_ctrl_table_g12a_path0[] = { /* flag reg bit len*/ {LCD_CLK_CTRL_EN, HHI_HDMI_PLL_CNTL, LCD_PLL_EN_HPLL_G12A, 1}, {LCD_CLK_CTRL_RST, HHI_HDMI_PLL_CNTL, LCD_PLL_RST_HPLL_G12A, 1}, + {LCD_CLK_CTRL_M, HHI_HDMI_PLL_CNTL, LCD_PLL_M_HPLL_G12A, 8}, {LCD_CLK_CTRL_FRAC, HHI_HDMI_PLL_CNTL2, 0, 19}, {LCD_CLK_CTRL_END, LCD_CLK_REG_END, 0, 0}, }; @@ -410,6 +413,7 @@ struct lcd_clk_ctrl_s pll_ctrl_table_g12a_path1[] = { /* flag reg bit len*/ {LCD_CLK_CTRL_EN, HHI_GP0_PLL_CNTL0_G12A, LCD_PLL_EN_GP0_G12A, 1}, {LCD_CLK_CTRL_RST, HHI_GP0_PLL_CNTL0_G12A, LCD_PLL_RST_GP0_G12A, 1}, + {LCD_CLK_CTRL_M, HHI_GP0_PLL_CNTL0_G12A, LCD_PLL_M_GP0_G12A, 8}, {LCD_CLK_CTRL_FRAC, HHI_GP0_PLL_CNTL1_G12A, 0, 19}, {LCD_CLK_CTRL_END, LCD_CLK_REG_END, 0, 0}, }; @@ -418,6 +422,7 @@ struct lcd_clk_ctrl_s pll_ctrl_table_tl1[] = { /* flag reg bit len*/ {LCD_CLK_CTRL_EN, HHI_TCON_PLL_CNTL0, LCD_PLL_EN_TL1, 1}, {LCD_CLK_CTRL_RST, HHI_TCON_PLL_CNTL0, LCD_PLL_RST_TL1, 1}, + {LCD_CLK_CTRL_M, HHI_TCON_PLL_CNTL0, LCD_PLL_M_TL1, 8}, {LCD_CLK_CTRL_FRAC, HHI_TCON_PLL_CNTL1, 0, 17}, {LCD_CLK_CTRL_END, LCD_CLK_REG_END, 0, 0}, }; diff --git a/drivers/amlogic/media/vout/lcd/lcd_common.c b/drivers/amlogic/media/vout/lcd/lcd_common.c index ff11fa3..ca87abc 100644 --- a/drivers/amlogic/media/vout/lcd/lcd_common.c +++ b/drivers/amlogic/media/vout/lcd/lcd_common.c @@ -752,8 +752,8 @@ void lcd_timing_init_config(struct lcd_config_s *pconf) vsync_bp = pconf->lcd_timing.vsync_bp; vsync_width = pconf->lcd_timing.vsync_width; - de_hstart = h_period - h_active - 1; - de_vstart = v_period - v_active; + de_hstart = hsync_bp + hsync_width; + de_vstart = vsync_bp + vsync_width; pconf->lcd_timing.video_on_pixel = de_hstart - h_delay; pconf->lcd_timing.video_on_line = de_vstart; diff --git a/drivers/amlogic/media/vout/lcd/lcd_debug.c b/drivers/amlogic/media/vout/lcd/lcd_debug.c index 561d2e4..45e332b 100644 --- a/drivers/amlogic/media/vout/lcd/lcd_debug.c +++ b/drivers/amlogic/media/vout/lcd/lcd_debug.c @@ -1493,6 +1493,8 @@ static void lcd_debug_clk_change(unsigned int pclk) struct lcd_config_s *pconf; unsigned int sync_duration; + vout_notifier_call_chain(VOUT_EVENT_MODE_CHANGE_PRE, + &lcd_drv->lcd_info->mode); pconf = lcd_drv->lcd_config; sync_duration = pclk / pconf->lcd_basic.h_period; sync_duration = sync_duration * 100 / pconf->lcd_basic.v_period; diff --git a/drivers/amlogic/media/vout/lcd/lcd_tablet/lcd_tablet.c b/drivers/amlogic/media/vout/lcd/lcd_tablet/lcd_tablet.c index 7176e5c..4bf4862 100644 --- a/drivers/amlogic/media/vout/lcd/lcd_tablet/lcd_tablet.c +++ b/drivers/amlogic/media/vout/lcd/lcd_tablet/lcd_tablet.c @@ -1251,6 +1251,8 @@ static void lcd_set_vinfo(unsigned int sync_duration) LCDPR("%s: sync_duration=%d\n", __func__, sync_duration); + vout_notifier_call_chain(VOUT_EVENT_MODE_CHANGE_PRE, + &lcd_drv->lcd_info->mode); /* update vinfo */ lcd_drv->lcd_info->sync_duration_num = sync_duration; lcd_drv->lcd_info->sync_duration_den = 100; diff --git a/drivers/amlogic/media/vout/lcd/lcd_tv/lcd_tv.c b/drivers/amlogic/media/vout/lcd/lcd_tv/lcd_tv.c index abd0899..b692ed4 100644 --- a/drivers/amlogic/media/vout/lcd/lcd_tv/lcd_tv.c +++ b/drivers/amlogic/media/vout/lcd/lcd_tv/lcd_tv.c @@ -1455,6 +1455,8 @@ static void lcd_set_vinfo(unsigned int sync_duration) LCDPR("%s: sync_duration=%d\n", __func__, sync_duration); + vout_notifier_call_chain(VOUT_EVENT_MODE_CHANGE_PRE, + &lcd_drv->lcd_info->mode); /* update vinfo */ lcd_drv->lcd_info->sync_duration_num = sync_duration; lcd_drv->lcd_info->sync_duration_den = 100; diff --git a/drivers/amlogic/media/vout/vout_serve/vout_serve.c b/drivers/amlogic/media/vout/vout_serve/vout_serve.c index ea168f8..6cc183c 100644 --- a/drivers/amlogic/media/vout/vout_serve/vout_serve.c +++ b/drivers/amlogic/media/vout/vout_serve/vout_serve.c @@ -408,12 +408,14 @@ static ssize_t vout_dummy_store(struct class *class, mode = VMODE_DUMMY_LCD; ret = sscanf(buf, "%d %d %d %d", &tmp[0], &tmp[1], &tmp[2], &tmp[3]); if (ret == 2) { + vout_notifier_call_chain(VOUT_EVENT_MODE_CHANGE_PRE, &mode); nulldisp_vinfo[2].width = tmp[0]; nulldisp_vinfo[2].height = tmp[1]; nulldisp_vinfo[2].field_height = tmp[1]; VOUTPR("set dummy size: %d x %d\n", tmp[0], tmp[1]); vout_notifier_call_chain(VOUT_EVENT_MODE_CHANGE, &mode); } else if (ret == 4) { + vout_notifier_call_chain(VOUT_EVENT_MODE_CHANGE_PRE, &mode); nulldisp_vinfo[2].width = tmp[0]; nulldisp_vinfo[2].height = tmp[1]; nulldisp_vinfo[2].field_height = tmp[1]; diff --git a/include/linux/amlogic/media/vout/lcd/lcd_vout.h b/include/linux/amlogic/media/vout/lcd/lcd_vout.h index c0dd0e5..455206e 100644 --- a/include/linux/amlogic/media/vout/lcd/lcd_vout.h +++ b/include/linux/amlogic/media/vout/lcd/lcd_vout.h @@ -24,6 +24,8 @@ #include #include +extern void lcd_vlock_m_update(unsigned int vlock_m); +extern void lcd_vlock_frac_update(unsigned int vlock_farc); /* ********************************** * debug print define -- 2.7.4