Microchip: XEC RTOS timer: Add MEC172x support to driver
Update Microchip XEC RTOS timer driver adding MEC172x support and
using more device tree properities in the driver. We must also update
the XEC counter driver to use the new GIRQ DT properties.
Add new properties to RTOS timer and RTC timer YAML. These two timers
are linked due to option using a high speed timer for kernel busy wait.
Add Kconfig logic for XEC RTOS timer to MEC172x SoC.
Enable the Microchip XEC RTOS timer in the MEC172x evaluation board.
Add device tree nodes for most peripeherals.
Signed-off-by: Scott Worley <scott.worley@microchip.com>
diff --git a/boards/arm/mec15xxevb_assy6853/mec15xxevb_assy6853.dts b/boards/arm/mec15xxevb_assy6853/mec15xxevb_assy6853.dts
index a69c026..510544a 100644
--- a/boards/arm/mec15xxevb_assy6853/mec15xxevb_assy6853.dts
+++ b/boards/arm/mec15xxevb_assy6853/mec15xxevb_assy6853.dts
@@ -125,7 +125,7 @@
pc_girq = <15>;
};
-&timer3 {
+&timer5 {
status = "okay";
};
diff --git a/boards/arm/mec172xevb_assy6906/Kconfig.defconfig b/boards/arm/mec172xevb_assy6906/Kconfig.defconfig
index d559899..8b23b52 100644
--- a/boards/arm/mec172xevb_assy6906/Kconfig.defconfig
+++ b/boards/arm/mec172xevb_assy6906/Kconfig.defconfig
@@ -6,4 +6,34 @@
config BOARD
default "mec172xevb_assy6906"
+if RTOS_TIMER
+
+# XEC RTOS timer HW frequency is fixed at 32768 Hz.
+# The driver requires tickless mode and ticks per second to be 32768 for
+# accurate operation.
+
+config SYS_CLOCK_HW_CYCLES_PER_SEC
+ default 32768
+
+config SYS_CLOCK_TICKS_PER_SEC
+ default 32768
+
+endif # RTOS_TIMER
+
+if !RTOS_TIMER
+
+# If RTOS timer is not enabled we use ARM Cortex-M
+# SYSTICK. SYSTICK frequency is 96 MHz divided down by the MEC172x PCR
+# processor clock divider register. We assume PCR processor clock divider
+# is set to 1. Refer to SOC_MEC172X_PROC_CLK_DIV
+#
+
+config SYS_CLOCK_HW_CYCLES_PER_SEC
+ default 96000000
+
+config SYS_CLOCK_TICKS_PER_SEC
+ default 1000
+
+endif # RTOS_TIMER
+
endif # BOARD_MEC172XEVB_ASSY6906
diff --git a/boards/arm/mec172xevb_assy6906/mec172xevb_assy6906.dts b/boards/arm/mec172xevb_assy6906/mec172xevb_assy6906.dts
index 198acaf..466568d 100644
--- a/boards/arm/mec172xevb_assy6906/mec172xevb_assy6906.dts
+++ b/boards/arm/mec172xevb_assy6906/mec172xevb_assy6906.dts
@@ -20,7 +20,7 @@
};
&cpu0 {
- clock-frequency = <96000000>;
+ status = "okay";
};
/* Initialize ECIA. Does not initialize child devices */
@@ -28,7 +28,7 @@
status = "okay";
};
-&systick {
+&rtimer {
status = "okay";
};
diff --git a/boards/arm/mec172xevb_assy6906/mec172xevb_assy6906_defconfig b/boards/arm/mec172xevb_assy6906/mec172xevb_assy6906_defconfig
index f8c33a2..bd2a206 100644
--- a/boards/arm/mec172xevb_assy6906/mec172xevb_assy6906_defconfig
+++ b/boards/arm/mec172xevb_assy6906/mec172xevb_assy6906_defconfig
@@ -7,8 +7,7 @@
CONFIG_SOC_MEC172X_NSZ=y
CONFIG_SOC_SERIES_MEC172X=y
CONFIG_BOARD_MEC172XEVB_ASSY6906=y
-
-CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=96000000
+CONFIG_RTOS_TIMER=y
CONFIG_CLOCK_CONTROL=y
CONFIG_SERIAL=y
diff --git a/drivers/counter/counter_mchp_xec.c b/drivers/counter/counter_mchp_xec.c
index a75d763..39583ac 100644
--- a/drivers/counter/counter_mchp_xec.c
+++ b/drivers/counter/counter_mchp_xec.c
@@ -318,8 +318,8 @@
.config_func = counter_xec_irq_config_##inst, \
.base_address = DT_INST_REG_ADDR(inst), \
.prescaler = DT_INST_PROP(inst, prescaler), \
- .girq_id = DT_INST_PROP(inst, girq), \
- .girq_bit = DT_INST_PROP(inst, girq_bit), \
+ .girq_id = DT_INST_PROP_BY_IDX(0, girqs, 0), \
+ .girq_bit = DT_INST_PROP_BY_IDX(0, girqs, 1), \
}; \
\
DEVICE_DT_INST_DEFINE(inst, \
diff --git a/drivers/timer/mchp_xec_rtos_timer.c b/drivers/timer/mchp_xec_rtos_timer.c
index 360c831..7dd853d 100644
--- a/drivers/timer/mchp_xec_rtos_timer.c
+++ b/drivers/timer/mchp_xec_rtos_timer.c
@@ -6,10 +6,12 @@
#define DT_DRV_COMPAT microchip_xec_rtos_timer
+#include <devicetree.h>
#include <soc.h>
#include <drivers/timer/system_timer.h>
#include <sys_clock.h>
#include <spinlock.h>
+#include <arch/arm/aarch32/cortex_m/cmsis.h>
BUILD_ASSERT(!IS_ENABLED(CONFIG_SMP), "XEC RTOS timer doesn't support SMP");
BUILD_ASSERT(CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC == 32768,
@@ -50,14 +52,30 @@
(CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC / CONFIG_SYS_CLOCK_TICKS_PER_SEC)
#define TIMER_REGS \
- ((RTMR_Type *) DT_INST_REG_ADDR(0))
+ ((struct rtmr_regs *)DT_INST_REG_ADDR(0))
+
+#define ECIA_XEC_REGS \
+ ((struct ecia_regs *)DT_REG_ADDR(DT_NODELABEL(ecia)))
+
+#ifdef CONFIG_ARCH_HAS_CUSTOM_BUSY_WAIT
+#define PCR_XEC_REGS \
+ ((struct pcr_regs *)DT_REG_ADDR(DT_NODELABEL(pcr)))
+
+/*
+ * pcrs property at index 0 is register index into array of 32-bit PCR SLP_EN,
+ * CLK_REQ, or RST_EN registers. Property at index 1 is the bit position.
+ */ /*DT_PROP_BY_IDX(DT_NODELABEL(kbc0), girqs, 0)*/
+#define BTMR32_0_PCR_REG_IDX (DT_PROP_BY_IDX(DT_NODELABEL(timer4), pcrs, 0))
+#define BTMR32_0_PCR_BITPOS (DT_PROP_BY_IDX(DT_NODELABEL(timer4), pcrs, 1))
+
+#define BTMR32_0_REGS \
+ ((struct btmr_regs *)(DT_REG_ADDR(DT_NODELABEL(timer4))))
+#endif
/* Mask off bits[31:28] of 32-bit count */
-#define TIMER_MAX 0x0FFFFFFFUL
-
-#define TIMER_COUNT_MASK 0x0FFFFFFFUL
-
-#define TIMER_STOPPED 0xF0000000UL
+#define TIMER_MAX 0x0fffffffu
+#define TIMER_COUNT_MASK 0x0fffffffu
+#define TIMER_STOPPED 0xf0000000u
/* Adjust cycle count programmed into timer for HW restart latency */
#define TIMER_ADJUST_LIMIT 2
@@ -66,6 +84,11 @@
/* max number of ticks we can load into the timer in one shot */
#define MAX_TICKS (TIMER_MAX / CYCLES_PER_TICK)
+#define TIMER_GIRQ DT_INST_PROP_BY_IDX(0, girqs, 0)
+#define TIMER_GIRQ_POS DT_INST_PROP_BY_IDX(0, girqs, 1)
+#define TIMER_NVIC_NO DT_INST_IRQN(0)
+#define TIMER_NVIC_PRIO DT_INST_IRQ(0, priority)
+
/*
* The spinlock protects all access to the RTMR registers, as well as
* 'total_cycles', 'last_announcement', and 'cached_icr'.
@@ -79,6 +102,38 @@
static uint32_t total_cycles;
static uint32_t cached_icr = CYCLES_PER_TICK;
+/*
+ * NOTE: using inline for speed instead of call to external SoC function.
+ * MEC GIRQ numbers are documented as 8 to 26, check and convert to zero
+ * based index.
+ */
+static inline void girq_src_clr(int girq, int bitpos)
+{
+ if ((girq < 8) || (girq > 26)) {
+ return;
+ }
+
+ ECIA_XEC_REGS->GIRQ[girq - 8].SRC = BIT(bitpos);
+}
+
+static inline void girq_src_en(int girq, int bitpos)
+{
+ if ((girq < 8) || (girq > 26)) {
+ return;
+ }
+
+ ECIA_XEC_REGS->GIRQ[girq - 8].EN_SET = BIT(bitpos);
+}
+
+static inline void girq_src_dis(int girq, int bitpos)
+{
+ if ((girq < 8) || (girq > 26)) {
+ return;
+ }
+
+ ECIA_XEC_REGS->GIRQ[girq - 8].EN_CLR = BIT(bitpos);
+}
+
static void timer_restart(uint32_t countdown)
{
TIMER_REGS->CTRL = 0U;
@@ -160,10 +215,9 @@
ccr = timer_count();
/* turn off to clear any pending interrupt status */
- TIMER_REGS->CTRL = 0U;
- MCHP_GIRQ_SRC(DT_INST_PROP(0, girq)) =
- BIT(DT_INST_PROP(0, girq_bit));
- NVIC_ClearPendingIRQ(RTMR_IRQn);
+ TIMER_REGS->CTRL = 0u;
+ girq_src_clr(TIMER_GIRQ, TIMER_GIRQ_POS);
+ NVIC_ClearPendingIRQ(TIMER_NVIC_NO);
temp = total_cycles;
temp += (cached_icr - ccr);
@@ -222,8 +276,7 @@
k_spinlock_key_t key = k_spin_lock(&lock);
- MCHP_GIRQ_SRC(DT_INST_PROP(0, girq)) =
- BIT(DT_INST_PROP(0, girq_bit));
+ girq_src_clr(TIMER_GIRQ, TIMER_GIRQ_POS);
/* Restart the timer as early as possible to minimize drift... */
timer_restart(MAX_TICKS * CYCLES_PER_TICK);
@@ -255,8 +308,7 @@
k_spinlock_key_t key = k_spin_lock(&lock);
- MCHP_GIRQ_SRC(DT_INST_PROP(0, girq)) =
- BIT(DT_INST_PROP(0, girq_bit));
+ girq_src_clr(TIMER_GIRQ, TIMER_GIRQ_POS);
/* Restart the timer as early as possible to minimize drift... */
timer_restart(cached_icr);
@@ -318,40 +370,42 @@
{
ARG_UNUSED(dev);
- mchp_pcr_periph_slp_ctrl(PCR_RTMR, MCHP_PCR_SLEEP_DIS);
-
#ifdef CONFIG_TICKLESS_KERNEL
cached_icr = MAX_TICKS;
#endif
- TIMER_REGS->CTRL = 0U;
- MCHP_GIRQ_SRC(DT_INST_PROP(0, girq)) =
- BIT(DT_INST_PROP(0, girq_bit));
- NVIC_ClearPendingIRQ(RTMR_IRQn);
+ TIMER_REGS->CTRL = 0u;
+ girq_src_clr(TIMER_GIRQ, TIMER_GIRQ_POS);
+ girq_src_dis(TIMER_GIRQ, TIMER_GIRQ_POS);
+ NVIC_ClearPendingIRQ(TIMER_NVIC_NO);
- IRQ_CONNECT(RTMR_IRQn,
- DT_INST_IRQ(0, priority),
- xec_rtos_timer_isr, 0, 0);
-
- MCHP_GIRQ_ENSET(DT_INST_PROP(0, girq)) =
- BIT(DT_INST_PROP(0, girq_bit));
- irq_enable(RTMR_IRQn);
+ IRQ_CONNECT(TIMER_NVIC_NO, TIMER_NVIC_PRIO, xec_rtos_timer_isr, 0, 0);
+ irq_enable(TIMER_NVIC_NO);
+ girq_src_en(TIMER_GIRQ, TIMER_GIRQ_POS);
#ifdef CONFIG_ARCH_HAS_CUSTOM_BUSY_WAIT
- uint32_t btmr_ctrl = B32TMR0_REGS->CTRL = (MCHP_BTMR_CTRL_ENABLE
- | MCHP_BTMR_CTRL_AUTO_RESTART
- | MCHP_BTMR_CTRL_COUNT_UP
- | (47UL << MCHP_BTMR_CTRL_PRESCALE_POS));
- B32TMR0_REGS->CTRL = MCHP_BTMR_CTRL_SOFT_RESET;
- B32TMR0_REGS->CTRL = btmr_ctrl;
- B32TMR0_REGS->PRLD = 0xFFFFFFFFUL;
+ uint32_t btmr_ctrl = (MCHP_BTMR_CTRL_ENABLE
+ | MCHP_BTMR_CTRL_AUTO_RESTART
+ | MCHP_BTMR_CTRL_COUNT_UP
+ | (47UL << MCHP_BTMR_CTRL_PRESCALE_POS));
+
+#if CONFIG_SOC_SERIES_MEC1501X
+ mchp_pcr_periph_slp_ctrl(PCR_B32TMR0, 0);
+#else
+ PCR_XEC_REGS->SLP_EN[BTMR32_0_PCR_REG_IDX] &= ~BIT(BTMR32_0_PCR_BITPOS);
+#endif
+ BTMR32_0_REGS->CTRL = MCHP_BTMR_CTRL_SOFT_RESET;
+ BTMR32_0_REGS->CTRL = btmr_ctrl;
+ BTMR32_0_REGS->PRLD = UINT32_MAX;
btmr_ctrl |= MCHP_BTMR_CTRL_START;
timer_restart(cached_icr);
- /* wait for Hibernation timer to load count register from preload */
- while (TIMER_REGS->CNT == 0)
+ /* wait for RTOS timer to load count register from preload */
+ while (TIMER_REGS->CNT == 0) {
;
- B32TMR0_REGS->CTRL = btmr_ctrl;
+ }
+
+ BTMR32_0_REGS->CTRL = btmr_ctrl;
#else
timer_restart(cached_icr);
#endif
@@ -377,10 +431,10 @@
return;
}
- uint32_t start = B32TMR0_REGS->CNT;
+ uint32_t start = BTMR32_0_REGS->CNT;
for (;;) {
- uint32_t curr = B32TMR0_REGS->CNT;
+ uint32_t curr = BTMR32_0_REGS->CNT;
if ((curr - start) >= usec_to_wait) {
break;
diff --git a/dts/arm/microchip/mec1501hsz.dtsi b/dts/arm/microchip/mec1501hsz.dtsi
index 29d49e6..e8441b8 100644
--- a/dts/arm/microchip/mec1501hsz.dtsi
+++ b/dts/arm/microchip/mec1501hsz.dtsi
@@ -61,13 +61,23 @@
};
soc {
+ pcr: pcr@40080100 {
+ reg = <0x40080100 0x100 0x4000a400 0x100>;
+ reg-names = "pcrr", "vbatr";
+ label = "PCR";
+ };
+ ecia: ecia@4000e000 {
+ reg = <0x4000e000 0x400>;
+ label = "ECIA_0";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ };
rtimer: timer@40007400 {
compatible = "microchip,xec-rtos-timer";
reg = <0x40007400 0x10>;
interrupts = <111 0>;
label = "RTIMER";
- girq = <23>;
- girq-bit = <10>;
+ girqs = <23 10>;
};
wdog: watchdog@40000400 {
compatible = "microchip,xec-watchdog";
@@ -242,37 +252,55 @@
timer0: timer@40000c00 {
compatible = "microchip,xec-timer";
clock-frequency = <48000000>;
- reg = <0x40000C00 0x20>;
+ reg = <0x40000c00 0x20>;
interrupts = <136 0>;
label = "TIMER_0";
max-value = <0xFFFF>;
prescaler = <0>;
status = "disabled";
- girq = <23>;
- girq-bit = <0>;
+ girqs = <23 0>;
+ pcrs = <1 30>;
};
timer1: timer@40000c20 {
compatible = "microchip,xec-timer";
clock-frequency = <48000000>;
- reg = <0x40000C20 0x20>;
+ reg = <0x40000c20 0x20>;
interrupts = <137 0>;
label = "TIMER_1";
max-value = <0xFFFF>;
prescaler = <0>;
status = "disabled";
- girq = <23>;
- girq-bit = <1>;
+ girqs = <23 1>;
+ pcrs = <1 31>;
};
- timer3: timer@40000ca0 {
+ /*
+ * NOTE 1: timers 2 and 3 not implemented in MEC152x.
+ * NOTE 2: When RTOS timer used as kernel timer, timer4 used
+ * to provide high speed busy wait counter. Keep disabled to
+ * prevent counter driver from claiming it.
+ */
+ timer4: timer@40000c80 {
compatible = "microchip,xec-timer";
clock-frequency = <48000000>;
- reg = <0x40000CA0 0x20>;
- interrupts = <141 0>;
- label = "TIMER_3";
+ reg = <0x40000c80 0x20>;
+ interrupts = <140 0>;
+ label = "TIMER_4";
max-value = <0xFFFFFFFF>;
prescaler = <0>;
- girq = <23>;
- girq-bit = <5>;
+ girqs = <23 4>;
+ pcrs = <3 23>;
+ status = "disabled";
+ };
+ timer5: timer@40000ca0 {
+ compatible = "microchip,xec-timer";
+ clock-frequency = <48000000>;
+ reg = <0x40000ca0 0x20>;
+ interrupts = <141 0>;
+ label = "TIMER_5";
+ max-value = <0xFFFFFFFF>;
+ prescaler = <0>;
+ girqs = <23 5>;
+ pcrs = <3 24>;
};
ps2_0: ps2@40009000 {
compatible = "microchip,xec-ps2";
diff --git a/dts/arm/microchip/mec172xnsz.dtsi b/dts/arm/microchip/mec172xnsz.dtsi
index 29c2597..017ecaa 100644
--- a/dts/arm/microchip/mec172xnsz.dtsi
+++ b/dts/arm/microchip/mec172xnsz.dtsi
@@ -314,14 +314,16 @@
#pcrs-cells = <2>;
};
rtimer: timer@40007400 {
+ compatible = "microchip,xec-rtos-timer";
reg = <0x40007400 0x10>;
interrupts = <111 0>;
label = "RTIMER";
girqs = <23 10>;
};
timer0: timer@40000c00 {
+ compatible = "microchip,xec-timer";
clock-frequency = <48000000>;
- reg = <0x40000C00 0x20>;
+ reg = <0x40000c00 0x20>;
interrupts = <136 0>;
girqs = <23 0>;
pcrs = <1 30>;
@@ -333,8 +335,9 @@
status = "disabled";
};
timer1: timer@40000c20 {
+ compatible = "microchip,xec-timer";
clock-frequency = <48000000>;
- reg = <0x40000C20 0x20>;
+ reg = <0x40000c20 0x20>;
interrupts = <137 0>;
girqs = <23 1>;
pcrs = <1 31>;
@@ -346,8 +349,9 @@
status = "disabled";
};
timer2: timer@40000c40 {
+ compatible = "microchip,xec-timer";
clock-frequency = <48000000>;
- reg = <0x40000C40 0x20>;
+ reg = <0x40000c40 0x20>;
interrupts = <138 0>;
girqs = <23 2>;
pcrs = <3 21>;
@@ -359,8 +363,9 @@
status = "disabled";
};
timer3: timer@40000c60 {
+ compatible = "microchip,xec-timer";
clock-frequency = <48000000>;
- reg = <0x40000C60 0x20>;
+ reg = <0x40000c60 0x20>;
interrupts = <139 0>;
girqs = <23 3>;
pcrs = <3 22>;
@@ -371,23 +376,29 @@
#pcrs-cells = <2>;
status = "disabled";
};
+ /*
+ * NOTE: When RTOS timer used as kernel timer, timer4 used
+ * to provide high speed busy wait counter. Keep disabled to
+ * prevent counter driver from claiming it.
+ */
timer4: timer@40000c80 {
+ compatible = "microchip,xec-timer";
clock-frequency = <48000000>;
- reg = <0x40000C80 0x20>;
+ reg = <0x40000c80 0x20>;
interrupts = <140 0>;
girqs = <23 4>;
pcrs = <3 23>;
label = "TIMER_4";
max-value = <0xFFFFFFFF>;
prescaler = <0>;
- exclude;
#girqs-cells = <2>;
#pcrs-cells = <2>;
status = "disabled";
};
timer5: timer@40000ca0 {
+ compatible = "microchip,xec-timer";
clock-frequency = <48000000>;
- reg = <0x40000CA0 0x20>;
+ reg = <0x40000ca0 0x20>;
interrupts = <141 0>;
girqs = <23 5>;
pcrs = <3 24>;
diff --git a/dts/bindings/rtc/microchip,xec-timer.yaml b/dts/bindings/rtc/microchip,xec-timer.yaml
index f10498c..a83c5e0 100644
--- a/dts/bindings/rtc/microchip,xec-timer.yaml
+++ b/dts/bindings/rtc/microchip,xec-timer.yaml
@@ -27,12 +27,28 @@
required: true
description: Maximum counter value the instance can handle
- girq:
- type: int
+ girqs:
+ type: array
required: true
- description: GIRQ for this device
+ description: Array of GIRQ numbers [8:26] and bit positions [0:31].
- girq-bit:
- type: int
+ pcrs:
+ type: array
required: true
- description: Bit position in GIRQ for this device
+ description: PCR sleep enable register index and bit position.
+
+ "girqs-cells":
+ type: int
+ const: 2
+
+ "#pcrs-cells":
+ type: int
+ const: 2
+
+girqs-cells:
+ - girq_num
+ - bitpos
+
+pcrs-cells:
+ - reg_index
+ - bitpos
diff --git a/dts/bindings/timer/microchip,xec-rtos-timer.yaml b/dts/bindings/timer/microchip,xec-rtos-timer.yaml
index 3cad9d6..d269767 100644
--- a/dts/bindings/timer/microchip,xec-rtos-timer.yaml
+++ b/dts/bindings/timer/microchip,xec-rtos-timer.yaml
@@ -17,12 +17,15 @@
label:
required: true
- girq:
- type: int
+ girqs:
+ type: array
required: true
- description: GIRQ for this device
+ description: Array of GIRQ numbers [8:26] and bit positions [0:31].
- girq-bit:
+ "girqs-cells":
type: int
- required: true
- description: Bit position in GIRQ for this device
+ const: 2
+
+girqs-cells:
+ - girq_num
+ - bitpos
diff --git a/soc/arm/microchip_mec/mec172x/Kconfig.defconfig.series b/soc/arm/microchip_mec/mec172x/Kconfig.defconfig.series
index 76244dd..1a34351 100644
--- a/soc/arm/microchip_mec/mec172x/Kconfig.defconfig.series
+++ b/soc/arm/microchip_mec/mec172x/Kconfig.defconfig.series
@@ -16,8 +16,22 @@
source "soc/arm/microchip_mec/mec172x/Kconfig.defconfig.mec172x*"
+if RTOS_TIMER
+
+config MCHP_XEC_RTOS_TIMER
+ default y
+
+config SOC_HAS_TIMING_FUNCTIONS
+ default y if !CORTEX_M_DWT
+
+config ARCH_HAS_CUSTOM_BUSY_WAIT
+ default y
+
+endif # RTOS_TIMER
+
config CORTEX_M_SYSTICK
default y
+ depends on !RTOS_TIMER
config CLOCK_CONTROL_MCHP_XEC
default y
diff --git a/soc/arm/microchip_mec/mec172x/Kconfig.soc b/soc/arm/microchip_mec/mec172x/Kconfig.soc
index 827819c..4b910c1 100644
--- a/soc/arm/microchip_mec/mec172x/Kconfig.soc
+++ b/soc/arm/microchip_mec/mec172x/Kconfig.soc
@@ -12,6 +12,9 @@
endchoice
+config RTOS_TIMER
+ bool "MEC172x RTOS Timer(32KHz) as kernel timer"
+
config SOC_MEC172X_PROC_CLK_DIV
int "PROC_CLK_DIV"
default 1