rockchip: implement hdcp key decryption feature for rk3399

Decrypt device private keys which transfer from kernel, then stuff it to
DP controller. So that DP driver could start HDCP authentication in
kernel.

Change-Id: If3c2cd99bca811fe5fc30acc88bf5dc1afd7416d
Signed-off-by: Ziyuan Xu <xzy.xu@rock-chips.com>
Signed-off-by: Caesar Wang <wxt@rock-chips.com>
This commit is contained in:
Ziyuan Xu 2017-02-10 11:54:52 +08:00 committed by Caesar Wang
parent c76631c52b
commit 10301bf7ea
3 changed files with 105 additions and 0 deletions

View File

@ -4,7 +4,10 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <cdn_dp.h>
#include <smcc.h>
#include <stdlib.h>
#include <string.h>
__asm__(
".pushsection .text.hdcp_handler, \"ax\", %progbits\n"
@ -17,3 +20,46 @@ __asm__(
".popsection\n"
);
static uint64_t *hdcp_key_pdata;
static struct cdn_dp_hdcp_key_1x key;
int hdcp_handler(struct cdn_dp_hdcp_key_1x *key);
uint64_t dp_hdcp_ctrl(uint64_t type)
{
switch (type) {
case HDCP_KEY_DATA_START_TRANSFER:
memset(&key, 0x00, sizeof(key));
hdcp_key_pdata = (uint64_t *)&key;
return 0;
case HDCP_KEY_DATA_START_DECRYPT:
if (hdcp_key_pdata == (uint64_t *)(&key + 1))
return hdcp_handler(&key);
else
return PSCI_E_INVALID_PARAMS;
default:
return SMC_UNK;
}
}
uint64_t dp_hdcp_store_key(uint64_t x1,
uint64_t x2,
uint64_t x3,
uint64_t x4,
uint64_t x5,
uint64_t x6)
{
if (hdcp_key_pdata < (uint64_t *)&key ||
hdcp_key_pdata + 6 > (uint64_t *)(&key + 1))
return PSCI_E_INVALID_PARAMS;
hdcp_key_pdata[0] = x1;
hdcp_key_pdata[1] = x2;
hdcp_key_pdata[2] = x3;
hdcp_key_pdata[3] = x4;
hdcp_key_pdata[4] = x5;
hdcp_key_pdata[5] = x6;
hdcp_key_pdata += 6;
return 0;
}

View File

@ -0,0 +1,47 @@
/*
* Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef __SOC_ROCKCHIP_RK3399_DP_H__
#define __SOC_ROCKCHIP_RK3399_DP_H__
#include <plat_private.h>
enum {
CDN_DP_HDCP_1X_KSV_LEN = 5,
CDN_DP_HDCP_KSV_LEN = 8,
CDN_DP_HDCP_RESERVED_LEN = 10,
CDN_DP_HDCP_UID_LEN = 16,
CDN_DP_HDCP_SHA_LEN = 20,
CDN_DP_HDCP_DPK_LEN = 280,
CDN_DP_HDCP_1X_KEYS_LEN = 285,
CDN_DP_HDCP_KEY_LEN = 326,
};
struct cdn_dp_hdcp_key_1x {
uint8_t ksv[CDN_DP_HDCP_KSV_LEN];
uint8_t device_key[CDN_DP_HDCP_DPK_LEN];
uint8_t sha1[CDN_DP_HDCP_SHA_LEN];
uint8_t uid[CDN_DP_HDCP_UID_LEN];
uint16_t seed;
uint8_t reserved[CDN_DP_HDCP_RESERVED_LEN];
};
#define HDCP_KEY_DATA_START_TRANSFER 0
#define HDCP_KEY_DATA_START_DECRYPT 1
#define HDCP_KEY_1X_STORE_DATA_ALIGN_SIZE (6 * 64) / 8
/* Checks the cdn_dp_hdcp_key_1x must be aligned on 6 x 64-bit word boundary */
CASSERT(sizeof(struct cdn_dp_hdcp_key_1x) % HDCP_KEY_1X_STORE_DATA_ALIGN_SIZE, \
assert_hdcp_key_1x_store_data_align_size_mismatch);
uint64_t dp_hdcp_ctrl(uint64_t type);
uint64_t dp_hdcp_store_key(uint64_t x1,
uint64_t x2,
uint64_t x3,
uint64_t x4,
uint64_t x5,
uint64_t x6);
#endif

View File

@ -4,6 +4,7 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <cdn_dp.h>
#include <debug.h>
#include <mmio.h>
#include <plat_sip_calls.h>
@ -22,6 +23,9 @@
#define DRAM_SET_PARAM 0x07
#define DRAM_SET_ODT_PD 0x08
#define RK_SIP_HDCP_CONTROL 0x82000009
#define RK_SIP_HDCP_KEY_DATA64 0xC200000A
uint32_t ddr_smc_handler(uint64_t arg0, uint64_t arg1,
uint64_t id, uint64_t arg2)
{
@ -51,9 +55,17 @@ uint64_t rockchip_plat_sip_handler(uint32_t smc_fid,
void *handle,
uint64_t flags)
{
uint64_t x5, x6;
switch (smc_fid) {
case RK_SIP_DDR_CFG:
SMC_RET1(handle, ddr_smc_handler(x1, x2, x3, x4));
case RK_SIP_HDCP_CONTROL:
SMC_RET1(handle, dp_hdcp_ctrl(x1));
case RK_SIP_HDCP_KEY_DATA64:
x5 = read_ctx_reg(get_gpregs_ctx(handle), CTX_GPREG_X5);
x6 = read_ctx_reg(get_gpregs_ctx(handle), CTX_GPREG_X6);
SMC_RET1(handle, dp_hdcp_store_key(x1, x2, x3, x4, x5, x6));
default:
ERROR("%s: unhandled SMC (0x%x)\n", __func__, smc_fid);
SMC_RET1(handle, SMC_UNK);