xref: /arm-trusted-firmware/plat/mediatek/mt8173/drivers/crypt/crypt.c (revision 91f16700b400a8c0651d24a598fc48ee2997a0d7)
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