hdmirx: add new hdcp14 key configuration method
authoryicheng shen <yicheng.shen@amlogic.com>
Tue, 26 Jun 2018 03:02:22 +0000 (11:02 +0800)
committerJianxin Pan <jianxin.pan@amlogic.com>
Wed, 15 Aug 2018 11:34:03 +0000 (04:34 -0700)
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>
drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_drv.c
drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_drv.h
drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_hw.c
drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_hw.h
drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_wrapper.c

index 5faf346..a75901c 100644 (file)
@@ -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;
index 6114bff..efe571b 100644 (file)
@@ -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)
index 7d3af12..4e98762 100644 (file)
@@ -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);
index 947111a..dda52ee 100644 (file)
 #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);
index 7329a3f..71b56ed 100644 (file)
@@ -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");
 }