lcd: optimize vbyone auto recovery with hw filter [1/1]
authorEvoke Zhang <evoke.zhang@amlogic.com>
Wed, 27 Feb 2019 08:27:51 +0000 (16:27 +0800)
committerJianxin Pan <jianxin.pan@amlogic.com>
Mon, 4 Mar 2019 06:30:38 +0000 (22:30 -0800)
PD#SWPL-5172

Problem:
vbyone stable is easily affected by ESD

Solution:
increase hw filter time to anti ESD after vbyone stable,
but lower the hw filter time when vbyone training,
to avoid side effect to vbyone fsm working.
only support in TL1.

Verify:
x301

Change-Id: If8a8b14a47262abd682f5c95185e82cf3c0f58f2
Signed-off-by: Evoke Zhang <evoke.zhang@amlogic.com>
drivers/amlogic/media/vout/lcd/lcd_tv/lcd_drv.c

index 71daa52..6e07695 100644 (file)
@@ -510,6 +510,30 @@ static int lcd_vbyone_lanes_set(int lane_num, int byte_mode, int region_num,
        return 0;
 }
 
+static void lcd_vbyone_hw_filter(int flag)
+{
+       struct aml_lcd_drv_s *lcd_drv = aml_lcd_get_driver();
+
+       switch (lcd_drv->data->chip_type) {
+       case LCD_CHIP_TL1:
+               if (flag) {
+                       lcd_vcbus_write(VBO_INFILTER_TICK_PERIOD_L, 0xffff);
+                       lcd_vcbus_write(VBO_INFILTER_TICK_PERIOD_H, 0xf);
+                       lcd_vcbus_setb(VBO_INSGN_CTRL, 0x7, 8, 4);
+                       lcd_vcbus_setb(VBO_INSGN_CTRL, 0x7, 12, 4);
+               } else {
+                       lcd_vcbus_write(VBO_INFILTER_TICK_PERIOD_L, 0xff);
+                       lcd_vcbus_write(VBO_INFILTER_TICK_PERIOD_H, 0x0);
+                       lcd_vcbus_setb(VBO_INSGN_CTRL, 0x7, 8, 4);
+                       lcd_vcbus_setb(VBO_INSGN_CTRL, 0x7, 12, 4);
+               }
+               break;
+       default:
+               lcd_vcbus_write(VBO_INFILTER_CTRL, 0xff77);
+               break;
+       }
+}
+
 static void lcd_vbyone_sw_reset(void)
 {
        if (lcd_debug_print_flag)
@@ -559,7 +583,6 @@ static void lcd_vbyone_cdr_training_hold(struct vbyone_config_s *vx1_conf,
 
 static void lcd_vbyone_control_set(struct lcd_config_s *pconf)
 {
-       struct aml_lcd_drv_s *lcd_drv = aml_lcd_get_driver();
        int lane_count, byte_mode, region_num, hsize, vsize, color_fmt;
        int vin_color, vin_bpp;
 
@@ -641,17 +664,7 @@ static void lcd_vbyone_control_set(struct lcd_config_s *pconf)
        /* Mux pads in combo-phy: 0 for dsi; 1 for lvds or vbyone; 2 for edp */
        /*lcd_hiu_write(HHI_DSI_LVDS_EDP_CNTL0, 0x1);*/
 
-       switch (lcd_drv->data->chip_type) {
-       case LCD_CHIP_TL1:
-               lcd_vcbus_write(VBO_INFILTER_TICK_PERIOD_L, 0xff);
-               lcd_vcbus_write(VBO_INFILTER_TICK_PERIOD_H, 0x0);
-               lcd_vcbus_setb(VBO_INSGN_CTRL, 0x7, 8, 4);
-               lcd_vcbus_setb(VBO_INSGN_CTRL, 0x7, 12, 4);
-               break;
-       default:
-               lcd_vcbus_write(VBO_INFILTER_CTRL, 0xff77);
-               break;
-       }
+       lcd_vbyone_hw_filter(0);
        lcd_vcbus_setb(VBO_INSGN_CTRL, 0, 2, 2);
        lcd_vcbus_setb(VBO_CTRL_L, 1, 0, 1);
 
@@ -689,6 +702,7 @@ void lcd_vbyone_interrupt_enable(int flag)
 
        vx1_conf = lcd_drv->lcd_config->lcd_control.vbyone_config;
        if (flag) {
+               lcd_vbyone_hw_filter(1);
                if (vx1_conf->intr_en) {
                        vx1_fsm_acq_st = 0;
                        /* clear interrupt */
@@ -743,6 +757,7 @@ static void lcd_vbyone_interrupt_init(struct aml_lcd_drv_s *lcd_drv)
 
        /* release sw filter ctrl in uboot */
        lcd_vcbus_setb(VBO_INSGN_CTRL, 0, 0, 1);
+       lcd_vbyone_hw_filter(1);
 
        /* set hold in FSM_ACQ */
        if (vx1_conf->vsync_intr_en == 3)
@@ -977,19 +992,23 @@ static irqreturn_t lcd_vbyone_vsync_isr(int irq, void *dev_id)
                if (vsync_cnt < VSYNC_CNT_VX1_RESET)
                        vsync_cnt++;
                else if (vsync_cnt == VSYNC_CNT_VX1_RESET) {
+                       lcd_vbyone_hw_filter(0);
                        lcd_vbyone_sw_reset();
                        vsync_cnt++;
                } else if ((vsync_cnt > VSYNC_CNT_VX1_RESET) &&
                        (vsync_cnt < VSYNC_CNT_VX1_STABLE)) {
-                       if (lcd_vcbus_read(VBO_STATUS_L) & 0x20)
+                       if (lcd_vcbus_read(VBO_STATUS_L) & 0x20) {
                                vsync_cnt = VSYNC_CNT_VX1_STABLE;
-                       else
+                               lcd_vbyone_hw_filter(1);
+                       } else {
                                vsync_cnt++;
+                       }
                }
        } else if (vx1_conf->vsync_intr_en == 2) {
                if (vsync_cnt >= 5) {
                        vsync_cnt = 0;
                        if (!(lcd_vcbus_read(VBO_STATUS_L) & 0x20)) {
+                               lcd_vbyone_hw_filter(0);
                                lcd_vbyone_sw_reset();
                                LCDPR("vx1 sw_reset 2\n");
                                while (lcd_vcbus_read(VBO_STATUS_L) & 0x4)
@@ -997,6 +1016,8 @@ static irqreturn_t lcd_vbyone_vsync_isr(int irq, void *dev_id)
 
                                lcd_vcbus_setb(VBO_INTR_STATE_CTRL, 0, 15, 1);
                                lcd_vcbus_setb(VBO_INTR_STATE_CTRL, 1, 15, 1);
+                       } else {
+                               lcd_vbyone_hw_filter(1);
                        }
                } else
                        vsync_cnt++;
@@ -1159,6 +1180,7 @@ static irqreturn_t lcd_vbyone_interrupt_handler(int irq, void *dev_id)
 #if (VX1_FSM_ACQ_NEXT == VX1_FSM_ACQ_NEXT_RELEASE_HOLDER)
                        lcd_vcbus_setb(VBO_FSM_HOLDER_L, 0xffff, 0, 16);
 #endif
+                       lcd_vbyone_hw_filter(1);
                        LCDPR("vx1 fsm stable\n");
                }
        }