Skip to content

Commit 7c6f855

Browse files
bjarki-andreasencarlescufi
authored andcommitted
[nrf fromlist] drivers: clock_control nrf_lfclk: patch clock option order
The clock options used within the driver are supposed to be ordered from lowest to highest power consumption, so the lowest/default option is the most power efficient. The order was reversed to make the init code of the lfclk a bit simpler, and this was accounted for in the clock option lookup function. However, the common nrf clock control request/release feature would request the lowest index, not the lowest clock option, so the lfclk would default to its highest power consumption mode. The clock option init and lookup has been refactored to be sorted from lowest to highest power consumption, and comments have been adjusted accordingly. Upstream PR #: 99382 Signed-off-by: Bjarki Arge Andreasen <[email protected]>
1 parent 5ce544d commit 7c6f855

File tree

1 file changed

+55
-49
lines changed

1 file changed

+55
-49
lines changed

drivers/clock_control/clock_control_nrf_lfclk.c

Lines changed: 55 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -25,38 +25,25 @@ BUILD_ASSERT(DT_NUM_INST_STATUS_OKAY(DT_DRV_COMPAT) == 1,
2525
#define LFCLK_LFRC_STARTUP_TIME_US DT_INST_PROP(0, lfrc_startup_time_us)
2626

2727
#define LFCLK_MAX_OPTS 4
28-
#define LFCLK_DEF_OPTS 2
2928

3029
#define NRFS_CLOCK_TIMEOUT K_MSEC(CONFIG_CLOCK_CONTROL_NRF_LFCLK_CLOCK_TIMEOUT_MS)
3130

3231
#define BICR (NRF_BICR_Type *)DT_REG_ADDR(DT_NODELABEL(bicr))
3332

34-
/* Clock options sorted from highest to lowest power consumption.
35-
* - Clock synthesized from a high frequency clock
33+
/*
34+
* Clock options sorted from lowest to highest power consumption. If clock option
35+
* is not available it is not included.
36+
* - External sine or square wave
37+
* - XTAL low precision
38+
* - XTAL high precision
3639
* - Internal RC oscillator
37-
* - External clock. These are inserted into the list at driver initialization.
38-
* Set to one of the following:
39-
* - XTAL. Low or High precision
40-
* - External sine or square wave
40+
* - Clock synthesized from a high frequency clock
4141
*/
4242
static struct clock_options {
4343
uint16_t accuracy : 15;
4444
uint16_t precision : 1;
4545
nrfs_clock_src_t src;
46-
} clock_options[LFCLK_MAX_OPTS] = {
47-
{
48-
/* NRFS will request FLL16M use HFXO in bypass mode if SYNTH src is used */
49-
.accuracy = LFCLK_HFXO_ACCURACY,
50-
.precision = 1,
51-
.src = NRFS_CLOCK_SRC_LFCLK_SYNTH,
52-
},
53-
{
54-
.accuracy = LFCLK_LFRC_ACCURACY,
55-
.precision = 0,
56-
.src = NRFS_CLOCK_SRC_LFCLK_LFRC,
57-
},
58-
/* Remaining options are populated on lfclk_init */
59-
};
46+
} clock_options[LFCLK_MAX_OPTS];
6047

6148
struct lfclk_dev_data {
6249
STRUCT_CLOCK_CONFIG(lfclk, ARRAY_SIZE(clock_options)) clk_cfg;
@@ -161,7 +148,7 @@ static int lfclk_resolve_spec_to_idx(const struct device *dev,
161148
? dev_data->max_accuracy
162149
: req_spec->accuracy;
163150

164-
for (int i = dev_data->clock_options_cnt - 1; i >= 0; --i) {
151+
for (int i = 0; i < dev_data->clock_options_cnt; i++) {
165152
/* Iterate to a more power hungry and accurate clock source
166153
* If the requested accuracy is higher (lower ppm) than what
167154
* the clock source can provide.
@@ -331,24 +318,24 @@ static int api_get_rate_lfclk(const struct device *dev,
331318
static int lfclk_init(const struct device *dev)
332319
{
333320
struct lfclk_dev_data *dev_data = dev->data;
334-
nrf_bicr_lfosc_mode_t lfosc_mode;
335321
nrfs_err_t res;
322+
int ret;
323+
nrf_bicr_lfosc_mode_t lfosc_mode;
324+
struct clock_options *clock_option;
336325

337326
res = nrfs_clock_init(clock_evt_handler);
338327
if (res != NRFS_SUCCESS) {
339328
return -EIO;
340329
}
341330

342-
dev_data->clock_options_cnt = LFCLK_DEF_OPTS;
331+
dev_data->clock_options_cnt = 0;
343332

344333
lfosc_mode = nrf_bicr_lfosc_mode_get(BICR);
345334

346335
if (lfosc_mode == NRF_BICR_LFOSC_MODE_UNCONFIGURED ||
347336
lfosc_mode == NRF_BICR_LFOSC_MODE_DISABLED) {
348337
dev_data->max_accuracy = LFCLK_HFXO_ACCURACY;
349338
} else {
350-
int ret;
351-
352339
ret = lfosc_get_accuracy(&dev_data->max_accuracy);
353340
if (ret < 0) {
354341
LOG_ERR("LFOSC enabled with invalid accuracy");
@@ -357,34 +344,41 @@ static int lfclk_init(const struct device *dev)
357344

358345
switch (lfosc_mode) {
359346
case NRF_BICR_LFOSC_MODE_CRYSTAL:
360-
clock_options[LFCLK_MAX_OPTS - 1].accuracy = dev_data->max_accuracy;
361-
clock_options[LFCLK_MAX_OPTS - 1].precision = 0;
362-
clock_options[LFCLK_MAX_OPTS - 1].src = NRFS_CLOCK_SRC_LFCLK_XO_PIERCE;
363-
364-
clock_options[LFCLK_MAX_OPTS - 2].accuracy = dev_data->max_accuracy;
365-
clock_options[LFCLK_MAX_OPTS - 2].precision = 1;
366-
clock_options[LFCLK_MAX_OPTS - 2].src = NRFS_CLOCK_SRC_LFCLK_XO_PIERCE_HP;
367-
368-
dev_data->clock_options_cnt += 2;
347+
clock_option = &clock_options[dev_data->clock_options_cnt];
348+
clock_option->accuracy = dev_data->max_accuracy;
349+
clock_option->precision = 0;
350+
clock_option->src = NRFS_CLOCK_SRC_LFCLK_XO_PIERCE;
351+
dev_data->clock_options_cnt++;
352+
353+
clock_option = &clock_options[dev_data->clock_options_cnt];
354+
clock_option->accuracy = dev_data->max_accuracy;
355+
clock_option->precision = 1;
356+
clock_option->src = NRFS_CLOCK_SRC_LFCLK_XO_PIERCE_HP;
357+
dev_data->clock_options_cnt++;
369358
break;
370-
case NRF_BICR_LFOSC_MODE_EXTSINE:
371-
clock_options[LFCLK_MAX_OPTS - 1].accuracy = dev_data->max_accuracy;
372-
clock_options[LFCLK_MAX_OPTS - 1].precision = 0;
373-
clock_options[LFCLK_MAX_OPTS - 1].src = NRFS_CLOCK_SRC_LFCLK_XO_EXT_SINE;
374359

375-
clock_options[LFCLK_MAX_OPTS - 2].accuracy = dev_data->max_accuracy;
376-
clock_options[LFCLK_MAX_OPTS - 2].precision = 1;
377-
clock_options[LFCLK_MAX_OPTS - 2].src = NRFS_CLOCK_SRC_LFCLK_XO_EXT_SINE_HP;
378-
379-
dev_data->clock_options_cnt += 2;
360+
case NRF_BICR_LFOSC_MODE_EXTSINE:
361+
clock_option = &clock_options[dev_data->clock_options_cnt];
362+
clock_option->accuracy = dev_data->max_accuracy;
363+
clock_option->precision = 0;
364+
clock_option->src = NRFS_CLOCK_SRC_LFCLK_XO_EXT_SINE;
365+
dev_data->clock_options_cnt++;
366+
367+
clock_option = &clock_options[dev_data->clock_options_cnt];
368+
clock_option->accuracy = dev_data->max_accuracy;
369+
clock_option->precision = 1;
370+
clock_option->src = NRFS_CLOCK_SRC_LFCLK_XO_EXT_SINE_HP;
371+
dev_data->clock_options_cnt++;
380372
break;
381-
case NRF_BICR_LFOSC_MODE_EXTSQUARE:
382-
clock_options[LFCLK_MAX_OPTS - 2].accuracy = dev_data->max_accuracy;
383-
clock_options[LFCLK_MAX_OPTS - 2].precision = 0;
384-
clock_options[LFCLK_MAX_OPTS - 2].src = NRFS_CLOCK_SRC_LFCLK_XO_EXT_SQUARE;
385373

386-
dev_data->clock_options_cnt += 1;
374+
case NRF_BICR_LFOSC_MODE_EXTSQUARE:
375+
clock_option = &clock_options[dev_data->clock_options_cnt];
376+
clock_option->accuracy = dev_data->max_accuracy;
377+
clock_option->precision = 0;
378+
clock_option->src = NRFS_CLOCK_SRC_LFCLK_XO_EXT_SQUARE;
379+
dev_data->clock_options_cnt++;
387380
break;
381+
388382
default:
389383
LOG_ERR("Unexpected LFOSC mode");
390384
return -EINVAL;
@@ -398,6 +392,18 @@ static int lfclk_init(const struct device *dev)
398392
}
399393
}
400394

395+
clock_option = &clock_options[dev_data->clock_options_cnt];
396+
clock_option->accuracy = LFCLK_LFRC_ACCURACY;
397+
clock_option->precision = 0;
398+
clock_option->src = NRFS_CLOCK_SRC_LFCLK_LFRC;
399+
dev_data->clock_options_cnt++;
400+
401+
clock_option = &clock_options[dev_data->clock_options_cnt];
402+
clock_option->accuracy = LFCLK_HFXO_ACCURACY;
403+
clock_option->precision = 1;
404+
clock_option->src = NRFS_CLOCK_SRC_LFCLK_SYNTH;
405+
dev_data->clock_options_cnt++;
406+
401407
dev_data->hfxo_startup_time_us = nrf_bicr_hfxo_startup_time_us_get(BICR);
402408
if (dev_data->hfxo_startup_time_us == NRF_BICR_HFXO_STARTUP_TIME_UNCONFIGURED) {
403409
LOG_ERR("BICR HFXO startup time invalid");

0 commit comments

Comments
 (0)