From 510102dd71c0479c55fd23071b250e477a2e87bd Mon Sep 17 00:00:00 2001 From: Krzysztof Chruscinski Date: Tue, 28 Jan 2020 08:05:50 +0100 Subject: [PATCH] soc: arm: nordic_nrf: nrf52: Add workaround for anomaly 132 Added delay before starting low frequency clock for the first time to ensure that anomaly conditions are not met. Delay is configurable and might be disabled. Signed-off-by: Krzysztof Chruscinski --- drivers/clock_control/nrf_power_clock.c | 18 ++++++++++++++++++ .../nrf52/Kconfig.defconfig.nrf52832_CIAA | 4 ++++ .../nrf52/Kconfig.defconfig.nrf52832_QFAA | 4 ++++ .../nrf52/Kconfig.defconfig.nrf52832_QFAB | 4 ++++ soc/arm/nordic_nrf/nrf52/Kconfig.soc | 18 ++++++++++++++++++ 5 files changed, 48 insertions(+) diff --git a/drivers/clock_control/nrf_power_clock.c b/drivers/clock_control/nrf_power_clock.c index 8a1befbe4df..df45a9430cb 100644 --- a/drivers/clock_control/nrf_power_clock.c +++ b/drivers/clock_control/nrf_power_clock.c @@ -228,6 +228,18 @@ static struct clock_control_async_data *list_get(sys_slist_t *list) return async_data; } +static inline void anomaly_132_workaround(void) +{ +#if (CONFIG_NRF52_ANOMALY_132_DELAY_US - 0) + static bool once; + + if (!once) { + k_busy_wait(CONFIG_NRF52_ANOMALY_132_DELAY_US); + once = true; + } +#endif +} + static int clock_async_start(struct device *dev, clock_control_subsys_t subsys, struct clock_control_async_data *data) @@ -280,6 +292,12 @@ static int clock_async_start(struct device *dev, config->start_handler(dev) : true; if (do_start) { DBG(dev, subsys, "Triggering start task"); + + if (IS_ENABLED(CONFIG_NRF52_ANOMALY_132_WORKAROUND) && + (subsys == CLOCK_CONTROL_NRF_SUBSYS_LF)) { + anomaly_132_workaround(); + } + nrf_clock_task_trigger(NRF_CLOCK, config->start_tsk); } else { diff --git a/soc/arm/nordic_nrf/nrf52/Kconfig.defconfig.nrf52832_CIAA b/soc/arm/nordic_nrf/nrf52/Kconfig.defconfig.nrf52832_CIAA index 72e192f9007..4060453badc 100644 --- a/soc/arm/nordic_nrf/nrf52/Kconfig.defconfig.nrf52832_CIAA +++ b/soc/arm/nordic_nrf/nrf52/Kconfig.defconfig.nrf52832_CIAA @@ -11,4 +11,8 @@ config SOC config NUM_IRQS default 39 +config NRF52_ANOMALY_132_WORKAROUND + bool + default y + endif # SOC_NRF52832_CIAA diff --git a/soc/arm/nordic_nrf/nrf52/Kconfig.defconfig.nrf52832_QFAA b/soc/arm/nordic_nrf/nrf52/Kconfig.defconfig.nrf52832_QFAA index 94c103267fd..cc48aaeaccb 100644 --- a/soc/arm/nordic_nrf/nrf52/Kconfig.defconfig.nrf52832_QFAA +++ b/soc/arm/nordic_nrf/nrf52/Kconfig.defconfig.nrf52832_QFAA @@ -11,4 +11,8 @@ config SOC config NUM_IRQS default 39 +config NRF52_ANOMALY_132_WORKAROUND + bool + default y + endif # SOC_NRF52832_QFAA diff --git a/soc/arm/nordic_nrf/nrf52/Kconfig.defconfig.nrf52832_QFAB b/soc/arm/nordic_nrf/nrf52/Kconfig.defconfig.nrf52832_QFAB index 67abf704346..2b9491cae3b 100644 --- a/soc/arm/nordic_nrf/nrf52/Kconfig.defconfig.nrf52832_QFAB +++ b/soc/arm/nordic_nrf/nrf52/Kconfig.defconfig.nrf52832_QFAB @@ -11,4 +11,8 @@ config SOC config NUM_IRQS default 39 +config NRF52_ANOMALY_132_WORKAROUND + bool + default y + endif # SOC_NRF52832_QFAB diff --git a/soc/arm/nordic_nrf/nrf52/Kconfig.soc b/soc/arm/nordic_nrf/nrf52/Kconfig.soc index 56ace7ed89f..ce9c3abda1e 100644 --- a/soc/arm/nordic_nrf/nrf52/Kconfig.soc +++ b/soc/arm/nordic_nrf/nrf52/Kconfig.soc @@ -361,3 +361,21 @@ config NRF_ENABLE_ICACHE bool "Enable the instruction cache (I-Cache)" depends on SOC_NRF52832 || SOC_NRF52833 || SOC_NRF52840 default y + +config NRF52_ANOMALY_132_DELAY_US + int "Anomaly 132 workaround delay (microseconds)" + default 330 + range 0 330 + depends on NRF52_ANOMALY_132_WORKAROUND + help + Due to Anomaly 132 LF RC source may not start if restarted in certain + window after stopping (230 us to 330 us). Software reset also stops the + clock so if clock is initiated in certain window, the clock may also fail + to start at reboot. A delay is added before starting LF clock to ensure + that anomaly conditions are not met. Delay should be long enough to ensure + that clock is started later than 330 us after reset. If crystal oscillator + (XO) is used then low frequency clock initially starts with RC and then + seamlessly switches to XO which has much longer startup time thus, + depending on application, workaround may also need to be applied. + Additional drivers initialization increases initialization time and delay + may be shortened. Workaround is disabled by setting delay to 0.