1 /*
2 * Copyright (c) 2023 - 2024 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 uint64_t sedi_rtc_get_us(void);
399
400 #define __SEDI_POLL_WAIT(_cond, _ms, _mute) \
401 ({ \
402 int ret = SEDI_DRIVER_OK; \
403 uint64_t us_start; \
404 us_start = sedi_rtc_get_us(); \
405 while (_cond) { \
406 uint64_t us_cur; \
407 us_cur = sedi_rtc_get_us(); \
408 if (((int64_t)(us_cur - us_start) > ((_ms) * 1000)) && (_cond)) { \
409 if (!(_mute)) { \
410 SEDI_LOG_ERR("SEDI poll %d ms timeout at %s : %d\n", (_ms),\
411 __func__, __LINE__); \
412 } \
413 ret = SEDI_DRIVER_ERROR_TIMEOUT; \
414 break; \
415 } \
416 } \
417 ret; \
418 })
419
420 /*!
421 * \function SEDI_POLL_WAIT
422 * \brief SEDI helper function to poll wait ((_cond) == true) at most (_ms) milliseconds.
423 * \return SEDI_DRIVER_OK or SEDI_DRIVER_ERROR_TIMEOUT
424 * \ingroup sedi_driver_common
425 */
426 #define SEDI_POLL_WAIT(_cond, _ms) __SEDI_POLL_WAIT(_cond, _ms, false)
427
428 /*!
429 * \function SEDI_POLL_WAIT_MUTE
430 * \brief SEDI helper function to poll wait ((_cond) == true) at most (_ms) milliseconds, and don't
431 * print error log when timeout happens to avoid potential recursive logging.
432 * \return SEDI_DRIVER_OK or SEDI_DRIVER_ERROR_TIMEOUT
433 * \ingroup sedi_driver_common
434 */
435 #define SEDI_POLL_WAIT_MUTE(_cond, _ms) __SEDI_POLL_WAIT(_cond, _ms, true)
436 #endif /* _SEDI_DRIVER_COMMON_H_*/
437