author | Evoke Zhang <evoke.zhang@amlogic.com> | 2020-04-17 05:27:58 (GMT) |
---|---|---|
committer | Shen Liu <shen.liu@amlogic.com> | 2020-05-27 06:07:54 (GMT) |
commit | 7c65aafcec0e1db12eed8c0dbb6cd052f5b8de86 (patch) | |
tree | 360b307344070d8728a304be43fe17cb1933040c | |
parent | 036f8451c0614265d3511965d1867584c3627647 (diff) | |
download | common-7c65aafcec0e1db12eed8c0dbb6cd052f5b8de86.zip common-7c65aafcec0e1db12eed8c0dbb6cd052f5b8de86.tar.gz common-7c65aafcec0e1db12eed8c0dbb6cd052f5b8de86.tar.bz2 |
cvbsout: disable vdac in driver shutdown [1/1]
PD#SWPL-23746
Problem:
vdac is enabled after shutdown
Solution:
disable vdac in driver shutdown
Verify:
ac232
Change-Id: Ia3ad46d17989ad0dde407c3b6a1be73119e73c7b
Signed-off-by: Evoke Zhang <evoke.zhang@amlogic.com>
-rw-r--r-- | drivers/amlogic/media/vout/cvbs/cvbs_out.c | 46 | ||||
-rw-r--r-- | drivers/amlogic/media/vout/cvbs/cvbs_out.h | 8 | ||||
-rw-r--r-- | drivers/amlogic/media/vout/vdac/vdac_dev.c | 105 |
3 files changed, 93 insertions, 66 deletions
diff --git a/drivers/amlogic/media/vout/cvbs/cvbs_out.c b/drivers/amlogic/media/vout/cvbs/cvbs_out.c index d10c56b..63c6ba1 100644 --- a/drivers/amlogic/media/vout/cvbs/cvbs_out.c +++ b/drivers/amlogic/media/vout/cvbs/cvbs_out.c @@ -205,14 +205,16 @@ static unsigned int cvbs_config_vdac(unsigned int value) return gsw_cfg; } -static void cvbs_cntl_output(unsigned int open) +static void cvbs_vdac_output(unsigned int open) { if (open == 0) { /* close */ + cvbs_drv->flag &= ~CVBS_FLAG_EN_VDAC; vdac_enable(0, VDAC_MODULE_CVBS_OUT); } else if (open == 1) { /* open */ vdac_vref_adj(cvbs_drv->cvbs_data->vdac_vref_adj); vdac_gsw_adj(cvbs_drv->cvbs_data->vdac_gsw); vdac_enable(1, VDAC_MODULE_CVBS_OUT); + cvbs_drv->flag |= CVBS_FLAG_EN_VDAC; } cvbs_log_info("%s: %d\n", __func__, open); } @@ -367,14 +369,14 @@ static void cvbs_out_clk_gate_ctrl(int status) } } -static void cvbs_dv_dwork(struct work_struct *work) +static void cvbs_vdac_dwork(struct work_struct *work) { - if (!cvbs_drv->dwork_flag) + if ((cvbs_drv->flag & CVBS_FLAG_EN_ENCI) == 0) return; - cvbs_cntl_output(1); + cvbs_vdac_output(1); } -int cvbs_out_setmode(void) +static int cvbs_out_setmode(void) { int ret; @@ -405,7 +407,7 @@ int cvbs_out_setmode(void) cvbs_out_vpu_power_ctrl(1); cvbs_out_clk_gate_ctrl(1); - cvbs_cntl_output(0); + cvbs_vdac_output(0); cvbs_out_reg_write(VENC_VDAC_SETTING, 0xff); /* Before setting clk for CVBS, disable ENCI to avoid hungup */ cvbs_out_reg_write(ENCI_VIDEO_EN, 0); @@ -418,8 +420,8 @@ int cvbs_out_setmode(void) #ifdef CONFIG_CVBS_PERFORMANCE_COMPATIBILITY_SUPPORT cvbs_performance_enhancement(local_cvbs_mode); #endif - cvbs_drv->dwork_flag = 1; - schedule_delayed_work(&cvbs_drv->dv_dwork, msecs_to_jiffies(1000)); + cvbs_drv->flag |= CVBS_FLAG_EN_ENCI; + schedule_delayed_work(&cvbs_drv->vdac_dwork, msecs_to_jiffies(1000)); mutex_unlock(&setmode_mutex); return 0; } @@ -577,7 +579,8 @@ static int cvbs_set_current_vmode(enum vmode_e mode) if (mode & VMODE_INIT_BIT_MASK) { cvbs_out_vpu_power_ctrl(1); cvbs_out_clk_gate_ctrl(1); - cvbs_cntl_output(1); + cvbs_vdac_output(1); + cvbs_drv->flag = (CVBS_FLAG_EN_ENCI | CVBS_FLAG_EN_VDAC); cvbs_log_info("already display in uboot\n"); return 0; } @@ -602,8 +605,8 @@ static int cvbs_vmode_is_supported(enum vmode_e mode) } static int cvbs_module_disable(enum vmode_e cur_vmod) { - cvbs_drv->dwork_flag = 0; - cvbs_cntl_output(0); + cvbs_drv->flag &= ~CVBS_FLAG_EN_ENCI; + cvbs_vdac_output(0); /*restore full range for encp/encl*/ amvecm_clip_range_limit(0); @@ -637,8 +640,8 @@ static int cvbs_suspend(void) { /* TODO */ /* video_dac_disable(); */ - cvbs_drv->dwork_flag = 0; - cvbs_cntl_output(0); + cvbs_drv->flag &= ~CVBS_FLAG_EN_ENCI; + cvbs_vdac_output(0); return 0; } @@ -1221,9 +1224,9 @@ static void cvbs_debug_store(char *buf) } ret = kstrtoul(argv[1], 10, &value); if (value) - cvbs_cntl_output(1); + cvbs_vdac_output(1); else - cvbs_cntl_output(0); + cvbs_vdac_output(0); break; case CMD_HELP: @@ -1531,7 +1534,7 @@ static int cvbsout_probe(struct platform_device *pdev) cvbs_clk_path = 0; local_cvbs_mode = MODE_MAX; - cvbs_drv = kmalloc(sizeof(*cvbs_drv), GFP_KERNEL); + cvbs_drv = kzalloc(sizeof(*cvbs_drv), GFP_KERNEL); if (!cvbs_drv) return -ENOMEM; @@ -1560,7 +1563,7 @@ static int cvbsout_probe(struct platform_device *pdev) goto cvbsout_probe_err; } - INIT_DELAYED_WORK(&cvbs_drv->dv_dwork, cvbs_dv_dwork); + INIT_DELAYED_WORK(&cvbs_drv->vdac_dwork, cvbs_vdac_dwork); cvbs_log_info("%s OK\n", __func__); return 0; @@ -1595,12 +1598,19 @@ static int cvbsout_remove(struct platform_device *pdev) static void cvbsout_shutdown(struct platform_device *pdev) { - cvbs_drv->dwork_flag = 0; + if ((cvbs_drv->flag & CVBS_FLAG_EN_ENCI) == 0) + return; + + if (cvbs_drv->flag & CVBS_FLAG_EN_VDAC) + cvbs_vdac_output(0); + + cvbs_drv->flag &= ~CVBS_FLAG_EN_ENCI; cvbs_out_reg_write(ENCI_VIDEO_EN, 0); cvbs_out_disable_clk(); cvbs_out_vpu_power_ctrl(0); cvbs_out_clk_gate_ctrl(0); + cvbs_log_info("%s\n", __func__); } static struct platform_driver cvbsout_driver = { diff --git a/drivers/amlogic/media/vout/cvbs/cvbs_out.h b/drivers/amlogic/media/vout/cvbs/cvbs_out.h index 34dafeb..7c06962 100644 --- a/drivers/amlogic/media/vout/cvbs/cvbs_out.h +++ b/drivers/amlogic/media/vout/cvbs/cvbs_out.h @@ -64,6 +64,10 @@ struct performance_config_s { struct reg_s *reg_table; }; +/* cvbs driver flag */ +#define CVBS_FLAG_EN_ENCI BIT(0) +#define CVBS_FLAG_EN_VDAC BIT(1) + struct cvbs_drv_s { struct vinfo_s *vinfo; struct cdev *cdev; @@ -73,8 +77,8 @@ struct cvbs_drv_s { struct meson_cvbsout_data *cvbs_data; struct performance_config_s perf_conf_pal; struct performance_config_s perf_conf_ntsc; - struct delayed_work dv_dwork; - bool dwork_flag; + struct delayed_work vdac_dwork; + unsigned int flag; /* clktree */ unsigned int clk_gate_state; diff --git a/drivers/amlogic/media/vout/vdac/vdac_dev.c b/drivers/amlogic/media/vout/vdac/vdac_dev.c index 613c500..52979a8 100644 --- a/drivers/amlogic/media/vout/vdac/vdac_dev.c +++ b/drivers/amlogic/media/vout/vdac/vdac_dev.c @@ -444,29 +444,6 @@ void vdac_enable(bool on, unsigned int module_sel) } EXPORT_SYMBOL(vdac_enable); -static void vdac_set_ctrl0_ctrl1(unsigned int ctrl0, unsigned int ctrl1) -{ - unsigned int reg_cntl0; - unsigned int reg_cntl1; - - if (!s_vdac_data) { - pr_err("\n%s: s_vdac_data NULL\n", __func__); - return; - } - - reg_cntl0 = s_vdac_data->reg_cntl0; - reg_cntl1 = s_vdac_data->reg_cntl1; - - vdac_hiu_reg_write(reg_cntl0, ctrl0); - vdac_hiu_reg_write(reg_cntl1, ctrl1); - if (vdac_debug_print) { - pr_info("vdac: set reg 0x%02x=0x%08x, readback=0x%08x\n", - reg_cntl0, ctrl0, vdac_hiu_reg_read(reg_cntl0)); - pr_info("vdac: set reg 0x%02x=0x%08x, readback=0x%08x\n", - reg_cntl1, ctrl1, vdac_hiu_reg_read(reg_cntl1)); - } -} - int vdac_vref_adj(unsigned int value) { struct meson_vdac_ctrl_s *table; @@ -564,6 +541,59 @@ int vdac_enable_check_cvbs(void) return (pri_flag & VDAC_MODULE_CVBS_OUT) ? 1 : 0; } +static void vdac_dev_disable(void) +{ + if (!s_vdac_data) + return; + + mutex_lock(&vdac_mutex); + if ((pri_flag & VDAC_MODULE_MASK) == 0) { + mutex_unlock(&vdac_mutex); + return; + } + + if (pri_flag & VDAC_MODULE_CVBS_OUT) + vdac_enable_cvbs_out(0); + if (pri_flag & VDAC_MODULE_AVOUT_ATV) + vdac_enable_avout_atv(0); + if (pri_flag & VDAC_MODULE_AVOUT_AV) + vdac_enable_avout_av(0); + if (pri_flag & VDAC_MODULE_DTV_DEMOD) + vdac_enable_dtv_demod(0); + + mutex_unlock(&vdac_mutex); + + if (vdac_debug_print) { + pr_info("private_flag: 0x%02x\n" + "reg_cntl0: 0x%02x=0x%08x\n" + "reg_cntl1: 0x%02x=0x%08x\n", + pri_flag, + s_vdac_data->reg_cntl0, + vdac_hiu_reg_read(s_vdac_data->reg_cntl0), + s_vdac_data->reg_cntl1, + vdac_hiu_reg_read(s_vdac_data->reg_cntl1)); + } +} + +static void vdac_dev_enable(void) +{ + if (!s_vdac_data) + return; + if ((pri_flag & VDAC_MODULE_MASK) == 0) + return; + + if (vdac_debug_print) { + pr_info("private_flag: 0x%02x\n" + "reg_cntl0: 0x%02x=0x%08x\n" + "reg_cntl1: 0x%02x=0x%08x\n", + pri_flag, + s_vdac_data->reg_cntl0, + vdac_hiu_reg_read(s_vdac_data->reg_cntl0), + s_vdac_data->reg_cntl1, + vdac_hiu_reg_read(s_vdac_data->reg_cntl1)); + } +} + /* ********************************************************* */ static ssize_t vdac_info_show(struct class *class, struct class_attribute *attr, char *buf) @@ -801,40 +831,23 @@ static int __exit aml_vdac_remove(struct platform_device *pdev) static int amvdac_drv_suspend(struct platform_device *pdev, pm_message_t state) { - if (s_vdac_data->cpu_id == VDAC_CPU_TXL || - s_vdac_data->cpu_id == VDAC_CPU_TXLX) - vdac_hiu_reg_write(s_vdac_data->reg_cntl0, 0); - else if (s_vdac_data->cpu_id == VDAC_CPU_TL1 || - s_vdac_data->cpu_id == VDAC_CPU_TM2) - vdac_ctrl_config(0, s_vdac_data->reg_cntl1, 7); - pr_info("%s: suspend module\n", __func__); + vdac_dev_disable(); + pr_info("%s: private_flag:0x%x\n", __func__, pri_flag); return 0; } static int amvdac_drv_resume(struct platform_device *pdev) { - /*0xbc[7] for bandgap enable: 0:enable,1:disable*/ - if (s_vdac_data->cpu_id == VDAC_CPU_TL1 || - s_vdac_data->cpu_id == VDAC_CPU_TM2) { - vdac_ctrl_config(1, s_vdac_data->reg_cntl1, 7); - } - pr_info("%s: resume module\n", __func__); + vdac_dev_enable(); + pr_info("%s: private_flag:0x%x\n", __func__, pri_flag); return 0; } #endif static void amvdac_drv_shutdown(struct platform_device *pdev) { - unsigned int cntl0, cntl1; - - pr_info("%s: shutdown module, private_flag:0x%x\n", - __func__, pri_flag); - cntl0 = 0x0; - if (is_meson_txl_cpu() || is_meson_txlx_cpu()) - cntl1 = 0x0; - else - cntl1 = 0x8; - vdac_set_ctrl0_ctrl1(cntl0, cntl1); + vdac_dev_disable(); + pr_info("%s: private_flag:0x%x\n", __func__, pri_flag); } static struct platform_driver aml_vdac_driver = { |