1*91f16700Schasinglulu /* 2*91f16700Schasinglulu * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved. 3*91f16700Schasinglulu * 4*91f16700Schasinglulu * SPDX-License-Identifier: BSD-3-Clause 5*91f16700Schasinglulu */ 6*91f16700Schasinglulu 7*91f16700Schasinglulu #include <assert.h> 8*91f16700Schasinglulu 9*91f16700Schasinglulu #include <arch.h> 10*91f16700Schasinglulu #include <arch_helpers.h> 11*91f16700Schasinglulu #include <common/debug.h> 12*91f16700Schasinglulu #include <drivers/delay_timer.h> 13*91f16700Schasinglulu #include <lib/mmio.h> 14*91f16700Schasinglulu 15*91f16700Schasinglulu #include <mt8173_def.h> 16*91f16700Schasinglulu #include <mtk_sip_svc.h> 17*91f16700Schasinglulu 18*91f16700Schasinglulu #define crypt_read32(offset) \ 19*91f16700Schasinglulu mmio_read_32((uintptr_t)(CRYPT_BASE+((offset) * 4))) 20*91f16700Schasinglulu 21*91f16700Schasinglulu #define crypt_write32(offset, value) \ 22*91f16700Schasinglulu mmio_write_32((uintptr_t)(CRYPT_BASE + ((offset) * 4)), (uint32_t)value) 23*91f16700Schasinglulu 24*91f16700Schasinglulu #define GET_L32(x) ((uint32_t)(x & 0xffffffff)) 25*91f16700Schasinglulu #define GET_H32(x) ((uint32_t)((x >> 32) & 0xffffffff)) 26*91f16700Schasinglulu 27*91f16700Schasinglulu #define REG_INIT 0 28*91f16700Schasinglulu #define REG_MSC 4 29*91f16700Schasinglulu #define REG_TRIG 256 30*91f16700Schasinglulu #define REG_STAT 512 31*91f16700Schasinglulu #define REG_CLR 513 32*91f16700Schasinglulu #define REG_INT 514 33*91f16700Schasinglulu #define REG_P68 768 34*91f16700Schasinglulu #define REG_P69 769 35*91f16700Schasinglulu #define REG_P70 770 36*91f16700Schasinglulu #define REG_P71 771 37*91f16700Schasinglulu #define REG_P72 772 38*91f16700Schasinglulu #define REG_D20 820 39*91f16700Schasinglulu #define KEY_SIZE 160 40*91f16700Schasinglulu #define KEY_LEN 40 41*91f16700Schasinglulu 42*91f16700Schasinglulu /* Wait until crypt is completed */ 43*91f16700Schasinglulu uint64_t crypt_wait(void) 44*91f16700Schasinglulu { 45*91f16700Schasinglulu crypt_write32(REG_TRIG, 0); 46*91f16700Schasinglulu while (crypt_read32(REG_STAT) == 0) 47*91f16700Schasinglulu ; 48*91f16700Schasinglulu udelay(100); 49*91f16700Schasinglulu crypt_write32(REG_CLR, crypt_read32(REG_STAT)); 50*91f16700Schasinglulu crypt_write32(REG_INT, 0); 51*91f16700Schasinglulu return MTK_SIP_E_SUCCESS; 52*91f16700Schasinglulu } 53*91f16700Schasinglulu 54*91f16700Schasinglulu static uint32_t record[4]; 55*91f16700Schasinglulu /* Copy encrypted key to crypt engine */ 56*91f16700Schasinglulu uint64_t crypt_set_hdcp_key_ex(uint64_t x1, uint64_t x2, uint64_t x3) 57*91f16700Schasinglulu { 58*91f16700Schasinglulu uint32_t i = (uint32_t)x1; 59*91f16700Schasinglulu uint32_t j = 0; 60*91f16700Schasinglulu 61*91f16700Schasinglulu if (i > KEY_LEN) 62*91f16700Schasinglulu return MTK_SIP_E_INVALID_PARAM; 63*91f16700Schasinglulu 64*91f16700Schasinglulu if (i < KEY_LEN) { 65*91f16700Schasinglulu crypt_write32(REG_MSC, 0x80ff3800); 66*91f16700Schasinglulu crypt_write32(REG_INIT, 0); 67*91f16700Schasinglulu crypt_write32(REG_INIT, 0xF); 68*91f16700Schasinglulu crypt_write32(REG_CLR, 1); 69*91f16700Schasinglulu crypt_write32(REG_INT, 0); 70*91f16700Schasinglulu 71*91f16700Schasinglulu crypt_write32(REG_P68, 0x70); 72*91f16700Schasinglulu crypt_write32(REG_P69, 0x1C0); 73*91f16700Schasinglulu crypt_write32(REG_P70, 0x30); 74*91f16700Schasinglulu crypt_write32(REG_P71, 0x4); 75*91f16700Schasinglulu crypt_wait(); 76*91f16700Schasinglulu 77*91f16700Schasinglulu crypt_write32(REG_D20 + 4 * i, GET_L32(x2)); 78*91f16700Schasinglulu crypt_write32(REG_D20 + 4 * i + 1, GET_H32(x2)); 79*91f16700Schasinglulu crypt_write32(REG_D20 + 4 * i + 2, GET_L32(x3)); 80*91f16700Schasinglulu crypt_write32(REG_D20 + 4 * i + 3, GET_H32(x3)); 81*91f16700Schasinglulu 82*91f16700Schasinglulu crypt_write32(REG_P69, 0); 83*91f16700Schasinglulu crypt_write32(REG_P68, 0x20); 84*91f16700Schasinglulu crypt_write32(REG_P71, 0x34 + 4 * i); 85*91f16700Schasinglulu crypt_write32(REG_P72, 0x34 + 4 * i); 86*91f16700Schasinglulu crypt_wait(); 87*91f16700Schasinglulu 88*91f16700Schasinglulu for (j = 0; j < 4; j++) { 89*91f16700Schasinglulu crypt_write32(REG_P68, 0x71); 90*91f16700Schasinglulu crypt_write32(REG_P69, 0x34 + 4 * i + j); 91*91f16700Schasinglulu crypt_write32(REG_P70, record[j]); 92*91f16700Schasinglulu crypt_wait(); 93*91f16700Schasinglulu } 94*91f16700Schasinglulu } 95*91f16700Schasinglulu /* Prepare data for next iteration */ 96*91f16700Schasinglulu record[0] = GET_L32(x2); 97*91f16700Schasinglulu record[1] = GET_H32(x2); 98*91f16700Schasinglulu record[2] = GET_L32(x3); 99*91f16700Schasinglulu record[3] = GET_H32(x3); 100*91f16700Schasinglulu return MTK_SIP_E_SUCCESS; 101*91f16700Schasinglulu } 102*91f16700Schasinglulu 103*91f16700Schasinglulu /* Set key to hdcp */ 104*91f16700Schasinglulu uint64_t crypt_set_hdcp_key_num(uint32_t num) 105*91f16700Schasinglulu { 106*91f16700Schasinglulu if (num > KEY_LEN) 107*91f16700Schasinglulu return MTK_SIP_E_INVALID_PARAM; 108*91f16700Schasinglulu 109*91f16700Schasinglulu crypt_write32(REG_P68, 0x6A); 110*91f16700Schasinglulu crypt_write32(REG_P69, 0x34 + 4 * num); 111*91f16700Schasinglulu crypt_wait(); 112*91f16700Schasinglulu return MTK_SIP_E_SUCCESS; 113*91f16700Schasinglulu } 114*91f16700Schasinglulu 115*91f16700Schasinglulu /* Clear key in crypt engine */ 116*91f16700Schasinglulu uint64_t crypt_clear_hdcp_key(void) 117*91f16700Schasinglulu { 118*91f16700Schasinglulu uint32_t i; 119*91f16700Schasinglulu 120*91f16700Schasinglulu for (i = 0; i < KEY_SIZE; i++) 121*91f16700Schasinglulu crypt_write32(REG_D20 + i, 0); 122*91f16700Schasinglulu return MTK_SIP_E_SUCCESS; 123*91f16700Schasinglulu } 124