From: hongmin hua Date: Sun, 30 Sep 2018 03:06:17 +0000 (+0800) Subject: hdmirx: add hdmirx repeater function [1/6] X-Git-Tag: khadas-vims-v0.9.6-release~1198 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=79377624273cfe346b7ecf65ca8ce896bec82f54;p=platform%2Fkernel%2Flinux-amlogic.git hdmirx: add hdmirx repeater function [1/6] PD#SWPL-323: Problem: add hdmi repeater function Solution: 1.add the edid receive and mix. 2.add the flow of repeater. Verify: R321 Change-Id: I9942c5f345e2fdfff110f01d4d0c2b4b23120c07 Signed-off-by: hongmin hua --- diff --git a/drivers/amlogic/esm/hdcp_main.c b/drivers/amlogic/esm/hdcp_main.c index cbddd87..f7d8ecb 100644 --- a/drivers/amlogic/esm/hdcp_main.c +++ b/drivers/amlogic/esm/hdcp_main.c @@ -63,6 +63,8 @@ struct esm_device { dma_addr_t data_base; uint32_t data_size; uint8_t *data; + + struct dentry *esm_blob; struct debugfs_blob_wrapper blob; struct resource *hpi_resource; uint8_t __iomem *hpi; @@ -106,7 +108,7 @@ static long load_code(struct esm_device *esm, struct esm_ioc_code __user *arg) if (copy_from_user(esm->code, &arg->data, head.len) != 0) return -EFAULT; - esm->code_loaded = 1; + /* esm->code_loaded = 1; */ return 0; } @@ -233,7 +235,7 @@ static struct esm_device *alloc_esm_slot(const struct esm_ioc_meminfo *info) } static struct dentry *esm_debugfs; -static struct dentry *esm_blob; +/*static struct dentry *esm_blob;*/ static void free_dma_areas(struct esm_device *esm) { @@ -255,6 +257,8 @@ static void free_dma_areas(struct esm_device *esm) static int alloc_dma_areas(struct esm_device *esm, const struct esm_ioc_meminfo *info) { + char blobname[32]; + esm->code_size = info->code_size; esm->code_is_phys_mem = (info->code_base != 0); @@ -289,20 +293,24 @@ static int alloc_dma_areas(struct esm_device *esm, return -ENOMEM; } } - /* add blob note to show esm feature and debug*/ - esm_debugfs = debugfs_create_dir("esm", NULL); - if (!esm_debugfs) - return -ENOENT; - - esm->blob.data = (void *)esm->code; - esm->blob.size = esm->code_size; - esm_blob = debugfs_create_blob("blob", 0644, esm_debugfs, &esm->blob); if (randomize_mem) { prandom_bytes(esm->code, esm->code_size); prandom_bytes(esm->data, esm->data_size); } + if (!esm_debugfs) { + esm_debugfs = debugfs_create_dir("esm", NULL); + if (!esm_debugfs) + return -ENOENT; + } + memset(blobname, 0, sizeof(blobname)); + sprintf(blobname, "blob.%x", info->hpi_base); + esm->blob.data = (void *)esm->data; + esm->blob.size = esm->data_size; + esm->esm_blob = debugfs_create_blob(blobname, 0644, esm_debugfs, + &esm->blob); + return 0; } @@ -312,6 +320,7 @@ static long init(struct file *f, void __user *arg) struct resource *hpi_mem; struct esm_ioc_meminfo info; struct esm_device *esm; + char region_name[20]; int rc; if (copy_from_user(&info, arg, sizeof(info)) != 0) @@ -325,8 +334,15 @@ static long init(struct file *f, void __user *arg) rc = alloc_dma_areas(esm, &info); if (rc < 0) goto err_free; - pr_info("info.hpi_base = 0x%x\n", info.hpi_base); - hpi_mem = request_mem_region(info.hpi_base, 128, "esm-hpi"); + /* pr_info("info.hpi_base = 0x%x\n", info.hpi_base); */ + /* hpi_mem = + * request_mem_region(info.hpi_base, 128, "esm-hpi"); + */ + sprintf(region_name, "ESM-%X", info.hpi_base); + pr_info("info.hpi_base = 0x%x region_name:%s\n", + info.hpi_base, region_name); + hpi_mem = request_mem_region(info.hpi_base, 0x100, region_name); + if (!hpi_mem) { rc = -EADDRNOTAVAIL; goto err_free; @@ -342,6 +358,12 @@ static long init(struct file *f, void __user *arg) esm->initialized = 1; } + /*every time clear the data buff*/ + if (esm->data) + memset(esm->data, 0, esm->data_size); + pr_info("esm data = %p size:%d\n", + esm->data, esm->data_size); + f->private_data = esm; return 0; diff --git a/drivers/amlogic/media/vin/tvin/hdmirx/hdcp_rx_main.c b/drivers/amlogic/media/vin/tvin/hdmirx/hdcp_rx_main.c index d52b9f6..dbd19a6 100644 --- a/drivers/amlogic/media/vin/tvin/hdmirx/hdcp_rx_main.c +++ b/drivers/amlogic/media/vin/tvin/hdmirx/hdcp_rx_main.c @@ -32,6 +32,7 @@ #include #include #include "hdcp_rx_main.h" +#include "hdmi_rx_repeater.h" #include "hdmi_rx_drv.h" #include "hdmi_rx_hw.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 4ddf66b..b86c6d9 100644 --- a/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_drv.c +++ b/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_drv.c @@ -53,6 +53,7 @@ #endif /* Local include */ +#include "hdmi_rx_repeater.h" #include "hdmi_rx_drv.h" #include "hdmi_rx_wrapper.h" #include "hdmi_rx_hw.h" @@ -60,7 +61,6 @@ #include "hdmi_rx_edid.h" #include "hdmi_rx_eq.h" #include "hdmi_rx_repeater.h" - /*------------------------extern function------------------------------*/ static int aml_hdcp22_pm_notify(struct notifier_block *nb, unsigned long event, void *dummy); @@ -113,6 +113,10 @@ int hdmi_yuv444_enable; module_param(hdmi_yuv444_enable, int, 0664); MODULE_PARM_DESC(hdmi_yuv444_enable, "hdmi_yuv444_enable"); +bool downstream_repeat_support; +MODULE_PARM_DESC(downstream_repeat_support, "\n downstream_repeat_support\n"); +module_param(downstream_repeat_support, bool, 0664); + int pc_mode_en; MODULE_PARM_DESC(pc_mode_en, "\n pc_mode_en\n"); module_param(pc_mode_en, int, 0664); @@ -259,6 +263,11 @@ unsigned int rx_set_bits(unsigned int data, return ((value << first_bit_set(mask)) & mask) | (data & ~mask); } +bool hdmirx_repeat_support(void) +{ + return downstream_repeat_support; +} + /* * hdmirx_dec_support - check if given port is supported * @fe: frontend device of tvin interface @@ -940,14 +949,13 @@ static long hdmirx_ioctl(struct file *file, unsigned int cmd, case HDMI_IOC_HDCP_ON: hdcp_enable = 1; rx_set_cur_hpd(0); - fsm_restart(); + /*fsm_restart();*/ break; case HDMI_IOC_HDCP_OFF: hdcp_enable = 0; rx_set_cur_hpd(0); hdmirx_hw_config(); - hdmi_rx_top_edid_update(); - fsm_restart(); + /*fsm_restart();*/ break; case HDMI_IOC_EDID_UPDATE: if (rx.open_fg) { @@ -1356,11 +1364,100 @@ static ssize_t cec_get_state(struct device *dev, return 0; } -/* +static ssize_t hdcp_version_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return sprintf(buf, "%x\n", rx.hdcp.hdcp_version); +} + +static ssize_t hdcp_version_store(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t count) +{ + return count; +} + +static ssize_t hw_info_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct hdcp_hw_info_s info; + + memset(&info, 0, sizeof(info)); + info.cur_5v = rx.cur_5v_sts; + info.open = rx.open_fg; + info.frame_rate = rx.pre.frame_rate/100; + info.signal_stable = ((rx.state == FSM_SIG_READY)?1:0); + return sprintf(buf, "%x\n", *((unsigned int *)&info)); +} + +static ssize_t hw_info_store(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t count) +{ + return count; +} + +static ssize_t edid_dw_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return 0; +} + +static ssize_t edid_dw_store(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t count) +{ + int cnt = count; + + rx_pr("edid store len: %d\n", cnt); + rx_set_receiver_edid(buf, cnt); + + return count; +} + +static ssize_t ksvlist_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return 0; +} + +static ssize_t ksvlist_store(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t count) +{ + int cnt; + /* unsigned long tmp; */ + unsigned char *hdcp = rx_get_dw_hdcp_addr(); + /* unsigned char t_tmp[3]; */ + cnt = count; + /* t_tmp[2] = '\0'; */ + rx_pr("dw hdcp %d,%d\n", cnt, sizeof(struct hdcp14_topo_s)); + /*for(i = 0;i < count/2;i++) { + * memcpy(t_tmp, buf + i*2, 2); + * if (kstrtoul(t_tmp, 16, &tmp)) + * rx_pr("ksvlist %s:\n", t_tmp); + * *(hdcp + i) = (unsigned char)tmp; + * rx_pr("%#x ", *(hdcp + i)); + *} + */ + memcpy(hdcp, buf, cnt); + rx_pr("\n"); + return count; +} + +/************************************* * val == 0 : cec disable * val == 1 : cec on * val == 2 : cec on && system startup - */ + **************************************/ static ssize_t cec_set_state(struct device *dev, struct device_attribute *attr, const char *buf, @@ -1460,6 +1557,25 @@ static ssize_t get_arc_aud_type(struct device *dev, return 0; } +static ssize_t set_reset_hdcp22(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t count) +{ + int reset; + + memcpy(&reset, buf, sizeof(reset)); + rx_pr("%s:%d\n", __func__, reset); + rx_reload_firm_reset(reset); + return count; +} + +static ssize_t get_reset_hdcp22(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return 0; +} static DEVICE_ATTR(debug, 0644, hdmirx_debug_show, hdmirx_debug_store); static DEVICE_ATTR(edid, 0644, hdmirx_edid_show, hdmirx_edid_store); static DEVICE_ATTR(key, 0644, hdmirx_key_show, hdmirx_key_store); @@ -1470,7 +1586,11 @@ static DEVICE_ATTR(param, 0644, param_get_value, param_set_value); static DEVICE_ATTR(esm_base, 0644, esm_get_base, esm_set_base); static DEVICE_ATTR(info, 0644, show_info, store_info); static DEVICE_ATTR(arc_aud_type, 0644, get_arc_aud_type, set_arc_aud_type); - +static DEVICE_ATTR(reset22, 0644, get_reset_hdcp22, set_reset_hdcp22); +static DEVICE_ATTR(hdcp_version, 0644, hdcp_version_show, hdcp_version_store); +static DEVICE_ATTR(hw_info, 0644, hw_info_show, hw_info_store); +static DEVICE_ATTR(edid_dw, 0644, edid_dw_show, edid_dw_store); +static DEVICE_ATTR(ksvlist, 0644, ksvlist_show, ksvlist_store); static int hdmirx_add_cdev(struct cdev *cdevp, const struct file_operations *fops, @@ -1808,6 +1928,32 @@ static int hdmirx_probe(struct platform_device *pdev) rx_pr("hdmirx: fail to create arc_aud_type file\n"); goto fail_create_arc_aud_type_file; } + ret = device_create_file(hdevp->dev, &dev_attr_reset22); + if (ret < 0) { + rx_pr("hdmirx: fail to create reset22 file\n"); + goto fail_create_reset22; + } + ret = device_create_file(hdevp->dev, &dev_attr_hdcp_version); + if (ret < 0) { + rx_pr("hdmirx: fail to create hdcp version file\n"); + goto fail_create_hdcp_version; + } + ret = device_create_file(hdevp->dev, &dev_attr_hw_info); + if (ret < 0) { + rx_pr("hdmirx: fail to create cur 5v file\n"); + goto fail_create_hw_info; + } + ret = device_create_file(hdevp->dev, &dev_attr_edid_dw); + if (ret < 0) { + rx_pr("hdmirx: fail to create edid_dw file\n"); + goto fail_create_edid_dw; + } + ret = device_create_file(hdevp->dev, &dev_attr_ksvlist); + if (ret < 0) { + rx_pr("hdmirx: fail to create ksvlist file\n"); + goto fail_create_ksvlist; + } + res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (!res) { rx_pr("%s: can't get irq resource\n", __func__); @@ -1946,8 +2092,8 @@ static int hdmirx_probe(struct platform_device *pdev) INIT_DELAYED_WORK(&esm_dwork, rx_hpd_to_esm_handle); /* queue_delayed_work(eq_wq, &eq_dwork, msecs_to_jiffies(5)); */ - repeater_wq = create_singlethread_workqueue(hdevp->frontend.name); - INIT_DELAYED_WORK(&repeater_dwork, repeater_dwork_handle); + /*repeater_wq = create_singlethread_workqueue(hdevp->frontend.name);*/ + /*INIT_DELAYED_WORK(&repeater_dwork, repeater_dwork_handle);*/ ret = of_property_read_u32(pdev->dev.of_node, "en_4k_2_2k", &en_4k_2_2k); @@ -1998,6 +2144,16 @@ fail_kmalloc_pd_fifo: return ret; fail_get_resource_irq: return ret; +fail_create_ksvlist: + device_remove_file(hdevp->dev, &dev_attr_ksvlist); +fail_create_edid_dw: + device_remove_file(hdevp->dev, &dev_attr_edid_dw); +fail_create_hw_info: + device_remove_file(hdevp->dev, &dev_attr_hw_info); +fail_create_hdcp_version: + device_remove_file(hdevp->dev, &dev_attr_hdcp_version); +fail_create_reset22: + device_remove_file(hdevp->dev, &dev_attr_reset22); fail_create_arc_aud_type_file: device_remove_file(hdevp->dev, &dev_attr_arc_aud_type); fail_create_cec_file: @@ -2055,6 +2211,11 @@ static int hdmirx_remove(struct platform_device *pdev) device_remove_file(hdevp->dev, &dev_attr_esm_base); device_remove_file(hdevp->dev, &dev_attr_info); device_remove_file(hdevp->dev, &dev_attr_arc_aud_type); + device_remove_file(hdevp->dev, &dev_attr_ksvlist); + device_remove_file(hdevp->dev, &dev_attr_edid_dw); + device_remove_file(hdevp->dev, &dev_attr_hw_info); + device_remove_file(hdevp->dev, &dev_attr_hdcp_version); + device_remove_file(hdevp->dev, &dev_attr_reset22); tvin_unreg_frontend(&hdevp->frontend); hdmirx_delete_device(hdevp->index); tasklet_kill(&rx_tasklet); @@ -2071,7 +2232,8 @@ static int aml_hdcp22_pm_notify(struct notifier_block *nb, { int delay = 0; - if (event == PM_SUSPEND_PREPARE && hdcp22_on) { + if ((event == PM_SUSPEND_PREPARE) && hdcp22_on) { + rx_pr("PM_SUSPEND_PREPARE\n"); hdcp22_kill_esm = 1; /*wait time out ESM_KILL_WAIT_TIMES*20 ms*/ while (delay++ < ESM_KILL_WAIT_TIMES) { @@ -2079,10 +2241,15 @@ static int aml_hdcp22_pm_notify(struct notifier_block *nb, break; msleep(20); } - if (delay < ESM_KILL_WAIT_TIMES) + if (!hdcp22_kill_esm) rx_pr("hdcp22 kill ok!\n"); else rx_pr("hdcp22 kill timeout!\n"); + hdcp22_kill_esm = 0; + hdcp22_suspend(); + } else if ((event == PM_POST_SUSPEND) && hdcp22_on) { + rx_pr("PM_POST_SUSPEND\n"); + hdcp22_resume(); } return NOTIFY_OK; } @@ -2099,8 +2266,6 @@ static int hdmirx_suspend(struct platform_device *pdev, pm_message_t state) if (!early_suspend_flag) #endif rx_phy_suspend(); - if (hdcp22_on) - hdcp22_suspend(); rx_pr("hdmirx: suspend success\n"); return 0; } @@ -2116,8 +2281,7 @@ static int hdmirx_resume(struct platform_device *pdev) if (!early_suspend_flag) #endif rx_phy_resume(); - if (hdcp22_on) - hdcp22_resume(); + rx_pr("hdmirx: resume\n"); return 0; } 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 ee05f9e..0e6fb09 100644 --- a/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_drv.h +++ b/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_drv.h @@ -46,7 +46,7 @@ * * */ -#define RX_VER2 "ver.2018/09/06" +#define RX_VER2 "ver.2018/10/30" /*print type*/ #define LOG_EN 0x01 @@ -271,6 +271,8 @@ struct rx_video_info { * @short HDMI RX controller HDCP configuration */ struct hdmi_rx_hdcp { + /*hdcp auth state*/ + enum repeater_state_e state; /** Repeater mode else receiver only */ bool repeat; bool cascade_exceed; @@ -394,6 +396,7 @@ struct rx_s { bool boot_flag; bool open_fg; uint8_t irq_flag; + bool firm_change;/*hdcp2.2 rp/rx switch time*/ /** HDMI RX controller HDCP configuration */ struct hdmi_rx_hdcp hdcp; /*report hpd status to app*/ @@ -452,6 +455,7 @@ extern struct tasklet_struct rx_tasklet; extern struct device *hdmirx_dev; extern struct rx_s rx; extern struct reg_map reg_maps[MAP_ADDR_MODULE_NUM]; +extern bool downstream_repeat_support; extern void rx_tasklet_handler(unsigned long arg); extern void skip_frame(unsigned int cnt); @@ -509,6 +513,7 @@ bool hdmirx_repeat_support(void); /* edid-hdcp14 */ extern unsigned int edid_update_flag; +extern unsigned int downstream_hpd_flag; extern void hdmirx_fill_edid_buf(const char *buf, int size); extern unsigned int hdmirx_read_edid_buf(char *buf, int max_size); diff --git a/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_edid.c b/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_edid.c index 7a81a4d..c94ee5b 100644 --- a/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_edid.c +++ b/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_edid.c @@ -30,9 +30,9 @@ #include /* Local include */ +#include "hdmi_rx_repeater.h" #include "hdmi_rx_drv.h" #include "hdmi_rx_edid.h" -#include "hdmi_rx_repeater.h" #include "hdmi_rx_hw.h" static unsigned char edid_temp[EDID_SIZE]; @@ -810,7 +810,7 @@ void rx_edid_update_audio_info(unsigned char *p_edid, { if (p_edid == NULL) return; - rx_modify_edid(p_edid, len, rx_get_receiver_edid()); + rx_modify_edid(p_edid, len, rx_get_dw_edid_addr()); } unsigned int rx_edid_cal_phy_addr( diff --git a/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_eq.c b/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_eq.c index a5c5d7a..31bbcd3 100644 --- a/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_eq.c +++ b/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_eq.c @@ -36,6 +36,7 @@ #include #include /* Local include */ +#include "hdmi_rx_repeater.h" #include "hdmi_rx_eq.h" #include "hdmi_rx_drv.h" #include "hdmi_rx_hw.h" diff --git a/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_hw.c b/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_hw.c index 526ed63..7ac74de 100644 --- a/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_hw.c +++ b/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_hw.c @@ -38,6 +38,7 @@ #include /* Local include */ +#include "hdmi_rx_repeater.h" #include "hdmi_rx_drv.h" #include "hdmi_rx_hw.h" #include "hdmi_rx_edid.h" @@ -628,11 +629,14 @@ unsigned int rx_sec_reg_read(unsigned int *addr) /* * rx_sec_set_duk */ -unsigned int rx_sec_set_duk(void) +unsigned int rx_sec_set_duk(bool repeater) { struct arm_smccc_res res; - arm_smccc_smc(HDCP22_RX_SET_DUK_KEY, 0, 0, 0, 0, 0, 0, 0, &res); + if (repeater) + arm_smccc_smc(HDCP22_RP_SET_DUK_KEY, 0, 0, 0, 0, 0, 0, 0, &res); + else + arm_smccc_smc(HDCP22_RX_SET_DUK_KEY, 0, 0, 0, 0, 0, 0, 0, &res); return (unsigned int)((res.a0)&0xffffffff); } @@ -1561,7 +1565,7 @@ int rx_is_hdcp22_support(void) { int ret = 0; - if (rx_sec_set_duk() == 1) { + if (rx_sec_set_duk(hdmirx_repeat_support()) == 1) { rx_hdcp22_wr_top(TOP_SKP_CNTL_STAT, 7); ret = 1; } else @@ -2080,6 +2084,47 @@ void rx_hdcp_init(void) hdmirx_wr_bits_dwc(DWC_HDCP_CTRL, ENCRIPTION_ENABLE, 0); } +/*type 1 pull down hpd,reset hdcp2.2 + *type 2 only pull down hpd + */ +void hdmirx_load_firm_reset(int type) +{ + int ret = 0; + + rx_pr("%s\n", __func__); + rx_pr("3firm_change:%d,repeat_plug:%d,repeat:%d\n", + rx.firm_change, repeat_plug, rx.hdcp.repeat); + /*wait the fsm end*/ + rx.firm_change = 1; + msleep(20); + /*External_Mute(1);rx_aud_pll_ctl(0);*/ + rx_set_cur_hpd(0); + /*type 2 only pull down hpd*/ + if (type == 2) { + downstream_hpd_flag = 0; + fsm_restart(); + return; + } + if (!repeat_plug) + downstream_hpd_flag = 1; + else + downstream_hpd_flag = 0; + ret = rx_sec_set_duk(hdmirx_repeat_support()); + rx_pr("ret = %d\n", ret); + if (ret == 1) { + hdmirx_wr_dwc(DWC_HDCP22_CONTROL, 0x0); + hdmirx_hdcp22_esm_rst(); + mdelay(100); + hdmirx_wr_dwc(DWC_HDCP22_CONTROL, + 0x1000); + rx_hdcp22_wr_top(TOP_SKP_CNTL_STAT, 0x1); + fsm_restart(); + rx_is_hdcp22_support(); + } + rx_pr("4firm_change:%d,repeat_plug:%d,repeat:%d\n", + rx.firm_change, repeat_plug, rx.hdcp.repeat); +} + /* need reset bandgap when * aud_clk=0 & req_clk!=0 * according to analog team's request @@ -2670,7 +2715,7 @@ void rx_debug_load22key(void) int ret = 0; int wait_kill_done_cnt = 0; - ret = rx_sec_set_duk(); + ret = rx_sec_set_duk(hdmirx_repeat_support()); rx_pr("22 = %d\n", ret); if (ret == 1) { rx_pr("load 2.2 key\n"); diff --git a/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_hw.h b/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_hw.h index c56d304..6d982f8 100644 --- a/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_hw.h +++ b/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_hw.h @@ -1076,6 +1076,7 @@ #define HDCP22_RX_ESM_READ 0x8200001f #define HDCP22_RX_ESM_WRITE 0x8200002f #define HDCP22_RX_SET_DUK_KEY 0x8200002e +#define HDCP22_RP_SET_DUK_KEY 0x8200002c #define HDCP14_RX_SETKEY 0x8200002d enum hdcp14_key_mode_e { @@ -1154,11 +1155,12 @@ extern unsigned int sec_top_read(unsigned int *addr); extern void sec_top_write(unsigned int *addr, unsigned int value); extern void rx_esm_tmdsclk_en(bool en); extern int hdcp22_on; +extern int hdcp14_on; extern bool hdcp22_kill_esm; extern bool hpd_to_esm; extern void hdcp22_clk_en(bool en); extern void hdmirx_hdcp22_esm_rst(void); -extern unsigned int rx_sec_set_duk(void); +extern unsigned int rx_sec_set_duk(bool repeater); extern void hdmirx_hdcp22_init(void); extern void hdcp22_suspend(void); extern void hdcp22_resume(void); @@ -1166,8 +1168,8 @@ extern void hdmirx_hdcp22_hpd(bool value); extern void esm_set_reset(bool reset); extern void esm_set_stable(bool stable); extern void rx_hpd_to_esm_handle(struct work_struct *work); - - +extern void rx_hdcp14_resume(void); +extern void hdmirx_load_firm_reset(int type); extern unsigned int hdmirx_packet_fifo_rst(void); extern unsigned int hdmirx_audio_fifo_rst(void); extern void hdmirx_phy_init(void); diff --git a/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_pktinfo.c b/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_pktinfo.c index dcaafe1..d0ba34c 100644 --- a/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_pktinfo.c +++ b/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_pktinfo.c @@ -30,6 +30,7 @@ #include /* Local include */ +#include "hdmi_rx_repeater.h" #include "hdmi_rx_pktinfo.h" #include "hdmi_rx_drv.h" #include "hdmi_rx_hw.h" diff --git a/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_repeater.c b/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_repeater.c index 47bff53..e3a1e3d76 100644 --- a/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_repeater.c +++ b/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_repeater.c @@ -37,9 +37,9 @@ #include /* Local include */ +#include "hdmi_rx_repeater.h" #include "hdmi_rx_drv.h" #include "hdmi_rx_hw.h" -#include "hdmi_rx_repeater.h" #include "hdmi_rx_wrapper.h" #include "hdmi_rx_edid.h" /*edid original data from device*/ @@ -47,6 +47,9 @@ static unsigned char receive_edid[MAX_RECEIVE_EDID]; int receive_edid_len = MAX_RECEIVE_EDID; MODULE_PARM_DESC(receive_edid, "\n receive_edid\n"); module_param_array(receive_edid, byte, &receive_edid_len, 0664); +int edid_len; +MODULE_PARM_DESC(edid_len, "\n edid_len\n"); +module_param(edid_len, int, 0664); bool new_edid; /*original bksv from device*/ static unsigned char receive_hdcp[MAX_KSV_LIST_SIZE]; @@ -56,77 +59,79 @@ module_param_array(receive_hdcp, byte, &hdcp_array_len, 0664); int hdcp_len; int hdcp_repeat_depth; bool new_hdcp; -bool repeat_plug; -int up_phy_addr;/*d c b a 4bit*/ +bool start_auth_14; +MODULE_PARM_DESC(start_auth_14, "\n start_auth_14\n"); +module_param(start_auth_14, bool, 0664); -bool downstream_rp_en; +bool repeat_plug; +MODULE_PARM_DESC(repeat_plug, "\n repeat_plug\n"); +module_param(repeat_plug, bool, 0664); -enum repeater_state_e rpt_state; +int up_phy_addr;/*d c b a 4bit*/ +MODULE_PARM_DESC(up_phy_addr, "\n up_phy_addr\n"); +module_param(up_phy_addr, int, 0664); +int hdcp22_firm_switch_timeout; -bool hdmirx_repeat_support(void) +unsigned char *rx_get_dw_hdcp_addr(void) { - return downstream_rp_en; + return receive_hdcp; } void rx_start_repeater_auth(void) { - rpt_state = REPEATER_STATE_START; + rx.hdcp.state = REPEATER_STATE_START; + start_auth_14 = 1; rx.hdcp.delay = 0; hdcp_len = 0; hdcp_repeat_depth = 0; rx.hdcp.dev_exceed = 0; rx.hdcp.cascade_exceed = 0; + rx.hdcp.depth = 0; + rx.hdcp.count = 0; memset(&receive_hdcp, 0, sizeof(receive_hdcp)); } -void repeater_dwork_handle(struct work_struct *work) -{ - if (hdmirx_repeat_support()) { - if (rx.hdcp.hdcp_version && hdmirx_is_key_write() - && rx.open_fg) { - extcon_set_state_sync(rx.hdcp.rx_excton_auth, - EXTCON_DISP_HDMI, 0); - extcon_set_state_sync(rx.hdcp.rx_excton_auth, - EXTCON_DISP_HDMI, rx.hdcp.hdcp_version); - } - } -} - -bool hdmirx_is_key_write(void) -{ - if (hdmirx_rd_dwc(DWC_HDCP_BKSV0) != 0) - return 1; - else - return 0; -} - void rx_check_repeat(void) { + struct hdcp14_topo_s *topo_data = (struct hdcp14_topo_s *)receive_hdcp; + if (!hdmirx_repeat_support()) return; if (rx.hdcp.repeat != repeat_plug) { + /*pull down hpd if downstream plug low*/ + rx_set_cur_hpd(0); + rx_pr("firm_change:%d,repeat_plug:%d,repeat:%d\n", + rx.firm_change, repeat_plug, rx.hdcp.repeat); rx_set_repeat_signal(repeat_plug); if (!repeat_plug) { - hdcp_len = 0; - hdcp_repeat_depth = 0; + edid_len = 0; rx.hdcp.dev_exceed = 0; rx.hdcp.cascade_exceed = 0; memset(&receive_hdcp, 0, sizeof(receive_hdcp)); - new_edid = true; memset(&receive_edid, 0, sizeof(receive_edid)); - rx_send_hpd_pulse(); + up_phy_addr = 0; + /*new_edid = true;*/ + /* rx_set_cur_hpd(1); */ + /*rx.firm_change = 0;*/ + rx_pr("1firm_change:%d,repeat_plug:%d,repeat:%d\n", + rx.firm_change, repeat_plug, rx.hdcp.repeat); } } - if (new_edid) { + + /*this is addition for the downstream edid too late*/ + if (new_edid && rx.hdcp.repeat && (!rx.firm_change)) { /*check downstream plug when new plug occur*/ /*check receive change*/ + /*it's contained in hwconfig*/ hdmi_rx_top_edid_update(); + hdcp22_firm_switch_timeout = 0; new_edid = false; rx_send_hpd_pulse(); } + if (repeat_plug) { - switch (rpt_state) { + switch (rx.hdcp.state) { case REPEATER_STATE_START: rx_pr("[RX] receive aksv\n"); hdmirx_wr_bits_dwc(DWC_HDCP_RPT_CTRL, @@ -135,12 +140,16 @@ void rx_check_repeat(void) KSVLIST_LOSTAUTH, 0); hdmirx_wr_bits_dwc(DWC_HDCP_RPT_CTRL, KSVLIST_READY, 0); - rpt_state = REPEATER_STATE_WAIT_KSV; + hdmirx_wr_bits_dwc(DWC_HDCP_RPT_BSTATUS, + MAX_CASCADE_EXCEEDED, 0); + hdmirx_wr_bits_dwc(DWC_HDCP_RPT_BSTATUS, + MAX_DEVS_EXCEEDED, 0); + rx.hdcp.state = REPEATER_STATE_WAIT_KSV; break; case REPEATER_STATE_WAIT_KSV: if (!rx.cur_5v_sts) { - rpt_state = REPEATER_STATE_IDLE; + rx.hdcp.state = REPEATER_STATE_IDLE; break; } if (hdmirx_rd_bits_dwc(DWC_HDCP_RPT_CTRL, WAITING_KSV)) { @@ -152,13 +161,14 @@ void rx_check_repeat(void) } else if (rx.hdcp.delay >= KSV_LIST_WAIT_DELAY) { hdmirx_wr_bits_dwc(DWC_HDCP_RPT_CTRL, KSVLIST_TIMEOUT, 1); - rpt_state = REPEATER_STATE_IDLE; + rx.hdcp.state = REPEATER_STATE_IDLE; rx_pr("[RX] receive ksv wait timeout\n"); } - if (rx_set_repeat_aksv(receive_hdcp, hdcp_len, - hdcp_repeat_depth, rx.hdcp.dev_exceed, - rx.hdcp.cascade_exceed)) { - rpt_state = REPEATER_STATE_IDLE; + if (rx_set_repeat_aksv(topo_data->ksv_list, + topo_data->device_count, + topo_data->depth, topo_data->max_devs_exceeded, + topo_data->max_cascade_exceeded)) { + rx.hdcp.state = REPEATER_STATE_IDLE; } } /*if support hdcp2.2 jump to wait_ack else to idle*/ @@ -184,27 +194,58 @@ void rx_check_repeat(void) /*}*/ } -unsigned char *rx_get_receiver_edid(void) +void rx_reload_firm_reset(int reset) +{ + if (reset) + hdmirx_load_firm_reset(reset); + else + rx_firm_reset_end(); +} + +void rx_firm_reset_end(void) +{ + rx_pr("%s new_edid:%d\n", __func__, new_edid); + if (new_edid) { + new_edid = 0; + hdmi_rx_top_edid_update(); + } + rx.firm_change = 0; +} +unsigned char *rx_get_dw_edid_addr(void) { return receive_edid; } -int rx_set_receiver_edid(unsigned char *data, int len) +int rx_set_receiver_edid(const char *data, int len) { - if ((data == NULL) || (len == 0) || (len > MAX_RECEIVE_EDID)) + if ((data == NULL) || (len == 0)) return false; - memset(receive_edid, 0, sizeof(receive_edid)); - if ((len > 0) && (*data != 0)) + if ((len > MAX_RECEIVE_EDID) || (len < 3)) { + memset(receive_edid, 0, sizeof(receive_edid)); + edid_len = 0; + } else { memcpy(receive_edid, data, len); + edid_len = len; + } new_edid = true; return true; } -EXPORT_SYMBOL(rx_set_receiver_edid); + +void rx_hdcp14_resume(void) +{ + hdcp22_kill_esm = 0; + extcon_set_state_sync(rx.rx_excton_rx22, EXTCON_DISP_HDMI, 0); + hdmirx_wr_dwc(DWC_HDCP22_CONTROL, + 0x1000); + extcon_set_state_sync(rx.rx_excton_rx22, EXTCON_DISP_HDMI, 1); + hpd_to_esm = 1; + rx_pr("hdcp14 on\n"); +} void rx_set_repeater_support(bool enable) { - downstream_rp_en = enable; + downstream_repeat_support = enable; } EXPORT_SYMBOL(rx_set_repeater_support); @@ -224,7 +265,8 @@ bool rx_poll_dwc(uint16_t addr, uint32_t exp_data, rd_data = hdmirx_rd_dwc(addr); } } - rx_pr("poll dwc cnt :%d\n", cnt); + if (log_level & VIDEO_LOG) + rx_pr("poll dwc cnt :%d\n", cnt); if (done == 0) { /* if(log_level & ERR_LOG) */ rx_pr("poll dwc%x time-out!\n", addr); @@ -237,9 +279,13 @@ bool rx_set_repeat_aksv(unsigned char *data, int len, int depth, bool dev_exceed, bool cascade_exceed) { int i; - /*rx_pr("set ksv list len:%d,depth:%d\n", len, depth);*/ - if ((len == 0) || (data == 0) || (depth == 0)) + bool ksvlist_ready = 0; + + if ((data == 0) || (((depth == 0) || (len == 0)) + && (!dev_exceed) && (!cascade_exceed))) return false; + rx_pr("set ksv list len:%d,depth:%d, exceed count:%d,cascade:%d\n", + len, depth, dev_exceed, cascade_exceed); /*set repeat depth*/ if ((depth <= MAX_REPEAT_DEPTH) && (!cascade_exceed)) { hdmirx_wr_bits_dwc(DWC_HDCP_RPT_BSTATUS, MAX_CASCADE_EXCEEDED, @@ -249,9 +295,10 @@ bool rx_set_repeat_aksv(unsigned char *data, int len, int depth, } else { hdmirx_wr_bits_dwc(DWC_HDCP_RPT_BSTATUS, MAX_CASCADE_EXCEEDED, 1); + rx.hdcp.depth = 0; } /*set repeat count*/ - if ((len <= MAX_REPEAT_COUNT) && (!dev_exceed)) { + if ((len <= HDCP14_KSV_MAX_COUNT) && (!dev_exceed)) { hdmirx_wr_bits_dwc(DWC_HDCP_RPT_BSTATUS, MAX_DEVS_EXCEEDED, 0); rx.hdcp.count = len; @@ -260,15 +307,19 @@ bool rx_set_repeat_aksv(unsigned char *data, int len, int depth, } else { hdmirx_wr_bits_dwc(DWC_HDCP_RPT_BSTATUS, MAX_DEVS_EXCEEDED, 1); + rx.hdcp.count = 0; } /*set repeat status*/ - if (rx.hdcp.count > 0) { - rx.hdcp.repeat = true; - hdmirx_wr_bits_dwc(DWC_HDCP_RPT_CTRL, REPEATER, 1); - } else { - rx.hdcp.repeat = false; - hdmirx_wr_bits_dwc(DWC_HDCP_RPT_CTRL, REPEATER, 0); - } + /* if (rx.hdcp.count > 0) { + * rx.hdcp.repeat = true; + * hdmirx_wr_bits_dwc(DWC_HDCP_RPT_CTRL, REPEATER, 1); + *} else { + * rx.hdcp.repeat = false; + * hdmirx_wr_bits_dwc(DWC_HDCP_RPT_CTRL, REPEATER, 0); + *} + */ + ksvlist_ready = ((rx.hdcp.count > 0) && (rx.hdcp.depth > 0)); + rx_pr("[RX]write ksv list count:%d\n", rx.hdcp.count); /*write ksv list to fifo*/ for (i = 0; i < rx.hdcp.count; i++) { if (rx_poll_dwc(DWC_HDCP_RPT_CTRL, ~KSV_HOLD, KSV_HOLD, @@ -279,10 +330,11 @@ bool rx_set_repeat_aksv(unsigned char *data, int len, int depth, *(data + i*MAX_KSV_SIZE + 4)); hdmirx_wr_dwc(DWC_HDCP_RPT_KSVFIFO0, *((uint32_t *)(data + i*MAX_KSV_SIZE))); - rx_pr( - "[RX]write ksv list index:%d, ksv hi:%#x, low:%#x\n", + if (log_level & VIDEO_LOG) + rx_pr( + "[RX]write ksv list index:%d, ksv hi:%#x, low:%#x\n", i, *(data + i*MAX_KSV_SIZE + - 4), *((uint32_t *)(data + i*MAX_KSV_SIZE))); + 4), *((uint32_t *)(data + i*MAX_KSV_SIZE))); } else { return false; } @@ -290,11 +342,12 @@ bool rx_set_repeat_aksv(unsigned char *data, int len, int depth, /* Wait for ksv_hold=0*/ rx_poll_dwc(DWC_HDCP_RPT_CTRL, ~KSV_HOLD, KSV_HOLD, KSV_LIST_WR_TH); /*set ksv list ready*/ - hdmirx_wr_bits_dwc(DWC_HDCP_RPT_CTRL, KSVLIST_READY, - (rx.hdcp.count > 0)); + hdmirx_wr_bits_dwc(DWC_HDCP_RPT_CTRL, KSVLIST_READY, ksvlist_ready); /* Wait for HW completion of V value*/ - rx_poll_dwc(DWC_HDCP_RPT_CTRL, FIFO_READY, FIFO_READY, KSV_V_WR_TH); - rx_pr("[RX]write Ready signal!\n"); + if (ksvlist_ready) + rx_poll_dwc(DWC_HDCP_RPT_CTRL, FIFO_READY, + FIFO_READY, KSV_V_WR_TH); + rx_pr("[RX]write Ready signal!\n", ksvlist_ready); return true; } @@ -308,35 +361,17 @@ void rx_set_repeat_signal(bool repeat) bool rx_set_receive_hdcp(unsigned char *data, int len, int depth, bool cas_exceed, bool devs_exceed) { - if ((data != 0) && (len != 0) && (len <= MAX_REPEAT_COUNT)) - memcpy(receive_hdcp, data, len*MAX_KSV_SIZE); - rx_pr("receive ksv list len:%d,depth:%d,cas:%d,dev:%d\n", len, - depth, cas_exceed, devs_exceed); - hdcp_len = len; - hdcp_repeat_depth = depth; - rx.hdcp.cascade_exceed = cas_exceed; - rx.hdcp.dev_exceed = devs_exceed; - return true; } EXPORT_SYMBOL(rx_set_receive_hdcp); void rx_repeat_hpd_state(bool plug) { - repeat_plug = plug; } EXPORT_SYMBOL(rx_repeat_hpd_state); -void rx_repeat_hdcp_ver(int version) -{ - -} -EXPORT_SYMBOL(rx_repeat_hdcp_ver); - void rx_edid_physical_addr(int a, int b, int c, int d) { - up_phy_addr = ((d & 0xf) << 12) | ((c & 0xf) << 8) | ((b & - 0xf) << 4) | (a & 0xf); } EXPORT_SYMBOL(rx_edid_physical_addr); diff --git a/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_repeater.h b/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_repeater.h index 82340b4..da190fb 100644 --- a/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_repeater.h +++ b/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_repeater.h @@ -19,11 +19,12 @@ #define __HDMIRX_REPEATER__ /* EDID */ -#define MAX_RECEIVE_EDID 33 +#define MAX_RECEIVE_EDID 40/*33*/ +#define MAX_HDR_LUMI 3 #define MAX_KSV_SIZE 5 -#define MAX_REPEAT_COUNT 127 #define MAX_REPEAT_DEPTH 7 -#define MAX_KSV_LIST_SIZE (MAX_KSV_SIZE*MAX_REPEAT_COUNT) +#define MAX_KSV_LIST_SIZE sizeof(struct hdcp14_topo_s) +#define HDCP14_KSV_MAX_COUNT 127 #define DETAILED_TIMING_LEN 18 /*size of one format in edid*/ #define FORMAT_SIZE sizeof(struct edid_audio_block_t) @@ -45,6 +46,22 @@ enum repeater_state_e { REPEATER_STATE_START, }; +struct hdcp14_topo_s { + unsigned char max_cascade_exceeded:1; + unsigned char depth:3; + unsigned char max_devs_exceeded:1; + unsigned char device_count:7; /* 1 ~ 127 */ + unsigned char ksv_list[HDCP14_KSV_MAX_COUNT * 5]; +}; + +struct hdcp_hw_info_s { + unsigned int cur_5v:4; + unsigned int open:4; + unsigned int frame_rate:8; + unsigned int signal_stable:1; + unsigned int reseved:15; +}; + extern int receive_edid_len; extern bool new_edid; extern int hdcp_array_len; @@ -53,15 +70,14 @@ extern int hdcp_repeat_depth; extern bool new_hdcp; extern bool repeat_plug; extern int up_phy_addr;/*d c b a 4bit*/ -extern bool downstream_rp_en; -void rx_set_repeater_support(bool enable); -extern int rx_set_receiver_edid(unsigned char *data, int len); +extern void rx_set_repeater_support(bool enable); +extern int rx_set_receiver_edid(const char *data, int len); extern void rx_start_repeater_auth(void); extern void rx_set_repeat_signal(bool repeat); extern bool rx_set_repeat_aksv(unsigned char *data, int len, int depth, bool dev_exceed, bool cascade_exceed); -extern unsigned char *rx_get_receiver_edid(void); +extern unsigned char *rx_get_dw_edid_addr(void); extern void repeater_dwork_handle(struct work_struct *work); bool rx_set_receive_hdcp(unsigned char *data, int len, int depth, bool cas_exceed, bool devs_exceed); @@ -69,7 +85,10 @@ void rx_repeat_hpd_state(bool plug); void rx_repeat_hdcp_ver(int version); void rx_check_repeat(void); extern bool hdmirx_is_key_write(void); - +extern void rx_reload_firm_reset(int reset); +extern void rx_firm_reset_end(void); +extern unsigned char *rx_get_dw_hdcp_addr(void); +extern unsigned char *rx_get_dw_edid_addr(void); #endif diff --git a/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_wrapper.c b/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_wrapper.c index ecf4640..3429e37 100644 --- a/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_wrapper.c +++ b/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_wrapper.c @@ -37,12 +37,12 @@ #include /* Local include */ +#include "hdmi_rx_repeater.h" #include "hdmi_rx_drv.h" #include "hdmi_rx_hw.h" #include "hdmi_rx_eq.h" #include "hdmi_rx_wrapper.h" #include "hdmi_rx_pktinfo.h" -#include "hdmi_rx_repeater.h" #include "hdmi_rx_edid.h" static int pll_unlock_cnt; @@ -171,6 +171,10 @@ static bool mute_kill_en; MODULE_PARM_DESC(mute_kill_en, "\n mute_kill_en\n"); module_param(mute_kill_en, bool, 0664); +int hdcp14_on; +MODULE_PARM_DESC(hdcp14_on, "\n hdcp14_on\n"); +module_param(hdcp14_on, int, 0664); + /*esm recovery mode for changing resolution & hdmi2.0*/ static int esm_recovery_mode = ESM_REC_MODE_TMDS; module_param(esm_recovery_mode, int, 0664); @@ -190,6 +194,7 @@ static int edid_update_delay = 150; int skip_frame_cnt = 1; static bool hdcp22_reauth_enable; unsigned int edid_update_flag; +unsigned int downstream_hpd_flag; static bool hdcp22_stop_auth_enable; static bool hdcp22_esm_reset2_enable; int sm_pause; @@ -355,11 +360,8 @@ static int hdmi_rx_ctrl_irq_handler(void) /*if (log_level & HDCP_LOG)*/ rx_pr("[*aksv*\n"); rx.hdcp.hdcp_version = HDCP_VER_14; - if (hdmirx_repeat_support()) { - queue_delayed_work(repeater_wq, &repeater_dwork, - msecs_to_jiffies(5)); + if (hdmirx_repeat_support()) rx_start_repeater_auth(); - } } } @@ -1421,8 +1423,9 @@ void dump_unnormal_info(void) void rx_send_hpd_pulse(void) { - rx_set_cur_hpd(0); - fsm_restart(); + /*rx_set_cur_hpd(0);*/ + /*fsm_restart();*/ + rx.state = FSM_HPD_LOW; } static void set_hdcp(struct hdmi_rx_hdcp *hdcp, const unsigned char *b_key) @@ -1470,6 +1473,8 @@ void hdmirx_fill_key_buf(const char *buf, int size) //key_size = size; //rx_pr("HDMIRX: fill key buf, size %d\n", size); } + hdcp14_on = 1; + rx_pr("HDMIRX: fill key buf, hdcp14_on %d\n", hdcp14_on); } /* @@ -1672,8 +1677,8 @@ int rx_set_global_variable(const char *buf, int size) return pr_var(dv_nopacket_timeout, index); if (set_pr_var(tmpbuf, delay_ms_cnt, value, &index, ret)) return pr_var(delay_ms_cnt, index); - if (set_pr_var(tmpbuf, downstream_rp_en, value, &index, ret)) - return pr_var(downstream_rp_en, index); + if (set_pr_var(tmpbuf, downstream_repeat_support, value, &index, ret)) + return pr_var(downstream_repeat_support, index); if (set_pr_var(tmpbuf, eq_max_setting, value, &index, ret)) return pr_var(eq_max_setting, index); if (set_pr_var(tmpbuf, eq_dbg_ch0, value, &index, ret)) @@ -1798,7 +1803,7 @@ void rx_get_global_variable(const char *buf) pr_var(hdcp22_on, i++); pr_var(dv_nopacket_timeout, i++); pr_var(delay_ms_cnt, i++); - pr_var(downstream_rp_en, i++); + pr_var(downstream_repeat_support, i++); pr_var(eq_max_setting, i++); pr_var(eq_dbg_ch0, i++); pr_var(eq_dbg_ch1, i++); @@ -1952,6 +1957,7 @@ void rx_5v_monitor(void) rx.cur_5v_sts = (pwr_sts >> rx.port) & 1; hotplug_wait_query(); if (rx.cur_5v_sts == 0) { + /*External_Mute(1);*/ #ifdef USE_NEW_FSM_METHODE set_fsm_state(FSM_5V_LOST); rx.err_code = ERR_5V_LOST; @@ -2101,12 +2107,18 @@ void rx_main_state_machine(void) case FSM_HPD_HIGH: hpd_wait_cnt++; if (rx_get_cur_hpd_sts() == 0) { - if (hpd_wait_cnt <= hpd_wait_max) - break; + if (downstream_hpd_flag) { + if (hpd_wait_cnt <= hpd_wait_max*5) + break; + } else { + if (hpd_wait_cnt <= hpd_wait_max) + break; + } } hpd_wait_cnt = 0; clk_unstable_cnt = 0; esd_phy_rst_cnt = 0; + downstream_hpd_flag = 0; pre_port = rx.port; rx_set_cur_hpd(1); set_scdc_cfg(0, 1); @@ -2339,6 +2351,7 @@ void rx_main_state_machine(void) rx.aud_sr_unstable_cnt++; if (rx.aud_sr_unstable_cnt > aud_sr_stb_max) { unsigned int aud_sts = rx_get_aud_pll_err_sts(); + if (aud_sts == E_REQUESTCLK_ERR) { hdmirx_phy_init(); rx.state = FSM_WAIT_CLK_STABLE; @@ -2381,9 +2394,6 @@ void rx_main_state_machine(void) if (log_level & VIDEO_LOG) rx_esm_exception_monitor();/* only for debug */ - if ((hdcp22_on) && (rx.state > FSM_SIG_UNSTABLE)) { - /*monitor_hdcp22_sts();*/ - } switch (rx.state) { case FSM_HPD_LOW: @@ -3025,7 +3035,7 @@ int hdmirx_debug(const char *buf, int size) } else if (strncmp(tmpbuf, "reg", 3) == 0) { dump_reg(); } else if (strncmp(tmpbuf, "duk", 3) == 0) { - rx_pr("hdcp22=%d\n", rx_sec_set_duk()); + rx_pr("hdcp22=%d\n", rx_sec_set_duk(hdmirx_repeat_support())); } else if (strncmp(tmpbuf, "edid", 4) == 0) { dump_edid_reg(); } else if (strncmp(tmpbuf, "load14key", 7) == 0) { @@ -3080,6 +3090,8 @@ int hdmirx_debug(const char *buf, int size) rx_pr("error input Value\n"); rx_pr("set pkt cnt:0x%x\n", value); rx.empbuff.emppktcnt = value; + } else if (strncmp(tmpbuf, "audio", 5) == 0) { + hdmirx_audio_fifo_rst(); } return 0; @@ -3092,14 +3104,16 @@ void hdmirx_timer_handler(unsigned long arg) rx_5v_monitor(); rx_check_repeat(); if (rx.open_fg) { - if (!sm_pause) - rx_main_state_machine(); rx_nosig_monitor(); - rx_pkt_check_content(); - #ifdef USE_NEW_FSM_METHODE - rx_err_monitor(); - rx_clkrate_monitor(); - #endif + if (!hdmirx_repeat_support() || !rx.firm_change) { + if (!sm_pause) + rx_main_state_machine(); + rx_pkt_check_content(); + #ifdef USE_NEW_FSM_METHODE + rx_err_monitor(); + rx_clkrate_monitor(); + #endif + } } devp->timer.expires = jiffies + TIMER_STATE_CHECK; add_timer(&devp->timer);