1*7ace1cc0SYi Zheng /* 2*7ace1cc0SYi Zheng * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved. 3*7ace1cc0SYi Zheng * 4*7ace1cc0SYi Zheng * Redistribution and use in source and binary forms, with or without 5*7ace1cc0SYi Zheng * modification, are permitted provided that the following conditions are met: 6*7ace1cc0SYi Zheng * 7*7ace1cc0SYi Zheng * Redistributions of source code must retain the above copyright notice, this 8*7ace1cc0SYi Zheng * list of conditions and the following disclaimer. 9*7ace1cc0SYi Zheng * 10*7ace1cc0SYi Zheng * Redistributions in binary form must reproduce the above copyright notice, 11*7ace1cc0SYi Zheng * this list of conditions and the following disclaimer in the documentation 12*7ace1cc0SYi Zheng * and/or other materials provided with the distribution. 13*7ace1cc0SYi Zheng * 14*7ace1cc0SYi Zheng * Neither the name of ARM nor the names of its contributors may be used 15*7ace1cc0SYi Zheng * to endorse or promote products derived from this software without specific 16*7ace1cc0SYi Zheng * prior written permission. 17*7ace1cc0SYi Zheng * 18*7ace1cc0SYi Zheng * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19*7ace1cc0SYi Zheng * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20*7ace1cc0SYi Zheng * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21*7ace1cc0SYi Zheng * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 22*7ace1cc0SYi Zheng * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23*7ace1cc0SYi Zheng * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24*7ace1cc0SYi Zheng * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25*7ace1cc0SYi Zheng * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26*7ace1cc0SYi Zheng * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27*7ace1cc0SYi Zheng * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28*7ace1cc0SYi Zheng * POSSIBILITY OF SUCH DAMAGE. 29*7ace1cc0SYi Zheng */ 30*7ace1cc0SYi Zheng #include <arch.h> 31*7ace1cc0SYi Zheng #include <arch_helpers.h> 32*7ace1cc0SYi Zheng #include <assert.h> 33*7ace1cc0SYi Zheng #include <debug.h> 34*7ace1cc0SYi Zheng #include <delay_timer.h> 35*7ace1cc0SYi Zheng #include <mmio.h> 36*7ace1cc0SYi Zheng #include <mt8173_def.h> 37*7ace1cc0SYi Zheng #include <mtk_sip_svc.h> 38*7ace1cc0SYi Zheng 39*7ace1cc0SYi Zheng #define crypt_read32(offset) \ 40*7ace1cc0SYi Zheng mmio_read_32((uintptr_t)(CRYPT_BASE+((offset) * 4))) 41*7ace1cc0SYi Zheng 42*7ace1cc0SYi Zheng #define crypt_write32(offset, value) \ 43*7ace1cc0SYi Zheng mmio_write_32((uintptr_t)(CRYPT_BASE + ((offset) * 4)), (uint32_t)value) 44*7ace1cc0SYi Zheng 45*7ace1cc0SYi Zheng #define GET_L32(x) ((uint32_t)(x & 0xffffffff)) 46*7ace1cc0SYi Zheng #define GET_H32(x) ((uint32_t)((x >> 32) & 0xffffffff)) 47*7ace1cc0SYi Zheng 48*7ace1cc0SYi Zheng #define REG_INIT 0 49*7ace1cc0SYi Zheng #define REG_MSC 4 50*7ace1cc0SYi Zheng #define REG_TRIG 256 51*7ace1cc0SYi Zheng #define REG_STAT 512 52*7ace1cc0SYi Zheng #define REG_CLR 513 53*7ace1cc0SYi Zheng #define REG_INT 514 54*7ace1cc0SYi Zheng #define REG_P68 768 55*7ace1cc0SYi Zheng #define REG_P69 769 56*7ace1cc0SYi Zheng #define REG_P70 770 57*7ace1cc0SYi Zheng #define REG_P71 771 58*7ace1cc0SYi Zheng #define REG_P72 772 59*7ace1cc0SYi Zheng #define REG_D20 820 60*7ace1cc0SYi Zheng #define KEY_SIZE 160 61*7ace1cc0SYi Zheng #define KEY_LEN 40 62*7ace1cc0SYi Zheng 63*7ace1cc0SYi Zheng /* Wait until crypt is completed */ 64*7ace1cc0SYi Zheng uint64_t crypt_wait(void) 65*7ace1cc0SYi Zheng { 66*7ace1cc0SYi Zheng crypt_write32(REG_TRIG, 0); 67*7ace1cc0SYi Zheng while (crypt_read32(REG_STAT) == 0) 68*7ace1cc0SYi Zheng ; 69*7ace1cc0SYi Zheng udelay(100); 70*7ace1cc0SYi Zheng crypt_write32(REG_CLR, crypt_read32(REG_STAT)); 71*7ace1cc0SYi Zheng crypt_write32(REG_INT, 0); 72*7ace1cc0SYi Zheng return MTK_SIP_E_SUCCESS; 73*7ace1cc0SYi Zheng } 74*7ace1cc0SYi Zheng 75*7ace1cc0SYi Zheng static uint32_t record[4]; 76*7ace1cc0SYi Zheng /* Copy encrypted key to crypt engine */ 77*7ace1cc0SYi Zheng uint64_t crypt_set_hdcp_key_ex(uint64_t x1, uint64_t x2, uint64_t x3) 78*7ace1cc0SYi Zheng { 79*7ace1cc0SYi Zheng uint32_t i = (uint32_t)x1; 80*7ace1cc0SYi Zheng uint32_t j = 0; 81*7ace1cc0SYi Zheng 82*7ace1cc0SYi Zheng if (i > KEY_LEN) 83*7ace1cc0SYi Zheng return MTK_SIP_E_INVALID_PARAM; 84*7ace1cc0SYi Zheng 85*7ace1cc0SYi Zheng if (i < KEY_LEN) { 86*7ace1cc0SYi Zheng crypt_write32(REG_MSC, 0x80ff3800); 87*7ace1cc0SYi Zheng crypt_write32(REG_INIT, 0); 88*7ace1cc0SYi Zheng crypt_write32(REG_INIT, 0xF); 89*7ace1cc0SYi Zheng crypt_write32(REG_CLR, 1); 90*7ace1cc0SYi Zheng crypt_write32(REG_INT, 0); 91*7ace1cc0SYi Zheng 92*7ace1cc0SYi Zheng crypt_write32(REG_P68, 0x70); 93*7ace1cc0SYi Zheng crypt_write32(REG_P69, 0x1C0); 94*7ace1cc0SYi Zheng crypt_write32(REG_P70, 0x30); 95*7ace1cc0SYi Zheng crypt_write32(REG_P71, 0x4); 96*7ace1cc0SYi Zheng crypt_wait(); 97*7ace1cc0SYi Zheng 98*7ace1cc0SYi Zheng crypt_write32(REG_D20 + 4 * i, GET_L32(x2)); 99*7ace1cc0SYi Zheng crypt_write32(REG_D20 + 4 * i + 1, GET_H32(x2)); 100*7ace1cc0SYi Zheng crypt_write32(REG_D20 + 4 * i + 2, GET_L32(x3)); 101*7ace1cc0SYi Zheng crypt_write32(REG_D20 + 4 * i + 3, GET_H32(x3)); 102*7ace1cc0SYi Zheng 103*7ace1cc0SYi Zheng crypt_write32(REG_P69, 0); 104*7ace1cc0SYi Zheng crypt_write32(REG_P68, 0x20); 105*7ace1cc0SYi Zheng crypt_write32(REG_P71, 0x34 + 4 * i); 106*7ace1cc0SYi Zheng crypt_write32(REG_P72, 0x34 + 4 * i); 107*7ace1cc0SYi Zheng crypt_wait(); 108*7ace1cc0SYi Zheng 109*7ace1cc0SYi Zheng for (j = 0; j < 4; j++) { 110*7ace1cc0SYi Zheng crypt_write32(REG_P68, 0x71); 111*7ace1cc0SYi Zheng crypt_write32(REG_P69, 0x34 + 4 * i + j); 112*7ace1cc0SYi Zheng crypt_write32(REG_P70, record[j]); 113*7ace1cc0SYi Zheng crypt_wait(); 114*7ace1cc0SYi Zheng } 115*7ace1cc0SYi Zheng } 116*7ace1cc0SYi Zheng /* Prepare data for next iteration */ 117*7ace1cc0SYi Zheng record[0] = GET_L32(x2); 118*7ace1cc0SYi Zheng record[1] = GET_H32(x2); 119*7ace1cc0SYi Zheng record[2] = GET_L32(x3); 120*7ace1cc0SYi Zheng record[3] = GET_H32(x3); 121*7ace1cc0SYi Zheng return MTK_SIP_E_SUCCESS; 122*7ace1cc0SYi Zheng } 123*7ace1cc0SYi Zheng 124*7ace1cc0SYi Zheng /* Set key to hdcp */ 125*7ace1cc0SYi Zheng uint64_t crypt_set_hdcp_key_num(uint32_t num) 126*7ace1cc0SYi Zheng { 127*7ace1cc0SYi Zheng if (num > KEY_LEN) 128*7ace1cc0SYi Zheng return MTK_SIP_E_INVALID_PARAM; 129*7ace1cc0SYi Zheng 130*7ace1cc0SYi Zheng crypt_write32(REG_P68, 0x6A); 131*7ace1cc0SYi Zheng crypt_write32(REG_P69, 0x34 + 4 * num); 132*7ace1cc0SYi Zheng crypt_wait(); 133*7ace1cc0SYi Zheng return MTK_SIP_E_SUCCESS; 134*7ace1cc0SYi Zheng } 135*7ace1cc0SYi Zheng 136*7ace1cc0SYi Zheng /* Clear key in crypt engine */ 137*7ace1cc0SYi Zheng uint64_t crypt_clear_hdcp_key(void) 138*7ace1cc0SYi Zheng { 139*7ace1cc0SYi Zheng uint32_t i; 140*7ace1cc0SYi Zheng 141*7ace1cc0SYi Zheng for (i = 0; i < KEY_SIZE; i++) 142*7ace1cc0SYi Zheng crypt_write32(REG_D20 + i, 0); 143*7ace1cc0SYi Zheng return MTK_SIP_E_SUCCESS; 144*7ace1cc0SYi Zheng } 145