1 /*
2 * Copyright (c) 2024 Renesas Electronics Corporation
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/drivers/clock_control.h>
8 #include <zephyr/dt-bindings/clock/renesas_rzg_clock.h>
9 #include <zephyr/kernel.h>
10
11 #define DT_DRV_COMPAT renesas_rz_cpg
12
clock_control_renesas_rz_on(const struct device * dev,clock_control_subsys_t sys)13 static int clock_control_renesas_rz_on(const struct device *dev, clock_control_subsys_t sys)
14 {
15 if (!dev || !sys) {
16 return -EINVAL;
17 }
18
19 uint32_t *clock_id = (uint32_t *)sys;
20
21 uint32_t ip = (*clock_id & RZ_IP_MASK) >> RZ_IP_SHIFT;
22 uint32_t ch = (*clock_id & RZ_IP_CH_MASK) >> RZ_IP_CH_SHIFT;
23
24 switch (ip) {
25 case RZ_IP_GTM:
26 R_BSP_MODULE_START(FSP_IP_GTM, ch);
27 break;
28 case RZ_IP_GPT:
29 R_BSP_MODULE_START(FSP_IP_GPT, ch);
30 break;
31 case RZ_IP_SCIF:
32 R_BSP_MODULE_START(FSP_IP_SCIF, ch);
33 break;
34 case RZ_IP_RIIC:
35 R_BSP_MODULE_START(FSP_IP_RIIC, ch);
36 break;
37 case RZ_IP_RSPI:
38 R_BSP_MODULE_START(FSP_IP_RSPI, ch);
39 break;
40 case RZ_IP_MHU:
41 R_BSP_MODULE_START(FSP_IP_MHU, ch);
42 break;
43 case RZ_IP_DMAC:
44 R_BSP_MODULE_START(FSP_IP_DMAC, ch);
45 break;
46 case RZ_IP_CANFD:
47 R_BSP_MODULE_START(FSP_IP_CANFD, ch);
48 break;
49 case RZ_IP_ADC:
50 R_BSP_MODULE_START(FSP_IP_ADC, ch);
51 break;
52 default:
53 return -EINVAL; /* Invalid FSP IP Module */
54 }
55
56 return 0;
57 }
58
clock_control_renesas_rz_off(const struct device * dev,clock_control_subsys_t sys)59 static int clock_control_renesas_rz_off(const struct device *dev, clock_control_subsys_t sys)
60 {
61 if (!dev || !sys) {
62 return -EINVAL;
63 }
64
65 uint32_t *clock_id = (uint32_t *)sys;
66
67 uint32_t ip = (*clock_id & RZ_IP_MASK) >> RZ_IP_SHIFT;
68 uint32_t ch = (*clock_id & RZ_IP_CH_MASK) >> RZ_IP_CH_SHIFT;
69
70 switch (ip) {
71 case RZ_IP_GTM:
72 R_BSP_MODULE_STOP(FSP_IP_GTM, ch);
73 break;
74 case RZ_IP_GPT:
75 R_BSP_MODULE_STOP(FSP_IP_GPT, ch);
76 break;
77 case RZ_IP_SCIF:
78 R_BSP_MODULE_STOP(FSP_IP_SCIF, ch);
79 break;
80 case RZ_IP_RIIC:
81 R_BSP_MODULE_STOP(FSP_IP_RIIC, ch);
82 break;
83 case RZ_IP_RSPI:
84 R_BSP_MODULE_STOP(FSP_IP_RSPI, ch);
85 break;
86 case RZ_IP_MHU:
87 R_BSP_MODULE_STOP(FSP_IP_MHU, ch);
88 break;
89 case RZ_IP_DMAC:
90 R_BSP_MODULE_STOP(FSP_IP_DMAC, ch);
91 break;
92 case RZ_IP_CANFD:
93 R_BSP_MODULE_STOP(FSP_IP_CANFD, ch);
94 break;
95 case RZ_IP_ADC:
96 R_BSP_MODULE_STOP(FSP_IP_ADC, ch);
97 break;
98 default:
99 return -EINVAL; /* Invalid */
100 }
101 return 0;
102 }
103
clock_control_renesas_rz_get_rate(const struct device * dev,clock_control_subsys_t sys,uint32_t * rate)104 static int clock_control_renesas_rz_get_rate(const struct device *dev, clock_control_subsys_t sys,
105 uint32_t *rate)
106 {
107 if (!dev || !sys || !rate) {
108 return -EINVAL;
109 }
110
111 uint32_t *clock_id = (uint32_t *)sys;
112
113 fsp_priv_clock_t clk_src = (*clock_id & RZ_CLOCK_MASK) >> RZ_CLOCK_SHIFT;
114 uint32_t clk_div = (*clock_id & RZ_CLOCK_DIV_MASK) >> RZ_CLOCK_DIV_SHIFT;
115
116 uint32_t clk_hz = R_FSP_SystemClockHzGet(clk_src);
117 *rate = clk_hz / clk_div;
118 return 0;
119 }
120
121 static DEVICE_API(clock_control, rz_clock_control_driver_api) = {
122 .on = clock_control_renesas_rz_on,
123 .off = clock_control_renesas_rz_off,
124 .get_rate = clock_control_renesas_rz_get_rate,
125 };
126
clock_control_rz_init(const struct device * dev)127 static int clock_control_rz_init(const struct device *dev)
128 {
129 ARG_UNUSED(dev);
130 return 0;
131 }
132
133 DEVICE_DT_INST_DEFINE(0, clock_control_rz_init, NULL, NULL, NULL, PRE_KERNEL_1,
134 CONFIG_CLOCK_CONTROL_INIT_PRIORITY, &rz_clock_control_driver_api);
135