Lines Matching +full:32 +full:- +full:bit
4 * SPDX-License-Identifier: Apache-2.0
15 #include <zephyr/dt-bindings/clock/mchp_xec_pcr.h>
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
37 * One 32KHz clock pulse = 1464.84 48 MHz counts.
47 #define CLK32K_FLAG_CRYSTAL_SE BIT(0)
48 #define CLK32K_FLAG_PIN_FB_CRYSTAL BIT(1)
99 uint32_t RSVD4[(0x00c0 - 0x0094) / 4];
116 #define XEC_CC_PCR_OSC_ID_PLL_LOCK BIT(8)
117 #define XEC_CC_PCR_TURBO_CLK_96M BIT(2)
126 #define XEC_CC_PCR3_CRYPTO_MASK (BIT(26) | BIT(27) | BIT(28))
128 #define XEC_CC_PCR3_CRYPTO_MASK BIT(26)
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))
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 */
162 /* MEC172x Select source of peripheral 32KHz clock */
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 */
190 uint16_t period_min; /* mix and max 32KHz period range */
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 */
208 pcr->SYS_SLP_CTRL = 0U; in pcr_slp_init()
209 SCB->SCR &= ~BIT(2); in pcr_slp_init()
212 pcr->SLP_EN[i] = 0U; in pcr_slp_init()
215 pcr->SLP_EN[3] = XEC_CC_PCR3_CRYPTO_MASK; in pcr_slp_init()
221 * its reference clock. Available peripheral timers using 32KHz are:
225 * We use the hibernation timer GIRQ interrupt status bit instead of reading
227 * one 32KHz cycle to move pre-load into count register.
229 * Hibernation timer is using the chosen 32KHz source. If the external 32KHz source
240 htmr0->PRLD = 0; /* disable */ in pll_wait_lock_periph()
241 htmr0->CTRL = 0; /* 30.5 us units */ in pll_wait_lock_periph()
242 girq23->SRC = BIT(XEC_CC_HTMR_0_GIRQ23_POS); in pll_wait_lock_periph()
243 htmr0->PRLD = hcount; in pll_wait_lock_periph()
244 while (!(pcr->OSC_ID & MCHP_PCR_OSC_ID_PLL_LOCK)) { in pll_wait_lock_periph()
246 if (girq23->SRC & BIT(XEC_CC_HTMR_0_GIRQ23_POS)) { in pll_wait_lock_periph()
247 rc = -ETIMEDOUT; in pll_wait_lock_periph()
267 /* MEC15xx uses the same 32KHz source for both PLL and Peripheral 32K clock domains.
269 * If XTAL is selected (parallel) or single-ended the external 32KHz MUST stay on
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.
280 const struct xec_pcr_config * const devcfg = dev->config; in soc_clk32_init()
281 struct pcr_hw_regs *const pcr = (struct pcr_hw_regs *)devcfg->pcr_base; in soc_clk32_init()
282 struct vbatr_hw_regs *const vbr = (struct vbatr_hw_regs *)devcfg->vbr_base; in soc_clk32_init()
288 vbr->CLK32_TRIM_CTRL = XEC_CC15_TRIM_ENABLE_INT_OSCILLATOR; in soc_clk32_init()
303 case PLL_CLK32K_SRC_PIN: /* 32KHZ_IN pin falls back to Silicon OSC */ in soc_clk32_init()
307 return -EINVAL; in soc_clk32_init()
310 if ((vbr->CLK32_SRC & 0xffU) != cken) { in soc_clk32_init()
311 vbr->CLK32_SRC = cken; in soc_clk32_init()
314 rc = pll_wait_lock_periph(pcr, devcfg->xtal_enable_delay_ms); in soc_clk32_init()
344 if (vbr->CLK32_SRC & XEC_CC_VBATR_CS_SO_EN) { in is_sil_osc_enabled()
353 vbr->CLK32_SRC |= XEC_CC_VBATR_CS_SO_EN; in enable_sil_osc()
357 * may be running on its ring oscillator (+/- 50% accuracy). Configuring the
359 * by writing to a read-only hardware register in the PCR block.
366 pcr->OSC_ID = n; in spin_delay()
380 while (!(pcr->OSC_ID & MCHP_PCR_OSC_ID_PLL_LOCK)) { in pll_wait_lock()
382 return -ETIMEDOUT; in pll_wait_lock()
384 --wait_cnt; in pll_wait_lock()
390 /* caller has enabled internal silicon 32 KHz oscillator */
401 hcnt -= UINT16_MAX; in hib_timer_delay()
404 htmr0->PRLD = 0; /* disable */ in hib_timer_delay()
405 while (htmr0->PRLD != 0) { in hib_timer_delay()
408 htmr0->CTRL = 0; /* 32k time base */ in hib_timer_delay()
410 girq23->SRC = BIT(XEC_CC_HTMR_0_GIRQ23_POS); in hib_timer_delay()
411 htmr0->PRLD = hib_timer_count; in hib_timer_delay()
416 while ((girq23->SRC & BIT(XEC_CC_HTMR_0_GIRQ23_POS)) == 0) { in hib_timer_delay()
420 htmr0->PRLD = 0; /* disable */ in hib_timer_delay()
421 while (htmr0->PRLD != 0) { in hib_timer_delay()
424 girq23->SRC = BIT(XEC_CC_HTMR_0_GIRQ23_POS); in hib_timer_delay()
426 hib_timer_count -= hcnt; in hib_timer_delay()
433 const struct xec_pcr_config * const devcfg = dev->config; in disable_32k_crystal()
434 struct vbatr_hw_regs *const vbr = (struct vbatr_hw_regs *)devcfg->vbr_base; in disable_32k_crystal()
435 uint32_t vbcs = vbr->CLK32_SRC; in disable_32k_crystal()
438 vbr->CLK32_SRC = vbcs; in disable_32k_crystal()
444 * Start external 32 KHz crystal.
451 const struct xec_pcr_config * const devcfg = dev->config; in enable_32k_crystal()
452 struct vbatr_hw_regs *const vbr = (struct vbatr_hw_regs *)devcfg->vbr_base; in enable_32k_crystal()
453 uint32_t vbcs = vbr->CLK32_SRC; in enable_32k_crystal()
465 vbr->CLK32_SRC &= ~(MCHP_VBATR_CS_XTAL_SE | MCHP_VBATR_CS_XTAL_DHC | in enable_32k_crystal()
468 vbr->CLK32_SRC |= MCHP_VBATR_CS_XTAL_SE; in enable_32k_crystal()
472 vbr->CLK32_SRC |= MCHP_VBATR_CS_XTAL_CNTR_DG; in enable_32k_crystal()
475 vbr->CLK32_SRC |= MCHP_VBATR_CS_XTAL_EN; in enable_32k_crystal()
477 hib_timer_delay(HIBTIMER_MS_TO_CNT(devcfg->xtal_enable_delay_ms)); in enable_32k_crystal()
479 vbr->CLK32_SRC |= MCHP_VBATR_CS_XTAL_DHC; in enable_32k_crystal()
492 const struct xec_pcr_config * const devcfg = dev->config; in check_32k_crystal()
493 struct pcr_hw_regs *const pcr = (struct pcr_hw_regs *)devcfg->pcr_base; in check_32k_crystal()
499 htmr0->PRLD = 0; in check_32k_crystal()
500 htmr0->CTRL = 0; in check_32k_crystal()
501 girq23->SRC = BIT(XEC_CC_HTMR_0_GIRQ23_POS); in check_32k_crystal()
503 pcr->CNT32K_CTRL = 0U; in check_32k_crystal()
504 pcr->CLK32K_MON_IEN = 0U; in check_32k_crystal()
505 pcr->CLK32K_MON_ISTS = MCHP_PCR_CLK32M_ISTS_MASK; in check_32k_crystal()
507 pcr->CNT32K_PER_MIN = devcfg->period_min; in check_32k_crystal()
508 pcr->CNT32K_PER_MAX = devcfg->period_max; in check_32k_crystal()
509 pcr->CNT32K_DV_MAX = devcfg->max_dc_va; in check_32k_crystal()
510 pcr->CNT32K_VALID_MIN = devcfg->min_valid; in check_32k_crystal()
512 pcr->CNT32K_CTRL = in check_32k_crystal()
516 rc = -ETIMEDOUT; in check_32k_crystal()
517 htmr0->PRLD = HIBTIMER_10_MS; in check_32k_crystal()
518 status = pcr->CLK32K_MON_ISTS; in check_32k_crystal()
520 while ((girq23->SRC & BIT(XEC_CC_HTMR_0_GIRQ23_POS)) == 0) { in check_32k_crystal()
531 rc = -EBUSY; in check_32k_crystal()
535 status = pcr->CLK32K_MON_ISTS; in check_32k_crystal()
538 pcr->CNT32K_CTRL = 0u; in check_32k_crystal()
539 htmr0->PRLD = 0; in check_32k_crystal()
540 girq23->SRC = BIT(XEC_CC_HTMR_0_GIRQ23_POS); in check_32k_crystal()
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
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
563 const struct xec_pcr_config * const devcfg = dev->config; in connect_pll_32k()
564 struct pcr_hw_regs *const pcr = (struct pcr_hw_regs *)devcfg->pcr_base; in connect_pll_32k()
579 pcr->CLK32K_SRC_VTR = pcr_clk_sel; in connect_pll_32k()
584 const struct xec_pcr_config * const devcfg = dev->config; in connect_periph_32k()
585 struct vbatr_hw_regs *const vbr = (struct vbatr_hw_regs *)devcfg->vbr_base; in connect_periph_32k()
586 uint32_t vbr_clk_sel = vbr->CLK32_SRC & ~(MCHP_VBATR_CS_PCS_MSK); in connect_periph_32k()
603 vbr->CLK32_SRC = vbr_clk_sel; in connect_periph_32k()
606 /* two bit field in PCR VTR 32KHz source register */
609 const struct xec_pcr_config * const devcfg = dev->config; in get_pll_32k_source()
610 struct pcr_hw_regs *const pcr = (struct pcr_hw_regs *)devcfg->pcr_base; in get_pll_32k_source()
613 switch (pcr->CLK32K_SRC_VTR & XEC_CC_PCR_CLK32K_SRC_MSK) { in get_pll_32k_source()
631 /* two bit field in VBAT source 32KHz register */
634 const struct xec_pcr_config * const devcfg = dev->config; in get_periph_32k_source()
635 struct vbatr_hw_regs *const vbr = (struct vbatr_hw_regs *)devcfg->vbr_base; in get_periph_32k_source()
639 temp = (vbr->CLK32_SRC & XEC_CC_VBATR_CS_PCS_MSK) >> XEC_CC_VBATR_CS_PCS_POS; in get_periph_32k_source()
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%
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
663 * At chip reset the PLL is held in reset and the +/- 50% ring oscillator is
665 * If no VBAT reset occurs the VBAT 32 KHz source register maintains its state.
672 const struct xec_pcr_config * const devcfg = dev->config; in soc_clk32_init()
673 struct pcr_hw_regs *const pcr = (struct pcr_hw_regs *)devcfg->pcr_base; in soc_clk32_init()
674 struct vbatr_hw_regs *const vbr = (struct vbatr_hw_regs *)devcfg->vbr_base; in soc_clk32_init()
677 /* disable PCR 32K monitor and clear counters */ in soc_clk32_init()
678 pcr->CNT32K_CTRL = MCHP_PCR_CLK32M_CTRL_CLR_CNT; in soc_clk32_init()
679 pcr->CLK32K_MON_ISTS = MCHP_PCR_CLK32M_ISTS_MASK; in soc_clk32_init()
680 pcr->CLK32K_MON_IEN = 0; in soc_clk32_init()
687 /* Default to 32KHz Silicon OSC for PLL and peripherals */ in soc_clk32_init()
693 LOG_ERR("XEC clock control: MEC172x lock timeout for internal 32K OSC"); in soc_clk32_init()
697 /* If crystal input required, enable and check. Single-ended 32KHz square wave in soc_clk32_init()
702 if (!devcfg->clkmon_bypass) { in soc_clk32_init()
706 vbr->CLK32_SRC &= ~(MCHP_VBATR_CS_XTAL_EN); in soc_clk32_init()
718 rc = pll_wait_lock_periph(pcr, devcfg->pll_lock_timeout_ms); in soc_clk32_init()
726 if (devcfg->dis_internal_osc) { in soc_clk32_init()
729 vbr->CLK32_SRC &= ~(XEC_CC_VBATR_CS_SO_EN); in soc_clk32_init()
734 if (devcfg->dis_internal_osc) { in soc_clk32_init()
737 vbr->CLK32_SRC &= ~(XEC_CC_VBATR_CS_SO_EN); in soc_clk32_init()
748 * Cortex-M4 may cause a clock glitch. The recommended work-around is to
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
764 pcr->PROC_CLK_CTRL = (uint32_t)clkdiv; in xec_clock_control_core_clock_divider_set()
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
785 if ((slp_idx >= MCHP_MAX_PCR_SCR_REGS) || (slp_pos >= 32)) { in z_mchp_xec_pcr_periph_sleep()
786 return -EINVAL; in z_mchp_xec_pcr_periph_sleep()
790 pcr->SLP_EN[slp_idx] |= BIT(slp_pos); in z_mchp_xec_pcr_periph_sleep()
792 pcr->SLP_EN[slp_idx] &= ~BIT(slp_pos); in z_mchp_xec_pcr_periph_sleep()
798 /* Most peripherals have a write only reset bit in the PCR reset enable registers.
806 if ((slp_idx >= MCHP_MAX_PCR_SCR_REGS) || (slp_pos >= 32)) { in z_mchp_xec_pcr_periph_reset()
807 return -EINVAL; in z_mchp_xec_pcr_periph_reset()
812 pcr->RST_EN_LOCK = XEC_CC_PCR_RST_EN_UNLOCK; in z_mchp_xec_pcr_periph_reset()
813 pcr->RST_EN[slp_idx] = BIT(slp_pos); in z_mchp_xec_pcr_periph_reset()
814 pcr->RST_EN_LOCK = XEC_CC_PCR_RST_EN_LOCK; in z_mchp_xec_pcr_periph_reset()
833 return -EINVAL; in xec_cc_on()
836 switch (MCHP_XEC_CLK_SRC_GET(cc->pcr_info)) { in xec_cc_on()
841 if (cc->pcr_info & MCHP_XEC_CLK_CPU_MASK) { in xec_cc_on()
845 cc->pcr_info & MCHP_XEC_CLK_CPU_MASK); in xec_cc_on()
849 return -EINVAL; in xec_cc_on()
854 pcr_idx = MCHP_XEC_PCR_SCR_GET_IDX(cc->pcr_info); in xec_cc_on()
855 bitpos = MCHP_XEC_PCR_SCR_GET_BITPOS(cc->pcr_info); in xec_cc_on()
858 return -EINVAL; in xec_cc_on()
862 pcr->SLP_EN[pcr_idx] &= ~BIT(bitpos); in xec_cc_on()
864 pcr->SLP_EN[pcr_idx] |= BIT(bitpos); in xec_cc_on()
869 pcr->SLOW_CLK_CTRL = in xec_cc_on()
870 cc->pcr_info & MCHP_XEC_CLK_SLOW_MASK; in xec_cc_on()
872 pcr->SLOW_CLK_CTRL = 0; in xec_cc_on()
876 return -EINVAL; in xec_cc_on()
887 * its PCR CLOCK_REQ read-only status.
888 * Peripheral slow clock my be turned on by writing a non-zero divider value
900 * turned off. Exception is 32 KHz clock.
902 * and the peripheral indicates is no longer needs a clock by de-asserting
903 * its read-only PCR CLOCK_REQ bit.
923 const struct xec_pcr_config * const devcfg = dev->config; in get_turbo_clock()
924 struct pcr_hw_regs *const pcr = (struct pcr_hw_regs *)devcfg->pcr_base; in get_turbo_clock()
926 if (pcr->TURBO_CLK & XEC_CC_PCR_TURBO_CLK_96M) { in get_turbo_clock()
936 * Two main clock domains: PLL and Peripheral-32K. Each domain's 32 KHz source
938 * internal silicon OSC +/- 2% accuracy
940 * external 32 KHz 50% duty cycle waveform on 32KHZ_IN pin.
942 * peripherals except those in the Peripheral-32K clock domain. The slow clock
944 * ARM Cortex-M4 core input: 96MHz
948 * Peripheral-32K domain peripherals:
951 * Peripherals using both PLL and 32K clock domains:
958 const struct xec_pcr_config * const devcfg = dev->config; in xec_clock_control_get_subsys_rate()
959 struct pcr_hw_regs *const pcr = (struct pcr_hw_regs *)devcfg->pcr_base; in xec_clock_control_get_subsys_rate()
972 *rate = turbo_clock / pcr->PROC_CLK_CTRL; in xec_clock_control_get_subsys_rate()
979 temp = pcr->SLOW_CLK_CTRL; in xec_clock_control_get_subsys_rate()
988 return -EINVAL; in xec_clock_control_get_subsys_rate()
1004 SCB->SCR |= BIT(2); in mchp_xec_clk_ctrl_sys_sleep_enable()
1005 pcr->SYS_SLP_CTRL = sys_sleep_mode; in mchp_xec_clk_ctrl_sys_sleep_enable()
1011 pcr->SYS_SLP_CTRL = 0; in mchp_xec_clk_ctrl_sys_sleep_disable()
1012 SCB->SCR &= ~BIT(2); in mchp_xec_clk_ctrl_sys_sleep_disable()
1025 const struct xec_pcr_config * const devcfg = dev->config; in xec_clock_control_init()
1026 struct pcr_hw_regs *const pcr = (struct pcr_hw_regs *)devcfg->pcr_base; in xec_clock_control_init()
1027 enum pll_clk32k_src pll_clk_src = devcfg->pll_src; in xec_clock_control_init()
1028 enum periph_clk32k_src periph_clk_src = devcfg->periph_src; in xec_clock_control_init()
1032 if (devcfg->xtal_se) { in xec_clock_control_init()
1038 rc = pinctrl_apply_state(devcfg->pcfg, PINCTRL_STATE_DEFAULT); in xec_clock_control_init()
1049 rc = pinctrl_apply_state(devcfg->pcfg, PINCTRL_STATE_SLEEP); in xec_clock_control_init()
1050 if ((rc != 0) && (rc != -ENOENT)) { in xec_clock_control_init()
1059 xec_clock_control_core_clock_divider_set(devcfg->core_clk_div); in xec_clock_control_init()