1 /*
2  * Copyright (c) 2021 Microchip Technology Inc.
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #define DT_DRV_COMPAT microchip_xec_pcr
8 
9 #include <soc.h>
10 #include <zephyr/arch/cpu.h>
11 #include <cmsis_core.h>
12 #include <zephyr/drivers/clock_control.h>
13 #include <zephyr/drivers/clock_control/mchp_xec_clock_control.h>
14 #include <zephyr/drivers/pinctrl.h>
15 #include <zephyr/dt-bindings/clock/mchp_xec_pcr.h>
16 #include <zephyr/irq.h>
17 #include <zephyr/logging/log.h>
18 #include <zephyr/sys/barrier.h>
19 LOG_MODULE_REGISTER(clock_control_xec, LOG_LEVEL_ERR);
20 
21 #define CLK32K_SIL_OSC_DELAY		256
22 #define CLK32K_PLL_LOCK_WAIT		(16 * 1024)
23 #define CLK32K_PIN_WAIT			4096
24 #define CLK32K_XTAL_WAIT		(16 * 1024)
25 #define CLK32K_XTAL_MON_WAIT		(64 * 1024)
26 #define XEC_CC_DFLT_PLL_LOCK_WAIT_MS	30
27 
28 /*
29  * Counter checks:
30  * 32KHz period counter minimum for pass/fail: 16-bit
31  * 32KHz period counter maximum for pass/fail: 16-bit
32  * 32KHz duty cycle variation max for pass/fail: 16-bit
33  * 32KHz valid count minimum: 8-bit
34  *
35  * 32768 Hz period is 30.518 us
36  * HW count resolution is 48 MHz.
37  * One 32KHz clock pulse = 1464.84 48 MHz counts.
38  */
39 #define CNT32K_TMIN			1435
40 #define CNT32K_TMAX			1495
41 #define CNT32K_DUTY_MAX			132
42 #define CNT32K_VAL_MIN			4
43 
44 #define DEST_PLL			0
45 #define DEST_PERIPH			1
46 
47 #define CLK32K_FLAG_CRYSTAL_SE		BIT(0)
48 #define CLK32K_FLAG_PIN_FB_CRYSTAL	BIT(1)
49 
50 #define PCR_PERIPH_RESET_SPIN		8u
51 
52 #define XEC_CC_XTAL_EN_DELAY_MS_DFLT	300u
53 #define HIBTIMER_MS_TO_CNT(x)		((uint32_t)(x) * 33U)
54 
55 #define HIBTIMER_10_MS			328u
56 #define HIBTIMER_300_MS			9830u
57 
58 enum pll_clk32k_src {
59 	PLL_CLK32K_SRC_SO = MCHP_XEC_PLL_CLK32K_SRC_SIL_OSC,
60 	PLL_CLK32K_SRC_XTAL = MCHP_XEC_PLL_CLK32K_SRC_XTAL,
61 	PLL_CLK32K_SRC_PIN = MCHP_XEC_PLL_CLK32K_SRC_PIN,
62 	PLL_CLK32K_SRC_MAX,
63 };
64 
65 enum periph_clk32k_src {
66 	PERIPH_CLK32K_SRC_SO_SO = MCHP_XEC_PERIPH_CLK32K_SRC_SO_SO,
67 	PERIPH_CLK32K_SRC_XTAL_XTAL = MCHP_XEC_PERIPH_CLK32K_SRC_XTAL_XTAL,
68 	PERIPH_CLK32K_SRC_PIN_SO = MCHP_XEC_PERIPH_CLK32K_SRC_PIN_SO,
69 	PERIPH_CLK32K_SRC_PIN_XTAL = MCHP_XEC_PERIPH_CLK32K_SRC_PIN_XTAL,
70 	PERIPH_CLK32K_SRC_MAX
71 };
72 
73 enum clk32k_dest { CLK32K_DEST_PLL = 0, CLK32K_DEST_PERIPH, CLK32K_DEST_MAX };
74 
75 /* PCR hardware registers for MEC15xx and MEC172x */
76 #define XEC_CC_PCR_MAX_SCR 5
77 
78 struct pcr_hw_regs {
79 	volatile uint32_t SYS_SLP_CTRL;
80 	volatile uint32_t PROC_CLK_CTRL;
81 	volatile uint32_t SLOW_CLK_CTRL;
82 	volatile uint32_t OSC_ID;
83 	volatile uint32_t PWR_RST_STS;
84 	volatile uint32_t PWR_RST_CTRL;
85 	volatile uint32_t SYS_RST;
86 	volatile uint32_t TURBO_CLK; /* MEC172x only */
87 	volatile uint32_t TEST20;
88 	uint32_t RSVD1[3];
89 	volatile uint32_t SLP_EN[XEC_CC_PCR_MAX_SCR];
90 	uint32_t RSVD2[3];
91 	volatile uint32_t CLK_REQ[XEC_CC_PCR_MAX_SCR];
92 	uint32_t RSVD3[3];
93 	volatile uint32_t RST_EN[5];
94 	volatile uint32_t RST_EN_LOCK;
95 	/* all registers below are MEC172x only */
96 	volatile uint32_t VBAT_SRST;
97 	volatile uint32_t CLK32K_SRC_VTR;
98 	volatile uint32_t TEST90;
99 	uint32_t RSVD4[(0x00c0 - 0x0094) / 4];
100 	volatile uint32_t CNT32K_PER;
101 	volatile uint32_t CNT32K_PULSE_HI;
102 	volatile uint32_t CNT32K_PER_MIN;
103 	volatile uint32_t CNT32K_PER_MAX;
104 	volatile uint32_t CNT32K_DV;
105 	volatile uint32_t CNT32K_DV_MAX;
106 	volatile uint32_t CNT32K_VALID;
107 	volatile uint32_t CNT32K_VALID_MIN;
108 	volatile uint32_t CNT32K_CTRL;
109 	volatile uint32_t CLK32K_MON_ISTS;
110 	volatile uint32_t CLK32K_MON_IEN;
111 };
112 
113 #define XEC_CC_PCR_RST_EN_UNLOCK	0xa6382d4cu
114 #define XEC_CC_PCR_RST_EN_LOCK		0xa6382d4du
115 
116 #define XEC_CC_PCR_OSC_ID_PLL_LOCK	BIT(8)
117 #define XEC_CC_PCR_TURBO_CLK_96M	BIT(2)
118 
119 #define XEC_CC_PCR_CLK32K_SRC_MSK	0x3u
120 #define XEC_CC_PCR_CLK32K_SRC_SIL	0u
121 #define XEC_CC_PCR_CLK32K_SRC_XTAL	1
122 #define XEC_CC_PCR_CLK32K_SRC_PIN	2
123 #define XEC_CC_PCR_CLK32K_SRC_OFF	3
124 
125 #ifdef CONFIG_SOC_SERIES_MEC1501X
126 #define XEC_CC_PCR3_CRYPTO_MASK		(BIT(26) | BIT(27) | BIT(28))
127 #else
128 #define XEC_CC_PCR3_CRYPTO_MASK		BIT(26)
129 #endif
130 
131 /* VBAT powered hardware registers related to clock configuration */
132 struct vbatr_hw_regs {
133 	volatile uint32_t PFRS;
134 	uint32_t RSVD1[1];
135 	volatile uint32_t CLK32_SRC;
136 	uint32_t RSVD2[2];
137 	volatile uint32_t CLK32_TRIM;
138 	uint32_t RSVD3[1];
139 	volatile uint32_t CLK32_TRIM_CTRL;
140 };
141 
142 /* MEC152x VBAT CLK32_SRC register defines */
143 #define XEC_CC15_VBATR_USE_SIL_OSC		0u
144 #define XEC_CC15_VBATR_USE_32KIN_PIN		BIT(1)
145 #define XEC_CC15_VBATR_USE_PAR_CRYSTAL		BIT(2)
146 #define XEC_CC15_VBATR_USE_SE_CRYSTAL		(BIT(2) | BIT(3))
147 
148 /* MEC150x special requirements */
149 #define XEC_CC15_GCFG_DID_DEV_ID_MEC150x	0x0020U
150 #define XEC_CC15_TRIM_ENABLE_INT_OSCILLATOR	0x06U
151 
152 
153 /* MEC172x VBAT CLK32_SRC register defines */
154 #define XEC_CC_VBATR_CS_SO_EN			BIT(0) /* enable and start silicon OSC */
155 #define XEC_CC_VBATR_CS_XTAL_EN			BIT(8) /* enable & start external crystal */
156 #define XEC_CC_VBATR_CS_XTAL_SE			BIT(9) /* crystal XTAL2 used as 32KHz input */
157 #define XEC_CC_VBATR_CS_XTAL_DHC		BIT(10) /* disable high XTAL startup current */
158 #define XEC_CC_VBATR_CS_XTAL_CNTR_MSK		0x1800u /* XTAL amplifier gain control */
159 #define XEC_CC_VBATR_CS_XTAL_CNTR_DG		0x0800u
160 #define XEC_CC_VBATR_CS_XTAL_CNTR_RG		0x1000u
161 #define XEC_CC_VBATR_CS_XTAL_CNTR_MG		0x1800u
162 /* MEC172x Select source of peripheral 32KHz clock */
163 #define XEC_CC_VBATR_CS_PCS_POS			16
164 #define XEC_CC_VBATR_CS_PCS_MSK0		0x3u
165 #define XEC_CC_VBATR_CS_PCS_MSK			0x30000u
166 #define XEC_CC_VBATR_CS_PCS_VTR_VBAT_SO		0u /* VTR & VBAT use silicon OSC */
167 #define XEC_CC_VBATR_CS_PCS_VTR_VBAT_XTAL	0x10000u /* VTR & VBAT use crystal */
168 #define XEC_CC_VBATR_CS_PCS_VTR_PIN_SO		0x20000u /* VTR 32KHZ_IN, VBAT silicon OSC */
169 #define XEC_CC_VBATR_CS_PCS_VTR_PIN_XTAL	0x30000u /* VTR 32KHZ_IN, VBAT XTAL */
170 #define XEC_CC_VBATR_CS_DI32_VTR_OFF		BIT(18) /* disable silicon OSC when VTR off */
171 
172 enum vbr_clk32k_src {
173 	VBR_CLK32K_SRC_SO_SO = 0,
174 	VBR_CLK32K_SRC_XTAL_XTAL,
175 	VBR_CLK32K_SRC_PIN_SO,
176 	VBR_CLK32K_SRC_PIN_XTAL,
177 	VBR_CLK32K_SRC_MAX,
178 };
179 
180 /* GIRQ23 hardware registers */
181 #define XEC_CC_HTMR_0_GIRQ23_POS		16
182 
183 /* Driver config */
184 struct xec_pcr_config {
185 	uintptr_t pcr_base;
186 	uintptr_t vbr_base;
187 	const struct pinctrl_dev_config *pcfg;
188 	uint16_t xtal_enable_delay_ms;
189 	uint16_t pll_lock_timeout_ms;
190 	uint16_t period_min; /* mix and max 32KHz period range */
191 	uint16_t period_max; /* monitor values in units of 48MHz (20.8 ns) */
192 	uint8_t core_clk_div; /* Cortex-M4 clock divider (CPU and NVIC) */
193 	uint8_t xtal_se; /* External 32KHz square wave on XTAL2 pin */
194 	uint8_t max_dc_va; /* 32KHz monitor maximum duty cycle variation */
195 	uint8_t min_valid; /* minimum number of valid consecutive 32KHz pulses */
196 	enum pll_clk32k_src pll_src;
197 	enum periph_clk32k_src periph_src;
198 	uint8_t clkmon_bypass;
199 	uint8_t dis_internal_osc;
200 };
201 
202 /*
203  * Make sure PCR sleep enables are clear except for crypto
204  * which do not have internal clock gating.
205  */
pcr_slp_init(struct pcr_hw_regs * pcr)206 static void pcr_slp_init(struct pcr_hw_regs *pcr)
207 {
208 	pcr->SYS_SLP_CTRL = 0U;
209 	SCB->SCR &= ~BIT(2);
210 
211 	for (int i = 0; i < XEC_CC_PCR_MAX_SCR; i++) {
212 		pcr->SLP_EN[i] = 0U;
213 	}
214 
215 	pcr->SLP_EN[3] = XEC_CC_PCR3_CRYPTO_MASK;
216 }
217 
218 /* MEC172x:
219  * Check if PLL is locked with timeout provided by a peripheral clock domain
220  * timer. We assume peripheral domain is still using internal silicon OSC as
221  * its reference clock. Available peripheral timers using 32KHz are:
222  * RTOS timer, hibernation timers, RTC, and week timer. We will use hibernation
223  * timer 0 in 30.5 us tick mode. Maximum internal is 2 seconds.
224  * A timer count value of 0 is interpreted as no timeout.
225  * We use the hibernation timer GIRQ interrupt status bit instead of reading
226  * the timer's count register due to race condition of HW taking at least
227  * one 32KHz cycle to move pre-load into count register.
228  * MEC15xx:
229  * Hibernation timer is using the chosen 32KHz source. If the external 32KHz source
230  * has a ramp up time, we make not get an accurate delay. This may only occur for
231  * the parallel crystal.
232  */
pll_wait_lock_periph(struct pcr_hw_regs * const pcr,uint16_t ms)233 static int pll_wait_lock_periph(struct pcr_hw_regs *const pcr, uint16_t ms)
234 {
235 	struct htmr_regs *htmr0 = (struct htmr_regs *)DT_REG_ADDR(DT_NODELABEL(hibtimer0));
236 	struct girq_regs *girq23 = (struct girq_regs *)DT_REG_ADDR(DT_NODELABEL(girq23));
237 	uint32_t hcount = HIBTIMER_MS_TO_CNT(ms);
238 	int rc = 0;
239 
240 	htmr0->PRLD = 0; /* disable */
241 	htmr0->CTRL = 0; /* 30.5 us units */
242 	girq23->SRC = BIT(XEC_CC_HTMR_0_GIRQ23_POS);
243 	htmr0->PRLD = hcount;
244 	while (!(pcr->OSC_ID & MCHP_PCR_OSC_ID_PLL_LOCK)) {
245 		if (hcount) {
246 			if (girq23->SRC & BIT(XEC_CC_HTMR_0_GIRQ23_POS)) {
247 				rc = -ETIMEDOUT;
248 			}
249 		}
250 	}
251 
252 	return rc;
253 }
254 
periph_clk_src_using_pin(enum periph_clk32k_src src)255 static int periph_clk_src_using_pin(enum periph_clk32k_src src)
256 {
257 	switch (src) {
258 	case PERIPH_CLK32K_SRC_PIN_SO:
259 	case PERIPH_CLK32K_SRC_PIN_XTAL:
260 		return 1;
261 	default:
262 		return 0;
263 	}
264 }
265 
266 #ifdef CONFIG_SOC_SERIES_MEC1501X
267 /* MEC15xx uses the same 32KHz source for both PLL and Peripheral 32K clock domains.
268  * We ignore the peripheral clock source.
269  * If XTAL is selected (parallel) or single-ended the external 32KHz MUST stay on
270  * even when when VTR goes off.
271  * If PIN(32KHZ_IN pin) as the external source, hardware can auto-switch to internal
272  * silicon OSC if the signal on the 32KHZ_PIN goes away.
273  * We ignore th
274  */
soc_clk32_init(const struct device * dev,enum pll_clk32k_src pll_clk_src,enum periph_clk32k_src periph_clk_src,uint32_t flags)275 static int soc_clk32_init(const struct device *dev,
276 			  enum pll_clk32k_src pll_clk_src,
277 			  enum periph_clk32k_src periph_clk_src,
278 			  uint32_t flags)
279 {
280 	const struct xec_pcr_config * const devcfg = dev->config;
281 	struct pcr_hw_regs *const pcr = (struct pcr_hw_regs *)devcfg->pcr_base;
282 	struct vbatr_hw_regs *const vbr = (struct vbatr_hw_regs *)devcfg->vbr_base;
283 	uint32_t cken = 0U;
284 	int rc = 0;
285 
286 	if (MCHP_DEVICE_ID() == XEC_CC15_GCFG_DID_DEV_ID_MEC150x) {
287 		if (MCHP_REVISION_ID() == MCHP_GCFG_REV_B0) {
288 			vbr->CLK32_TRIM_CTRL = XEC_CC15_TRIM_ENABLE_INT_OSCILLATOR;
289 		}
290 	}
291 
292 	switch (pll_clk_src) {
293 	case PLL_CLK32K_SRC_SO:
294 		cken = XEC_CC15_VBATR_USE_SIL_OSC;
295 		break;
296 	case PLL_CLK32K_SRC_XTAL:
297 		if (flags & CLK32K_FLAG_CRYSTAL_SE) {
298 			cken = XEC_CC15_VBATR_USE_SE_CRYSTAL;
299 		} else {
300 			cken = XEC_CC15_VBATR_USE_PAR_CRYSTAL;
301 		}
302 		break;
303 	case PLL_CLK32K_SRC_PIN: /* 32KHZ_IN pin falls back to Silicon OSC */
304 		cken = XEC_CC15_VBATR_USE_32KIN_PIN;
305 		break;
306 	default: /* do not touch HW */
307 		return -EINVAL;
308 	}
309 
310 	if ((vbr->CLK32_SRC & 0xffU) != cken) {
311 		vbr->CLK32_SRC = cken;
312 	}
313 
314 	rc = pll_wait_lock_periph(pcr, devcfg->xtal_enable_delay_ms);
315 
316 	return rc;
317 }
318 #else
319 
periph_clk_src_using_si(enum periph_clk32k_src src)320 static int periph_clk_src_using_si(enum periph_clk32k_src src)
321 {
322 	switch (src) {
323 	case PERIPH_CLK32K_SRC_SO_SO:
324 	case PERIPH_CLK32K_SRC_PIN_SO:
325 		return 1;
326 	default:
327 		return 0;
328 	}
329 }
330 
periph_clk_src_using_xtal(enum periph_clk32k_src src)331 static int periph_clk_src_using_xtal(enum periph_clk32k_src src)
332 {
333 	switch (src) {
334 	case PERIPH_CLK32K_SRC_XTAL_XTAL:
335 	case PERIPH_CLK32K_SRC_PIN_XTAL:
336 		return 1;
337 	default:
338 		return 0;
339 	}
340 }
341 
is_sil_osc_enabled(struct vbatr_hw_regs * vbr)342 static bool is_sil_osc_enabled(struct vbatr_hw_regs *vbr)
343 {
344 	if (vbr->CLK32_SRC & XEC_CC_VBATR_CS_SO_EN) {
345 		return true;
346 	}
347 
348 	return false;
349 }
350 
enable_sil_osc(struct vbatr_hw_regs * vbr)351 static void enable_sil_osc(struct vbatr_hw_regs *vbr)
352 {
353 	vbr->CLK32_SRC |= XEC_CC_VBATR_CS_SO_EN;
354 }
355 
356 /* In early Zephyr initialization we don't have timer services. Also, the SoC
357  * may be running on its ring oscillator (+/- 50% accuracy). Configuring the
358  * SoC's clock subsystem requires wait/delays. We implement a simple delay
359  * by writing to a read-only hardware register in the PCR block.
360  */
spin_delay(struct pcr_hw_regs * pcr,uint32_t cnt)361 static uint32_t spin_delay(struct pcr_hw_regs *pcr, uint32_t cnt)
362 {
363 	uint32_t n;
364 
365 	for (n = 0U; n < cnt; n++) {
366 		pcr->OSC_ID = n;
367 	}
368 
369 	return n;
370 }
371 
372 /*
373  * This routine checks if the PLL is locked to its input source. Minimum lock
374  * time is 3.3 ms. Lock time can be larger when the source is an external
375  * crystal. Crystal cold start times may vary greatly based on many factors.
376  * Crystals do not like being power cycled.
377  */
pll_wait_lock(struct pcr_hw_regs * const pcr,uint32_t wait_cnt)378 static int pll_wait_lock(struct pcr_hw_regs *const pcr, uint32_t wait_cnt)
379 {
380 	while (!(pcr->OSC_ID & MCHP_PCR_OSC_ID_PLL_LOCK)) {
381 		if (wait_cnt == 0) {
382 			return -ETIMEDOUT;
383 		}
384 		--wait_cnt;
385 	}
386 
387 	return 0;
388 }
389 
390 /* caller has enabled internal silicon 32 KHz oscillator */
hib_timer_delay(uint32_t hib_timer_count)391 static void hib_timer_delay(uint32_t hib_timer_count)
392 {
393 	struct htmr_regs *htmr0 = (struct htmr_regs *)DT_REG_ADDR(DT_NODELABEL(hibtimer0));
394 	struct girq_regs *girq23 = (struct girq_regs *)DT_REG_ADDR(DT_NODELABEL(girq23));
395 	uint32_t hcnt;
396 
397 	while (hib_timer_count) {
398 
399 		hcnt = hib_timer_count;
400 		if (hcnt > UINT16_MAX) {
401 			hcnt -= UINT16_MAX;
402 		}
403 
404 		htmr0->PRLD = 0; /* disable */
405 		while (htmr0->PRLD != 0) {
406 			;
407 		}
408 		htmr0->CTRL = 0; /* 32k time base */
409 		/* clear hibernation timer 0 status */
410 		girq23->SRC = BIT(XEC_CC_HTMR_0_GIRQ23_POS);
411 		htmr0->PRLD = hib_timer_count;
412 		if (hib_timer_count == 0) {
413 			return;
414 		}
415 
416 		while ((girq23->SRC & BIT(XEC_CC_HTMR_0_GIRQ23_POS)) == 0) {
417 			;
418 		}
419 
420 		htmr0->PRLD = 0; /* disable */
421 		while (htmr0->PRLD != 0) {
422 			;
423 		}
424 		girq23->SRC = BIT(XEC_CC_HTMR_0_GIRQ23_POS);
425 
426 		hib_timer_count -= hcnt;
427 	}
428 }
429 
430 /* Turn off crystal when we are not using it */
disable_32k_crystal(const struct device * dev)431 static int disable_32k_crystal(const struct device *dev)
432 {
433 	const struct xec_pcr_config * const devcfg = dev->config;
434 	struct vbatr_hw_regs *const vbr = (struct vbatr_hw_regs *)devcfg->vbr_base;
435 	uint32_t vbcs = vbr->CLK32_SRC;
436 
437 	vbcs &= ~(XEC_CC_VBATR_CS_XTAL_EN | XEC_CC_VBATR_CS_XTAL_SE | XEC_CC_VBATR_CS_XTAL_DHC);
438 	vbr->CLK32_SRC = vbcs;
439 
440 	return 0;
441 }
442 
443 /*
444  * Start external 32 KHz crystal.
445  * Assumes peripheral clocks source is Silicon OSC.
446  * If current configuration matches desired crystal configuration do nothing.
447  * NOTE: Crystal requires ~300 ms to stabilize.
448  */
enable_32k_crystal(const struct device * dev,uint32_t flags)449 static int enable_32k_crystal(const struct device *dev, uint32_t flags)
450 {
451 	const struct xec_pcr_config * const devcfg = dev->config;
452 	struct vbatr_hw_regs *const vbr = (struct vbatr_hw_regs *)devcfg->vbr_base;
453 	uint32_t vbcs = vbr->CLK32_SRC;
454 	uint32_t cfg = MCHP_VBATR_CS_XTAL_EN;
455 
456 	if (flags & CLK32K_FLAG_CRYSTAL_SE) {
457 		cfg |= MCHP_VBATR_CS_XTAL_SE;
458 	}
459 
460 	if ((vbcs & cfg) == cfg) {
461 		return 0;
462 	}
463 
464 	/* Configure crystal connection before enabling the crystal. */
465 	vbr->CLK32_SRC &= ~(MCHP_VBATR_CS_XTAL_SE | MCHP_VBATR_CS_XTAL_DHC |
466 			    MCHP_VBATR_CS_XTAL_CNTR_MSK);
467 	if (flags & CLK32K_FLAG_CRYSTAL_SE) {
468 		vbr->CLK32_SRC |= MCHP_VBATR_CS_XTAL_SE;
469 	}
470 
471 	/* Set crystal gain */
472 	vbr->CLK32_SRC |= MCHP_VBATR_CS_XTAL_CNTR_DG;
473 
474 	/* enable crystal */
475 	vbr->CLK32_SRC |= MCHP_VBATR_CS_XTAL_EN;
476 	/* wait for crystal stabilization */
477 	hib_timer_delay(HIBTIMER_MS_TO_CNT(devcfg->xtal_enable_delay_ms));
478 	/* turn off crystal high startup current */
479 	vbr->CLK32_SRC |= MCHP_VBATR_CS_XTAL_DHC;
480 
481 	return 0;
482 }
483 
484 /*
485  * Use PCR clock monitor hardware to test crystal output.
486  * Requires crystal to have stabilized after enable.
487  * When enabled the clock monitor hardware measures high/low, edges, and
488  * duty cycle and compares to programmed limits.
489  */
check_32k_crystal(const struct device * dev)490 static int check_32k_crystal(const struct device *dev)
491 {
492 	const struct xec_pcr_config * const devcfg = dev->config;
493 	struct pcr_hw_regs *const pcr = (struct pcr_hw_regs *)devcfg->pcr_base;
494 	struct htmr_regs *htmr0 = (struct htmr_regs *)DT_REG_ADDR(DT_NODELABEL(hibtimer0));
495 	struct girq_regs *girq23 = (struct girq_regs *)DT_REG_ADDR(DT_NODELABEL(girq23));
496 	uint32_t status = 0;
497 	int rc = 0;
498 
499 	htmr0->PRLD = 0;
500 	htmr0->CTRL = 0;
501 	girq23->SRC = BIT(XEC_CC_HTMR_0_GIRQ23_POS);
502 
503 	pcr->CNT32K_CTRL = 0U;
504 	pcr->CLK32K_MON_IEN = 0U;
505 	pcr->CLK32K_MON_ISTS = MCHP_PCR_CLK32M_ISTS_MASK;
506 
507 	pcr->CNT32K_PER_MIN = devcfg->period_min;
508 	pcr->CNT32K_PER_MAX = devcfg->period_max;
509 	pcr->CNT32K_DV_MAX = devcfg->max_dc_va;
510 	pcr->CNT32K_VALID_MIN = devcfg->min_valid;
511 
512 	pcr->CNT32K_CTRL =
513 		MCHP_PCR_CLK32M_CTRL_PER_EN | MCHP_PCR_CLK32M_CTRL_DC_EN |
514 		MCHP_PCR_CLK32M_CTRL_VAL_EN | MCHP_PCR_CLK32M_CTRL_CLR_CNT;
515 
516 	rc = -ETIMEDOUT;
517 	htmr0->PRLD = HIBTIMER_10_MS;
518 	status = pcr->CLK32K_MON_ISTS;
519 
520 	while ((girq23->SRC & BIT(XEC_CC_HTMR_0_GIRQ23_POS)) == 0) {
521 		if (status == (MCHP_PCR_CLK32M_ISTS_PULSE_RDY |
522 			       MCHP_PCR_CLK32M_ISTS_PASS_PER |
523 			       MCHP_PCR_CLK32M_ISTS_PASS_DC |
524 			       MCHP_PCR_CLK32M_ISTS_VALID)) {
525 			rc = 0;
526 			break;
527 		}
528 
529 		if (status & (MCHP_PCR_CLK32M_ISTS_FAIL |
530 			      MCHP_PCR_CLK32M_ISTS_STALL)) {
531 			rc = -EBUSY;
532 			break;
533 		}
534 
535 		status = pcr->CLK32K_MON_ISTS;
536 	}
537 
538 	pcr->CNT32K_CTRL = 0u;
539 	htmr0->PRLD = 0;
540 	girq23->SRC = BIT(XEC_CC_HTMR_0_GIRQ23_POS);
541 
542 	return rc;
543 }
544 
545 /*
546  * Set the clock source for either PLL or Peripheral-32K clock domain.
547  * The source must be a stable 32 KHz input: internal silicon oscillator,
548  * external crystal dual-ended crystal, 50% duty cycle waveform on XTAL2 only,
549  * or a 50% duty cycles waveform on the 32KHZ_PIN.
550  * NOTE: 32KHZ_PIN is an alternate function of a chip specific GPIO.
551  * Signal on 32KHZ_PIN may go off when VTR rail go down. MEC172x can automatically
552  * switch to silicon OSC or XTAL. At this time we do not support fall back to XTAL
553  * when using 32KHZ_PIN.
554  * !!! IMPORTANT !!! Fall back from 32KHZ_PIN to SO/XTAL is only for the Peripheral
555  * Clock domain. If the PLL is configured to use 32KHZ_PIN as its source then the
556  * PLL will shutdown and the PLL clock domain should switch to the ring oscillator.
557  * This means the PLL clock domain clock will not longer be accurate and may cause
558  * FW malfunction(s).
559  */
560 
connect_pll_32k(const struct device * dev,enum pll_clk32k_src src,uint32_t flags)561 static void connect_pll_32k(const struct device *dev, enum pll_clk32k_src src, uint32_t flags)
562 {
563 	const struct xec_pcr_config * const devcfg = dev->config;
564 	struct pcr_hw_regs *const pcr = (struct pcr_hw_regs *)devcfg->pcr_base;
565 	uint32_t pcr_clk_sel;
566 
567 	switch (src) {
568 	case PLL_CLK32K_SRC_XTAL:
569 		pcr_clk_sel = MCHP_PCR_VTR_32K_SRC_XTAL;
570 		break;
571 	case PLL_CLK32K_SRC_PIN:
572 		pcr_clk_sel = MCHP_PCR_VTR_32K_SRC_PIN;
573 		break;
574 	default: /* default to silicon OSC */
575 		pcr_clk_sel = MCHP_PCR_VTR_32K_SRC_SILOSC;
576 		break;
577 	}
578 
579 	pcr->CLK32K_SRC_VTR = pcr_clk_sel;
580 }
581 
connect_periph_32k(const struct device * dev,enum periph_clk32k_src src,uint32_t flags)582 static void connect_periph_32k(const struct device *dev, enum periph_clk32k_src src, uint32_t flags)
583 {
584 	const struct xec_pcr_config * const devcfg = dev->config;
585 	struct vbatr_hw_regs *const vbr = (struct vbatr_hw_regs *)devcfg->vbr_base;
586 	uint32_t vbr_clk_sel = vbr->CLK32_SRC & ~(MCHP_VBATR_CS_PCS_MSK);
587 
588 	switch (src) {
589 	case PERIPH_CLK32K_SRC_XTAL_XTAL:
590 		vbr_clk_sel |= MCHP_VBATR_CS_PCS_VTR_VBAT_XTAL;
591 		break;
592 	case PERIPH_CLK32K_SRC_PIN_SO:
593 		vbr_clk_sel |= MCHP_VBATR_CS_PCS_VTR_PIN_SO;
594 		break;
595 	case PERIPH_CLK32K_SRC_PIN_XTAL:
596 		vbr_clk_sel |= MCHP_VBATR_CS_PCS_VTR_PIN_XTAL;
597 		break;
598 	default: /* default to silicon OSC for VTR/VBAT */
599 		vbr_clk_sel |= MCHP_VBATR_CS_PCS_VTR_VBAT_SO;
600 		break;
601 	}
602 
603 	vbr->CLK32_SRC = vbr_clk_sel;
604 }
605 
606 /* two bit field in PCR VTR 32KHz source register */
get_pll_32k_source(const struct device * dev)607 enum pll_clk32k_src get_pll_32k_source(const struct device *dev)
608 {
609 	const struct xec_pcr_config * const devcfg = dev->config;
610 	struct pcr_hw_regs *const pcr = (struct pcr_hw_regs *)devcfg->pcr_base;
611 	enum pll_clk32k_src src = PLL_CLK32K_SRC_MAX;
612 
613 	switch (pcr->CLK32K_SRC_VTR & XEC_CC_PCR_CLK32K_SRC_MSK) {
614 	case XEC_CC_PCR_CLK32K_SRC_SIL:
615 		src = PLL_CLK32K_SRC_SO;
616 		break;
617 	case XEC_CC_PCR_CLK32K_SRC_XTAL:
618 		src = PLL_CLK32K_SRC_XTAL;
619 		break;
620 	case XEC_CC_PCR_CLK32K_SRC_PIN:
621 		src = PLL_CLK32K_SRC_PIN;
622 		break;
623 	default:
624 		src = PLL_CLK32K_SRC_MAX;
625 		break;
626 	}
627 
628 	return src;
629 }
630 
631 /* two bit field in VBAT source 32KHz register */
get_periph_32k_source(const struct device * dev)632 enum periph_clk32k_src get_periph_32k_source(const struct device *dev)
633 {
634 	const struct xec_pcr_config * const devcfg = dev->config;
635 	struct vbatr_hw_regs *const vbr = (struct vbatr_hw_regs *)devcfg->vbr_base;
636 	enum periph_clk32k_src src = PERIPH_CLK32K_SRC_MAX;
637 	uint32_t temp;
638 
639 	temp = (vbr->CLK32_SRC & XEC_CC_VBATR_CS_PCS_MSK) >> XEC_CC_VBATR_CS_PCS_POS;
640 	if (temp == VBR_CLK32K_SRC_SO_SO) {
641 		src = PERIPH_CLK32K_SRC_SO_SO;
642 	} else if (temp == VBR_CLK32K_SRC_XTAL_XTAL) {
643 		src = PERIPH_CLK32K_SRC_XTAL_XTAL;
644 	} else if (temp == VBR_CLK32K_SRC_PIN_SO) {
645 		src = PERIPH_CLK32K_SRC_PIN_SO;
646 	} else {
647 		src = PERIPH_CLK32K_SRC_PIN_XTAL;
648 	}
649 
650 	return src;
651 }
652 
653 /*
654  * MEC172x has two 32 KHz clock domains
655  *   PLL domain: 32 KHz clock input for PLL to produce 96 MHz and 48 MHz clocks
656  *   Peripheral domain: 32 KHz clock for subset of peripherals.
657  * Each domain 32 KHz clock input can be from one of the following sources:
658  *   Internal Silicon oscillator: +/- 2%
659  *   External Crystal connected as parallel or single ended
660  *   External 32KHZ_PIN 50% duty cycle waveform with fall back to either
661  *     Silicon OSC or crystal when 32KHZ_PIN signal goes away or VTR power rail
662  *     goes off.
663  * At chip reset the PLL is held in reset and the +/- 50% ring oscillator is
664  * the main clock.
665  * If no VBAT reset occurs the VBAT 32 KHz source register maintains its state.
666  */
soc_clk32_init(const struct device * dev,enum pll_clk32k_src pll_src,enum periph_clk32k_src periph_src,uint32_t flags)667 static int soc_clk32_init(const struct device *dev,
668 			  enum pll_clk32k_src pll_src,
669 			  enum periph_clk32k_src periph_src,
670 			  uint32_t flags)
671 {
672 	const struct xec_pcr_config * const devcfg = dev->config;
673 	struct pcr_hw_regs *const pcr = (struct pcr_hw_regs *)devcfg->pcr_base;
674 	struct vbatr_hw_regs *const vbr = (struct vbatr_hw_regs *)devcfg->vbr_base;
675 	int rc = 0;
676 
677 	/* disable PCR 32K monitor and clear counters */
678 	pcr->CNT32K_CTRL = MCHP_PCR_CLK32M_CTRL_CLR_CNT;
679 	pcr->CLK32K_MON_ISTS = MCHP_PCR_CLK32M_ISTS_MASK;
680 	pcr->CLK32K_MON_IEN = 0;
681 
682 	if (!is_sil_osc_enabled(vbr)) {
683 		enable_sil_osc(vbr);
684 		spin_delay(pcr, CLK32K_SIL_OSC_DELAY);
685 	}
686 
687 	/* Default to 32KHz Silicon OSC for PLL and peripherals */
688 	connect_pll_32k(dev, PLL_CLK32K_SRC_SO, 0);
689 	connect_periph_32k(dev, PERIPH_CLK32K_SRC_SO_SO, 0);
690 
691 	rc = pll_wait_lock(pcr, CLK32K_PLL_LOCK_WAIT);
692 	if (rc) {
693 		LOG_ERR("XEC clock control: MEC172x lock timeout for internal 32K OSC");
694 		return rc;
695 	}
696 
697 	/* If crystal input required, enable and check. Single-ended 32KHz square wave
698 	 * on XTAL pin is also handled here.
699 	 */
700 	if ((pll_src == PLL_CLK32K_SRC_XTAL) || periph_clk_src_using_xtal(periph_src)) {
701 		enable_32k_crystal(dev, flags);
702 		if (!devcfg->clkmon_bypass) {
703 			rc = check_32k_crystal(dev);
704 			if (rc) {
705 				/* disable crystal */
706 				vbr->CLK32_SRC &= ~(MCHP_VBATR_CS_XTAL_EN);
707 				LOG_ERR("XEC clock control: MEC172x XTAL check failed: %d", rc);
708 				return rc;
709 			}
710 		}
711 	} else {
712 		disable_32k_crystal(dev);
713 	}
714 
715 	/* Do PLL first so we can use a peripheral timer still on silicon OSC */
716 	if (pll_src != PLL_CLK32K_SRC_SO) {
717 		connect_pll_32k(dev, pll_src, flags);
718 		rc = pll_wait_lock_periph(pcr, devcfg->pll_lock_timeout_ms);
719 	}
720 
721 	if (periph_src != PERIPH_CLK32K_SRC_SO_SO) {
722 		connect_periph_32k(dev, periph_src, flags);
723 	}
724 
725 	/* Configuration requests disabling internal silicon OSC. */
726 	if (devcfg->dis_internal_osc) {
727 		if ((get_pll_32k_source(dev) != PLL_CLK32K_SRC_SO)
728 		    && !periph_clk_src_using_si(get_periph_32k_source(dev))) {
729 			vbr->CLK32_SRC &= ~(XEC_CC_VBATR_CS_SO_EN);
730 		}
731 	}
732 
733 	/* Configuration requests disabling internal silicon OSC. */
734 	if (devcfg->dis_internal_osc) {
735 		if ((get_pll_32k_source(dev) != PLL_CLK32K_SRC_SO)
736 		    && !periph_clk_src_using_si(get_periph_32k_source(dev))) {
737 			vbr->CLK32_SRC &= ~(XEC_CC_VBATR_CS_SO_EN);
738 		}
739 	}
740 
741 	return rc;
742 }
743 #endif
744 
745 /*
746  * MEC172x Errata document DS80000913C
747  * Programming the PCR clock divider that divides the clock input to the ARM
748  * Cortex-M4 may cause a clock glitch. The recommended work-around is to
749  * issue four NOP instruction before and after the write to the PCR processor
750  * clock control register. The final four NOP instructions are followed by
751  * data and instruction barriers to flush the Cortex-M4's pipeline.
752  * NOTE: Zephyr provides inline functions for Cortex-Mx NOP but not for
753  * data and instruction barrier instructions. Caller's should only invoke this
754  * function with interrupts locked.
755  */
xec_clock_control_core_clock_divider_set(uint8_t clkdiv)756 static void xec_clock_control_core_clock_divider_set(uint8_t clkdiv)
757 {
758 	struct pcr_hw_regs *const pcr = (struct pcr_hw_regs *)DT_INST_REG_ADDR_BY_IDX(0, 0);
759 
760 	arch_nop();
761 	arch_nop();
762 	arch_nop();
763 	arch_nop();
764 	pcr->PROC_CLK_CTRL = (uint32_t)clkdiv;
765 	arch_nop();
766 	arch_nop();
767 	arch_nop();
768 	arch_nop();
769 	barrier_dsync_fence_full();
770 	barrier_isync_fence_full();
771 }
772 
773 /*
774  * PCR peripheral sleep enable allows the clocks to a specific peripheral to
775  * be gated off if the peripheral is not requesting a clock.
776  * slp_idx = zero based index into 32-bit PCR sleep enable registers.
777  * slp_pos = bit position in the register
778  * slp_en if non-zero set the bit else clear the bit
779  */
z_mchp_xec_pcr_periph_sleep(uint8_t slp_idx,uint8_t slp_pos,uint8_t slp_en)780 int z_mchp_xec_pcr_periph_sleep(uint8_t slp_idx, uint8_t slp_pos,
781 				uint8_t slp_en)
782 {
783 	struct pcr_hw_regs *const pcr = (struct pcr_hw_regs *)DT_INST_REG_ADDR_BY_IDX(0, 0);
784 
785 	if ((slp_idx >= MCHP_MAX_PCR_SCR_REGS) || (slp_pos >= 32)) {
786 		return -EINVAL;
787 	}
788 
789 	if (slp_en) {
790 		pcr->SLP_EN[slp_idx] |= BIT(slp_pos);
791 	} else {
792 		pcr->SLP_EN[slp_idx] &= ~BIT(slp_pos);
793 	}
794 
795 	return 0;
796 }
797 
798 /* Most peripherals have a write only reset bit in the PCR reset enable registers.
799  * The layout of these registers is identical to the PCR sleep enable registers.
800  * Reset enables are protected by a lock register.
801  */
z_mchp_xec_pcr_periph_reset(uint8_t slp_idx,uint8_t slp_pos)802 int z_mchp_xec_pcr_periph_reset(uint8_t slp_idx, uint8_t slp_pos)
803 {
804 	struct pcr_hw_regs *const pcr = (struct pcr_hw_regs *)DT_INST_REG_ADDR_BY_IDX(0, 0);
805 
806 	if ((slp_idx >= MCHP_MAX_PCR_SCR_REGS) || (slp_pos >= 32)) {
807 		return -EINVAL;
808 	}
809 
810 	uint32_t lock = irq_lock();
811 
812 	pcr->RST_EN_LOCK = XEC_CC_PCR_RST_EN_UNLOCK;
813 	pcr->RST_EN[slp_idx] = BIT(slp_pos);
814 	pcr->RST_EN_LOCK = XEC_CC_PCR_RST_EN_LOCK;
815 
816 	irq_unlock(lock);
817 
818 	return 0;
819 }
820 
821 /* clock control driver API implementation */
822 
xec_cc_on(const struct device * dev,clock_control_subsys_t sub_system,bool turn_on)823 static int xec_cc_on(const struct device *dev,
824 		     clock_control_subsys_t sub_system,
825 		     bool turn_on)
826 {
827 	struct pcr_hw_regs *const pcr = (struct pcr_hw_regs *)DT_INST_REG_ADDR_BY_IDX(0, 0);
828 	struct mchp_xec_pcr_clk_ctrl *cc = (struct mchp_xec_pcr_clk_ctrl *)sub_system;
829 	uint16_t pcr_idx = 0;
830 	uint16_t bitpos = 0;
831 
832 	if (!cc) {
833 		return -EINVAL;
834 	}
835 
836 	switch (MCHP_XEC_CLK_SRC_GET(cc->pcr_info)) {
837 	case MCHP_XEC_PCR_CLK_CORE:
838 	case MCHP_XEC_PCR_CLK_BUS:
839 		break;
840 	case MCHP_XEC_PCR_CLK_CPU:
841 		if (cc->pcr_info & MCHP_XEC_CLK_CPU_MASK) {
842 			uint32_t lock = irq_lock();
843 
844 			xec_clock_control_core_clock_divider_set(
845 				cc->pcr_info & MCHP_XEC_CLK_CPU_MASK);
846 
847 			irq_unlock(lock);
848 		} else {
849 			return -EINVAL;
850 		}
851 		break;
852 	case MCHP_XEC_PCR_CLK_PERIPH:
853 	case MCHP_XEC_PCR_CLK_PERIPH_FAST:
854 		pcr_idx = MCHP_XEC_PCR_SCR_GET_IDX(cc->pcr_info);
855 		bitpos = MCHP_XEC_PCR_SCR_GET_BITPOS(cc->pcr_info);
856 
857 		if (pcr_idx >= MCHP_MAX_PCR_SCR_REGS) {
858 			return -EINVAL;
859 		}
860 
861 		if (turn_on) {
862 			pcr->SLP_EN[pcr_idx] &= ~BIT(bitpos);
863 		} else {
864 			pcr->SLP_EN[pcr_idx] |= BIT(bitpos);
865 		}
866 		break;
867 	case MCHP_XEC_PCR_CLK_PERIPH_SLOW:
868 		if (turn_on) {
869 			pcr->SLOW_CLK_CTRL =
870 				cc->pcr_info & MCHP_XEC_CLK_SLOW_MASK;
871 		} else {
872 			pcr->SLOW_CLK_CTRL = 0;
873 		}
874 		break;
875 	default:
876 		return -EINVAL;
877 	}
878 
879 	return 0;
880 }
881 
882 /*
883  * Turn on requested clock source.
884  * Core, CPU, and Bus clocks are always on except in deep sleep state.
885  * Peripheral clocks can be gated off if the peripheral's PCR sleep enable
886  * is set and the peripheral indicates it does not need a clock by clearing
887  * its PCR CLOCK_REQ read-only status.
888  * Peripheral slow clock my be turned on by writing a non-zero divider value
889  * to its PCR control register.
890  */
xec_clock_control_on(const struct device * dev,clock_control_subsys_t sub_system)891 static int xec_clock_control_on(const struct device *dev,
892 				clock_control_subsys_t sub_system)
893 {
894 	return xec_cc_on(dev, sub_system, true);
895 }
896 
897 /*
898  * Turn off clock source.
899  * Core, CPU, and Bus clocks are always on except in deep sleep when PLL is
900  * turned off. Exception is 32 KHz clock.
901  * Peripheral clocks are gated off when the peripheral's sleep enable is set
902  * and the peripheral indicates is no longer needs a clock by de-asserting
903  * its read-only PCR CLOCK_REQ bit.
904  * Peripheral slow clock can be turned off by writing 0 to its control register.
905  */
xec_clock_control_off(const struct device * dev,clock_control_subsys_t sub_system)906 static inline int xec_clock_control_off(const struct device *dev,
907 					clock_control_subsys_t sub_system)
908 {
909 	return xec_cc_on(dev, sub_system, false);
910 }
911 
912 /* MEC172x and future SoC's implement a turbo clock mode where
913  * ARM Core, QMSPI, and PK use turbo clock.  All other peripherals
914  * use AHB clock or the slow clock.
915  */
get_turbo_clock(const struct device * dev)916 static uint32_t get_turbo_clock(const struct device *dev)
917 {
918 #ifdef CONFIG_SOC_SERIES_MEC1501X
919 	ARG_UNUSED(dev);
920 
921 	return MHZ(48);
922 #else
923 	const struct xec_pcr_config * const devcfg = dev->config;
924 	struct pcr_hw_regs *const pcr = (struct pcr_hw_regs *)devcfg->pcr_base;
925 
926 	if (pcr->TURBO_CLK & XEC_CC_PCR_TURBO_CLK_96M) {
927 		return MHZ(96);
928 	}
929 
930 	return MHZ(48);
931 #endif
932 }
933 
934 /*
935  * MEC172x clock subsystem:
936  * Two main clock domains: PLL and Peripheral-32K. Each domain's 32 KHz source
937  * can be selected from one of three inputs:
938  *  internal silicon OSC +/- 2% accuracy
939  *  external crystal connected parallel or single ended
940  *  external 32 KHz 50% duty cycle waveform on 32KHZ_IN pin.
941  * PLL domain supplies 96 MHz, 48 MHz, and other high speed clocks to all
942  * peripherals except those in the Peripheral-32K clock domain. The slow clock
943  * is derived from the 48 MHz produced by the PLL.
944  *   ARM Cortex-M4 core input: 96MHz
945  *   AHB clock input: 48 MHz
946  *   Fast AHB peripherals: 96 MHz internal and 48 MHz AHB interface.
947  *   Slow clock peripherals: PWM,  TACH, PROCHOT
948  * Peripheral-32K domain peripherals:
949  *   WDT, RTC, RTOS timer, hibernation timers, week timer
950  *
951  * Peripherals using both PLL and 32K clock domains:
952  *   BBLED, RPMFAN
953  */
xec_clock_control_get_subsys_rate(const struct device * dev,clock_control_subsys_t sub_system,uint32_t * rate)954 static int xec_clock_control_get_subsys_rate(const struct device *dev,
955 					     clock_control_subsys_t sub_system,
956 					     uint32_t *rate)
957 {
958 	const struct xec_pcr_config * const devcfg = dev->config;
959 	struct pcr_hw_regs *const pcr = (struct pcr_hw_regs *)devcfg->pcr_base;
960 	uint32_t bus = (uint32_t)sub_system;
961 	uint32_t temp = 0;
962 	uint32_t ahb_clock = MHZ(48);
963 	uint32_t turbo_clock = get_turbo_clock(dev);
964 
965 	switch (bus) {
966 	case MCHP_XEC_PCR_CLK_CORE:
967 	case MCHP_XEC_PCR_CLK_PERIPH_FAST:
968 		*rate = turbo_clock;
969 		break;
970 	case MCHP_XEC_PCR_CLK_CPU:
971 		/* if PCR PROC_CLK_CTRL is 0 the chip is not running */
972 		*rate = turbo_clock / pcr->PROC_CLK_CTRL;
973 		break;
974 	case MCHP_XEC_PCR_CLK_BUS:
975 	case MCHP_XEC_PCR_CLK_PERIPH:
976 		*rate = ahb_clock;
977 		break;
978 	case MCHP_XEC_PCR_CLK_PERIPH_SLOW:
979 		temp = pcr->SLOW_CLK_CTRL;
980 		if (temp) {
981 			*rate = ahb_clock / temp;
982 		} else {
983 			*rate = 0; /* slow clock off */
984 		}
985 		break;
986 	default:
987 		*rate = 0;
988 		return -EINVAL;
989 	}
990 
991 	return 0;
992 }
993 
994 #if defined(CONFIG_PM)
mchp_xec_clk_ctrl_sys_sleep_enable(bool is_deep)995 void mchp_xec_clk_ctrl_sys_sleep_enable(bool is_deep)
996 {
997 	struct pcr_hw_regs *const pcr = (struct pcr_hw_regs *)DT_INST_REG_ADDR_BY_IDX(0, 0);
998 	uint32_t sys_sleep_mode = MCHP_PCR_SYS_SLP_CTRL_SLP_ALL;
999 
1000 	if (is_deep) {
1001 		sys_sleep_mode |= MCHP_PCR_SYS_SLP_CTRL_SLP_HEAVY;
1002 	}
1003 
1004 	SCB->SCR |= BIT(2);
1005 	pcr->SYS_SLP_CTRL = sys_sleep_mode;
1006 }
1007 
mchp_xec_clk_ctrl_sys_sleep_disable(void)1008 void mchp_xec_clk_ctrl_sys_sleep_disable(void)
1009 {
1010 	struct pcr_hw_regs *const pcr = (struct pcr_hw_regs *)DT_INST_REG_ADDR_BY_IDX(0, 0);
1011 	pcr->SYS_SLP_CTRL = 0;
1012 	SCB->SCR &= ~BIT(2);
1013 }
1014 #endif
1015 
1016 /* Clock controller driver registration */
1017 static struct clock_control_driver_api xec_clock_control_api = {
1018 	.on = xec_clock_control_on,
1019 	.off = xec_clock_control_off,
1020 	.get_rate = xec_clock_control_get_subsys_rate,
1021 };
1022 
xec_clock_control_init(const struct device * dev)1023 static int xec_clock_control_init(const struct device *dev)
1024 {
1025 	const struct xec_pcr_config * const devcfg = dev->config;
1026 	struct pcr_hw_regs *const pcr = (struct pcr_hw_regs *)devcfg->pcr_base;
1027 	enum pll_clk32k_src pll_clk_src = devcfg->pll_src;
1028 	enum periph_clk32k_src periph_clk_src = devcfg->periph_src;
1029 	uint32_t clk_flags = 0U;
1030 	int rc = 0;
1031 
1032 	if (devcfg->xtal_se) {
1033 		clk_flags |= CLK32K_FLAG_CRYSTAL_SE;
1034 	}
1035 
1036 	pcr_slp_init(pcr);
1037 
1038 	rc = pinctrl_apply_state(devcfg->pcfg, PINCTRL_STATE_DEFAULT);
1039 	if ((pll_clk_src == PLL_CLK32K_SRC_PIN) || periph_clk_src_using_pin(periph_clk_src)) {
1040 		if (rc) {
1041 			LOG_ERR("XEC clock control: PINCTRL apply error %d", rc);
1042 			pll_clk_src = PLL_CLK32K_SRC_SO;
1043 			periph_clk_src = PERIPH_CLK32K_SRC_SO_SO;
1044 			clk_flags = 0U;
1045 		}
1046 	}
1047 
1048 	/* sleep used as debug */
1049 	rc = pinctrl_apply_state(devcfg->pcfg, PINCTRL_STATE_SLEEP);
1050 	if ((rc != 0) && (rc != -ENOENT)) {
1051 		LOG_ERR("XEC clock control: PINCTRL debug apply error %d", rc);
1052 	}
1053 
1054 	rc = soc_clk32_init(dev, pll_clk_src, periph_clk_src, clk_flags);
1055 	if (rc) {
1056 		LOG_ERR("XEC clock control: init error %d", rc);
1057 	}
1058 
1059 	xec_clock_control_core_clock_divider_set(devcfg->core_clk_div);
1060 
1061 	return rc;
1062 }
1063 
1064 #define XEC_PLL_32K_SRC(i)	\
1065 	(enum pll_clk32k_src)DT_INST_PROP_OR(i, pll_32k_src, PLL_CLK32K_SRC_SO)
1066 
1067 #define XEC_PERIPH_32K_SRC(i)	\
1068 	(enum periph_clk32k_src)DT_INST_PROP_OR(0, periph_32k_src, PERIPH_CLK32K_SRC_SO_SO)
1069 
1070 PINCTRL_DT_INST_DEFINE(0);
1071 
1072 const struct xec_pcr_config pcr_xec_config = {
1073 	.pcr_base = DT_INST_REG_ADDR_BY_IDX(0, 0),
1074 	.vbr_base = DT_INST_REG_ADDR_BY_IDX(0, 1),
1075 	.pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(0),
1076 	.xtal_enable_delay_ms =
1077 		(uint16_t)DT_INST_PROP_OR(0, xtal_enable_delay_ms, XEC_CC_XTAL_EN_DELAY_MS_DFLT),
1078 	.pll_lock_timeout_ms =
1079 		(uint16_t)DT_INST_PROP_OR(0, pll_lock_timeout_ms, XEC_CC_DFLT_PLL_LOCK_WAIT_MS),
1080 	.period_min = (uint16_t)DT_INST_PROP_OR(0, clk32kmon_period_min, CNT32K_TMIN),
1081 	.period_max = (uint16_t)DT_INST_PROP_OR(0, clk32kmon_period_max, CNT32K_TMAX),
1082 	.core_clk_div = (uint8_t)DT_INST_PROP_OR(0, core_clk_div, CONFIG_SOC_MEC172X_PROC_CLK_DIV),
1083 	.xtal_se = (uint8_t)DT_INST_PROP_OR(0, xtal_single_ended, 0),
1084 	.max_dc_va = (uint8_t)DT_INST_PROP_OR(0, clk32kmon_duty_cycle_var_max, CNT32K_DUTY_MAX),
1085 	.min_valid = (uint8_t)DT_INST_PROP_OR(0, clk32kmon_valid_min, CNT32K_VAL_MIN),
1086 	.pll_src = XEC_PLL_32K_SRC(0),
1087 	.periph_src = XEC_PERIPH_32K_SRC(0),
1088 	.clkmon_bypass = (uint8_t)DT_INST_PROP_OR(0, clkmon_bypass, 0),
1089 	.dis_internal_osc = (uint8_t)DT_INST_PROP_OR(0, internal_osc_disable, 0),
1090 };
1091 
1092 DEVICE_DT_INST_DEFINE(0,
1093 		    &xec_clock_control_init,
1094 		    NULL,
1095 		    NULL, &pcr_xec_config,
1096 		    PRE_KERNEL_1,
1097 		    CONFIG_CLOCK_CONTROL_INIT_PRIORITY,
1098 		    &xec_clock_control_api);
1099