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