xref: /optee_os/core/drivers/stm32_omm.c (revision 528e10da3fd4c2cfab6af22a87cd3ac7faf95f07)
1*528e10daSGatien Chevallier // SPDX-License-Identifier: BSD-2-Clause
2*528e10daSGatien Chevallier /*
3*528e10daSGatien Chevallier  * Copyright (c) 2021-2025, STMicroelectronics
4*528e10daSGatien Chevallier  */
5*528e10daSGatien Chevallier 
6*528e10daSGatien Chevallier #include <arm.h>
7*528e10daSGatien Chevallier #include <config.h>
8*528e10daSGatien Chevallier #include <drivers/clk.h>
9*528e10daSGatien Chevallier #include <drivers/clk_dt.h>
10*528e10daSGatien Chevallier #include <drivers/rstctrl.h>
11*528e10daSGatien Chevallier #include <drivers/stm32_gpio.h>
12*528e10daSGatien Chevallier #include <io.h>
13*528e10daSGatien Chevallier #include <kernel/boot.h>
14*528e10daSGatien Chevallier #include <kernel/delay.h>
15*528e10daSGatien Chevallier #include <kernel/dt.h>
16*528e10daSGatien Chevallier #include <kernel/dt_driver.h>
17*528e10daSGatien Chevallier #include <kernel/panic.h>
18*528e10daSGatien Chevallier #include <kernel/pm.h>
19*528e10daSGatien Chevallier #include <libfdt.h>
20*528e10daSGatien Chevallier #include <mm/core_memprot.h>
21*528e10daSGatien Chevallier #include <stdbool.h>
22*528e10daSGatien Chevallier #include <stdlib.h>
23*528e10daSGatien Chevallier #include <stm32_sysconf.h>
24*528e10daSGatien Chevallier #include <stm32_util.h>
25*528e10daSGatien Chevallier #include <trace.h>
26*528e10daSGatien Chevallier 
27*528e10daSGatien Chevallier /*
28*528e10daSGatien Chevallier  * OCTOSPI registers
29*528e10daSGatien Chevallier  */
30*528e10daSGatien Chevallier #define _OCTOSPI_CR			U(0x0)
31*528e10daSGatien Chevallier 
32*528e10daSGatien Chevallier /*
33*528e10daSGatien Chevallier  * OCTOSPI CR register bitfields
34*528e10daSGatien Chevallier  */
35*528e10daSGatien Chevallier #define _OCTOSPI_CR_EN			BIT(0)
36*528e10daSGatien Chevallier 
37*528e10daSGatien Chevallier /*
38*528e10daSGatien Chevallier  * OCTOSPIM registers
39*528e10daSGatien Chevallier  */
40*528e10daSGatien Chevallier #define _OCTOSPIM_CR			U(0x0)
41*528e10daSGatien Chevallier 
42*528e10daSGatien Chevallier /*
43*528e10daSGatien Chevallier  * OCTOSPIM CR register bitfields
44*528e10daSGatien Chevallier  */
45*528e10daSGatien Chevallier 
46*528e10daSGatien Chevallier #define _OCTOSPIM_CR_MUXEN		BIT(0)
47*528e10daSGatien Chevallier #define _OCTOSPIM_CR_MUXEN_MODE_MASK	GENMASK_32(1, 0)
48*528e10daSGatien Chevallier #define _OCTOSPIM_CR_CSSEL_OVR_EN	BIT(4)
49*528e10daSGatien Chevallier #define _OCTOSPIM_CR_CSSEL_OVR_MASK	GENMASK_32(6, 4)
50*528e10daSGatien Chevallier #define _OCTOSPIM_CR_CSSEL_OVR_SHIFT	U(5)
51*528e10daSGatien Chevallier #define _OCTOSPIM_CR_REQ2ACK_MASK	GENMASK_32(23, 16)
52*528e10daSGatien Chevallier #define _OCTOSPIM_CR_REQ2ACK_SHIFT	U(16)
53*528e10daSGatien Chevallier 
54*528e10daSGatien Chevallier #define OSPI_NB				U(2)
55*528e10daSGatien Chevallier #define OSPIM_NSEC_PER_SEC		UL(1000000000)
56*528e10daSGatien Chevallier #define OSPI_NB_RESET			U(2)
57*528e10daSGatien Chevallier #define OSPI_TIMEOUT_US_1MS		U(1000)
58*528e10daSGatien Chevallier #define OSPI_RESET_DELAY		U(2)
59*528e10daSGatien Chevallier 
60*528e10daSGatien Chevallier #define OMM_CS_OVERRIDE_DISABLE		U(0xff)
61*528e10daSGatien Chevallier 
62*528e10daSGatien Chevallier struct stm32_mm_region {
63*528e10daSGatien Chevallier 	paddr_t start;
64*528e10daSGatien Chevallier 	paddr_t end;
65*528e10daSGatien Chevallier };
66*528e10daSGatien Chevallier 
67*528e10daSGatien Chevallier struct stm32_ospi_pdata {
68*528e10daSGatien Chevallier 	struct clk *clock;
69*528e10daSGatien Chevallier 	struct rstctrl *reset[OSPI_NB_RESET];
70*528e10daSGatien Chevallier 	struct stm32_mm_region region;
71*528e10daSGatien Chevallier };
72*528e10daSGatien Chevallier 
73*528e10daSGatien Chevallier struct stm32_omm_pdata {
74*528e10daSGatien Chevallier 	struct clk *clock;
75*528e10daSGatien Chevallier 	struct pinctrl_state *pinctrl_d;
76*528e10daSGatien Chevallier 	struct pinctrl_state *pinctrl_s;
77*528e10daSGatien Chevallier 	struct stm32_ospi_pdata ospi_d[OSPI_NB];
78*528e10daSGatien Chevallier 	struct stm32_mm_region region;
79*528e10daSGatien Chevallier 	vaddr_t base;
80*528e10daSGatien Chevallier 	uint32_t mux;
81*528e10daSGatien Chevallier 	uint32_t cssel_ovr;
82*528e10daSGatien Chevallier 	uint32_t req2ack;
83*528e10daSGatien Chevallier };
84*528e10daSGatien Chevallier 
85*528e10daSGatien Chevallier static struct stm32_omm_pdata *omm_d;
86*528e10daSGatien Chevallier 
stm32_omm_parse_fdt(const void * fdt,int node)87*528e10daSGatien Chevallier static TEE_Result stm32_omm_parse_fdt(const void *fdt, int node)
88*528e10daSGatien Chevallier {
89*528e10daSGatien Chevallier 	struct stm32_ospi_pdata *ospi_d = NULL;
90*528e10daSGatien Chevallier 	size_t size = DT_INFO_INVALID_REG_SIZE;
91*528e10daSGatien Chevallier 	TEE_Result res = TEE_ERROR_GENERIC;
92*528e10daSGatien Chevallier 	paddr_t base = DT_INFO_INVALID_REG;
93*528e10daSGatien Chevallier 	const fdt32_t *cuint = NULL;
94*528e10daSGatien Chevallier 	struct io_pa_va addr = { };
95*528e10daSGatien Chevallier 	uint8_t ospi_assigned = 0;
96*528e10daSGatien Chevallier 	unsigned int reset_i = 0;
97*528e10daSGatien Chevallier 	uint32_t ospi_i = 0;
98*528e10daSGatien Chevallier 	unsigned int i = 0;
99*528e10daSGatien Chevallier 	int ctrl_node = 0;
100*528e10daSGatien Chevallier 	int len = 0;
101*528e10daSGatien Chevallier 
102*528e10daSGatien Chevallier 	if (fdt_get_reg_props_by_name(fdt, node, "regs", &base, &size) < 0)
103*528e10daSGatien Chevallier 		panic();
104*528e10daSGatien Chevallier 
105*528e10daSGatien Chevallier 	addr.pa = base;
106*528e10daSGatien Chevallier 	omm_d->base = io_pa_or_va(&addr, size);
107*528e10daSGatien Chevallier 
108*528e10daSGatien Chevallier 	if (fdt_get_reg_props_by_name(fdt, node, "memory_map", &base, &size) <
109*528e10daSGatien Chevallier 	    0)
110*528e10daSGatien Chevallier 		panic();
111*528e10daSGatien Chevallier 
112*528e10daSGatien Chevallier 	omm_d->region.start = base;
113*528e10daSGatien Chevallier 	omm_d->region.end = base + size;
114*528e10daSGatien Chevallier 	if (size)
115*528e10daSGatien Chevallier 		omm_d->region.end--;
116*528e10daSGatien Chevallier 
117*528e10daSGatien Chevallier 	res = clk_dt_get_by_index(fdt, node, 0, &omm_d->clock);
118*528e10daSGatien Chevallier 	if (res)
119*528e10daSGatien Chevallier 		return res;
120*528e10daSGatien Chevallier 
121*528e10daSGatien Chevallier 	res = pinctrl_get_state_by_name(fdt, node, "default",
122*528e10daSGatien Chevallier 					&omm_d->pinctrl_d);
123*528e10daSGatien Chevallier 	if (res && res != TEE_ERROR_ITEM_NOT_FOUND)
124*528e10daSGatien Chevallier 		return res;
125*528e10daSGatien Chevallier 
126*528e10daSGatien Chevallier 	res = pinctrl_get_state_by_name(fdt, node, "sleep",
127*528e10daSGatien Chevallier 					&omm_d->pinctrl_s);
128*528e10daSGatien Chevallier 	if (res && res != TEE_ERROR_ITEM_NOT_FOUND)
129*528e10daSGatien Chevallier 		return res;
130*528e10daSGatien Chevallier 
131*528e10daSGatien Chevallier 	omm_d->mux = fdt_read_uint32_default(fdt, node, "st,omm-mux", 0);
132*528e10daSGatien Chevallier 	omm_d->req2ack = fdt_read_uint32_default(fdt, node,
133*528e10daSGatien Chevallier 						 "st,omm-req2ack-ns", 0);
134*528e10daSGatien Chevallier 	omm_d->cssel_ovr = fdt_read_uint32_default(fdt, node,
135*528e10daSGatien Chevallier 						   "st,omm-cssel-ovr",
136*528e10daSGatien Chevallier 						   OMM_CS_OVERRIDE_DISABLE);
137*528e10daSGatien Chevallier 
138*528e10daSGatien Chevallier 	cuint = fdt_getprop(fdt, node, "memory-region", &len);
139*528e10daSGatien Chevallier 	if (cuint) {
140*528e10daSGatien Chevallier 		const char *mm_name[OSPI_NB] = { "mm_ospi1", "mm_ospi2" };
141*528e10daSGatien Chevallier 		struct stm32_mm_region *region = NULL;
142*528e10daSGatien Chevallier 		uint32_t offset = 0;
143*528e10daSGatien Chevallier 		int pnode = 0;
144*528e10daSGatien Chevallier 		int index = 0;
145*528e10daSGatien Chevallier 
146*528e10daSGatien Chevallier 		for (i = 0; i < OSPI_NB; i++) {
147*528e10daSGatien Chevallier 			index = fdt_stringlist_search(fdt, node,
148*528e10daSGatien Chevallier 						      "memory-region-names",
149*528e10daSGatien Chevallier 						      mm_name[i]);
150*528e10daSGatien Chevallier 			if (index < 0)
151*528e10daSGatien Chevallier 				continue;
152*528e10daSGatien Chevallier 
153*528e10daSGatien Chevallier 			if (index >= (int)(len / sizeof(uint32_t)))
154*528e10daSGatien Chevallier 				panic();
155*528e10daSGatien Chevallier 
156*528e10daSGatien Chevallier 			offset = fdt32_to_cpu(*(cuint + index));
157*528e10daSGatien Chevallier 			pnode = fdt_node_offset_by_phandle(fdt, offset);
158*528e10daSGatien Chevallier 			if (pnode < 0)
159*528e10daSGatien Chevallier 				panic();
160*528e10daSGatien Chevallier 
161*528e10daSGatien Chevallier 			region = &omm_d->ospi_d[i].region;
162*528e10daSGatien Chevallier 			if (fdt_reg_info(fdt, pnode, &region->start, &size) < 0)
163*528e10daSGatien Chevallier 				panic();
164*528e10daSGatien Chevallier 
165*528e10daSGatien Chevallier 			region->end = region->start + size;
166*528e10daSGatien Chevallier 			if (size)
167*528e10daSGatien Chevallier 				region->end--;
168*528e10daSGatien Chevallier 		}
169*528e10daSGatien Chevallier 	}
170*528e10daSGatien Chevallier 
171*528e10daSGatien Chevallier 	fdt_for_each_subnode(ctrl_node, fdt, node)
172*528e10daSGatien Chevallier 		ospi_i++;
173*528e10daSGatien Chevallier 
174*528e10daSGatien Chevallier 	if (ospi_i != OSPI_NB)
175*528e10daSGatien Chevallier 		panic();
176*528e10daSGatien Chevallier 
177*528e10daSGatien Chevallier 	fdt_for_each_subnode(ctrl_node, fdt, node) {
178*528e10daSGatien Chevallier 		cuint = fdt_getprop(fdt, ctrl_node, "reg", NULL);
179*528e10daSGatien Chevallier 		if (!cuint)
180*528e10daSGatien Chevallier 			panic();
181*528e10daSGatien Chevallier 
182*528e10daSGatien Chevallier 		ospi_i = fdt32_to_cpu(*cuint);
183*528e10daSGatien Chevallier 		if (ospi_i >= OSPI_NB || (ospi_assigned & BIT(ospi_i)))
184*528e10daSGatien Chevallier 			panic();
185*528e10daSGatien Chevallier 
186*528e10daSGatien Chevallier 		ospi_d = &omm_d->ospi_d[ospi_i];
187*528e10daSGatien Chevallier 		ospi_assigned |= BIT(ospi_i);
188*528e10daSGatien Chevallier 
189*528e10daSGatien Chevallier 		res = clk_dt_get_by_index(fdt, ctrl_node, 0, &ospi_d->clock);
190*528e10daSGatien Chevallier 		if (res)
191*528e10daSGatien Chevallier 			return res;
192*528e10daSGatien Chevallier 
193*528e10daSGatien Chevallier 		for (reset_i = 0; reset_i < OSPI_NB_RESET; reset_i++) {
194*528e10daSGatien Chevallier 			res = rstctrl_dt_get_by_index(fdt, ctrl_node, reset_i,
195*528e10daSGatien Chevallier 						      &ospi_d->reset[reset_i]);
196*528e10daSGatien Chevallier 			if (res)
197*528e10daSGatien Chevallier 				return res;
198*528e10daSGatien Chevallier 		}
199*528e10daSGatien Chevallier 	}
200*528e10daSGatien Chevallier 
201*528e10daSGatien Chevallier 	return res;
202*528e10daSGatien Chevallier }
203*528e10daSGatien Chevallier 
stm32_omm_region_contains(struct stm32_mm_region * r1,struct stm32_mm_region * r2)204*528e10daSGatien Chevallier static bool stm32_omm_region_contains(struct stm32_mm_region *r1,
205*528e10daSGatien Chevallier 				      struct stm32_mm_region *r2)
206*528e10daSGatien Chevallier {
207*528e10daSGatien Chevallier 	return r1->start <= r2->start && r1->end >= r2->end;
208*528e10daSGatien Chevallier }
209*528e10daSGatien Chevallier 
stm32_omm_region_overlaps(struct stm32_mm_region * r1,struct stm32_mm_region * r2)210*528e10daSGatien Chevallier static bool stm32_omm_region_overlaps(struct stm32_mm_region *r1,
211*528e10daSGatien Chevallier 				      struct stm32_mm_region *r2)
212*528e10daSGatien Chevallier {
213*528e10daSGatien Chevallier 	return r1->start <= r2->end && r1->end >= r2->start;
214*528e10daSGatien Chevallier }
215*528e10daSGatien Chevallier 
stm32_omm_set_mm(void)216*528e10daSGatien Chevallier static void stm32_omm_set_mm(void)
217*528e10daSGatien Chevallier {
218*528e10daSGatien Chevallier 	struct stm32_mm_region *region[OSPI_NB] = { };
219*528e10daSGatien Chevallier 	unsigned int valid_regions = 0;
220*528e10daSGatien Chevallier 	size_t mm_size[OSPI_NB] = { };
221*528e10daSGatien Chevallier 	unsigned int ospi_i = 0;
222*528e10daSGatien Chevallier 
223*528e10daSGatien Chevallier 	for (ospi_i = 0; ospi_i < OSPI_NB; ospi_i++) {
224*528e10daSGatien Chevallier 		region[ospi_i] = &omm_d->ospi_d[ospi_i].region;
225*528e10daSGatien Chevallier 
226*528e10daSGatien Chevallier 		if (region[ospi_i]->start >= region[ospi_i]->end)
227*528e10daSGatien Chevallier 			continue;
228*528e10daSGatien Chevallier 
229*528e10daSGatien Chevallier 		if (!stm32_omm_region_contains(&omm_d->region, region[ospi_i]))
230*528e10daSGatien Chevallier 			panic();
231*528e10daSGatien Chevallier 
232*528e10daSGatien Chevallier 		mm_size[ospi_i] = region[ospi_i]->end - region[ospi_i]->start
233*528e10daSGatien Chevallier 				  + 1;
234*528e10daSGatien Chevallier 		valid_regions++;
235*528e10daSGatien Chevallier 	}
236*528e10daSGatien Chevallier 
237*528e10daSGatien Chevallier 	if (valid_regions == OSPI_NB &&
238*528e10daSGatien Chevallier 	    stm32_omm_region_overlaps(region[0], region[1]))
239*528e10daSGatien Chevallier 		panic();
240*528e10daSGatien Chevallier 
241*528e10daSGatien Chevallier 	if (valid_regions)
242*528e10daSGatien Chevallier 		stm32mp25_syscfg_set_amcr(mm_size[0], mm_size[1]);
243*528e10daSGatien Chevallier }
244*528e10daSGatien Chevallier 
stm32_omm_configure(void)245*528e10daSGatien Chevallier static void stm32_omm_configure(void)
246*528e10daSGatien Chevallier {
247*528e10daSGatien Chevallier 	struct stm32_ospi_pdata *ospi_d = NULL;
248*528e10daSGatien Chevallier 	unsigned long clk_rate_max = 0;
249*528e10daSGatien Chevallier 	unsigned int reset_i = 0;
250*528e10daSGatien Chevallier 	unsigned int ospi_i = 0;
251*528e10daSGatien Chevallier 	uint32_t cssel_ovr = 0;
252*528e10daSGatien Chevallier 	uint32_t req2ack = 0;
253*528e10daSGatien Chevallier 
254*528e10daSGatien Chevallier 	for (ospi_i = 0; ospi_i < OSPI_NB; ospi_i++) {
255*528e10daSGatien Chevallier 		ospi_d = &omm_d->ospi_d[ospi_i];
256*528e10daSGatien Chevallier 		clk_rate_max = MAX(clk_get_rate(ospi_d->clock), clk_rate_max);
257*528e10daSGatien Chevallier 
258*528e10daSGatien Chevallier 		if (clk_enable(ospi_d->clock))
259*528e10daSGatien Chevallier 			panic();
260*528e10daSGatien Chevallier 
261*528e10daSGatien Chevallier 		for (reset_i = 0; reset_i < OSPI_NB_RESET; reset_i++) {
262*528e10daSGatien Chevallier 			if (rstctrl_assert_to(ospi_d->reset[reset_i],
263*528e10daSGatien Chevallier 					      OSPI_TIMEOUT_US_1MS))
264*528e10daSGatien Chevallier 				panic();
265*528e10daSGatien Chevallier 		}
266*528e10daSGatien Chevallier 
267*528e10daSGatien Chevallier 		udelay(OSPI_RESET_DELAY);
268*528e10daSGatien Chevallier 
269*528e10daSGatien Chevallier 		for (reset_i = 0; reset_i < OSPI_NB_RESET; reset_i++) {
270*528e10daSGatien Chevallier 			if (rstctrl_deassert_to(ospi_d->reset[reset_i],
271*528e10daSGatien Chevallier 						OSPI_TIMEOUT_US_1MS))
272*528e10daSGatien Chevallier 				panic();
273*528e10daSGatien Chevallier 		}
274*528e10daSGatien Chevallier 
275*528e10daSGatien Chevallier 		clk_disable(ospi_d->clock);
276*528e10daSGatien Chevallier 	}
277*528e10daSGatien Chevallier 
278*528e10daSGatien Chevallier 	if (omm_d->mux & _OCTOSPIM_CR_MUXEN && omm_d->req2ack) {
279*528e10daSGatien Chevallier 		unsigned long hclkn = OSPIM_NSEC_PER_SEC / clk_rate_max;
280*528e10daSGatien Chevallier 		unsigned long timing = DIV_ROUND_UP(omm_d->req2ack, hclkn) - 1;
281*528e10daSGatien Chevallier 
282*528e10daSGatien Chevallier 		if (timing >
283*528e10daSGatien Chevallier 		    _OCTOSPIM_CR_REQ2ACK_MASK >> _OCTOSPIM_CR_REQ2ACK_SHIFT)
284*528e10daSGatien Chevallier 			req2ack = _OCTOSPIM_CR_REQ2ACK_MASK;
285*528e10daSGatien Chevallier 		else
286*528e10daSGatien Chevallier 			req2ack = timing << _OCTOSPIM_CR_REQ2ACK_SHIFT;
287*528e10daSGatien Chevallier 	}
288*528e10daSGatien Chevallier 
289*528e10daSGatien Chevallier 	if (omm_d->cssel_ovr != OMM_CS_OVERRIDE_DISABLE)
290*528e10daSGatien Chevallier 		cssel_ovr = (omm_d->cssel_ovr << _OCTOSPIM_CR_CSSEL_OVR_SHIFT) |
291*528e10daSGatien Chevallier 			    _OCTOSPIM_CR_CSSEL_OVR_EN;
292*528e10daSGatien Chevallier 
293*528e10daSGatien Chevallier 	if (clk_enable(omm_d->clock))
294*528e10daSGatien Chevallier 		panic();
295*528e10daSGatien Chevallier 
296*528e10daSGatien Chevallier 	io_clrsetbits32(omm_d->base + _OCTOSPIM_CR,
297*528e10daSGatien Chevallier 			_OCTOSPIM_CR_REQ2ACK_MASK |
298*528e10daSGatien Chevallier 			_OCTOSPIM_CR_CSSEL_OVR_MASK |
299*528e10daSGatien Chevallier 			_OCTOSPIM_CR_MUXEN_MODE_MASK,
300*528e10daSGatien Chevallier 			req2ack | cssel_ovr | omm_d->mux);
301*528e10daSGatien Chevallier 
302*528e10daSGatien Chevallier 	clk_disable(omm_d->clock);
303*528e10daSGatien Chevallier 
304*528e10daSGatien Chevallier 	if (omm_d->mux & _OCTOSPIM_CR_MUXEN) {
305*528e10daSGatien Chevallier 		/*
306*528e10daSGatien Chevallier 		 * If the mux is enabled, the 2 OSPI clocks have to be
307*528e10daSGatien Chevallier 		 * always enabled
308*528e10daSGatien Chevallier 		 */
309*528e10daSGatien Chevallier 		for (ospi_i = 0; ospi_i < OSPI_NB; ospi_i++) {
310*528e10daSGatien Chevallier 			ospi_d = &omm_d->ospi_d[ospi_i];
311*528e10daSGatien Chevallier 
312*528e10daSGatien Chevallier 			if (clk_enable(ospi_d->clock))
313*528e10daSGatien Chevallier 				panic();
314*528e10daSGatien Chevallier 		}
315*528e10daSGatien Chevallier 	}
316*528e10daSGatien Chevallier }
317*528e10daSGatien Chevallier 
stm32_omm_setup(void)318*528e10daSGatien Chevallier static void stm32_omm_setup(void)
319*528e10daSGatien Chevallier {
320*528e10daSGatien Chevallier 	stm32_omm_set_mm();
321*528e10daSGatien Chevallier 	stm32_omm_configure();
322*528e10daSGatien Chevallier 	if (omm_d->pinctrl_d && pinctrl_apply_state(omm_d->pinctrl_d))
323*528e10daSGatien Chevallier 		panic();
324*528e10daSGatien Chevallier }
325*528e10daSGatien Chevallier 
stm32_omm_suspend(void)326*528e10daSGatien Chevallier static void stm32_omm_suspend(void)
327*528e10daSGatien Chevallier {
328*528e10daSGatien Chevallier 	if (omm_d->pinctrl_s && pinctrl_apply_state(omm_d->pinctrl_s))
329*528e10daSGatien Chevallier 		panic();
330*528e10daSGatien Chevallier }
331*528e10daSGatien Chevallier 
332*528e10daSGatien Chevallier static TEE_Result
stm32_omm_pm(enum pm_op op,unsigned int pm_hint,const struct pm_callback_handle * pm_handle __unused)333*528e10daSGatien Chevallier stm32_omm_pm(enum pm_op op, unsigned int pm_hint,
334*528e10daSGatien Chevallier 	     const struct pm_callback_handle *pm_handle __unused)
335*528e10daSGatien Chevallier {
336*528e10daSGatien Chevallier 	if (!PM_HINT_IS_STATE(pm_hint, CONTEXT))
337*528e10daSGatien Chevallier 		return TEE_SUCCESS;
338*528e10daSGatien Chevallier 
339*528e10daSGatien Chevallier 	if (op == PM_OP_RESUME)
340*528e10daSGatien Chevallier 		stm32_omm_setup();
341*528e10daSGatien Chevallier 	else
342*528e10daSGatien Chevallier 		stm32_omm_suspend();
343*528e10daSGatien Chevallier 
344*528e10daSGatien Chevallier 	return TEE_SUCCESS;
345*528e10daSGatien Chevallier }
346*528e10daSGatien Chevallier 
stm32_omm_probe(const void * fdt,int node,const void * compat_data __unused)347*528e10daSGatien Chevallier static TEE_Result stm32_omm_probe(const void *fdt, int node,
348*528e10daSGatien Chevallier 				  const void *compat_data __unused)
349*528e10daSGatien Chevallier {
350*528e10daSGatien Chevallier 	TEE_Result res = TEE_ERROR_GENERIC;
351*528e10daSGatien Chevallier 
352*528e10daSGatien Chevallier 	omm_d = calloc(1, sizeof(*omm_d));
353*528e10daSGatien Chevallier 	if (!omm_d)
354*528e10daSGatien Chevallier 		return TEE_ERROR_OUT_OF_MEMORY;
355*528e10daSGatien Chevallier 
356*528e10daSGatien Chevallier 	res = stm32_omm_parse_fdt(fdt, node);
357*528e10daSGatien Chevallier 	if (res)
358*528e10daSGatien Chevallier 		goto err_free;
359*528e10daSGatien Chevallier 
360*528e10daSGatien Chevallier 	stm32_omm_setup();
361*528e10daSGatien Chevallier 
362*528e10daSGatien Chevallier 	register_pm_core_service_cb(stm32_omm_pm, NULL, "stm32-omm");
363*528e10daSGatien Chevallier 
364*528e10daSGatien Chevallier 	return TEE_SUCCESS;
365*528e10daSGatien Chevallier 
366*528e10daSGatien Chevallier err_free:
367*528e10daSGatien Chevallier 	free(omm_d);
368*528e10daSGatien Chevallier 
369*528e10daSGatien Chevallier 	return res;
370*528e10daSGatien Chevallier }
371*528e10daSGatien Chevallier 
372*528e10daSGatien Chevallier static const struct dt_device_match stm32_omm_match_table[] = {
373*528e10daSGatien Chevallier 	{ .compatible = "st,stm32mp25-omm" },
374*528e10daSGatien Chevallier 	{ }
375*528e10daSGatien Chevallier };
376*528e10daSGatien Chevallier 
377*528e10daSGatien Chevallier DEFINE_DT_DRIVER(stm32_omm_dt_driver) = {
378*528e10daSGatien Chevallier 	.name = "stm32_omm",
379*528e10daSGatien Chevallier 	.match_table = stm32_omm_match_table,
380*528e10daSGatien Chevallier 	.probe = stm32_omm_probe,
381*528e10daSGatien Chevallier };
382