xref: /rk3399_ARM-atf/drivers/st/crypto/stm32_hash.c (revision c1ad67a174528f2295fac0f4c728a4d4398aa15c)
1b1e0b11cSLionel Debieve /*
2*84ebe2a5SThomas BOURGOIN  * Copyright (c) 2019-2025, 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>
13e9529e46SRaghu Krishnamurthy #include <common/sha_common_macros.h>
1433667d29SYann Gautier #include <drivers/clk.h>
15b1e0b11cSLionel Debieve #include <drivers/delay_timer.h>
16b1e0b11cSLionel Debieve #include <drivers/st/stm32_hash.h>
17b1e0b11cSLionel Debieve #include <drivers/st/stm32mp_reset.h>
18b1e0b11cSLionel Debieve #include <lib/mmio.h>
19b1e0b11cSLionel Debieve #include <lib/utils.h>
2068039f2dSNicolas Toromanoff #include <libfdt.h>
21b1e0b11cSLionel Debieve #include <plat/common/platform.h>
22b1e0b11cSLionel Debieve 
2368039f2dSNicolas Toromanoff #include <platform_def.h>
2468039f2dSNicolas Toromanoff 
2568039f2dSNicolas Toromanoff #if STM32_HASH_VER == 2
26b1e0b11cSLionel Debieve #define DT_HASH_COMPAT			"st,stm32f756-hash"
2768039f2dSNicolas Toromanoff #endif
2868039f2dSNicolas Toromanoff #if STM32_HASH_VER == 4
2968039f2dSNicolas Toromanoff #define DT_HASH_COMPAT			"st,stm32mp13-hash"
3068039f2dSNicolas Toromanoff #endif
31b1e0b11cSLionel Debieve 
32b1e0b11cSLionel Debieve #define HASH_CR				0x00U
33b1e0b11cSLionel Debieve #define HASH_DIN			0x04U
34b1e0b11cSLionel Debieve #define HASH_STR			0x08U
35b1e0b11cSLionel Debieve #define HASH_SR				0x24U
36b1e0b11cSLionel Debieve #define HASH_HREG(x)			(0x310U + ((x) * 0x04U))
37b1e0b11cSLionel Debieve 
38b1e0b11cSLionel Debieve /* Control Register */
39b1e0b11cSLionel Debieve #define HASH_CR_INIT			BIT(2)
40b1e0b11cSLionel Debieve #define HASH_CR_DATATYPE_SHIFT		U(4)
4168039f2dSNicolas Toromanoff #if STM32_HASH_VER == 2
42b1e0b11cSLionel Debieve #define HASH_CR_ALGO_SHA1		0x0U
43b1e0b11cSLionel Debieve #define HASH_CR_ALGO_MD5		BIT(7)
44b1e0b11cSLionel Debieve #define HASH_CR_ALGO_SHA224		BIT(18)
45b1e0b11cSLionel Debieve #define HASH_CR_ALGO_SHA256		(BIT(18) | BIT(7))
4668039f2dSNicolas Toromanoff #endif
4768039f2dSNicolas Toromanoff #if STM32_HASH_VER == 4
4868039f2dSNicolas Toromanoff #define HASH_CR_ALGO_SHIFT		U(17)
49*84ebe2a5SThomas BOURGOIN #define HASH_CR_ALGO_SHA1		((uint32_t)(0x0U) << HASH_CR_ALGO_SHIFT)
50*84ebe2a5SThomas BOURGOIN #define HASH_CR_ALGO_SHA224		((uint32_t)(0x2U) << HASH_CR_ALGO_SHIFT)
51*84ebe2a5SThomas BOURGOIN #define HASH_CR_ALGO_SHA256		((uint32_t)(0x3U) << HASH_CR_ALGO_SHIFT)
52*84ebe2a5SThomas BOURGOIN #define HASH_CR_ALGO_SHA384		((uint32_t)(0xCU) << HASH_CR_ALGO_SHIFT)
53*84ebe2a5SThomas BOURGOIN #define HASH_CR_ALGO_SHA512_224		((uint32_t)(0xDU) << HASH_CR_ALGO_SHIFT)
54*84ebe2a5SThomas BOURGOIN #define HASH_CR_ALGO_SHA512_256		((uint32_t)(0xEU) << HASH_CR_ALGO_SHIFT)
55*84ebe2a5SThomas BOURGOIN #define HASH_CR_ALGO_SHA512		((uint32_t)(0xFU) << HASH_CR_ALGO_SHIFT)
5668039f2dSNicolas Toromanoff #endif
57b1e0b11cSLionel Debieve 
58b1e0b11cSLionel Debieve /* Status Flags */
59b1e0b11cSLionel Debieve #define HASH_SR_DCIS			BIT(1)
60b1e0b11cSLionel Debieve #define HASH_SR_BUSY			BIT(3)
61b1e0b11cSLionel Debieve 
62b1e0b11cSLionel Debieve /* STR Register */
63b1e0b11cSLionel Debieve #define HASH_STR_NBLW_MASK		GENMASK(4, 0)
64b1e0b11cSLionel Debieve #define HASH_STR_DCAL			BIT(8)
65b1e0b11cSLionel Debieve 
6645c70e68SEtienne Carriere #define RESET_TIMEOUT_US_1MS		1000U
67b1e0b11cSLionel Debieve #define HASH_TIMEOUT_US			10000U
68b1e0b11cSLionel Debieve 
69b1e0b11cSLionel Debieve enum stm32_hash_data_format {
70b1e0b11cSLionel Debieve 	HASH_DATA_32_BITS,
71b1e0b11cSLionel Debieve 	HASH_DATA_16_BITS,
72b1e0b11cSLionel Debieve 	HASH_DATA_8_BITS,
73b1e0b11cSLionel Debieve 	HASH_DATA_1_BIT
74b1e0b11cSLionel Debieve };
75b1e0b11cSLionel Debieve 
76b1e0b11cSLionel Debieve struct stm32_hash_instance {
77b1e0b11cSLionel Debieve 	uintptr_t base;
78b1e0b11cSLionel Debieve 	unsigned int clock;
79b1e0b11cSLionel Debieve 	size_t digest_size;
80b1e0b11cSLionel Debieve };
81b1e0b11cSLionel Debieve 
82b1e0b11cSLionel Debieve struct stm32_hash_remain {
83b1e0b11cSLionel Debieve 	uint32_t buffer;
84b1e0b11cSLionel Debieve 	size_t length;
85b1e0b11cSLionel Debieve };
86b1e0b11cSLionel Debieve 
87b1e0b11cSLionel Debieve /* Expect a single HASH peripheral */
88b1e0b11cSLionel Debieve static struct stm32_hash_instance stm32_hash;
89b1e0b11cSLionel Debieve static struct stm32_hash_remain stm32_remain;
90b1e0b11cSLionel Debieve 
hash_base(void)91b1e0b11cSLionel Debieve static uintptr_t hash_base(void)
92b1e0b11cSLionel Debieve {
93b1e0b11cSLionel Debieve 	return stm32_hash.base;
94b1e0b11cSLionel Debieve }
95b1e0b11cSLionel Debieve 
hash_wait_busy(void)96b1e0b11cSLionel Debieve static int hash_wait_busy(void)
97b1e0b11cSLionel Debieve {
98b1e0b11cSLionel Debieve 	uint64_t timeout = timeout_init_us(HASH_TIMEOUT_US);
99b1e0b11cSLionel Debieve 
100b1e0b11cSLionel Debieve 	while ((mmio_read_32(hash_base() + HASH_SR) & HASH_SR_BUSY) != 0U) {
101b1e0b11cSLionel Debieve 		if (timeout_elapsed(timeout)) {
102b1e0b11cSLionel Debieve 			ERROR("%s: busy timeout\n", __func__);
103b1e0b11cSLionel Debieve 			return -ETIMEDOUT;
104b1e0b11cSLionel Debieve 		}
105b1e0b11cSLionel Debieve 	}
106b1e0b11cSLionel Debieve 
107b1e0b11cSLionel Debieve 	return 0;
108b1e0b11cSLionel Debieve }
109b1e0b11cSLionel Debieve 
hash_wait_computation(void)110b1e0b11cSLionel Debieve static int hash_wait_computation(void)
111b1e0b11cSLionel Debieve {
112b1e0b11cSLionel Debieve 	uint64_t timeout = timeout_init_us(HASH_TIMEOUT_US);
113b1e0b11cSLionel Debieve 
114b1e0b11cSLionel Debieve 	while ((mmio_read_32(hash_base() + HASH_SR) & HASH_SR_DCIS) == 0U) {
115b1e0b11cSLionel Debieve 		if (timeout_elapsed(timeout)) {
116b1e0b11cSLionel Debieve 			ERROR("%s: busy timeout\n", __func__);
117b1e0b11cSLionel Debieve 			return -ETIMEDOUT;
118b1e0b11cSLionel Debieve 		}
119b1e0b11cSLionel Debieve 	}
120b1e0b11cSLionel Debieve 
121b1e0b11cSLionel Debieve 	return 0;
122b1e0b11cSLionel Debieve }
123b1e0b11cSLionel Debieve 
hash_write_data(uint32_t data)124b1e0b11cSLionel Debieve static int hash_write_data(uint32_t data)
125b1e0b11cSLionel Debieve {
126b1e0b11cSLionel Debieve 	int ret;
127b1e0b11cSLionel Debieve 
128b1e0b11cSLionel Debieve 	ret = hash_wait_busy();
129b1e0b11cSLionel Debieve 	if (ret != 0) {
130b1e0b11cSLionel Debieve 		return ret;
131b1e0b11cSLionel Debieve 	}
132b1e0b11cSLionel Debieve 
133b1e0b11cSLionel Debieve 	mmio_write_32(hash_base() + HASH_DIN, data);
134b1e0b11cSLionel Debieve 
135b1e0b11cSLionel Debieve 	return 0;
136b1e0b11cSLionel Debieve }
137b1e0b11cSLionel Debieve 
hash_hw_init(enum stm32_hash_algo_mode mode)138b1e0b11cSLionel Debieve static void hash_hw_init(enum stm32_hash_algo_mode mode)
139b1e0b11cSLionel Debieve {
140b1e0b11cSLionel Debieve 	uint32_t reg;
141b1e0b11cSLionel Debieve 
142*84ebe2a5SThomas BOURGOIN 	reg = HASH_CR_INIT | ((uint32_t)HASH_DATA_8_BITS << HASH_CR_DATATYPE_SHIFT);
143b1e0b11cSLionel Debieve 
144b1e0b11cSLionel Debieve 	switch (mode) {
14568039f2dSNicolas Toromanoff #if STM32_HASH_VER == 2
146b1e0b11cSLionel Debieve 	case HASH_MD5SUM:
147b1e0b11cSLionel Debieve 		reg |= HASH_CR_ALGO_MD5;
148b1e0b11cSLionel Debieve 		stm32_hash.digest_size = MD5_DIGEST_SIZE;
149b1e0b11cSLionel Debieve 		break;
15068039f2dSNicolas Toromanoff #endif
151b1e0b11cSLionel Debieve 	case HASH_SHA1:
152b1e0b11cSLionel Debieve 		reg |= HASH_CR_ALGO_SHA1;
153b1e0b11cSLionel Debieve 		stm32_hash.digest_size = SHA1_DIGEST_SIZE;
154b1e0b11cSLionel Debieve 		break;
155b1e0b11cSLionel Debieve 	case HASH_SHA224:
156b1e0b11cSLionel Debieve 		reg |= HASH_CR_ALGO_SHA224;
157b1e0b11cSLionel Debieve 		stm32_hash.digest_size = SHA224_DIGEST_SIZE;
158b1e0b11cSLionel Debieve 		break;
15968039f2dSNicolas Toromanoff #if STM32_HASH_VER == 4
16068039f2dSNicolas Toromanoff 	case HASH_SHA384:
16168039f2dSNicolas Toromanoff 		reg |= HASH_CR_ALGO_SHA384;
16268039f2dSNicolas Toromanoff 		stm32_hash.digest_size = SHA384_DIGEST_SIZE;
16368039f2dSNicolas Toromanoff 		break;
16468039f2dSNicolas Toromanoff 	case HASH_SHA512:
16568039f2dSNicolas Toromanoff 		reg |= HASH_CR_ALGO_SHA512;
16668039f2dSNicolas Toromanoff 		stm32_hash.digest_size = SHA512_DIGEST_SIZE;
16768039f2dSNicolas Toromanoff 		break;
16868039f2dSNicolas Toromanoff #endif
169b1e0b11cSLionel Debieve 	/* Default selected algo is SHA256 */
170b1e0b11cSLionel Debieve 	case HASH_SHA256:
171b1e0b11cSLionel Debieve 	default:
172b1e0b11cSLionel Debieve 		reg |= HASH_CR_ALGO_SHA256;
173b1e0b11cSLionel Debieve 		stm32_hash.digest_size = SHA256_DIGEST_SIZE;
174b1e0b11cSLionel Debieve 		break;
175b1e0b11cSLionel Debieve 	}
176b1e0b11cSLionel Debieve 
177b1e0b11cSLionel Debieve 	mmio_write_32(hash_base() + HASH_CR, reg);
178b1e0b11cSLionel Debieve }
179b1e0b11cSLionel Debieve 
hash_get_digest(uint8_t * digest)180b1e0b11cSLionel Debieve static int hash_get_digest(uint8_t *digest)
181b1e0b11cSLionel Debieve {
182b1e0b11cSLionel Debieve 	int ret;
183b1e0b11cSLionel Debieve 	uint32_t i;
184b1e0b11cSLionel Debieve 	uint32_t dsg;
185b1e0b11cSLionel Debieve 
186b1e0b11cSLionel Debieve 	ret = hash_wait_computation();
187b1e0b11cSLionel Debieve 	if (ret != 0) {
188b1e0b11cSLionel Debieve 		return ret;
189b1e0b11cSLionel Debieve 	}
190b1e0b11cSLionel Debieve 
191b1e0b11cSLionel Debieve 	for (i = 0U; i < (stm32_hash.digest_size / sizeof(uint32_t)); i++) {
192b1e0b11cSLionel Debieve 		dsg = __builtin_bswap32(mmio_read_32(hash_base() +
193b1e0b11cSLionel Debieve 						     HASH_HREG(i)));
194*84ebe2a5SThomas BOURGOIN 		(void)(memcpy(&digest[i * sizeof(uint32_t)], (uint8_t *)&dsg, sizeof(uint32_t)));
195b1e0b11cSLionel Debieve 	}
196b1e0b11cSLionel Debieve 
197b1e0b11cSLionel Debieve 	/*
198b1e0b11cSLionel Debieve 	 * Clean hardware context as HASH could be used later
199b1e0b11cSLionel Debieve 	 * by non-secure software
200b1e0b11cSLionel Debieve 	 */
201b1e0b11cSLionel Debieve 	hash_hw_init(HASH_SHA256);
2026b5fc192SLionel Debieve 
203b1e0b11cSLionel Debieve 	return 0;
204b1e0b11cSLionel Debieve }
205b1e0b11cSLionel Debieve 
stm32_hash_update(const uint8_t * buffer,size_t length)206b1e0b11cSLionel Debieve int stm32_hash_update(const uint8_t *buffer, size_t length)
207b1e0b11cSLionel Debieve {
208b1e0b11cSLionel Debieve 	size_t remain_length = length;
209*84ebe2a5SThomas BOURGOIN 	uint8_t *remain_buf = (uint8_t *)&stm32_remain.buffer;
210*84ebe2a5SThomas BOURGOIN 	const uint8_t *buf = buffer;
211b1e0b11cSLionel Debieve 	int ret = 0;
212b1e0b11cSLionel Debieve 
213b1e0b11cSLionel Debieve 	if ((length == 0U) || (buffer == NULL)) {
214b1e0b11cSLionel Debieve 		return 0;
215b1e0b11cSLionel Debieve 	}
216b1e0b11cSLionel Debieve 
217*84ebe2a5SThomas BOURGOIN 	ret = clk_enable(stm32_hash.clock);
218*84ebe2a5SThomas BOURGOIN 	if (ret != 0) {
219*84ebe2a5SThomas BOURGOIN 		return ret;
220*84ebe2a5SThomas BOURGOIN 	}
221b1e0b11cSLionel Debieve 
222b1e0b11cSLionel Debieve 	if (stm32_remain.length != 0U) {
223b1e0b11cSLionel Debieve 		uint32_t copysize;
224b1e0b11cSLionel Debieve 
225b1e0b11cSLionel Debieve 		copysize = MIN((sizeof(uint32_t) - stm32_remain.length),
226b1e0b11cSLionel Debieve 			       length);
227*84ebe2a5SThomas BOURGOIN 		(void)(memcpy(&remain_buf[stm32_remain.length], buf, copysize));
228b1e0b11cSLionel Debieve 		remain_length -= copysize;
229*84ebe2a5SThomas BOURGOIN 		buf = &buf[copysize];
230b1e0b11cSLionel Debieve 		if (stm32_remain.length == sizeof(uint32_t)) {
231b1e0b11cSLionel Debieve 			ret = hash_write_data(stm32_remain.buffer);
232b1e0b11cSLionel Debieve 			if (ret != 0) {
233b1e0b11cSLionel Debieve 				goto exit;
234b1e0b11cSLionel Debieve 			}
235b1e0b11cSLionel Debieve 
236b1e0b11cSLionel Debieve 			zeromem(&stm32_remain, sizeof(stm32_remain));
237b1e0b11cSLionel Debieve 		}
238b1e0b11cSLionel Debieve 	}
239b1e0b11cSLionel Debieve 
240b1e0b11cSLionel Debieve 	while (remain_length / sizeof(uint32_t) != 0U) {
241b1e0b11cSLionel Debieve 		uint32_t tmp_buf;
242b1e0b11cSLionel Debieve 
243*84ebe2a5SThomas BOURGOIN 		(void)(memcpy((void *)&tmp_buf, buf, sizeof(uint32_t)));
244b1e0b11cSLionel Debieve 		ret = hash_write_data(tmp_buf);
245b1e0b11cSLionel Debieve 		if (ret != 0) {
246b1e0b11cSLionel Debieve 			goto exit;
247b1e0b11cSLionel Debieve 		}
248b1e0b11cSLionel Debieve 
249*84ebe2a5SThomas BOURGOIN 		buf = &buf[sizeof(uint32_t)];
250b1e0b11cSLionel Debieve 		remain_length -= sizeof(uint32_t);
251b1e0b11cSLionel Debieve 	}
252b1e0b11cSLionel Debieve 
253b1e0b11cSLionel Debieve 	if (remain_length != 0U) {
254b1e0b11cSLionel Debieve 		assert(stm32_remain.length == 0U);
255b1e0b11cSLionel Debieve 
256*84ebe2a5SThomas BOURGOIN 		(void)(memcpy((uint8_t *)&stm32_remain.buffer, buf, remain_length));
257b1e0b11cSLionel Debieve 		stm32_remain.length = remain_length;
258b1e0b11cSLionel Debieve 	}
259b1e0b11cSLionel Debieve 
260b1e0b11cSLionel Debieve exit:
26133667d29SYann Gautier 	clk_disable(stm32_hash.clock);
262b1e0b11cSLionel Debieve 
263b1e0b11cSLionel Debieve 	return ret;
264b1e0b11cSLionel Debieve }
265b1e0b11cSLionel Debieve 
stm32_hash_final(uint8_t * digest)266b1e0b11cSLionel Debieve int stm32_hash_final(uint8_t *digest)
267b1e0b11cSLionel Debieve {
268b1e0b11cSLionel Debieve 	int ret;
269b1e0b11cSLionel Debieve 
270*84ebe2a5SThomas BOURGOIN 	ret = clk_enable(stm32_hash.clock);
271*84ebe2a5SThomas BOURGOIN 	if (ret != 0) {
272*84ebe2a5SThomas BOURGOIN 		return ret;
273*84ebe2a5SThomas BOURGOIN 	}
274b1e0b11cSLionel Debieve 
275b1e0b11cSLionel Debieve 	if (stm32_remain.length != 0U) {
276b1e0b11cSLionel Debieve 		ret = hash_write_data(stm32_remain.buffer);
277b1e0b11cSLionel Debieve 		if (ret != 0) {
27833667d29SYann Gautier 			clk_disable(stm32_hash.clock);
279b1e0b11cSLionel Debieve 			return ret;
280b1e0b11cSLionel Debieve 		}
281b1e0b11cSLionel Debieve 
282b1e0b11cSLionel Debieve 		mmio_clrsetbits_32(hash_base() + HASH_STR, HASH_STR_NBLW_MASK,
283b1e0b11cSLionel Debieve 				   8U * stm32_remain.length);
284b1e0b11cSLionel Debieve 		zeromem(&stm32_remain, sizeof(stm32_remain));
285662c1f5cSLionel Debieve 	} else {
286662c1f5cSLionel Debieve 		mmio_clrbits_32(hash_base() + HASH_STR, HASH_STR_NBLW_MASK);
287b1e0b11cSLionel Debieve 	}
288b1e0b11cSLionel Debieve 
289b1e0b11cSLionel Debieve 	mmio_setbits_32(hash_base() + HASH_STR, HASH_STR_DCAL);
290b1e0b11cSLionel Debieve 
291b1e0b11cSLionel Debieve 	ret = hash_get_digest(digest);
292b1e0b11cSLionel Debieve 
29333667d29SYann Gautier 	clk_disable(stm32_hash.clock);
294b1e0b11cSLionel Debieve 
295b1e0b11cSLionel Debieve 	return ret;
296b1e0b11cSLionel Debieve }
297b1e0b11cSLionel Debieve 
stm32_hash_final_update(const uint8_t * buffer,uint32_t length,uint8_t * digest)298b1e0b11cSLionel Debieve int stm32_hash_final_update(const uint8_t *buffer, uint32_t length,
299b1e0b11cSLionel Debieve 			    uint8_t *digest)
300b1e0b11cSLionel Debieve {
301b1e0b11cSLionel Debieve 	int ret;
302b1e0b11cSLionel Debieve 
303b1e0b11cSLionel Debieve 	ret = stm32_hash_update(buffer, length);
304b1e0b11cSLionel Debieve 	if (ret != 0) {
305b1e0b11cSLionel Debieve 		return ret;
306b1e0b11cSLionel Debieve 	}
307b1e0b11cSLionel Debieve 
308b1e0b11cSLionel Debieve 	return stm32_hash_final(digest);
309b1e0b11cSLionel Debieve }
310b1e0b11cSLionel Debieve 
stm32_hash_init(enum stm32_hash_algo_mode mode)311b1e0b11cSLionel Debieve void stm32_hash_init(enum stm32_hash_algo_mode mode)
312b1e0b11cSLionel Debieve {
313*84ebe2a5SThomas BOURGOIN 	if (clk_enable(stm32_hash.clock) != 0) {
314*84ebe2a5SThomas BOURGOIN 		ERROR("%s: fail to enable clock\n", __func__);
315*84ebe2a5SThomas BOURGOIN 		panic();
316*84ebe2a5SThomas BOURGOIN 	}
317b1e0b11cSLionel Debieve 
318b1e0b11cSLionel Debieve 	hash_hw_init(mode);
319b1e0b11cSLionel Debieve 
32033667d29SYann Gautier 	clk_disable(stm32_hash.clock);
321b1e0b11cSLionel Debieve 
322b1e0b11cSLionel Debieve 	zeromem(&stm32_remain, sizeof(stm32_remain));
323b1e0b11cSLionel Debieve }
324b1e0b11cSLionel Debieve 
stm32_hash_register(void)325b1e0b11cSLionel Debieve int stm32_hash_register(void)
326b1e0b11cSLionel Debieve {
327b1e0b11cSLionel Debieve 	struct dt_node_info hash_info;
328b1e0b11cSLionel Debieve 	int node;
329*84ebe2a5SThomas BOURGOIN 	int ret;
330b1e0b11cSLionel Debieve 
331b1e0b11cSLionel Debieve 	for (node = dt_get_node(&hash_info, -1, DT_HASH_COMPAT);
332b1e0b11cSLionel Debieve 	     node != -FDT_ERR_NOTFOUND;
333b1e0b11cSLionel Debieve 	     node = dt_get_node(&hash_info, node, DT_HASH_COMPAT)) {
334b1e0b11cSLionel Debieve 		if (hash_info.status != DT_DISABLED) {
335b1e0b11cSLionel Debieve 			break;
336b1e0b11cSLionel Debieve 		}
337b1e0b11cSLionel Debieve 	}
338b1e0b11cSLionel Debieve 
339b1e0b11cSLionel Debieve 	if (node == -FDT_ERR_NOTFOUND) {
340b1e0b11cSLionel Debieve 		return -ENODEV;
341b1e0b11cSLionel Debieve 	}
342b1e0b11cSLionel Debieve 
343b1e0b11cSLionel Debieve 	if (hash_info.clock < 0) {
344b1e0b11cSLionel Debieve 		return -EINVAL;
345b1e0b11cSLionel Debieve 	}
346b1e0b11cSLionel Debieve 
347b1e0b11cSLionel Debieve 	stm32_hash.base = hash_info.base;
348b1e0b11cSLionel Debieve 	stm32_hash.clock = hash_info.clock;
349b1e0b11cSLionel Debieve 
350*84ebe2a5SThomas BOURGOIN 	ret = clk_enable(stm32_hash.clock);
351*84ebe2a5SThomas BOURGOIN 	if (ret != 0) {
352*84ebe2a5SThomas BOURGOIN 		return ret;
353*84ebe2a5SThomas BOURGOIN 	}
354b1e0b11cSLionel Debieve 
355b1e0b11cSLionel Debieve 	if (hash_info.reset >= 0) {
35645c70e68SEtienne Carriere 		uint32_t id = (uint32_t)hash_info.reset;
35745c70e68SEtienne Carriere 
35845c70e68SEtienne Carriere 		if (stm32mp_reset_assert(id, RESET_TIMEOUT_US_1MS) != 0) {
35945c70e68SEtienne Carriere 			panic();
36045c70e68SEtienne Carriere 		}
361b1e0b11cSLionel Debieve 		udelay(20);
36245c70e68SEtienne Carriere 		if (stm32mp_reset_deassert(id, RESET_TIMEOUT_US_1MS) != 0) {
36345c70e68SEtienne Carriere 			panic();
36445c70e68SEtienne Carriere 		}
365b1e0b11cSLionel Debieve 	}
366b1e0b11cSLionel Debieve 
36733667d29SYann Gautier 	clk_disable(stm32_hash.clock);
368b1e0b11cSLionel Debieve 
369b1e0b11cSLionel Debieve 	return 0;
370b1e0b11cSLionel Debieve }
371