Loading Documentation/devicetree/bindings/regulator/cpr3-regulator.txt +9 −0 Original line number Diff line number Diff line Loading @@ -209,6 +209,15 @@ Platform independent properties: as the corresponding addresses are specified in the qcom,cpr-panic-reg-addr-list property. - qcom,cpr-reset-step-quot-loop-en Usage: optional; only meaningful for CPR4 and CPRh controllers Value type: <empty> Definition: Boolean value which indicates that the CPR controller should be configured to reset step_quot on each loop_en = 0 transition. This configuration allows the CPR controller to first use the default step_quot and then later switch to the run-time calibrated step_quot. ================================================= Second Level Nodes - CPR Threads for a Controller ================================================= Loading drivers/regulator/cpr3-regulator.c +28 −4 Original line number Diff line number Diff line /* * Copyright (c) 2015-2019, The Linux Foundation. All rights reserved. * Copyright (c) 2015-2020, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -174,6 +174,7 @@ #define CPR4_CPR_TIMER_CLAMP_THREAD_AGGREGATION_EN BIT(27) #define CPR4_REG_MISC 0x700 #define CPR4_MISC_RESET_STEP_QUOT_LOOP_EN BIT(2) #define CPR4_MISC_MARGIN_TABLE_ROW_SELECT_MASK GENMASK(23, 20) #define CPR4_MISC_MARGIN_TABLE_ROW_SELECT_SHIFT 20 #define CPR4_MISC_TEMP_SENSOR_ID_START_MASK GENMASK(27, 24) Loading Loading @@ -316,6 +317,12 @@ */ #define CPRH_DELTA_QUOT_STEP_FACTOR 4 /* * The multiplier applied to scaling factor value used to derive GCNT * for aging measurements. */ #define CPR3_AGING_GCNT_SCALING_UNITY 1000 static DEFINE_MUTEX(cpr3_controller_list_mutex); static LIST_HEAD(cpr3_controller_list); static struct dentry *cpr3_debugfs_base; Loading Loading @@ -698,6 +705,11 @@ static int cpr3_regulator_init_cpr4(struct cpr3_controller *ctrl) int thread_id = 0; u64 temp; if (ctrl->reset_step_quot_loop_en) cpr3_masked_write(ctrl, CPR4_REG_MISC, CPR4_MISC_RESET_STEP_QUOT_LOOP_EN, CPR4_MISC_RESET_STEP_QUOT_LOOP_EN); if (ctrl->supports_hw_closed_loop) { if (ctrl->saw_use_unit_mV) pmic_step_size = ctrl->step_volt / 1000; Loading Loading @@ -1005,7 +1017,8 @@ static int cpr3_controller_program_sdelta(struct cpr3_controller *ctrl) max_core_count << CPR4_MARGIN_ADJ_CTL_MAX_NUM_CORES_SHIFT | ((sdelta->allow_core_count_adj || sdelta->allow_boost) ? CPR4_MARGIN_ADJ_CTL_CORE_ADJ_EN : 0) | ((sdelta->allow_temp_adj && ctrl->supports_hw_closed_loop) | ((sdelta->allow_temp_adj && ctrl->supports_hw_closed_loop && sdelta->allow_core_count_adj) ? CPR4_MARGIN_ADJ_CTL_TEMP_ADJ_EN : 0) | (((ctrl->use_hw_closed_loop && !sdelta->allow_boost) || !ctrl->supports_hw_closed_loop) Loading Loading @@ -1310,6 +1323,11 @@ static int cpr3_regulator_init_cprh(struct cpr3_controller *ctrl) return rc; } if (ctrl->reset_step_quot_loop_en) cpr3_masked_write(ctrl, CPR4_REG_MISC, CPR4_MISC_RESET_STEP_QUOT_LOOP_EN, CPR4_MISC_RESET_STEP_QUOT_LOOP_EN); if (ctrl->saw_use_unit_mV) pmic_step_size = ctrl->step_volt / 1000; cpr3_masked_write(ctrl, CPR4_REG_MARGIN_ADJ_CTL, Loading Loading @@ -3098,7 +3116,8 @@ static int _cpr3_regulator_update_ctrl_state(struct cpr3_controller *ctrl) struct cpr4_sdelta *sdelta; bool valid = false; bool thread_valid; int i, j, rc, new_volt, vdd_volt, dynamic_floor_volt, last_corner_volt; int i, j, rc; int new_volt, vdd_volt, dynamic_floor_volt, last_corner_volt = 0; u32 reg_last_measurement = 0, sdelta_size; int *sdelta_table, *boost_table; Loading Loading @@ -3551,7 +3570,12 @@ static int cpr3_regulator_measure_aging(struct cpr3_controller *ctrl, gcnt0_restore = cpr3_read(ctrl, CPR3_REG_GCNT(0)); gcnt1_restore = cpr3_read(ctrl, CPR3_REG_GCNT(1)); gcnt_ref = cpr3_regulator_get_gcnt(ctrl); gcnt = gcnt_ref * 3 / 2; gcnt = gcnt_ref; if (ctrl->aging_gcnt_scaling_factor) gcnt = gcnt_ref * ctrl->aging_gcnt_scaling_factor / CPR3_AGING_GCNT_SCALING_UNITY; cpr3_write(ctrl, CPR3_REG_GCNT(0), gcnt); cpr3_write(ctrl, CPR3_REG_GCNT(1), gcnt); Loading drivers/regulator/cpr3-regulator.h +16 −1 Original line number Diff line number Diff line /* * Copyright (c) 2015-2019, The Linux Foundation. All rights reserved. * Copyright (c) 2015-2020, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -702,6 +702,13 @@ struct cpr3_panic_regs_info { * @aging_possible_val: Optional value that the masked aging_possible_reg * register must have in order for a CPR aging measurement * to be possible. * @aging_gcnt_scaling_factor: The scaling factor used to derive the gate count * used for aging measurements. This value is divided by * 1000 when used as shown in the below equation: * Aging_GCNT = GCNT_REF * scaling_factor / 1000. * For example, a value of 1500 specifies that the gate * count (GCNT) used for aging measurement should be 1.5 * times of reference gate count (GCNT_REF). * @step_quot_fixed: Fixed step quotient value used for target quotient * adjustment if use_dynamic_step_quot is not set. * This parameter is only relevant for CPR4 controllers Loading Loading @@ -735,6 +742,12 @@ struct cpr3_panic_regs_info { * @panic_notifier: Notifier block registered to global panic notifier list. * @support_ldo300_vreg: Boolean value which indicates that this CPR controller * manages an underlying LDO regulator of type LDO300. * @reset_step_quot_loop_en: Boolean value which indicates that this CPR * controller should be configured to reset step_quot on * each loop_en = 0 transition. This configuration allows * the CPR controller to first use the default step_quot * and then later switch to the run-time calibrated * step_quot. * * This structure contains both configuration and runtime state data. The * elements cpr_allowed_sw, use_hw_closed_loop, aggr_corner, cpr_enabled, Loading Loading @@ -821,6 +834,7 @@ struct cpr3_controller { int aging_sensor_count; u32 aging_possible_mask; u32 aging_possible_val; u32 aging_gcnt_scaling_factor; u32 step_quot_fixed; u32 initial_temp_band; Loading @@ -836,6 +850,7 @@ struct cpr3_controller { struct cpr3_panic_regs_info *panic_regs_info; struct notifier_block panic_notifier; bool support_ldo300_vreg; bool reset_step_quot_loop_en; }; /* Used for rounding voltages to the closest physically available set point. */ Loading drivers/regulator/cpr3-util.c +8 −0 Original line number Diff line number Diff line Loading @@ -1220,6 +1220,14 @@ int cpr3_parse_common_ctrl_data(struct cpr3_controller *ctrl) return -ENODEV; } /* * Reset step_quot to default on each loop_en = 0 transition is * optional. */ ctrl->reset_step_quot_loop_en = of_property_read_bool(ctrl->dev->of_node, "qcom,cpr-reset-step-quot-loop-en"); /* * Regulator device handles are not necessary for CPRh controllers * since communication with the regulators is completely managed Loading drivers/regulator/cprh-kbss-regulator.c +15 −3 Original line number Diff line number Diff line /* * Copyright (c) 2015-2019, The Linux Foundation. All rights reserved. * Copyright (c) 2015-2020, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -76,9 +76,10 @@ struct cprh_kbss_fuses { * Fuse combos 8 - 15 map to CPR fusing revision 0 - 7 with speed bin fuse = 1. * Fuse combos 16 - 23 map to CPR fusing revision 0 - 7 with speed bin fuse = 2. * Fuse combos 24 - 31 map to CPR fusing revision 0 - 7 with speed bin fuse = 3. * Fuse combos 32 - 39 map to CPR fusing revision 0 - 7 with speed bin fuse = 4. */ #define CPRH_MSM8998_KBSS_FUSE_COMBO_COUNT 32 #define CPRH_SDM660_KBSS_FUSE_COMBO_COUNT 16 #define CPRH_SDM660_KBSS_FUSE_COMBO_COUNT 40 /* * Constants which define the name of each fuse corner. Loading Loading @@ -808,6 +809,12 @@ static int cprh_kbss_calculate_open_loop_voltages(struct cpr3_regulator *vreg) CPRH_KBSS_FUSE_STEP_VOLT, fuse->init_voltage[i], CPRH_KBSS_VOLTAGE_FUSE_SIZE); /* SDM660 speed bin #3 does not support TURBO_L1/L2 */ if (soc_revision == SDM660_SOC_ID && vreg->speed_bin_fuse == 3 && (id == CPRH_KBSS_PERFORMANCE_CLUSTER_ID) && (i == CPRH_SDM660_PERF_KBSS_FUSE_CORNER_TURBO_L2)) continue; /* Log fused open-loop voltage values for debugging purposes. */ cpr3_info(vreg, "fused %8s: open-loop=%7d uV\n", corner_name[i], fuse_volt[i]); Loading Loading @@ -1354,6 +1361,11 @@ static int cprh_kbss_calculate_target_quotients(struct cpr3_regulator *vreg) CPRH_SDM660_PERF_KBSS_FUSE_CORNER_SVS; highest_fuse_corner = CPRH_SDM660_PERF_KBSS_FUSE_CORNER_TURBO_L2; /* speed-bin 3 does not have Turbo_L2 fuse */ if (vreg->speed_bin_fuse == 3) highest_fuse_corner = CPRH_SDM660_PERF_KBSS_FUSE_CORNER_TURBO; } break; case MSM8998_V1_SOC_ID: Loading Loading @@ -1699,7 +1711,7 @@ static int cprh_kbss_init_regulator(struct cpr3_regulator *vreg) static int cprh_kbss_init_aging(struct cpr3_controller *ctrl) { struct cprh_kbss_fuses *fuse = NULL; struct cpr3_regulator *vreg; struct cpr3_regulator *vreg = NULL; u32 aging_ro_scale; int i, j, rc = 0; Loading Loading
Documentation/devicetree/bindings/regulator/cpr3-regulator.txt +9 −0 Original line number Diff line number Diff line Loading @@ -209,6 +209,15 @@ Platform independent properties: as the corresponding addresses are specified in the qcom,cpr-panic-reg-addr-list property. - qcom,cpr-reset-step-quot-loop-en Usage: optional; only meaningful for CPR4 and CPRh controllers Value type: <empty> Definition: Boolean value which indicates that the CPR controller should be configured to reset step_quot on each loop_en = 0 transition. This configuration allows the CPR controller to first use the default step_quot and then later switch to the run-time calibrated step_quot. ================================================= Second Level Nodes - CPR Threads for a Controller ================================================= Loading
drivers/regulator/cpr3-regulator.c +28 −4 Original line number Diff line number Diff line /* * Copyright (c) 2015-2019, The Linux Foundation. All rights reserved. * Copyright (c) 2015-2020, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -174,6 +174,7 @@ #define CPR4_CPR_TIMER_CLAMP_THREAD_AGGREGATION_EN BIT(27) #define CPR4_REG_MISC 0x700 #define CPR4_MISC_RESET_STEP_QUOT_LOOP_EN BIT(2) #define CPR4_MISC_MARGIN_TABLE_ROW_SELECT_MASK GENMASK(23, 20) #define CPR4_MISC_MARGIN_TABLE_ROW_SELECT_SHIFT 20 #define CPR4_MISC_TEMP_SENSOR_ID_START_MASK GENMASK(27, 24) Loading Loading @@ -316,6 +317,12 @@ */ #define CPRH_DELTA_QUOT_STEP_FACTOR 4 /* * The multiplier applied to scaling factor value used to derive GCNT * for aging measurements. */ #define CPR3_AGING_GCNT_SCALING_UNITY 1000 static DEFINE_MUTEX(cpr3_controller_list_mutex); static LIST_HEAD(cpr3_controller_list); static struct dentry *cpr3_debugfs_base; Loading Loading @@ -698,6 +705,11 @@ static int cpr3_regulator_init_cpr4(struct cpr3_controller *ctrl) int thread_id = 0; u64 temp; if (ctrl->reset_step_quot_loop_en) cpr3_masked_write(ctrl, CPR4_REG_MISC, CPR4_MISC_RESET_STEP_QUOT_LOOP_EN, CPR4_MISC_RESET_STEP_QUOT_LOOP_EN); if (ctrl->supports_hw_closed_loop) { if (ctrl->saw_use_unit_mV) pmic_step_size = ctrl->step_volt / 1000; Loading Loading @@ -1005,7 +1017,8 @@ static int cpr3_controller_program_sdelta(struct cpr3_controller *ctrl) max_core_count << CPR4_MARGIN_ADJ_CTL_MAX_NUM_CORES_SHIFT | ((sdelta->allow_core_count_adj || sdelta->allow_boost) ? CPR4_MARGIN_ADJ_CTL_CORE_ADJ_EN : 0) | ((sdelta->allow_temp_adj && ctrl->supports_hw_closed_loop) | ((sdelta->allow_temp_adj && ctrl->supports_hw_closed_loop && sdelta->allow_core_count_adj) ? CPR4_MARGIN_ADJ_CTL_TEMP_ADJ_EN : 0) | (((ctrl->use_hw_closed_loop && !sdelta->allow_boost) || !ctrl->supports_hw_closed_loop) Loading Loading @@ -1310,6 +1323,11 @@ static int cpr3_regulator_init_cprh(struct cpr3_controller *ctrl) return rc; } if (ctrl->reset_step_quot_loop_en) cpr3_masked_write(ctrl, CPR4_REG_MISC, CPR4_MISC_RESET_STEP_QUOT_LOOP_EN, CPR4_MISC_RESET_STEP_QUOT_LOOP_EN); if (ctrl->saw_use_unit_mV) pmic_step_size = ctrl->step_volt / 1000; cpr3_masked_write(ctrl, CPR4_REG_MARGIN_ADJ_CTL, Loading Loading @@ -3098,7 +3116,8 @@ static int _cpr3_regulator_update_ctrl_state(struct cpr3_controller *ctrl) struct cpr4_sdelta *sdelta; bool valid = false; bool thread_valid; int i, j, rc, new_volt, vdd_volt, dynamic_floor_volt, last_corner_volt; int i, j, rc; int new_volt, vdd_volt, dynamic_floor_volt, last_corner_volt = 0; u32 reg_last_measurement = 0, sdelta_size; int *sdelta_table, *boost_table; Loading Loading @@ -3551,7 +3570,12 @@ static int cpr3_regulator_measure_aging(struct cpr3_controller *ctrl, gcnt0_restore = cpr3_read(ctrl, CPR3_REG_GCNT(0)); gcnt1_restore = cpr3_read(ctrl, CPR3_REG_GCNT(1)); gcnt_ref = cpr3_regulator_get_gcnt(ctrl); gcnt = gcnt_ref * 3 / 2; gcnt = gcnt_ref; if (ctrl->aging_gcnt_scaling_factor) gcnt = gcnt_ref * ctrl->aging_gcnt_scaling_factor / CPR3_AGING_GCNT_SCALING_UNITY; cpr3_write(ctrl, CPR3_REG_GCNT(0), gcnt); cpr3_write(ctrl, CPR3_REG_GCNT(1), gcnt); Loading
drivers/regulator/cpr3-regulator.h +16 −1 Original line number Diff line number Diff line /* * Copyright (c) 2015-2019, The Linux Foundation. All rights reserved. * Copyright (c) 2015-2020, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -702,6 +702,13 @@ struct cpr3_panic_regs_info { * @aging_possible_val: Optional value that the masked aging_possible_reg * register must have in order for a CPR aging measurement * to be possible. * @aging_gcnt_scaling_factor: The scaling factor used to derive the gate count * used for aging measurements. This value is divided by * 1000 when used as shown in the below equation: * Aging_GCNT = GCNT_REF * scaling_factor / 1000. * For example, a value of 1500 specifies that the gate * count (GCNT) used for aging measurement should be 1.5 * times of reference gate count (GCNT_REF). * @step_quot_fixed: Fixed step quotient value used for target quotient * adjustment if use_dynamic_step_quot is not set. * This parameter is only relevant for CPR4 controllers Loading Loading @@ -735,6 +742,12 @@ struct cpr3_panic_regs_info { * @panic_notifier: Notifier block registered to global panic notifier list. * @support_ldo300_vreg: Boolean value which indicates that this CPR controller * manages an underlying LDO regulator of type LDO300. * @reset_step_quot_loop_en: Boolean value which indicates that this CPR * controller should be configured to reset step_quot on * each loop_en = 0 transition. This configuration allows * the CPR controller to first use the default step_quot * and then later switch to the run-time calibrated * step_quot. * * This structure contains both configuration and runtime state data. The * elements cpr_allowed_sw, use_hw_closed_loop, aggr_corner, cpr_enabled, Loading Loading @@ -821,6 +834,7 @@ struct cpr3_controller { int aging_sensor_count; u32 aging_possible_mask; u32 aging_possible_val; u32 aging_gcnt_scaling_factor; u32 step_quot_fixed; u32 initial_temp_band; Loading @@ -836,6 +850,7 @@ struct cpr3_controller { struct cpr3_panic_regs_info *panic_regs_info; struct notifier_block panic_notifier; bool support_ldo300_vreg; bool reset_step_quot_loop_en; }; /* Used for rounding voltages to the closest physically available set point. */ Loading
drivers/regulator/cpr3-util.c +8 −0 Original line number Diff line number Diff line Loading @@ -1220,6 +1220,14 @@ int cpr3_parse_common_ctrl_data(struct cpr3_controller *ctrl) return -ENODEV; } /* * Reset step_quot to default on each loop_en = 0 transition is * optional. */ ctrl->reset_step_quot_loop_en = of_property_read_bool(ctrl->dev->of_node, "qcom,cpr-reset-step-quot-loop-en"); /* * Regulator device handles are not necessary for CPRh controllers * since communication with the regulators is completely managed Loading
drivers/regulator/cprh-kbss-regulator.c +15 −3 Original line number Diff line number Diff line /* * Copyright (c) 2015-2019, The Linux Foundation. All rights reserved. * Copyright (c) 2015-2020, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -76,9 +76,10 @@ struct cprh_kbss_fuses { * Fuse combos 8 - 15 map to CPR fusing revision 0 - 7 with speed bin fuse = 1. * Fuse combos 16 - 23 map to CPR fusing revision 0 - 7 with speed bin fuse = 2. * Fuse combos 24 - 31 map to CPR fusing revision 0 - 7 with speed bin fuse = 3. * Fuse combos 32 - 39 map to CPR fusing revision 0 - 7 with speed bin fuse = 4. */ #define CPRH_MSM8998_KBSS_FUSE_COMBO_COUNT 32 #define CPRH_SDM660_KBSS_FUSE_COMBO_COUNT 16 #define CPRH_SDM660_KBSS_FUSE_COMBO_COUNT 40 /* * Constants which define the name of each fuse corner. Loading Loading @@ -808,6 +809,12 @@ static int cprh_kbss_calculate_open_loop_voltages(struct cpr3_regulator *vreg) CPRH_KBSS_FUSE_STEP_VOLT, fuse->init_voltage[i], CPRH_KBSS_VOLTAGE_FUSE_SIZE); /* SDM660 speed bin #3 does not support TURBO_L1/L2 */ if (soc_revision == SDM660_SOC_ID && vreg->speed_bin_fuse == 3 && (id == CPRH_KBSS_PERFORMANCE_CLUSTER_ID) && (i == CPRH_SDM660_PERF_KBSS_FUSE_CORNER_TURBO_L2)) continue; /* Log fused open-loop voltage values for debugging purposes. */ cpr3_info(vreg, "fused %8s: open-loop=%7d uV\n", corner_name[i], fuse_volt[i]); Loading Loading @@ -1354,6 +1361,11 @@ static int cprh_kbss_calculate_target_quotients(struct cpr3_regulator *vreg) CPRH_SDM660_PERF_KBSS_FUSE_CORNER_SVS; highest_fuse_corner = CPRH_SDM660_PERF_KBSS_FUSE_CORNER_TURBO_L2; /* speed-bin 3 does not have Turbo_L2 fuse */ if (vreg->speed_bin_fuse == 3) highest_fuse_corner = CPRH_SDM660_PERF_KBSS_FUSE_CORNER_TURBO; } break; case MSM8998_V1_SOC_ID: Loading Loading @@ -1699,7 +1711,7 @@ static int cprh_kbss_init_regulator(struct cpr3_regulator *vreg) static int cprh_kbss_init_aging(struct cpr3_controller *ctrl) { struct cprh_kbss_fuses *fuse = NULL; struct cpr3_regulator *vreg; struct cpr3_regulator *vreg = NULL; u32 aging_ro_scale; int i, j, rc = 0; Loading