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 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