mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 19:30:30 +09:00
hdmirx: add new hdcp14 key configuration method
PD#168660: hdmirx: add new hdcp14 key configuration method set hdcp1.4 key via secure OS to protect the key Change-Id: If455aebe1c7fb65b4b16e8cf3ba7a70cf20702ac Signed-off-by: yicheng shen <yicheng.shen@amlogic.com>
This commit is contained in:
committed by
Jianxin Pan
parent
8633ffb2a1
commit
ea9054b008
@@ -1026,6 +1026,15 @@ static long hdmirx_ioctl(struct file *file, unsigned int cmd,
|
||||
}
|
||||
/*mutex_unlock(&pktbuff_lock);*/
|
||||
break;
|
||||
case HDMI_IOC_HDCP14_KEY_MODE:
|
||||
if (copy_from_user(&hdcp14_key_mode, argp,
|
||||
sizeof(enum hdcp14_key_mode_e))) {
|
||||
ret = -EFAULT;
|
||||
pr_info("HDMI_IOC_HDCP14_KEY_MODE err\n\n");
|
||||
break;
|
||||
}
|
||||
rx_pr("hdcp1.4 key mode-%d\n", hdcp14_key_mode);
|
||||
break;
|
||||
default:
|
||||
ret = -ENOIOCTLCMD;
|
||||
break;
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
*
|
||||
*
|
||||
*/
|
||||
#define RX_VER1 "ver.2018/06/26"
|
||||
#define RX_VER1 "ver.2018/07/19"
|
||||
/*
|
||||
*
|
||||
*
|
||||
@@ -129,6 +129,8 @@ struct hdmirx_dev_s {
|
||||
uint32_t)
|
||||
#define HDMI_IOC_GET_PD_FIFO_PARAM _IOWR(HDMI_IOC_MAGIC, 0x0c,\
|
||||
struct pd_infoframe_s)
|
||||
#define HDMI_IOC_HDCP14_KEY_MODE _IOR(HDMI_IOC_MAGIC, 0x0d,\
|
||||
enum hdcp14_key_mode_e)
|
||||
|
||||
#define IOC_SPD_INFO _BIT(0)
|
||||
#define IOC_AUD_INFO _BIT(1)
|
||||
|
||||
@@ -88,6 +88,13 @@ int hdcp22_on;
|
||||
MODULE_PARM_DESC(hdcp22_on, "\n hdcp22_on\n");
|
||||
module_param(hdcp22_on, int, 0664);
|
||||
|
||||
/*
|
||||
* hdcp14_key_mode:hdcp1.4 key handle method select
|
||||
* NORMAL_MODE:systemcontrol path
|
||||
* SECURE_MODE:secure OS path
|
||||
*/
|
||||
int hdcp14_key_mode = NORMAL_MODE;
|
||||
|
||||
int aud_ch_map;
|
||||
|
||||
/*------------------------variable define end------------------------------*/
|
||||
@@ -488,7 +495,7 @@ void sec_top_write(unsigned int *addr, unsigned int value)
|
||||
{
|
||||
struct arm_smccc_res res;
|
||||
|
||||
arm_smccc_smc(0x8200001e, (unsigned long)(uintptr_t)addr,
|
||||
arm_smccc_smc(HDMIRX_WR_SEC_TOP, (unsigned long)(uintptr_t)addr,
|
||||
value, 0, 0, 0, 0, 0, &res);
|
||||
}
|
||||
|
||||
@@ -499,7 +506,7 @@ unsigned int sec_top_read(unsigned int *addr)
|
||||
{
|
||||
struct arm_smccc_res res;
|
||||
|
||||
arm_smccc_smc(0x8200001d, (unsigned long)(uintptr_t)addr,
|
||||
arm_smccc_smc(HDMIRX_RD_SEC_TOP, (unsigned long)(uintptr_t)addr,
|
||||
0, 0, 0, 0, 0, 0, &res);
|
||||
|
||||
return (unsigned int)((res.a0)&0xffffffff);
|
||||
@@ -512,7 +519,7 @@ void rx_sec_reg_write(unsigned int *addr, unsigned int value)
|
||||
{
|
||||
struct arm_smccc_res res;
|
||||
|
||||
arm_smccc_smc(0x8200002f, (unsigned long)(uintptr_t)addr,
|
||||
arm_smccc_smc(HDCP22_RX_ESM_WRITE, (unsigned long)(uintptr_t)addr,
|
||||
value, 0, 0, 0, 0, 0, &res);
|
||||
}
|
||||
|
||||
@@ -523,7 +530,7 @@ unsigned int rx_sec_reg_read(unsigned int *addr)
|
||||
{
|
||||
struct arm_smccc_res res;
|
||||
|
||||
arm_smccc_smc(0x8200001f, (unsigned long)(uintptr_t)addr,
|
||||
arm_smccc_smc(HDCP22_RX_ESM_READ, (unsigned long)(uintptr_t)addr,
|
||||
0, 0, 0, 0, 0, 0, &res);
|
||||
|
||||
return (unsigned int)((res.a0)&0xffffffff);
|
||||
@@ -536,7 +543,22 @@ unsigned int rx_sec_set_duk(void)
|
||||
{
|
||||
struct arm_smccc_res res;
|
||||
|
||||
arm_smccc_smc(0x8200002e, 0, 0, 0, 0, 0, 0, 0, &res);
|
||||
arm_smccc_smc(HDCP22_RX_SET_DUK_KEY, 0, 0, 0, 0, 0, 0, 0, &res);
|
||||
|
||||
return (unsigned int)((res.a0)&0xffffffff);
|
||||
}
|
||||
|
||||
/*
|
||||
* rx_set_hdcp14_secure_key
|
||||
*/
|
||||
unsigned int rx_set_hdcp14_secure_key(void)
|
||||
{
|
||||
struct arm_smccc_res res;
|
||||
|
||||
/* 0x8200002d is the SMC cmd defined in BL31,this CMD
|
||||
* will call set hdcp1.4 key function
|
||||
*/
|
||||
arm_smccc_smc(HDCP14_RX_SETKEY, 0, 0, 0, 0, 0, 0, 0, &res);
|
||||
|
||||
return (unsigned int)((res.a0)&0xffffffff);
|
||||
}
|
||||
@@ -1110,16 +1132,37 @@ static int DWC_init(void)
|
||||
return err;
|
||||
}
|
||||
|
||||
void rx_hdcp14_set_normal_key(const struct hdmi_rx_hdcp *hdcp)
|
||||
{
|
||||
unsigned int i = 0;
|
||||
unsigned int k = 0;
|
||||
int error = 0;
|
||||
|
||||
for (i = 0; i < HDCP_KEYS_SIZE; i += 2) {
|
||||
for (k = 0; k < HDCP_KEY_WR_TRIES; k++) {
|
||||
if (hdmirx_rd_bits_dwc(DWC_HDCP_STS,
|
||||
HDCP_KEY_WR_OK_STS) != 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (k < HDCP_KEY_WR_TRIES) {
|
||||
hdmirx_wr_dwc(DWC_HDCP_KEY1, hdcp->keys[i + 0]);
|
||||
hdmirx_wr_dwc(DWC_HDCP_KEY0, hdcp->keys[i + 1]);
|
||||
} else {
|
||||
error = -EAGAIN;
|
||||
break;
|
||||
}
|
||||
}
|
||||
hdmirx_wr_dwc(DWC_HDCP_BKSV1, hdcp->bksv[0]);
|
||||
hdmirx_wr_dwc(DWC_HDCP_BKSV0, hdcp->bksv[1]);
|
||||
}
|
||||
/*
|
||||
* hdmi_rx_ctrl_hdcp_config - config hdcp1.4 keys
|
||||
*/
|
||||
void rx_hdcp14_config(const struct hdmi_rx_hdcp *hdcp)
|
||||
{
|
||||
int error = 0;
|
||||
unsigned int i = 0;
|
||||
unsigned int k = 0;
|
||||
|
||||
unsigned int data32 = 0;
|
||||
|
||||
/* I2C_SPIKE_SUPPR */
|
||||
data32 |= 1 << 16;
|
||||
/* FAST_I2C */
|
||||
@@ -1143,24 +1186,13 @@ void rx_hdcp14_config(const struct hdmi_rx_hdcp *hdcp)
|
||||
/* hdmirx_wr_bits_dwc(ctx, DWC_HDCP_CTRL, KEY_DECRYPT_ENABLE, 1); */
|
||||
hdmirx_wr_bits_dwc(DWC_HDCP_CTRL, KEY_DECRYPT_ENABLE, 0);
|
||||
hdmirx_wr_dwc(DWC_HDCP_SEED, hdcp->seed);
|
||||
for (i = 0; i < HDCP_KEYS_SIZE; i += 2) {
|
||||
|
||||
for (k = 0; k < HDCP_KEY_WR_TRIES; k++) {
|
||||
if (hdmirx_rd_bits_dwc(DWC_HDCP_STS,
|
||||
HDCP_KEY_WR_OK_STS) != 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (k < HDCP_KEY_WR_TRIES) {
|
||||
hdmirx_wr_dwc(DWC_HDCP_KEY1, hdcp->keys[i + 0]);
|
||||
hdmirx_wr_dwc(DWC_HDCP_KEY0, hdcp->keys[i + 1]);
|
||||
} else {
|
||||
error = -EAGAIN;
|
||||
break;
|
||||
}
|
||||
if (hdcp14_key_mode == SECURE_MODE) {
|
||||
rx_set_hdcp14_secure_key();
|
||||
rx_pr("hdcp1.4 secure mode\n");
|
||||
} else {
|
||||
rx_hdcp14_set_normal_key(&rx.hdcp);
|
||||
rx_pr("hdcp1.4 normal mode\n");
|
||||
}
|
||||
hdmirx_wr_dwc(DWC_HDCP_BKSV1, hdcp->bksv[0]);
|
||||
hdmirx_wr_dwc(DWC_HDCP_BKSV0, hdcp->bksv[1]);
|
||||
if (rx.chip_id != CHIP_ID_TXHD) {
|
||||
hdmirx_wr_bits_dwc(DWC_HDCP_RPT_CTRL,
|
||||
REPEATER, hdcp->repeat ? 1 : 0);
|
||||
|
||||
@@ -980,6 +980,22 @@
|
||||
#define TMDS_CLK_MIN (24000UL)
|
||||
#define TMDS_CLK_MAX (340000UL)
|
||||
|
||||
/*
|
||||
* SMC CMD define
|
||||
* call BL31 interface
|
||||
*/
|
||||
#define HDMIRX_RD_SEC_TOP 0x8200001d
|
||||
#define HDMIRX_WR_SEC_TOP 0x8200001e
|
||||
#define HDCP22_RX_ESM_READ 0x8200001f
|
||||
#define HDCP22_RX_ESM_WRITE 0x8200002f
|
||||
#define HDCP22_RX_SET_DUK_KEY 0x8200002e
|
||||
#define HDCP14_RX_SETKEY 0x8200002d
|
||||
|
||||
enum hdcp14_key_mode_e {
|
||||
NORMAL_MODE,
|
||||
SECURE_MODE,
|
||||
};
|
||||
|
||||
extern unsigned int hdmirx_addr_port;
|
||||
extern unsigned int hdmirx_data_port;
|
||||
extern unsigned int hdmirx_ctrl_port;
|
||||
@@ -993,6 +1009,7 @@ extern int pd_fifo_start_cnt;
|
||||
extern int md_ists_en;
|
||||
extern int eq_ref_voltage;
|
||||
extern int aud_ch_map;
|
||||
extern int hdcp14_key_mode;
|
||||
|
||||
extern void wr_reg_hhi(unsigned int offset, unsigned int val);
|
||||
extern unsigned int rd_reg_hhi(unsigned int offset);
|
||||
|
||||
@@ -1262,8 +1262,8 @@ bool is_unnormal_format(uint8_t wait_cnt)
|
||||
if (sig_stable_max == wait_cnt)
|
||||
rx_pr("hdcp14 unfinished\n");
|
||||
if (unnormal_wait_max == wait_cnt) {
|
||||
if ((rx.hdcp.bksv[0] == 0) &&
|
||||
(rx.hdcp.bksv[1] == 0))
|
||||
if ((hdmirx_rd_dwc(DWC_HDCP_KEY1) == 0) &&
|
||||
(hdmirx_rd_dwc(DWC_HDCP_KEY0) == 0))
|
||||
rx.err_code = ERR_NO_HDCP14_KEY;
|
||||
ret = false;
|
||||
}
|
||||
@@ -2720,9 +2720,9 @@ static void dump_hdcp_data(void)
|
||||
rx_pr("\n hdcp-seed = %d ",
|
||||
rx.hdcp.seed);
|
||||
/* KSV CONFIDENTIAL */
|
||||
rx_pr("\n hdcp-ksv = %x---%x",
|
||||
rx.hdcp.bksv[0],
|
||||
rx.hdcp.bksv[1]);
|
||||
rx_pr("hdcp-bksv = %x---%x",
|
||||
hdmirx_rd_dwc(DWC_HDCP_BKSV1),
|
||||
hdmirx_rd_dwc(DWC_HDCP_BKSV0));
|
||||
rx_pr("\n*************HDCP end**********\n");
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user