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