1 /*
2 * Copyright (c) 2024 Nordic Semiconductor ASA
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include "dvfs_oppoint.h"
8 #include <nrfs_config.h>
9 #include <zephyr/kernel.h>
10
11 #define MOVE_AND_MASK_32(x, mask, move) (((uint32_t)(x) << move) & (uint32_t)mask)
12
13 #if !NRFS_UNIT_TESTS_ENABLED && NRF_SECURE
14
15 /* TODO: Use MDK when HM-21530 is fixed */
16 #define ABB_TRIM_LOCKRANGE_LOCKRANGELOWN_Pos_L \
17 (0UL) /*!< Position of LOCKRANGELOWN field. */
18 #define ABB_TRIM_LOCKRANGE_LOCKRANGELOWN_Msk_L (0xFFUL << ABB_TRIM_LOCKRANGE_LOCKRANGELOWN_Pos_L)
19
20 #define ABB_TRIM_LOCKRANGE_LOCKRANGEHIGHN_Pos_L \
21 (8UL) /*!< Position of LOCKRANGEHIGHN field. */
22 #define ABB_TRIM_LOCKRANGE_LOCKRANGEHIGHN_Msk_L (0xFFUL << ABB_TRIM_LOCKRANGE_LOCKRANGEHIGHN_Pos_L)
23
24 #define ABB_TRIM_LOCKRANGE_LOCKRANGELOWP_Pos_L \
25 (16UL) /*!< Position of LOCKRANGELOWP field. */
26 #define ABB_TRIM_LOCKRANGE_LOCKRANGELOWP_Msk_L (0xFFUL << ABB_TRIM_LOCKRANGE_LOCKRANGELOWP_Pos_L)
27
28 #define ABB_TRIM_LOCKRANGE_LOCKRANGEHIGHP_Pos_L \
29 (24UL) /*!< Position of LOCKRANGEHIGHP field. */
30 #define ABB_TRIM_LOCKRANGE_LOCKRANGEHIGHP_Msk_L (0xFFUL << ABB_TRIM_LOCKRANGE_LOCKRANGEHIGHP_Pos_L)
31
32 #define ABB_LOCKRANGE(low_n, high_n, low_p, high_p) \
33 (MOVE_AND_MASK_32((low_n), \
34 (ABB_TRIM_LOCKRANGE_LOCKRANGELOWN_Msk_L), \
35 (ABB_TRIM_LOCKRANGE_LOCKRANGELOWN_Pos_L)) | \
36 MOVE_AND_MASK_32((high_n), \
37 (ABB_TRIM_LOCKRANGE_LOCKRANGEHIGHN_Msk_L), \
38 (ABB_TRIM_LOCKRANGE_LOCKRANGEHIGHN_Pos_L)) | \
39 MOVE_AND_MASK_32((low_p), \
40 (ABB_TRIM_LOCKRANGE_LOCKRANGELOWP_Msk_L), \
41 (ABB_TRIM_LOCKRANGE_LOCKRANGELOWP_Pos_L)) | \
42 MOVE_AND_MASK_32((high_p), \
43 (ABB_TRIM_LOCKRANGE_LOCKRANGEHIGHP_Msk_L), \
44 (ABB_TRIM_LOCKRANGE_LOCKRANGEHIGHP_Pos_L)))
45
46 #define ABB_RINGO(ringo_target_n, ringo_target_p) \
47 (MOVE_AND_MASK_32((ringo_target_n), \
48 (ABB_TRIM_RINGO_RINGOTARGETVALN_Msk), \
49 (ABB_TRIM_RINGO_RINGOTARGETVALN_Pos)) | \
50 MOVE_AND_MASK_32((ringo_target_p), \
51 (ABB_TRIM_RINGO_RINGOTARGETVALP_Msk), \
52 (ABB_TRIM_RINGO_RINGOTARGETVALP_Pos)))
53 #else
54 #define ABB_LOCKRANGE(low_n, high_n, low_p, high_p) (0)
55 #define ABB_RINGO(ringo_target_n, ringo_target_p) (0)
56 #endif
57
58 static const struct dvfs_oppoint_data dvfs_oppoints_data[DVFS_FREQ_COUNT] = {
59 /* ABB oppoint 0.8V */
60 {
61 .freq_setting = DVFS_FREQ_HIGH,
62 .opp_mv = DVFS_HIGH_OPPOINT_MV,
63 .abb_ringo = ABB_RINGO(524, 519),
64 .abb_lockrange = ABB_LOCKRANGE(105, 202, 102, 211),
65 .abb_pvtmoncycles = 2,
66 .new_f_mult = 20,
67 .new_f_trim_entry = 0,
68 .max_hsfll_freq = 320,
69 },
70 /* ABB oppoint 0.6V */
71 {
72 .freq_setting = DVFS_FREQ_MEDLOW,
73 .opp_mv = DVFS_MEDLOW_OPPOINT_MV,
74 .abb_ringo = ABB_RINGO(424, 389),
75 .abb_lockrange = ABB_LOCKRANGE(75, 168, 65, 176),
76 .abb_pvtmoncycles = 4,
77 .new_f_mult = 8,
78 .new_f_trim_entry = 5,
79 .max_hsfll_freq = 128,
80 },
81 /* ABB oppoint 0.5V */
82 {
83 .freq_setting = DVFS_FREQ_LOW,
84 .opp_mv = DVFS_LOW_OPPOINT_MV,
85 .abb_ringo = ABB_RINGO(471, 414),
86 .abb_lockrange = ABB_LOCKRANGE(73, 206, 60, 203),
87 .abb_pvtmoncycles = 9,
88 .new_f_mult = 4,
89 .new_f_trim_entry = 3,
90 .max_hsfll_freq = 64,
91 },
92 };
93
get_dvfs_oppoint_data(enum dvfs_frequency_setting oppoint)94 const struct dvfs_oppoint_data *get_dvfs_oppoint_data(enum dvfs_frequency_setting oppoint)
95 {
96 if (oppoint >= DVFS_FREQ_COUNT) {
97 return &dvfs_oppoints_data[DVFS_FREQ_COUNT - 1];
98 }
99
100 return &dvfs_oppoints_data[oppoint];
101 }
102
get_frequency_for_frequency_setting(enum dvfs_frequency_setting freq_setting)103 uint16_t get_frequency_for_frequency_setting(enum dvfs_frequency_setting freq_setting)
104 {
105 return dvfs_oppoints_data[freq_setting].max_hsfll_freq;
106 }
107