mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-09 04:10:18 +09:00
rk3036 hdmi: update hdcp coding style
This commit is contained in:
@@ -16,8 +16,7 @@ static void hdcp_work_queue(struct work_struct *work);
|
||||
|
||||
#define AUTH_TIMEOUT (2*HZ)
|
||||
static struct timer_list auth_timer;
|
||||
static int timer_state = 0;
|
||||
extern int is_1b_03_test(void);
|
||||
static int timer_state;
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
* Function: hdcp_submit_work
|
||||
@@ -27,9 +26,8 @@ static struct delayed_work *hdcp_submit_work(int event, int delay)
|
||||
{
|
||||
struct hdcp_delayed_work *work;
|
||||
|
||||
DBG("%s event %04x delay %d", __FUNCTION__, event, delay);
|
||||
|
||||
work = kmalloc(sizeof(struct hdcp_delayed_work), GFP_ATOMIC);
|
||||
DBG("%s event %04x delay %d\n", __func__, event, delay);
|
||||
work = kmalloc(sizeof(*work), GFP_ATOMIC);
|
||||
|
||||
if (work) {
|
||||
INIT_DELAYED_WORK(&work->work, hdcp_work_queue);
|
||||
@@ -38,8 +36,7 @@ static struct delayed_work *hdcp_submit_work(int event, int delay)
|
||||
&work->work,
|
||||
msecs_to_jiffies(delay));
|
||||
} else {
|
||||
printk(KERN_WARNING "HDCP: Cannot allocate memory to "
|
||||
"create work\n");
|
||||
HDCP_WARN("HDCP:Cannot allocate memory to create work\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -58,8 +55,7 @@ static void hdcp_cancel_work(struct delayed_work **work)
|
||||
ret = cancel_delayed_work(*work);
|
||||
if (ret != 1) {
|
||||
ret = cancel_work_sync(&((*work)->work));
|
||||
printk(KERN_INFO "Canceling work failed - "
|
||||
"cancel_work_sync done %d\n", ret);
|
||||
HDCP_WARN("Canceling sync work failed %d\n", ret);
|
||||
}
|
||||
kfree(*work);
|
||||
*work = 0;
|
||||
@@ -72,17 +68,16 @@ static void hdcp_cancel_work(struct delayed_work **work)
|
||||
*/
|
||||
static void auth_timer_func(unsigned long data)
|
||||
{
|
||||
printk(KERN_INFO "hdcp auth 2 second timeout\n");
|
||||
if(hdcp->auth_state == 0) {
|
||||
mod_timer(&auth_timer, jiffies + AUTH_TIMEOUT);
|
||||
if ((hdcp->hdcp_state != HDCP_DISABLED) &&
|
||||
(hdcp->hdcp_state != HDCP_ENABLE_PENDING)) {
|
||||
HDCP_WARN("hdcp auth 2 second timeout\n");
|
||||
if (hdcp->auth_state == 0) {
|
||||
mod_timer(&auth_timer, jiffies + AUTH_TIMEOUT);
|
||||
if ((hdcp->hdcp_state != HDCP_DISABLED) &&
|
||||
(hdcp->hdcp_state != HDCP_ENABLE_PENDING)) {
|
||||
if (is_1b_03_test())
|
||||
return;
|
||||
|
||||
hdcp_submit_work(HDCP_FAIL_EVENT, 0);
|
||||
}
|
||||
}
|
||||
hdcp_submit_work(HDCP_FAIL_EVENT, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
@@ -91,27 +86,22 @@ static void auth_timer_func(unsigned long data)
|
||||
*/
|
||||
static void hdcp_wq_authentication_failure(void)
|
||||
{
|
||||
if (hdcp->hdmi_state == HDMI_STOPPED) {
|
||||
if (hdcp->hdmi_state == HDMI_STOPPED)
|
||||
return;
|
||||
}
|
||||
|
||||
rk3036_hdcp_disable();
|
||||
/*
|
||||
rk3036_hdmi_control_output(false);
|
||||
*/
|
||||
rk3036_set_colorbar(1);
|
||||
|
||||
rk3036_set_colorbar(1);
|
||||
hdcp_cancel_work(&hdcp->pending_wq_event);
|
||||
|
||||
if (hdcp->retry_cnt && (hdcp->hdmi_state != HDMI_STOPPED)) {
|
||||
if (hdcp->retry_cnt <= HDCP_INFINITE_REAUTH) {
|
||||
hdcp->retry_cnt--;
|
||||
printk(KERN_INFO "HDCP: authentication failed - "
|
||||
"retrying, attempts=%d\n",
|
||||
hdcp->retry_cnt);
|
||||
HDCP_WARN("authentication failed attempts=%d\n",
|
||||
hdcp->retry_cnt);
|
||||
} else
|
||||
printk(KERN_INFO "HDCP: authentication failed - "
|
||||
"retrying\n");
|
||||
HDCP_WARN("authentication failed retrying\n");
|
||||
|
||||
hdcp->hdcp_state = HDCP_AUTHENTICATION_START;
|
||||
|
||||
@@ -127,8 +117,7 @@ static void hdcp_wq_authentication_failure(void)
|
||||
hdcp->pending_wq_event = hdcp_submit_work(HDCP_AUTH_REATT_EVENT,
|
||||
HDCP_REAUTH_DELAY);
|
||||
} else {
|
||||
printk(KERN_INFO "HDCP: authentication failed - "
|
||||
"HDCP disabled\n");
|
||||
HDCP_WARN("authentication failed HDCP disabled\n");
|
||||
hdcp->hdcp_state = HDCP_ENABLE_PENDING;
|
||||
|
||||
if (timer_state == 1) {
|
||||
@@ -137,7 +126,6 @@ static void hdcp_wq_authentication_failure(void)
|
||||
timer_state = 0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
@@ -149,16 +137,13 @@ static void hdcp_wq_start_authentication(void)
|
||||
int status = HDCP_OK;
|
||||
|
||||
hdcp->hdcp_state = HDCP_AUTHENTICATION_START;
|
||||
|
||||
DBG("HDCP: authentication start");
|
||||
|
||||
DBG("HDCP: authentication start\n");
|
||||
status = rk3036_hdcp_start_authentication();
|
||||
|
||||
if (status != HDCP_OK) {
|
||||
DBG("HDCP: authentication failed");
|
||||
DBG("HDCP: authentication failed\n");
|
||||
hdcp_wq_authentication_failure();
|
||||
} else {
|
||||
// hdcp->hdcp_state = HDCP_WAIT_KSV_LIST;
|
||||
/*hdcp->hdcp_state = HDCP_WAIT_KSV_LIST;*/
|
||||
hdcp->hdcp_state = HDCP_LINK_INTEGRITY_CHECK;
|
||||
}
|
||||
}
|
||||
@@ -172,21 +157,16 @@ static void hdcp_wq_check_bksv(void)
|
||||
int status = HDCP_OK;
|
||||
|
||||
DBG("Check BKSV start");
|
||||
|
||||
status = rk3036_hdcp_check_bksv();
|
||||
|
||||
if (status != HDCP_OK) {
|
||||
printk(KERN_INFO "HDCP: Check BKSV failed");
|
||||
HDCP_WARN("HDCP: Check BKSV failed");
|
||||
hdcp->retry_cnt = 0;
|
||||
hdcp_wq_authentication_failure();
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
DBG("HDCP: Check BKSV successful");
|
||||
|
||||
hdcp->hdcp_state = HDCP_LINK_INTEGRITY_CHECK;
|
||||
|
||||
/* Restore retry counter */
|
||||
if(hdcp->retry_times == 0)
|
||||
if (hdcp->retry_times == 0)
|
||||
hdcp->retry_cnt = HDCP_INFINITE_REAUTH;
|
||||
else
|
||||
hdcp->retry_cnt = hdcp->retry_times;
|
||||
@@ -208,8 +188,8 @@ static void hdcp_wq_authentication_sucess(void)
|
||||
/*
|
||||
rk616_hdmi_control_output(true);
|
||||
*/
|
||||
rk3036_set_colorbar(0);
|
||||
printk(KERN_INFO "HDCP: authentication pass");
|
||||
rk3036_set_colorbar(0);
|
||||
HDCP_WARN("HDCP: authentication pass\n");
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
@@ -218,11 +198,11 @@ static void hdcp_wq_authentication_sucess(void)
|
||||
*/
|
||||
static void hdcp_wq_disable(int event)
|
||||
{
|
||||
printk(KERN_INFO "HDCP: disabled");
|
||||
HDCP_WARN("HDCP: disabled\n");
|
||||
|
||||
hdcp_cancel_work(&hdcp->pending_wq_event);
|
||||
rk3036_hdcp_disable();
|
||||
if(event == HDCP_DISABLE_CTL) {
|
||||
if (event == HDCP_DISABLE_CTL) {
|
||||
hdcp->hdcp_state = HDCP_DISABLED;
|
||||
if (hdcp->hdmi_state == HDMI_STARTED)
|
||||
rk3036_set_colorbar(0);
|
||||
@@ -242,97 +222,80 @@ static void hdcp_work_queue(struct work_struct *work)
|
||||
int event = hdcp_w->event;
|
||||
|
||||
mutex_lock(&hdcp->lock);
|
||||
|
||||
DBG("hdcp_work_queue() - START - %u hdmi=%d hdcp=%d evt= %x %d",
|
||||
jiffies_to_msecs(jiffies),
|
||||
hdcp->hdmi_state,
|
||||
hdcp->hdcp_state,
|
||||
(event & 0xFF00) >> 8,
|
||||
event & 0xFF);
|
||||
|
||||
if(event == HDCP_STOP_FRAME_EVENT) {
|
||||
DBG("hdcp_work_queue() - START - %u hdmi=%d hdcp=%d evt= %x %d\n",
|
||||
jiffies_to_msecs(jiffies),
|
||||
hdcp->hdmi_state,
|
||||
hdcp->hdcp_state,
|
||||
(event & 0xFF00) >> 8,
|
||||
event & 0xFF);
|
||||
|
||||
if (event == HDCP_STOP_FRAME_EVENT)
|
||||
hdcp->hdmi_state = HDMI_STOPPED;
|
||||
}
|
||||
|
||||
if (event == HDCP_DISABLE_CTL || event == HDCP_STOP_FRAME_EVENT) {
|
||||
if (event == HDCP_DISABLE_CTL || event == HDCP_STOP_FRAME_EVENT)
|
||||
hdcp_wq_disable(event);
|
||||
}
|
||||
|
||||
if (event & HDCP_WORKQUEUE_SRC)
|
||||
hdcp->pending_wq_event = 0;
|
||||
|
||||
/* First handle HDMI state */
|
||||
if (event == HDCP_START_FRAME_EVENT) {
|
||||
hdcp->pending_start = 0;
|
||||
hdcp->hdmi_state = HDMI_STARTED;
|
||||
}
|
||||
|
||||
|
||||
/**********************/
|
||||
/* HDCP state machine */
|
||||
/**********************/
|
||||
switch (hdcp->hdcp_state) {
|
||||
case HDCP_DISABLED:
|
||||
/* HDCP enable control or re-authentication event */
|
||||
if (event == HDCP_ENABLE_CTL) {
|
||||
/*
|
||||
if (hdcp->retry_times == 0)
|
||||
hdcp->retry_cnt = HDCP_INFINITE_REAUTH;
|
||||
else
|
||||
hdcp->retry_cnt = hdcp->retry_times;
|
||||
*/
|
||||
case HDCP_DISABLED:
|
||||
/* HDCP enable control or re-authentication event */
|
||||
if (event == HDCP_ENABLE_CTL) {
|
||||
/*if (hdcp->retry_times == 0)
|
||||
hdcp->retry_cnt = HDCP_INFINITE_REAUTH;
|
||||
if (hdcp->hdmi_state == HDMI_STARTED)
|
||||
hdcp_wq_start_authentication();
|
||||
else
|
||||
hdcp->hdcp_state = HDCP_ENABLE_PENDING;
|
||||
}
|
||||
break;
|
||||
|
||||
case HDCP_ENABLE_PENDING:
|
||||
/* HDMI start frame event */
|
||||
if (event == HDCP_START_FRAME_EVENT)
|
||||
else
|
||||
hdcp->retry_cnt = hdcp->retry_times;*/
|
||||
hdcp->retry_cnt = HDCP_INFINITE_REAUTH;
|
||||
if (hdcp->hdmi_state == HDMI_STARTED)
|
||||
hdcp_wq_start_authentication();
|
||||
|
||||
break;
|
||||
|
||||
case HDCP_AUTHENTICATION_START:
|
||||
/* Re-authentication */
|
||||
if (event == HDCP_AUTH_REATT_EVENT)
|
||||
hdcp_wq_start_authentication();
|
||||
|
||||
break;
|
||||
else
|
||||
hdcp->hdcp_state = HDCP_ENABLE_PENDING;
|
||||
}
|
||||
break;
|
||||
case HDCP_ENABLE_PENDING:
|
||||
/* HDMI start frame event */
|
||||
if (event == HDCP_START_FRAME_EVENT)
|
||||
hdcp_wq_start_authentication();
|
||||
break;
|
||||
case HDCP_AUTHENTICATION_START:
|
||||
/* Re-authentication */
|
||||
if (event == HDCP_AUTH_REATT_EVENT)
|
||||
hdcp_wq_start_authentication();
|
||||
break;
|
||||
#if 0
|
||||
case HDCP_WAIT_KSV_LIST:
|
||||
/* KSV failure */
|
||||
if (event == HDCP_FAIL_EVENT) {
|
||||
printk(KERN_INFO "HDCP: KSV switch failure\n");
|
||||
|
||||
hdcp_wq_authentication_failure();
|
||||
}
|
||||
/* KSV list ready event */
|
||||
else if (event == HDCP_KSV_LIST_RDY_EVENT)
|
||||
hdcp_wq_check_bksv();
|
||||
break;
|
||||
case HDCP_WAIT_KSV_LIST:
|
||||
/* KSV failure */
|
||||
if (event == HDCP_FAIL_EVENT) {
|
||||
HDCP_WARN("HDCP: KSV switch failure\n");
|
||||
hdcp_wq_authentication_failure();
|
||||
}
|
||||
/* KSV list ready event */
|
||||
else if (event == HDCP_KSV_LIST_RDY_EVENT)
|
||||
hdcp_wq_check_bksv();
|
||||
break;
|
||||
#endif
|
||||
case HDCP_LINK_INTEGRITY_CHECK:
|
||||
/* authentication failure */
|
||||
if (event == HDCP_FAIL_EVENT) {
|
||||
printk(KERN_INFO "HDCP: Ri check failure\n");
|
||||
hdcp_wq_authentication_failure();
|
||||
}
|
||||
else if(event == HDCP_AUTH_PASS_EVENT)
|
||||
hdcp_wq_authentication_sucess();
|
||||
break;
|
||||
|
||||
default:
|
||||
printk(KERN_WARNING "HDCP: error - unknow HDCP state\n");
|
||||
break;
|
||||
case HDCP_LINK_INTEGRITY_CHECK:
|
||||
/* authentication failure */
|
||||
if (event == HDCP_FAIL_EVENT) {
|
||||
HDCP_WARN("HDCP: Ri check failure\n");
|
||||
hdcp_wq_authentication_failure();
|
||||
} else if (event == HDCP_AUTH_PASS_EVENT)
|
||||
hdcp_wq_authentication_sucess();
|
||||
break;
|
||||
default:
|
||||
HDCP_WARN("HDCP: error - unknow HDCP state\n");
|
||||
break;
|
||||
}
|
||||
|
||||
kfree(hdcp_w);
|
||||
if(event == HDCP_STOP_FRAME_EVENT)
|
||||
if (event == HDCP_STOP_FRAME_EVENT)
|
||||
complete(&hdcp->complete);
|
||||
|
||||
mutex_unlock(&hdcp->lock);
|
||||
}
|
||||
|
||||
@@ -342,7 +305,7 @@ static void hdcp_work_queue(struct work_struct *work)
|
||||
*/
|
||||
static void hdcp_start_frame_cb(void)
|
||||
{
|
||||
DBG("hdcp_start_frame_cb()");
|
||||
DBG("hdcp_start_frame_cb()\n");
|
||||
|
||||
/* Cancel any pending work */
|
||||
if (hdcp->pending_start)
|
||||
@@ -358,7 +321,6 @@ static void hdcp_start_frame_cb(void)
|
||||
}
|
||||
|
||||
hdcp->retry_cnt = HDCP_INFINITE_REAUTH;
|
||||
|
||||
hdcp->pending_start = hdcp_submit_work(HDCP_START_FRAME_EVENT,
|
||||
HDCP_ENABLE_DELAY);
|
||||
}
|
||||
@@ -371,22 +333,19 @@ static void hdcp_irq_cb(int status)
|
||||
{
|
||||
char interrupt1;
|
||||
char interrupt2;
|
||||
|
||||
|
||||
rk3036_hdcp_interrupt(&interrupt1, &interrupt2);
|
||||
DBG("%s 0x%02x 0x%02x", __FUNCTION__, interrupt1, interrupt2);
|
||||
if(interrupt1 & m_INT_HDCP_ERR)
|
||||
{
|
||||
if( (hdcp->hdcp_state != HDCP_DISABLED) &&
|
||||
(hdcp->hdcp_state != HDCP_ENABLE_PENDING) )
|
||||
{
|
||||
DBG("%s 0x%02x 0x%02x\n", __func__, interrupt1, interrupt2);
|
||||
if (interrupt1 & m_INT_HDCP_ERR) {
|
||||
if ((hdcp->hdcp_state != HDCP_DISABLED) &&
|
||||
(hdcp->hdcp_state != HDCP_ENABLE_PENDING))
|
||||
hdcp_submit_work(HDCP_FAIL_EVENT, 0);
|
||||
}
|
||||
}
|
||||
/*
|
||||
else if(interrupt1 & (m_INT_BKSV_READY | m_INT_BKSV_UPDATE))
|
||||
else if (interrupt1 & (m_INT_BKSV_READY | m_INT_BKSV_UPDATE))
|
||||
hdcp_submit_work(HDCP_KSV_LIST_RDY_EVENT, 0);
|
||||
*/
|
||||
else if(interrupt1 & m_INT_AUTH_SUCCESS)
|
||||
else if (interrupt1 & m_INT_AUTH_SUCCESS)
|
||||
hdcp_submit_work(HDCP_AUTH_PASS_EVENT, 0);
|
||||
}
|
||||
|
||||
@@ -396,7 +355,7 @@ static void hdcp_irq_cb(int status)
|
||||
*/
|
||||
static int hdcp_power_on_cb(void)
|
||||
{
|
||||
DBG("%s", __FUNCTION__);
|
||||
DBG("%s", __func__);
|
||||
return rk3036_hdcp_load_key2mem(hdcp->keys);
|
||||
return HDCP_OK;
|
||||
}
|
||||
@@ -407,7 +366,7 @@ static int hdcp_power_on_cb(void)
|
||||
*/
|
||||
static void hdcp_power_off_cb(void)
|
||||
{
|
||||
DBG("%s", __FUNCTION__);
|
||||
DBG("%s\n", __func__);
|
||||
if (timer_state == 1) {
|
||||
DBG("delete auth timer\n");
|
||||
timer_state = 0;
|
||||
@@ -415,16 +374,16 @@ static void hdcp_power_off_cb(void)
|
||||
}
|
||||
hdcp->auth_state = 0;
|
||||
|
||||
if(!hdcp->enable)
|
||||
if (!hdcp->enable)
|
||||
return;
|
||||
rk3036_hdcp_stop_authentication();
|
||||
hdcp_cancel_work(&hdcp->pending_start);
|
||||
hdcp_cancel_work(&hdcp->pending_wq_event);
|
||||
init_completion(&hdcp->complete);
|
||||
/* Post event to workqueue */
|
||||
if (hdcp_submit_work(HDCP_STOP_FRAME_EVENT, 0))
|
||||
if (hdcp_submit_work(HDCP_STOP_FRAME_EVENT, 0))
|
||||
wait_for_completion_interruptible_timeout(&hdcp->complete,
|
||||
msecs_to_jiffies(5000));
|
||||
msecs_to_jiffies(5000));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -436,70 +395,67 @@ static void hdcp_load_keys_cb(const struct firmware *fw, void *context)
|
||||
pr_err("HDCP: failed to load keys\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if(fw->size < HDCP_KEY_SIZE) {
|
||||
if (fw->size < HDCP_KEY_SIZE) {
|
||||
pr_err("HDCP: firmware wrong size %d\n", fw->size);
|
||||
return;
|
||||
}
|
||||
|
||||
hdcp->keys = kmalloc(HDCP_KEY_SIZE, GFP_KERNEL);
|
||||
if(hdcp->keys == NULL) {
|
||||
if (hdcp->keys == NULL) {
|
||||
pr_err("HDCP: can't allocated space for keys\n");
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy(hdcp->keys, fw->data, HDCP_KEY_SIZE);
|
||||
|
||||
printk(KERN_INFO "HDCP: load hdcp key success\n");
|
||||
HDCP_WARN("HDCP: load hdcp key success\n");
|
||||
|
||||
if(fw->size > HDCP_KEY_SIZE) {
|
||||
DBG("%s invalid key size %d", __FUNCTION__, fw->size - HDCP_KEY_SIZE);
|
||||
if((fw->size - HDCP_KEY_SIZE) % 5) {
|
||||
if (fw->size > HDCP_KEY_SIZE) {
|
||||
DBG("%s invalid key size %d\n", __func__,
|
||||
fw->size - HDCP_KEY_SIZE);
|
||||
if ((fw->size - HDCP_KEY_SIZE) % 5) {
|
||||
pr_err("HDCP: failed to load invalid keys\n");
|
||||
return;
|
||||
}
|
||||
hdcp->invalidkeys = kmalloc(fw->size - HDCP_KEY_SIZE, GFP_KERNEL);
|
||||
if(hdcp->invalidkeys == NULL) {
|
||||
hdcp->invalidkeys =
|
||||
kmalloc(fw->size - HDCP_KEY_SIZE, GFP_KERNEL);
|
||||
if (hdcp->invalidkeys == NULL) {
|
||||
pr_err("HDCP: can't allocated space for invalid keys\n");
|
||||
return;
|
||||
}
|
||||
memcpy(hdcp->invalidkeys, fw->data + HDCP_KEY_SIZE, fw->size - HDCP_KEY_SIZE);
|
||||
memcpy(hdcp->invalidkeys, fw->data +
|
||||
HDCP_KEY_SIZE, fw->size - HDCP_KEY_SIZE);
|
||||
hdcp->invalidkey = (fw->size - HDCP_KEY_SIZE)/5;
|
||||
printk(KERN_INFO "HDCP: loaded hdcp invalid key success\n");
|
||||
HDCP_WARN("HDCP: loaded hdcp invalid key success\n");
|
||||
}
|
||||
}
|
||||
|
||||
static ssize_t hdcp_enable_read(struct device *device,
|
||||
struct device_attribute *attr, char *buf)
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
int enable = 0;
|
||||
|
||||
if(hdcp)
|
||||
|
||||
if (hdcp)
|
||||
enable = hdcp->enable;
|
||||
|
||||
return snprintf(buf, PAGE_SIZE, "%d\n", enable);
|
||||
}
|
||||
|
||||
static ssize_t hdcp_enable_write(struct device *device,
|
||||
struct device_attribute *attr, const char *buf, size_t count)
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
int enable;
|
||||
|
||||
if(hdcp == NULL)
|
||||
if (hdcp == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
sscanf(buf, "%d", &enable);
|
||||
if(hdcp->enable != enable)
|
||||
{
|
||||
if (hdcp->enable != enable) {
|
||||
/* Post event to workqueue */
|
||||
if(enable) {
|
||||
if (enable) {
|
||||
if (hdcp_submit_work(HDCP_ENABLE_CTL, 0) == 0)
|
||||
return -EFAULT;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
hdcp_cancel_work(&hdcp->pending_start);
|
||||
hdcp_cancel_work(&hdcp->pending_wq_event);
|
||||
|
||||
|
||||
/* Post event to workqueue */
|
||||
if (hdcp_submit_work(HDCP_DISABLE_CTL, 0) == 0)
|
||||
return -EFAULT;
|
||||
@@ -509,106 +465,96 @@ static ssize_t hdcp_enable_write(struct device *device,
|
||||
return count;
|
||||
}
|
||||
|
||||
static DEVICE_ATTR(enable, S_IRUGO|S_IWUSR, hdcp_enable_read, hdcp_enable_write);
|
||||
static DEVICE_ATTR(enable, S_IRUGO|S_IWUSR,
|
||||
hdcp_enable_read, hdcp_enable_write);
|
||||
|
||||
static ssize_t hdcp_trytimes_read(struct device *device,
|
||||
struct device_attribute *attr, char *buf)
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
int trytimes = 0;
|
||||
|
||||
if(hdcp)
|
||||
|
||||
if (hdcp)
|
||||
trytimes = hdcp->retry_times;
|
||||
|
||||
return snprintf(buf, PAGE_SIZE, "%d\n", trytimes);
|
||||
}
|
||||
|
||||
static ssize_t hdcp_trytimes_wrtie(struct device *device,
|
||||
struct device_attribute *attr, const char *buf, size_t count)
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
int trytimes;
|
||||
|
||||
if(hdcp == NULL)
|
||||
if (hdcp == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
sscanf(buf, "%d", &trytimes);
|
||||
if(hdcp->retry_times != trytimes)
|
||||
if (hdcp->retry_times != trytimes)
|
||||
hdcp->retry_times = trytimes;
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
static DEVICE_ATTR(trytimes, S_IRUGO|S_IWUSR, hdcp_trytimes_read, hdcp_trytimes_wrtie);
|
||||
|
||||
|
||||
static DEVICE_ATTR(trytimes, S_IRUGO|S_IWUSR,
|
||||
hdcp_trytimes_read, hdcp_trytimes_wrtie);
|
||||
static struct miscdevice mdev;
|
||||
|
||||
static int __init rk3036_hdcp_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
DBG("[%s] %u", __FUNCTION__, jiffies_to_msecs(jiffies));
|
||||
|
||||
|
||||
DBG("[%s] %u\n", __func__, jiffies_to_msecs(jiffies));
|
||||
hdcp = kmalloc(sizeof(struct hdcp), GFP_KERNEL);
|
||||
if(!hdcp)
|
||||
{
|
||||
printk(KERN_ERR ">>HDCP: kmalloc fail!");
|
||||
ret = -ENOMEM;
|
||||
goto error0;
|
||||
if (!hdcp) {
|
||||
HDCP_WARN(">>HDCP: kmalloc fail!\n");
|
||||
ret = -ENOMEM;
|
||||
goto error0;
|
||||
}
|
||||
memset(hdcp, 0, sizeof(struct hdcp));
|
||||
mutex_init(&hdcp->lock);
|
||||
|
||||
mdev.minor = MISC_DYNAMIC_MINOR;
|
||||
mdev.name = "hdcp";
|
||||
mdev.mode = 0666;
|
||||
if (misc_register(&mdev)) {
|
||||
printk(KERN_ERR "HDCP: Could not add character driver\n");
|
||||
HDCP_WARN("HDCP: Could not add character driver\n");
|
||||
ret = HDMI_ERROR_FALSE;
|
||||
goto error1;
|
||||
}
|
||||
ret = device_create_file(mdev.this_device, &dev_attr_enable);
|
||||
if(ret)
|
||||
{
|
||||
printk(KERN_ERR "HDCP: Could not add sys file enable\n");
|
||||
ret = -EINVAL;
|
||||
goto error2;
|
||||
}
|
||||
|
||||
ret = device_create_file(mdev.this_device, &dev_attr_trytimes);
|
||||
if(ret)
|
||||
{
|
||||
printk(KERN_ERR "HDCP: Could not add sys file trytimes\n");
|
||||
ret = -EINVAL;
|
||||
goto error3;
|
||||
}
|
||||
|
||||
hdcp->workqueue = create_singlethread_workqueue("hdcp");
|
||||
if (ret) {
|
||||
HDCP_WARN("HDCP: Could not add sys file enable\n");
|
||||
ret = -EINVAL;
|
||||
goto error2;
|
||||
}
|
||||
ret = device_create_file(mdev.this_device, &dev_attr_trytimes);
|
||||
if (ret) {
|
||||
HDCP_WARN("HDCP: Could not add sys file trytimes\n");
|
||||
ret = -EINVAL;
|
||||
goto error3;
|
||||
}
|
||||
hdcp->workqueue = create_singlethread_workqueue("hdcp");
|
||||
if (hdcp->workqueue == NULL) {
|
||||
printk(KERN_ERR "HDCP,: create workqueue failed.\n");
|
||||
HDCP_WARN("HDCP,: create workqueue failed.\n");
|
||||
goto error4;
|
||||
}
|
||||
|
||||
|
||||
ret = request_firmware_nowait(THIS_MODULE, FW_ACTION_NOHOTPLUG,
|
||||
"hdcp.keys", mdev.this_device, GFP_KERNEL,
|
||||
hdcp, hdcp_load_keys_cb);
|
||||
ret = request_firmware_nowait(THIS_MODULE, FW_ACTION_NOHOTPLUG,
|
||||
"hdcp.keys", mdev.this_device,
|
||||
GFP_KERNEL, hdcp,
|
||||
hdcp_load_keys_cb);
|
||||
if (ret < 0) {
|
||||
printk(KERN_ERR "HDCP: request_firmware_nowait failed: %d\n", ret);
|
||||
HDCP_WARN("HDCP: request_firmware_nowait failed: %d\n", ret);
|
||||
goto error5;
|
||||
}
|
||||
|
||||
|
||||
rk3036_hdmi_register_hdcp_callbacks(hdcp_start_frame_cb,
|
||||
hdcp_irq_cb,
|
||||
hdcp_power_on_cb,
|
||||
hdcp_power_off_cb);
|
||||
hdcp_irq_cb,
|
||||
hdcp_power_on_cb,
|
||||
hdcp_power_off_cb);
|
||||
|
||||
init_timer(&auth_timer);
|
||||
auth_timer.data = 0;
|
||||
auth_timer.function = auth_timer_func;
|
||||
DBG("%s success %u", __FUNCTION__, jiffies_to_msecs(jiffies));
|
||||
DBG("%s success %u\n", __func__, jiffies_to_msecs(jiffies));
|
||||
return 0;
|
||||
|
||||
error5:
|
||||
destroy_workqueue(hdcp->workqueue);
|
||||
error4:
|
||||
@@ -618,10 +564,8 @@ error3:
|
||||
error2:
|
||||
misc_deregister(&mdev);
|
||||
error1:
|
||||
if(hdcp->keys)
|
||||
kfree(hdcp->keys);
|
||||
if(hdcp->invalidkeys)
|
||||
kfree(hdcp->invalidkeys);
|
||||
kfree(hdcp->keys);
|
||||
kfree(hdcp->invalidkeys);
|
||||
kfree(hdcp);
|
||||
error0:
|
||||
return ret;
|
||||
@@ -631,10 +575,8 @@ static void __exit rk3036_hdcp_exit(void)
|
||||
{
|
||||
device_remove_file(mdev.this_device, &dev_attr_enable);
|
||||
misc_deregister(&mdev);
|
||||
if(hdcp->keys)
|
||||
kfree(hdcp->keys);
|
||||
if(hdcp->invalidkeys)
|
||||
kfree(hdcp->invalidkeys);
|
||||
kfree(hdcp->keys);
|
||||
kfree(hdcp->invalidkeys);
|
||||
kfree(hdcp);
|
||||
}
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
#define HDCP_AUTH_REATT_EVENT (HDCP_WORKQUEUE_SRC | 7)
|
||||
|
||||
/* Key size */
|
||||
#define HDCP_KEY_SIZE 308
|
||||
#define HDCP_KEY_SIZE 308
|
||||
|
||||
/* HDCP DDC Clock */
|
||||
#define HDCP_DDC_CLK 100000
|
||||
@@ -52,7 +52,7 @@
|
||||
#define m_ADVANED_ENABLE (1 << 2)
|
||||
#define m_HDMI_DVI (1 << 1)
|
||||
#define m_HDCP_RESET (1 << 0)
|
||||
|
||||
|
||||
#define v_AUTH_START(n) (n << 7)
|
||||
#define v_BKSV_VALID(n) (n << 6)
|
||||
#define v_BKSV_INVALID(n) (n << 5)
|
||||
@@ -70,7 +70,7 @@
|
||||
#define m_DELAY_RI_1_CLK (1 << 3)
|
||||
#define m_USE_PRESET_AN (1 << 2)
|
||||
#define m_KEY_COMBINATION (3 << 0)
|
||||
|
||||
|
||||
#define v_DISABLE_127_CHECK(n) (n << 7)
|
||||
#define v_SKIP_BKSV_CHECK(n) (n << 6)
|
||||
#define v_ENABLE_PJ_CHECK(n) (n << 5)
|
||||
@@ -88,7 +88,7 @@
|
||||
#define m_NOT_AUTHENTICATED (1 << 5)
|
||||
#define m_ENCRYPTED (1 << 4)
|
||||
#define m_ADVANCED_CIPHER (1 << 3)
|
||||
|
||||
|
||||
#define HDCP_BCAPS_RX 0x58
|
||||
#define HDCP_TIMER_100MS 0x63
|
||||
#define HDCP_TIMER_5S 0x64
|
||||
@@ -119,7 +119,7 @@
|
||||
#define m_INT_BKSV_UPDATE (1 << 5)
|
||||
#define m_INT_AUTH_SUCCESS (1 << 4)
|
||||
#define m_INT_AUTH_READY (1 << 3)
|
||||
|
||||
|
||||
#define HDCP_INT_MASK2 0xc4
|
||||
#define HDCP_INT_STATUS2 0xc5
|
||||
#define m_INT_SOFT_MODE_READY (1 << 7)
|
||||
@@ -146,9 +146,9 @@ enum hdmi_states {
|
||||
#define HDCP_PRIVATE_KEY_SIZE 280
|
||||
#define HDCP_KEY_SHA_SIZE 20
|
||||
|
||||
struct hdcp_keys{
|
||||
u8 KSV[8];
|
||||
u8 DeviceKey[HDCP_PRIVATE_KEY_SIZE];
|
||||
struct hdcp_keys {
|
||||
u8 ksv[8];
|
||||
u8 devicekey[HDCP_PRIVATE_KEY_SIZE];
|
||||
u8 sha1[HDCP_KEY_SHA_SIZE];
|
||||
};
|
||||
|
||||
@@ -162,14 +162,14 @@ struct hdcp {
|
||||
int retry_times;
|
||||
struct hdcp_keys *keys;
|
||||
int invalidkey;
|
||||
char *invalidkeys;
|
||||
char *invalidkeys;
|
||||
struct mutex lock;
|
||||
struct completion complete;
|
||||
struct workqueue_struct *workqueue;
|
||||
|
||||
|
||||
enum hdmi_states hdmi_state;
|
||||
enum hdcp_states hdcp_state;
|
||||
|
||||
|
||||
struct delayed_work *pending_start;
|
||||
struct delayed_work *pending_wq_event;
|
||||
int retry_cnt;
|
||||
@@ -185,6 +185,12 @@ extern struct hdcp *hdcp;
|
||||
#define DBG(format, ...)
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
#define HDCP_WARN(x...) printk(KERN_INFO x)
|
||||
#else
|
||||
#define I2S_DBG(x...) do { } while (0)
|
||||
#endif
|
||||
|
||||
extern void rk3036_hdcp_disable(void);
|
||||
extern int rk3036_hdcp_start_authentication(void);
|
||||
extern int rk3036_hdcp_check_bksv(void);
|
||||
@@ -192,4 +198,5 @@ extern int rk3036_hdcp_load_key2mem(struct hdcp_keys *key);
|
||||
extern void rk3036_hdcp_interrupt(char *status1, char *status2);
|
||||
extern void rk3036_set_colorbar(int enable);
|
||||
extern int rk3036_hdcp_stop_authentication(void);
|
||||
extern int is_1b_03_test(void);
|
||||
#endif /* __rk3036_HDCP_H__ */
|
||||
|
||||
@@ -6,6 +6,7 @@ int is_1b_03_test(void)
|
||||
{
|
||||
int reg_value;
|
||||
int reg_val_1;
|
||||
|
||||
hdmi_readl(hdmi_dev, 0x58, ®_value);
|
||||
hdmi_readl(hdmi_dev, 0xc3, ®_val_1);
|
||||
|
||||
@@ -18,90 +19,98 @@ int is_1b_03_test(void)
|
||||
|
||||
void rk3036_set_colorbar(int enable)
|
||||
{
|
||||
static int display_mask = 0;
|
||||
int reg_value;
|
||||
if (enable) {
|
||||
if (!display_mask) {
|
||||
if (hdmi_dev->driver.tmdsclk <= (HDMI_SYS_FREG_CLK << 2)) {
|
||||
hdmi_readl(hdmi_dev, SYS_CTRL, ®_value);
|
||||
hdmi_msk_reg(hdmi_dev, SYS_CTRL, m_REG_CLK_SOURCE, v_REG_CLK_SOURCE_SYS);
|
||||
hdmi_writel(hdmi_dev, HDMI_COLORBAR, 0x00);
|
||||
hdmi_writel(hdmi_dev, SYS_CTRL, reg_value);
|
||||
} else {
|
||||
hdmi_writel(hdmi_dev, HDMI_COLORBAR, 0x00);
|
||||
}
|
||||
static int display_mask;
|
||||
int reg_value;
|
||||
int tmds_clk;
|
||||
|
||||
display_mask = 1;
|
||||
}
|
||||
} else {
|
||||
if (display_mask) {
|
||||
|
||||
if (hdmi_dev->driver.tmdsclk <= (HDMI_SYS_FREG_CLK << 2)) {
|
||||
hdmi_readl(hdmi_dev, SYS_CTRL, ®_value);
|
||||
hdmi_msk_reg(hdmi_dev, SYS_CTRL, m_REG_CLK_SOURCE, v_REG_CLK_SOURCE_SYS);
|
||||
hdmi_writel(hdmi_dev, HDMI_COLORBAR, 0x10);
|
||||
hdmi_writel(hdmi_dev, SYS_CTRL, reg_value);
|
||||
} else {
|
||||
hdmi_writel(hdmi_dev, HDMI_COLORBAR, 0x10);
|
||||
}
|
||||
|
||||
display_mask = 0;
|
||||
}
|
||||
}
|
||||
tmds_clk = hdmi_dev->driver.tmdsclk;
|
||||
if (enable) {
|
||||
if (!display_mask) {
|
||||
if (tmds_clk <= (HDMI_SYS_FREG_CLK << 2)) {
|
||||
hdmi_readl(hdmi_dev, SYS_CTRL, ®_value);
|
||||
hdmi_msk_reg(hdmi_dev, SYS_CTRL,
|
||||
m_REG_CLK_SOURCE,
|
||||
v_REG_CLK_SOURCE_SYS);
|
||||
hdmi_writel(hdmi_dev, HDMI_COLORBAR, 0x00);
|
||||
hdmi_writel(hdmi_dev, SYS_CTRL, reg_value);
|
||||
} else {
|
||||
hdmi_writel(hdmi_dev, HDMI_COLORBAR, 0x00);
|
||||
}
|
||||
display_mask = 1;
|
||||
}
|
||||
} else {
|
||||
if (display_mask) {
|
||||
if (tmds_clk <= (HDMI_SYS_FREG_CLK << 2)) {
|
||||
hdmi_readl(hdmi_dev, SYS_CTRL, ®_value);
|
||||
hdmi_msk_reg(hdmi_dev, SYS_CTRL,
|
||||
m_REG_CLK_SOURCE,
|
||||
v_REG_CLK_SOURCE_SYS);
|
||||
hdmi_writel(hdmi_dev, HDMI_COLORBAR, 0x10);
|
||||
hdmi_writel(hdmi_dev, SYS_CTRL, reg_value);
|
||||
} else {
|
||||
hdmi_writel(hdmi_dev, HDMI_COLORBAR, 0x10);
|
||||
}
|
||||
display_mask = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void rk3036_hdcp_disable(void)
|
||||
{
|
||||
int reg_value;
|
||||
if (hdmi_dev->driver.tmdsclk <= (HDMI_SYS_FREG_CLK << 2)) {
|
||||
int tmds_clk;
|
||||
|
||||
tmds_clk = hdmi_dev->driver.tmdsclk;
|
||||
if (tmds_clk <= (HDMI_SYS_FREG_CLK << 2)) {
|
||||
hdmi_readl(hdmi_dev, SYS_CTRL, ®_value);
|
||||
hdmi_msk_reg(hdmi_dev, SYS_CTRL, m_REG_CLK_SOURCE, v_REG_CLK_SOURCE_SYS);
|
||||
hdmi_msk_reg(hdmi_dev, SYS_CTRL,
|
||||
m_REG_CLK_SOURCE, v_REG_CLK_SOURCE_SYS);
|
||||
}
|
||||
|
||||
// Diable HDCP Interrupt
|
||||
/* Diable HDCP Interrupt*/
|
||||
hdmi_writel(hdmi_dev, HDCP_INT_MASK1, 0x00);
|
||||
// Stop and Reset HDCP
|
||||
hdmi_msk_reg(hdmi_dev, HDCP_CTRL1, m_AUTH_START | m_AUTH_STOP | m_HDCP_RESET,
|
||||
v_AUTH_START(0) | v_AUTH_STOP(1) | v_HDCP_RESET(1) );
|
||||
/* Stop and Reset HDCP*/
|
||||
hdmi_msk_reg(hdmi_dev, HDCP_CTRL1,
|
||||
m_AUTH_START | m_AUTH_STOP | m_HDCP_RESET,
|
||||
v_AUTH_START(0) | v_AUTH_STOP(1) | v_HDCP_RESET(1));
|
||||
|
||||
if (hdmi_dev->driver.tmdsclk <= (HDMI_SYS_FREG_CLK << 2))
|
||||
if (tmds_clk <= (HDMI_SYS_FREG_CLK << 2))
|
||||
hdmi_writel(hdmi_dev, SYS_CTRL, reg_value);
|
||||
|
||||
}
|
||||
|
||||
int rk3036_hdcp_key_check(struct hdcp_keys *key)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
|
||||
DBG("HDCP: check hdcp key\n");
|
||||
//check 40 private key
|
||||
for(i = 0; i < HDCP_PRIVATE_KEY_SIZE; i++){
|
||||
if(key->DeviceKey[i] != 0x00)
|
||||
/*check 40 private key */
|
||||
for (i = 0; i < HDCP_PRIVATE_KEY_SIZE; i++) {
|
||||
if (key->devicekey[i] != 0x00)
|
||||
return HDCP_KEY_VALID;
|
||||
}
|
||||
//check aksv
|
||||
for(i = 0; i < 5; i++){
|
||||
if(key->KSV[i] != 0x00)
|
||||
/*check aksv*/
|
||||
for (i = 0; i < 5; i++) {
|
||||
if (key->ksv[i] != 0x00)
|
||||
return HDCP_KEY_VALID;
|
||||
}
|
||||
|
||||
return HDCP_KEY_INVALID;
|
||||
return HDCP_KEY_INVALID;
|
||||
}
|
||||
int rk3036_hdcp_load_key2mem(struct hdcp_keys *key)
|
||||
{
|
||||
int i;
|
||||
DBG("HDCP: rk3036_hdcp_load_key2mem start");
|
||||
// Write 40 private key
|
||||
for(i = 0; i < HDCP_PRIVATE_KEY_SIZE; i++)
|
||||
hdmi_writel(hdmi_dev, HDCP_KEY_FIFO, key->DeviceKey[i]);
|
||||
|
||||
// Write 1st aksv
|
||||
for(i = 0; i < 5; i++)
|
||||
hdmi_writel(hdmi_dev, HDCP_KEY_FIFO, key->KSV[i]);
|
||||
|
||||
// Write 2nd aksv
|
||||
for(i = 0; i < 5; i++)
|
||||
hdmi_writel(hdmi_dev, HDCP_KEY_FIFO, key->KSV[i]);
|
||||
DBG("HDCP: rk3036_hdcp_load_key2mem end");
|
||||
|
||||
DBG("HDCP: rk3036_hdcp_load_key2mem start\n");
|
||||
/* Write 40 private key*/
|
||||
for (i = 0; i < HDCP_PRIVATE_KEY_SIZE; i++)
|
||||
hdmi_writel(hdmi_dev, HDCP_KEY_FIFO, key->devicekey[i]);
|
||||
/* Write 1st aksv*/
|
||||
for (i = 0; i < 5; i++)
|
||||
hdmi_writel(hdmi_dev, HDCP_KEY_FIFO, key->ksv[i]);
|
||||
/* Write 2nd aksv*/
|
||||
for (i = 0; i < 5; i++)
|
||||
hdmi_writel(hdmi_dev, HDCP_KEY_FIFO, key->ksv[i]);
|
||||
DBG("HDCP: rk3036_hdcp_load_key2mem end\n");
|
||||
return HDCP_OK;
|
||||
}
|
||||
|
||||
@@ -109,68 +118,72 @@ int rk3036_hdcp_start_authentication(void)
|
||||
{
|
||||
int temp;
|
||||
int retry = 0;
|
||||
int tmds_clk;
|
||||
|
||||
if(hdcp->keys == NULL) {
|
||||
printk(KERN_ERR "HDCP: key is not loaded\n");
|
||||
tmds_clk = hdmi_dev->driver.tmdsclk;
|
||||
if (hdcp->keys == NULL) {
|
||||
HDCP_WARN("HDCP: key is not loaded\n");
|
||||
return HDCP_KEY_ERR;
|
||||
}
|
||||
|
||||
if(rk3036_hdcp_key_check(hdcp->keys) == HDCP_KEY_INVALID){
|
||||
printk(KERN_ERR "loaded HDCP key is incorrect\n");
|
||||
if (rk3036_hdcp_key_check(hdcp->keys) == HDCP_KEY_INVALID) {
|
||||
HDCP_WARN("loaded HDCP key is incorrect\n");
|
||||
return HDCP_KEY_ERR;
|
||||
}
|
||||
|
||||
if (hdmi_dev->driver.tmdsclk > (HDMI_SYS_FREG_CLK << 2)) {
|
||||
// Select TMDS CLK to configure regs
|
||||
hdmi_msk_reg(hdmi_dev, SYS_CTRL, m_REG_CLK_SOURCE, v_REG_CLK_SOURCE_TMDS);
|
||||
} else {
|
||||
hdmi_msk_reg(hdmi_dev, SYS_CTRL, m_REG_CLK_SOURCE, v_REG_CLK_SOURCE_SYS);
|
||||
}
|
||||
|
||||
hdmi_writel(hdmi_dev, HDCP_TIMER_100MS,0x28);
|
||||
hdmi_readl(hdmi_dev, HDCP_KEY_STATUS,&temp);
|
||||
while( ( temp & m_KEY_READY) == 0 ) {
|
||||
if(retry > 1000) {
|
||||
printk(KERN_ERR "HDCP: loaded key error\n");
|
||||
}
|
||||
if (tmds_clk > (HDMI_SYS_FREG_CLK << 2)) {
|
||||
/*Select TMDS CLK to configure regs*/
|
||||
hdmi_msk_reg(hdmi_dev, SYS_CTRL,
|
||||
m_REG_CLK_SOURCE, v_REG_CLK_SOURCE_TMDS);
|
||||
} else {
|
||||
hdmi_msk_reg(hdmi_dev, SYS_CTRL,
|
||||
m_REG_CLK_SOURCE, v_REG_CLK_SOURCE_SYS);
|
||||
}
|
||||
hdmi_writel(hdmi_dev, HDCP_TIMER_100MS, 0x28);
|
||||
hdmi_readl(hdmi_dev, HDCP_KEY_STATUS, &temp);
|
||||
while ((temp & m_KEY_READY) == 0) {
|
||||
if (retry > 1000) {
|
||||
HDCP_WARN("HDCP: loaded key error\n");
|
||||
return HDCP_KEY_ERR;
|
||||
}
|
||||
rk3036_hdcp_load_key2mem(hdcp->keys);
|
||||
msleep(1);
|
||||
hdmi_readl(hdmi_dev, HDCP_KEY_STATUS,&temp);
|
||||
retry++;
|
||||
hdmi_readl(hdmi_dev, HDCP_KEY_STATUS, &temp);
|
||||
retry++;
|
||||
}
|
||||
|
||||
// Config DDC bus clock: ddc_clk = reg_clk/4*(reg 0x4c 0x4b)
|
||||
retry = hdmi_dev->hclk_rate/(HDCP_DDC_CLK << 2);
|
||||
hdmi_writel(hdmi_dev, DDC_CLK_L, retry & 0xFF);
|
||||
hdmi_writel(hdmi_dev, DDC_CLK_H, (retry >> 8) & 0xFF);
|
||||
|
||||
/*Config DDC bus clock: ddc_clk = reg_clk/4*(reg 0x4c 0x4b)*/
|
||||
retry = hdmi_dev->hclk_rate/(HDCP_DDC_CLK << 2);
|
||||
hdmi_writel(hdmi_dev, DDC_CLK_L, retry & 0xFF);
|
||||
hdmi_writel(hdmi_dev, DDC_CLK_H, (retry >> 8) & 0xFF);
|
||||
hdmi_writel(hdmi_dev, HDCP_CTRL2, 0x67);
|
||||
/*Enable interrupt*/
|
||||
hdmi_writel(hdmi_dev, HDCP_INT_MASK1,
|
||||
m_INT_HDCP_ERR | m_INT_BKSV_READY | m_INT_BKSV_UPDATE |
|
||||
m_INT_AUTH_SUCCESS | m_INT_AUTH_READY);
|
||||
hdmi_writel(hdmi_dev, HDCP_INT_MASK2, 0x00);
|
||||
/*Start authentication*/
|
||||
hdmi_msk_reg(hdmi_dev, HDCP_CTRL1,
|
||||
m_AUTH_START | m_ENCRYPT_ENABLE | m_ADVANED_ENABLE |
|
||||
m_AUTH_STOP | m_HDCP_RESET,
|
||||
v_AUTH_START(1) | v_ENCRYPT_ENABLE(1) |
|
||||
v_ADVANED_ENABLE(0) | v_AUTH_STOP(0) | v_HDCP_RESET(0));
|
||||
|
||||
//Enable interrupt
|
||||
hdmi_writel(hdmi_dev, HDCP_INT_MASK1, m_INT_HDCP_ERR | m_INT_BKSV_READY | m_INT_BKSV_UPDATE | m_INT_AUTH_SUCCESS | m_INT_AUTH_READY);
|
||||
hdmi_writel(hdmi_dev, HDCP_INT_MASK2, 0x00);
|
||||
|
||||
//Start authentication
|
||||
hdmi_msk_reg(hdmi_dev, HDCP_CTRL1, m_AUTH_START | m_ENCRYPT_ENABLE | m_ADVANED_ENABLE | m_AUTH_STOP | m_HDCP_RESET,
|
||||
v_AUTH_START(1) | v_ENCRYPT_ENABLE(1) | v_ADVANED_ENABLE(0) | v_AUTH_STOP(0) | v_HDCP_RESET(0));
|
||||
|
||||
if (hdmi_dev->driver.tmdsclk <= (HDMI_SYS_FREG_CLK << 2)) {
|
||||
hdmi_msk_reg(hdmi_dev, SYS_CTRL, m_REG_CLK_SOURCE, v_REG_CLK_SOURCE_TMDS);
|
||||
}
|
||||
if (tmds_clk <= (HDMI_SYS_FREG_CLK << 2)) {
|
||||
hdmi_msk_reg(hdmi_dev, SYS_CTRL, m_REG_CLK_SOURCE,
|
||||
v_REG_CLK_SOURCE_TMDS);
|
||||
}
|
||||
return HDCP_OK;
|
||||
}
|
||||
|
||||
int rk3036_hdcp_stop_authentication(void)
|
||||
{
|
||||
hdmi_msk_reg(hdmi_dev, SYS_CTRL, m_REG_CLK_SOURCE, v_REG_CLK_SOURCE_SYS);
|
||||
hdmi_writel(hdmi_dev, DDC_CLK_L, 0x1c);
|
||||
hdmi_msk_reg(hdmi_dev, SYS_CTRL,
|
||||
m_REG_CLK_SOURCE, v_REG_CLK_SOURCE_SYS);
|
||||
hdmi_writel(hdmi_dev, DDC_CLK_L, 0x1c);
|
||||
hdmi_writel(hdmi_dev, DDC_CLK_H, 0x00);
|
||||
hdmi_writel(hdmi_dev, HDCP_CTRL2, 0x08);
|
||||
hdmi_writel(hdmi_dev, HDCP_INT_MASK2, 0x06);
|
||||
hdmi_writel(hdmi_dev, HDCP_CTRL1, 0x02);
|
||||
return 0;
|
||||
//hdmi_writel(HDCP_CTRL1, 0x0a);
|
||||
return 0;
|
||||
/*hdmi_writel(HDCP_CTRL1, 0x0a);*/
|
||||
}
|
||||
#if 0
|
||||
int rk3036_hdcp_check_bksv(void)
|
||||
@@ -178,102 +191,94 @@ int rk3036_hdcp_check_bksv(void)
|
||||
int i, j;
|
||||
char temp = 0, bksv[5];
|
||||
char *invalidkey;
|
||||
|
||||
for(i = 0; i < 5; i++) {
|
||||
|
||||
for (i = 0; i < 5; i++) {
|
||||
hdmi_readl(HDCP_KSV_BYTE0 + (4 - i), &temp);
|
||||
bksv[i] = temp & 0xFF;
|
||||
}
|
||||
DBG("bksv is 0x%02x%02x%02x%02x%02x", bksv[0], bksv[1], bksv[2], bksv[3], bksv[4]);
|
||||
|
||||
temp = 0;
|
||||
for (i = 0; i < 5; i++)
|
||||
{
|
||||
for (j = 0; j < 8; j++)
|
||||
{
|
||||
if (bksv[i] & 0x01)
|
||||
{
|
||||
temp++;
|
||||
}
|
||||
bksv[i] >>= 1;
|
||||
}
|
||||
}
|
||||
if (temp != 20)
|
||||
return HDCP_KSV_ERR;
|
||||
|
||||
for(i = 0; i < hdcp->invalidkey; i++)
|
||||
{
|
||||
invalidkey = hdcp->invalidkeys + i *5;
|
||||
if(memcmp(bksv, invalidkey, 5) == 0) {
|
||||
printk(KERN_ERR "HDCP: BKSV was revocated!!!\n");
|
||||
hdmi_msk_reg(HDCP_CTRL1, m_BKSV_INVALID | m_ENCRYPT_ENABLE, v_BKSV_INVALID(1) | v_ENCRYPT_ENABLE(1));
|
||||
DBG("bksv is 0x%02x%02x%02x%02x%02x",
|
||||
bksv[0], bksv[1], bksv[2], bksv[3], bksv[4]);
|
||||
|
||||
temp = 0;
|
||||
for (i = 0; i < 5; i++) {
|
||||
for (j = 0; j < 8; j++) {
|
||||
if (bksv[i] & 0x01)
|
||||
temp++;
|
||||
bksv[i] >>= 1;
|
||||
}
|
||||
}
|
||||
if (temp != 20)
|
||||
return HDCP_KSV_ERR;
|
||||
for (i = 0; i < hdcp->invalidkey; i++) {
|
||||
invalidkey = hdcp->invalidkeys + i*5;
|
||||
if (memcmp(bksv, invalidkey, 5) == 0) {
|
||||
HDCP_WARN("HDCP:BKSV was revocated!\n");
|
||||
hdmi_msk_reg(HDCP_CTRL1, m_BKSV_INVALID | m_ENCRYPT_ENABLE,
|
||||
v_BKSV_INVALID(1) | v_ENCRYPT_ENABLE(1));
|
||||
return HDCP_KSV_ERR;
|
||||
}
|
||||
}
|
||||
hdmi_msk_reg(HDCP_CTRL1, m_BKSV_VALID | m_ENCRYPT_ENABLE, v_BKSV_VALID(1) | v_ENCRYPT_ENABLE(1));
|
||||
hdmi_msk_reg(HDCP_CTRL1, m_BKSV_VALID | m_ENCRYPT_ENABLE,
|
||||
v_BKSV_VALID(1) | v_ENCRYPT_ENABLE(1));
|
||||
return HDCP_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
int rk3036_hdcp_error(int value)
|
||||
{
|
||||
if (value & 0x80) {
|
||||
printk("Timed out waiting for downstream repeater\n");
|
||||
|
||||
} else if (value & 0x40) {
|
||||
printk("Too many devices connected to repeater tree\n");
|
||||
|
||||
} else if (value & 0x20) {
|
||||
printk("SHA-1 hash check of BKSV list failed\n");
|
||||
|
||||
} else if (value & 0x10) {
|
||||
printk("SHA-1 hash check of BKSV list failed\n");
|
||||
|
||||
} else if (value & 0x08) {
|
||||
printk("DDC channels no acknowledge\n");
|
||||
|
||||
} else if (value & 0x04) {
|
||||
printk("Pj mismatch\n");
|
||||
|
||||
} else if (value & 0x02) {
|
||||
printk("Ri mismatch\n");
|
||||
|
||||
} else if (value & 0x01) {
|
||||
printk("Bksv is wrong\n");
|
||||
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
if (value & 0x80)
|
||||
HDCP_WARN("Timed out waiting for downstream repeater\n");
|
||||
else if (value & 0x40)
|
||||
HDCP_WARN("Too many devices connected to repeater tree\n");
|
||||
else if (value & 0x20)
|
||||
HDCP_WARN("SHA-1 hash check of BKSV list failed\n");
|
||||
else if (value & 0x10)
|
||||
HDCP_WARN("SHA-1 hash check of BKSV list failed\n");
|
||||
else if (value & 0x08)
|
||||
HDCP_WARN("DDC channels no acknowledge\n");
|
||||
else if (value & 0x04)
|
||||
HDCP_WARN("Pj mismatch\n");
|
||||
else if (value & 0x02)
|
||||
HDCP_WARN("Ri mismatch\n");
|
||||
else if (value & 0x01)
|
||||
HDCP_WARN("Bksv is wrong\n");
|
||||
else
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
void rk3036_hdcp_interrupt(char *status1, char *status2)
|
||||
{
|
||||
int interrupt1 = 0;
|
||||
int interrupt2 = 0;
|
||||
int temp =0;
|
||||
int temp = 0;
|
||||
int tmds_clk;
|
||||
|
||||
hdmi_readl(hdmi_dev, HDCP_INT_STATUS1,&interrupt1);
|
||||
hdmi_readl(hdmi_dev, HDCP_INT_STATUS2,&interrupt2);
|
||||
tmds_clk = hdmi_dev->driver.tmdsclk;
|
||||
hdmi_readl(hdmi_dev, HDCP_INT_STATUS1, &interrupt1);
|
||||
hdmi_readl(hdmi_dev, HDCP_INT_STATUS2, &interrupt2);
|
||||
|
||||
if (hdmi_dev->driver.tmdsclk <= (HDMI_SYS_FREG_CLK << 2))
|
||||
hdmi_msk_reg(hdmi_dev, SYS_CTRL, m_REG_CLK_SOURCE, v_REG_CLK_SOURCE_SYS);
|
||||
if (tmds_clk <= (HDMI_SYS_FREG_CLK << 2))
|
||||
hdmi_msk_reg(hdmi_dev, SYS_CTRL,
|
||||
m_REG_CLK_SOURCE, v_REG_CLK_SOURCE_SYS);
|
||||
|
||||
if(interrupt1) {
|
||||
if (interrupt1) {
|
||||
hdmi_writel(hdmi_dev, HDCP_INT_STATUS1, interrupt1);
|
||||
if(interrupt1 & m_INT_HDCP_ERR){
|
||||
hdmi_readl(hdmi_dev, HDCP_ERROR,&temp);
|
||||
printk(KERN_INFO "HDCP: Error reg 0x65 = 0x%02x\n", temp);
|
||||
rk3036_hdcp_error(temp);
|
||||
if (interrupt1 & m_INT_HDCP_ERR) {
|
||||
hdmi_readl(hdmi_dev, HDCP_ERROR, &temp);
|
||||
HDCP_WARN("HDCP: Error reg 0x65 = 0x%02x\n", temp);
|
||||
rk3036_hdcp_error(temp);
|
||||
hdmi_writel(hdmi_dev, HDCP_ERROR, temp);
|
||||
}
|
||||
}
|
||||
if(interrupt2)
|
||||
if (interrupt2)
|
||||
hdmi_writel(hdmi_dev, HDCP_INT_STATUS2, interrupt2);
|
||||
|
||||
|
||||
*status1 = interrupt1;
|
||||
*status2 = interrupt2;
|
||||
|
||||
if (hdmi_dev->driver.tmdsclk <= (HDMI_SYS_FREG_CLK << 2))
|
||||
hdmi_msk_reg(hdmi_dev, SYS_CTRL, m_REG_CLK_SOURCE, v_REG_CLK_SOURCE_TMDS);
|
||||
if (tmds_clk <= (HDMI_SYS_FREG_CLK << 2))
|
||||
hdmi_msk_reg(hdmi_dev, SYS_CTRL, m_REG_CLK_SOURCE,
|
||||
v_REG_CLK_SOURCE_TMDS);
|
||||
/*
|
||||
hdmi_readl(HDCP_ERROR, &temp);
|
||||
DBG("HDCP: Error reg 0x65 = 0x%02x\n", temp);
|
||||
|
||||
Reference in New Issue
Block a user