1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <commonlib/helpers.h>
4 #include <console/console.h>
6 #include <soc/pmif_clk_common.h>
7 #include <soc/pmif_sw.h>
9 int pmif_ulposc_check(u32 current_clk_mhz
, u32 target_clk_mhz
)
11 if (current_clk_mhz
< (target_clk_mhz
* (1000 - CAL_TOL_RATE
) / 1000) ||
12 current_clk_mhz
> (target_clk_mhz
* (1000 + CAL_TOL_RATE
) / 1000)) {
14 "[%s] calibration fail: cur=%dM, CAL_RATE=%d, target=%dM\n",
15 __func__
, current_clk_mhz
, CAL_TOL_RATE
, target_clk_mhz
);
20 "[%s] calibration done: cur=%dM, CAL_RATE=%d, target=%dM\n",
21 __func__
, current_clk_mhz
, CAL_TOL_RATE
, target_clk_mhz
);
26 int pmif_ulposc_cali(u32 target_freq_mhz
)
28 u32 current_val
, min
= 0, max
= CAL_MAX_VAL
, middle
;
29 int diff_by_min
, diff_by_max
, cal_result
;
32 middle
= (min
+ max
) / 2;
36 current_val
= pmif_get_ulposc_freq_mhz(middle
);
37 if (current_val
> target_freq_mhz
)
43 diff_by_min
= pmif_get_ulposc_freq_mhz(min
) - target_freq_mhz
;
44 diff_by_min
= ABS(diff_by_min
);
46 diff_by_max
= pmif_get_ulposc_freq_mhz(max
) - target_freq_mhz
;
47 diff_by_max
= ABS(diff_by_max
);
49 cal_result
= (diff_by_min
< diff_by_max
) ? min
: max
;
50 current_val
= pmif_get_ulposc_freq_mhz(cal_result
);
52 /* check if calibrated value is in the range of target value +- 15% */
53 return pmif_ulposc_check(current_val
, target_freq_mhz
);