Rex-BC Chen | 3d6816a | 2021-05-03 16:25:49 +0800 | [diff] [blame] | 1 | /* SPDX-License-Identifier: GPL-2.0-only */ |
| 2 | |
| 3 | #include <commonlib/helpers.h> |
| 4 | #include <console/console.h> |
| 5 | #include <soc/pmif_clk_common.h> |
| 6 | #include <soc/pmif_sw.h> |
| 7 | |
Rex-BC Chen | 823dcea | 2022-07-14 14:15:43 +0800 | [diff] [blame] | 8 | int pmif_ulposc_check(u32 current_clk, u32 target_clk) |
| 9 | { |
| 10 | if (current_clk < (target_clk * (1000 - CAL_TOL_RATE) / 1000) || |
| 11 | current_clk > (target_clk * (1000 + CAL_TOL_RATE) / 1000)) { |
| 12 | printk(BIOS_WARNING, |
Bo-Chen Chen | dcdbda5 | 2022-08-18 18:28:27 +0800 | [diff] [blame] | 13 | "[%s] calibration fail: cur=%dM, CAL_RATE=%d, target=%dM\n", |
Rex-BC Chen | 823dcea | 2022-07-14 14:15:43 +0800 | [diff] [blame] | 14 | __func__, current_clk, CAL_TOL_RATE, target_clk); |
| 15 | return -1; |
| 16 | } |
| 17 | |
| 18 | printk(BIOS_DEBUG, |
Bo-Chen Chen | dcdbda5 | 2022-08-18 18:28:27 +0800 | [diff] [blame] | 19 | "[%s] calibration done: cur=%dM, CAL_RATE=%d, target=%dM\n", |
Rex-BC Chen | 823dcea | 2022-07-14 14:15:43 +0800 | [diff] [blame] | 20 | __func__, current_clk, CAL_TOL_RATE, target_clk); |
| 21 | |
| 22 | return 0; |
| 23 | } |
| 24 | |
Rex-BC Chen | 3d6816a | 2021-05-03 16:25:49 +0800 | [diff] [blame] | 25 | int pmif_ulposc_cali(u32 target_val) |
| 26 | { |
| 27 | u32 current_val, min = 0, max = CAL_MAX_VAL, middle; |
| 28 | int diff_by_min, diff_by_max, cal_result; |
| 29 | |
| 30 | do { |
| 31 | middle = (min + max) / 2; |
| 32 | if (middle == min) |
| 33 | break; |
| 34 | |
| 35 | current_val = pmif_get_ulposc_freq_mhz(middle); |
| 36 | if (current_val > target_val) |
| 37 | max = middle; |
| 38 | else |
| 39 | min = middle; |
| 40 | } while (min <= max); |
| 41 | |
| 42 | diff_by_min = pmif_get_ulposc_freq_mhz(min) - target_val; |
| 43 | diff_by_min = ABS(diff_by_min); |
| 44 | |
| 45 | diff_by_max = pmif_get_ulposc_freq_mhz(max) - target_val; |
| 46 | diff_by_max = ABS(diff_by_max); |
| 47 | |
| 48 | cal_result = (diff_by_min < diff_by_max) ? min : max; |
| 49 | current_val = pmif_get_ulposc_freq_mhz(cal_result); |
| 50 | |
| 51 | /* check if calibrated value is in the range of target value +- 15% */ |
Rex-BC Chen | 823dcea | 2022-07-14 14:15:43 +0800 | [diff] [blame] | 52 | return pmif_ulposc_check(current_val, target_val); |
Rex-BC Chen | 3d6816a | 2021-05-03 16:25:49 +0800 | [diff] [blame] | 53 | } |