Skip to content

Commit e039b8d

Browse files
nzmichaelhkartben
authored andcommitted
drivers: clock_control: set the flash wait state to match the RM
The flash latency needs to be configured before switching to the high speed clock. Set the latency based on the CH32V003 and CH32V00x reference manual. Signed-off-by: Michael Hope <[email protected]>
1 parent 3dbf080 commit e039b8d

File tree

1 file changed

+30
-4
lines changed

1 file changed

+30
-4
lines changed

drivers/clock_control/clock_control_wch_rcc.c

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
#define WCH_RCC_CLOCK_ID_OFFSET(id) (((id) >> 5) & 0xFF)
2020
#define WCH_RCC_CLOCK_ID_BIT(id) ((id) & 0x1F)
21+
#define WCH_RCC_SYSCLK DT_PROP(DT_NODELABEL(cpu0), clock_frequency)
2122

2223
#if DT_NODE_HAS_COMPAT(DT_INST_CLOCKS_CTLR(0), wch_ch32v00x_pll_clock) || \
2324
DT_NODE_HAS_COMPAT(DT_INST_CLOCKS_CTLR(0), wch_ch32v20x_30x_pll_clock)
@@ -78,6 +79,33 @@ static int clock_control_wch_rcc_get_rate(const struct device *dev, clock_contro
7879
return 0;
7980
}
8081

82+
static void clock_control_wch_rcc_setup_flash(void)
83+
{
84+
#if defined(FLASH_ACTLR_LATENCY)
85+
uint32_t latency;
86+
87+
#if defined(CONFIG_SOC_CH32V003)
88+
if (WCH_RCC_SYSCLK <= 24000000) {
89+
latency = FLASH_ACTLR_LATENCY_0;
90+
} else {
91+
latency = FLASH_ACTLR_LATENCY_1;
92+
}
93+
#elif defined(CONFIG_SOC_SERIES_CH32V00X)
94+
if (WCH_RCC_SYSCLK <= 15000000) {
95+
latency = FLASH_ACTLR_LATENCY_0;
96+
} else if (WCH_RCC_SYSCLK <= 24000000) {
97+
latency = FLASH_ACTLR_LATENCY_1;
98+
} else {
99+
latency = FLASH_ACTLR_LATENCY_2;
100+
}
101+
FLASH->ACTLR = (FLASH->ACTLR & ~FLASH_ACTLR_LATENCY) | latency;
102+
#else
103+
#error Unrecognised SOC family
104+
#endif
105+
FLASH->ACTLR = (FLASH->ACTLR & ~FLASH_ACTLR_LATENCY) | latency;
106+
#endif
107+
}
108+
81109
static DEVICE_API(clock_control, clock_control_wch_rcc_api) = {
82110
.on = clock_control_wch_rcc_on,
83111
.get_rate = clock_control_wch_rcc_get_rate,
@@ -87,6 +115,8 @@ static int clock_control_wch_rcc_init(const struct device *dev)
87115
{
88116
const struct clock_control_wch_rcc_config *config = dev->config;
89117

118+
clock_control_wch_rcc_setup_flash();
119+
90120
if (IS_ENABLED(CONFIG_DT_HAS_WCH_CH32V00X_PLL_CLOCK_ENABLED) ||
91121
IS_ENABLED(CONFIG_DT_HAS_WCH_CH32V20X_30X_PLL_CLOCK_ENABLED)) {
92122
/* Disable the PLL before potentially changing the input clocks. */
@@ -145,10 +175,6 @@ static int clock_control_wch_rcc_init(const struct device *dev)
145175
RCC->INTR = RCC_CSSC | RCC_PLLRDYC | RCC_HSERDYC | RCC_LSIRDYC;
146176
/* HCLK = SYSCLK = APB1 */
147177
RCC->CFGR0 = (RCC->CFGR0 & ~RCC_HPRE) | RCC_HPRE_DIV1;
148-
#if defined(CONFIG_SOC_CH32V003)
149-
/* Set the Flash to 0 wait state */
150-
FLASH->ACTLR = (FLASH->ACTLR & ~FLASH_ACTLR_LATENCY) | FLASH_ACTLR_LATENCY_1;
151-
#endif
152178

153179
return 0;
154180
}

0 commit comments

Comments
 (0)