xref: /OK3568_Linux_fs/u-boot/arch/arm/mach-rockchip/vendor_misc.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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 
vendor_handle_hdcp(struct vendor_item * vhead)22 int vendor_handle_hdcp(struct vendor_item *vhead)
23 {
24 	struct arm_smccc_res res;
25 	struct hdcpdata *hdcp;
26 	char *shm;
27 	u32 crc, len;
28 	int ret;
29 
30 	hdcp = (void *)vhead + sizeof(struct vendor_item);
31 	if ((hdcp->signature != HDCP_SIGNED) || !(hdcp->flags & HDCP_FLG_AES))
32 		return 0;
33 
34 	crc = crc32(0, hdcp->data, hdcp->length);
35 	if (crc != hdcp->crc32) {
36 		printf("%s: bad crc32 0x%08x != 0x%08x\n",
37 		       __func__, crc, hdcp->crc32);
38 		return -EIO;
39 	}
40 
41 	res = sip_smc_request_share_mem(2, SHARE_PAGE_TYPE_HDCP);
42 	if (res.a0) {
43 		printf("%s: Can't get share mem\n", __func__);
44 		return -EIO;
45 	}
46 
47 	shm = (char *)res.a1;
48 	len = sizeof(struct hdcpdata) + hdcp->length;
49 
50 	memcpy(shm, hdcp, len);
51 	flush_dcache_range((ulong)shm, (ulong)(shm + len));
52 
53 	ret = sip_smc_hdcp_config(HDCP_FUNC_STORAGE_ENCRYPT, 0, 0);
54 	if (ret) {
55 		printf("%s: failed, ret=%d\n", __func__, ret);
56 		return -EIO;
57 	}
58 
59 	invalidate_dcache_range((ulong)shm, (ulong)(shm + len));
60 	memcpy(hdcp, shm, len);
61 
62 	return 0;
63 }
64 
65