xref: /optee_os/core/drivers/crypto/caam/hal/common/hal_cfg_dt.c (revision 6a0116edfb65dc6c4096e8ad2b94989699c7c7a6)
1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright 2017-2019, 2021 NXP
4  *
5  * Brief   CAAM Configuration.
6  */
7 #include <caam_common.h>
8 #include <caam_hal_cfg.h>
9 #include <caam_hal_jr.h>
10 #include <caam_jr.h>
11 #include <kernel/boot.h>
12 #include <kernel/dt.h>
13 #include <kernel/interrupt.h>
14 #include <libfdt.h>
15 #include <mm/core_memprot.h>
16 #include <mm/core_mmu.h>
17 
18 static const char *dt_caam_match_table = {
19 	"fsl,sec-v4.0",
20 };
21 
22 static const char *dt_jr_match_table = {
23 	"fsl,sec-v4.0-job-ring",
24 };
25 
26 /*
27  * Finds the Job Ring reserved for the Secure Mode in the DTB
28  *
29  * @fdt         Reference to the Device Tree
30  * @status      Status mask flag of the node to found
31  * @find_node   [out] Node offset found
32  */
find_jr_offset(void * fdt,int status,int * find_node)33 static paddr_t find_jr_offset(void *fdt, int status, int *find_node)
34 {
35 	paddr_t jr_offset = 0;
36 	int node = fdt_node_offset_by_compatible(fdt, 0, dt_jr_match_table);
37 
38 	for (; node != -FDT_ERR_NOTFOUND;
39 	     node = fdt_node_offset_by_compatible(fdt, node,
40 						  dt_jr_match_table)) {
41 		HAL_TRACE("Found Job Ring node status @%" PRId32, node);
42 		if (fdt_get_status(fdt, node) == status) {
43 			HAL_TRACE("Found Job Ring node @%" PRId32, node);
44 			jr_offset = fdt_reg_base_address(fdt, node);
45 			*find_node = node;
46 			break;
47 		}
48 	}
49 
50 	HAL_TRACE("JR Offset return 0x%" PRIxPTR, jr_offset);
51 	return jr_offset;
52 }
53 
caam_hal_cfg_get_ctrl_dt(void * fdt,vaddr_t * ctrl_base)54 void caam_hal_cfg_get_ctrl_dt(void *fdt, vaddr_t *ctrl_base)
55 {
56 	size_t size = 0;
57 	int node = 0;
58 	paddr_t pctrl_base = 0;
59 
60 	*ctrl_base = 0;
61 	/* Get the CAAM Node to get the controller base address */
62 	node = fdt_node_offset_by_compatible(fdt, 0, dt_caam_match_table);
63 
64 	if (node < 0)
65 		return;
66 
67 	/*
68 	 * Map CAAM controller base address as Secure IO if not
69 	 * already present in the MMU table.
70 	 * Then get the virtual address of the CAAM controller
71 	 */
72 	if (fdt_reg_info(fdt, node, &pctrl_base, &size)) {
73 		HAL_TRACE("CAAM control base address or size not defined");
74 		return;
75 	}
76 
77 	*ctrl_base = (vaddr_t)core_mmu_add_mapping(MEM_AREA_IO_SEC, pctrl_base,
78 						   size);
79 	if (!*ctrl_base) {
80 		EMSG("CAAM control base MMU PA mapping failure");
81 		return;
82 	}
83 
84 	HAL_TRACE("Map Controller 0x%" PRIxVA, *ctrl_base);
85 }
86 
caam_hal_cfg_get_jobring_dt(void * fdt,struct caam_jrcfg * jrcfg)87 void caam_hal_cfg_get_jobring_dt(void *fdt, struct caam_jrcfg *jrcfg)
88 {
89 	paddr_t jr_offset = 0;
90 	int jr_it_num = 0;
91 	int node = 0;
92 
93 	jr_offset = find_jr_offset(fdt, DT_STATUS_OK_SEC, &node);
94 	if (jr_offset) {
95 		if (!is_embedded_dt(fdt)) {
96 			/* Disable JR for Normal World */
97 			if (dt_enable_secure_status(fdt, node)) {
98 				EMSG("Not able to disable JR DTB entry");
99 				return;
100 			}
101 		}
102 
103 		/* Get the job ring interrupt */
104 		jr_it_num = dt_get_irq(fdt, node);
105 		if (jr_it_num == DT_INFO_INVALID_INTERRUPT) {
106 			EMSG("Job Ring interrupt number not defined in DTB");
107 			return;
108 		}
109 
110 		jrcfg->offset = jr_offset;
111 		jrcfg->it_num = jr_it_num;
112 	}
113 }
114 
caam_hal_cfg_disable_jobring_dt(void * fdt,struct caam_jrcfg * jrcfg)115 void caam_hal_cfg_disable_jobring_dt(void *fdt, struct caam_jrcfg *jrcfg)
116 {
117 	int node = fdt_node_offset_by_compatible(fdt, 0, dt_jr_match_table);
118 
119 	for (; node != -FDT_ERR_NOTFOUND;
120 	     node = fdt_node_offset_by_compatible(fdt, node,
121 						  dt_jr_match_table)) {
122 		HAL_TRACE("Found Job Ring node @%" PRId32, node);
123 		if (fdt_reg_base_address(fdt, node) == jrcfg->offset) {
124 			HAL_TRACE("Disable Job Ring node @%" PRId32, node);
125 			if (dt_enable_secure_status(fdt, node))
126 				panic();
127 			break;
128 		}
129 	}
130 }
131