xref: /rk3399_ARM-atf/drivers/st/crypto/stm32_hash.c (revision 68039f2d14626adce09512871d6cde20ff45e1d9)
1b1e0b11cSLionel Debieve /*
2*68039f2dSNicolas Toromanoff  * Copyright (c) 2019-2022, STMicroelectronics - All Rights Reserved
3b1e0b11cSLionel Debieve  *
4b1e0b11cSLionel Debieve  * SPDX-License-Identifier: BSD-3-Clause
5b1e0b11cSLionel Debieve  */
6b1e0b11cSLionel Debieve 
7b1e0b11cSLionel Debieve #include <assert.h>
8b1e0b11cSLionel Debieve #include <errno.h>
9b1e0b11cSLionel Debieve #include <stdint.h>
10b1e0b11cSLionel Debieve 
11b1e0b11cSLionel Debieve #include <arch_helpers.h>
12b1e0b11cSLionel Debieve #include <common/debug.h>
1333667d29SYann Gautier #include <drivers/clk.h>
14b1e0b11cSLionel Debieve #include <drivers/delay_timer.h>
15b1e0b11cSLionel Debieve #include <drivers/st/stm32_hash.h>
16b1e0b11cSLionel Debieve #include <drivers/st/stm32mp_reset.h>
17b1e0b11cSLionel Debieve #include <lib/mmio.h>
18b1e0b11cSLionel Debieve #include <lib/utils.h>
19*68039f2dSNicolas Toromanoff #include <libfdt.h>
20b1e0b11cSLionel Debieve #include <plat/common/platform.h>
21b1e0b11cSLionel Debieve 
22*68039f2dSNicolas Toromanoff #include <platform_def.h>
23*68039f2dSNicolas Toromanoff 
24*68039f2dSNicolas Toromanoff #if STM32_HASH_VER == 2
25b1e0b11cSLionel Debieve #define DT_HASH_COMPAT			"st,stm32f756-hash"
26*68039f2dSNicolas Toromanoff #endif
27*68039f2dSNicolas Toromanoff #if STM32_HASH_VER == 4
28*68039f2dSNicolas Toromanoff #define DT_HASH_COMPAT			"st,stm32mp13-hash"
29*68039f2dSNicolas Toromanoff #endif
30b1e0b11cSLionel Debieve 
31b1e0b11cSLionel Debieve #define HASH_CR				0x00U
32b1e0b11cSLionel Debieve #define HASH_DIN			0x04U
33b1e0b11cSLionel Debieve #define HASH_STR			0x08U
34b1e0b11cSLionel Debieve #define HASH_SR				0x24U
35b1e0b11cSLionel Debieve #define HASH_HREG(x)			(0x310U + ((x) * 0x04U))
36b1e0b11cSLionel Debieve 
37b1e0b11cSLionel Debieve /* Control Register */
38b1e0b11cSLionel Debieve #define HASH_CR_INIT			BIT(2)
39b1e0b11cSLionel Debieve #define HASH_CR_DATATYPE_SHIFT		U(4)
40*68039f2dSNicolas Toromanoff #if STM32_HASH_VER == 2
41b1e0b11cSLionel Debieve #define HASH_CR_ALGO_SHA1		0x0U
42b1e0b11cSLionel Debieve #define HASH_CR_ALGO_MD5		BIT(7)
43b1e0b11cSLionel Debieve #define HASH_CR_ALGO_SHA224		BIT(18)
44b1e0b11cSLionel Debieve #define HASH_CR_ALGO_SHA256		(BIT(18) | BIT(7))
45*68039f2dSNicolas Toromanoff #endif
46*68039f2dSNicolas Toromanoff #if STM32_HASH_VER == 4
47*68039f2dSNicolas Toromanoff #define HASH_CR_ALGO_SHIFT		U(17)
48*68039f2dSNicolas Toromanoff #define HASH_CR_ALGO_SHA1		(0x0U << HASH_CR_ALGO_SHIFT)
49*68039f2dSNicolas Toromanoff #define HASH_CR_ALGO_SHA224		(0x2U << HASH_CR_ALGO_SHIFT)
50*68039f2dSNicolas Toromanoff #define HASH_CR_ALGO_SHA256		(0x3U << HASH_CR_ALGO_SHIFT)
51*68039f2dSNicolas Toromanoff #define HASH_CR_ALGO_SHA384		(0xCU << HASH_CR_ALGO_SHIFT)
52*68039f2dSNicolas Toromanoff #define HASH_CR_ALGO_SHA512_224		(0xDU << HASH_CR_ALGO_SHIFT)
53*68039f2dSNicolas Toromanoff #define HASH_CR_ALGO_SHA512_256		(0xEU << HASH_CR_ALGO_SHIFT)
54*68039f2dSNicolas Toromanoff #define HASH_CR_ALGO_SHA512		(0xFU << HASH_CR_ALGO_SHIFT)
55*68039f2dSNicolas Toromanoff #endif
56b1e0b11cSLionel Debieve 
57b1e0b11cSLionel Debieve /* Status Flags */
58b1e0b11cSLionel Debieve #define HASH_SR_DCIS			BIT(1)
59b1e0b11cSLionel Debieve #define HASH_SR_BUSY			BIT(3)
60b1e0b11cSLionel Debieve 
61b1e0b11cSLionel Debieve /* STR Register */
62b1e0b11cSLionel Debieve #define HASH_STR_NBLW_MASK		GENMASK(4, 0)
63b1e0b11cSLionel Debieve #define HASH_STR_DCAL			BIT(8)
64b1e0b11cSLionel Debieve 
65b1e0b11cSLionel Debieve #define MD5_DIGEST_SIZE			16U
66b1e0b11cSLionel Debieve #define SHA1_DIGEST_SIZE		20U
67b1e0b11cSLionel Debieve #define SHA224_DIGEST_SIZE		28U
68b1e0b11cSLionel Debieve #define SHA256_DIGEST_SIZE		32U
69*68039f2dSNicolas Toromanoff #define SHA384_DIGEST_SIZE		48U
70*68039f2dSNicolas Toromanoff #define SHA512_224_DIGEST_SIZE		28U
71*68039f2dSNicolas Toromanoff #define SHA512_256_DIGEST_SIZE		32U
72*68039f2dSNicolas Toromanoff #define SHA512_DIGEST_SIZE		64U
73b1e0b11cSLionel Debieve 
7445c70e68SEtienne Carriere #define RESET_TIMEOUT_US_1MS		1000U
75b1e0b11cSLionel Debieve #define HASH_TIMEOUT_US			10000U
76b1e0b11cSLionel Debieve 
77b1e0b11cSLionel Debieve enum stm32_hash_data_format {
78b1e0b11cSLionel Debieve 	HASH_DATA_32_BITS,
79b1e0b11cSLionel Debieve 	HASH_DATA_16_BITS,
80b1e0b11cSLionel Debieve 	HASH_DATA_8_BITS,
81b1e0b11cSLionel Debieve 	HASH_DATA_1_BIT
82b1e0b11cSLionel Debieve };
83b1e0b11cSLionel Debieve 
84b1e0b11cSLionel Debieve struct stm32_hash_instance {
85b1e0b11cSLionel Debieve 	uintptr_t base;
86b1e0b11cSLionel Debieve 	unsigned int clock;
87b1e0b11cSLionel Debieve 	size_t digest_size;
88b1e0b11cSLionel Debieve };
89b1e0b11cSLionel Debieve 
90b1e0b11cSLionel Debieve struct stm32_hash_remain {
91b1e0b11cSLionel Debieve 	uint32_t buffer;
92b1e0b11cSLionel Debieve 	size_t length;
93b1e0b11cSLionel Debieve };
94b1e0b11cSLionel Debieve 
95b1e0b11cSLionel Debieve /* Expect a single HASH peripheral */
96b1e0b11cSLionel Debieve static struct stm32_hash_instance stm32_hash;
97b1e0b11cSLionel Debieve static struct stm32_hash_remain stm32_remain;
98b1e0b11cSLionel Debieve 
99b1e0b11cSLionel Debieve static uintptr_t hash_base(void)
100b1e0b11cSLionel Debieve {
101b1e0b11cSLionel Debieve 	return stm32_hash.base;
102b1e0b11cSLionel Debieve }
103b1e0b11cSLionel Debieve 
104b1e0b11cSLionel Debieve static int hash_wait_busy(void)
105b1e0b11cSLionel Debieve {
106b1e0b11cSLionel Debieve 	uint64_t timeout = timeout_init_us(HASH_TIMEOUT_US);
107b1e0b11cSLionel Debieve 
108b1e0b11cSLionel Debieve 	while ((mmio_read_32(hash_base() + HASH_SR) & HASH_SR_BUSY) != 0U) {
109b1e0b11cSLionel Debieve 		if (timeout_elapsed(timeout)) {
110b1e0b11cSLionel Debieve 			ERROR("%s: busy timeout\n", __func__);
111b1e0b11cSLionel Debieve 			return -ETIMEDOUT;
112b1e0b11cSLionel Debieve 		}
113b1e0b11cSLionel Debieve 	}
114b1e0b11cSLionel Debieve 
115b1e0b11cSLionel Debieve 	return 0;
116b1e0b11cSLionel Debieve }
117b1e0b11cSLionel Debieve 
118b1e0b11cSLionel Debieve static int hash_wait_computation(void)
119b1e0b11cSLionel Debieve {
120b1e0b11cSLionel Debieve 	uint64_t timeout = timeout_init_us(HASH_TIMEOUT_US);
121b1e0b11cSLionel Debieve 
122b1e0b11cSLionel Debieve 	while ((mmio_read_32(hash_base() + HASH_SR) & HASH_SR_DCIS) == 0U) {
123b1e0b11cSLionel Debieve 		if (timeout_elapsed(timeout)) {
124b1e0b11cSLionel Debieve 			ERROR("%s: busy timeout\n", __func__);
125b1e0b11cSLionel Debieve 			return -ETIMEDOUT;
126b1e0b11cSLionel Debieve 		}
127b1e0b11cSLionel Debieve 	}
128b1e0b11cSLionel Debieve 
129b1e0b11cSLionel Debieve 	return 0;
130b1e0b11cSLionel Debieve }
131b1e0b11cSLionel Debieve 
132b1e0b11cSLionel Debieve static int hash_write_data(uint32_t data)
133b1e0b11cSLionel Debieve {
134b1e0b11cSLionel Debieve 	int ret;
135b1e0b11cSLionel Debieve 
136b1e0b11cSLionel Debieve 	ret = hash_wait_busy();
137b1e0b11cSLionel Debieve 	if (ret != 0) {
138b1e0b11cSLionel Debieve 		return ret;
139b1e0b11cSLionel Debieve 	}
140b1e0b11cSLionel Debieve 
141b1e0b11cSLionel Debieve 	mmio_write_32(hash_base() + HASH_DIN, data);
142b1e0b11cSLionel Debieve 
143b1e0b11cSLionel Debieve 	return 0;
144b1e0b11cSLionel Debieve }
145b1e0b11cSLionel Debieve 
146b1e0b11cSLionel Debieve static void hash_hw_init(enum stm32_hash_algo_mode mode)
147b1e0b11cSLionel Debieve {
148b1e0b11cSLionel Debieve 	uint32_t reg;
149b1e0b11cSLionel Debieve 
150b1e0b11cSLionel Debieve 	reg = HASH_CR_INIT | (HASH_DATA_8_BITS << HASH_CR_DATATYPE_SHIFT);
151b1e0b11cSLionel Debieve 
152b1e0b11cSLionel Debieve 	switch (mode) {
153*68039f2dSNicolas Toromanoff #if STM32_HASH_VER == 2
154b1e0b11cSLionel Debieve 	case HASH_MD5SUM:
155b1e0b11cSLionel Debieve 		reg |= HASH_CR_ALGO_MD5;
156b1e0b11cSLionel Debieve 		stm32_hash.digest_size = MD5_DIGEST_SIZE;
157b1e0b11cSLionel Debieve 		break;
158*68039f2dSNicolas Toromanoff #endif
159b1e0b11cSLionel Debieve 	case HASH_SHA1:
160b1e0b11cSLionel Debieve 		reg |= HASH_CR_ALGO_SHA1;
161b1e0b11cSLionel Debieve 		stm32_hash.digest_size = SHA1_DIGEST_SIZE;
162b1e0b11cSLionel Debieve 		break;
163b1e0b11cSLionel Debieve 	case HASH_SHA224:
164b1e0b11cSLionel Debieve 		reg |= HASH_CR_ALGO_SHA224;
165b1e0b11cSLionel Debieve 		stm32_hash.digest_size = SHA224_DIGEST_SIZE;
166b1e0b11cSLionel Debieve 		break;
167*68039f2dSNicolas Toromanoff #if STM32_HASH_VER == 4
168*68039f2dSNicolas Toromanoff 	case HASH_SHA384:
169*68039f2dSNicolas Toromanoff 		reg |= HASH_CR_ALGO_SHA384;
170*68039f2dSNicolas Toromanoff 		stm32_hash.digest_size = SHA384_DIGEST_SIZE;
171*68039f2dSNicolas Toromanoff 		break;
172*68039f2dSNicolas Toromanoff 	case HASH_SHA512:
173*68039f2dSNicolas Toromanoff 		reg |= HASH_CR_ALGO_SHA512;
174*68039f2dSNicolas Toromanoff 		stm32_hash.digest_size = SHA512_DIGEST_SIZE;
175*68039f2dSNicolas Toromanoff 		break;
176*68039f2dSNicolas Toromanoff #endif
177b1e0b11cSLionel Debieve 	/* Default selected algo is SHA256 */
178b1e0b11cSLionel Debieve 	case HASH_SHA256:
179b1e0b11cSLionel Debieve 	default:
180b1e0b11cSLionel Debieve 		reg |= HASH_CR_ALGO_SHA256;
181b1e0b11cSLionel Debieve 		stm32_hash.digest_size = SHA256_DIGEST_SIZE;
182b1e0b11cSLionel Debieve 		break;
183b1e0b11cSLionel Debieve 	}
184b1e0b11cSLionel Debieve 
185b1e0b11cSLionel Debieve 	mmio_write_32(hash_base() + HASH_CR, reg);
186b1e0b11cSLionel Debieve }
187b1e0b11cSLionel Debieve 
188b1e0b11cSLionel Debieve static int hash_get_digest(uint8_t *digest)
189b1e0b11cSLionel Debieve {
190b1e0b11cSLionel Debieve 	int ret;
191b1e0b11cSLionel Debieve 	uint32_t i;
192b1e0b11cSLionel Debieve 	uint32_t dsg;
193b1e0b11cSLionel Debieve 
194b1e0b11cSLionel Debieve 	ret = hash_wait_computation();
195b1e0b11cSLionel Debieve 	if (ret != 0) {
196b1e0b11cSLionel Debieve 		return ret;
197b1e0b11cSLionel Debieve 	}
198b1e0b11cSLionel Debieve 
199b1e0b11cSLionel Debieve 	for (i = 0U; i < (stm32_hash.digest_size / sizeof(uint32_t)); i++) {
200b1e0b11cSLionel Debieve 		dsg = __builtin_bswap32(mmio_read_32(hash_base() +
201b1e0b11cSLionel Debieve 						     HASH_HREG(i)));
202b1e0b11cSLionel Debieve 		memcpy(digest + (i * sizeof(uint32_t)), &dsg, sizeof(uint32_t));
203b1e0b11cSLionel Debieve 	}
204b1e0b11cSLionel Debieve 
205b1e0b11cSLionel Debieve #if defined(IMAGE_BL2)
206b1e0b11cSLionel Debieve 	/*
207b1e0b11cSLionel Debieve 	 * Clean hardware context as HASH could be used later
208b1e0b11cSLionel Debieve 	 * by non-secure software
209b1e0b11cSLionel Debieve 	 */
210b1e0b11cSLionel Debieve 	hash_hw_init(HASH_SHA256);
211b1e0b11cSLionel Debieve #endif
212b1e0b11cSLionel Debieve 	return 0;
213b1e0b11cSLionel Debieve }
214b1e0b11cSLionel Debieve 
215b1e0b11cSLionel Debieve int stm32_hash_update(const uint8_t *buffer, size_t length)
216b1e0b11cSLionel Debieve {
217b1e0b11cSLionel Debieve 	size_t remain_length = length;
218b1e0b11cSLionel Debieve 	int ret = 0;
219b1e0b11cSLionel Debieve 
220b1e0b11cSLionel Debieve 	if ((length == 0U) || (buffer == NULL)) {
221b1e0b11cSLionel Debieve 		return 0;
222b1e0b11cSLionel Debieve 	}
223b1e0b11cSLionel Debieve 
22433667d29SYann Gautier 	clk_enable(stm32_hash.clock);
225b1e0b11cSLionel Debieve 
226b1e0b11cSLionel Debieve 	if (stm32_remain.length != 0U) {
227b1e0b11cSLionel Debieve 		uint32_t copysize;
228b1e0b11cSLionel Debieve 
229b1e0b11cSLionel Debieve 		copysize = MIN((sizeof(uint32_t) - stm32_remain.length),
230b1e0b11cSLionel Debieve 			       length);
231b1e0b11cSLionel Debieve 		memcpy(((uint8_t *)&stm32_remain.buffer) + stm32_remain.length,
232b1e0b11cSLionel Debieve 		       buffer, copysize);
233b1e0b11cSLionel Debieve 		remain_length -= copysize;
234b1e0b11cSLionel Debieve 		buffer += copysize;
235b1e0b11cSLionel Debieve 		if (stm32_remain.length == sizeof(uint32_t)) {
236b1e0b11cSLionel Debieve 			ret = hash_write_data(stm32_remain.buffer);
237b1e0b11cSLionel Debieve 			if (ret != 0) {
238b1e0b11cSLionel Debieve 				goto exit;
239b1e0b11cSLionel Debieve 			}
240b1e0b11cSLionel Debieve 
241b1e0b11cSLionel Debieve 			zeromem(&stm32_remain, sizeof(stm32_remain));
242b1e0b11cSLionel Debieve 		}
243b1e0b11cSLionel Debieve 	}
244b1e0b11cSLionel Debieve 
245b1e0b11cSLionel Debieve 	while (remain_length / sizeof(uint32_t) != 0U) {
246b1e0b11cSLionel Debieve 		uint32_t tmp_buf;
247b1e0b11cSLionel Debieve 
248b1e0b11cSLionel Debieve 		memcpy(&tmp_buf, buffer, sizeof(uint32_t));
249b1e0b11cSLionel Debieve 		ret = hash_write_data(tmp_buf);
250b1e0b11cSLionel Debieve 		if (ret != 0) {
251b1e0b11cSLionel Debieve 			goto exit;
252b1e0b11cSLionel Debieve 		}
253b1e0b11cSLionel Debieve 
254b1e0b11cSLionel Debieve 		buffer += sizeof(uint32_t);
255b1e0b11cSLionel Debieve 		remain_length -= sizeof(uint32_t);
256b1e0b11cSLionel Debieve 	}
257b1e0b11cSLionel Debieve 
258b1e0b11cSLionel Debieve 	if (remain_length != 0U) {
259b1e0b11cSLionel Debieve 		assert(stm32_remain.length == 0U);
260b1e0b11cSLionel Debieve 
261b1e0b11cSLionel Debieve 		memcpy((uint8_t *)&stm32_remain.buffer, buffer, remain_length);
262b1e0b11cSLionel Debieve 		stm32_remain.length = remain_length;
263b1e0b11cSLionel Debieve 	}
264b1e0b11cSLionel Debieve 
265b1e0b11cSLionel Debieve exit:
26633667d29SYann Gautier 	clk_disable(stm32_hash.clock);
267b1e0b11cSLionel Debieve 
268b1e0b11cSLionel Debieve 	return ret;
269b1e0b11cSLionel Debieve }
270b1e0b11cSLionel Debieve 
271b1e0b11cSLionel Debieve int stm32_hash_final(uint8_t *digest)
272b1e0b11cSLionel Debieve {
273b1e0b11cSLionel Debieve 	int ret;
274b1e0b11cSLionel Debieve 
27533667d29SYann Gautier 	clk_enable(stm32_hash.clock);
276b1e0b11cSLionel Debieve 
277b1e0b11cSLionel Debieve 	if (stm32_remain.length != 0U) {
278b1e0b11cSLionel Debieve 		ret = hash_write_data(stm32_remain.buffer);
279b1e0b11cSLionel Debieve 		if (ret != 0) {
28033667d29SYann Gautier 			clk_disable(stm32_hash.clock);
281b1e0b11cSLionel Debieve 			return ret;
282b1e0b11cSLionel Debieve 		}
283b1e0b11cSLionel Debieve 
284b1e0b11cSLionel Debieve 		mmio_clrsetbits_32(hash_base() + HASH_STR, HASH_STR_NBLW_MASK,
285b1e0b11cSLionel Debieve 				   8U * stm32_remain.length);
286b1e0b11cSLionel Debieve 		zeromem(&stm32_remain, sizeof(stm32_remain));
287662c1f5cSLionel Debieve 	} else {
288662c1f5cSLionel Debieve 		mmio_clrbits_32(hash_base() + HASH_STR, HASH_STR_NBLW_MASK);
289b1e0b11cSLionel Debieve 	}
290b1e0b11cSLionel Debieve 
291b1e0b11cSLionel Debieve 	mmio_setbits_32(hash_base() + HASH_STR, HASH_STR_DCAL);
292b1e0b11cSLionel Debieve 
293b1e0b11cSLionel Debieve 	ret = hash_get_digest(digest);
294b1e0b11cSLionel Debieve 
29533667d29SYann Gautier 	clk_disable(stm32_hash.clock);
296b1e0b11cSLionel Debieve 
297b1e0b11cSLionel Debieve 	return ret;
298b1e0b11cSLionel Debieve }
299b1e0b11cSLionel Debieve 
300b1e0b11cSLionel Debieve int stm32_hash_final_update(const uint8_t *buffer, uint32_t length,
301b1e0b11cSLionel Debieve 			    uint8_t *digest)
302b1e0b11cSLionel Debieve {
303b1e0b11cSLionel Debieve 	int ret;
304b1e0b11cSLionel Debieve 
305b1e0b11cSLionel Debieve 	ret = stm32_hash_update(buffer, length);
306b1e0b11cSLionel Debieve 	if (ret != 0) {
307b1e0b11cSLionel Debieve 		return ret;
308b1e0b11cSLionel Debieve 	}
309b1e0b11cSLionel Debieve 
310b1e0b11cSLionel Debieve 	return stm32_hash_final(digest);
311b1e0b11cSLionel Debieve }
312b1e0b11cSLionel Debieve 
313b1e0b11cSLionel Debieve void stm32_hash_init(enum stm32_hash_algo_mode mode)
314b1e0b11cSLionel Debieve {
31533667d29SYann Gautier 	clk_enable(stm32_hash.clock);
316b1e0b11cSLionel Debieve 
317b1e0b11cSLionel Debieve 	hash_hw_init(mode);
318b1e0b11cSLionel Debieve 
31933667d29SYann Gautier 	clk_disable(stm32_hash.clock);
320b1e0b11cSLionel Debieve 
321b1e0b11cSLionel Debieve 	zeromem(&stm32_remain, sizeof(stm32_remain));
322b1e0b11cSLionel Debieve }
323b1e0b11cSLionel Debieve 
324b1e0b11cSLionel Debieve int stm32_hash_register(void)
325b1e0b11cSLionel Debieve {
326b1e0b11cSLionel Debieve 	struct dt_node_info hash_info;
327b1e0b11cSLionel Debieve 	int node;
328b1e0b11cSLionel Debieve 
329b1e0b11cSLionel Debieve 	for (node = dt_get_node(&hash_info, -1, DT_HASH_COMPAT);
330b1e0b11cSLionel Debieve 	     node != -FDT_ERR_NOTFOUND;
331b1e0b11cSLionel Debieve 	     node = dt_get_node(&hash_info, node, DT_HASH_COMPAT)) {
332b1e0b11cSLionel Debieve #if defined(IMAGE_BL2)
333b1e0b11cSLionel Debieve 		if (hash_info.status != DT_DISABLED) {
334b1e0b11cSLionel Debieve 			break;
335b1e0b11cSLionel Debieve 		}
336b1e0b11cSLionel Debieve #else
3373d0d0a1bSEtienne Carriere 		/* BL32 uses hash if it is assigned only to secure world */
338b1e0b11cSLionel Debieve 		if (hash_info.status == DT_SECURE) {
3393d0d0a1bSEtienne Carriere 			stm32mp_register_secure_periph_iomem(hash_info.base);
340b1e0b11cSLionel Debieve 			break;
341b1e0b11cSLionel Debieve 		}
342b1e0b11cSLionel Debieve #endif
343b1e0b11cSLionel Debieve 	}
344b1e0b11cSLionel Debieve 
345b1e0b11cSLionel Debieve 	if (node == -FDT_ERR_NOTFOUND) {
346b1e0b11cSLionel Debieve 		return -ENODEV;
347b1e0b11cSLionel Debieve 	}
348b1e0b11cSLionel Debieve 
349b1e0b11cSLionel Debieve 	if (hash_info.clock < 0) {
350b1e0b11cSLionel Debieve 		return -EINVAL;
351b1e0b11cSLionel Debieve 	}
352b1e0b11cSLionel Debieve 
353b1e0b11cSLionel Debieve 	stm32_hash.base = hash_info.base;
354b1e0b11cSLionel Debieve 	stm32_hash.clock = hash_info.clock;
355b1e0b11cSLionel Debieve 
35633667d29SYann Gautier 	clk_enable(stm32_hash.clock);
357b1e0b11cSLionel Debieve 
358b1e0b11cSLionel Debieve 	if (hash_info.reset >= 0) {
35945c70e68SEtienne Carriere 		uint32_t id = (uint32_t)hash_info.reset;
36045c70e68SEtienne Carriere 
36145c70e68SEtienne Carriere 		if (stm32mp_reset_assert(id, RESET_TIMEOUT_US_1MS) != 0) {
36245c70e68SEtienne Carriere 			panic();
36345c70e68SEtienne Carriere 		}
364b1e0b11cSLionel Debieve 		udelay(20);
36545c70e68SEtienne Carriere 		if (stm32mp_reset_deassert(id, RESET_TIMEOUT_US_1MS) != 0) {
36645c70e68SEtienne Carriere 			panic();
36745c70e68SEtienne Carriere 		}
368b1e0b11cSLionel Debieve 	}
369b1e0b11cSLionel Debieve 
37033667d29SYann Gautier 	clk_disable(stm32_hash.clock);
371b1e0b11cSLionel Debieve 
372b1e0b11cSLionel Debieve 	return 0;
373b1e0b11cSLionel Debieve }
374