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;
if (copy_from_user(esm->code, &arg->data, head.len) != 0)
return -EFAULT;
- esm->code_loaded = 1;
+ /* esm->code_loaded = 1; */
return 0;
}
}
static struct dentry *esm_debugfs;
-static struct dentry *esm_blob;
+/*static struct dentry *esm_blob;*/
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);
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;
}
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)
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;
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;
#include <linux/debugfs.h>
#include <linux/version.h>
#include "hdcp_rx_main.h"
+#include "hdmi_rx_repeater.h"
#include "hdmi_rx_drv.h"
#include "hdmi_rx_hw.h"
#endif
/* Local include */
+#include "hdmi_rx_repeater.h"
#include "hdmi_rx_drv.h"
#include "hdmi_rx_wrapper.h"
#include "hdmi_rx_hw.h"
#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);
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);
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
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) {
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,
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);
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,
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__);
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);
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:
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);
{
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) {
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;
}
if (!early_suspend_flag)
#endif
rx_phy_suspend();
- if (hdcp22_on)
- hdcp22_suspend();
rx_pr("hdmirx: suspend success\n");
return 0;
}
if (!early_suspend_flag)
#endif
rx_phy_resume();
- if (hdcp22_on)
- hdcp22_resume();
+
rx_pr("hdmirx: resume\n");
return 0;
}
*
*
*/
-#define RX_VER2 "ver.2018/09/06"
+#define RX_VER2 "ver.2018/10/30"
/*print type*/
#define LOG_EN 0x01
* @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;
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*/
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);
/* 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);
#include <linux/cdev.h>
/* 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];
{
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(
#include <linux/delay.h>
#include <linux/amlogic/media/frame_provider/tvin/tvin.h>
/* Local include */
+#include "hdmi_rx_repeater.h"
#include "hdmi_rx_eq.h"
#include "hdmi_rx_drv.h"
#include "hdmi_rx_hw.h"
#include <linux/arm-smccc.h>
/* Local include */
+#include "hdmi_rx_repeater.h"
#include "hdmi_rx_drv.h"
#include "hdmi_rx_hw.h"
#include "hdmi_rx_edid.h"
/*
* 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);
}
{
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
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
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");
#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 {
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);
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);
#include <linux/cdev.h>
/* Local include */
+#include "hdmi_rx_repeater.h"
#include "hdmi_rx_pktinfo.h"
#include "hdmi_rx_drv.h"
#include "hdmi_rx_hw.h"
#include <linux/amlogic/media/frame_provider/tvin/tvin.h>
/* 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*/
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];
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,
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)) {
} 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*/
/*}*/
}
-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);
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);
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,
} 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;
} 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,
*(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;
}
/* 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;
}
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);
#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)
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;
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);
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
#include <linux/amlogic/media/frame_provider/tvin/tvin.h>
/* 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;
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);
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;
/*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();
- }
}
}
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)
//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);
}
/*
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))
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++);
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;
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);
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;
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:
} 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) {
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;
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);