From e8cea36bf89cb28fb4e96de51200cf59fb1a2a6a Mon Sep 17 00:00:00 2001 From: David Collins Date: Wed, 3 Aug 2016 15:25:03 -0700 Subject: regulator: cpr3-mmss-regulator: update msmcobalt partial binning Update the algorithm applied to open-loop voltage partial binning values so that it only affects the lowest two fused corners (i.e. MinSVS and SVS). These values correspond to valid voltages for the highest two fused corners (i.e. Nominal and Turbo). Change-Id: Ifa54325a1364f10b6f1760c52ad029612114759c CRs-Fixed: 1050071 Signed-off-by: David Collins --- drivers/regulator/cpr3-mmss-regulator.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/drivers/regulator/cpr3-mmss-regulator.c b/drivers/regulator/cpr3-mmss-regulator.c index e5055708a871..f2a1f6730228 100644 --- a/drivers/regulator/cpr3-mmss-regulator.c +++ b/drivers/regulator/cpr3-mmss-regulator.c @@ -243,6 +243,12 @@ enum msmcobalt_cpr_partial_binning { MSMCOBALT_CPR_PARTIAL_BINNING_SAFE_CORNER = 0xE, }; +/* + * The partial binning open-loop voltage fuse values only apply to the lowest + * two fuse corners (0 and 1, i.e. MinSVS and SVS). + */ +#define MSMCOBALT_CPR_PARTIAL_BINNING_MAX_FUSE_CORNER 1 + /** * cpr3_msm8996_mmss_read_fuse_data() - load MMSS specific fuse parameter values * @vreg: Pointer to the CPR3 regulator @@ -738,7 +744,8 @@ static int cpr3_msm8996_mmss_calculate_open_loop_voltages( */ if (is_msmcobalt && (volt_init == MSMCOBALT_CPR_PARTIAL_BINNING_NEXT_CORNER || - volt_init == MSMCOBALT_CPR_PARTIAL_BINNING_SAFE_CORNER)) + volt_init == MSMCOBALT_CPR_PARTIAL_BINNING_SAFE_CORNER) && + i <= MSMCOBALT_CPR_PARTIAL_BINNING_MAX_FUSE_CORNER) volt_init = MSM8996_MMSS_MIN_VOLTAGE_FUSE_VAL; fuse_volt[i] = cpr3_convert_open_loop_voltage_fuse(ref_volt[i], @@ -849,19 +856,25 @@ static int cpr3_msmcobalt_partial_binning_override(struct cpr3_regulator *vreg) u32 proc_freq; struct cpr3_corner *corner; struct cpr3_corner *safe_corner; - int i, j, low, high, safe_fuse_corner; + int i, j, low, high, safe_fuse_corner, max_fuse_corner; if (vreg->thread->ctrl->soc_revision != MSMCOBALT_SOC_ID) return 0; - /* Loop over all fuse corners except for the highest one. */ - for (i = 0; i < vreg->fuse_corner_count - 1; i++) { + /* + * Allow up to the max corner which can be fused with partial + * binning values. + */ + max_fuse_corner = min(MSMCOBALT_CPR_PARTIAL_BINNING_MAX_FUSE_CORNER, + vreg->fuse_corner_count - 2); + + for (i = 0; i <= max_fuse_corner; i++) { /* Determine which higher corners to override with (if any). */ if (fuse->init_voltage[i] != next && fuse->init_voltage[i] != safe) continue; - for (j = i + 1; j < vreg->fuse_corner_count - 1; j++) + for (j = i + 1; j <= max_fuse_corner; j++) if (fuse->init_voltage[j] != next && fuse->init_voltage[j] != safe) break; -- cgit v1.2.3 From e239c7f54120117e66141983e770bffc4b161cf2 Mon Sep 17 00:00:00 2001 From: David Collins Date: Wed, 3 Aug 2016 16:17:42 -0700 Subject: regulator: cpr3-mmss-regulator: add support for force highest corner fuse Add support for the MSMCOBALT force highest corner fuse. This fuse is set on parts which can only operate consistently when the highest corner's voltage is applied to all of the lower corners. Change-Id: Ibeef761044deea375dc7684c0a160609b610b8f6 CRs-Fixed: 1050071 Signed-off-by: David Collins --- drivers/regulator/cpr3-mmss-regulator.c | 41 +++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/drivers/regulator/cpr3-mmss-regulator.c b/drivers/regulator/cpr3-mmss-regulator.c index f2a1f6730228..232bcf8fcf31 100644 --- a/drivers/regulator/cpr3-mmss-regulator.c +++ b/drivers/regulator/cpr3-mmss-regulator.c @@ -50,6 +50,9 @@ * @limitation: CPR limitation select fuse parameter value * @aging_init_quot_diff: Initial quotient difference between CPR aging * min and max sensors measured at time of manufacturing + * @force_highest_corner: Flag indicating that all corners must operate + * at the voltage of the highest corner. This is + * applicable to MSMCOBALT only. * * This struct holds the values for all of the fuses read from memory. */ @@ -60,6 +63,7 @@ struct cpr3_msm8996_mmss_fuses { u64 cpr_fusing_rev; u64 limitation; u64 aging_init_quot_diff; + u64 force_highest_corner; }; /* Fuse combos 0 - 7 map to CPR fusing revision 0 - 7 */ @@ -158,6 +162,12 @@ msmcobalt_mmss_offset_voltage_param[MSM8996_MMSS_FUSE_CORNERS][2] = { {{65, 44, 47}, {} }, }; +static const struct cpr3_fuse_param +msmcobalt_cpr_force_highest_corner_param[] = { + {100, 45, 45}, + {}, +}; + #define MSM8996PRO_SOC_ID 4 #define MSMCOBALT_SOC_ID 5 @@ -343,6 +353,19 @@ static int cpr3_msm8996_mmss_read_fuse_data(struct cpr3_regulator *vreg) } } + if (vreg->thread->ctrl->soc_revision == MSMCOBALT_SOC_ID) { + rc = cpr3_read_fuse_param(base, + msmcobalt_cpr_force_highest_corner_param, + &fuse->force_highest_corner); + if (rc) { + cpr3_err(vreg, "Unable to read CPR force highest corner fuse, rc=%d\n", + rc); + return rc; + } + if (fuse->force_highest_corner) + cpr3_info(vreg, "Fusing requires all operation at the highest corner\n"); + } + if (vreg->thread->ctrl->soc_revision == MSMCOBALT_SOC_ID) { combo_max = CPR3_MSMCOBALT_MMSS_FUSE_COMBO_COUNT; vreg->fuse_combo = fuse->cpr_fusing_rev; @@ -861,6 +884,24 @@ static int cpr3_msmcobalt_partial_binning_override(struct cpr3_regulator *vreg) if (vreg->thread->ctrl->soc_revision != MSMCOBALT_SOC_ID) return 0; + /* Handle the force highest corner fuse. */ + if (fuse->force_highest_corner) { + cpr3_info(vreg, "overriding CPR parameters for corners 0 to %d with quotients and voltages of corner %d\n", + vreg->corner_count - 2, vreg->corner_count - 1); + corner = &vreg->corner[vreg->corner_count - 1]; + for (i = 0; i < vreg->corner_count - 1; i++) { + proc_freq = vreg->corner[i].proc_freq; + vreg->corner[i] = *corner; + vreg->corner[i].proc_freq = proc_freq; + } + + /* + * Return since the potential partial binning fuse values are + * superceded by the force highest corner fuse value. + */ + return 0; + } + /* * Allow up to the max corner which can be fused with partial * binning values. -- cgit v1.2.3 From 0388b2a99fb03fee205e3819e7cc0db204c0cb54 Mon Sep 17 00:00:00 2001 From: David Collins Date: Wed, 3 Aug 2016 16:26:38 -0700 Subject: ARM: dts: msm: increase VDD_GFX CPR ceiling voltages for msmcobalt Hardware characterization has shown that some parts require higher voltages in order to operate consistently. Increase the ceiling voltage for all corners so that they are able to operate at higher voltages. This applies to all CPR revisions except 0. Change-Id: Ie9d4e825e5c6040036642cdaf22d1f67b6129685 CRs-Fixed: 1050071 Signed-off-by: David Collins --- arch/arm/boot/dts/qcom/msmcobalt-regulator.dtsi | 28 ++++++++++++------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/arch/arm/boot/dts/qcom/msmcobalt-regulator.dtsi b/arch/arm/boot/dts/qcom/msmcobalt-regulator.dtsi index 5833b30d1fd1..9f8ecea15568 100644 --- a/arch/arm/boot/dts/qcom/msmcobalt-regulator.dtsi +++ b/arch/arm/boot/dts/qcom/msmcobalt-regulator.dtsi @@ -944,20 +944,20 @@ qcom,cpr-voltage-ceiling = <896000 896000 896000 896000 896000 1032000>, - <632000 696000 768000 828000 896000 - 1032000>, - <632000 696000 768000 828000 896000 - 1032000>, - <632000 696000 768000 828000 896000 - 1032000>, - <632000 696000 768000 828000 896000 - 1032000>, - <632000 696000 768000 828000 896000 - 1032000>, - <632000 696000 768000 828000 896000 - 1032000>, - <632000 696000 768000 828000 896000 - 1032000>; + <672000 740000 800000 868000 976000 + 1100000>, + <672000 740000 800000 868000 976000 + 1100000>, + <672000 740000 800000 868000 976000 + 1100000>, + <672000 740000 800000 868000 976000 + 1100000>, + <672000 740000 800000 868000 976000 + 1100000>, + <672000 740000 800000 868000 976000 + 1100000>, + <672000 740000 800000 868000 976000 + 1100000>; qcom,cpr-voltage-floor = <896000 896000 896000 896000 896000 -- cgit v1.2.3