diff --git a/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_drv.c b/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_drv.c index 5faf346d125c..a75901c6643a 100644 --- a/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_drv.c +++ b/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_drv.c @@ -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; diff --git a/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_drv.h b/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_drv.h index 6114bff1098f..efe571b21a89 100644 --- a/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_drv.h +++ b/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_drv.h @@ -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) diff --git a/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_hw.c b/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_hw.c index 7d3af12af550..4e98762e0e5b 100644 --- a/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_hw.c +++ b/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_hw.c @@ -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); diff --git a/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_hw.h b/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_hw.h index 947111aa540c..dda52eea11bd 100644 --- a/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_hw.h +++ b/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_hw.h @@ -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); diff --git a/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_wrapper.c b/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_wrapper.c index 7329a3fdb421..71b56ed0872e 100644 --- a/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_wrapper.c +++ b/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_wrapper.c @@ -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"); }