1c76631c5SZiyuan Xu /* 2085e80ecSAntonio Nino Diaz * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. 3c76631c5SZiyuan Xu * 4c76631c5SZiyuan Xu * SPDX-License-Identifier: BSD-3-Clause 5c76631c5SZiyuan Xu */ 6c76631c5SZiyuan Xu 7a08a2014SDaniel Boulby #include <assert.h> 893c78ed2SAntonio Nino Diaz #include <cdefs.h> 9c76631c5SZiyuan Xu #include <stdlib.h> 1010301bf7SZiyuan Xu #include <string.h> 11c76631c5SZiyuan Xu 1209d40e0eSAntonio Nino Diaz #include <lib/smccc.h> 1309d40e0eSAntonio Nino Diaz 1409d40e0eSAntonio Nino Diaz #include <cdn_dp.h> 1509d40e0eSAntonio Nino Diaz 16c76631c5SZiyuan Xu __asm__( 17c76631c5SZiyuan Xu ".pushsection .text.hdcp_handler, \"ax\", %progbits\n" 18c76631c5SZiyuan Xu ".global hdcp_handler\n" 19c76631c5SZiyuan Xu ".balign 4\n" 20c76631c5SZiyuan Xu "hdcp_handler:\n" 21*39a97dceSJoshua Watt ".incbin \"" HDCPFW "\"\n" 22c76631c5SZiyuan Xu ".type hdcp_handler, %function\n" 23c76631c5SZiyuan Xu ".size hdcp_handler, .- hdcp_handler\n" 24c76631c5SZiyuan Xu ".popsection\n" 25c76631c5SZiyuan Xu ); 26c76631c5SZiyuan Xu 2710301bf7SZiyuan Xu static uint64_t *hdcp_key_pdata; 2810301bf7SZiyuan Xu static struct cdn_dp_hdcp_key_1x key; 2910301bf7SZiyuan Xu 3010301bf7SZiyuan Xu int hdcp_handler(struct cdn_dp_hdcp_key_1x *key); 3110301bf7SZiyuan Xu 3210301bf7SZiyuan Xu uint64_t dp_hdcp_ctrl(uint64_t type) 3310301bf7SZiyuan Xu { 3410301bf7SZiyuan Xu switch (type) { 3510301bf7SZiyuan Xu case HDCP_KEY_DATA_START_TRANSFER: 3610301bf7SZiyuan Xu memset(&key, 0x00, sizeof(key)); 3710301bf7SZiyuan Xu hdcp_key_pdata = (uint64_t *)&key; 3810301bf7SZiyuan Xu return 0; 3910301bf7SZiyuan Xu case HDCP_KEY_DATA_START_DECRYPT: 4010301bf7SZiyuan Xu if (hdcp_key_pdata == (uint64_t *)(&key + 1)) 4110301bf7SZiyuan Xu return hdcp_handler(&key); 4210301bf7SZiyuan Xu else 4310301bf7SZiyuan Xu return PSCI_E_INVALID_PARAMS; 44a08a2014SDaniel Boulby assert(0); /* Unreachable */ 4510301bf7SZiyuan Xu default: 4610301bf7SZiyuan Xu return SMC_UNK; 4710301bf7SZiyuan Xu } 4810301bf7SZiyuan Xu } 4910301bf7SZiyuan Xu 5010301bf7SZiyuan Xu uint64_t dp_hdcp_store_key(uint64_t x1, 5110301bf7SZiyuan Xu uint64_t x2, 5210301bf7SZiyuan Xu uint64_t x3, 5310301bf7SZiyuan Xu uint64_t x4, 5410301bf7SZiyuan Xu uint64_t x5, 5510301bf7SZiyuan Xu uint64_t x6) 5610301bf7SZiyuan Xu { 5710301bf7SZiyuan Xu if (hdcp_key_pdata < (uint64_t *)&key || 5810301bf7SZiyuan Xu hdcp_key_pdata + 6 > (uint64_t *)(&key + 1)) 5910301bf7SZiyuan Xu return PSCI_E_INVALID_PARAMS; 6010301bf7SZiyuan Xu 6110301bf7SZiyuan Xu hdcp_key_pdata[0] = x1; 6210301bf7SZiyuan Xu hdcp_key_pdata[1] = x2; 6310301bf7SZiyuan Xu hdcp_key_pdata[2] = x3; 6410301bf7SZiyuan Xu hdcp_key_pdata[3] = x4; 6510301bf7SZiyuan Xu hdcp_key_pdata[4] = x5; 6610301bf7SZiyuan Xu hdcp_key_pdata[5] = x6; 6710301bf7SZiyuan Xu hdcp_key_pdata += 6; 6810301bf7SZiyuan Xu 6910301bf7SZiyuan Xu return 0; 7010301bf7SZiyuan Xu } 71