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