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