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