xref: /rk3399_ARM-atf/plat/mediatek/mt8173/drivers/crypt/crypt.c (revision 7ace1cc088adf4e0dc10f41fa2571129d9f52e53)
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