Commit bd412d75 authored by Łukasz Stępnicki's avatar Łukasz Stępnicki Committed by Johan Hedberg
Browse files

soc: nordic: ironside: dvfs: check abb analog status more than once

Added ABB analog status lock read retries if needed.
After cpu idle ABB macro may need some time to initialize
and report status locked. Attempts cound can be configured
using Kconfig option.

Signed-off-by: default avatarŁukasz Stępnicki <lukasz.stepnicki@nordicsemi.no>
parent 51a8cc2d
Loading
Loading
Loading
Loading
+5 −4
Changes for soc/nordic/ironside/Kconfig: 5 added lines, 4 removed lines.
Original line number Diff line number Diff line
@@ -65,11 +65,12 @@ config NRF_IRONSIDE_DVFS_SERVICE

if NRF_IRONSIDE_DVFS_SERVICE

config NRF_IRONSIDE_DVFS_OPPOINT_CHANGE_MUTEX_TIMEOUT_MS
	int "IRONSside DVFS change oppoint mutex timeout"
	default 100
config NRF_IRONSIDE_ABB_STATUSANA_CHECK_MAX_ATTEMPTS
	int "IRONSside DVFS ABB analog status check maximum attempts"
	range 0 255
	default 50
	help
	  Maximum timeout when waiting for DVFS oppoint change mutex lock.
	  Maximum attempts with 10us intervals before busy status will be reported.

endif # NRF_IRONSIDE_DVFS_SERVICE

+10 −0
Changes for soc/nordic/ironside/dvfs.c: 10 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -18,6 +18,9 @@ static enum ironside_dvfs_oppoint current_dvfs_oppoint = IRONSIDE_DVFS_OPP_HIGH;
#error "Unsupported SoC series for IronSide DVFS"
#endif

#define ABB_STATUSANA_CHECK_MAX_ATTEMPTS (CONFIG_NRF_IRONSIDE_ABB_STATUSANA_CHECK_MAX_ATTEMPTS)
#define ABB_STATUSANA_CHECK_INTERVAL_US  (10U)

struct dvfs_hsfll_data_t {
	uint32_t new_f_mult;
	uint32_t new_f_trim_entry;
@@ -129,6 +132,13 @@ static inline bool ironside_dvfs_is_abb_locked(NRF_ABB_Type *abb)
	/* Temporary workaround until STATUSANA register is visible. */
	volatile const uint32_t *statusana = (uint32_t *)abb + ABB_STATUSANA_REG_OFFSET;

	uint8_t status_read_attempts = ABB_STATUSANA_CHECK_MAX_ATTEMPTS;

	while ((*statusana & ABB_STATUSANA_LOCKED_L_Msk) == 0 && status_read_attempts > 0) {
		k_busy_wait(ABB_STATUSANA_CHECK_INTERVAL_US);
		status_read_attempts--;
	}

	return ((*statusana & ABB_STATUSANA_LOCKED_L_Msk) != 0);
}