Loading Documentation/devicetree/bindings/regulator/cpr3-regulator.txt +15 −0 Original line number Diff line number Diff line Loading @@ -517,6 +517,21 @@ Platform independent properties: regardless of the fuse combination and speed bin found on a given chip. - qcom,allow-aging-open-loop-voltage-adjustment Usage: optional Value type: <prop-encoded-array> Definition: A list of integers which specifies if CPR aging adjustment should be applied to open-loop voltages for each fuse combination. Note that aging adjustment must be allowed via qcom,allow-aging-voltage-adjustment in order for this property to have an effect. Supported per-combo element values: 0 - do not perform CPR aging adjustment 1 - perform CPR aging adjustment The list must meet the same size requirements as those specified for qcom,allow-aging-voltage-adjustment above. - qcom,cpr-aging-max-voltage-adjustment Usage: required if qcom,allow-aging-voltage-adjustment is specified Value type: <prop-encoded-array> Loading arch/arm/boot/dts/qcom/msm8996pro.dtsi +3 −0 Original line number Diff line number Diff line Loading @@ -153,6 +153,7 @@ qcom,cpr-aging-ref-corner = <14 14>; qcom,cpr-aging-ro-scaling-factor = <3200>; qcom,allow-aging-voltage-adjustment = <1>; qcom,allow-aging-open-loop-voltage-adjustment = <1>; }; &apc0_cbf_vreg { Loading Loading @@ -251,6 +252,7 @@ qcom,cpr-aging-ref-corner = <14 14>; qcom,cpr-aging-ro-scaling-factor = <3200>; qcom,allow-aging-voltage-adjustment = <1>; qcom,allow-aging-open-loop-voltage-adjustment = <1>; }; &apc1_vreg { Loading Loading @@ -375,6 +377,7 @@ qcom,cpr-aging-ref-corner = <15 15>; qcom,cpr-aging-ro-scaling-factor = <3200>; qcom,allow-aging-voltage-adjustment = <1>; qcom,allow-aging-open-loop-voltage-adjustment = <1>; qcom,cpr-dynamic-floor-corner = <1>; }; Loading drivers/regulator/cpr3-regulator.c +60 −7 Original line number Diff line number Diff line Loading @@ -3505,7 +3505,8 @@ cleanup: } /** * cpr3_regulator_readjust_quotients() - readjust the target quotients for the * cpr3_regulator_readjust_volt_and_quot() - readjust the target quotients as * well as the floor, ceiling, and open-loop voltages for the * regulator by removing the old adjustment and adding the new one * @vreg: Pointer to the CPR3 regulator * @old_adjust_volt: Old aging adjustment voltage in microvolts Loading @@ -3513,12 +3514,14 @@ cleanup: * * Also reset the cached closed loop voltage (last_volt) to equal the open-loop * voltage for each corner. * * Return: None */ static void cpr3_regulator_readjust_quotients(struct cpr3_regulator *vreg, static void cpr3_regulator_readjust_volt_and_quot(struct cpr3_regulator *vreg, int old_adjust_volt, int new_adjust_volt) { unsigned long long temp; int i, j, old_volt, new_volt; int i, j, old_volt, new_volt, rounded_volt; if (!vreg->aging_allowed) return; Loading Loading @@ -3548,14 +3551,34 @@ static void cpr3_regulator_readjust_quotients(struct cpr3_regulator *vreg, old_volt); } } rounded_volt = CPR3_ROUND(new_volt, vreg->thread->ctrl->step_volt); if (!vreg->aging_allow_open_loop_adj) rounded_volt = 0; vreg->corner[i].ceiling_volt = vreg->corner[i].unaged_ceiling_volt + rounded_volt; vreg->corner[i].ceiling_volt = min(vreg->corner[i].ceiling_volt, vreg->corner[i].abs_ceiling_volt); vreg->corner[i].floor_volt = vreg->corner[i].unaged_floor_volt + rounded_volt; vreg->corner[i].floor_volt = min(vreg->corner[i].floor_volt, vreg->corner[i].ceiling_volt); vreg->corner[i].open_loop_volt = vreg->corner[i].unaged_open_loop_volt + rounded_volt; vreg->corner[i].open_loop_volt = min(vreg->corner[i].open_loop_volt, vreg->corner[i].ceiling_volt); vreg->corner[i].last_volt = vreg->corner[i].open_loop_volt; cpr3_debug(vreg, "corner %d: applying %d uV closed-loop voltage margin adjustment\n", i, new_volt); cpr3_debug(vreg, "corner %d: applying %d uV closed-loop and %d uV open-loop voltage margin adjustment\n", i, new_volt, rounded_volt); } } /** * cpr3_regulator_set_aging_ref_adjustment() - adjust target quotients for the * regulators managed by this CPR controller to account for aging Loading @@ -3574,7 +3597,7 @@ static void cpr3_regulator_set_aging_ref_adjustment( for (i = 0; i < ctrl->thread_count; i++) { for (j = 0; j < ctrl->thread[i].vreg_count; j++) { cpr3_regulator_readjust_quotients( cpr3_regulator_readjust_volt_and_quot( &ctrl->thread[i].vreg[j], ctrl->aging_ref_adjust_volt, ref_adjust_volt); Loading Loading @@ -5587,10 +5610,13 @@ static int cpr3_regulator_init_ctrl_data(struct cpr3_controller *ctrl) static int cpr3_regulator_init_vreg_data(struct cpr3_regulator *vreg) { int i, j; bool init_aging; vreg->current_corner = CPR3_REGULATOR_CORNER_INVALID; vreg->last_closed_loop_corner = CPR3_REGULATOR_CORNER_INVALID; init_aging = vreg->aging_allowed && vreg->thread->ctrl->aging_required; for (i = 0; i < vreg->corner_count; i++) { vreg->corner[i].last_volt = vreg->corner[i].open_loop_volt; vreg->corner[i].irq_en = CPR3_IRQ_UP | CPR3_IRQ_DOWN; Loading @@ -5600,6 +5626,33 @@ static int cpr3_regulator_init_vreg_data(struct cpr3_regulator *vreg) if (vreg->corner[i].target_quot[j] == 0) vreg->corner[i].ro_mask |= BIT(j); } if (init_aging) { vreg->corner[i].unaged_floor_volt = vreg->corner[i].floor_volt; vreg->corner[i].unaged_ceiling_volt = vreg->corner[i].ceiling_volt; vreg->corner[i].unaged_open_loop_volt = vreg->corner[i].open_loop_volt; } if (vreg->aging_allowed) { if (vreg->corner[i].unaged_floor_volt <= 0) { cpr3_err(vreg, "invalid unaged_floor_volt[%d] = %d\n", i, vreg->corner[i].unaged_floor_volt); return -EINVAL; } if (vreg->corner[i].unaged_ceiling_volt <= 0) { cpr3_err(vreg, "invalid unaged_ceiling_volt[%d] = %d\n", i, vreg->corner[i].unaged_ceiling_volt); return -EINVAL; } if (vreg->corner[i].unaged_open_loop_volt <= 0) { cpr3_err(vreg, "invalid unaged_open_loop_volt[%d] = %d\n", i, vreg->corner[i].unaged_open_loop_volt); return -EINVAL; } } } if (vreg->aging_allowed && vreg->corner[vreg->aging_corner].ceiling_volt Loading drivers/regulator/cpr3-regulator.h +27 −1 Original line number Diff line number Diff line Loading @@ -100,6 +100,16 @@ struct cpr4_sdelta { * microvolts * @last_volt: Last known settled CPR closed-loop voltage which is used * when switching to a new corner * @abs_ceiling_volt: The absolute CPR closed-loop ceiling voltage in * microvolts. This is used to limit the ceiling_volt * value when it is increased as a result of aging * adjustment. * @unaged_floor_volt: The CPR closed-loop floor voltage in microvolts before * any aging adjustment is performed * @unaged_ceiling_volt: The CPR closed-loop ceiling voltage in microvolts * before any aging adjustment is performed * @unaged_open_loop_volt: The CPR open-loop voltage (i.e. initial voltage) in * microvolts before any aging adjusment is performed * @system_volt: The system-supply voltage in microvolts or corners or * levels * @mem_acc_volt: The mem-acc-supply voltage in corners Loading Loading @@ -136,7 +146,11 @@ struct cpr4_sdelta { * * The value of last_volt is initialized inside of the cpr3_regulator_register() * call with the open_loop_volt value. It can later be updated to the settled * VDD supply voltage. * VDD supply voltage. The values for unaged_floor_volt, unaged_ceiling_volt, * and unaged_open_loop_volt are initialized inside of cpr3_regulator_register() * if ctrl->aging_required == true. These three values must be pre-initialized * if cpr3_regulator_register() is called with ctrl->aging_required == false and * ctrl->aging_succeeded == true. * * The values of ro_mask and irq_en are initialized inside of the * cpr3_regulator_register() call. Loading @@ -146,6 +160,10 @@ struct cpr3_corner { int ceiling_volt; int open_loop_volt; int last_volt; int abs_ceiling_volt; int unaged_floor_volt; int unaged_ceiling_volt; int unaged_open_loop_volt; int system_volt; int mem_acc_volt; u32 proc_freq; Loading Loading @@ -269,6 +287,13 @@ struct cprh_corner_band { * @aging_allowed: Boolean defining if CPR aging adjustments are allowed * for this CPR3 regulator given the fuse combo of the * device * @aging_allow_open_loop_adj: Boolean defining if the open-loop voltage of each * corner of this regulator should be adjusted as a result * of an aging measurement. This flag can be set to false * when the open-loop voltage adjustments have been * specified such that they include the maximum possible * aging adjustment. This flag is only used if * aging_allowed == true. * @aging_corner: The corner that should be configured for this regulator * when an aging measurement is performed. * @aging_max_adjust_volt: The maximum aging voltage margin in microvolts that Loading Loading @@ -333,6 +358,7 @@ struct cpr3_regulator { bool vreg_enabled; bool aging_allowed; bool aging_allow_open_loop_adj; int aging_corner; int aging_max_adjust_volt; Loading drivers/regulator/cpr3-util.c +14 −1 Original line number Diff line number Diff line Loading @@ -695,9 +695,11 @@ int cpr3_parse_common_corner_data(struct cpr3_regulator *vreg) 1, temp); if (rc) goto free_temp; for (i = 0; i < vreg->corner_count; i++) for (i = 0; i < vreg->corner_count; i++) { vreg->corner[i].ceiling_volt = CPR3_ROUND(temp[i], ctrl->step_volt); vreg->corner[i].abs_ceiling_volt = vreg->corner[i].ceiling_volt; } rc = cpr3_parse_corner_array_property(vreg, "qcom,cpr-voltage-floor", 1, temp); Loading Loading @@ -793,6 +795,17 @@ int cpr3_parse_common_corner_data(struct cpr3_regulator *vreg) vreg->aging_allowed = aging_allowed; } if (of_find_property(vreg->of_node, "qcom,allow-aging-open-loop-voltage-adjustment", NULL)) { rc = cpr3_parse_array_property(vreg, "qcom,allow-aging-open-loop-voltage-adjustment", 1, &aging_allowed); if (rc) goto free_temp; vreg->aging_allow_open_loop_adj = aging_allowed; } if (vreg->aging_allowed) { if (ctrl->aging_ref_volt <= 0) { cpr3_err(ctrl, "qcom,cpr-aging-ref-voltage must be specified\n"); Loading Loading
Documentation/devicetree/bindings/regulator/cpr3-regulator.txt +15 −0 Original line number Diff line number Diff line Loading @@ -517,6 +517,21 @@ Platform independent properties: regardless of the fuse combination and speed bin found on a given chip. - qcom,allow-aging-open-loop-voltage-adjustment Usage: optional Value type: <prop-encoded-array> Definition: A list of integers which specifies if CPR aging adjustment should be applied to open-loop voltages for each fuse combination. Note that aging adjustment must be allowed via qcom,allow-aging-voltage-adjustment in order for this property to have an effect. Supported per-combo element values: 0 - do not perform CPR aging adjustment 1 - perform CPR aging adjustment The list must meet the same size requirements as those specified for qcom,allow-aging-voltage-adjustment above. - qcom,cpr-aging-max-voltage-adjustment Usage: required if qcom,allow-aging-voltage-adjustment is specified Value type: <prop-encoded-array> Loading
arch/arm/boot/dts/qcom/msm8996pro.dtsi +3 −0 Original line number Diff line number Diff line Loading @@ -153,6 +153,7 @@ qcom,cpr-aging-ref-corner = <14 14>; qcom,cpr-aging-ro-scaling-factor = <3200>; qcom,allow-aging-voltage-adjustment = <1>; qcom,allow-aging-open-loop-voltage-adjustment = <1>; }; &apc0_cbf_vreg { Loading Loading @@ -251,6 +252,7 @@ qcom,cpr-aging-ref-corner = <14 14>; qcom,cpr-aging-ro-scaling-factor = <3200>; qcom,allow-aging-voltage-adjustment = <1>; qcom,allow-aging-open-loop-voltage-adjustment = <1>; }; &apc1_vreg { Loading Loading @@ -375,6 +377,7 @@ qcom,cpr-aging-ref-corner = <15 15>; qcom,cpr-aging-ro-scaling-factor = <3200>; qcom,allow-aging-voltage-adjustment = <1>; qcom,allow-aging-open-loop-voltage-adjustment = <1>; qcom,cpr-dynamic-floor-corner = <1>; }; Loading
drivers/regulator/cpr3-regulator.c +60 −7 Original line number Diff line number Diff line Loading @@ -3505,7 +3505,8 @@ cleanup: } /** * cpr3_regulator_readjust_quotients() - readjust the target quotients for the * cpr3_regulator_readjust_volt_and_quot() - readjust the target quotients as * well as the floor, ceiling, and open-loop voltages for the * regulator by removing the old adjustment and adding the new one * @vreg: Pointer to the CPR3 regulator * @old_adjust_volt: Old aging adjustment voltage in microvolts Loading @@ -3513,12 +3514,14 @@ cleanup: * * Also reset the cached closed loop voltage (last_volt) to equal the open-loop * voltage for each corner. * * Return: None */ static void cpr3_regulator_readjust_quotients(struct cpr3_regulator *vreg, static void cpr3_regulator_readjust_volt_and_quot(struct cpr3_regulator *vreg, int old_adjust_volt, int new_adjust_volt) { unsigned long long temp; int i, j, old_volt, new_volt; int i, j, old_volt, new_volt, rounded_volt; if (!vreg->aging_allowed) return; Loading Loading @@ -3548,14 +3551,34 @@ static void cpr3_regulator_readjust_quotients(struct cpr3_regulator *vreg, old_volt); } } rounded_volt = CPR3_ROUND(new_volt, vreg->thread->ctrl->step_volt); if (!vreg->aging_allow_open_loop_adj) rounded_volt = 0; vreg->corner[i].ceiling_volt = vreg->corner[i].unaged_ceiling_volt + rounded_volt; vreg->corner[i].ceiling_volt = min(vreg->corner[i].ceiling_volt, vreg->corner[i].abs_ceiling_volt); vreg->corner[i].floor_volt = vreg->corner[i].unaged_floor_volt + rounded_volt; vreg->corner[i].floor_volt = min(vreg->corner[i].floor_volt, vreg->corner[i].ceiling_volt); vreg->corner[i].open_loop_volt = vreg->corner[i].unaged_open_loop_volt + rounded_volt; vreg->corner[i].open_loop_volt = min(vreg->corner[i].open_loop_volt, vreg->corner[i].ceiling_volt); vreg->corner[i].last_volt = vreg->corner[i].open_loop_volt; cpr3_debug(vreg, "corner %d: applying %d uV closed-loop voltage margin adjustment\n", i, new_volt); cpr3_debug(vreg, "corner %d: applying %d uV closed-loop and %d uV open-loop voltage margin adjustment\n", i, new_volt, rounded_volt); } } /** * cpr3_regulator_set_aging_ref_adjustment() - adjust target quotients for the * regulators managed by this CPR controller to account for aging Loading @@ -3574,7 +3597,7 @@ static void cpr3_regulator_set_aging_ref_adjustment( for (i = 0; i < ctrl->thread_count; i++) { for (j = 0; j < ctrl->thread[i].vreg_count; j++) { cpr3_regulator_readjust_quotients( cpr3_regulator_readjust_volt_and_quot( &ctrl->thread[i].vreg[j], ctrl->aging_ref_adjust_volt, ref_adjust_volt); Loading Loading @@ -5587,10 +5610,13 @@ static int cpr3_regulator_init_ctrl_data(struct cpr3_controller *ctrl) static int cpr3_regulator_init_vreg_data(struct cpr3_regulator *vreg) { int i, j; bool init_aging; vreg->current_corner = CPR3_REGULATOR_CORNER_INVALID; vreg->last_closed_loop_corner = CPR3_REGULATOR_CORNER_INVALID; init_aging = vreg->aging_allowed && vreg->thread->ctrl->aging_required; for (i = 0; i < vreg->corner_count; i++) { vreg->corner[i].last_volt = vreg->corner[i].open_loop_volt; vreg->corner[i].irq_en = CPR3_IRQ_UP | CPR3_IRQ_DOWN; Loading @@ -5600,6 +5626,33 @@ static int cpr3_regulator_init_vreg_data(struct cpr3_regulator *vreg) if (vreg->corner[i].target_quot[j] == 0) vreg->corner[i].ro_mask |= BIT(j); } if (init_aging) { vreg->corner[i].unaged_floor_volt = vreg->corner[i].floor_volt; vreg->corner[i].unaged_ceiling_volt = vreg->corner[i].ceiling_volt; vreg->corner[i].unaged_open_loop_volt = vreg->corner[i].open_loop_volt; } if (vreg->aging_allowed) { if (vreg->corner[i].unaged_floor_volt <= 0) { cpr3_err(vreg, "invalid unaged_floor_volt[%d] = %d\n", i, vreg->corner[i].unaged_floor_volt); return -EINVAL; } if (vreg->corner[i].unaged_ceiling_volt <= 0) { cpr3_err(vreg, "invalid unaged_ceiling_volt[%d] = %d\n", i, vreg->corner[i].unaged_ceiling_volt); return -EINVAL; } if (vreg->corner[i].unaged_open_loop_volt <= 0) { cpr3_err(vreg, "invalid unaged_open_loop_volt[%d] = %d\n", i, vreg->corner[i].unaged_open_loop_volt); return -EINVAL; } } } if (vreg->aging_allowed && vreg->corner[vreg->aging_corner].ceiling_volt Loading
drivers/regulator/cpr3-regulator.h +27 −1 Original line number Diff line number Diff line Loading @@ -100,6 +100,16 @@ struct cpr4_sdelta { * microvolts * @last_volt: Last known settled CPR closed-loop voltage which is used * when switching to a new corner * @abs_ceiling_volt: The absolute CPR closed-loop ceiling voltage in * microvolts. This is used to limit the ceiling_volt * value when it is increased as a result of aging * adjustment. * @unaged_floor_volt: The CPR closed-loop floor voltage in microvolts before * any aging adjustment is performed * @unaged_ceiling_volt: The CPR closed-loop ceiling voltage in microvolts * before any aging adjustment is performed * @unaged_open_loop_volt: The CPR open-loop voltage (i.e. initial voltage) in * microvolts before any aging adjusment is performed * @system_volt: The system-supply voltage in microvolts or corners or * levels * @mem_acc_volt: The mem-acc-supply voltage in corners Loading Loading @@ -136,7 +146,11 @@ struct cpr4_sdelta { * * The value of last_volt is initialized inside of the cpr3_regulator_register() * call with the open_loop_volt value. It can later be updated to the settled * VDD supply voltage. * VDD supply voltage. The values for unaged_floor_volt, unaged_ceiling_volt, * and unaged_open_loop_volt are initialized inside of cpr3_regulator_register() * if ctrl->aging_required == true. These three values must be pre-initialized * if cpr3_regulator_register() is called with ctrl->aging_required == false and * ctrl->aging_succeeded == true. * * The values of ro_mask and irq_en are initialized inside of the * cpr3_regulator_register() call. Loading @@ -146,6 +160,10 @@ struct cpr3_corner { int ceiling_volt; int open_loop_volt; int last_volt; int abs_ceiling_volt; int unaged_floor_volt; int unaged_ceiling_volt; int unaged_open_loop_volt; int system_volt; int mem_acc_volt; u32 proc_freq; Loading Loading @@ -269,6 +287,13 @@ struct cprh_corner_band { * @aging_allowed: Boolean defining if CPR aging adjustments are allowed * for this CPR3 regulator given the fuse combo of the * device * @aging_allow_open_loop_adj: Boolean defining if the open-loop voltage of each * corner of this regulator should be adjusted as a result * of an aging measurement. This flag can be set to false * when the open-loop voltage adjustments have been * specified such that they include the maximum possible * aging adjustment. This flag is only used if * aging_allowed == true. * @aging_corner: The corner that should be configured for this regulator * when an aging measurement is performed. * @aging_max_adjust_volt: The maximum aging voltage margin in microvolts that Loading Loading @@ -333,6 +358,7 @@ struct cpr3_regulator { bool vreg_enabled; bool aging_allowed; bool aging_allow_open_loop_adj; int aging_corner; int aging_max_adjust_volt; Loading
drivers/regulator/cpr3-util.c +14 −1 Original line number Diff line number Diff line Loading @@ -695,9 +695,11 @@ int cpr3_parse_common_corner_data(struct cpr3_regulator *vreg) 1, temp); if (rc) goto free_temp; for (i = 0; i < vreg->corner_count; i++) for (i = 0; i < vreg->corner_count; i++) { vreg->corner[i].ceiling_volt = CPR3_ROUND(temp[i], ctrl->step_volt); vreg->corner[i].abs_ceiling_volt = vreg->corner[i].ceiling_volt; } rc = cpr3_parse_corner_array_property(vreg, "qcom,cpr-voltage-floor", 1, temp); Loading Loading @@ -793,6 +795,17 @@ int cpr3_parse_common_corner_data(struct cpr3_regulator *vreg) vreg->aging_allowed = aging_allowed; } if (of_find_property(vreg->of_node, "qcom,allow-aging-open-loop-voltage-adjustment", NULL)) { rc = cpr3_parse_array_property(vreg, "qcom,allow-aging-open-loop-voltage-adjustment", 1, &aging_allowed); if (rc) goto free_temp; vreg->aging_allow_open_loop_adj = aging_allowed; } if (vreg->aging_allowed) { if (ctrl->aging_ref_volt <= 0) { cpr3_err(ctrl, "qcom,cpr-aging-ref-voltage must be specified\n"); Loading