1 // SPDX-License-Identifier: BSD-Source-Code
2 /*
3  * Copyright (c) 2013, Atmel Corporation
4  * Copyright (c) 2017, Timesys Corporation
5  *
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions are met:
10  *
11  * - Redistributions of source code must retain the above copyright notice,
12  * this list of conditions and the disclaimer below.
13  *
14  * Atmel's name may not be used to endorse or promote products derived from
15  * this software without specific prior written permission.
16  *
17  * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
20  * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
23  * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
24  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
25  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
26  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28 #include <arm32.h>
29 #include <initcall.h>
30 #include <io.h>
31 #include <kernel/pm.h>
32 #include <kernel/panic.h>
33 #include <matrix.h>
34 #include <platform_config.h>
35 #include <sama5d2.h>
36 #include <stdint.h>
37 #include <tz_matrix.h>
38 #include <trace.h>
39 
40 #define MATRIX_AXIMX	1
41 #define MATRIX_H64MX	2
42 #define MATRIX_H32MX	3
43 
44 #define SECURITY_TYPE_AS	1
45 #define SECURITY_TYPE_NS	2
46 #define SECURITY_TYPE_PS	3
47 
48 #define WORLD_NON_SECURE	0
49 #define WORLD_SECURE		1
50 
51 #define MATRIX_SPSELR_COUNT	3
52 #define MATRIX_SLAVE_COUNT	15
53 
54 struct peri_security {
55 	unsigned int peri_id;
56 	unsigned int matrix;
57 	unsigned int security_type;
58 };
59 
60 static const struct peri_security peri_security_array[] = {
61 	{
62 		.peri_id = AT91C_ID_PMC,
63 		.matrix = MATRIX_H64MX,
64 		.security_type = SECURITY_TYPE_PS,
65 	},
66 	{
67 		.peri_id = AT91C_ID_ARM,
68 		.matrix = MATRIX_H64MX,
69 		.security_type = SECURITY_TYPE_PS,
70 	},
71 	{
72 		.peri_id = AT91C_ID_PIT,
73 		.matrix = MATRIX_H32MX,
74 		.security_type = SECURITY_TYPE_PS,
75 	},
76 	{
77 		.peri_id = AT91C_ID_WDT,
78 		.matrix = MATRIX_H32MX,
79 		.security_type = SECURITY_TYPE_PS,
80 	},
81 	{
82 		.peri_id = AT91C_ID_GMAC,
83 		.matrix = MATRIX_H32MX,
84 		.security_type = SECURITY_TYPE_PS,
85 	},
86 	{
87 		.peri_id = AT91C_ID_XDMAC0,
88 		.matrix = MATRIX_H64MX,
89 		.security_type = SECURITY_TYPE_PS,
90 	},
91 	{
92 		.peri_id = AT91C_ID_XDMAC1,
93 		.matrix = MATRIX_H64MX,
94 		.security_type = SECURITY_TYPE_PS,
95 	},
96 	{
97 		.peri_id = AT91C_ID_ICM,
98 		.matrix = MATRIX_H32MX,
99 		.security_type = SECURITY_TYPE_PS,
100 	},
101 	{
102 		.peri_id = AT91C_ID_AES,
103 		.matrix = MATRIX_H64MX,
104 		.security_type = SECURITY_TYPE_PS,
105 	},
106 	{
107 		.peri_id = AT91C_ID_AESB,
108 		.matrix = MATRIX_H64MX,
109 		.security_type = SECURITY_TYPE_PS,
110 	},
111 	{
112 		.peri_id = AT91C_ID_TDES,
113 		.matrix = MATRIX_H32MX,
114 		.security_type = SECURITY_TYPE_PS,
115 	},
116 	{
117 		.peri_id = AT91C_ID_SHA,
118 		.matrix = MATRIX_H64MX,
119 		.security_type = SECURITY_TYPE_PS,
120 	},
121 	{
122 		.peri_id = AT91C_ID_MPDDRC,
123 		.matrix = MATRIX_H64MX,
124 		.security_type = SECURITY_TYPE_PS,
125 	},
126 	{
127 		.peri_id = AT91C_ID_MATRIX1,
128 		.matrix = MATRIX_H32MX,
129 		.security_type = SECURITY_TYPE_AS,
130 	},
131 	{
132 		.peri_id = AT91C_ID_MATRIX0,
133 		.matrix = MATRIX_H64MX,
134 		.security_type = SECURITY_TYPE_AS,
135 	},
136 	{
137 		.peri_id = AT91C_ID_SECUMOD,
138 		.matrix = MATRIX_H32MX,
139 		.security_type = SECURITY_TYPE_AS,
140 	},
141 	{
142 		.peri_id = AT91C_ID_HSMC,
143 		.matrix = MATRIX_H32MX,
144 		.security_type = SECURITY_TYPE_PS,
145 	},
146 	{
147 		.peri_id = AT91C_ID_PIOA,
148 		.matrix = MATRIX_H32MX,
149 		.security_type = SECURITY_TYPE_AS,
150 	},
151 	{
152 		.peri_id = AT91C_ID_FLEXCOM0,
153 		.matrix = MATRIX_H32MX,
154 		.security_type = SECURITY_TYPE_PS,
155 	},
156 	{
157 		.peri_id = AT91C_ID_FLEXCOM1,
158 		.matrix = MATRIX_H32MX,
159 		.security_type = SECURITY_TYPE_PS,
160 	},
161 	{
162 		.peri_id = AT91C_ID_FLEXCOM2,
163 		.matrix = MATRIX_H32MX,
164 		.security_type = SECURITY_TYPE_PS,
165 	},
166 	{
167 		.peri_id = AT91C_ID_FLEXCOM3,
168 		.matrix = MATRIX_H32MX,
169 		.security_type = SECURITY_TYPE_PS,
170 	},
171 	{
172 		.peri_id = AT91C_ID_FLEXCOM4,
173 		.matrix = MATRIX_H32MX,
174 		.security_type = SECURITY_TYPE_PS,
175 	},
176 	{
177 		.peri_id = AT91C_ID_UART0,
178 		.matrix = MATRIX_H32MX,
179 		.security_type = SECURITY_TYPE_PS,
180 	},
181 	{
182 		.peri_id = AT91C_ID_UART1,
183 		.matrix = MATRIX_H32MX,
184 		.security_type = SECURITY_TYPE_PS,
185 	},
186 	{
187 		.peri_id = AT91C_ID_UART2,
188 		.matrix = MATRIX_H32MX,
189 		.security_type = SECURITY_TYPE_PS,
190 	},
191 	{
192 		.peri_id = AT91C_ID_UART3,
193 		.matrix = MATRIX_H32MX,
194 		.security_type = SECURITY_TYPE_PS,
195 	},
196 	{
197 		.peri_id = AT91C_ID_UART4,
198 		.matrix = MATRIX_H32MX,
199 		.security_type = SECURITY_TYPE_PS,
200 	},
201 	{
202 		.peri_id = AT91C_ID_TWI0,
203 		.matrix = MATRIX_H32MX,
204 		.security_type = SECURITY_TYPE_PS,
205 	},
206 	{
207 		.peri_id = AT91C_ID_TWI1,
208 		.matrix = MATRIX_H32MX,
209 		.security_type = SECURITY_TYPE_PS,
210 	},
211 	{
212 		.peri_id = AT91C_ID_SDMMC0,
213 		.matrix = MATRIX_H64MX,
214 		.security_type = SECURITY_TYPE_PS,
215 	},
216 	{
217 		.peri_id = AT91C_ID_SDMMC1,
218 		.matrix = MATRIX_H64MX,
219 		.security_type = SECURITY_TYPE_PS,
220 	},
221 	{
222 		.peri_id = AT91C_ID_SPI0,
223 		.matrix = MATRIX_H32MX,
224 		.security_type = SECURITY_TYPE_PS,
225 	},
226 	{
227 		.peri_id = AT91C_ID_SPI1,
228 		.matrix = MATRIX_H32MX,
229 		.security_type = SECURITY_TYPE_PS,
230 	},
231 	{
232 		.peri_id = AT91C_ID_TC0,
233 		.matrix = MATRIX_H32MX,
234 		.security_type = SECURITY_TYPE_PS,
235 	},
236 	{
237 		.peri_id = AT91C_ID_TC1,
238 		.matrix = MATRIX_H32MX,
239 		.security_type = SECURITY_TYPE_PS,
240 	},
241 	{
242 		.peri_id = AT91C_ID_PWM,
243 		.matrix = MATRIX_H32MX,
244 		.security_type = SECURITY_TYPE_PS,
245 	},
246 	{
247 		.peri_id = AT91C_ID_ADC,
248 		.matrix = MATRIX_H32MX,
249 		.security_type = SECURITY_TYPE_PS,
250 	},
251 	{
252 		.peri_id = AT91C_ID_UHPHS,
253 		.matrix = MATRIX_H32MX,
254 		.security_type = SECURITY_TYPE_PS,
255 	},
256 	{
257 		.peri_id = AT91C_ID_UDPHS,
258 		.matrix = MATRIX_H32MX,
259 		.security_type = SECURITY_TYPE_PS,
260 	},
261 	{
262 		.peri_id = AT91C_ID_SSC0,
263 		.matrix = MATRIX_H32MX,
264 		.security_type = SECURITY_TYPE_PS,
265 	},
266 	{
267 		.peri_id = AT91C_ID_SSC1,
268 		.matrix = MATRIX_H32MX,
269 		.security_type = SECURITY_TYPE_PS,
270 	},
271 	{
272 		.peri_id = AT91C_ID_LCDC,
273 		.matrix = MATRIX_H64MX,
274 		.security_type = SECURITY_TYPE_PS,
275 	},
276 	{
277 		.peri_id = AT91C_ID_ISI,
278 		.matrix = MATRIX_H64MX,
279 		.security_type = SECURITY_TYPE_PS,
280 	},
281 	{
282 		.peri_id = AT91C_ID_TRNG,
283 		.matrix = MATRIX_H32MX,
284 		.security_type = SECURITY_TYPE_PS,
285 	},
286 	{
287 		.peri_id = AT91C_ID_PDMIC,
288 		.matrix = MATRIX_H32MX,
289 		.security_type = SECURITY_TYPE_PS,
290 	},
291 	{
292 		.peri_id = AT91C_ID_IRQ,
293 		.matrix = MATRIX_H32MX,
294 		.security_type = SECURITY_TYPE_NS,
295 	},
296 	{
297 		.peri_id = AT91C_ID_SFC,
298 		.matrix = MATRIX_H32MX,
299 		.security_type = SECURITY_TYPE_PS,
300 	},
301 	{
302 		.peri_id = AT91C_ID_SECURAM,
303 		.matrix = MATRIX_H32MX,
304 		.security_type = SECURITY_TYPE_AS,
305 	},
306 	{
307 		.peri_id = AT91C_ID_QSPI0,
308 		.matrix = MATRIX_H64MX,
309 		.security_type = SECURITY_TYPE_PS,
310 	},
311 	{
312 		.peri_id = AT91C_ID_QSPI1,
313 		.matrix = MATRIX_H64MX,
314 		.security_type = SECURITY_TYPE_PS,
315 	},
316 	{
317 		.peri_id = AT91C_ID_I2SC0,
318 		.matrix = MATRIX_H32MX,
319 		.security_type = SECURITY_TYPE_PS,
320 	},
321 	{
322 		.peri_id = AT91C_ID_I2SC1,
323 		.matrix = MATRIX_H32MX,
324 		.security_type = SECURITY_TYPE_PS,
325 	},
326 	{
327 		.peri_id = AT91C_ID_CAN0_INT0,
328 		.matrix = MATRIX_H32MX,
329 		.security_type = SECURITY_TYPE_PS,
330 	},
331 	{
332 		.peri_id = AT91C_ID_CAN1_INT0,
333 		.matrix = MATRIX_H32MX,
334 		.security_type = SECURITY_TYPE_PS,
335 	},
336 	{
337 		.peri_id = AT91C_ID_CLASSD,
338 		.matrix = MATRIX_H32MX,
339 		.security_type = SECURITY_TYPE_PS,
340 	},
341 	{
342 		.peri_id = AT91C_ID_SFR,
343 		.matrix = MATRIX_H32MX,
344 		.security_type = SECURITY_TYPE_PS,
345 	},
346 	{
347 		.peri_id = AT91C_ID_SAIC,
348 		.matrix = MATRIX_H32MX,
349 		.security_type = SECURITY_TYPE_AS,
350 	},
351 	{
352 		.peri_id = AT91C_ID_AIC,
353 		.matrix = MATRIX_H32MX,
354 		.security_type = SECURITY_TYPE_NS,
355 	},
356 	{
357 		.peri_id = AT91C_ID_L2CC,
358 		.matrix = MATRIX_H64MX,
359 		.security_type = SECURITY_TYPE_PS,
360 	},
361 	{
362 		.peri_id = AT91C_ID_CAN0_INT1,
363 		.matrix = MATRIX_H32MX,
364 		.security_type = SECURITY_TYPE_PS,
365 	},
366 	{
367 		.peri_id = AT91C_ID_CAN1_INT1,
368 		.matrix = MATRIX_H32MX,
369 		.security_type = SECURITY_TYPE_PS,
370 	},
371 	{
372 		.peri_id = AT91C_ID_GMAC_Q1,
373 		.matrix = MATRIX_H32MX,
374 		.security_type = SECURITY_TYPE_PS,
375 	},
376 	{
377 		.peri_id = AT91C_ID_GMAC_Q2,
378 		.matrix = MATRIX_H32MX,
379 		.security_type = SECURITY_TYPE_PS,
380 	},
381 	{
382 		.peri_id = AT91C_ID_PIOB,
383 		.matrix = MATRIX_H32MX,
384 		.security_type = SECURITY_TYPE_AS,
385 	},
386 	{
387 		.peri_id = AT91C_ID_PIOC,
388 		.matrix = MATRIX_H32MX,
389 		.security_type = SECURITY_TYPE_AS,
390 	},
391 	{
392 		.peri_id = AT91C_ID_PIOD,
393 		.matrix = MATRIX_H32MX,
394 		.security_type = SECURITY_TYPE_AS,
395 	},
396 	{
397 		.peri_id = AT91C_ID_SDMMC0_TIMER,
398 		.matrix = MATRIX_H32MX,
399 		.security_type = SECURITY_TYPE_PS,
400 	},
401 	{
402 		.peri_id = AT91C_ID_SDMMC1_TIMER,
403 		.matrix = MATRIX_H32MX,
404 		.security_type = SECURITY_TYPE_PS,
405 	},
406 	{
407 		.peri_id = AT91C_ID_SYS,
408 		.matrix = MATRIX_H32MX,
409 		.security_type = SECURITY_TYPE_PS,
410 	},
411 	{
412 		.peri_id = AT91C_ID_ACC,
413 		.matrix = MATRIX_H32MX,
414 		.security_type = SECURITY_TYPE_PS,
415 	},
416 	{
417 		.peri_id = AT91C_ID_RXLP,
418 		.matrix = MATRIX_H32MX,
419 		.security_type = SECURITY_TYPE_PS,
420 	},
421 	{
422 		.peri_id = AT91C_ID_SFRBU,
423 		.matrix = MATRIX_H32MX,
424 		.security_type = SECURITY_TYPE_PS,
425 	},
426 	{
427 		.peri_id = AT91C_ID_CHIPID,
428 		.matrix = MATRIX_H32MX,
429 		.security_type = SECURITY_TYPE_PS,
430 	},
431 };
432 
matrix_write(unsigned int base,unsigned int offset,const unsigned int value)433 static void matrix_write(unsigned int base,
434 			 unsigned int offset,
435 			 const unsigned int value)
436 {
437 	io_write32(offset + base, value);
438 }
439 
matrix_read(int base,unsigned int offset)440 static unsigned int matrix_read(int base, unsigned int offset)
441 {
442 	return io_read32(offset + base);
443 }
444 
matrix_write_protect_enable(unsigned int matrix_base)445 void matrix_write_protect_enable(unsigned int matrix_base)
446 {
447 	matrix_write(matrix_base, MATRIX_WPMR,
448 		    (MATRIX_WPMR_WPKEY_PASSWD | MATRIX_WPMR_WPEN_ENABLE));
449 }
450 
matrix_write_protect_disable(unsigned int matrix_base)451 void matrix_write_protect_disable(unsigned int matrix_base)
452 {
453 	matrix_write(matrix_base, MATRIX_WPMR, MATRIX_WPMR_WPKEY_PASSWD);
454 }
455 
matrix_configure_slave_security(unsigned int matrix_base,unsigned int slave,unsigned int srtop_setting,unsigned int srsplit_setting,unsigned int ssr_setting)456 void matrix_configure_slave_security(unsigned int matrix_base,
457 				     unsigned int slave,
458 				     unsigned int srtop_setting,
459 				     unsigned int srsplit_setting,
460 				     unsigned int ssr_setting)
461 {
462 	matrix_write(matrix_base, MATRIX_SSR(slave), ssr_setting);
463 	matrix_write(matrix_base, MATRIX_SRTSR(slave), srtop_setting);
464 	matrix_write(matrix_base, MATRIX_SASSR(slave), srsplit_setting);
465 }
466 
get_peri_security(unsigned int peri_id)467 static const struct peri_security *get_peri_security(unsigned int peri_id)
468 {
469 	unsigned int i;
470 
471 	for (i = 0; i < ARRAY_SIZE(peri_security_array); i++) {
472 		if (peri_id == peri_security_array[i].peri_id)
473 			return &peri_security_array[i];
474 	}
475 
476 	return NULL;
477 }
478 
matrix_set_periph_world(unsigned int matrix,unsigned int peri_id,unsigned int world)479 static int matrix_set_periph_world(unsigned int matrix, unsigned int peri_id,
480 				   unsigned int world)
481 {
482 	unsigned int base;
483 	unsigned int spselr;
484 	unsigned int idx;
485 	unsigned int bit;
486 
487 	idx = peri_id / 32;
488 	if (idx > 3)
489 		return -1;
490 
491 	bit = (0x01 << (peri_id % 32));
492 
493 	if (matrix == MATRIX_H32MX)
494 		base = matrix32_base();
495 	else if (matrix == MATRIX_H64MX)
496 		base = matrix64_base();
497 	else
498 		return -1;
499 
500 	spselr = matrix_read(base, MATRIX_SPSELR(idx));
501 	if (world == WORLD_SECURE)
502 		spselr &= ~bit;
503 	else
504 		spselr |= bit;
505 	matrix_write(base, MATRIX_SPSELR(idx), spselr);
506 
507 	return 0;
508 }
509 
matrix_configure_periph_secure(unsigned int peri_id)510 int matrix_configure_periph_secure(unsigned int peri_id)
511 {
512 	const struct peri_security *psec = NULL;
513 
514 	psec = get_peri_security(peri_id);
515 	if (!psec)
516 		return -1;
517 
518 	return matrix_set_periph_world(psec->matrix, peri_id, WORLD_SECURE);
519 }
520 
matrix_configure_periph_non_secure(unsigned int * peri_id_array,unsigned int size)521 int matrix_configure_periph_non_secure(unsigned int *peri_id_array,
522 				       unsigned int size)
523 {
524 	unsigned int i;
525 	unsigned int *peri_id_p;
526 	unsigned int matrix;
527 	unsigned int peri_id;
528 	const struct peri_security *peripheral_sec;
529 	int ret;
530 
531 	if (!peri_id_array || !size)
532 		return -1;
533 
534 	peri_id_p = peri_id_array;
535 	for (i = 0; i < size; i++) {
536 		peripheral_sec = get_peri_security(*peri_id_p);
537 		if (!peripheral_sec)
538 			return -1;
539 
540 		if (peripheral_sec->security_type != SECURITY_TYPE_PS)
541 			return -1;
542 
543 		matrix = peripheral_sec->matrix;
544 		peri_id = *peri_id_p;
545 		ret = matrix_set_periph_world(matrix, peri_id,
546 					      WORLD_NON_SECURE);
547 		if (ret)
548 			return -1;
549 
550 		peri_id_p++;
551 	}
552 
553 	return 0;
554 }
555 
556 #ifdef CFG_PM_ARM32
557 struct matrix_state {
558 	uint32_t spselr[MATRIX_SPSELR_COUNT];
559 	uint32_t ssr[MATRIX_SLAVE_COUNT];
560 	uint32_t srtsr[MATRIX_SLAVE_COUNT];
561 	uint32_t sassr[MATRIX_SLAVE_COUNT];
562 	uint32_t meier;
563 	uint32_t meimr;
564 };
565 
566 static struct matrix_state matrix32_state;
567 static struct matrix_state matrix64_state;
568 
matrix_save_regs(vaddr_t base,struct matrix_state * state)569 static void matrix_save_regs(vaddr_t base, struct matrix_state *state)
570 {
571 	int idx = 0;
572 
573 	for (idx = 0; idx < MATRIX_SPSELR_COUNT; idx++)
574 		state->spselr[idx] = matrix_read(base, MATRIX_SPSELR(idx));
575 
576 	for (idx = 0; idx < MATRIX_SLAVE_COUNT; idx++) {
577 		state->ssr[idx] = matrix_read(base, MATRIX_SSR(idx));
578 		state->srtsr[idx] = matrix_read(base, MATRIX_SRTSR(idx));
579 		state->sassr[idx] = matrix_read(base, MATRIX_SASSR(idx));
580 	}
581 
582 	state->meier = matrix_read(base, MATRIX_MEIER);
583 	state->meimr = matrix_read(base, MATRIX_MEIMR);
584 }
585 
matrix_suspend(void)586 static void matrix_suspend(void)
587 {
588 	matrix_save_regs(matrix32_base(), &matrix32_state);
589 	matrix_save_regs(matrix64_base(), &matrix64_state);
590 }
591 
matrix_restore_regs(vaddr_t base,struct matrix_state * state)592 static void matrix_restore_regs(vaddr_t base, struct matrix_state *state)
593 {
594 	int idx = 0;
595 
596 	matrix_write_protect_disable(base);
597 
598 	for (idx = 0; idx < MATRIX_SPSELR_COUNT; idx++)
599 		matrix_write(base, MATRIX_SPSELR(idx), state->spselr[idx]);
600 
601 	for (idx = 0; idx < MATRIX_SLAVE_COUNT; idx++) {
602 		matrix_write(base, MATRIX_SSR(idx), state->ssr[idx]);
603 		matrix_write(base, MATRIX_SRTSR(idx), state->srtsr[idx]);
604 		matrix_write(base, MATRIX_SASSR(idx), state->sassr[idx]);
605 	}
606 
607 	matrix_write(base, MATRIX_MEIER, state->meier);
608 	matrix_write(base, MATRIX_MEIMR, state->meimr);
609 }
610 
matrix_resume(void)611 static void matrix_resume(void)
612 {
613 	matrix_restore_regs(matrix32_base(), &matrix32_state);
614 	matrix_restore_regs(matrix64_base(), &matrix64_state);
615 }
616 
matrix_pm(enum pm_op op,uint32_t pm_hint __unused,const struct pm_callback_handle * hdl __unused)617 static TEE_Result matrix_pm(enum pm_op op, uint32_t pm_hint __unused,
618 			    const struct pm_callback_handle *hdl __unused)
619 {
620 	switch (op) {
621 	case PM_OP_RESUME:
622 		matrix_resume();
623 		break;
624 	case PM_OP_SUSPEND:
625 		matrix_suspend();
626 		break;
627 	default:
628 		panic("Invalid PM operation");
629 	}
630 
631 	return TEE_SUCCESS;
632 }
633 
matrix_pm_init(void)634 static TEE_Result matrix_pm_init(void)
635 {
636 	/*
637 	 * We can't call matrix_register_pm in matrix_init since allocator is
638 	 * not ready yet so we just call it later in this driver init callback.
639 	 */
640 	register_pm_driver_cb(matrix_pm, NULL, "sam-matrix");
641 
642 	return TEE_SUCCESS;
643 }
644 driver_init(matrix_pm_init);
645 
646 #endif
647