1 /*
2  * Copyright (c) 2022 Renesas Electronics Corporation
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <assert.h>
8 #include <soc.h>
9 #include <zephyr/sys/onoff.h>
10 #include <zephyr/drivers/clock_control.h>
11 #include <zephyr/drivers/clock_control/smartbond_clock_control.h>
12 #include <zephyr/logging/log.h>
13 #include <da1469x_clock.h>
14 
15 LOG_MODULE_REGISTER(clock_control, CONFIG_CLOCK_CONTROL_LOG_LEVEL);
16 
17 #define DT_DRV_COMPAT smartbond_clock
18 
19 struct lpc_clock_state {
20 	uint8_t rcx_started : 1;
21 	uint8_t rcx_ready : 1;
22 	uint8_t rc32k_started : 1;
23 	uint8_t rc32k_ready : 1;
24 	uint8_t xtal32k_started : 1;
25 	uint8_t xtal32k_ready : 1;
26 	uint32_t rcx_freq;
27 	uint32_t rc32k_freq;
28 } lpc_clock_state = {
29 	.rcx_freq = DT_PROP(DT_NODELABEL(rcx), clock_frequency),
30 	.rc32k_freq = DT_PROP(DT_NODELABEL(rc32k), clock_frequency),
31 };
32 
33 #define CALIBRATION_INTERVAL (DT_NODE_HAS_STATUS(DT_NODELABEL(rcx), okay) ?	\
34 			DT_PROP(DT_NODELABEL(rcx), calibration_interval) :	\
35 			DT_PROP(DT_NODELABEL(rc32k), calibration_interval))
36 
37 static void calibration_work_cb(struct k_work *work);
38 static void xtal32k_settle_work_cb(struct k_work *work);
39 
40 static K_WORK_DELAYABLE_DEFINE(calibration_work, calibration_work_cb);
41 static K_WORK_DELAYABLE_DEFINE(xtal32k_settle_work, xtal32k_settle_work_cb);
42 
calibration_work_cb(struct k_work * work)43 static void calibration_work_cb(struct k_work *work)
44 {
45 	if (lpc_clock_state.rcx_started) {
46 		da1469x_clock_lp_rcx_calibrate();
47 		lpc_clock_state.rcx_ready = true;
48 		lpc_clock_state.rcx_freq = da1469x_clock_lp_rcx_freq_get();
49 		k_work_schedule(&calibration_work,
50 				K_MSEC(1000 * CALIBRATION_INTERVAL));
51 		LOG_DBG("RCX calibration done, RCX freq: %d",
52 			(int)lpc_clock_state.rcx_freq);
53 	} else if (lpc_clock_state.rc32k_started) {
54 		da1469x_clock_lp_rc32k_calibrate();
55 		lpc_clock_state.rc32k_ready = true;
56 		lpc_clock_state.rc32k_freq = da1469x_clock_lp_rc32k_freq_get();
57 		k_work_schedule(&calibration_work,
58 				K_MSEC(1000 * CALIBRATION_INTERVAL));
59 		LOG_DBG("RC32K calibration done, RC32K freq: %d",
60 			(int)lpc_clock_state.rc32k_freq);
61 	}
62 }
63 
xtal32k_settle_work_cb(struct k_work * work)64 static void xtal32k_settle_work_cb(struct k_work *work)
65 {
66 	if (lpc_clock_state.xtal32k_started && !lpc_clock_state.xtal32k_ready) {
67 		LOG_DBG("XTAL32K settled.");
68 		lpc_clock_state.xtal32k_ready = true;
69 	}
70 }
71 
smartbond_start_rc32k(void)72 static void smartbond_start_rc32k(void)
73 {
74 	if ((CRG_TOP->CLK_RC32K_REG & CRG_TOP_CLK_RC32K_REG_RC32K_ENABLE_Msk) == 0) {
75 		CRG_TOP->CLK_RC32K_REG |= CRG_TOP_CLK_RC32K_REG_RC32K_ENABLE_Msk;
76 	}
77 	lpc_clock_state.rc32k_started = true;
78 	if (!lpc_clock_state.rc32k_ready && (CALIBRATION_INTERVAL > 0)) {
79 		if (!k_work_is_pending(&calibration_work.work)) {
80 			k_work_schedule(&calibration_work,
81 					K_MSEC(1000 * CALIBRATION_INTERVAL));
82 		}
83 	}
84 }
85 
smartbond_start_rcx(void)86 static void smartbond_start_rcx(void)
87 {
88 	if (!lpc_clock_state.rcx_started) {
89 		lpc_clock_state.rcx_ready = false;
90 		da1469x_clock_lp_rcx_enable();
91 		lpc_clock_state.rcx_started = true;
92 	}
93 	if (!lpc_clock_state.rcx_ready && (CALIBRATION_INTERVAL > 0)) {
94 		if (!k_work_is_pending(&calibration_work.work)) {
95 			k_work_schedule(&calibration_work,
96 					K_MSEC(1000 * CALIBRATION_INTERVAL));
97 		}
98 	}
99 }
100 
smartbond_start_xtal32k(void)101 static void smartbond_start_xtal32k(void)
102 {
103 	if (!lpc_clock_state.xtal32k_started) {
104 		lpc_clock_state.xtal32k_ready = false;
105 		da1469x_clock_lp_xtal32k_enable();
106 		lpc_clock_state.xtal32k_started = true;
107 		k_work_schedule(&xtal32k_settle_work,
108 				K_MSEC(DT_PROP(DT_NODELABEL(xtal32k),
109 					       settle_time)));
110 	}
111 }
112 
smartbond_clock_control_on(const struct device * dev,clock_control_subsys_t sub_system)113 static inline int smartbond_clock_control_on(const struct device *dev,
114 					     clock_control_subsys_t sub_system)
115 {
116 	enum smartbond_clock clk = (enum smartbond_clock)(sub_system);
117 
118 	ARG_UNUSED(dev);
119 
120 	switch (clk) {
121 	case SMARTBOND_CLK_RC32K:
122 		smartbond_start_rc32k();
123 		break;
124 	case SMARTBOND_CLK_RCX:
125 		smartbond_start_rcx();
126 		break;
127 	case SMARTBOND_CLK_XTAL32K:
128 		smartbond_start_xtal32k();
129 		break;
130 	case SMARTBOND_CLK_RC32M:
131 		CRG_TOP->CLK_RC32M_REG |= CRG_TOP_CLK_RC32M_REG_RC32M_ENABLE_Msk;
132 		break;
133 	case SMARTBOND_CLK_XTAL32M:
134 		da1469x_clock_sys_xtal32m_init();
135 		da1469x_clock_sys_xtal32m_enable();
136 		break;
137 	case SMARTBOND_CLK_PLL96M:
138 		if ((CRG_TOP->CLK_CTRL_REG & CRG_TOP_CLK_CTRL_REG_RUNNING_AT_PLL96M_Msk) == 0) {
139 			if ((CRG_TOP->CLK_CTRL_REG &
140 			     CRG_TOP_CLK_CTRL_REG_RUNNING_AT_XTAL32M_Msk) == 0) {
141 				da1469x_clock_sys_xtal32m_init();
142 				da1469x_clock_sys_xtal32m_enable();
143 				da1469x_clock_sys_xtal32m_wait_to_settle();
144 			}
145 			da1469x_clock_sys_pll_enable();
146 		}
147 		break;
148 	default:
149 		return -ENOTSUP;
150 	}
151 
152 	return 0;
153 }
154 
smartbond_clock_control_off(const struct device * dev,clock_control_subsys_t sub_system)155 static inline int smartbond_clock_control_off(const struct device *dev,
156 					      clock_control_subsys_t sub_system)
157 {
158 	enum smartbond_clock clk = (enum smartbond_clock)(sub_system);
159 
160 	ARG_UNUSED(dev);
161 
162 	switch (clk) {
163 	case SMARTBOND_CLK_RC32K:
164 		if (((CRG_TOP->CLK_CTRL_REG & CRG_TOP_CLK_CTRL_REG_LP_CLK_SEL_Msk) >>
165 			   CRG_TOP_CLK_CTRL_REG_LP_CLK_SEL_Pos) != 0) {
166 			CRG_TOP->CLK_RC32K_REG &= ~CRG_TOP_CLK_RC32K_REG_RC32K_ENABLE_Msk;
167 			lpc_clock_state.rc32k_ready = false;
168 			lpc_clock_state.rc32k_started = false;
169 		}
170 		break;
171 	case SMARTBOND_CLK_RCX:
172 		if (((CRG_TOP->CLK_CTRL_REG & CRG_TOP_CLK_CTRL_REG_LP_CLK_SEL_Msk) >>
173 			   CRG_TOP_CLK_CTRL_REG_LP_CLK_SEL_Pos) != 1) {
174 			CRG_TOP->CLK_RCX_REG &= ~CRG_TOP_CLK_RCX_REG_RCX_ENABLE_Msk;
175 			lpc_clock_state.rcx_ready = false;
176 			lpc_clock_state.rcx_started = false;
177 		}
178 		break;
179 	case SMARTBOND_CLK_XTAL32K:
180 		if (((CRG_TOP->CLK_CTRL_REG & CRG_TOP_CLK_CTRL_REG_LP_CLK_SEL_Msk) >>
181 			CRG_TOP_CLK_CTRL_REG_LP_CLK_SEL_Pos) > 1) {
182 			CRG_TOP->CLK_XTAL32K_REG &= ~CRG_TOP_CLK_XTAL32K_REG_XTAL32K_ENABLE_Msk;
183 			lpc_clock_state.xtal32k_ready = false;
184 			lpc_clock_state.xtal32k_started = false;
185 		}
186 		break;
187 	case SMARTBOND_CLK_RC32M:
188 		/* Disable rc32m only if not used as system clock */
189 		if ((CRG_TOP->CLK_CTRL_REG & CRG_TOP_CLK_CTRL_REG_RUNNING_AT_RC32M_Msk) == 0) {
190 			da1469x_clock_sys_rc32m_disable();
191 		}
192 		break;
193 	case SMARTBOND_CLK_XTAL32M:
194 		da1469x_clock_sys_xtal32m_init();
195 		da1469x_clock_sys_xtal32m_enable();
196 		break;
197 	case SMARTBOND_CLK_PLL96M:
198 		da1469x_clock_sys_pll_disable();
199 		break;
200 	default:
201 		return -ENOTSUP;
202 	}
203 
204 	return 0;
205 }
206 
smartbond_source_clock(enum smartbond_clock clk)207 static enum smartbond_clock smartbond_source_clock(enum smartbond_clock clk)
208 {
209 	static const enum smartbond_clock lp_clk_src[] = {
210 		SMARTBOND_CLK_RC32K,
211 		SMARTBOND_CLK_RCX,
212 		SMARTBOND_CLK_XTAL32K,
213 		SMARTBOND_CLK_XTAL32K,
214 	};
215 	static const enum smartbond_clock sys_clk_src[] = {
216 		SMARTBOND_CLK_XTAL32M,
217 		SMARTBOND_CLK_RC32M,
218 		SMARTBOND_CLK_LP_CLK,
219 		SMARTBOND_CLK_PLL96M,
220 	};
221 
222 	if (clk == SMARTBOND_CLK_SYS_CLK) {
223 		clk = sys_clk_src[CRG_TOP->CLK_CTRL_REG &
224 				  CRG_TOP_CLK_CTRL_REG_SYS_CLK_SEL_Msk];
225 	}
226 	/* System clock can be low power clock, so next check is not in else */
227 	if (clk == SMARTBOND_CLK_LP_CLK) {
228 		clk = lp_clk_src[(CRG_TOP->CLK_CTRL_REG &
229 				  CRG_TOP_CLK_CTRL_REG_LP_CLK_SEL_Msk) >>
230 				 CRG_TOP_CLK_CTRL_REG_LP_CLK_SEL_Pos];
231 	}
232 	return clk;
233 }
234 
smartbond_clock_get_rate(enum smartbond_clock clk,uint32_t * rate)235 static int smartbond_clock_get_rate(enum smartbond_clock clk, uint32_t *rate)
236 {
237 	clk = smartbond_source_clock(clk);
238 	switch (clk) {
239 	case SMARTBOND_CLK_RC32K:
240 		*rate = lpc_clock_state.rc32k_freq;
241 		break;
242 	case SMARTBOND_CLK_RCX:
243 		*rate = lpc_clock_state.rcx_freq;
244 		break;
245 	case SMARTBOND_CLK_XTAL32K:
246 		*rate = DT_PROP(DT_NODELABEL(xtal32k), clock_frequency);
247 		break;
248 	case SMARTBOND_CLK_RC32M:
249 		*rate = DT_PROP(DT_NODELABEL(rc32m), clock_frequency);
250 		break;
251 	case SMARTBOND_CLK_XTAL32M:
252 		*rate = DT_PROP(DT_NODELABEL(xtal32m), clock_frequency);
253 		break;
254 	case SMARTBOND_CLK_PLL96M:
255 		*rate = DT_PROP(DT_NODELABEL(pll), clock_frequency);
256 		break;
257 	default:
258 		return -ENOTSUP;
259 	}
260 	return 0;
261 }
262 
smartbond_clock_control_get_rate(const struct device * dev,clock_control_subsys_t sub_system,uint32_t * rate)263 static int smartbond_clock_control_get_rate(const struct device *dev,
264 					    clock_control_subsys_t sub_system,
265 					    uint32_t *rate)
266 {
267 	ARG_UNUSED(dev);
268 
269 	return smartbond_clock_get_rate((enum smartbond_clock)(sub_system), rate);
270 }
271 
smartbond_dt_ord_to_clock(uint32_t dt_ord)272 static enum smartbond_clock smartbond_dt_ord_to_clock(uint32_t dt_ord)
273 {
274 	switch (dt_ord) {
275 	case DT_DEP_ORD(DT_NODELABEL(rc32k)):
276 		return SMARTBOND_CLK_RC32K;
277 	case DT_DEP_ORD(DT_NODELABEL(rcx)):
278 		return SMARTBOND_CLK_RCX;
279 	case DT_DEP_ORD(DT_NODELABEL(xtal32k)):
280 		return SMARTBOND_CLK_XTAL32K;
281 	case DT_DEP_ORD(DT_NODELABEL(rc32m)):
282 		return SMARTBOND_CLK_RC32M;
283 	case DT_DEP_ORD(DT_NODELABEL(xtal32m)):
284 		return SMARTBOND_CLK_XTAL32M;
285 	case DT_DEP_ORD(DT_NODELABEL(pll)):
286 		return SMARTBOND_CLK_PLL96M;
287 	default:
288 		return SMARTBOND_CLK_NONE;
289 	}
290 }
291 
smartbond_clock_control_on_by_ord(const struct device * dev,uint32_t clock_id)292 static void smartbond_clock_control_on_by_ord(const struct device *dev,
293 					      uint32_t clock_id)
294 {
295 	enum smartbond_clock clk = smartbond_dt_ord_to_clock(clock_id);
296 
297 	smartbond_clock_control_on(dev, (clock_control_subsys_rate_t)clk);
298 }
299 
smartbond_clock_control_off_by_ord(const struct device * dev,uint32_t clock_id)300 static void smartbond_clock_control_off_by_ord(const struct device *dev,
301 					       uint32_t clock_id)
302 {
303 	enum smartbond_clock clk = smartbond_dt_ord_to_clock(clock_id);
304 
305 	smartbond_clock_control_off(dev, (clock_control_subsys_rate_t)clk);
306 }
307 
308 static void
qspi_set_read_pipe_delay(uint8_t delay)309 qspi_set_read_pipe_delay(uint8_t delay)
310 {
311 	QSPIC->QSPIC_CTRLMODE_REG =
312 		(QSPIC->QSPIC_CTRLMODE_REG & ~QSPIC_QSPIC_CTRLMODE_REG_QSPIC_PCLK_MD_Msk) |
313 		(delay << QSPIC_QSPIC_CTRLMODE_REG_QSPIC_PCLK_MD_Pos) |
314 		QSPIC_QSPIC_CTRLMODE_REG_QSPIC_RPIPE_EN_Msk;
315 }
316 
317 static void
qspi_set_cs_delay(uint32_t sys_clock_freq,uint32_t read_delay_ns,uint32_t erase_delay_ns)318 qspi_set_cs_delay(uint32_t sys_clock_freq, uint32_t read_delay_ns, uint32_t erase_delay_ns)
319 {
320 	sys_clock_freq /= 100000;
321 	uint32_t read_delay_cyc = ((read_delay_ns * sys_clock_freq) + 9999) / 10000;
322 	uint32_t erase_delay_cyc = ((erase_delay_ns * sys_clock_freq) + 9999) / 10000;
323 
324 	QSPIC->QSPIC_BURSTCMDB_REG =
325 		(QSPIC->QSPIC_BURSTCMDB_REG & ~QSPIC_QSPIC_BURSTCMDB_REG_QSPIC_CS_HIGH_MIN_Msk) |
326 		read_delay_cyc << QSPIC_QSPIC_BURSTCMDB_REG_QSPIC_CS_HIGH_MIN_Pos;
327 	QSPIC->QSPIC_ERASECMDB_REG =
328 		(QSPIC->QSPIC_ERASECMDB_REG & ~QSPIC_QSPIC_ERASECMDB_REG_QSPIC_ERS_CS_HI_Msk) |
329 		(erase_delay_cyc << QSPIC_QSPIC_ERASECMDB_REG_QSPIC_ERS_CS_HI_Pos);
330 }
331 
z_smartbond_select_lp_clk(enum smartbond_clock lp_clk)332 int z_smartbond_select_lp_clk(enum smartbond_clock lp_clk)
333 {
334 	int rc = 0;
335 	uint32_t clk_sel = 0;
336 	uint32_t clk_sel_msk = CRG_TOP_CLK_CTRL_REG_LP_CLK_SEL_Msk;
337 
338 	switch (lp_clk) {
339 	case SMARTBOND_CLK_RC32K:
340 		clk_sel = 0;
341 		break;
342 	case SMARTBOND_CLK_RCX:
343 		clk_sel = 1 << CRG_TOP_CLK_CTRL_REG_LP_CLK_SEL_Pos;
344 		break;
345 	case SMARTBOND_CLK_XTAL32K:
346 		clk_sel = 2 << CRG_TOP_CLK_CTRL_REG_LP_CLK_SEL_Pos;
347 		break;
348 	default:
349 		rc = -EINVAL;
350 	}
351 
352 	if (rc == 0) {
353 		CRG_TOP->CLK_CTRL_REG = (CRG_TOP->CLK_CTRL_REG & ~clk_sel_msk) | clk_sel;
354 	}
355 
356 	return rc;
357 }
358 
z_smartbond_select_sys_clk(enum smartbond_clock sys_clk)359 int z_smartbond_select_sys_clk(enum smartbond_clock sys_clk)
360 {
361 	uint32_t sys_clock_freq;
362 	uint32_t clk_sel;
363 	uint32_t clk_sel_msk = CRG_TOP_CLK_CTRL_REG_SYS_CLK_SEL_Msk;
364 	int res;
365 
366 	res = smartbond_clock_get_rate(sys_clk, &sys_clock_freq);
367 	if (res != 0) {
368 		return -EINVAL;
369 	}
370 
371 	/* When PLL is selected as system clock qspi read pipe delay must be set to 7 */
372 	if (sys_clock_freq > 32000000) {
373 		qspi_set_read_pipe_delay(7);
374 		qspi_set_cs_delay(SystemCoreClock,
375 				  DT_PROP(DT_NODELABEL(flash_controller),
376 					  read_cs_idle_delay),
377 				  DT_PROP(DT_NODELABEL(flash_controller),
378 					  erase_cs_idle_delay));
379 	}
380 
381 	if (sys_clk == SMARTBOND_CLK_RC32M) {
382 		clk_sel = 1 << CRG_TOP_CLK_CTRL_REG_SYS_CLK_SEL_Pos;
383 		CRG_TOP->CLK_CTRL_REG = (CRG_TOP->CLK_CTRL_REG & ~clk_sel_msk) | clk_sel;
384 		SystemCoreClock = sys_clock_freq;
385 	} else if (sys_clk == SMARTBOND_CLK_PLL96M) {
386 		da1469x_clock_pll_wait_to_lock();
387 		da1469x_clock_sys_pll_switch();
388 	} else if (sys_clk == SMARTBOND_CLK_XTAL32M) {
389 		da1469x_clock_sys_xtal32m_switch_safe();
390 	}
391 
392 	/* When switching back from PLL to 32MHz read pipe delay may be set to 2 */
393 	if (SystemCoreClock <= 32000000) {
394 		qspi_set_read_pipe_delay(2);
395 		qspi_set_cs_delay(SystemCoreClock,
396 				  DT_PROP(DT_NODELABEL(flash_controller),
397 					  read_cs_idle_delay),
398 				  DT_PROP(DT_NODELABEL(flash_controller),
399 					  erase_cs_idle_delay));
400 	}
401 
402 	return 0;
403 }
404 
405 /**
406  * @brief Initialize clocks for the Smartbond
407  *
408  * This routine is called to enable and configure the clocks and PLL
409  * of the soc on the board.
410  *
411  * @param dev clocks device struct
412  *
413  * @return 0
414  */
smartbond_clocks_init(const struct device * dev)415 int smartbond_clocks_init(const struct device *dev)
416 {
417 	uint32_t clk_id;
418 	enum smartbond_clock lp_clk;
419 	enum smartbond_clock sys_clk;
420 
421 	ARG_UNUSED(dev);
422 
423 #define ENABLE_OSC(clock) smartbond_clock_control_on_by_ord(dev, DT_DEP_ORD(clock))
424 #define DISABLE_OSC(clock) if (DT_NODE_HAS_STATUS(clock, disabled)) { \
425 		smartbond_clock_control_off_by_ord(dev, DT_DEP_ORD(clock)); \
426 	}
427 
428 	/* Enable all oscillators with status "okay" */
429 	DT_FOREACH_CHILD_STATUS_OKAY_SEP(DT_PATH(crg, osc), ENABLE_OSC, (;));
430 
431 	/* Make sure that selected sysclock is enabled */
432 	BUILD_ASSERT(DT_NODE_HAS_STATUS(DT_PROP(DT_NODELABEL(sys_clk), clock_src), okay),
433 		     "Clock selected as system clock no enabled in DT");
434 	BUILD_ASSERT(DT_NODE_HAS_STATUS(DT_PROP(DT_NODELABEL(lp_clk), clock_src), okay),
435 		     "Clock selected as LP clock no enabled in DT");
436 	BUILD_ASSERT(DT_NODE_HAS_STATUS(DT_NODELABEL(pll), disabled) ||
437 		     DT_NODE_HAS_STATUS(DT_NODELABEL(xtal32m), okay),
438 		     "PLL enabled in DT but XTAL32M is disabled");
439 
440 	clk_id = DT_DEP_ORD(DT_PROP(DT_NODELABEL(lp_clk), clock_src));
441 	lp_clk = smartbond_dt_ord_to_clock(clk_id);
442 	z_smartbond_select_lp_clk(lp_clk);
443 
444 	clk_id = DT_DEP_ORD(DT_PROP(DT_NODELABEL(sys_clk), clock_src));
445 	sys_clk = smartbond_dt_ord_to_clock(clk_id);
446 	smartbond_clock_control_on(dev,
447 				   (clock_control_subsys_rate_t)smartbond_source_clock(sys_clk));
448 	z_smartbond_select_sys_clk(sys_clk);
449 
450 	/* Disable unwanted oscillators */
451 	DT_FOREACH_CHILD_SEP(DT_PATH(crg, osc), DISABLE_OSC, (;));
452 
453 	return 0;
454 }
455 
456 static struct clock_control_driver_api smartbond_clock_control_api = {
457 	.on = smartbond_clock_control_on,
458 	.off = smartbond_clock_control_off,
459 	.get_rate = smartbond_clock_control_get_rate,
460 };
461 
462 DEVICE_DT_DEFINE(DT_NODELABEL(osc),
463 		 &smartbond_clocks_init,
464 		 NULL,
465 		 NULL, NULL,
466 		 PRE_KERNEL_1,
467 		 CONFIG_CLOCK_CONTROL_INIT_PRIORITY,
468 		 &smartbond_clock_control_api);
469