1 /*
2  * Copyright (c) 2023-2024 Analog Devices, Inc.
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #ifndef ZEPHYR_INCLUDE_DRIVERS_CLOCK_CONTROL_ADI_MAX32_CLOCK_CONTROL_H_
8 #define ZEPHYR_INCLUDE_DRIVERS_CLOCK_CONTROL_ADI_MAX32_CLOCK_CONTROL_H_
9 
10 #include <zephyr/drivers/clock_control.h>
11 
12 #include <zephyr/dt-bindings/clock/adi_max32_clock.h>
13 
14 #include <wrap_max32_sys.h>
15 
16 /** Driver structure definition */
17 
18 struct max32_perclk {
19 	uint32_t bus;
20 	uint32_t bit;
21 
22 	/* Peripheral clock source:
23 	 * Can be (see: adi_max32_clock.h file):
24 	 *
25 	 *   ADI_MAX32_PRPH_CLK_SRC_PCLK
26 	 *   ADI_MAX32_PRPH_CLK_SRC_EXTCLK
27 	 *   ADI_MAX32_PRPH_CLK_SRC_IBRO
28 	 *   ADI_MAX32_PRPH_CLK_SRC_ERFO
29 	 *   ADI_MAX32_PRPH_CLK_SRC_ERTCO
30 	 *   ADI_MAX32_PRPH_CLK_SRC_INRO
31 	 *   ADI_MAX32_PRPH_CLK_SRC_ISO
32 	 *   ADI_MAX32_PRPH_CLK_SRC_IBRO_DIV8
33 	 *   ADI_MAX32_PRPH_CLK_SRC_IPLL
34 	 *   ADI_MAX32_PRPH_CLK_SRC_EBO
35 	 */
36 	uint32_t clk_src;
37 };
38 
39 /** Get prescaler value if it defined  */
40 #define ADI_MAX32_SYSCLK_PRESCALER DT_PROP_OR(DT_NODELABEL(gcr), sysclk_prescaler, 1)
41 
42 #define ADI_MAX32_CLK_IPO_FREQ    DT_PROP(DT_NODELABEL(clk_ipo), clock_frequency)
43 #define ADI_MAX32_CLK_ERFO_FREQ   DT_PROP_OR(DT_NODELABEL(clk_erfo), clock_frequency, 0)
44 #define ADI_MAX32_CLK_IBRO_FREQ   DT_PROP(DT_NODELABEL(clk_ibro), clock_frequency)
45 #define ADI_MAX32_CLK_ISO_FREQ    DT_PROP_OR(DT_NODELABEL(clk_iso), clock_frequency, 0)
46 #define ADI_MAX32_CLK_INRO_FREQ   DT_PROP(DT_NODELABEL(clk_inro), clock_frequency)
47 #define ADI_MAX32_CLK_ERTCO_FREQ  DT_PROP(DT_NODELABEL(clk_ertco), clock_frequency)
48 #define ADI_MAX32_CLK_IPLL_FREQ   DT_PROP_OR(DT_NODELABEL(clk_ipll), clock_frequency, 0)
49 #define ADI_MAX32_CLK_EBO_FREQ    DT_PROP_OR(DT_NODELABEL(clk_ebo), clock_frequency, 0)
50 /* External clock may not be defined so _OR is used */
51 #define ADI_MAX32_CLK_EXTCLK_FREQ DT_PROP_OR(DT_NODELABEL(clk_extclk), clock_frequency, 0)
52 
53 #define DT_GCR_CLOCKS_CTRL DT_CLOCKS_CTLR(DT_NODELABEL(gcr))
54 
55 #if DT_SAME_NODE(DT_GCR_CLOCKS_CTRL, DT_NODELABEL(clk_ipo))
56 #define ADI_MAX32_SYSCLK_SRC  ADI_MAX32_CLK_IPO
57 #define ADI_MAX32_SYSCLK_FREQ (ADI_MAX32_CLK_IPO_FREQ / ADI_MAX32_SYSCLK_PRESCALER)
58 #endif
59 #if DT_SAME_NODE(DT_GCR_CLOCKS_CTRL, DT_NODELABEL(clk_erfo))
60 #define ADI_MAX32_SYSCLK_SRC  ADI_MAX32_CLK_ERFO
61 #define ADI_MAX32_SYSCLK_FREQ (ADI_MAX32_CLK_ERFO_FREQ / ADI_MAX32_SYSCLK_PRESCALER)
62 #endif
63 #if DT_SAME_NODE(DT_GCR_CLOCKS_CTRL, DT_NODELABEL(clk_ibro))
64 #define ADI_MAX32_SYSCLK_SRC  ADI_MAX32_CLK_IBRO
65 #define ADI_MAX32_SYSCLK_FREQ (ADI_MAX32_CLK_IBRO_FREQ / ADI_MAX32_SYSCLK_PRESCALER)
66 #endif
67 #if DT_SAME_NODE(DT_GCR_CLOCKS_CTRL, DT_NODELABEL(clk_iso))
68 #define ADI_MAX32_SYSCLK_SRC  ADI_MAX32_CLK_ISO
69 #define ADI_MAX32_SYSCLK_FREQ (ADI_MAX32_CLK_ISO_FREQ / ADI_MAX32_SYSCLK_PRESCALER)
70 #endif
71 #if DT_SAME_NODE(DT_GCR_CLOCKS_CTRL, DT_NODELABEL(clk_inro))
72 #define ADI_MAX32_SYSCLK_SRC  ADI_MAX32_CLK_INRO
73 #define ADI_MAX32_SYSCLK_FREQ (ADI_MAX32_CLK_INRO_FREQ / ADI_MAX32_SYSCLK_PRESCALER)
74 #endif
75 #if DT_SAME_NODE(DT_GCR_CLOCKS_CTRL, DT_NODELABEL(clk_ertco))
76 #define ADI_MAX32_SYSCLK_SRC  ADI_MAX32_CLK_ERTCO
77 #define ADI_MAX32_SYSCLK_FREQ (ADI_MAX32_CLK_ERTCO_FREQ / ADI_MAX32_SYSCLK_PRESCALER)
78 #endif
79 #if DT_SAME_NODE(DT_GCR_CLOCKS_CTRL, DT_NODELABEL(clk_extclk))
80 #define ADI_MAX32_SYSCLK_SRC  ADI_MAX32_CLK_EXTCLK
81 #define ADI_MAX32_SYSCLK_FREQ (ADI_MAX32_CLK_EXTCLK_FREQ / ADI_MAX32_SYSCLK_PRESCALER)
82 #endif
83 #if DT_SAME_NODE(DT_GCR_CLOCKS_CTRL, DT_NODELABEL(clk_ipll))
84 #define ADI_MAX32_SYSCLK_SRC  ADI_MAX32_CLK_IPLL
85 #define ADI_MAX32_SYSCLK_FREQ (ADI_MAX32_CLK_IPLL_FREQ / ADI_MAX32_SYSCLK_PRESCALER)
86 #endif
87 #if DT_SAME_NODE(DT_GCR_CLOCKS_CTRL, DT_NODELABEL(clk_ebo))
88 #define ADI_MAX32_SYSCLK_SRC  ADI_MAX32_CLK_EBO
89 #define ADI_MAX32_SYSCLK_FREQ (ADI_MAX32_CLK_EBO_FREQ / ADI_MAX32_SYSCLK_PRESCALER)
90 #endif
91 
92 #ifndef ADI_MAX32_SYSCLK_SRC
93 #define ADI_MAX32_SYSCLK_SRC  ADI_MAX32_CLK_IPO
94 #define ADI_MAX32_SYSCLK_FREQ (ADI_MAX32_CLK_IPO_FREQ / ADI_MAX32_SYSCLK_PRESCALER)
95 #endif
96 
97 #define ADI_MAX32_PCLK_FREQ (ADI_MAX32_SYSCLK_FREQ / 2)
98 
99 #define ADI_MAX32_GET_PRPH_CLK_FREQ(clk_src)                                                       \
100 	((clk_src) == ADI_MAX32_PRPH_CLK_SRC_PCLK        ? ADI_MAX32_PCLK_FREQ                     \
101 	 : (clk_src) == ADI_MAX32_PRPH_CLK_SRC_IBRO      ? ADI_MAX32_CLK_IBRO_FREQ                 \
102 	 : (clk_src) == ADI_MAX32_PRPH_CLK_SRC_ERFO      ? ADI_MAX32_CLK_ERFO_FREQ                 \
103 	 : (clk_src) == ADI_MAX32_PRPH_CLK_SRC_ERTCO     ? ADI_MAX32_CLK_ERTCO_FREQ                \
104 	 : (clk_src) == ADI_MAX32_PRPH_CLK_SRC_INRO      ? ADI_MAX32_CLK_INRO_FREQ                 \
105 	 : (clk_src) == ADI_MAX32_PRPH_CLK_SRC_ISO       ? ADI_MAX32_CLK_ISO_FREQ                  \
106 	 : (clk_src) == ADI_MAX32_PRPH_CLK_SRC_IBRO_DIV8 ? (ADI_MAX32_CLK_IBRO_FREQ / 8)           \
107 	 : (clk_src) == ADI_MAX32_PRPH_CLK_SRC_EXTCLK    ? ADI_MAX32_CLK_EXTCLK_FREQ               \
108 	 : (clk_src) == ADI_MAX32_PRPH_CLK_SRC_IPLL      ? ADI_MAX32_CLK_IPLL_FREQ                 \
109 	 : (clk_src) == ADI_MAX32_PRPH_CLK_SRC_EBO       ? ADI_MAX32_CLK_EBO_FREQ                  \
110 							 : 0)
111 
112 #endif /* ZEPHYR_INCLUDE_DRIVERS_CLOCK_CONTROL_ADI_MAX32_CLOCK_CONTROL_H_ */
113