lcd: driver defect clean up
authorEvoke Zhang <evoke.zhang@amlogic.com>
Wed, 6 Sep 2017 01:57:35 +0000 (09:57 +0800)
committerJianxin Pan <jianxin.pan@amlogic.com>
Tue, 12 Sep 2017 12:54:29 +0000 (05:54 -0700)
PD#150465: driver defect clean up:
#71
#77
#109
#127
#411
#600
#602
#603
#604
#611
#612

Change-Id: I38ac5ed6583bd6e57df9f42eaab04d05ee4ed663
Signed-off-by: Evoke Zhang <evoke.zhang@amlogic.com>
13 files changed:
drivers/amlogic/media/vout/lcd/lcd_clk_config.c
drivers/amlogic/media/vout/lcd/lcd_clk_config.h
drivers/amlogic/media/vout/lcd/lcd_common.c
drivers/amlogic/media/vout/lcd/lcd_common.h
drivers/amlogic/media/vout/lcd/lcd_debug.c
drivers/amlogic/media/vout/lcd/lcd_reg.h
drivers/amlogic/media/vout/lcd/lcd_tablet/lcd_drv.c
drivers/amlogic/media/vout/lcd/lcd_tablet/lcd_tablet.c
drivers/amlogic/media/vout/lcd/lcd_tv/lcd_drv.c
drivers/amlogic/media/vout/lcd/lcd_tv/lcd_tv.c
drivers/amlogic/media/vout/lcd/lcd_vout.c
include/linux/amlogic/media/vout/lcd/lcd_unifykey.h
include/linux/amlogic/media/vout/lcd/lcd_vout.h

index a69e6f0..96618f2 100644 (file)
@@ -229,14 +229,16 @@ void lcd_clk_config_print(void)
                        "div_sel:      %s(index %d)\n"
                        "xd:           %d\n"
                        "fout:         %dkHz\n"
-                       "ss_level:     %d\n\n",
+                       "ss_level:     %d\n"
+                       "pll_mode:     %d\n\n",
                        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.fout, clk_conf.ss_level,
+                       clk_conf.pll_mode);
                break;
        }
 }
@@ -587,7 +589,10 @@ static void lcd_set_pll_txl(struct lcd_clk_config_s *cConf)
        lcd_hiu_write(HHI_HDMI_PLL_CNTL, pll_ctrl);
        lcd_hiu_write(HHI_HDMI_PLL_CNTL2, pll_ctrl2);
        lcd_hiu_write(HHI_HDMI_PLL_CNTL3, pll_ctrl3);
-       lcd_hiu_write(HHI_HDMI_PLL_CNTL4, 0x0c8e0000);
+       if (cConf->pll_mode)
+               lcd_hiu_write(HHI_HDMI_PLL_CNTL4, 0x0d160000);
+       else
+               lcd_hiu_write(HHI_HDMI_PLL_CNTL4, 0x0c8e0000);
        lcd_hiu_write(HHI_HDMI_PLL_CNTL5, 0x001fa729);
        lcd_hiu_write(HHI_HDMI_PLL_CNTL6, 0x01a31500);
        lcd_hiu_setb(HHI_HDMI_PLL_CNTL, 1, LCD_PLL_RST_TXL, 1);
@@ -1286,6 +1291,11 @@ static void lcd_clk_generate_txl(struct lcd_config_s *pconf)
                goto generate_clk_done_txl;
        }
 
+       if (pconf->lcd_timing.clk_auto == 2)
+               cConf->pll_mode = 1;
+       else
+               cConf->pll_mode = 0;
+
        switch (pconf->lcd_basic.lcd_type) {
        case LCD_TTL:
                clk_div_sel = CLK_DIV_SEL_1;
index 911a843..863509c 100644 (file)
 #include <linux/types.h>
 #include <linux/amlogic/media/vout/lcd/lcd_vout.h>
 
-/* clk config */
+/* **********************************
+ * clk config
+ * **********************************
+ */
 struct lcd_clk_config_s { /* unit: kHz */
        /* IN-OUT parameters */
        unsigned int fin;
@@ -69,9 +72,13 @@ struct lcd_clk_config_s { /* unit: kHz */
        unsigned int div_out_fmax; /* g9tv, g9bb, gxbb */
        unsigned int xd_out_fmax;
        unsigned int err_fmin;
+       unsigned int pll_mode;
 };
 
-/* pll & clk parameter */
+/* **********************************
+ * pll & clk parameter
+ * **********************************
+ */
 /* ******** clk calculation ******** */
 #define PLL_WAIT_LOCK_CNT           200
  /* frequency unit: kHz */
@@ -110,7 +117,10 @@ enum div_sel_e {
 };
 
 
-/* GXTVBB */
+/* **********************************
+ * GXTVBB
+ * **********************************
+ */
 /* ******** register bit ******** */
 /* PLL_CNTL 0x10c8 */
 #define LCD_PLL_LOCK_GXTVBB         31
@@ -143,7 +153,10 @@ enum div_sel_e {
 #define CRT_VID_CLK_IN_MAX_GXTVBB   (3100 * 1000)
 #define ENCL_CLK_IN_MAX_GXTVBB      (620 * 1000)
 
-/* GXL */
+/* **********************************
+ * GXL
+ * **********************************
+ */
 /* ******** register bit ******** */
 /* PLL_CNTL 0x10c8 */
 #define LCD_PLL_LOCK_GXL            31
@@ -176,7 +189,10 @@ enum div_sel_e {
 #define CRT_VID_CLK_IN_MAX_GXL      (3100 * 1000)
 #define ENCL_CLK_IN_MAX_GXL         (620 * 1000)
 
-/* GXM */
+/* **********************************
+ * GXM
+ * **********************************
+ */
 /* ******** register bit ******** */
 /* PLL_CNTL 0x10c8 */
 #define LCD_PLL_LOCK_GXM            31
@@ -209,7 +225,10 @@ enum div_sel_e {
 #define CRT_VID_CLK_IN_MAX_GXM      (3100 * 1000)
 #define ENCL_CLK_IN_MAX_GXM         (620 * 1000)
 
-/* TXL */
+/* **********************************
+ * TXL
+ * **********************************
+ */
 /* ******** register bit ******** */
 /* PLL_CNTL 0x10c8 */
 #define LCD_PLL_LOCK_TXL            31
@@ -242,7 +261,10 @@ enum div_sel_e {
 #define CRT_VID_CLK_IN_MAX_TXL      (3100 * 1000)
 #define ENCL_CLK_IN_MAX_TXL         (620 * 1000)
 
-/*  TXLX */
+/* **********************************
+ * TXLX
+ * **********************************
+ */
 /* ******** register bit ******** */
 /* PLL_CNTL 0x10c8 */
 #define LCD_PLL_LOCK_TXLX            31
@@ -275,7 +297,10 @@ enum div_sel_e {
 #define CRT_VID_CLK_IN_MAX_TXLX      (3100 * 1000)
 #define ENCL_CLK_IN_MAX_TXLX         (620 * 1000)
 
-/* AXG */
+/* **********************************
+ * AXG
+ * **********************************
+ */
 /* ******** register bit ******** */
 /* PLL_CNTL */
 #define LCD_PLL_LOCK_AXG            31
index dcd0be7..85b0441 100644 (file)
 #include "lcd_common.h"
 #include "lcd_reg.h"
 
-/* lcd type */
+/* **********************************
+ * lcd type
+ * **********************************
+ */
 struct lcd_type_match_s {
        char *name;
        enum lcd_type_e type;
@@ -102,7 +105,10 @@ char *lcd_mode_mode_to_str(int mode)
        return lcd_mode_table[mode];
 }
 
-/* lcd gpio */
+/* **********************************
+ * lcd gpio
+ * **********************************
+ */
 #if 0
 #define lcd_gpio_request(dev, str)        gpiod_get(dev, str)
 #define lcd_gpio_free(gdesc)              gpiod_put(gdesc)
@@ -780,7 +786,7 @@ int lcd_vmode_change(struct lcd_config_s *pconf)
        char str[100];
        int len = 0;
 
-       pconf->lcd_timing.clk_change = 0; /* clear clk flga */
+       pconf->lcd_timing.clk_change = 0; /* clear clk flag */
        switch (type) {
        case 0: /* pixel clk adjust */
                pclk = (h_period * v_period) / duration_den * duration_num;
@@ -788,9 +794,9 @@ int lcd_vmode_change(struct lcd_config_s *pconf)
                        pconf->lcd_timing.clk_change = LCD_CLK_PLL_CHANGE;
                break;
        case 1: /* htotal adjust */
-               h_period = ((pclk / v_period) * duration_den * 10) /
+               h_period = ((pclk / v_period) * duration_den * 100) /
                                duration_num;
-               h_period = (h_period + 5) / 10; /* round off */
+               h_period = (h_period + 99) / 100; /* round off */
                if (pconf->lcd_basic.h_period != h_period) {
                        /* check clk frac update */
                        pclk = (h_period * v_period) / duration_den *
@@ -802,9 +808,9 @@ int lcd_vmode_change(struct lcd_config_s *pconf)
                }
                break;
        case 2: /* vtotal adjust */
-               v_period = ((pclk / h_period) * duration_den * 10) /
+               v_period = ((pclk / h_period) * duration_den * 100) /
                                duration_num;
-               v_period = (v_period + 5) / 10; /* round off */
+               v_period = (v_period + 99) / 100; /* round off */
                if (pconf->lcd_basic.v_period != v_period) {
                        /* check clk frac update */
                        pclk = (h_period * v_period) / duration_den *
@@ -817,14 +823,14 @@ int lcd_vmode_change(struct lcd_config_s *pconf)
                break;
        case 3: /* free adjust, use min/max range to calculate */
        default:
-               v_period = ((pclk / h_period) * duration_den * 10) /
+               v_period = ((pclk / h_period) * duration_den * 100) /
                        duration_num;
-               v_period = (v_period + 5) / 10; /* round off */
+               v_period = (v_period + 99) / 100; /* round off */
                if (v_period > pconf->lcd_basic.v_period_max) {
                        v_period = pconf->lcd_basic.v_period_max;
-                       h_period = ((pclk / v_period) * duration_den * 10) /
+                       h_period = ((pclk / v_period) * duration_den * 100) /
                                duration_num;
-                       h_period = (h_period + 5) / 10; /* round off */
+                       h_period = (h_period + 99) / 100; /* round off */
                        if (h_period > pconf->lcd_basic.h_period_max) {
                                h_period = pconf->lcd_basic.h_period_max;
                                pclk = (h_period * v_period) / duration_den *
@@ -841,9 +847,9 @@ int lcd_vmode_change(struct lcd_config_s *pconf)
                        }
                } else if (v_period < pconf->lcd_basic.v_period_min) {
                        v_period = pconf->lcd_basic.v_period_min;
-                       h_period = ((pclk / v_period) * duration_den * 10) /
+                       h_period = ((pclk / v_period) * duration_den * 100) /
                                duration_num;
-                       h_period = (h_period + 5) / 10; /* round off */
+                       h_period = (h_period + 99) / 100; /* round off */
                        if (h_period < pconf->lcd_basic.h_period_min) {
                                h_period = pconf->lcd_basic.h_period_min;
                                pclk = (h_period * v_period) / duration_den *
index 08ae6af..3fadbef 100644 (file)
@@ -23,7 +23,8 @@
 #include "lcd_clk_config.h"
 
 /* 20170505: add a113 support to linux4.9 */
-#define LCD_DRV_VERSION    "20170505"
+/* 20170905: fix coverity errors */
+#define LCD_DRV_VERSION    "20170905"
 
 #define VPP_OUT_SATURATE            (1 << 0)
 
index 99a9c76..bee979e 100644 (file)
@@ -349,37 +349,37 @@ static void lcd_ttl_reg_print(void)
                reg, lcd_vcbus_read(reg));
        reg = L_STH1_HE_ADDR;
        pr_info("STH1_HE_ADDR        [0x%04x] = 0x%08x\n",
-               reg, lcd_hiu_read(reg));
+               reg, lcd_vcbus_read(reg));
        reg = L_STH1_VS_ADDR;
        pr_info("STH1_VS_ADDR        [0x%04x] = 0x%08x\n",
-               reg, lcd_hiu_read(reg));
+               reg, lcd_vcbus_read(reg));
        reg = L_STH1_VE_ADDR;
        pr_info("STH1_VE_ADDR        [0x%04x] = 0x%08x\n",
-               reg, lcd_hiu_read(reg));
+               reg, lcd_vcbus_read(reg));
        reg = L_STV1_HS_ADDR;
        pr_info("STV1_HS_ADDR        [0x%04x] = 0x%08x\n",
-               reg, lcd_hiu_read(reg));
+               reg, lcd_vcbus_read(reg));
        reg = L_STV1_HE_ADDR;
        pr_info("STV1_HE_ADDR        [0x%04x] = 0x%08x\n",
-               reg, lcd_hiu_read(reg));
+               reg, lcd_vcbus_read(reg));
        reg = L_STV1_VS_ADDR;
        pr_info("STV1_VS_ADDR        [0x%04x] = 0x%08x\n",
-               reg, lcd_hiu_read(reg));
+               reg, lcd_vcbus_read(reg));
        reg = L_STV1_VE_ADDR;
        pr_info("STV1_VE_ADDR        [0x%04x] = 0x%08x\n",
-               reg, lcd_hiu_read(reg));
+               reg, lcd_vcbus_read(reg));
        reg = L_OEH_HS_ADDR;
        pr_info("OEH_HS_ADDR         [0x%04x] = 0x%08x\n",
-               reg, lcd_hiu_read(reg));
+               reg, lcd_vcbus_read(reg));
        reg = L_OEH_HE_ADDR;
        pr_info("OEH_HE_ADDR         [0x%04x] = 0x%08x\n",
-               reg, lcd_hiu_read(reg));
+               reg, lcd_vcbus_read(reg));
        reg = L_OEH_VS_ADDR;
        pr_info("OEH_VS_ADDR         [0x%04x] = 0x%08x\n",
-               reg, lcd_hiu_read(reg));
+               reg, lcd_vcbus_read(reg));
        reg = L_OEH_VE_ADDR;
        pr_info("OEH_VE_ADDR         [0x%04x] = 0x%08x\n",
-               reg, lcd_hiu_read(reg));
+               reg, lcd_vcbus_read(reg));
 }
 
 static void lcd_lvds_reg_print(void)
@@ -407,14 +407,37 @@ static void lcd_lvds_reg_print(void)
 static void lcd_vbyone_reg_print(void)
 {
        unsigned int reg;
+       struct aml_lcd_drv_s *lcd_drv = aml_lcd_get_driver();
 
        pr_info("\nvbyone registers:\n");
-       reg = PERIPHS_PIN_MUX_7;
-       pr_info("VX1_PINMUX          [0x%04x] = 0x%08x\n",
-               reg, lcd_periphs_read(reg));
+       switch (lcd_drv->chip_type) {
+       case LCD_CHIP_GXTVBB:
+               reg = PERIPHS_PIN_MUX_7;
+               pr_info("VX1_PINMUX          [0x%04x] = 0x%08x\n",
+                       reg, lcd_periphs_read(reg));
+               break;
+       case LCD_CHIP_TXL:
+       case LCD_CHIP_TXLX:
+               reg = PERIPHS_PIN_MUX_0;
+               pr_info("VX1_PINMUX          [0x%04x] = 0x%08x\n",
+                       reg, lcd_periphs_read(reg));
+               break;
+       default:
+               break;
+       }
        reg = VBO_STATUS_L;
        pr_info("VX1_STATUS          [0x%04x] = 0x%08x\n",
                reg, lcd_vcbus_read(reg));
+       switch (lcd_drv->chip_type) {
+       case LCD_CHIP_TXL:
+       case LCD_CHIP_TXLX:
+               reg = VBO_INSGN_CTRL;
+               pr_info("VBO_INSGN_CTRL      [0x%04x] = 0x%08x\n",
+                       reg, lcd_vcbus_read(reg));
+               break;
+       default:
+               break;
+       }
        reg = VBO_FSM_HOLDER_L;
        pr_info("VX1_FSM_HOLDER_L    [0x%04x] = 0x%08x\n",
                reg, lcd_vcbus_read(reg));
@@ -505,7 +528,7 @@ static void lcd_reg_print(void)
        struct lcd_config_s *pconf;
 
        pconf = lcd_drv->lcd_config;
-       pr_info("clk registers:\n");
+       LCDPR("clk registers:\n");
        switch (lcd_drv->chip_type) {
        case LCD_CHIP_AXG:
                for (i = 0; i < ARRAY_SIZE(lcd_reg_dump_clk_axg); i++) {
@@ -616,20 +639,19 @@ static void lcd_debug_test(unsigned int num)
 
        h_active = lcd_drv->lcd_config->lcd_basic.h_active;
        video_on_pixel = lcd_drv->lcd_config->lcd_timing.video_on_pixel;
-       if (num >= 0) {
-               lcd_vcbus_write(ENCL_VIDEO_RGBIN_CTRL, lcd_enc_tst[num][6]);
-               lcd_vcbus_write(ENCL_TST_MDSEL, lcd_enc_tst[num][0]);
-               lcd_vcbus_write(ENCL_TST_Y, lcd_enc_tst[num][1]);
-               lcd_vcbus_write(ENCL_TST_CB, lcd_enc_tst[num][2]);
-               lcd_vcbus_write(ENCL_TST_CR, lcd_enc_tst[num][3]);
-               lcd_vcbus_write(ENCL_TST_CLRBAR_STRT, video_on_pixel);
-               lcd_vcbus_write(ENCL_TST_CLRBAR_WIDTH, (h_active / 9));
-               lcd_vcbus_write(ENCL_TST_EN, lcd_enc_tst[num][4]);
-               lcd_vcbus_setb(ENCL_VIDEO_MODE_ADV, lcd_enc_tst[num][5], 3, 1);
+       lcd_vcbus_write(ENCL_VIDEO_RGBIN_CTRL, lcd_enc_tst[num][6]);
+       lcd_vcbus_write(ENCL_TST_MDSEL, lcd_enc_tst[num][0]);
+       lcd_vcbus_write(ENCL_TST_Y, lcd_enc_tst[num][1]);
+       lcd_vcbus_write(ENCL_TST_CB, lcd_enc_tst[num][2]);
+       lcd_vcbus_write(ENCL_TST_CR, lcd_enc_tst[num][3]);
+       lcd_vcbus_write(ENCL_TST_CLRBAR_STRT, video_on_pixel);
+       lcd_vcbus_write(ENCL_TST_CLRBAR_WIDTH, (h_active / 9));
+       lcd_vcbus_write(ENCL_TST_EN, lcd_enc_tst[num][4]);
+       lcd_vcbus_setb(ENCL_VIDEO_MODE_ADV, lcd_enc_tst[num][5], 3, 1);
+       if (num > 0)
                LCDPR("show test pattern: %s\n", lcd_enc_tst_str[num]);
-       } else {
+       else
                LCDPR("disable test pattern\n");
-       }
 }
 
 static void lcd_mute_setting(unsigned char flag)
@@ -680,11 +702,37 @@ static void lcd_test_check(void)
        }
 }
 
+static void lcd_vinfo_update(void)
+{
+       struct aml_lcd_drv_s *lcd_drv = aml_lcd_get_driver();
+       struct vinfo_s *vinfo;
+       struct lcd_config_s *pconf;
+
+       vinfo = lcd_drv->lcd_info;
+       pconf = lcd_drv->lcd_config;
+       if (vinfo) {
+               vinfo->width = pconf->lcd_basic.h_active;
+               vinfo->height = pconf->lcd_basic.v_active;
+               vinfo->field_height = pconf->lcd_basic.v_active;
+               vinfo->aspect_ratio_num = pconf->lcd_basic.screen_width;
+               vinfo->aspect_ratio_den = pconf->lcd_basic.screen_height;
+               vinfo->screen_real_width = pconf->lcd_basic.screen_width;
+               vinfo->screen_real_height = pconf->lcd_basic.screen_height;
+               vinfo->sync_duration_num = pconf->lcd_timing.sync_duration_num;
+               vinfo->sync_duration_den = pconf->lcd_timing.sync_duration_den;
+               vinfo->video_clk = pconf->lcd_timing.lcd_clk;
+       }
+       vout_notifier_call_chain(VOUT_EVENT_MODE_CHANGE,
+               &lcd_drv->lcd_info->mode);
+}
+
 static void lcd_debug_config_update(void)
 {
        struct aml_lcd_drv_s *lcd_drv = aml_lcd_get_driver();
 
        lcd_drv->module_reset();
+
+       lcd_vinfo_update();
 }
 
 static void lcd_debug_clk_change(unsigned int pclk)
@@ -697,6 +745,7 @@ static void lcd_debug_clk_change(unsigned int pclk)
        sync_duration = pclk / pconf->lcd_basic.h_period;
        sync_duration = sync_duration * 100 / pconf->lcd_basic.v_period;
        pconf->lcd_timing.lcd_clk = pclk;
+       pconf->lcd_timing.lcd_clk_dft = pconf->lcd_timing.lcd_clk;
        pconf->lcd_timing.sync_duration_num = sync_duration;
        pconf->lcd_timing.sync_duration_den = 100;
 
@@ -761,6 +810,8 @@ static ssize_t lcd_debug_store(struct class *class,
                                pconf->lcd_basic.v_active = val[1];
                                pconf->lcd_basic.h_period = val[2];
                                pconf->lcd_basic.v_period = val[3];
+                               pconf->lcd_timing.h_period_dft = val[2];
+                               pconf->lcd_timing.v_period_dft = val[3];
                                pr_info("set h_active=%d, v_active=%d\n",
                                        val[0], val[1]);
                                pr_info("set h_period=%d, v_period=%d\n",
@@ -772,6 +823,8 @@ static ssize_t lcd_debug_store(struct class *class,
                                pconf->lcd_basic.v_active = val[1];
                                pconf->lcd_basic.h_period = val[2];
                                pconf->lcd_basic.v_period = val[3];
+                               pconf->lcd_timing.h_period_dft = val[2];
+                               pconf->lcd_timing.v_period_dft = val[3];
                                pconf->lcd_basic.lcd_bits = val[4];
                                pr_info("set h_active=%d, v_active=%d\n",
                                        val[0], val[1]);
@@ -916,6 +969,15 @@ static ssize_t lcd_debug_store(struct class *class,
        return count;
 }
 
+static ssize_t lcd_debug_enable_show(struct class *class,
+               struct class_attribute *attr, char *buf)
+{
+       struct aml_lcd_drv_s *lcd_drv = aml_lcd_get_driver();
+
+       return sprintf(buf, "lcd_status: %d\n",
+               lcd_drv->lcd_status);
+}
+
 static ssize_t lcd_debug_enable_store(struct class *class,
                struct class_attribute *attr, const char *buf, size_t count)
 {
@@ -923,6 +985,10 @@ static ssize_t lcd_debug_enable_store(struct class *class,
        unsigned int temp = 1;
 
        ret = kstrtouint(buf, 10, &temp);
+       if (ret) {
+               LCDERR("invalid data\n");
+               return -EINVAL;
+       }
        if (temp) {
                mutex_lock(&lcd_power_mutex);
                aml_lcd_notifier_call_chain(LCD_EVENT_POWER_ON, NULL);
@@ -936,6 +1002,34 @@ static ssize_t lcd_debug_enable_store(struct class *class,
        return count;
 }
 
+static ssize_t lcd_debug_resume_show(struct class *class,
+               struct class_attribute *attr, char *buf)
+{
+       struct aml_lcd_drv_s *lcd_drv = aml_lcd_get_driver();
+
+       return sprintf(buf, "lcd resume flag: %d(%s)\n",
+               lcd_drv->lcd_resume_flag,
+               lcd_drv->lcd_resume_flag ? "workqueue" : "directly");
+}
+
+static ssize_t lcd_debug_resume_store(struct class *class,
+               struct class_attribute *attr, const char *buf, size_t count)
+{
+       int ret = 0;
+       struct aml_lcd_drv_s *lcd_drv = aml_lcd_get_driver();
+       unsigned int temp = 1;
+
+       ret = kstrtouint(buf, 10, &temp);
+       if (ret) {
+               LCDERR("invalid data\n");
+               return -EINVAL;
+       }
+       lcd_drv->lcd_resume_flag = (unsigned char)temp;
+       LCDPR("set lcd resume flag: %d\n", lcd_drv->lcd_resume_flag);
+
+       return count;
+}
+
 static ssize_t lcd_debug_power_show(struct class *class,
                struct class_attribute *attr, char *buf)
 {
@@ -1064,6 +1158,10 @@ static ssize_t lcd_debug_fr_policy_store(struct class *class,
        struct aml_lcd_drv_s *lcd_drv = aml_lcd_get_driver();
 
        ret = kstrtouint(buf, 10, &temp);
+       if (ret) {
+               pr_info("invalid data\n");
+               return -EINVAL;
+       }
        lcd_drv->fr_auto_policy = temp;
        pr_info("set fr_auto_policy: %d\n", temp);
 
@@ -1085,6 +1183,10 @@ static ssize_t lcd_debug_ss_store(struct class *class,
        struct aml_lcd_drv_s *lcd_drv = aml_lcd_get_driver();
 
        ret = kstrtouint(buf, 10, &temp);
+       if (ret) {
+               pr_info("invalid data\n");
+               return -EINVAL;
+       }
        lcd_drv->lcd_config->lcd_timing.ss_level = temp;
        lcd_set_spread_spectrum();
 
@@ -1106,6 +1208,10 @@ static ssize_t lcd_debug_test_store(struct class *class,
        struct aml_lcd_drv_s *lcd_drv = aml_lcd_get_driver();
 
        ret = kstrtouint(buf, 10, &temp);
+       if (ret) {
+               pr_info("invalid data\n");
+               return -EINVAL;
+       }
        lcd_drv->lcd_test_flag = (unsigned char)temp;
        lcd_debug_test(temp);
 
@@ -1128,6 +1234,10 @@ static ssize_t lcd_debug_mute_store(struct class *class,
        struct aml_lcd_drv_s *lcd_drv = aml_lcd_get_driver();
 
        ret = kstrtouint(buf, 10, &temp);
+       if (ret) {
+               pr_info("invalid data\n");
+               return -EINVAL;
+       }
        lcd_drv->lcd_mute = (unsigned char)temp;
        lcd_mute_setting(lcd_drv->lcd_mute);
 
@@ -1483,6 +1593,10 @@ static ssize_t lcd_debug_print_store(struct class *class,
        unsigned int temp = 0;
 
        ret = kstrtouint(buf, 10, &temp);
+       if (ret) {
+               pr_info("invalid data\n");
+               return -EINVAL;
+       }
        lcd_debug_print_flag = (unsigned char)temp;
        LCDPR("set debug print flag: %d\n", lcd_debug_print_flag);
 
@@ -1490,19 +1604,22 @@ static ssize_t lcd_debug_print_store(struct class *class,
 }
 
 static struct class_attribute lcd_debug_class_attrs[] = {
-       __ATTR(help,        0644, lcd_debug_common_help, NULL),
+       __ATTR(help,        0444, lcd_debug_common_help, NULL),
        __ATTR(debug,       0644, lcd_debug_show, lcd_debug_store),
-       __ATTR(enable,      0644, NULL, lcd_debug_enable_store),
+       __ATTR(enable,      0644,
+               lcd_debug_enable_show, lcd_debug_enable_store),
+       __ATTR(resume,      0644,
+               lcd_debug_resume_show, lcd_debug_resume_store),
        __ATTR(power,       0644, lcd_debug_power_show, lcd_debug_power_store),
        __ATTR(frame_rate,  0644,
                lcd_debug_frame_rate_show, lcd_debug_frame_rate_store),
        __ATTR(fr_policy,   0644,
                lcd_debug_fr_policy_show, lcd_debug_fr_policy_store),
        __ATTR(ss,          0644, lcd_debug_ss_show, lcd_debug_ss_store),
-       __ATTR(clk,         0644, lcd_debug_clk_show, NULL),
-       __ATTR(test,        0644, NULL, lcd_debug_test_store),
+       __ATTR(clk,         0444, lcd_debug_clk_show, NULL),
+       __ATTR(test,        0200, NULL, lcd_debug_test_store),
        __ATTR(mute,        0644, lcd_debug_mute_show, lcd_debug_mute_store),
-       __ATTR(reg,         0644, NULL, lcd_debug_reg_store),
+       __ATTR(reg,         0200, NULL, lcd_debug_reg_store),
        __ATTR(dither,      0644,
                lcd_debug_dither_show, lcd_debug_dither_store),
        __ATTR(print,       0644, lcd_debug_print_show, lcd_debug_print_store),
@@ -1524,7 +1641,7 @@ static const char *lcd_lvds_debug_usage_str = {
 "Usage:\n"
 "    echo <repack> <dual_port> <pn_swap> <port_swap> <lane_reverse> > lvds ; set lvds config\n"
 "data format:\n"
-"    <repack>    : 0=JEIDA mode, 1=VESA mode\n"
+"    <repack>    : 0=JEIDA mode, 1=VESA mode(8bit), 2=VESA mode(10bit)\n"
 "    <dual_port> : 0=single port, 1=dual port\n"
 "    <pn_swap>   : 0=normal, 1=swap p/n channels\n"
 "    <port_swap> : 0=normal, 1=swap A/B port\n"
@@ -1673,17 +1790,22 @@ static ssize_t lcd_lvds_debug_store(struct class *class,
        return count;
 }
 
+#ifdef CONFIG_AMLOGIC_LCD_TV
 static int vx1_intr_state = 1;
+#endif
 static ssize_t lcd_vx1_debug_store(struct class *class,
                struct class_attribute *attr, const char *buf, size_t count)
 {
        int ret = 0;
        struct aml_lcd_drv_s *lcd_drv = aml_lcd_get_driver();
        struct vbyone_config_s *vx1_conf;
+#ifdef CONFIG_AMLOGIC_LCD_TV
        int val[2];
+#endif
 
        vx1_conf = lcd_drv->lcd_config->lcd_control.vbyone_config;
        if (buf[0] == 'i') { /* intr */
+#ifdef CONFIG_AMLOGIC_LCD_TV
                ret = sscanf(buf, "intr %d %d", &val[0], &val[1]);
                if (ret == 1) {
                        pr_info("set vbyone interrupt enable: %d\n", val[0]);
@@ -1700,7 +1822,11 @@ static ssize_t lcd_vx1_debug_store(struct class *class,
                                vx1_intr_state, vx1_conf->intr_en);
                        return -EINVAL;
                }
+#else
+               return -EINVAL;
+#endif
        } else if (buf[0] == 'v') { /* vintr */
+#ifdef CONFIG_AMLOGIC_LCD_TV
                ret = sscanf(buf, "vintr %d", &val[0]);
                if (ret == 1) {
                        pr_info("set vbyone vsync interrupt enable: %d\n",
@@ -1712,6 +1838,9 @@ static ssize_t lcd_vx1_debug_store(struct class *class,
                                vx1_conf->vsync_intr_en);
                        return -EINVAL;
                }
+#else
+               return -EINVAL;
+#endif
        } else {
                ret = sscanf(buf, "%d %d %d", &vx1_conf->lane_count,
                        &vx1_conf->region_num, &vx1_conf->byte_mode);
index f7c4f09..a200f73 100644 (file)
 #define VBO_TMCHK_VDE_STATE_L                      0x14f6
 #define VBO_TMCHK_VDE_STATE_H                      0x14f7
 #define VBO_INTR_STATE                             0x14f8
+#define VBO_INFILTER_CTRL                          0x14f9
+#define VBO_INSGN_CTRL                             0x14fa
 
 /* ********************************
  * Video Interface:  VENC_VCBUS_BASE = 0x1b
index 183dc1f..b70241e 100644 (file)
@@ -356,8 +356,6 @@ static void lcd_lvds_control_set(struct lcd_config_s *pconf)
        switch (pconf->lcd_basic.lcd_bits) {
        case 10:
                bit_num = 0;
-               if (lvds_repack == 1)
-                       lvds_repack = 2;
                break;
        case 8:
                bit_num = 1;
@@ -734,7 +732,6 @@ static void lcd_vbyone_config_set(struct lcd_config_s *pconf)
 {
        unsigned int band_width, bit_rate, pclk, phy_div;
        unsigned int byte_mode, lane_count, minlane;
-       unsigned int lcd_bits;
        unsigned int temp, i;
 
        if (lcd_debug_print_flag)
@@ -742,8 +739,7 @@ static void lcd_vbyone_config_set(struct lcd_config_s *pconf)
 
        /* auto calculate bandwidth, clock */
        lane_count = pconf->lcd_control.vbyone_config->lane_count;
-       lcd_bits = 10; /* pconf->lcd_basic.lcd_bits */
-       byte_mode = (lcd_bits == 10) ? 4 : 3;
+       byte_mode = pconf->lcd_control.vbyone_config->byte_mode;
        /* byte_mode * byte2bit * 8/10_encoding * pclk =
           byte_mode * 8 * 10 / 8 * pclk */
        pclk = pconf->lcd_timing.lcd_clk / 1000; /* kHz */
index 54e0c9d..f33f38c 100644 (file)
@@ -140,6 +140,8 @@ static int lcd_framerate_automation_set_mode(void)
 {
        struct aml_lcd_drv_s *lcd_drv = aml_lcd_get_driver();
 
+       LCDPR("%s\n", __func__);
+
        /* update lcd config sync_duration, for calculate */
        lcd_drv->lcd_config->lcd_timing.sync_duration_num =
                lcd_drv->lcd_info->sync_duration_num;
@@ -296,15 +298,35 @@ static int lcd_suspend(void)
        mutex_unlock(&lcd_power_mutex);
        return 0;
 }
+
 static int lcd_resume(void)
 {
-       mutex_lock(&lcd_power_mutex);
-       if (lcd_resume_flag == 0) {
+       struct aml_lcd_drv_s *lcd_drv = aml_lcd_get_driver();
+
+       if (lcd_resume_flag)
+               return 0;
+
+       if (lcd_drv->lcd_resume_flag) {
+               if (lcd_drv->workqueue) {
+                       queue_work(lcd_drv->workqueue,
+                               &(lcd_drv->lcd_resume_work));
+               } else {
+                       LCDPR("Warning: no lcd workqueue\n");
+                       mutex_lock(&lcd_power_mutex);
+                       lcd_resume_flag = 1;
+                       aml_lcd_notifier_call_chain(LCD_EVENT_POWER_ON, NULL);
+                       LCDPR("%s finished\n", __func__);
+                       mutex_unlock(&lcd_power_mutex);
+               }
+       } else {
+               LCDPR("directly lcd late resume\n");
+               mutex_lock(&lcd_power_mutex);
                lcd_resume_flag = 1;
                aml_lcd_notifier_call_chain(LCD_EVENT_POWER_ON, NULL);
                LCDPR("%s finished\n", __func__);
+               mutex_unlock(&lcd_power_mutex);
        }
-       mutex_unlock(&lcd_power_mutex);
+
        return 0;
 }
 #endif
@@ -336,6 +358,13 @@ static void lcd_tablet_vinfo_update(void)
 
        vinfo = lcd_drv->lcd_info;
        pconf = lcd_drv->lcd_config;
+
+       /* store standard duration */
+       lcd_drv->std_duration.duration_num =
+               pconf->lcd_timing.sync_duration_num;
+       lcd_drv->std_duration.duration_den =
+               pconf->lcd_timing.sync_duration_den;
+
        if (vinfo) {
                vinfo->name = PANEL_NAME;
                vinfo->mode = VMODE_LCD;
@@ -524,10 +553,13 @@ static int lcd_config_load_from_dts(struct lcd_config_s *pconf,
        ret = of_property_read_string(child, "model_name", &str);
        if (ret) {
                LCDERR("failed to get model_name\n");
-               strcpy(pconf->lcd_basic.model_name, pconf->lcd_propname);
+               strncpy(pconf->lcd_basic.model_name, pconf->lcd_propname,
+                       MOD_LEN_MAX);
        } else {
-               strcpy(pconf->lcd_basic.model_name, str);
+               strncpy(pconf->lcd_basic.model_name, str, MOD_LEN_MAX);
        }
+       /* ensure string ending */
+       pconf->lcd_basic.model_name[MOD_LEN_MAX-1] = '\0';
 
        ret = of_property_read_string(child, "interface", &str);
        if (ret) {
@@ -705,7 +737,7 @@ static int lcd_config_load_from_dts(struct lcd_config_s *pconf,
                        pconf->lcd_control.vbyone_config->phy_vswing = para[0];
                        pconf->lcd_control.vbyone_config->phy_preem = para[1];
                        if (lcd_debug_print_flag) {
-                               LCDPR("phy vswing=%d, preemphasis=%d\n",
+                               LCDPR("phy vswing=0x%x, preemphasis=0x%x\n",
                                pconf->lcd_control.vbyone_config->phy_vswing,
                                pconf->lcd_control.vbyone_config->phy_preem);
                        }
@@ -791,12 +823,19 @@ static int lcd_config_load_from_unifykey(struct lcd_config_s *pconf)
        }
 
        lcd_unifykey_header_check(para, &lcd_header);
-       len = 10 + 36 + 18 + 31 + 20;
+       LCDPR("unifykey version: 0x%04x\n", lcd_header.version);
+       switch (lcd_header.version) {
+       case 2:
+               len = 10 + 36 + 18 + 31 + 20 + 44 + 10;
+               break;
+       default:
+               len = 10 + 36 + 18 + 31 + 20;
+               break;
+       }
        if (lcd_debug_print_flag) {
                LCDPR("unifykey header:\n");
                LCDPR("crc32             = 0x%08x\n", lcd_header.crc32);
                LCDPR("data_len          = %d\n", lcd_header.data_len);
-               LCDPR("version           = 0x%04x\n", lcd_header.version);
                LCDPR("reserved          = 0x%04x\n", lcd_header.reserved);
        }
 
@@ -808,11 +847,15 @@ static int lcd_config_load_from_unifykey(struct lcd_config_s *pconf)
                return -1;
        }
 
+       /* panel_type update */
+       sprintf(pconf->lcd_propname, "%s", "unifykey");
+
        /* basic: 36byte */
        p = para + LCD_UKEY_HEAD_SIZE;
-       *(p + LCD_UKEY_MODEL_NAME - 1) = '\0'; /* ensure string ending */
        str = (const char *)p;
-       strcpy(pconf->lcd_basic.model_name, str);
+       strncpy(pconf->lcd_basic.model_name, str, MOD_LEN_MAX);
+       /* ensure string ending */
+       pconf->lcd_basic.model_name[MOD_LEN_MAX-1] = '\0';
        p += LCD_UKEY_MODEL_NAME;
        pconf->lcd_basic.lcd_type = *p;
        p += LCD_UKEY_INTERFACE;
@@ -875,68 +918,59 @@ static int lcd_config_load_from_unifykey(struct lcd_config_s *pconf)
 
        /* interface: 20byte */
        if (pconf->lcd_basic.lcd_type == LCD_LVDS) {
-               if (lcd_header.version == 1) {
+               if (lcd_header.version == 2) {
                        pconf->lcd_control.lvds_config->lvds_repack =
                                        (*p | ((*(p + 1)) << 8)) & 0xff;
                        p += LCD_UKEY_IF_ATTR_0;
                        pconf->lcd_control.lvds_config->dual_port =
                                        (*p | ((*(p + 1)) << 8)) & 0xff;
                        p += LCD_UKEY_IF_ATTR_1;
-                       pconf->lcd_control.lvds_config->pn_swap  =
+                       pconf->lcd_control.lvds_config->pn_swap =
                                        (*p | ((*(p + 1)) << 8)) & 0xff;
                        p += LCD_UKEY_IF_ATTR_2;
-                       pconf->lcd_control.lvds_config->port_swap  =
+                       pconf->lcd_control.lvds_config->port_swap =
                                        (*p | ((*(p + 1)) << 8)) & 0xff;
                        p += LCD_UKEY_IF_ATTR_3;
-                       pconf->lcd_control.lvds_config->phy_vswing =
+                       pconf->lcd_control.lvds_config->lane_reverse =
                                        (*p | ((*(p + 1)) << 8)) & 0xff;
                        p += LCD_UKEY_IF_ATTR_4;
-                       pconf->lcd_control.lvds_config->phy_preem =
-                                       (*p | ((*(p + 1)) << 8)) & 0xff;
+                       /* dummy pointer */
                        p += LCD_UKEY_IF_ATTR_5;
-                       pconf->lcd_control.lvds_config->phy_clk_vswing =
-                                       (*p | ((*(p + 1)) << 8)) & 0xff;
                        p += LCD_UKEY_IF_ATTR_6;
-                       pconf->lcd_control.lvds_config->phy_clk_preem  =
-                                       (*p | ((*(p + 1)) << 8)) & 0xff;
                        p += LCD_UKEY_IF_ATTR_7;
-                       pconf->lcd_control.lvds_config->lane_reverse = 0;
                        p += LCD_UKEY_IF_ATTR_8;
-
-                       /* dummy pointer */
                        p += LCD_UKEY_IF_ATTR_9;
-                       }
-               else if (lcd_header.version == 2) {
+               } else {
                        pconf->lcd_control.lvds_config->lvds_repack =
                                        (*p | ((*(p + 1)) << 8)) & 0xff;
                        p += LCD_UKEY_IF_ATTR_0;
                        pconf->lcd_control.lvds_config->dual_port =
                                        (*p | ((*(p + 1)) << 8)) & 0xff;
                        p += LCD_UKEY_IF_ATTR_1;
-                       pconf->lcd_control.lvds_config->pn_swap  =
+                       pconf->lcd_control.lvds_config->pn_swap =
                                        (*p | ((*(p + 1)) << 8)) & 0xff;
                        p += LCD_UKEY_IF_ATTR_2;
-                       pconf->lcd_control.lvds_config->port_swap  =
+                       pconf->lcd_control.lvds_config->port_swap =
                                        (*p | ((*(p + 1)) << 8)) & 0xff;
                        p += LCD_UKEY_IF_ATTR_3;
-                       pconf->lcd_control.lvds_config->lane_reverse  =
+                       pconf->lcd_control.lvds_config->phy_vswing =
                                        (*p | ((*(p + 1)) << 8)) & 0xff;
                        p += LCD_UKEY_IF_ATTR_4;
-                       pconf->lcd_control.lvds_config->phy_vswing =
+                       pconf->lcd_control.lvds_config->phy_preem =
                                        (*p | ((*(p + 1)) << 8)) & 0xff;
                        p += LCD_UKEY_IF_ATTR_5;
-                       pconf->lcd_control.lvds_config->phy_preem =
+                       pconf->lcd_control.lvds_config->phy_clk_vswing =
                                        (*p | ((*(p + 1)) << 8)) & 0xff;
                        p += LCD_UKEY_IF_ATTR_6;
-                       pconf->lcd_control.lvds_config->phy_clk_vswing =
+                       pconf->lcd_control.lvds_config->phy_clk_preem =
                                        (*p | ((*(p + 1)) << 8)) & 0xff;
                        p += LCD_UKEY_IF_ATTR_7;
-                       pconf->lcd_control.lvds_config->phy_clk_preem  =
-                                       (*p | ((*(p + 1)) << 8)) & 0xff;
-                       p += LCD_UKEY_IF_ATTR_8;
                        /* dummy pointer */
+                       p += LCD_UKEY_IF_ATTR_8;
                        p += LCD_UKEY_IF_ATTR_9;
-                       }
+
+                       pconf->lcd_control.lvds_config->lane_reverse = 0;
+               }
        } else if (pconf->lcd_basic.lcd_type == LCD_TTL) {
                pconf->lcd_control.ttl_config->clk_pol =
                        (*p | ((*(p + 1)) << 8)) & 0x1;
@@ -960,67 +994,59 @@ static int lcd_config_load_from_unifykey(struct lcd_config_s *pconf)
                p += LCD_UKEY_IF_ATTR_8;
                p += LCD_UKEY_IF_ATTR_9;
        } else if (pconf->lcd_basic.lcd_type == LCD_VBYONE) {
-               pconf->lcd_control.vbyone_config->lane_count =
-                               (*p | ((*(p + 1)) << 8)) & 0xff;
-               p += LCD_UKEY_IF_ATTR_0;
-               pconf->lcd_control.vbyone_config->region_num =
-                               (*p | ((*(p + 1)) << 8)) & 0xff;
-               p += LCD_UKEY_IF_ATTR_1;
-               pconf->lcd_control.vbyone_config->byte_mode  =
-                               (*p | ((*(p + 1)) << 8)) & 0xff;
-               p += LCD_UKEY_IF_ATTR_2;
-               pconf->lcd_control.vbyone_config->color_fmt  =
-                               (*p | ((*(p + 1)) << 8)) & 0xff;
-               p += LCD_UKEY_IF_ATTR_3;
-               pconf->lcd_control.vbyone_config->phy_vswing =
-                               (*p | ((*(p + 1)) << 8)) & 0xff;
-               p += LCD_UKEY_IF_ATTR_4;
-               pconf->lcd_control.vbyone_config->phy_preem =
-                               (*p | ((*(p + 1)) << 8)) & 0xff;
-               p += LCD_UKEY_IF_ATTR_5;
-               pconf->lcd_control.vbyone_config->intr_en =
-                               (*p | ((*(p + 1)) << 8)) & 0xff;
-               p += LCD_UKEY_IF_ATTR_6;
-               pconf->lcd_control.vbyone_config->vsync_intr_en =
-                               (*p | ((*(p + 1)) << 8)) & 0xff;
-               p += LCD_UKEY_IF_ATTR_7;
-               /* dummy pointer */
-               p += LCD_UKEY_IF_ATTR_8;
-               p += LCD_UKEY_IF_ATTR_9;
-       } else if (pconf->lcd_basic.lcd_type == LCD_MIPI) {
-               pconf->lcd_control.mipi_config->lane_num =
-                       (*p | ((*(p + 1)) << 8)) & 0xff;
-               p += LCD_UKEY_IF_ATTR_0;
-               pconf->lcd_control.mipi_config->bit_rate_max =
-                       (*p | ((*(p + 1)) << 8)) & 0xff;
-               p += LCD_UKEY_IF_ATTR_1;
-               pconf->lcd_control.mipi_config->factor_numerator =
-                       (*p | ((*(p + 1)) << 8)) & 0xff;
-               p += LCD_UKEY_IF_ATTR_2;
-               pconf->lcd_control.mipi_config->factor_denominator =
-                       100;
-               pconf->lcd_control.mipi_config->operation_mode_init =
-                       (*p | ((*(p + 1)) << 8)) & 0xff;
-               p += LCD_UKEY_IF_ATTR_3;
-               pconf->lcd_control.mipi_config->operation_mode_display =
-                       (*p | ((*(p + 1)) << 8)) & 0xff;
-               p += LCD_UKEY_IF_ATTR_4;
-               pconf->lcd_control.mipi_config->video_mode_type =
-                       (*p | ((*(p + 1)) << 8)) & 0xff;
-               p += LCD_UKEY_IF_ATTR_5;
-               pconf->lcd_control.mipi_config->clk_lp_continuous =
-                       (*p | ((*(p + 1)) << 8)) & 0xff;
-               p += LCD_UKEY_IF_ATTR_6;
-               pconf->lcd_control.mipi_config->phy_stop_wait =
-                       (*p | ((*(p + 1)) << 8)) & 0xff;
-               p += LCD_UKEY_IF_ATTR_7;
-               pconf->lcd_control.mipi_config->extern_init =
-                       (*p | ((*(p + 1)) << 8)) & 0xff;
-               p += LCD_UKEY_IF_ATTR_8;
-
-               /* dummy pointer */
-               p += LCD_UKEY_IF_ATTR_9;
-
+               if (lcd_header.version == 2) {
+                       pconf->lcd_control.vbyone_config->lane_count =
+                                       (*p | ((*(p + 1)) << 8)) & 0xff;
+                       p += LCD_UKEY_IF_ATTR_0;
+                       pconf->lcd_control.vbyone_config->region_num =
+                                       (*p | ((*(p + 1)) << 8)) & 0xff;
+                       p += LCD_UKEY_IF_ATTR_1;
+                       pconf->lcd_control.vbyone_config->byte_mode  =
+                                       (*p | ((*(p + 1)) << 8)) & 0xff;
+                       p += LCD_UKEY_IF_ATTR_2;
+                       pconf->lcd_control.vbyone_config->color_fmt  =
+                                       (*p | ((*(p + 1)) << 8)) & 0xff;
+                       p += LCD_UKEY_IF_ATTR_3;
+                       pconf->lcd_control.vbyone_config->intr_en =
+                                       (*p | ((*(p + 1)) << 8)) & 0xff;
+                       p += LCD_UKEY_IF_ATTR_4;
+                       pconf->lcd_control.vbyone_config->vsync_intr_en =
+                                       (*p | ((*(p + 1)) << 8)) & 0xff;
+                       p += LCD_UKEY_IF_ATTR_5;
+                       /* dummy pointer */
+                       p += LCD_UKEY_IF_ATTR_6;
+                       p += LCD_UKEY_IF_ATTR_7;
+                       p += LCD_UKEY_IF_ATTR_8;
+                       p += LCD_UKEY_IF_ATTR_9;
+               } else {
+                       pconf->lcd_control.vbyone_config->lane_count =
+                                       (*p | ((*(p + 1)) << 8)) & 0xff;
+                       p += LCD_UKEY_IF_ATTR_0;
+                       pconf->lcd_control.vbyone_config->region_num =
+                                       (*p | ((*(p + 1)) << 8)) & 0xff;
+                       p += LCD_UKEY_IF_ATTR_1;
+                       pconf->lcd_control.vbyone_config->byte_mode  =
+                                       (*p | ((*(p + 1)) << 8)) & 0xff;
+                       p += LCD_UKEY_IF_ATTR_2;
+                       pconf->lcd_control.vbyone_config->color_fmt  =
+                                       (*p | ((*(p + 1)) << 8)) & 0xff;
+                       p += LCD_UKEY_IF_ATTR_3;
+                       pconf->lcd_control.vbyone_config->phy_vswing =
+                                       (*p | ((*(p + 1)) << 8)) & 0xff;
+                       p += LCD_UKEY_IF_ATTR_4;
+                       pconf->lcd_control.vbyone_config->phy_preem =
+                                       (*p | ((*(p + 1)) << 8)) & 0xff;
+                       p += LCD_UKEY_IF_ATTR_5;
+                       pconf->lcd_control.vbyone_config->intr_en =
+                                       (*p | ((*(p + 1)) << 8)) & 0xff;
+                       p += LCD_UKEY_IF_ATTR_6;
+                       pconf->lcd_control.vbyone_config->vsync_intr_en =
+                                       (*p | ((*(p + 1)) << 8)) & 0xff;
+                       p += LCD_UKEY_IF_ATTR_7;
+                       /* dummy pointer */
+                       p += LCD_UKEY_IF_ATTR_8;
+                       p += LCD_UKEY_IF_ATTR_9;
+               }
        } else {
                LCDERR("unsupport lcd_type: %d\n", pconf->lcd_basic.lcd_type);
                p += LCD_UKEY_IF_ATTR_0;
@@ -1035,6 +1061,78 @@ static int lcd_config_load_from_unifykey(struct lcd_config_s *pconf)
                p += LCD_UKEY_IF_ATTR_9;
        }
 
+       if (lcd_header.version == 2) {
+               /* ctrl: 44byte */ /* v2 */
+               /* dummy pointer */
+               p += LCD_UKEY_CTRL_FLAG;
+               p += LCD_UKEY_CTRL_ATTR_0;
+               p += LCD_UKEY_CTRL_ATTR_1;
+               p += LCD_UKEY_CTRL_ATTR_2;
+               p += LCD_UKEY_CTRL_ATTR_3;
+               p += LCD_UKEY_CTRL_ATTR_4;
+               p += LCD_UKEY_CTRL_ATTR_5;
+               p += LCD_UKEY_CTRL_ATTR_6;
+               p += LCD_UKEY_CTRL_ATTR_7;
+               p += LCD_UKEY_CTRL_ATTR_8;
+               p += LCD_UKEY_CTRL_ATTR_9;
+               p += LCD_UKEY_CTRL_ATTR_10;
+               p += LCD_UKEY_CTRL_ATTR_11;
+               p += LCD_UKEY_CTRL_ATTR_12;
+               p += LCD_UKEY_CTRL_ATTR_13;
+               p += LCD_UKEY_CTRL_ATTR_14;
+               p += LCD_UKEY_CTRL_ATTR_15;
+               p += LCD_UKEY_CTRL_ATTR_16;
+               p += LCD_UKEY_CTRL_ATTR_17;
+               p += LCD_UKEY_CTRL_ATTR_18;
+               p += LCD_UKEY_CTRL_ATTR_19;
+
+               /* phy: 10byte */ /* v2 */
+               if (pconf->lcd_basic.lcd_type == LCD_LVDS) {
+                       pconf->lcd_control.lvds_config->phy_vswing = *p;
+                       p += LCD_UKEY_PHY_ATTR_0;
+                       pconf->lcd_control.lvds_config->phy_preem = *p;
+                       p += LCD_UKEY_PHY_ATTR_1;
+                       pconf->lcd_control.lvds_config->phy_clk_vswing = *p;
+                       p += LCD_UKEY_PHY_ATTR_2;
+                       pconf->lcd_control.lvds_config->phy_clk_preem = *p;
+                       p += LCD_UKEY_PHY_ATTR_3;
+                       /* dummy pointer */
+                       p += LCD_UKEY_PHY_ATTR_4;
+                       p += LCD_UKEY_PHY_ATTR_5;
+                       p += LCD_UKEY_PHY_ATTR_6;
+                       p += LCD_UKEY_PHY_ATTR_7;
+                       p += LCD_UKEY_PHY_ATTR_8;
+                       p += LCD_UKEY_PHY_ATTR_9;
+               } else if (pconf->lcd_basic.lcd_type == LCD_VBYONE) {
+                       pconf->lcd_control.vbyone_config->phy_vswing =
+                                       (*p | ((*(p + 1)) << 8)) & 0xff;
+                       p += LCD_UKEY_PHY_ATTR_0;
+                       pconf->lcd_control.vbyone_config->phy_preem =
+                                       (*p | ((*(p + 1)) << 8)) & 0xff;
+                       p += LCD_UKEY_PHY_ATTR_1;
+                       /* dummy pointer */
+                       p += LCD_UKEY_PHY_ATTR_2;
+                       p += LCD_UKEY_PHY_ATTR_3;
+                       p += LCD_UKEY_PHY_ATTR_4;
+                       p += LCD_UKEY_PHY_ATTR_5;
+                       p += LCD_UKEY_PHY_ATTR_6;
+                       p += LCD_UKEY_PHY_ATTR_7;
+                       p += LCD_UKEY_PHY_ATTR_8;
+                       p += LCD_UKEY_PHY_ATTR_9;
+               } else {
+                       p += LCD_UKEY_PHY_ATTR_0;
+                       p += LCD_UKEY_PHY_ATTR_1;
+                       p += LCD_UKEY_PHY_ATTR_2;
+                       p += LCD_UKEY_PHY_ATTR_3;
+                       p += LCD_UKEY_PHY_ATTR_4;
+                       p += LCD_UKEY_PHY_ATTR_5;
+                       p += LCD_UKEY_PHY_ATTR_6;
+                       p += LCD_UKEY_PHY_ATTR_7;
+                       p += LCD_UKEY_PHY_ATTR_8;
+                       p += LCD_UKEY_PHY_ATTR_9;
+               }
+       }
+
        /* step 3: check power sequence */
        ret = lcd_power_load_from_unifykey(pconf, para, key_len, len);
        if (ret < 0) {
index a2ec892..9a33c53 100644 (file)
@@ -244,8 +244,6 @@ static void lcd_lvds_control_set(struct lcd_config_s *pconf)
        switch (pconf->lcd_basic.lcd_bits) {
        case 10:
                bit_num = 0;
-               if (lvds_repack == 1)
-                       lvds_repack = 2;
                break;
        case 8:
                bit_num = 1;
@@ -321,8 +319,8 @@ static void lcd_vbyone_clk_util_set(struct lcd_config_s *pconf)
        unsigned int div_sel, phy_div;
 
        phy_div = pconf->lcd_control.vbyone_config->phy_div;
+       lcd_bits = pconf->lcd_basic.lcd_bits;
 
-       lcd_bits = 10;
        switch (lcd_bits) {
        case 6:
                div_sel = 0;
@@ -1047,7 +1045,6 @@ static void lcd_vbyone_config_set(struct lcd_config_s *pconf)
 {
        unsigned int band_width, bit_rate, pclk, phy_div;
        unsigned int byte_mode, lane_count, minlane;
-       unsigned int lcd_bits;
        unsigned int temp, i;
 
        if (lcd_debug_print_flag)
@@ -1055,8 +1052,7 @@ static void lcd_vbyone_config_set(struct lcd_config_s *pconf)
 
        /* auto calculate bandwidth, clock */
        lane_count = pconf->lcd_control.vbyone_config->lane_count;
-       lcd_bits = 10; /* pconf->lcd_basic.lcd_bits */
-       byte_mode = (lcd_bits == 10) ? 4 : 3;
+       byte_mode = pconf->lcd_control.vbyone_config->byte_mode;
        /* byte_mode * byte2bit * 8/10_encoding * pclk =
         * byte_mode * 8 * 10 / 8 * pclk
         */
index 0076c3f..383e70a 100644 (file)
 static unsigned int lcd_output_vmode;
 static char lcd_output_name[30];
 
-/* lcd mode function */
+/* ************************************************** *
+ * lcd mode function
+ * **************************************************
+ */
 static unsigned int lcd_std_frame_rate[] = {
        50,
        60,
@@ -225,7 +228,10 @@ static void lcd_vmode_vinfo_update(enum vmode_e mode)
        lcd_hdr_vinfo_update();
 }
 
-/*  vout server api */
+/* ************************************************** *
+ * vout server api
+ * **************************************************
+ */
 static enum vmode_e lcd_validate_vmode(char *mode)
 {
        int lcd_vmode, frame_rate;
@@ -352,6 +358,8 @@ static int lcd_framerate_automation_set_mode(void)
 {
        struct aml_lcd_drv_s *lcd_drv = aml_lcd_get_driver();
 
+       LCDPR("%s\n", __func__);
+
        /* update interface timing */
        lcd_tv_config_update(lcd_drv->lcd_config);
 #ifdef CONFIG_AML_VPU
@@ -519,13 +527,32 @@ static int lcd_suspend(void)
 
 static int lcd_resume(void)
 {
-       mutex_lock(&lcd_power_mutex);
-       if (lcd_resume_flag == 0) {
+       struct aml_lcd_drv_s *lcd_drv = aml_lcd_get_driver();
+
+       if (lcd_resume_flag)
+               return 0;
+
+       if (lcd_drv->lcd_resume_flag) {
+               if (lcd_drv->workqueue) {
+                       queue_work(lcd_drv->workqueue,
+                               &(lcd_drv->lcd_resume_work));
+               } else {
+                       LCDPR("Warning: no lcd workqueue\n");
+                       mutex_lock(&lcd_power_mutex);
+                       lcd_resume_flag = 1;
+                       aml_lcd_notifier_call_chain(LCD_EVENT_POWER_ON, NULL);
+                       LCDPR("%s finished\n", __func__);
+                       mutex_unlock(&lcd_power_mutex);
+               }
+       } else {
+               LCDPR("directly lcd late resume\n");
+               mutex_lock(&lcd_power_mutex);
                lcd_resume_flag = 1;
                aml_lcd_notifier_call_chain(LCD_EVENT_POWER_ON, NULL);
                LCDPR("%s finished\n", __func__);
+               mutex_unlock(&lcd_power_mutex);
        }
-       mutex_unlock(&lcd_power_mutex);
+
        return 0;
 }
 
@@ -592,7 +619,10 @@ void lcd_tv_vout_server_init(void)
        vout_register_server(&lcd_vout_server);
 }
 
-/* lcd tv config */
+/* ************************************************** *
+ * lcd tv config
+ * **************************************************
+ */
 static void lcd_config_print(struct lcd_config_s *pconf)
 {
        LCDPR("%s, %s, %dbit, %dx%d\n",
@@ -686,10 +716,13 @@ static int lcd_config_load_from_dts(struct lcd_config_s *pconf,
        ret = of_property_read_string(child, "model_name", &str);
        if (ret) {
                LCDERR("failed to get model_name\n");
-               strcpy(pconf->lcd_basic.model_name, pconf->lcd_propname);
+               strncpy(pconf->lcd_basic.model_name, pconf->lcd_propname,
+                       MOD_LEN_MAX);
        } else {
-               strcpy(pconf->lcd_basic.model_name, str);
+               strncpy(pconf->lcd_basic.model_name, str, MOD_LEN_MAX);
        }
+       /* ensure string ending */
+       pconf->lcd_basic.model_name[MOD_LEN_MAX-1] = '\0';
 
        ret = of_property_read_string(child, "interface", &str);
        if (ret) {
@@ -863,6 +896,8 @@ static int lcd_config_load_from_unifykey(struct lcd_config_s *pconf)
        unsigned char *p;
        const char *str;
        struct aml_lcd_unifykey_header_s lcd_header;
+       struct lvds_config_s *lvdsconf = pconf->lcd_control.lvds_config;
+       struct vbyone_config_s *vx1_conf = pconf->lcd_control.vbyone_config;
        int ret;
 
        para = kmalloc((sizeof(unsigned char) * LCD_UKEY_LCD_SIZE), GFP_KERNEL);
@@ -888,12 +923,19 @@ static int lcd_config_load_from_unifykey(struct lcd_config_s *pconf)
        }
 
        lcd_unifykey_header_check(para, &lcd_header);
-       len = 10 + 36 + 18 + 31 + 20;
+       LCDPR("unifykey version: 0x%04x\n", lcd_header.version);
+       switch (lcd_header.version) {
+       case 2:
+               len = 10 + 36 + 18 + 31 + 20 + 44 + 10;
+               break;
+       default:
+               len = 10 + 36 + 18 + 31 + 20;
+               break;
+       }
        if (lcd_debug_print_flag) {
                LCDPR("unifykey header:\n");
                LCDPR("crc32             = 0x%08x\n", lcd_header.crc32);
                LCDPR("data_len          = %d\n", lcd_header.data_len);
-               LCDPR("version           = 0x%04x\n", lcd_header.version);
                LCDPR("reserved          = 0x%04x\n", lcd_header.reserved);
        }
 
@@ -905,11 +947,15 @@ static int lcd_config_load_from_unifykey(struct lcd_config_s *pconf)
                return -1;
        }
 
+       /* panel_type update */
+       sprintf(pconf->lcd_propname, "%s", "unifykey");
+
        /* basic: 36byte */
        p = para + LCD_UKEY_HEAD_SIZE;
-       *(p + LCD_UKEY_MODEL_NAME - 1) = '\0'; /* ensure string ending */
        str = (const char *)p;
-       strcpy(pconf->lcd_basic.model_name, str);
+       strncpy(pconf->lcd_basic.model_name, str, MOD_LEN_MAX);
+       /* ensure string ending */
+       pconf->lcd_basic.model_name[MOD_LEN_MAX-1] = '\0';
        p += LCD_UKEY_MODEL_NAME;
        pconf->lcd_basic.lcd_type = *p;
        p += LCD_UKEY_INTERFACE;
@@ -971,95 +1017,91 @@ static int lcd_config_load_from_unifykey(struct lcd_config_s *pconf)
 
        /* interface: 20byte */
        if (pconf->lcd_basic.lcd_type == LCD_VBYONE) {
-               pconf->lcd_control.vbyone_config->lane_count =
-                               (*p | ((*(p + 1)) << 8)) & 0xff;
-               p += LCD_UKEY_IF_ATTR_0;
-               pconf->lcd_control.vbyone_config->region_num =
-                               (*p | ((*(p + 1)) << 8)) & 0xff;
-               p += LCD_UKEY_IF_ATTR_1;
-               pconf->lcd_control.vbyone_config->byte_mode  =
-                               (*p | ((*(p + 1)) << 8)) & 0xff;
-               p += LCD_UKEY_IF_ATTR_2;
-               pconf->lcd_control.vbyone_config->color_fmt  =
-                               (*p | ((*(p + 1)) << 8)) & 0xff;
-               p += LCD_UKEY_IF_ATTR_3;
-               pconf->lcd_control.vbyone_config->phy_vswing =
-                               (*p | ((*(p + 1)) << 8)) & 0xff;
-               p += LCD_UKEY_IF_ATTR_4;
-               pconf->lcd_control.vbyone_config->phy_preem =
-                               (*p | ((*(p + 1)) << 8)) & 0xff;
-               p += LCD_UKEY_IF_ATTR_5;
-               pconf->lcd_control.vbyone_config->intr_en =
-                               (*p | ((*(p + 1)) << 8)) & 0xff;
-               p += LCD_UKEY_IF_ATTR_6;
-               pconf->lcd_control.vbyone_config->vsync_intr_en =
-                               (*p | ((*(p + 1)) << 8)) & 0xff;
-               p += LCD_UKEY_IF_ATTR_7;
-               /* dummy pointer */
-               p += LCD_UKEY_IF_ATTR_8;
-               p += LCD_UKEY_IF_ATTR_9;
-       } else if (pconf->lcd_basic.lcd_type == LCD_LVDS) {
-               if (lcd_header.version == 1) {
-                       pconf->lcd_control.lvds_config->lvds_repack =
-                                       (*p | ((*(p + 1)) << 8)) & 0xff;
+               if (lcd_header.version == 2) {
+                       vx1_conf->lane_count = (*p | ((*(p + 1)) << 8)) & 0xff;
                        p += LCD_UKEY_IF_ATTR_0;
-                       pconf->lcd_control.lvds_config->dual_port =
-                                       (*p | ((*(p + 1)) << 8)) & 0xff;
+                       vx1_conf->region_num = (*p | ((*(p + 1)) << 8)) & 0xff;
                        p += LCD_UKEY_IF_ATTR_1;
-                       pconf->lcd_control.lvds_config->pn_swap  =
-                                       (*p | ((*(p + 1)) << 8)) & 0xff;
+                       vx1_conf->byte_mode = (*p | ((*(p + 1)) << 8)) & 0xff;
                        p += LCD_UKEY_IF_ATTR_2;
-                       pconf->lcd_control.lvds_config->port_swap  =
-                                       (*p | ((*(p + 1)) << 8)) & 0xff;
+                       vx1_conf->color_fmt = (*p | ((*(p + 1)) << 8)) & 0xff;
                        p += LCD_UKEY_IF_ATTR_3;
-                       pconf->lcd_control.lvds_config->phy_vswing =
-                                       (*p | ((*(p + 1)) << 8)) & 0xff;
+                       vx1_conf->intr_en = (*p | ((*(p + 1)) << 8)) & 0xff;
                        p += LCD_UKEY_IF_ATTR_4;
-                       pconf->lcd_control.lvds_config->phy_preem =
+                       vx1_conf->vsync_intr_en =
                                        (*p | ((*(p + 1)) << 8)) & 0xff;
                        p += LCD_UKEY_IF_ATTR_5;
-                       pconf->lcd_control.lvds_config->phy_clk_vswing =
-                                       (*p | ((*(p + 1)) << 8)) & 0xff;
+                       /* dummy pointer */
                        p += LCD_UKEY_IF_ATTR_6;
-                       pconf->lcd_control.lvds_config->phy_clk_preem  =
-                                       (*p | ((*(p + 1)) << 8)) & 0xff;
                        p += LCD_UKEY_IF_ATTR_7;
-                       pconf->lcd_control.lvds_config->lane_reverse = 0;
                        p += LCD_UKEY_IF_ATTR_8;
-                       /* dummy pointer */
                        p += LCD_UKEY_IF_ATTR_9;
-                       }
-               else if (lcd_header.version == 2) {
-                       pconf->lcd_control.lvds_config->lvds_repack =
-                                       (*p | ((*(p + 1)) << 8)) & 0xff;
+               } else {
+                       vx1_conf->lane_count = (*p | ((*(p + 1)) << 8)) & 0xff;
                        p += LCD_UKEY_IF_ATTR_0;
-                       pconf->lcd_control.lvds_config->dual_port =
-                                       (*p | ((*(p + 1)) << 8)) & 0xff;
+                       vx1_conf->region_num = (*p | ((*(p + 1)) << 8)) & 0xff;
                        p += LCD_UKEY_IF_ATTR_1;
-                       pconf->lcd_control.lvds_config->pn_swap  =
-                                       (*p | ((*(p + 1)) << 8)) & 0xff;
+                       vx1_conf->byte_mode = (*p | ((*(p + 1)) << 8)) & 0xff;
                        p += LCD_UKEY_IF_ATTR_2;
-                       pconf->lcd_control.lvds_config->port_swap  =
+                       vx1_conf->color_fmt = (*p | ((*(p + 1)) << 8)) & 0xff;
+                       p += LCD_UKEY_IF_ATTR_3;
+                       vx1_conf->phy_vswing = (*p | ((*(p + 1)) << 8)) & 0xff;
+                       p += LCD_UKEY_IF_ATTR_4;
+                       vx1_conf->phy_preem = (*p | ((*(p + 1)) << 8)) & 0xff;
+                       p += LCD_UKEY_IF_ATTR_5;
+                       vx1_conf->intr_en = (*p | ((*(p + 1)) << 8)) & 0xff;
+                       p += LCD_UKEY_IF_ATTR_6;
+                       vx1_conf->vsync_intr_en =
                                        (*p | ((*(p + 1)) << 8)) & 0xff;
+                       p += LCD_UKEY_IF_ATTR_7;
+                       /* dummy pointer */
+                       p += LCD_UKEY_IF_ATTR_8;
+                       p += LCD_UKEY_IF_ATTR_9;
+               }
+       } else if (pconf->lcd_basic.lcd_type == LCD_LVDS) {
+               if (lcd_header.version == 2) {
+                       lvdsconf->lvds_repack = (*p | ((*(p + 1)) << 8)) & 0xff;
+                       p += LCD_UKEY_IF_ATTR_0;
+                       lvdsconf->dual_port = (*p | ((*(p + 1)) << 8)) & 0xff;
+                       p += LCD_UKEY_IF_ATTR_1;
+                       lvdsconf->pn_swap = (*p | ((*(p + 1)) << 8)) & 0xff;
+                       p += LCD_UKEY_IF_ATTR_2;
+                       lvdsconf->port_swap = (*p | ((*(p + 1)) << 8)) & 0xff;
                        p += LCD_UKEY_IF_ATTR_3;
-                       pconf->lcd_control.lvds_config->lane_reverse  =
+                       lvdsconf->lane_reverse =
                                        (*p | ((*(p + 1)) << 8)) & 0xff;
                        p += LCD_UKEY_IF_ATTR_4;
-                       pconf->lcd_control.lvds_config->phy_vswing =
-                                       (*p | ((*(p + 1)) << 8)) & 0xff;
+                       /* dummy pointer */
                        p += LCD_UKEY_IF_ATTR_5;
-                       pconf->lcd_control.lvds_config->phy_preem =
+                       p += LCD_UKEY_IF_ATTR_6;
+                       p += LCD_UKEY_IF_ATTR_7;
+                       p += LCD_UKEY_IF_ATTR_8;
+                       p += LCD_UKEY_IF_ATTR_9;
+               } else {
+                       lvdsconf->lvds_repack = (*p | ((*(p + 1)) << 8)) & 0xff;
+                       p += LCD_UKEY_IF_ATTR_0;
+                       lvdsconf->dual_port = (*p | ((*(p + 1)) << 8)) & 0xff;
+                       p += LCD_UKEY_IF_ATTR_1;
+                       lvdsconf->pn_swap = (*p | ((*(p + 1)) << 8)) & 0xff;
+                       p += LCD_UKEY_IF_ATTR_2;
+                       lvdsconf->port_swap = (*p | ((*(p + 1)) << 8)) & 0xff;
+                       p += LCD_UKEY_IF_ATTR_3;
+                       lvdsconf->phy_vswing = (*p | ((*(p + 1)) << 8)) & 0xff;
+                       p += LCD_UKEY_IF_ATTR_4;
+                       lvdsconf->phy_preem = (*p | ((*(p + 1)) << 8)) & 0xff;
+                       p += LCD_UKEY_IF_ATTR_5;
+                       lvdsconf->phy_clk_vswing =
                                        (*p | ((*(p + 1)) << 8)) & 0xff;
                        p += LCD_UKEY_IF_ATTR_6;
-                       pconf->lcd_control.lvds_config->phy_clk_vswing =
+                       lvdsconf->phy_clk_preem =
                                        (*p | ((*(p + 1)) << 8)) & 0xff;
                        p += LCD_UKEY_IF_ATTR_7;
-                       pconf->lcd_control.lvds_config->phy_clk_preem  =
-                                       (*p | ((*(p + 1)) << 8)) & 0xff;
-                       p += LCD_UKEY_IF_ATTR_8;
                        /* dummy pointer */
+                       p += LCD_UKEY_IF_ATTR_8;
                        p += LCD_UKEY_IF_ATTR_9;
-                       }
+
+                       lvdsconf->lane_reverse = 0;
+               }
        } else {
                LCDERR("unsupport lcd_type: %d\n", pconf->lcd_basic.lcd_type);
                p += LCD_UKEY_IF_ATTR_0;
@@ -1074,6 +1116,75 @@ static int lcd_config_load_from_unifykey(struct lcd_config_s *pconf)
                p += LCD_UKEY_IF_ATTR_9;
        }
 
+       if (lcd_header.version == 2) {
+               /* ctrl: 44byte */ /* v2 */
+               p += LCD_UKEY_CTRL_FLAG;
+               p += LCD_UKEY_CTRL_ATTR_0;
+               p += LCD_UKEY_CTRL_ATTR_1;
+               p += LCD_UKEY_CTRL_ATTR_2;
+               p += LCD_UKEY_CTRL_ATTR_3;
+               p += LCD_UKEY_CTRL_ATTR_4;
+               p += LCD_UKEY_CTRL_ATTR_5;
+               p += LCD_UKEY_CTRL_ATTR_6;
+               p += LCD_UKEY_CTRL_ATTR_7;
+               p += LCD_UKEY_CTRL_ATTR_8;
+               p += LCD_UKEY_CTRL_ATTR_9;
+               p += LCD_UKEY_CTRL_ATTR_10;
+               p += LCD_UKEY_CTRL_ATTR_11;
+               p += LCD_UKEY_CTRL_ATTR_12;
+               p += LCD_UKEY_CTRL_ATTR_13;
+               p += LCD_UKEY_CTRL_ATTR_14;
+               p += LCD_UKEY_CTRL_ATTR_15;
+               p += LCD_UKEY_CTRL_ATTR_16;
+               p += LCD_UKEY_CTRL_ATTR_17;
+               p += LCD_UKEY_CTRL_ATTR_18;
+               p += LCD_UKEY_CTRL_ATTR_19;
+
+               /* phy: 10byte */ /* v2 */
+               if (pconf->lcd_basic.lcd_type == LCD_VBYONE) {
+                       vx1_conf->phy_vswing = *p;
+                       p += LCD_UKEY_PHY_ATTR_0;
+                       vx1_conf->phy_preem = *p;
+                       p += LCD_UKEY_PHY_ATTR_1;
+                       /* dummy pointer */
+                       p += LCD_UKEY_PHY_ATTR_2;
+                       p += LCD_UKEY_PHY_ATTR_3;
+                       p += LCD_UKEY_PHY_ATTR_4;
+                       p += LCD_UKEY_PHY_ATTR_5;
+                       p += LCD_UKEY_PHY_ATTR_6;
+                       p += LCD_UKEY_PHY_ATTR_7;
+                       p += LCD_UKEY_PHY_ATTR_8;
+                       p += LCD_UKEY_PHY_ATTR_9;
+               } else if (pconf->lcd_basic.lcd_type == LCD_LVDS) {
+                       lvdsconf->phy_vswing = *p;
+                       p += LCD_UKEY_PHY_ATTR_0;
+                       lvdsconf->phy_preem = *p;
+                       p += LCD_UKEY_PHY_ATTR_1;
+                       lvdsconf->phy_clk_vswing = *p;
+                       p += LCD_UKEY_PHY_ATTR_2;
+                       lvdsconf->phy_clk_preem = *p;
+                       p += LCD_UKEY_PHY_ATTR_3;
+                       /* dummy pointer */
+                       p += LCD_UKEY_PHY_ATTR_4;
+                       p += LCD_UKEY_PHY_ATTR_5;
+                       p += LCD_UKEY_PHY_ATTR_6;
+                       p += LCD_UKEY_PHY_ATTR_7;
+                       p += LCD_UKEY_PHY_ATTR_8;
+                       p += LCD_UKEY_PHY_ATTR_9;
+               } else {
+                       p += LCD_UKEY_PHY_ATTR_0;
+                       p += LCD_UKEY_PHY_ATTR_1;
+                       p += LCD_UKEY_PHY_ATTR_2;
+                       p += LCD_UKEY_PHY_ATTR_3;
+                       p += LCD_UKEY_PHY_ATTR_4;
+                       p += LCD_UKEY_PHY_ATTR_5;
+                       p += LCD_UKEY_PHY_ATTR_6;
+                       p += LCD_UKEY_PHY_ATTR_7;
+                       p += LCD_UKEY_PHY_ATTR_8;
+                       p += LCD_UKEY_PHY_ATTR_9;
+               }
+       }
+
        /* step 3: check power sequence */
        ret = lcd_power_load_from_unifykey(pconf, para, key_len, len);
        if (ret < 0) {
@@ -1098,7 +1209,6 @@ static void lcd_vmode_init(struct lcd_config_s *pconf)
                vmode = VMODE_LCD;
        }
        lcd_vmode_vinfo_update(vmode & VMODE_MODE_BIT_MASK);
-       lcd_tv_config_update(pconf);
 }
 
 static void lcd_config_init(struct lcd_config_s *pconf)
@@ -1116,6 +1226,7 @@ static void lcd_config_init(struct lcd_config_s *pconf)
 
        lcd_vmode_init(pconf);
 
+       lcd_tv_config_update(pconf);
        lcd_clk_generate_parameter(pconf);
        ss_level = pconf->lcd_timing.ss_level;
        cconf->ss_level = (ss_level >= cconf->ss_level_max) ? 0 : ss_level;
@@ -1157,7 +1268,10 @@ static int lcd_get_config(struct lcd_config_s *pconf, struct device *dev)
        return 0;
 }
 
-/*  lcd notify */
+/* ************************************************** *
+ * lcd notify
+ * **************************************************
+ */
 /* sync_duration is real_value * 100 */
 static void lcd_set_vinfo(unsigned int sync_duration)
 {
@@ -1217,7 +1331,10 @@ static struct notifier_block lcd_frame_rate_adjust_nb = {
        .notifier_call = lcd_frame_rate_adjust_notifier,
 };
 
-/*  lcd tv */
+/* ************************************************** *
+ * lcd tv
+ * **************************************************
+ */
 int lcd_tv_probe(struct device *dev)
 {
        struct aml_lcd_drv_s *lcd_drv = aml_lcd_get_driver();
index 758f460..967612f 100644 (file)
@@ -57,7 +57,7 @@ struct mutex lcd_power_mutex;
 struct mutex lcd_vout_mutex;
 int lcd_vout_serve_bypass;
 
-static char lcd_propname[20] = "lvds_0";
+static char lcd_propname[20] = "null";
 
 struct lcd_cdev_s {
        dev_t           devno;
@@ -67,7 +67,10 @@ struct lcd_cdev_s {
 
 static struct lcd_cdev_s *lcd_cdev;
 
-/* lcd config define */
+/* *********************************************************
+ * lcd config define
+ * *********************************************************
+ */
 static struct ttl_config_s lcd_ttl_config = {
        .clk_pol = 0,
        .sync_valid = ((1 << 1) | (1 << 0)),
@@ -179,6 +182,7 @@ static struct lcd_config_s lcd_config_dft = {
                .mipi_config = &lcd_mipi_config,
        },
        .lcd_power = &lcd_power_config,
+       .pinmux_flag = 0,
 };
 
 static struct vinfo_s lcd_vinfo = {
@@ -416,19 +420,32 @@ static void lcd_module_tiny_reset(void)
        mutex_unlock(&lcd_vout_mutex);
 }
 
-/* lcd notify */
+static void lcd_resume_work(struct work_struct *p_work)
+{
+       mutex_lock(&lcd_power_mutex);
+       aml_lcd_notifier_call_chain(LCD_EVENT_POWER_ON, NULL);
+       LCDPR("%s finished\n", __func__);
+       mutex_unlock(&lcd_power_mutex);
+}
+
+/* ****************************************
+ * lcd notify
+ * ****************************************
+ */
 static int lcd_power_notifier(struct notifier_block *nb,
                unsigned long event, void *data)
 {
-       if (lcd_debug_print_flag)
-               LCDPR("%s: 0x%lx\n", __func__, event);
-
-       if (event & LCD_EVENT_LCD_ON)
+       if (event & LCD_EVENT_LCD_ON) {
+               if (lcd_debug_print_flag)
+                       LCDPR("%s: 0x%lx\n", __func__, event);
                lcd_module_enable();
-       else if (event & LCD_EVENT_LCD_OFF)
+       } else if (event & LCD_EVENT_LCD_OFF) {
+               if (lcd_debug_print_flag)
+                       LCDPR("%s: 0x%lx\n", __func__, event);
                lcd_module_disable();
-       else
+       } else {
                return NOTIFY_DONE;
+       }
 
        return NOTIFY_OK;
 }
@@ -441,15 +458,17 @@ static struct notifier_block lcd_power_nb = {
 static int lcd_interface_notifier(struct notifier_block *nb,
                unsigned long event, void *data)
 {
-       if (lcd_debug_print_flag)
-               LCDPR("%s: 0x%lx\n", __func__, event);
-
-       if (event & LCD_EVENT_IF_ON)
+       if (event & LCD_EVENT_IF_ON) {
+               if (lcd_debug_print_flag)
+                       LCDPR("%s: 0x%lx\n", __func__, event);
                lcd_driver->power_tiny_ctrl(1);
-       else if (event & LCD_EVENT_IF_OFF)
+       } else if (event & LCD_EVENT_IF_OFF) {
+               if (lcd_debug_print_flag)
+                       LCDPR("%s: 0x%lx\n", __func__, event);
                lcd_driver->power_tiny_ctrl(0);
-       else
+       } else {
                return NOTIFY_DONE;
+       }
 
        return NOTIFY_OK;
 }
@@ -464,9 +483,9 @@ static int lcd_bl_select_notifier(struct notifier_block *nb,
 {
        unsigned int *index;
 
-       /* LCDPR("%s: 0x%lx\n", __func__, event); */
        if ((event & LCD_EVENT_BACKLIGHT_SEL) == 0)
                return NOTIFY_DONE;
+       /* LCDPR("%s: 0x%lx\n", __func__, event); */
 
        index = (unsigned int *)data;
        *index = lcd_driver->lcd_config->backlight_index;
@@ -802,8 +821,8 @@ static int lcd_config_probe(void)
 
        lcd_driver->lcd_info = &lcd_vinfo;
        lcd_driver->lcd_config = &lcd_config_dft;
-       lcd_driver->lcd_config->pinmux_flag = 0;
        lcd_driver->lcd_test_flag = 0;
+       lcd_driver->lcd_resume_flag = 1; /* default workqueue */
        lcd_driver->power_ctrl = lcd_power_ctrl;
        lcd_driver->module_reset = lcd_module_reset;
        lcd_driver->power_tiny_ctrl = lcd_power_tiny_ctrl;
@@ -837,15 +856,6 @@ static int lcd_config_probe(void)
        return 0;
 }
 
-static void lcd_resume_work(struct work_struct *p_work)
-{
-       mutex_lock(&lcd_power_mutex);
-       lcd_resume_flag = 1;
-       aml_lcd_notifier_call_chain(LCD_EVENT_POWER_ON, NULL);
-       LCDPR("%s finished\n", __func__);
-       mutex_unlock(&lcd_power_mutex);
-}
-
 static int lcd_probe(struct platform_device *pdev)
 {
        int ret = 0;
@@ -915,7 +925,26 @@ static int lcd_remove(struct platform_device *pdev)
 
 static int lcd_resume(struct platform_device *pdev)
 {
-       queue_work(lcd_driver->workqueue, &(lcd_driver->lcd_resume_work));
+       if (lcd_driver->lcd_resume_flag) {
+               lcd_resume_flag = 1;
+               if (lcd_driver->workqueue) {
+                       queue_work(lcd_driver->workqueue,
+                               &(lcd_driver->lcd_resume_work));
+               } else {
+                       LCDPR("Warning: no lcd workqueue\n");
+                       mutex_lock(&lcd_power_mutex);
+                       aml_lcd_notifier_call_chain(LCD_EVENT_POWER_ON, NULL);
+                       LCDPR("%s finished\n", __func__);
+                       mutex_unlock(&lcd_power_mutex);
+               }
+       } else {
+               LCDPR("directly lcd resume\n");
+               mutex_lock(&lcd_power_mutex);
+               lcd_resume_flag = 1;
+               aml_lcd_notifier_call_chain(LCD_EVENT_POWER_ON, NULL);
+               LCDPR("%s finished\n", __func__);
+               mutex_unlock(&lcd_power_mutex);
+       }
 
        return 0;
 }
index 6413024..9dccb3e 100644 (file)
@@ -51,8 +51,13 @@ struct aml_lcd_unifykey_header_s {
        unsigned short reserved;
 };
 
-/*  lcd */
-#define LCD_UKEY_LCD_SIZE          265
+/* ********************************
+ * lcd
+ * *********************************
+ */
+/* V1: 265 */
+/* V2: 319 */
+#define LCD_UKEY_LCD_SIZE          319
 
 /* header (10Byte) */
 /* LCD_UKEY_HEAD_SIZE */
@@ -97,13 +102,49 @@ struct aml_lcd_unifykey_header_s {
 #define LCD_UKEY_IF_ATTR_7         2
 #define LCD_UKEY_IF_ATTR_8         2
 #define LCD_UKEY_IF_ATTR_9         2
+/* ctrl (44Byte) */ /* V2 */
+#define LCD_UKEY_CTRL_FLAG         4
+#define LCD_UKEY_CTRL_ATTR_0       2
+#define LCD_UKEY_CTRL_ATTR_1       2
+#define LCD_UKEY_CTRL_ATTR_2       2
+#define LCD_UKEY_CTRL_ATTR_3       2
+#define LCD_UKEY_CTRL_ATTR_4       2
+#define LCD_UKEY_CTRL_ATTR_5       2
+#define LCD_UKEY_CTRL_ATTR_6       2
+#define LCD_UKEY_CTRL_ATTR_7       2
+#define LCD_UKEY_CTRL_ATTR_8       2
+#define LCD_UKEY_CTRL_ATTR_9       2
+#define LCD_UKEY_CTRL_ATTR_10      2
+#define LCD_UKEY_CTRL_ATTR_11      2
+#define LCD_UKEY_CTRL_ATTR_12      2
+#define LCD_UKEY_CTRL_ATTR_13      2
+#define LCD_UKEY_CTRL_ATTR_14      2
+#define LCD_UKEY_CTRL_ATTR_15      2
+#define LCD_UKEY_CTRL_ATTR_16      2
+#define LCD_UKEY_CTRL_ATTR_17      2
+#define LCD_UKEY_CTRL_ATTR_18      2
+#define LCD_UKEY_CTRL_ATTR_19      2
+/* phy (10Byte) */ /* V2 */
+#define LCD_UKEY_PHY_ATTR_0        1
+#define LCD_UKEY_PHY_ATTR_1        1
+#define LCD_UKEY_PHY_ATTR_2        1
+#define LCD_UKEY_PHY_ATTR_3        1
+#define LCD_UKEY_PHY_ATTR_4        1
+#define LCD_UKEY_PHY_ATTR_5        1
+#define LCD_UKEY_PHY_ATTR_6        1
+#define LCD_UKEY_PHY_ATTR_7        1
+#define LCD_UKEY_PHY_ATTR_8        1
+#define LCD_UKEY_PHY_ATTR_9        1
 /* power (5Byte * n) */
 #define LCD_UKEY_PWR_TYPE          1
 #define LCD_UKEY_PWR_INDEX         1
 #define LCD_UKEY_PWR_VAL           1
 #define LCD_UKEY_PWR_DELAY         2
 
-/* lcd extern */
+/* ********************************
+ * lcd extern
+ * *********************************
+ */
 #define LCD_UKEY_LCD_EXT_SIZE       550
 
 /* header (10Byte) */
@@ -129,8 +170,13 @@ struct aml_lcd_unifykey_header_s {
 /*#define LCD_UKEY_EXT_INIT_VAL        1   //not defined */
 #define LCD_UKEY_EXT_INIT_DELAY      1
 
-/* backlight */
-#define LCD_UKEY_BL_SIZE            92
+/* ********************************
+ * backlight
+ * *********************************
+ */
+/* V1: 92 */
+/* V2: 102 */
+#define LCD_UKEY_BL_SIZE            102
 
 /* header (10Byte) */
 /* LCD_UKEY_HEAD_SIZE */
@@ -171,9 +217,17 @@ struct aml_lcd_unifykey_header_s {
 #define LCD_UKEY_BL_PWM_LEVEL_MIN   2
 #define LCD_UKEY_BL_PWM2_LEVEL_MAX  2
 #define LCD_UKEY_BL_PWM2_LEVEL_MIN  2
-
-
-/* API */
+/* customer(10Byte) */ /* V2 */
+#define LCD_UKEY_BL_CUST_VAL_0      2
+#define LCD_UKEY_BL_CUST_VAL_1      2
+#define LCD_UKEY_BL_CUST_VAL_2      2
+#define LCD_UKEY_BL_CUST_VAL_3      2
+#define LCD_UKEY_BL_CUST_VAL_4      2
+
+/* ********************************
+ * API
+ * *********************************
+ */
 extern int lcd_unifykey_len_check(int key_len, int len);
 extern int lcd_unifykey_check(char *key_name);
 extern int lcd_unifykey_header_check(unsigned char *buf,
index 8f1b086..350b4a9 100644 (file)
 #include <linux/pinctrl/consumer.h>
 #include <linux/amlogic/media/vout/vout_notify.h>
 
-/* debug print define */
+/* **********************************
+ * debug print define
+ * **********************************
+ */
 /* #define LCD_DEBUG_INFO */
 extern unsigned char lcd_debug_print_flag;
 #define LCDPR(fmt, args...)     pr_info("lcd: "fmt"", ## args)
 #define LCDERR(fmt, args...)    pr_err("lcd: error: "fmt"", ## args)
 
-/* clk parameter bit define */
-/* pll_ctrl, div_ctrl, clk_ctrl */
-
+/* **********************************
+ * clk parameter bit define
+ * pll_ctrl, div_ctrl, clk_ctrl
+ * **********************************
+ */
 /* ******** pll_ctrl ******** */
 #define PLL_CTRL_OD3                20 /* [21:20] */
 #define PLL_CTRL_OD2                18 /* [19:18] */
@@ -51,7 +56,10 @@ extern unsigned char lcd_debug_print_flag;
 #define CLK_CTRL_LEVEL              12 /* [14:12] */
 #define CLK_CTRL_FRAC               0  /* [11:0] */
 
-/* VENC to TCON sync delay */
+/* **********************************
+ * VENC to TCON sync delay
+ * **********************************
+ */
 #define TTL_DELAY                   13
 
 /* ******** AXG ******** */
@@ -73,7 +81,10 @@ extern unsigned char lcd_debug_print_flag;
                                        DSI_LANE_1 | DSI_LANE_2 | DSI_LANE_3)
 
 
-/* global control define */
+/* **********************************
+ * global control define
+ * **********************************
+ */
 enum lcd_mode_e {
        LCD_MODE_TV = 0,
        LCD_MODE_TABLET,
@@ -169,7 +180,10 @@ struct lcd_timing_s {
        unsigned short vs_ve_addr;
 };
 
-/*  HDR info define */
+/* **********************************
+ * HDR info define
+ * **********************************
+ */
 struct lcd_hdr_info_s {
        unsigned int hdr_support;
        unsigned int features;
@@ -270,7 +284,10 @@ struct lcd_control_config_s {
        struct dsi_config_s *mipi_config;
 };
 
-/* power control define */
+/* **********************************
+ * power control define
+ * **********************************
+ */
 enum lcd_power_type_e {
        LCD_POWER_TYPE_CPU = 0,
        LCD_POWER_TYPE_PMU,
@@ -355,6 +372,7 @@ struct aml_lcd_drv_s {
        unsigned char lcd_key_valid;
        unsigned char lcd_config_load;
        unsigned char lcd_test_flag;
+       unsigned char lcd_resume_flag; /* 0=directly, 1=workqueue */
        unsigned char lcd_mute;
 
        struct clk *vencl_top;
@@ -393,7 +411,11 @@ struct aml_lcd_drv_s {
 
 extern struct aml_lcd_drv_s *aml_lcd_get_driver(void);
 
-/*  IOCTL define  */
+
+/* **********************************
+ * IOCTL define
+ * **********************************
+ */
 #define LCD_IOC_TYPE               'C'
 #define LCD_IOC_NR_GET_HDR_INFO    0x0
 #define LCD_IOC_NR_SET_HDR_INFO    0x1