From b98ac8f0975a9aa4d2053610979ebc434c0380e1 Mon Sep 17 00:00:00 2001 From: Yong Qin Date: Wed, 6 Jun 2018 16:48:59 +0800 Subject: [PATCH] cec: fix cts test bug and transwich cec bug PD#167701: cec: sync code from 3.14 1.add weakup reason 2.set default cec version is 1.4 3.add hw reset for transwich ip when access register fail Change-Id: Ie664123213fcbdf68a7161f90322a12fee50f1ea Signed-off-by: Yong Qin --- drivers/amlogic/cec/hdmi_ao_cec.c | 70 ++++++++++++++++------ drivers/amlogic/cec/hdmi_ao_cec.h | 33 ++++++---- .../amlogic/media/vin/tvin/hdmirx/hdmi_rx_drv.c | 6 ++ .../amlogic/media/vin/tvin/hdmirx/hdmi_rx_drv.h | 3 +- include/linux/amlogic/cec_common.h | 12 ++-- .../amlogic/media/vout/hdmi_tx/hdmi_tx_cec_20.h | 2 + 6 files changed, 91 insertions(+), 35 deletions(-) diff --git a/drivers/amlogic/cec/hdmi_ao_cec.c b/drivers/amlogic/cec/hdmi_ao_cec.c index e091319..284bdac 100644 --- a/drivers/amlogic/cec/hdmi_ao_cec.c +++ b/drivers/amlogic/cec/hdmi_ao_cec.c @@ -91,6 +91,12 @@ struct cec_platform_data_s { bool ee_to_ao;/*ee cec hw module mv to ao;ao cec delete*/ }; +struct cec_wakeup_t { + unsigned int wk_logic_addr:8; + unsigned int wk_phy_addr:16; + unsigned int wk_port_id:8; +}; + /* global struct for tx and rx */ struct ao_cec_dev { unsigned long dev_type; @@ -116,6 +122,8 @@ struct ao_cec_dev { spinlock_t cec_reg_lock; struct mutex cec_mutex; struct mutex cec_ioctl_mutex; + struct cec_wakeup_t wakup_data; + unsigned int wakeup_reason; #ifdef CONFIG_PM int cec_suspend; #endif @@ -155,7 +163,7 @@ static unsigned int new_msg; static bool wake_ok = 1; static bool ee_cec; static bool pin_status; -static bool cec_msg_dbg_en; +bool cec_msg_dbg_en; #define CEC_ERR(format, args...) \ {if (cec_dev->dbg_dev) \ @@ -169,12 +177,15 @@ static bool cec_msg_dbg_en; static unsigned char msg_log_buf[128] = { 0 }; +static void cec_hw_reset(void); + #define waiting_aocec_free(r) \ do {\ unsigned long cnt = 0;\ while (readl(cec_dev->cec_reg + r) & (1<<23)) {\ if (cnt++ == 3500) { \ pr_info("waiting aocec %x free time out\n", r);\ + cec_hw_reset();\ break;\ } \ } \ @@ -196,8 +207,8 @@ unsigned int aocec_rd_reg(unsigned long addr) unsigned int data32; unsigned long flags; - waiting_aocec_free(AO_CEC_RW_REG); spin_lock_irqsave(&cec_dev->cec_reg_lock, flags); + waiting_aocec_free(AO_CEC_RW_REG); data32 = 0; data32 |= 0 << 16; /* [16] cec_reg_wr */ data32 |= 0 << 8; /* [15:8] cec_reg_wrdata */ @@ -215,8 +226,8 @@ void aocec_wr_reg(unsigned long addr, unsigned long data) unsigned long data32; unsigned long flags; - waiting_aocec_free(AO_CEC_RW_REG); spin_lock_irqsave(&cec_dev->cec_reg_lock, flags); + waiting_aocec_free(AO_CEC_RW_REG); data32 = 0; data32 |= 1 << 16; /* [16] cec_reg_wr */ data32 |= data << 8; /* [15:8] cec_reg_wrdata */ @@ -749,7 +760,7 @@ static void cec_hw_reset(void) cec_arbit_bit_time_set(7, 0x2aa, 0); CEC_INFO("hw reset :logical addr:0x%x\n", - aocec_rd_reg(CEC_LOGICAL_ADDR0)); + aocec_rd_reg(CEC_LOGICAL_ADDR0)); } void cec_rx_buf_clear(void) @@ -934,6 +945,8 @@ static int cec_ll_trigle_tx(const unsigned char *msg, int len) } cec_timeout_cnt = 0; return 0; + } else { + CEC_ERR("error msg sts:0x%x\n", reg); } return -1; } @@ -1857,14 +1870,14 @@ static ssize_t port_status_show(struct class *cla, if (cec_dev->dev_type == DEV_TYPE_PLAYBACK) { tmp = tx_hpd; return sprintf(buf, "%x\n", tmp); + } else { + tmp = hdmirx_rd_top(TOP_HPD_PWR5V); + CEC_INFO("TOP_HPD_PWR5V:%x\n", tmp); + tmp >>= 20; + tmp &= 0xf; + tmp |= (tx_hpd << 16); + return sprintf(buf, "%x\n", tmp); } - - tmp = hdmirx_rd_top(TOP_HPD_PWR5V); - CEC_INFO("TOP_HPD_PWR5V:%x\n", tmp); - tmp >>= 20; - tmp &= 0xf; - tmp |= (tx_hpd << 16); - return sprintf(buf, "%x\n", tmp); } static ssize_t pin_status_show(struct class *cla, @@ -1908,6 +1921,7 @@ static ssize_t physical_addr_store(struct class *cla, if (kstrtouint(buf, 16, &addr) != 0) return -EINVAL; + if (addr > 0xffff || addr < 0) { CEC_ERR("invalid input:%s\n", buf); phy_addr_test = 0; @@ -1986,6 +2000,7 @@ static ssize_t fun_cfg_show(struct class *cla, static ssize_t cec_version_show(struct class *cla, struct class_attribute *attr, char *buf) { + CEC_INFO("driver date:%s\n", CEC_DRIVER_VERSION); return sprintf(buf, "%d\n", cec_dev->cec_info.cec_version); } @@ -2327,7 +2342,7 @@ static long hdmitx_cec_ioctl(struct file *f, if (!a && cec_dev->dev_type == DEV_TYPE_TUNER) tmp = tx_hpd; else { /* mixed for rx */ - tmp = (hdmirx_rd_top(TOP_HPD_PWR5V) >> 20); + tmp = hdmirx_get_connect_info(); if (tmp & (1 << (a - 1))) tmp = 1; else @@ -2374,7 +2389,23 @@ static long hdmitx_cec_ioctl(struct file *f, cec_enable_arc_pin(arg); break; + case CEC_IOC_GET_BOOT_ADDR: + tmp = (cec_dev->wakup_data.wk_logic_addr << 16) | + cec_dev->wakup_data.wk_phy_addr; + CEC_ERR("Boot addr:%#x\n", (unsigned int)tmp); + if (copy_to_user(argp, &tmp, _IOC_SIZE(cmd))) + return -EINVAL; + break; + + case CEC_IOC_GET_BOOT_REASON: + tmp = cec_dev->wakeup_reason; + CEC_ERR("Boot reason:%#x\n", (unsigned int)tmp); + if (copy_to_user(argp, &tmp, _IOC_SIZE(cmd))) + return -EINVAL; + break; + default: + CEC_ERR("error ioctrl\n"); break; } mutex_unlock(&cec_dev->cec_ioctl_mutex); @@ -2490,7 +2521,6 @@ static int aml_cec_probe(struct platform_device *pdev) ret = -ENOMEM; goto tag_cec_devm_err; } - CEC_ERR("cec driver date:%s\n", CEC_DRIVER_VERSION); cec_dev->dev_type = DEV_TYPE_PLAYBACK; cec_dev->dbg_dev = &pdev->dev; cec_dev->tx_dev = get_hdmitx_device(); @@ -2573,7 +2603,7 @@ static int aml_cec_probe(struct platform_device *pdev) ee_cec = 1; else ee_cec = 0; - CEC_INFO("using cec:%d\n", ee_cec); + CEC_ERR("using EE cec:%d\n", ee_cec); /* pinmux set */ if (of_get_property(node, "pinctrl-names", NULL)) { @@ -2679,7 +2709,7 @@ static int aml_cec_probe(struct platform_device *pdev) if (r) { /* default set to 2.0 */ CEC_INFO("not find cec_version\n"); - cec_dev->cec_info.cec_version = CEC_VERSION_20; + cec_dev->cec_info.cec_version = CEC_VERSION_14A; } /* irq set */ @@ -2695,10 +2725,14 @@ static int aml_cec_probe(struct platform_device *pdev) if (!r && !ee_cec) { r = request_irq(irq_idx, &cec_isr_handler, IRQF_SHARED, irq_name, (void *)cec_dev); + if (r < 0) + CEC_INFO("aocec irq request fail\n"); } if (!r && ee_cec) { r = request_irq(irq_idx, &cecrx_isr, IRQF_SHARED, irq_name, (void *)cec_dev); + if (r < 0) + CEC_INFO("cecb irq request fail\n"); } } #endif @@ -2725,10 +2759,12 @@ static int aml_cec_probe(struct platform_device *pdev) /* for init */ cec_pre_init(); queue_delayed_work(cec_dev->cec_thread, &cec_dev->cec_work, 0); - + CEC_ERR("cec driver date:%s\n", CEC_DRIVER_VERSION); + CEC_ERR("boot:%#x;%#x\n", *((unsigned int *)&cec_dev->wakup_data), + cec_dev->wakeup_reason); CEC_ERR("%s success end\n", __func__); - return 0; + tag_cec_msg_alloc_err: input_free_device(cec_dev->cec_info.remote_cec_dev); tag_cec_alloc_input_err: diff --git a/drivers/amlogic/cec/hdmi_ao_cec.h b/drivers/amlogic/cec/hdmi_ao_cec.h index 70a1a74..abca514 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 "2018/05/15\n" +#define CEC_DRIVER_VERSION "2018/06/13\n" #define CEC_FRAME_DELAY msecs_to_jiffies(400) #define CEC_DEV_NAME "cec" @@ -33,7 +33,6 @@ #define ONE_TOUCH_STANDBY_MASK 2 #define AUTO_POWER_ON_MASK 3 - #define AO_BASE 0xc8100000 #define AO_GPIO_I ((0x0A << 2)) @@ -58,6 +57,7 @@ #define AO_DEBUG_REG1 ((0x29 << 2)) #define AO_DEBUG_REG2 ((0x2a << 2)) #define AO_DEBUG_REG3 ((0x2b << 2)) +/* for new add after g12a/b ...*/ #define AO_CEC_STICKY_DATA0 ((0xca << 2)) #define AO_CEC_STICKY_DATA1 ((0xcb << 2)) #define AO_CEC_STICKY_DATA2 ((0xcc << 2)) @@ -371,16 +371,8 @@ #define HHI_32K_CLK_CNTL (0x89 << 2) -#ifdef CONFIG_AMLOGIC_AO_CEC -unsigned int aocec_rd_reg(unsigned long addr); -void aocec_wr_reg(unsigned long addr, unsigned long data); -void cecrx_irq_handle(void); -void cec_logicaddr_set(int l_add); -void cec_arbit_bit_time_set(unsigned int bit_set, - unsigned int time_set, unsigned int flag); -void cec_irq_enable(bool enable); -void aocec_irq_enable(bool enable); -#endif + + #ifdef CONFIG_AMLOGIC_MEDIA_TVIN_HDMI extern unsigned long hdmirx_rd_top(unsigned long addr); @@ -406,4 +398,21 @@ static inline void hdmirx_wr_dwc(uint16_t addr, uint32_t data) } #endif +extern int hdmirx_get_connect_info(void); +int __attribute__((weak))hdmirx_get_connect_info(void) +{ + return 0; +} + +#ifdef CONFIG_AMLOGIC_AO_CEC +unsigned int aocec_rd_reg(unsigned long addr); +void aocec_wr_reg(unsigned long addr, unsigned long data); +void cecrx_irq_handle(void); +void cec_logicaddr_set(int l_add); +void cec_arbit_bit_time_set(unsigned int bit_set, + unsigned int time_set, unsigned int flag); +void cec_irq_enable(bool enable); +void aocec_irq_enable(bool enable); +#endif + #endif /* __AO_CEC_H__ */ diff --git a/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_drv.c b/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_drv.c index 551eccb..0fe5243 100644 --- a/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_drv.c +++ b/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_drv.c @@ -567,6 +567,12 @@ void hdmirx_set_timing_info(struct tvin_sig_property_s *prop) prop->ve = 1; } +int hdmirx_get_connect_info(void) +{ + return pwr_sts; +} +EXPORT_SYMBOL(hdmirx_get_connect_info); + /* * hdmirx_get_color_fmt - get video color format */ diff --git a/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_drv.h b/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_drv.h index ddb30d4..0cfb5c90 100644 --- a/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_drv.h +++ b/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_drv.h @@ -34,7 +34,7 @@ #include "hdmi_rx_edid.h" -#define RX_VER0 "ver.2018-05-30" +#define RX_VER0 "ver.2018-06-13" /* * * @@ -465,4 +465,5 @@ extern unsigned int *pd_fifo_buf; extern int External_Mute(int mute_flag); extern void vdac_enable(bool on, unsigned int module_sel); extern int rx_is_hdcp22_support(void); +extern int hdmirx_get_connect_info(void); #endif diff --git a/include/linux/amlogic/cec_common.h b/include/linux/amlogic/cec_common.h index f49de0f..e7ce80b5 100644 --- a/include/linux/amlogic/cec_common.h +++ b/include/linux/amlogic/cec_common.h @@ -148,13 +148,13 @@ enum _cec_log_dev_addr_e { #define CEC_DISPLAY_DEVICE (CEC_TV | CEC_FREE_USE) #define CEC_RECORDING_DEVICE (CEC_RECORDING_DEVICE_1 | \ - CEC_RECORDING_DEVICE_2 | \ - CEC_RECORDING_DEVICE_3) + CEC_RECORDING_DEVICE_2 | \ + CEC_RECORDING_DEVICE_3) #define CEC_PLAYBACK_DEVICE (CEC_PLAYBACK_DEVICE_1 | \ - CEC_PLAYBACK_DEVICE_2 | \ - CEC_PLAYBACK_DEVICE_3) + CEC_PLAYBACK_DEVICE_2 | \ + CEC_PLAYBACK_DEVICE_3) #define CEC_TUNER_DEVICE (CEC_TUNER_1 | CEC_TUNER_2 | \ - CEC_TUNER_3 | CEC_TUNER_4) + CEC_TUNER_3 | CEC_TUNER_4) #define CEC_AUDIO_SYSTEM_DEVICE (CEC_AUDIO_SYSTEM) #define CEC_IOC_MAGIC 'C' @@ -174,6 +174,8 @@ enum _cec_log_dev_addr_e { #define CEC_IOC_SET_DEV_TYPE _IOW(CEC_IOC_MAGIC, 0x0D, uint32_t) #define CEC_IOC_SET_ARC_ENABLE _IOW(CEC_IOC_MAGIC, 0x0E, uint32_t) #define CEC_IOC_SET_AUTO_DEVICE_OFF _IOW(CEC_IOC_MAGIC, 0x0F, uint32_t) +#define CEC_IOC_GET_BOOT_ADDR _IOW(CEC_IOC_MAGIC, 0x10, uint32_t) +#define CEC_IOC_GET_BOOT_REASON _IOW(CEC_IOC_MAGIC, 0x11, uint32_t) enum hdmi_port_type { HDMI_INPUT = 0, diff --git a/include/linux/amlogic/media/vout/hdmi_tx/hdmi_tx_cec_20.h b/include/linux/amlogic/media/vout/hdmi_tx/hdmi_tx_cec_20.h index 6e3bf3e..9fe74a2 100644 --- a/include/linux/amlogic/media/vout/hdmi_tx/hdmi_tx_cec_20.h +++ b/include/linux/amlogic/media/vout/hdmi_tx/hdmi_tx_cec_20.h @@ -98,6 +98,8 @@ enum _cec_log_dev_addr_e { #define CEC_IOC_SET_DEV_TYPE _IOW(CEC_IOC_MAGIC, 0x0D, uint32_t) #define CEC_IOC_SET_ARC_ENABLE _IOW(CEC_IOC_MAGIC, 0x0E, uint32_t) #define CEC_IOC_SET_AUTO_DEVICE_OFF _IOW(CEC_IOC_MAGIC, 0x0F, uint32_t) +#define CEC_IOC_GET_BOOT_ADDR _IOW(CEC_IOC_MAGIC, 0x10, uint32_t) +#define CEC_IOC_GET_BOOT_REASON _IOW(CEC_IOC_MAGIC, 0x11, uint32_t) #define CEC_FAIL_NONE 0 #define CEC_FAIL_NACK 1 -- 2.7.4