1 /*
2 * Copyright 2022 Rockchip Electronics Co., Ltd
3 *
4 * SPDX-License-Identifier: GPL-2.0+
5 */
6
7 #include <common.h>
8 #include <asm/arch/rockchip_smccc.h>
9 #include <asm/arch/vendor.h>
10
11 #define HDCP_SIGNED 0x4B534541 /* "AESK" */
12 #define HDCP_FLG_AES (1 << 0)
13
14 struct hdcpdata {
15 unsigned int signature;
16 unsigned int length;
17 unsigned int crc32;
18 unsigned int flags;
19 unsigned char data[0];
20 };
21
22 #ifndef CONFIG_SUPPORT_USBPLUG
vendor_handle_hdcp(struct vendor_item * vhead)23 int vendor_handle_hdcp(struct vendor_item *vhead)
24 {
25 struct arm_smccc_res res;
26 struct hdcpdata *hdcp;
27 char *shm;
28 u32 crc, len;
29 int ret;
30
31 hdcp = (void *)vhead + sizeof(struct vendor_item);
32 if ((hdcp->signature != HDCP_SIGNED) || !(hdcp->flags & HDCP_FLG_AES))
33 return 0;
34
35 crc = crc32(0, hdcp->data, hdcp->length);
36 if (crc != hdcp->crc32) {
37 printf("%s: bad crc32 0x%08x != 0x%08x\n",
38 __func__, crc, hdcp->crc32);
39 return -EIO;
40 }
41
42 res = sip_smc_request_share_mem(2, SHARE_PAGE_TYPE_HDCP);
43 if (res.a0) {
44 printf("%s: Can't get share mem\n", __func__);
45 return -EIO;
46 }
47
48 shm = (char *)res.a1;
49 len = sizeof(struct hdcpdata) + hdcp->length;
50
51 memcpy(shm, hdcp, len);
52 flush_dcache_range((ulong)shm, (ulong)(shm + len));
53
54 ret = sip_smc_hdcp_config(HDCP_FUNC_STORAGE_ENCRYPT, 0, 0);
55 if (ret) {
56 printf("%s: failed, ret=%d\n", __func__, ret);
57 return -EIO;
58 }
59
60 invalidate_dcache_range((ulong)shm, (ulong)(shm + len));
61 memcpy(hdcp, shm, len);
62
63 return 0;
64 }
65 #endif
66