1 /*
2  * Copyright (c) 2023 Intel Corporation
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #ifndef _SEDI_DRIVER_COMMON_H_
8 #define _SEDI_DRIVER_COMMON_H_
9 
10 #include <stdbool.h>
11 #include <stdint.h>
12 
13 #include "sedi_soc_regs.h"
14 #include "sedi_soc.h"
15 
16 /*!
17  * \defgroup sedi_driver_common Common
18  * \ingroup sedi_driver
19  */
20 
21 #ifndef NULL
22 #define NULL ((void *)0)
23 #endif
24 
25 /*!
26  * \def BIT
27  * \brief Generate a mask with bit x set.
28  * \ingroup sedi_driver_common
29  */
30 
31 #ifndef BIT
32 #define BIT(x) (1U << (x))
33 #endif
34 
35 /*!
36  * \defgroup sedi_driver_common Common
37  * \ingroup sedi_driver
38  */
39 
40 #ifndef TRUE
41 #define TRUE 1
42 #endif
43 
44 /*!
45  * \defgroup sedi_driver_common Common
46  * \ingroup sedi_driver
47  */
48 
49 #ifndef FALSE
50 #define FALSE 0
51 #endif
52 
53 /*!
54  * \defgroup sedi_driver_common Common
55  * \ingroup sedi_driver
56  */
57 
58 #ifndef MS_PER_SEC
59 #define MS_PER_SEC 1000
60 #endif
61 
62 #ifndef NS_PER_US
63 #define NS_PER_US 1000
64 #endif
65 
66 /*!
67  * \def SEDI_DRIVER_VERSION_MAJOR_MINOR
68  * \ingroup sedi_driver_common
69  */
70 #define SEDI_DRIVER_VERSION_MAJOR_MINOR(major, minor) (((major) << 8) | (minor))
71 
72 /*!
73  * \struct sedi_driver_version_t
74  * \brief Driver Version
75  * \ingroup sedi_driver_common
76  */
77 typedef struct {
78 	uint16_t api; /**< API version */
79 	uint16_t drv; /**< Driver version */
80 } sedi_driver_version_t;
81 
82 /*!
83  * \defgroup return_status  Return Status Codes
84  * \ingroup sedi_driver_common
85  * \{
86  */
87 
88 /*!
89  * \def SEDI_DRIVER_OK
90  * \brief Operation succeeded
91  */
92 #define SEDI_DRIVER_OK 0
93 
94 /*!
95  * \def SEDI_DRIVER_ERROR
96  * \brief Unspecified error
97  */
98 #define SEDI_DRIVER_ERROR -1
99 
100 /*!
101  * \def SEDI_DRIVER_ERROR_BUSY
102  * \brief Driver is busy
103  */
104 #define SEDI_DRIVER_ERROR_BUSY -2
105 
106 /*!
107  * \def SEDI_DRIVER_ERROR_TIMEOUT
108  * \brief Timeout occurred
109  */
110 #define SEDI_DRIVER_ERROR_TIMEOUT -3
111 
112 /*!
113  * \def SEDI_DRIVER_ERROR_UNSUPPORTED
114  * \brief Operation not supported
115  */
116 #define SEDI_DRIVER_ERROR_UNSUPPORTED -4
117 
118 /*!
119  * \def SEDI_DRIVER_ERROR_PARAMETER
120  * \brief Parameter error
121  */
122 #define SEDI_DRIVER_ERROR_PARAMETER -5
123 
124 /*!
125  * \def SEDI_DRIVER_ERROR_TRANSFER
126  * \brief transfer error
127  */
128 #define SEDI_DRIVER_ERROR_TRANSFER -6
129 
130 /*!
131  * \def SEDI_DRIVER_ERROR_NO_DEV
132  * \brief Device not available
133  */
134 #define SEDI_DRIVER_ERROR_NO_DEV -7
135 
136 /*!
137  * \def SEDI_DRIVER_ERROR_SPECIFIC
138  * \brief Start of driver specific errors
139  */
140 #define SEDI_DRIVER_ERROR_SPECIFIC -8
141 
142 /*!
143  * \def SEDI_USART_ERROR_CANCELED
144  * \brief Operation was canceled.
145  */
146 #define SEDI_USART_ERROR_CANCELED (SEDI_DRIVER_ERROR_SPECIFIC - 1)
147 
148 /*!
149  * \def SEDI_PM_ERROR_NOMEM
150  * \brief No empty entry for client configurations.
151  */
152 #define SEDI_PM_ERROR_NOMEM (SEDI_DRIVER_ERROR_SPECIFIC - 2)
153 
154 /*!
155  * \def SEDI_PM_ERROR_INTR_PENDING
156  * \brief Interrupt pending to block clock gating.
157  */
158 #define SEDI_PM_ERROR_INTR_PENDING (SEDI_DRIVER_ERROR_SPECIFIC - 3)
159 
160 /*!
161  * \def SEDI_PM_ERROR_CG_ABORT
162  * \brief Clock gating aborted
163  */
164 #define SEDI_PM_ERROR_CG_PG_ABORT (SEDI_DRIVER_ERROR_SPECIFIC - 4)
165 
166 /*!
167  * \def PARAM_UNUSED
168  * \brief Parameter Not Used.
169  */
170 #define PARAM_UNUSED(x) (void)(x)
171 
172 /*!
173  * \enum sedi_log_level
174  * \brief SEDI logging levels
175  * \ingroup sedi_driver_common
176  */
177 enum {
178 	SEDI_LOG_LEVEL_ERR = 1,
179 	SEDI_LOG_LEVEL_WRN = 2,
180 	SEDI_LOG_LEVEL_INF = 3,
181 	SEDI_LOG_LEVEL_DBG = 4,
182 };
183 
184 /*!
185  * \function sedi_log
186  * \brief SEDI logging function
187  * \ingroup sedi_driver_common
188  */
189 void sedi_log(int level, const char *fmt, ...);
190 
191 #define SEDI_LOG_ERR(...) sedi_log(SEDI_LOG_LEVEL_ERR, __VA_ARGS__)
192 #define SEDI_LOG_WRN(...) sedi_log(SEDI_LOG_LEVEL_WRN, __VA_ARGS__)
193 #define SEDI_LOG_INF(...) sedi_log(SEDI_LOG_LEVEL_INF, __VA_ARGS__)
194 #define SEDI_LOG_DBG(...) sedi_log(SEDI_LOG_LEVEL_DBG, __VA_ARGS__)
195 
196 /*!
197  * \def DBG_CHECK
198  * \brief Check error and return for debug mode.
199  */
200 #ifdef CONFIG_DEBUG
201 #define DBG_CHECK(condition, error)                                            \
202 	do {                                                                   \
203 		if (!(condition)) {                                            \
204 			SEDI_LOG_ERR("SEDI DBG_CHECK error %d @%s:%d:(%s)\n",  \
205 				error, __func__, __LINE__, #condition);    \
206 			return error;                                          \
207 		}                                                              \
208 	} while (0)
209 #else
210 #define DBG_CHECK(condition, error)
211 #endif
212 
213 /*!
214  * \def SEDI_ASSERT
215  * \brief Assert function for debug mode.
216  */
217 #ifdef CONFIG_DEBUG
218 void sedi_assert_halt(void);
219 #define SEDI_ASSERT(condition)                                                 \
220 	do {                                                                   \
221 		if (!(condition)) {                                            \
222 			SEDI_LOG_ERR("SEDI ASSERT @%s:%d:(%s)\n",              \
223 					__func__, __LINE__, #condition);   \
224 			sedi_assert_halt();                                    \
225 		}                                                              \
226 	} while (0)
227 #else
228 #define SEDI_ASSERT(condition)
229 #endif
230 
231 /*!
232  * \def SET_MASK
233  * \brief Mask Value for Bit Set.
234  */
235 #define SET_MASK(x) (1UL << (x))
236 
237 /*!
238  * \def SET_MASK
239  * \brief Mask Value for Bit Clear.
240  */
241 #define CLEAR_MASK(x) (~(1UL << (x)))
242 
243 /*!
244  * \def SEDI_ISR_DECLARE
245  * \brief SEDI interrupt handler prototype
246  */
247 #define SEDI_ISR_DECLARE(func) void func(void)
248 
249 /*!
250  * \def SET_BITS
251  * \brief SEDI set certain bit with certain value
252  */
253 
254 #define SET_BITS(reg_name, start, width, value)                                \
255 	do {                                                                   \
256 		uint32_t tmp = 1 << (width);                                   \
257 		reg_name &= ~((tmp - 1) << (start));                           \
258 		reg_name |= ((value) << (start));                              \
259 	} while (0)
260 
261 /*!
262  * \def GET_BITS
263  * \brief SEDI get value from certain bit
264  */
265 
266 #define GET_BITS(reg_name, start, width)                                       \
267 	((reg_name) & (((1<<(width)) - 1) << (start)))
268 
269 /*!
270  * \}
271  */
272 
273 /*!
274  * \struct sedi_power_state_t
275  * \brief General power states
276  * \ingroup sedi_driver_common
277  */
278 typedef enum {
279 	/**< Power off: no operation possible */
280 	SEDI_POWER_OFF,
281 	/**< Suspend: context should be saved and restored by driver */
282 	SEDI_POWER_SUSPEND,
283 	/**< Force suspend: complete ongoing operation before suspend */
284 	SEDI_POWER_FORCE_SUSPEND,
285 	/**< Low Power mode: retain state, detect and signal wake-up events */
286 	SEDI_POWER_LOW,
287 	/**< Power on: full operation at maximum performance */
288 	SEDI_POWER_FULL
289 } sedi_power_state_t;
290 
291 #ifndef __IO_R
292 /*!
293  * \def __IO_R
294  * \brief 'read only' permissions
295  * \ingroup sedi_driver_common
296  */
297 #define __IO_R volatile const
298 #endif
299 
300 #ifndef __IO_W
301 /*!
302  * \def __IO_W
303  * \brief 'write only' permissions
304  * \ingroup sedi_driver_common
305  */
306 #define __IO_W volatile
307 #endif
308 
309 #ifndef __IO_RW
310 /*!
311  * \def __IO_RW
312  * \brief 'read / write' permissions
313  * \ingroup sedi_driver_common
314  */
315 #define __IO_RW volatile
316 #endif
317 
318 #ifndef IN
319 /*!
320  * \def IN
321  * \brief Input parameter indicator
322  * \ingroup sedi_driver_common
323  */
324 #define IN const
325 #endif
326 
327 #ifndef OUT
328 /*!
329  * \def OUT
330  * \brief Output parameter indicator
331  * \ingroup sedi_driver_common
332  */
333 #define OUT
334 #endif
335 
336 #ifndef INOUT
337 /*!
338  * \def  INOUT
339  * \brief Input/Output parameter indicator
340  * \ingroup sedi_driver_common
341  */
342 #define INOUT
343 #endif
344 
345 /*!
346  * \function read/write address
347  * \ingroup sedi_driver_common
348  */
349 /* register read/write help function */
read8(IN uint32_t addr)350 static inline uint8_t read8(IN uint32_t addr)
351 {
352 	return *(const volatile uint8_t *)addr;
353 }
354 
read16(IN uint32_t addr)355 static inline uint16_t read16(IN uint32_t addr)
356 {
357 	return *(const volatile uint16_t *)addr;
358 }
359 
read32(IN uint32_t addr)360 static inline uint32_t read32(IN uint32_t addr)
361 {
362 	return *(const volatile uint32_t *)addr;
363 }
364 
365 /* Note - 64 bit function isn't atomic */
read64(IN uint32_t addr)366 static inline uint64_t read64(IN uint32_t addr)
367 {
368 	return *(const volatile uint64_t *)addr;
369 }
370 
write8(uint32_t addr,IN uint8_t val)371 static inline void write8(uint32_t addr, IN uint8_t val)
372 {
373 	*(volatile uint8_t *)addr = (uint8_t)val;
374 }
375 
write16(uint32_t addr,IN uint16_t val)376 static inline void write16(uint32_t addr, IN uint16_t val)
377 {
378 	*(volatile uint16_t *)addr = (uint16_t)val;
379 }
380 
write32(uint32_t addr,IN uint32_t val)381 static inline void write32(uint32_t addr, IN uint32_t val)
382 {
383 	*(volatile uint32_t *)addr = val;
384 }
385 
386 /* Note - 64 bit function isn't atomic */
write64(uint32_t addr,IN uint64_t val)387 static inline void write64(uint32_t addr, IN uint64_t val)
388 {
389 	*(volatile uint64_t *)addr = val;
390 }
391 
392 #define SET_REG_BIT(address, smask)                                           \
393 	write32(address, read32(address) | (smask))
394 
395 #define CLEAR_REG_BIT(address, cmask)                                         \
396 	write32(address, read32(address) & ~(cmask))
397 
398 #endif /* _SEDI_DRIVER_COMMON_H_*/
399