1 /*
2  * Copyright (c) 2024 Nordic Semiconductor ASA
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #ifndef ZEPHYR_INCLUDE_DRIVERS_MISC_CORESIGHT_STMESP_H_
8 #define ZEPHYR_INCLUDE_DRIVERS_MISC_CORESIGHT_STMESP_H_
9 
10 #include <zephyr/devicetree.h>
11 
12 /**
13  * @brief Coresight STMESP (STM Extended Stimulus Port) Interface
14  * @defgroup stmsp_interface Coresight STMESP interface
15  * @ingroup misc_interfaces
16  * @{
17  */
18 
19 #ifdef __cplusplus
20 extern "C" {
21 #endif
22 
23 /** @cond INTERNAL_HIDDEN
24  * @brief STMESP register structure.
25  */
26 typedef struct {
27 	volatile uint32_t G_DMTS[2];
28 	volatile uint32_t G_DM[2];
29 	volatile uint32_t G_DTS[2];
30 	volatile uint32_t G_D[2];
31 	volatile uint32_t RESERVED0[16];
32 	volatile uint32_t G_FLAGTS[2];
33 	volatile uint32_t G_FLAG[2];
34 	volatile uint32_t G_TRIGTS[2];
35 	volatile uint32_t G_TRIG[2];
36 	volatile uint32_t I_DMTS[2];
37 	volatile uint32_t I_DM[2];
38 	volatile uint32_t I_DTS[2];
39 	volatile uint32_t I_D[2];
40 	volatile uint32_t RESERVED1[16];
41 	volatile uint32_t I_FLAGTS[2];
42 	volatile uint32_t I_FLAG[2];
43 	volatile uint32_t I_TRIGTS[2];
44 	volatile uint32_t I_TRIG[2];
45 } STMESP_Type;
46 
47 /** @brief Helper function for getting target register.
48  *
49  * @param reg STMESP register set.
50  * @param ts Use timestamp.
51  * @param marked Use marked register.
52  * @param guaranteed True to use guaranteed access.
53  *
54  * @return Address of the register.
55  */
_stmesp_get_data_reg(STMESP_Type * reg,bool ts,bool marked,bool guaranteed)56 static inline volatile void *_stmesp_get_data_reg(STMESP_Type *reg, bool ts,
57 						  bool marked, bool guaranteed)
58 {
59 	if (ts) {
60 		if (guaranteed) {
61 			if (marked) {
62 				return &reg->G_DMTS[0];
63 			} else {
64 				return &reg->G_DTS[0];
65 			}
66 		} else {
67 			if (marked) {
68 				return &reg->I_DMTS[0];
69 			} else {
70 				return &reg->I_DTS[0];
71 			}
72 		}
73 	} else {
74 		if (guaranteed) {
75 			if (marked) {
76 				return &reg->G_DM[0];
77 			} else {
78 				return &reg->G_D[0];
79 			}
80 		} else {
81 			if (marked) {
82 				return &reg->I_DM[0];
83 			} else {
84 				return &reg->I_D[0];
85 			}
86 		}
87 	}
88 }
89 
90 /** @endcond */
91 
92 /** @brief Write flag to STMESP
93  *
94  * @param reg STMESP register set.
95  * @param data Data written to the flag register.
96  * @param ts If true add timestamp.
97  * @param guaranteed If true guaranteed write and invariant if false.
98  */
stmesp_flag(STMESP_Type * reg,uint32_t data,bool ts,bool guaranteed)99 static inline void stmesp_flag(STMESP_Type *reg, uint32_t data, bool ts, bool guaranteed)
100 {
101 	if (ts) {
102 		if (guaranteed) {
103 			reg->G_FLAGTS[0] = data;
104 		} else {
105 			reg->I_FLAGTS[0] = data;
106 		}
107 	} else {
108 		if (guaranteed) {
109 			reg->G_FLAG[0] = data;
110 		} else {
111 			reg->I_FLAG[0] = data;
112 		}
113 	}
114 }
115 
116 /** @brief Write 8 bit data to STMESP
117  *
118  * @param reg STMESP register set.
119  * @param data Byte to write.
120  * @param ts If true add timestamp.
121  * @param marked If true marked write.
122  * @param guaranteed If true guaranteed write and invariant if false.
123  */
stmesp_data8(STMESP_Type * reg,uint8_t data,bool ts,bool marked,bool guaranteed)124 static inline void stmesp_data8(STMESP_Type *reg, uint8_t data, bool ts,
125 				bool marked, bool guaranteed)
126 {
127 	*(volatile uint8_t *)_stmesp_get_data_reg(reg, ts, marked, guaranteed) = data;
128 }
129 
130 /** @brief Write 16 bit data to STMESP
131  *
132  * @param reg STMESP register set.
133  * @param data Half word to write.
134  * @param ts If true add timestamp.
135  * @param marked If true marked write.
136  * @param guaranteed If true guaranteed write and invariant if false.
137  */
stmesp_data16(STMESP_Type * reg,uint16_t data,bool ts,bool marked,bool guaranteed)138 static inline void stmesp_data16(STMESP_Type *reg, uint16_t data, bool ts,
139 				 bool marked, bool guaranteed)
140 {
141 	*(volatile uint16_t *)_stmesp_get_data_reg(reg, ts, marked, guaranteed) = data;
142 }
143 
144 /** @brief Write 32 bit data to STMESP
145  *
146  * @param reg STMESP register set.
147  * @param data Word to write.
148  * @param ts If true add timestamp.
149  * @param marked If true marked write.
150  * @param guaranteed If true guaranteed write and invariant if false.
151  */
stmesp_data32(STMESP_Type * reg,uint32_t data,bool ts,bool marked,bool guaranteed)152 static inline void stmesp_data32(STMESP_Type *reg, uint32_t data, bool ts,
153 				 bool marked, bool guaranteed)
154 {
155 	*(volatile uint32_t *)_stmesp_get_data_reg(reg, ts, marked, guaranteed) = data;
156 }
157 
158 /**
159  * @brief Return address of a STM extended stimulus port.
160  *
161  * Function return a port from the local STMESP instance.
162  *
163  * @param[in]	idx	Index of the requested stimulus port.
164  * @param[out]	port	Location where pointer to the port is written.
165  *
166  * @retval	-EINVAL if @p idx or @p port is invalid.
167  * @retval	0 on success.
168  */
stmesp_get_port(uint32_t idx,STMESP_Type ** port)169 static inline int stmesp_get_port(uint32_t idx, STMESP_Type **port)
170 
171 {
172 	/* Check if index is within STM ports */
173 	if ((port == NULL) ||
174 	    (idx >= (DT_REG_SIZE(DT_NODELABEL(stmesp)) / sizeof(STMESP_Type)))) {
175 		return -EINVAL;
176 	}
177 
178 	STMESP_Type *const base = (STMESP_Type *const)DT_REG_ADDR(DT_NODELABEL(stmesp));
179 
180 	*port = &base[idx];
181 
182 	return 0;
183 }
184 
185 #ifdef __cplusplus
186 }
187 #endif
188 
189 /**
190  * @}
191  */
192 
193 #endif /* ZEPHYR_INCLUDE_DRIVERS_MISC_CORESIGHT_STMESP_H_ */
194