mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 11:26:02 +09:00
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 <hongmin.hua@amlogic.com>
This commit is contained in:
@@ -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;
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#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"
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -30,9 +30,9 @@
|
||||
#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];
|
||||
@@ -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(
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
#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"
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
#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"
|
||||
@@ -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");
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#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"
|
||||
|
||||
@@ -37,9 +37,9 @@
|
||||
#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*/
|
||||
@@ -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 start_auth_14;
|
||||
MODULE_PARM_DESC(start_auth_14, "\n start_auth_14\n");
|
||||
module_param(start_auth_14, bool, 0664);
|
||||
|
||||
bool repeat_plug;
|
||||
MODULE_PARM_DESC(repeat_plug, "\n repeat_plug\n");
|
||||
module_param(repeat_plug, bool, 0664);
|
||||
|
||||
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 downstream_rp_en;
|
||||
|
||||
enum repeater_state_e rpt_state;
|
||||
|
||||
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);
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -37,12 +37,12 @@
|
||||
#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;
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user