summaryrefslogtreecommitdiff
authorEvoke 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)
commit7c65aafcec0e1db12eed8c0dbb6cd052f5b8de86 (patch)
tree360b307344070d8728a304be43fe17cb1933040c
parent036f8451c0614265d3511965d1867584c3627647 (diff)
downloadcommon-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>
Diffstat
-rw-r--r--drivers/amlogic/media/vout/cvbs/cvbs_out.c46
-rw-r--r--drivers/amlogic/media/vout/cvbs/cvbs_out.h8
-rw-r--r--drivers/amlogic/media/vout/vdac/vdac_dev.c105
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 = {