From eb25b26488db3959bfce9a704d59a632001baa9c Mon Sep 17 00:00:00 2001 From: Yong Qin Date: Tue, 21 Jan 2020 20:53:16 +0800 Subject: [PATCH] cec: pw down save phy addr [1/1] PD#SWPL-19940 Problem: sometime uboot got wrong phy addr Solution: power down save phy addr again Verify: g12a Change-Id: I0a4c468e1c1752c4dcdc4d33a32e14db60dd67b5 Signed-off-by: Yong Qin --- drivers/amlogic/cec/hdmi_ao_cec.c | 92 +++++++++++++++++++++++-------- drivers/amlogic/cec/hdmi_ao_cec.h | 2 +- 2 files changed, 71 insertions(+), 23 deletions(-) diff --git a/drivers/amlogic/cec/hdmi_ao_cec.c b/drivers/amlogic/cec/hdmi_ao_cec.c index fc6fc0f2049a..5b5a926c5322 100644 --- a/drivers/amlogic/cec/hdmi_ao_cec.c +++ b/drivers/amlogic/cec/hdmi_ao_cec.c @@ -2122,7 +2122,12 @@ static void cec_rx_process(void) case CEC_OC_SET_STREAM_PATH: cec_set_stream_path(msg); /* wake up if in early suspend */ - if (cec_dev->cec_suspend == CEC_PW_STANDBY) + dest_phy_addr = (unsigned int)(msg[2] << 8 | msg[3]); + CEC_ERR("phyaddr:0x%x, 0x%x\n", + cec_dev->phy_addr, dest_phy_addr); + if ((dest_phy_addr != 0xffff) && + (dest_phy_addr == cec_dev->phy_addr) && + (cec_dev->cec_suspend == CEC_PW_STANDBY)) cec_key_report(0); break; @@ -2202,8 +2207,8 @@ static void cec_save_pre_setting(void) cec_set_reg_bits(AO_DEBUG_REG1, config_data, 20, 4); CEC_ERR("%s: logaddr:0x%x, devtype:0x%x\n", __func__, cec_dev->cec_info.log_addr, - config_data = cec_dev->dev_type); - cec_set_reg_bits(AO_DEBUG_REG1, cec_dev->phy_addr, 0, 8); + (unsigned int)cec_dev->dev_type); + cec_set_reg_bits(AO_DEBUG_REG1, cec_dev->phy_addr, 0, 16); } static void cec_restore_pre_setting(void) @@ -3085,14 +3090,35 @@ void cec_status(void) CEC_ERR("addr_enable:0x%x\n", cec_dev->cec_info.addr_enable); } +unsigned int cec_get_cur_phy_addr(void) +{ + struct hdmitx_dev *tx_dev; + unsigned int a, b, c, d; + unsigned int tmp; + + tx_dev = cec_dev->tx_dev; + if (!tx_dev || cec_dev->dev_type == CEC_TV_ADDR) + tmp = 0; + else/* if (tx_dev->hdmi_info.vsdb_phy_addr.valid == 1) */{ + /*hpd attach and wait read edid*/ + a = tx_dev->hdmi_info.vsdb_phy_addr.a; + b = tx_dev->hdmi_info.vsdb_phy_addr.b; + c = tx_dev->hdmi_info.vsdb_phy_addr.c; + d = tx_dev->hdmi_info.vsdb_phy_addr.d; + tmp = ((a << 12) | (b << 8) | (c << 4) | (d)); + } + + return tmp; +} + static long hdmitx_cec_ioctl(struct file *f, unsigned int cmd, unsigned long arg) { void __user *argp = (void __user *)arg; unsigned int tmp; struct hdmi_port_info *port; - unsigned int a, b, c, d, i = 0; - struct hdmitx_dev *tx_dev; + unsigned int a, i = 0; + /*struct hdmitx_dev *tx_dev;*/ /*unsigned int tx_hpd;*/ mutex_lock(&cec_dev->cec_ioctl_mutex); @@ -3100,26 +3126,19 @@ static long hdmitx_cec_ioctl(struct file *f, case CEC_IOC_GET_PHYSICAL_ADDR: /*check_physical_addr_valid(20);*/ /* physical address for TV or repeator */ - tx_dev = cec_dev->tx_dev; - if (!tx_dev || cec_dev->dev_type == CEC_TV_ADDR) { - tmp = 0; - } else if (tx_dev->hdmi_info.vsdb_phy_addr.valid == 1) { - /*hpd attach and wait read edid*/ - a = tx_dev->hdmi_info.vsdb_phy_addr.a; - b = tx_dev->hdmi_info.vsdb_phy_addr.b; - c = tx_dev->hdmi_info.vsdb_phy_addr.c; - d = tx_dev->hdmi_info.vsdb_phy_addr.d; - tmp = ((a << 12) | (b << 8) | (c << 4) | (d)); - } else - tmp = 0; + tmp = cec_get_cur_phy_addr(); + if ((cec_dev->dev_type != CEC_TV_ADDR) && (tmp != 0) && + tmp != 0xffff) + cec_dev->phy_addr = tmp; if (!phy_addr_test) { - cec_dev->phy_addr = tmp; - cec_phyaddr_config(tmp, 1); + cec_phyaddr_config(cec_dev->phy_addr, 1); + CEC_INFO("type %d, save phy_addr:0x%x\n", + (unsigned int)cec_dev->dev_type, cec_dev->phy_addr); } else tmp = cec_dev->phy_addr; - if (copy_to_user(argp, &tmp, _IOC_SIZE(cmd))) { + if (copy_to_user(argp, &cec_dev->phy_addr, _IOC_SIZE(cmd))) { mutex_unlock(&cec_dev->cec_ioctl_mutex); return -EINVAL; } @@ -3369,8 +3388,23 @@ static const struct file_operations hdmitx_cec_fops = { #ifdef CONFIG_AMLOGIC_LEGACY_EARLY_SUSPEND static void aocec_early_suspend(struct early_suspend *h) { + /*unsigned int tempaddr;*/ + cec_dev->cec_suspend = CEC_PW_STANDBY; - CEC_ERR("%s, suspend sts:%d\n", __func__, cec_dev->cec_suspend); + #if 0 + tempaddr = cec_get_cur_phy_addr(); + if ((cec_dev->dev_type != CEC_TV_ADDR) && (tempaddr != 0) && + tempaddr != 0xffff) + cec_dev->phy_addr = tempaddr; + CEC_ERR("%s sts:%d,type:0x%x, phyaddr:0x%x (0x%x)\n", __func__, + cec_dev->cec_suspend, (unsigned int)cec_dev->dev_type, + cec_dev->phy_addr, tempaddr); + if ((cec_dev->dev_type != CEC_TV_ADDR) && (cec_dev->phy_addr == 0)) { + CEC_ERR("err phyaddr 0\n"); + cec_dev->phy_addr = 0x1000; + } + cec_phyaddr_config(cec_dev->phy_addr, 1); + #endif /* reset wakeup reason for considering light sleep situation*/ cec_dev->wakeup_reason = 0; } @@ -3976,10 +4010,24 @@ static void aml_cec_pm_complete(struct device *dev) static int aml_cec_suspend_noirq(struct device *dev) { int ret = 0; + /*unsigned int tempaddr;*/ cec_dev->cec_info.power_status = CEC_PW_TRANS_ON_TO_STANDBY; cec_dev->cec_suspend = CEC_PW_TRANS_ON_TO_STANDBY; - + #if 0 + tempaddr = cec_get_cur_phy_addr(); + if (cec_dev->dev_type != CEC_TV_ADDR && (tempaddr != 0) && + tempaddr != 0xffff) + cec_dev->phy_addr = tempaddr; + CEC_ERR("%s type:0x%x phyaddr:0x%x(0x%x)\n", __func__, + (unsigned int)cec_dev->dev_type, + cec_dev->phy_addr, tempaddr); + if ((cec_dev->dev_type != CEC_TV_ADDR) && (cec_dev->phy_addr == 0)) { + CEC_ERR("err phyaddr 0\n"); + cec_dev->phy_addr = 0x1000; + } + cec_phyaddr_config(cec_dev->phy_addr, 1); + #endif if (is_pm_freeze_mode()) { CEC_ERR("%s:freeze mode\n", __func__); cec_restore_pre_setting(); diff --git a/drivers/amlogic/cec/hdmi_ao_cec.h b/drivers/amlogic/cec/hdmi_ao_cec.h index 7828f7941989..6bc946c46f62 100644 --- a/drivers/amlogic/cec/hdmi_ao_cec.h +++ b/drivers/amlogic/cec/hdmi_ao_cec.h @@ -18,7 +18,7 @@ #ifndef __AO_CEC_H__ #define __AO_CEC_H__ -#define CEC_DRIVER_VERSION "2019/12/01:finetune ARB time, cause cts 9.6.1\n" +#define CEC_DRIVER_VERSION "2020/01/22:suspend get phy addr from tx and save\n" #define CEC_FRAME_DELAY msecs_to_jiffies(400) #define CEC_DEV_NAME "cec" -- 2.20.1