diff options
author | Linux Build Service Account <lnxbuild@localhost> | 2017-01-04 03:25:38 -0800 |
---|---|---|
committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2017-01-04 03:25:37 -0800 |
commit | 8bb66a7e413624884e697d295b7e136f96209cd9 (patch) | |
tree | 14db76003eedf66b02cafa17b694b6e197b04ae5 | |
parent | 246e930ecb79fd66d864b4affd6c251e7427d0c2 (diff) | |
parent | a8af09abd17eec9aaf59b3757d1c4642d69f9451 (diff) |
Merge "regulator: cprh-kbss: add support for sdm660 kbss cpr instances"
-rw-r--r-- | Documentation/devicetree/bindings/regulator/cprh-kbss-regulator.txt | 3 | ||||
-rw-r--r-- | drivers/regulator/cprh-kbss-regulator.c | 726 |
2 files changed, 582 insertions, 147 deletions
diff --git a/Documentation/devicetree/bindings/regulator/cprh-kbss-regulator.txt b/Documentation/devicetree/bindings/regulator/cprh-kbss-regulator.txt index 5b0770785dbe..ff800352cc05 100644 --- a/Documentation/devicetree/bindings/regulator/cprh-kbss-regulator.txt +++ b/Documentation/devicetree/bindings/regulator/cprh-kbss-regulator.txt @@ -33,7 +33,8 @@ KBSS specific properties: Definition: should be one of the following: "qcom,cprh-msm8998-v1-kbss-regulator", "qcom,cprh-msm8998-v2-kbss-regulator", - "qcom,cprh-msm8998-kbss-regulator". + "qcom,cprh-msm8998-kbss-regulator", + "qcom,cprh-sdm660-kbss-regulator". If the SoC revision is not specified, then it is assumed to be the most recent revision of MSM8998, i.e. v2. diff --git a/drivers/regulator/cprh-kbss-regulator.c b/drivers/regulator/cprh-kbss-regulator.c index 9cbd1ee18ec3..0472ce13197b 100644 --- a/drivers/regulator/cprh-kbss-regulator.c +++ b/drivers/regulator/cprh-kbss-regulator.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. + * Copyright (c) 2015-2017, 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 @@ -36,9 +36,10 @@ #include "cpr3-regulator.h" #define MSM8998_KBSS_FUSE_CORNERS 4 +#define SDM660_KBSS_FUSE_CORNERS 5 /** - * struct cprh_msm8998_kbss_fuses - KBSS specific fuse data for MSM8998 + * struct cprh_kbss_fuses - KBSS specific fuse data * @ro_sel: Ring oscillator select fuse parameter value for each * fuse corner * @init_voltage: Initial (i.e. open-loop) voltage fuse parameter value @@ -59,11 +60,11 @@ * * This struct holds the values for all of the fuses read from memory. */ -struct cprh_msm8998_kbss_fuses { - u64 ro_sel[MSM8998_KBSS_FUSE_CORNERS]; - u64 init_voltage[MSM8998_KBSS_FUSE_CORNERS]; - u64 target_quot[MSM8998_KBSS_FUSE_CORNERS]; - u64 quot_offset[MSM8998_KBSS_FUSE_CORNERS]; +struct cprh_kbss_fuses { + u64 *ro_sel; + u64 *init_voltage; + u64 *target_quot; + u64 *quot_offset; u64 speed_bin; u64 cpr_fusing_rev; u64 force_highest_corner; @@ -76,7 +77,8 @@ struct cprh_msm8998_kbss_fuses { * 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. */ -#define CPRH_MSM8998_KBSS_FUSE_COMBO_COUNT 32 +#define CPRH_MSM8998_KBSS_FUSE_COMBO_COUNT 32 +#define CPRH_SDM660_KBSS_FUSE_COMBO_COUNT 16 /* * Constants which define the name of each fuse corner. @@ -95,13 +97,45 @@ static const char * const cprh_msm8998_kbss_fuse_corner_name[] = { [CPRH_MSM8998_KBSS_FUSE_CORNER_TURBO_L1] = "TURBO_L1", }; +enum cprh_sdm660_power_kbss_fuse_corner { + CPRH_SDM660_POWER_KBSS_FUSE_CORNER_LOWSVS = 0, + CPRH_SDM660_POWER_KBSS_FUSE_CORNER_SVS = 1, + CPRH_SDM660_POWER_KBSS_FUSE_CORNER_SVSPLUS = 2, + CPRH_SDM660_POWER_KBSS_FUSE_CORNER_NOM = 3, + CPRH_SDM660_POWER_KBSS_FUSE_CORNER_TURBO_L1 = 4, +}; + +static const char * const cprh_sdm660_power_kbss_fuse_corner_name[] = { + [CPRH_SDM660_POWER_KBSS_FUSE_CORNER_LOWSVS] = "LowSVS", + [CPRH_SDM660_POWER_KBSS_FUSE_CORNER_SVS] = "SVS", + [CPRH_SDM660_POWER_KBSS_FUSE_CORNER_SVSPLUS] = "SVSPLUS", + [CPRH_SDM660_POWER_KBSS_FUSE_CORNER_NOM] = "NOM", + [CPRH_SDM660_POWER_KBSS_FUSE_CORNER_TURBO_L1] = "TURBO_L1", +}; + +enum cprh_sdm660_perf_kbss_fuse_corner { + CPRH_SDM660_PERF_KBSS_FUSE_CORNER_SVS = 0, + CPRH_SDM660_PERF_KBSS_FUSE_CORNER_SVSPLUS = 1, + CPRH_SDM660_PERF_KBSS_FUSE_CORNER_NOM = 2, + CPRH_SDM660_PERF_KBSS_FUSE_CORNER_TURBO = 3, + CPRH_SDM660_PERF_KBSS_FUSE_CORNER_TURBO_L2 = 4, +}; + +static const char * const cprh_sdm660_perf_kbss_fuse_corner_name[] = { + [CPRH_SDM660_PERF_KBSS_FUSE_CORNER_SVS] = "SVS", + [CPRH_SDM660_PERF_KBSS_FUSE_CORNER_SVSPLUS] = "SVSPLUS", + [CPRH_SDM660_PERF_KBSS_FUSE_CORNER_NOM] = "NOM", + [CPRH_SDM660_PERF_KBSS_FUSE_CORNER_TURBO] = "TURBO", + [CPRH_SDM660_PERF_KBSS_FUSE_CORNER_TURBO_L2] = "TURBO_L2", +}; + /* KBSS cluster IDs */ -#define MSM8998_KBSS_POWER_CLUSTER_ID 0 -#define MSM8998_KBSS_PERFORMANCE_CLUSTER_ID 1 +#define CPRH_KBSS_POWER_CLUSTER_ID 0 +#define CPRH_KBSS_PERFORMANCE_CLUSTER_ID 1 /* KBSS controller IDs */ -#define MSM8998_KBSS_MIN_CONTROLLER_ID 0 -#define MSM8998_KBSS_MAX_CONTROLLER_ID 1 +#define CPRH_KBSS_MIN_CONTROLLER_ID 0 +#define CPRH_KBSS_MAX_CONTROLLER_ID 1 /* * MSM8998 KBSS fuse parameter locations: @@ -119,13 +153,13 @@ static const char * const cprh_msm8998_kbss_fuse_corner_name[] = { */ static const struct cpr3_fuse_param msm8998_kbss_ro_sel_param[2][MSM8998_KBSS_FUSE_CORNERS][2] = { - [MSM8998_KBSS_POWER_CLUSTER_ID] = { + [CPRH_KBSS_POWER_CLUSTER_ID] = { {{67, 12, 15}, {} }, {{67, 8, 11}, {} }, {{67, 4, 7}, {} }, {{67, 0, 3}, {} }, }, - [MSM8998_KBSS_PERFORMANCE_CLUSTER_ID] = { + [CPRH_KBSS_PERFORMANCE_CLUSTER_ID] = { {{69, 26, 29}, {} }, {{69, 22, 25}, {} }, {{69, 18, 21}, {} }, @@ -134,14 +168,32 @@ msm8998_kbss_ro_sel_param[2][MSM8998_KBSS_FUSE_CORNERS][2] = { }; static const struct cpr3_fuse_param +sdm660_kbss_ro_sel_param[2][SDM660_KBSS_FUSE_CORNERS][3] = { + [CPRH_KBSS_POWER_CLUSTER_ID] = { + {{67, 12, 15}, {} }, + {{67, 8, 11}, {} }, + {{65, 56, 59}, {} }, + {{67, 4, 7}, {} }, + {{67, 0, 3}, {} }, + }, + [CPRH_KBSS_PERFORMANCE_CLUSTER_ID] = { + {{68, 61, 63}, {69, 0, 0} }, + {{69, 1, 4}, {} }, + {{68, 57, 60}, {} }, + {{68, 53, 56}, {} }, + {{66, 14, 17}, {} }, + }, +}; + +static const struct cpr3_fuse_param msm8998_kbss_init_voltage_param[2][MSM8998_KBSS_FUSE_CORNERS][2] = { - [MSM8998_KBSS_POWER_CLUSTER_ID] = { + [CPRH_KBSS_POWER_CLUSTER_ID] = { {{67, 34, 39}, {} }, {{67, 28, 33}, {} }, {{67, 22, 27}, {} }, {{67, 16, 21}, {} }, }, - [MSM8998_KBSS_PERFORMANCE_CLUSTER_ID] = { + [CPRH_KBSS_PERFORMANCE_CLUSTER_ID] = { {{69, 48, 53}, {} }, {{69, 42, 47}, {} }, {{69, 36, 41}, {} }, @@ -150,14 +202,32 @@ msm8998_kbss_init_voltage_param[2][MSM8998_KBSS_FUSE_CORNERS][2] = { }; static const struct cpr3_fuse_param +sdm660_kbss_init_voltage_param[2][SDM660_KBSS_FUSE_CORNERS][2] = { + [CPRH_KBSS_POWER_CLUSTER_ID] = { + {{67, 34, 39}, {} }, + {{67, 28, 33}, {} }, + {{71, 3, 8}, {} }, + {{67, 22, 27}, {} }, + {{67, 16, 21}, {} }, + }, + [CPRH_KBSS_PERFORMANCE_CLUSTER_ID] = { + {{69, 17, 22}, {} }, + {{69, 23, 28}, {} }, + {{69, 11, 16}, {} }, + {{69, 5, 10}, {} }, + {{70, 42, 47}, {} }, + }, +}; + +static const struct cpr3_fuse_param msm8998_kbss_target_quot_param[2][MSM8998_KBSS_FUSE_CORNERS][3] = { - [MSM8998_KBSS_POWER_CLUSTER_ID] = { + [CPRH_KBSS_POWER_CLUSTER_ID] = { {{68, 18, 29}, {} }, {{68, 6, 17}, {} }, {{67, 58, 63}, {68, 0, 5} }, {{67, 46, 57}, {} }, }, - [MSM8998_KBSS_PERFORMANCE_CLUSTER_ID] = { + [CPRH_KBSS_PERFORMANCE_CLUSTER_ID] = { {{70, 32, 43}, {} }, {{70, 20, 31}, {} }, {{70, 8, 19}, {} }, @@ -166,14 +236,32 @@ msm8998_kbss_target_quot_param[2][MSM8998_KBSS_FUSE_CORNERS][3] = { }; static const struct cpr3_fuse_param +sdm660_kbss_target_quot_param[2][SDM660_KBSS_FUSE_CORNERS][3] = { + [CPRH_KBSS_POWER_CLUSTER_ID] = { + {{68, 12, 23}, {} }, + {{68, 0, 11}, {} }, + {{71, 9, 20}, {} }, + {{67, 52, 63}, {} }, + {{67, 40, 51}, {} }, + }, + [CPRH_KBSS_PERFORMANCE_CLUSTER_ID] = { + {{69, 53, 63}, {70, 0, 0}, {} }, + {{70, 1, 12}, {} }, + {{69, 41, 52}, {} }, + {{69, 29, 40}, {} }, + {{70, 48, 59}, {} }, + }, +}; + +static const struct cpr3_fuse_param msm8998_kbss_quot_offset_param[2][MSM8998_KBSS_FUSE_CORNERS][3] = { - [MSM8998_KBSS_POWER_CLUSTER_ID] = { + [CPRH_KBSS_POWER_CLUSTER_ID] = { {{} }, {{68, 63, 63}, {69, 0, 5}, {} }, {{68, 56, 62}, {} }, {{68, 49, 55}, {} }, }, - [MSM8998_KBSS_PERFORMANCE_CLUSTER_ID] = { + [CPRH_KBSS_PERFORMANCE_CLUSTER_ID] = { {{} }, {{71, 13, 15}, {71, 21, 24}, {} }, {{71, 6, 12}, {} }, @@ -181,12 +269,35 @@ msm8998_kbss_quot_offset_param[2][MSM8998_KBSS_FUSE_CORNERS][3] = { }, }; +static const struct cpr3_fuse_param +sdm660_kbss_quot_offset_param[2][SDM660_KBSS_FUSE_CORNERS][3] = { + [CPRH_KBSS_POWER_CLUSTER_ID] = { + {{} }, + {{68, 38, 44}, {} }, + {{71, 21, 27}, {} }, + {{68, 31, 37}, {} }, + {{68, 24, 30}, {} }, + }, + [CPRH_KBSS_PERFORMANCE_CLUSTER_ID] = { + {{} }, + {{70, 27, 33}, {} }, + {{70, 20, 26}, {} }, + {{70, 13, 19}, {} }, + {{70, 60, 63}, {71, 0, 2}, {} }, + }, +}; + static const struct cpr3_fuse_param msm8998_cpr_fusing_rev_param[] = { {39, 51, 53}, {}, }; -static const struct cpr3_fuse_param msm8998_kbss_speed_bin_param[] = { +static const struct cpr3_fuse_param sdm660_cpr_fusing_rev_param[] = { + {71, 28, 30}, + {}, +}; + +static const struct cpr3_fuse_param kbss_speed_bin_param[] = { {38, 29, 31}, {}, }; @@ -199,16 +310,28 @@ msm8998_cpr_force_highest_corner_param[] = { static const struct cpr3_fuse_param msm8998_kbss_aging_init_quot_diff_param[2][2] = { - [MSM8998_KBSS_POWER_CLUSTER_ID] = { + [CPRH_KBSS_POWER_CLUSTER_ID] = { {69, 6, 13}, {}, }, - [MSM8998_KBSS_PERFORMANCE_CLUSTER_ID] = { + [CPRH_KBSS_PERFORMANCE_CLUSTER_ID] = { {71, 25, 32}, {}, }, }; +static const struct cpr3_fuse_param +sdm660_kbss_aging_init_quot_diff_param[2][2] = { + [CPRH_KBSS_POWER_CLUSTER_ID] = { + {68, 45, 52}, + {}, + }, + [CPRH_KBSS_PERFORMANCE_CLUSTER_ID] = { + {70, 34, 41}, + {}, + }, +}; + /* * Open loop voltage fuse reference voltages in microvolts for MSM8998 v1 */ @@ -225,13 +348,13 @@ msm8998_v1_kbss_fuse_ref_volt[MSM8998_KBSS_FUSE_CORNERS] = { */ static const int msm8998_v2_kbss_fuse_ref_volt[2][MSM8998_KBSS_FUSE_CORNERS] = { - [MSM8998_KBSS_POWER_CLUSTER_ID] = { + [CPRH_KBSS_POWER_CLUSTER_ID] = { 688000, 756000, 828000, 1056000, }, - [MSM8998_KBSS_PERFORMANCE_CLUSTER_ID] = { + [CPRH_KBSS_PERFORMANCE_CLUSTER_ID] = { 756000, 756000, 828000, @@ -239,24 +362,49 @@ msm8998_v2_kbss_fuse_ref_volt[2][MSM8998_KBSS_FUSE_CORNERS] = { }, }; -#define MSM8998_KBSS_FUSE_STEP_VOLT 10000 -#define MSM8998_KBSS_VOLTAGE_FUSE_SIZE 6 -#define MSM8998_KBSS_QUOT_OFFSET_SCALE 5 -#define MSM8998_KBSS_AGING_INIT_QUOT_DIFF_SIZE 8 -#define MSM8998_KBSS_AGING_INIT_QUOT_DIFF_SCALE 1 +/* + * Open loop voltage fuse reference voltages in microvolts for SDM660 + */ +static const int +sdm660_kbss_fuse_ref_volt[2][SDM660_KBSS_FUSE_CORNERS] = { + [CPRH_KBSS_POWER_CLUSTER_ID] = { + 644000, + 724000, + 788000, + 868000, + 1068000, + }, + [CPRH_KBSS_PERFORMANCE_CLUSTER_ID] = { + 724000, + 788000, + 868000, + 988000, + 1068000, + }, +}; -#define MSM8998_KBSS_POWER_CPR_SENSOR_COUNT 6 -#define MSM8998_KBSS_PERFORMANCE_CPR_SENSOR_COUNT 9 +#define CPRH_KBSS_FUSE_STEP_VOLT 10000 +#define CPRH_KBSS_VOLTAGE_FUSE_SIZE 6 +#define CPRH_KBSS_QUOT_OFFSET_SCALE 5 +#define CPRH_KBSS_AGING_INIT_QUOT_DIFF_SIZE 8 +#define CPRH_KBSS_AGING_INIT_QUOT_DIFF_SCALE 1 -#define MSM8998_KBSS_CPR_CLOCK_RATE 19200000 +#define CPRH_KBSS_CPR_CLOCK_RATE 19200000 -#define MSM8998_KBSS_MAX_CORNER_BAND_COUNT 4 -#define MSM8998_KBSS_MAX_CORNER_COUNT 40 +#define CPRH_KBSS_MAX_CORNER_BAND_COUNT 4 +#define CPRH_KBSS_MAX_CORNER_COUNT 40 -#define MSM8998_KBSS_CPR_SDELTA_CORE_COUNT 4 +#define CPRH_KBSS_CPR_SDELTA_CORE_COUNT 4 -#define MSM8998_KBSS_MAX_TEMP_POINTS 3 -#define MSM8998_KBSS_POWER_TEMP_SENSOR_ID_START 1 +#define CPRH_KBSS_MAX_TEMP_POINTS 3 + +/* + * msm8998 configuration + */ +#define MSM8998_KBSS_POWER_CPR_SENSOR_COUNT 6 +#define MSM8998_KBSS_PERFORMANCE_CPR_SENSOR_COUNT 9 + +#define MSM8998_KBSS_POWER_TEMP_SENSOR_ID_START 1 #define MSM8998_KBSS_POWER_TEMP_SENSOR_ID_END 5 #define MSM8998_KBSS_PERFORMANCE_TEMP_SENSOR_ID_START 6 #define MSM8998_KBSS_PERFORMANCE_TEMP_SENSOR_ID_END 10 @@ -267,34 +415,49 @@ msm8998_v2_kbss_fuse_ref_volt[2][MSM8998_KBSS_FUSE_CORNERS] = { #define MSM8998_KBSS_PERFORMANCE_AGING_SENSOR_ID 0 #define MSM8998_KBSS_PERFORMANCE_AGING_BYPASS_MASK0 0 +/* + * sdm660 configuration + */ +#define SDM660_KBSS_POWER_CPR_SENSOR_COUNT 6 +#define SDM660_KBSS_PERFORMANCE_CPR_SENSOR_COUNT 9 + +#define SDM660_KBSS_POWER_TEMP_SENSOR_ID_START 10 +#define SDM660_KBSS_POWER_TEMP_SENSOR_ID_END 11 +#define SDM660_KBSS_PERFORMANCE_TEMP_SENSOR_ID_START 4 +#define SDM660_KBSS_PERFORMANCE_TEMP_SENSOR_ID_END 9 + +#define SDM660_KBSS_POWER_AGING_SENSOR_ID 0 +#define SDM660_KBSS_POWER_AGING_BYPASS_MASK0 0 + +#define SDM660_KBSS_PERFORMANCE_AGING_SENSOR_ID 0 +#define SDM660_KBSS_PERFORMANCE_AGING_BYPASS_MASK0 0 + +/* + * SOC IDs + */ +enum soc_id { + MSM8998_V1_SOC_ID = 1, + MSM8998_V2_SOC_ID = 2, + SDM660_SOC_ID = 3, +}; + /** - * cprh_msm8998_kbss_read_fuse_data() - load KBSS specific fuse parameter values + * cprh_msm8998_kbss_read_fuse_data() - load msm8998 KBSS specific fuse + * parameter values * @vreg: Pointer to the CPR3 regulator + * @fuse: KBSS specific fuse data * - * This function allocates a cprh_msm8998_kbss_fuses struct, fills it with - * values read out of hardware fuses, and finally copies common fuse values - * into the CPR3 regulator struct. + * This function fills cprh_kbss_fuses struct with values read out of hardware + * fuses. * * Return: 0 on success, errno on failure */ -static int cprh_msm8998_kbss_read_fuse_data(struct cpr3_regulator *vreg) +static int cprh_msm8998_kbss_read_fuse_data(struct cpr3_regulator *vreg, + struct cprh_kbss_fuses *fuse) { void __iomem *base = vreg->thread->ctrl->fuse_base; - struct cprh_msm8998_kbss_fuses *fuse; int i, id, rc; - fuse = devm_kzalloc(vreg->thread->ctrl->dev, sizeof(*fuse), GFP_KERNEL); - if (!fuse) - return -ENOMEM; - - rc = cpr3_read_fuse_param(base, msm8998_kbss_speed_bin_param, - &fuse->speed_bin); - if (rc) { - cpr3_err(vreg, "Unable to read speed bin fuse, rc=%d\n", rc); - return rc; - } - cpr3_info(vreg, "speed bin = %llu\n", fuse->speed_bin); - rc = cpr3_read_fuse_param(base, msm8998_cpr_fusing_rev_param, &fuse->cpr_fusing_rev); if (rc) { @@ -305,7 +468,6 @@ static int cprh_msm8998_kbss_read_fuse_data(struct cpr3_regulator *vreg) cpr3_info(vreg, "CPR fusing revision = %llu\n", fuse->cpr_fusing_rev); id = vreg->thread->ctrl->ctrl_id; - for (i = 0; i < MSM8998_KBSS_FUSE_CORNERS; i++) { rc = cpr3_read_fuse_param(base, msm8998_kbss_init_voltage_param[id][i], @@ -355,8 +517,8 @@ static int cprh_msm8998_kbss_read_fuse_data(struct cpr3_regulator *vreg) } rc = cpr3_read_fuse_param(base, - msm8998_cpr_force_highest_corner_param, - &fuse->force_highest_corner); + msm8998_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); @@ -373,9 +535,174 @@ static int cprh_msm8998_kbss_read_fuse_data(struct cpr3_regulator *vreg) return -EINVAL; } + return rc; +}; + +/** + * cprh_sdm660_kbss_read_fuse_data() - load SDM660 KBSS specific fuse parameter + * values + * @vreg: Pointer to the CPR3 regulator + * @fuse: KBSS specific fuse data + * + * This function fills cprh_kbss_fuses struct with values read out of hardware + * fuses. + * + * Return: 0 on success, errno on failure + */ +static int cprh_sdm660_kbss_read_fuse_data(struct cpr3_regulator *vreg, + struct cprh_kbss_fuses *fuse) +{ + void __iomem *base = vreg->thread->ctrl->fuse_base; + int i, id, rc; + + rc = cpr3_read_fuse_param(base, sdm660_cpr_fusing_rev_param, + &fuse->cpr_fusing_rev); + if (rc) { + cpr3_err(vreg, "Unable to read CPR fusing revision fuse, rc=%d\n", + rc); + return rc; + } + cpr3_info(vreg, "CPR fusing revision = %llu\n", fuse->cpr_fusing_rev); + + id = vreg->thread->ctrl->ctrl_id; + for (i = 0; i < SDM660_KBSS_FUSE_CORNERS; i++) { + rc = cpr3_read_fuse_param(base, + sdm660_kbss_init_voltage_param[id][i], + &fuse->init_voltage[i]); + if (rc) { + cpr3_err(vreg, "Unable to read fuse-corner %d initial voltage fuse, rc=%d\n", + i, rc); + return rc; + } + + rc = cpr3_read_fuse_param(base, + sdm660_kbss_target_quot_param[id][i], + &fuse->target_quot[i]); + if (rc) { + cpr3_err(vreg, "Unable to read fuse-corner %d target quotient fuse, rc=%d\n", + i, rc); + return rc; + } + + rc = cpr3_read_fuse_param(base, + sdm660_kbss_ro_sel_param[id][i], + &fuse->ro_sel[i]); + if (rc) { + cpr3_err(vreg, "Unable to read fuse-corner %d RO select fuse, rc=%d\n", + i, rc); + return rc; + } + + rc = cpr3_read_fuse_param(base, + sdm660_kbss_quot_offset_param[id][i], + &fuse->quot_offset[i]); + if (rc) { + cpr3_err(vreg, "Unable to read fuse-corner %d quotient offset fuse, rc=%d\n", + i, rc); + return rc; + } + } + + rc = cpr3_read_fuse_param(base, + sdm660_kbss_aging_init_quot_diff_param[id], + &fuse->aging_init_quot_diff); + if (rc) { + cpr3_err(vreg, "Unable to read aging initial quotient difference fuse, rc=%d\n", + rc); + return rc; + } + + vreg->fuse_combo = fuse->cpr_fusing_rev + 8 * fuse->speed_bin; + if (vreg->fuse_combo >= CPRH_SDM660_KBSS_FUSE_COMBO_COUNT) { + cpr3_err(vreg, "invalid CPR fuse combo = %d found\n", + vreg->fuse_combo); + return -EINVAL; + } + + return rc; +}; + +/** + * cprh_kbss_read_fuse_data() - load KBSS specific fuse parameter values + * @vreg: Pointer to the CPR3 regulator + * + * This function allocates a cprh_kbss_fuses struct, fills it with values + * read out of hardware fuses, and finally copies common fuse values + * into the CPR3 regulator struct. + * + * Return: 0 on success, errno on failure + */ +static int cprh_kbss_read_fuse_data(struct cpr3_regulator *vreg) +{ + void __iomem *base = vreg->thread->ctrl->fuse_base; + struct cprh_kbss_fuses *fuse; + int rc, fuse_corners; + enum soc_id soc_revision; + + fuse = devm_kzalloc(vreg->thread->ctrl->dev, sizeof(*fuse), GFP_KERNEL); + if (!fuse) + return -ENOMEM; + + soc_revision = vreg->thread->ctrl->soc_revision; + switch (soc_revision) { + case SDM660_SOC_ID: + fuse_corners = SDM660_KBSS_FUSE_CORNERS; + break; + case MSM8998_V1_SOC_ID: + case MSM8998_V2_SOC_ID: + fuse_corners = MSM8998_KBSS_FUSE_CORNERS; + break; + default: + cpr3_err(vreg, "unsupported soc id = %d\n", soc_revision); + return -EINVAL; + } + + fuse->ro_sel = devm_kcalloc(vreg->thread->ctrl->dev, fuse_corners, + sizeof(*fuse->ro_sel), GFP_KERNEL); + fuse->init_voltage = devm_kcalloc(vreg->thread->ctrl->dev, fuse_corners, + sizeof(*fuse->init_voltage), GFP_KERNEL); + fuse->target_quot = devm_kcalloc(vreg->thread->ctrl->dev, fuse_corners, + sizeof(*fuse->target_quot), GFP_KERNEL); + fuse->quot_offset = devm_kcalloc(vreg->thread->ctrl->dev, fuse_corners, + sizeof(*fuse->quot_offset), GFP_KERNEL); + + if (!fuse->ro_sel || !fuse->init_voltage || !fuse->target_quot + || !fuse->quot_offset) + return -ENOMEM; + + rc = cpr3_read_fuse_param(base, kbss_speed_bin_param, &fuse->speed_bin); + if (rc) { + cpr3_err(vreg, "Unable to read speed bin fuse, rc=%d\n", rc); + return rc; + } + cpr3_info(vreg, "speed bin = %llu\n", fuse->speed_bin); + + switch (soc_revision) { + case SDM660_SOC_ID: + rc = cprh_sdm660_kbss_read_fuse_data(vreg, fuse); + if (rc) { + cpr3_err(vreg, "sdm660 kbss fuse data read failed, rc=%d\n", + rc); + return rc; + } + break; + case MSM8998_V1_SOC_ID: + case MSM8998_V2_SOC_ID: + rc = cprh_msm8998_kbss_read_fuse_data(vreg, fuse); + if (rc) { + cpr3_err(vreg, "msm8998 kbss fuse data read failed, rc=%d\n", + rc); + return rc; + } + break; + default: + cpr3_err(vreg, "unsupported soc id = %d\n", soc_revision); + return -EINVAL; + } + vreg->speed_bin_fuse = fuse->speed_bin; vreg->cpr_rev_fuse = fuse->cpr_fusing_rev; - vreg->fuse_corner_count = MSM8998_KBSS_FUSE_CORNERS; + vreg->fuse_corner_count = fuse_corners; vreg->platform_fuses = fuse; return 0; @@ -399,13 +726,13 @@ static int cprh_kbss_parse_corner_data(struct cpr3_regulator *vreg) } /* - * A total of MSM8998_KBSS_MAX_CORNER_COUNT - 1 corners + * A total of CPRH_KBSS_MAX_CORNER_COUNT - 1 corners * may be specified in device tree as an additional corner * must be allocated to correspond to the APM crossover voltage. */ - if (vreg->corner_count > MSM8998_KBSS_MAX_CORNER_COUNT - 1) { + if (vreg->corner_count > CPRH_KBSS_MAX_CORNER_COUNT - 1) { cpr3_err(vreg, "corner count %d exceeds supported maximum %d\n", - vreg->corner_count, MSM8998_KBSS_MAX_CORNER_COUNT - 1); + vreg->corner_count, CPRH_KBSS_MAX_CORNER_COUNT - 1); return -EINVAL; } @@ -413,7 +740,7 @@ static int cprh_kbss_parse_corner_data(struct cpr3_regulator *vreg) } /** - * cprh_msm8998_kbss_calculate_open_loop_voltages() - calculate the open-loop + * cprh_kbss_calculate_open_loop_voltages() - calculate the open-loop * voltage for each corner of a CPR3 regulator * @vreg: Pointer to the CPR3 regulator * @@ -429,17 +756,18 @@ static int cprh_kbss_parse_corner_data(struct cpr3_regulator *vreg) * * Return: 0 on success, errno on failure */ -static int cprh_msm8998_kbss_calculate_open_loop_voltages( - struct cpr3_regulator *vreg) +static int cprh_kbss_calculate_open_loop_voltages(struct cpr3_regulator *vreg) { struct device_node *node = vreg->of_node; - struct cprh_msm8998_kbss_fuses *fuse = vreg->platform_fuses; - int i, j, soc_revision, id, rc = 0; + struct cprh_kbss_fuses *fuse = vreg->platform_fuses; + int i, j, id, rc = 0; bool allow_interpolation; u64 freq_low, volt_low, freq_high, volt_high; const int *ref_volt; int *fuse_volt; int *fmax_corner; + const char * const *corner_name; + enum soc_id soc_revision; fuse_volt = kcalloc(vreg->fuse_corner_count, sizeof(*fuse_volt), GFP_KERNEL); @@ -452,20 +780,36 @@ static int cprh_msm8998_kbss_calculate_open_loop_voltages( id = vreg->thread->ctrl->ctrl_id; soc_revision = vreg->thread->ctrl->soc_revision; - if (soc_revision == 1) + + switch (soc_revision) { + case SDM660_SOC_ID: + ref_volt = sdm660_kbss_fuse_ref_volt[id]; + if (id == CPRH_KBSS_POWER_CLUSTER_ID) + corner_name = cprh_sdm660_power_kbss_fuse_corner_name; + else + corner_name = cprh_sdm660_perf_kbss_fuse_corner_name; + break; + case MSM8998_V1_SOC_ID: ref_volt = msm8998_v1_kbss_fuse_ref_volt; - else + corner_name = cprh_msm8998_kbss_fuse_corner_name; + break; + case MSM8998_V2_SOC_ID: ref_volt = msm8998_v2_kbss_fuse_ref_volt[id]; + corner_name = cprh_msm8998_kbss_fuse_corner_name; + break; + default: + cpr3_err(vreg, "unsupported soc id = %d\n", soc_revision); + rc = -EINVAL; + goto done; + } for (i = 0; i < vreg->fuse_corner_count; i++) { - fuse_volt[i] = cpr3_convert_open_loop_voltage_fuse( - ref_volt[i], - MSM8998_KBSS_FUSE_STEP_VOLT, fuse->init_voltage[i], - MSM8998_KBSS_VOLTAGE_FUSE_SIZE); + fuse_volt[i] = cpr3_convert_open_loop_voltage_fuse(ref_volt[i], + CPRH_KBSS_FUSE_STEP_VOLT, fuse->init_voltage[i], + CPRH_KBSS_VOLTAGE_FUSE_SIZE); /* Log fused open-loop voltage values for debugging purposes. */ - cpr3_info(vreg, "fused %8s: open-loop=%7d uV\n", - cprh_msm8998_kbss_fuse_corner_name[i], + cpr3_info(vreg, "fused %8s: open-loop=%7d uV\n", corner_name[i], fuse_volt[i]); } @@ -563,7 +907,7 @@ done: */ static int cprh_msm8998_partial_binning_override(struct cpr3_regulator *vreg) { - struct cprh_msm8998_kbss_fuses *fuse = vreg->platform_fuses; + struct cprh_kbss_fuses *fuse = vreg->platform_fuses; struct cpr3_corner *corner; struct cpr4_sdelta *sdelta; int i; @@ -659,11 +1003,11 @@ static int cprh_kbss_parse_core_count_temp_adj_properties( kfree(combo_corner_bands); if (vreg->corner_band_count <= 0 || - vreg->corner_band_count > MSM8998_KBSS_MAX_CORNER_BAND_COUNT || + vreg->corner_band_count > CPRH_KBSS_MAX_CORNER_BAND_COUNT || vreg->corner_band_count > vreg->corner_count) { cpr3_err(vreg, "invalid corner band count %d > %d (max) for %d corners\n", vreg->corner_band_count, - MSM8998_KBSS_MAX_CORNER_BAND_COUNT, + CPRH_KBSS_MAX_CORNER_BAND_COUNT, vreg->corner_count); return -EINVAL; } @@ -761,9 +1105,9 @@ static int cprh_kbss_parse_core_count_temp_adj_properties( temp_point_count = len / sizeof(u32); if (temp_point_count <= 0 || temp_point_count > - MSM8998_KBSS_MAX_TEMP_POINTS) { + CPRH_KBSS_MAX_TEMP_POINTS) { cpr3_err(ctrl, "invalid number of temperature points %d > %d (max)\n", - temp_point_count, MSM8998_KBSS_MAX_TEMP_POINTS); + temp_point_count, CPRH_KBSS_MAX_TEMP_POINTS); rc = -EINVAL; goto free_temp; } @@ -811,18 +1155,35 @@ static int cprh_kbss_parse_core_count_temp_adj_properties( goto free_temp; } - ctrl->temp_sensor_id_start = ctrl->ctrl_id == - MSM8998_KBSS_POWER_CLUSTER_ID - ? MSM8998_KBSS_POWER_TEMP_SENSOR_ID_START : - MSM8998_KBSS_PERFORMANCE_TEMP_SENSOR_ID_START; - ctrl->temp_sensor_id_end = ctrl->ctrl_id == - MSM8998_KBSS_POWER_CLUSTER_ID - ? MSM8998_KBSS_PERFORMANCE_TEMP_SENSOR_ID_START : - MSM8998_KBSS_PERFORMANCE_TEMP_SENSOR_ID_END; + switch (ctrl->soc_revision) { + case SDM660_SOC_ID: + ctrl->temp_sensor_id_start = ctrl->ctrl_id == + CPRH_KBSS_POWER_CLUSTER_ID + ? SDM660_KBSS_POWER_TEMP_SENSOR_ID_START : + SDM660_KBSS_PERFORMANCE_TEMP_SENSOR_ID_START; + ctrl->temp_sensor_id_end = ctrl->ctrl_id == + CPRH_KBSS_POWER_CLUSTER_ID + ? SDM660_KBSS_POWER_TEMP_SENSOR_ID_END : + SDM660_KBSS_PERFORMANCE_TEMP_SENSOR_ID_END; + break; + case MSM8998_V1_SOC_ID: + case MSM8998_V2_SOC_ID: + ctrl->temp_sensor_id_start = ctrl->ctrl_id == + CPRH_KBSS_POWER_CLUSTER_ID + ? MSM8998_KBSS_POWER_TEMP_SENSOR_ID_START : + MSM8998_KBSS_PERFORMANCE_TEMP_SENSOR_ID_START; + ctrl->temp_sensor_id_end = ctrl->ctrl_id == + CPRH_KBSS_POWER_CLUSTER_ID + ? MSM8998_KBSS_POWER_TEMP_SENSOR_ID_END : + MSM8998_KBSS_PERFORMANCE_TEMP_SENSOR_ID_END; + break; + default: + cpr3_err(ctrl, "unsupported soc id = %d\n", ctrl->soc_revision); + rc = -EINVAL; + goto free_temp; + } ctrl->allow_temp_adj = true; - return 0; - free_temp: kfree(temp); @@ -906,8 +1267,8 @@ static int cprh_kbss_mem_acc_crossover_as_corner(struct cpr3_regulator *vreg) } /** - * cprh_msm8998_kbss_set_no_interpolation_quotients() - use the fused target - * quotient values for lower frequencies. + * cprh_kbss_set_no_interpolation_quotients() - use the fused target quotient + * values for lower frequencies. * @vreg: Pointer to the CPR3 regulator * @volt_adjust: Pointer to array of per-corner closed-loop adjustment * voltages @@ -918,11 +1279,10 @@ static int cprh_kbss_mem_acc_crossover_as_corner(struct cpr3_regulator *vreg) * * Return: 0 on success, errno on failure */ -static int cprh_msm8998_kbss_set_no_interpolation_quotients( - struct cpr3_regulator *vreg, int *volt_adjust, - int *volt_adjust_fuse, int *ro_scale) +static int cprh_kbss_set_no_interpolation_quotients(struct cpr3_regulator *vreg, + int *volt_adjust, int *volt_adjust_fuse, int *ro_scale) { - struct cprh_msm8998_kbss_fuses *fuse = vreg->platform_fuses; + struct cprh_kbss_fuses *fuse = vreg->platform_fuses; u32 quot, ro; int quot_adjust; int i, fuse_corner; @@ -949,7 +1309,7 @@ static int cprh_msm8998_kbss_set_no_interpolation_quotients( } /** - * cprh_msm8998_kbss_calculate_target_quotients() - calculate the CPR target + * cprh_kbss_calculate_target_quotients() - calculate the CPR target * quotient for each corner of a CPR3 regulator * @vreg: Pointer to the CPR3 regulator * @@ -965,10 +1325,9 @@ static int cprh_msm8998_kbss_set_no_interpolation_quotients( * * Return: 0 on success, errno on failure */ -static int cprh_msm8998_kbss_calculate_target_quotients( - struct cpr3_regulator *vreg) +static int cprh_kbss_calculate_target_quotients(struct cpr3_regulator *vreg) { - struct cprh_msm8998_kbss_fuses *fuse = vreg->platform_fuses; + struct cprh_kbss_fuses *fuse = vreg->platform_fuses; int rc; bool allow_interpolation; u64 freq_low, freq_high, prev_quot; @@ -978,18 +1337,49 @@ static int cprh_msm8998_kbss_calculate_target_quotients( int i, j, fuse_corner, quot_adjust; int *fmax_corner; int *volt_adjust, *volt_adjust_fuse, *ro_scale; + int lowest_fuse_corner, highest_fuse_corner; + const char * const *corner_name; + + switch (vreg->thread->ctrl->soc_revision) { + case SDM660_SOC_ID: + if (vreg->thread->ctrl->ctrl_id == CPRH_KBSS_POWER_CLUSTER_ID) { + corner_name = cprh_sdm660_power_kbss_fuse_corner_name; + lowest_fuse_corner = + CPRH_SDM660_POWER_KBSS_FUSE_CORNER_LOWSVS; + highest_fuse_corner = + CPRH_SDM660_POWER_KBSS_FUSE_CORNER_TURBO_L1; + } else { + corner_name = cprh_sdm660_perf_kbss_fuse_corner_name; + lowest_fuse_corner = + CPRH_SDM660_PERF_KBSS_FUSE_CORNER_SVS; + highest_fuse_corner = + CPRH_SDM660_PERF_KBSS_FUSE_CORNER_TURBO_L2; + } + break; + case MSM8998_V1_SOC_ID: + case MSM8998_V2_SOC_ID: + corner_name = cprh_msm8998_kbss_fuse_corner_name; + lowest_fuse_corner = + CPRH_MSM8998_KBSS_FUSE_CORNER_LOWSVS; + highest_fuse_corner = + CPRH_MSM8998_KBSS_FUSE_CORNER_TURBO_L1; + break; + default: + cpr3_err(vreg, "unsupported soc id = %d\n", + vreg->thread->ctrl->soc_revision); + return -EINVAL; + } /* Log fused quotient values for debugging purposes. */ - cpr3_info(vreg, "fused LowSVS: quot[%2llu]=%4llu\n", - fuse->ro_sel[CPRH_MSM8998_KBSS_FUSE_CORNER_LOWSVS], - fuse->target_quot[CPRH_MSM8998_KBSS_FUSE_CORNER_LOWSVS]); - for (i = CPRH_MSM8998_KBSS_FUSE_CORNER_SVS; - i <= CPRH_MSM8998_KBSS_FUSE_CORNER_TURBO_L1; i++) + cpr3_info(vreg, "fused %8s: quot[%2llu]=%4llu\n", + corner_name[lowest_fuse_corner], + fuse->ro_sel[lowest_fuse_corner], + fuse->target_quot[lowest_fuse_corner]); + for (i = lowest_fuse_corner + 1; i <= highest_fuse_corner; i++) cpr3_info(vreg, "fused %8s: quot[%2llu]=%4llu, quot_offset[%2llu]=%4llu\n", - cprh_msm8998_kbss_fuse_corner_name[i], - fuse->ro_sel[i], fuse->target_quot[i], + corner_name[i], fuse->ro_sel[i], fuse->target_quot[i], fuse->ro_sel[i], fuse->quot_offset[i] * - MSM8998_KBSS_QUOT_OFFSET_SCALE); + CPRH_KBSS_QUOT_OFFSET_SCALE); allow_interpolation = of_property_read_bool(vreg->of_node, "qcom,allow-quotient-interpolation"); @@ -1022,8 +1412,8 @@ static int cprh_msm8998_kbss_calculate_target_quotients( if (!allow_interpolation) { /* Use fused target quotients for lower frequencies. */ - return cprh_msm8998_kbss_set_no_interpolation_quotients( - vreg, volt_adjust, volt_adjust_fuse, ro_scale); + return cprh_kbss_set_no_interpolation_quotients(vreg, + volt_adjust, volt_adjust_fuse, ro_scale); } /* Determine highest corner mapped to each fuse corner */ @@ -1044,7 +1434,7 @@ static int cprh_msm8998_kbss_calculate_target_quotients( * Interpolation is not possible for corners mapped to the lowest fuse * corner so use the fuse corner value directly. */ - i = CPRH_MSM8998_KBSS_FUSE_CORNER_LOWSVS; + i = lowest_fuse_corner; quot_adjust = cpr3_quot_adjustment(ro_scale[i], volt_adjust_fuse[i]); quot = fuse->target_quot[i] + quot_adjust; quot_high[i] = quot_low[i] = quot; @@ -1053,19 +1443,17 @@ static int cprh_msm8998_kbss_calculate_target_quotients( cpr3_debug(vreg, "adjusted fuse corner %d RO%u target quot: %llu --> %u (%d uV)\n", i, ro, fuse->target_quot[i], quot, volt_adjust_fuse[i]); - for (i = 0; i <= fmax_corner[CPRH_MSM8998_KBSS_FUSE_CORNER_LOWSVS]; - i++) + for (i = 0; i <= fmax_corner[lowest_fuse_corner]; i++) vreg->corner[i].target_quot[ro] = quot; - for (i = CPRH_MSM8998_KBSS_FUSE_CORNER_SVS; - i < vreg->fuse_corner_count; i++) { + for (i = lowest_fuse_corner + 1; i < vreg->fuse_corner_count; i++) { quot_high[i] = fuse->target_quot[i]; if (fuse->ro_sel[i] == fuse->ro_sel[i - 1]) quot_low[i] = quot_high[i - 1]; else quot_low[i] = quot_high[i] - fuse->quot_offset[i] - * MSM8998_KBSS_QUOT_OFFSET_SCALE; + * CPRH_KBSS_QUOT_OFFSET_SCALE; if (quot_high[i] < quot_low[i]) { cpr3_debug(vreg, "quot_high[%d]=%llu < quot_low[%d]=%llu; overriding: quot_high[%d]=%llu\n", i, quot_high[i], i, quot_low[i], @@ -1203,10 +1591,10 @@ static int cprh_kbss_init_thread(struct cpr3_thread *thread) */ static int cprh_kbss_init_regulator(struct cpr3_regulator *vreg) { - struct cprh_msm8998_kbss_fuses *fuse; + struct cprh_kbss_fuses *fuse; int rc; - rc = cprh_msm8998_kbss_read_fuse_data(vreg); + rc = cprh_kbss_read_fuse_data(vreg); if (rc) { cpr3_err(vreg, "unable to read CPR fuse data, rc=%d\n", rc); return rc; @@ -1221,7 +1609,7 @@ static int cprh_kbss_init_regulator(struct cpr3_regulator *vreg) return rc; } - rc = cprh_msm8998_kbss_calculate_open_loop_voltages(vreg); + rc = cprh_kbss_calculate_open_loop_voltages(vreg); if (rc) { cpr3_err(vreg, "unable to calculate open-loop voltages, rc=%d\n", rc); @@ -1246,7 +1634,7 @@ static int cprh_kbss_init_regulator(struct cpr3_regulator *vreg) return rc; } - rc = cprh_msm8998_kbss_calculate_target_quotients(vreg); + rc = cprh_kbss_calculate_target_quotients(vreg); if (rc) { cpr3_err(vreg, "unable to calculate target quotients, rc=%d\n", rc); @@ -1269,7 +1657,7 @@ static int cprh_kbss_init_regulator(struct cpr3_regulator *vreg) if (vreg->allow_core_count_adj && (vreg->max_core_count <= 0 || vreg->max_core_count > - MSM8998_KBSS_CPR_SDELTA_CORE_COUNT)) { + CPRH_KBSS_CPR_SDELTA_CORE_COUNT)) { cpr3_err(vreg, "qcom,max-core-count has invalid value = %d\n", vreg->max_core_count); return -EINVAL; @@ -1310,10 +1698,10 @@ static int cprh_kbss_init_regulator(struct cpr3_regulator *vreg) */ static int cprh_kbss_init_aging(struct cpr3_controller *ctrl) { - struct cprh_msm8998_kbss_fuses *fuse = NULL; + struct cprh_kbss_fuses *fuse = NULL; struct cpr3_regulator *vreg; u32 aging_ro_scale; - int i, j, rc; + int i, j, rc = 0; for (i = 0; i < ctrl->thread_count; i++) { for (j = 0; j < ctrl->thread[i].vreg_count; j++) { @@ -1344,28 +1732,51 @@ static int cprh_kbss_init_aging(struct cpr3_controller *ctrl) ctrl->aging_complete_vdd_mode = REGULATOR_MODE_IDLE; ctrl->aging_sensor_count = 1; - ctrl->aging_sensor = kzalloc(sizeof(*ctrl->aging_sensor), GFP_KERNEL); + ctrl->aging_sensor = devm_kzalloc(ctrl->dev, + sizeof(*ctrl->aging_sensor), + GFP_KERNEL); if (!ctrl->aging_sensor) return -ENOMEM; - if (ctrl->ctrl_id == MSM8998_KBSS_POWER_CLUSTER_ID) { - ctrl->aging_sensor->sensor_id - = MSM8998_KBSS_POWER_AGING_SENSOR_ID; - ctrl->aging_sensor->bypass_mask[0] - = MSM8998_KBSS_POWER_AGING_BYPASS_MASK0; - } else { - ctrl->aging_sensor->sensor_id - = MSM8998_KBSS_PERFORMANCE_AGING_SENSOR_ID; - ctrl->aging_sensor->bypass_mask[0] - = MSM8998_KBSS_PERFORMANCE_AGING_BYPASS_MASK0; + switch (ctrl->soc_revision) { + case SDM660_SOC_ID: + if (ctrl->ctrl_id == CPRH_KBSS_POWER_CLUSTER_ID) { + ctrl->aging_sensor->sensor_id + = SDM660_KBSS_POWER_AGING_SENSOR_ID; + ctrl->aging_sensor->bypass_mask[0] + = SDM660_KBSS_POWER_AGING_BYPASS_MASK0; + } else { + ctrl->aging_sensor->sensor_id + = SDM660_KBSS_PERFORMANCE_AGING_SENSOR_ID; + ctrl->aging_sensor->bypass_mask[0] + = SDM660_KBSS_PERFORMANCE_AGING_BYPASS_MASK0; + } + break; + case MSM8998_V1_SOC_ID: + case MSM8998_V2_SOC_ID: + if (ctrl->ctrl_id == CPRH_KBSS_POWER_CLUSTER_ID) { + ctrl->aging_sensor->sensor_id + = MSM8998_KBSS_POWER_AGING_SENSOR_ID; + ctrl->aging_sensor->bypass_mask[0] + = MSM8998_KBSS_POWER_AGING_BYPASS_MASK0; + } else { + ctrl->aging_sensor->sensor_id + = MSM8998_KBSS_PERFORMANCE_AGING_SENSOR_ID; + ctrl->aging_sensor->bypass_mask[0] + = MSM8998_KBSS_PERFORMANCE_AGING_BYPASS_MASK0; + } + break; + default: + cpr3_err(ctrl, "unsupported soc id = %d\n", ctrl->soc_revision); + return -EINVAL; } ctrl->aging_sensor->ro_scale = aging_ro_scale; ctrl->aging_sensor->init_quot_diff = cpr3_convert_open_loop_voltage_fuse(0, - MSM8998_KBSS_AGING_INIT_QUOT_DIFF_SCALE, + CPRH_KBSS_AGING_INIT_QUOT_DIFF_SCALE, fuse->aging_init_quot_diff, - MSM8998_KBSS_AGING_INIT_QUOT_DIFF_SIZE); + CPRH_KBSS_AGING_INIT_QUOT_DIFF_SIZE); cpr3_debug(ctrl, "sensor %u aging init quotient diff = %d, aging RO scale = %u QUOT/V\n", ctrl->aging_sensor->sensor_id, @@ -1403,8 +1814,8 @@ static int cprh_kbss_init_controller(struct cpr3_controller *ctrl) return rc; } - if (ctrl->ctrl_id < MSM8998_KBSS_MIN_CONTROLLER_ID || - ctrl->ctrl_id > MSM8998_KBSS_MAX_CONTROLLER_ID) { + if (ctrl->ctrl_id < CPRH_KBSS_MIN_CONTROLLER_ID || + ctrl->ctrl_id > CPRH_KBSS_MAX_CONTROLLER_ID) { cpr3_err(ctrl, "invalid qcom,cpr-controller-id specified\n"); return -EINVAL; } @@ -1503,9 +1914,28 @@ static int cprh_kbss_init_controller(struct cpr3_controller *ctrl) "qcom,cpr-corner-switch-delay-time", &ctrl->corner_switch_delay_time); - ctrl->sensor_count = ctrl->ctrl_id == MSM8998_KBSS_POWER_CLUSTER_ID ? - MSM8998_KBSS_POWER_CPR_SENSOR_COUNT : - MSM8998_KBSS_PERFORMANCE_CPR_SENSOR_COUNT; + switch (ctrl->soc_revision) { + case SDM660_SOC_ID: + if (ctrl->ctrl_id == CPRH_KBSS_POWER_CLUSTER_ID) + ctrl->sensor_count = + SDM660_KBSS_POWER_CPR_SENSOR_COUNT; + else + ctrl->sensor_count = + SDM660_KBSS_PERFORMANCE_CPR_SENSOR_COUNT; + break; + case MSM8998_V1_SOC_ID: + case MSM8998_V2_SOC_ID: + if (ctrl->ctrl_id == CPRH_KBSS_POWER_CLUSTER_ID) + ctrl->sensor_count = + MSM8998_KBSS_POWER_CPR_SENSOR_COUNT; + else + ctrl->sensor_count = + MSM8998_KBSS_PERFORMANCE_CPR_SENSOR_COUNT; + break; + default: + cpr3_err(ctrl, "unsupported soc id = %d\n", ctrl->soc_revision); + return -EINVAL; + } /* * KBSS only has one thread (0) per controller so the zeroed @@ -1516,7 +1946,7 @@ static int cprh_kbss_init_controller(struct cpr3_controller *ctrl) if (!ctrl->sensor_owner) return -ENOMEM; - ctrl->cpr_clock_rate = MSM8998_KBSS_CPR_CLOCK_RATE; + ctrl->cpr_clock_rate = CPRH_KBSS_CPR_CLOCK_RATE; ctrl->supports_hw_closed_loop = true; ctrl->use_hw_closed_loop = of_property_read_bool(ctrl->dev->of_node, "qcom,cpr-hw-closed-loop"); @@ -1580,15 +2010,19 @@ static int cprh_kbss_regulator_resume(struct platform_device *pdev) static struct of_device_id cprh_regulator_match_table[] = { { .compatible = "qcom,cprh-msm8998-v1-kbss-regulator", - .data = (void *)(uintptr_t)1 + .data = (void *)(uintptr_t)MSM8998_V1_SOC_ID, }, { .compatible = "qcom,cprh-msm8998-v2-kbss-regulator", - .data = (void *)(uintptr_t)2 + .data = (void *)(uintptr_t)MSM8998_V2_SOC_ID, }, { .compatible = "qcom,cprh-msm8998-kbss-regulator", - .data = (void *)(uintptr_t)2 + .data = (void *)(uintptr_t)MSM8998_V2_SOC_ID, + }, + { + .compatible = "qcom,cprh-sdm660-kbss-regulator", + .data = (void *)(uintptr_t)SDM660_SOC_ID, }, {} }; |