@@ -32,10 +32,29 @@ enum spm_reg {
SPM_REG_SEQ_ENTRY,
SPM_REG_SPM_STS,
SPM_REG_PMIC_STS,
+ SPM_REG_AVS_CTL,
+ SPM_REG_AVS_LIMIT,
SPM_REG_NR,
};
-static const u8 spm_reg_offset_v2_1[SPM_REG_NR] = {
+static const u16 spm_reg_offset_v4_1[SPM_REG_NR] = {
+ [SPM_REG_AVS_CTL] = 0x904,
+ [SPM_REG_AVS_LIMIT] = 0x908,
+};
+
+static const struct spm_reg_data spm_reg_660_gold_l2 = {
+ .reg_offset = spm_reg_offset_v4_1,
+ .avs_ctl = 0x1010031,
+ .avs_limit = 0x4580458,
+};
+
+static const struct spm_reg_data spm_reg_660_silver_l2 = {
+ .reg_offset = spm_reg_offset_v4_1,
+ .avs_ctl = 0x101c031,
+ .avs_limit = 0x4580458,
+};
+
+static const u16 spm_reg_offset_v2_1[SPM_REG_NR] = {
[SPM_REG_CFG] = 0x08,
[SPM_REG_SPM_CTL] = 0x30,
[SPM_REG_DLY] = 0x34,
@@ -54,7 +73,7 @@ static const struct spm_reg_data spm_reg_8974_8084_cpu = {
.start_index[PM_SLEEP_MODE_SPC] = 3,
};
-static const u8 spm_reg_offset_v1_1[SPM_REG_NR] = {
+static const u16 spm_reg_offset_v1_1[SPM_REG_NR] = {
[SPM_REG_CFG] = 0x08,
[SPM_REG_SPM_CTL] = 0x20,
[SPM_REG_PMIC_DLY] = 0x24,
@@ -126,6 +145,10 @@ void spm_set_low_power_mode(struct spm_driver_data *drv,
}
static const struct of_device_id spm_match_table[] = {
+ { .compatible = "qcom,sdm660-gold-saw2-v4.1-l2",
+ .data = &spm_reg_660_gold_l2 },
+ { .compatible = "qcom,sdm660-silver-saw2-v4.1-l2",
+ .data = &spm_reg_660_silver_l2 },
{ .compatible = "qcom,msm8974-saw2-v2.1-cpu",
.data = &spm_reg_8974_8084_cpu },
{ .compatible = "qcom,apq8084-saw2-v2.1-cpu",
@@ -169,6 +192,8 @@ static int spm_dev_probe(struct platform_device *pdev)
* CPU was held in reset, the reset signal could trigger the SPM state
* machine, before the sequences are completely written.
*/
+ spm_register_write(drv, SPM_REG_AVS_CTL, drv->reg_data->avs_ctl);
+ spm_register_write(drv, SPM_REG_AVS_LIMIT, drv->reg_data->avs_limit);
spm_register_write(drv, SPM_REG_CFG, drv->reg_data->spm_cfg);
spm_register_write(drv, SPM_REG_DLY, drv->reg_data->spm_dly);
spm_register_write(drv, SPM_REG_PMIC_DLY, drv->reg_data->pmic_dly);
@@ -178,7 +203,8 @@ static int spm_dev_probe(struct platform_device *pdev)
drv->reg_data->pmic_data[1]);
/* Set up Standby as the default low power mode */
- spm_set_low_power_mode(drv, PM_SLEEP_MODE_STBY);
+ if (drv->reg_data->reg_offset[SPM_REG_SPM_CTL])
+ spm_set_low_power_mode(drv, PM_SLEEP_MODE_STBY);
return 0;
}
@@ -21,11 +21,13 @@ enum pm_sleep_mode {
};
struct spm_reg_data {
- const u8 *reg_offset;
+ const u16 *reg_offset;
u32 spm_cfg;
u32 spm_dly;
u32 pmic_dly;
u32 pmic_data[MAX_PMIC_DATA];
+ u32 avs_ctl;
+ u32 avs_limit;
u8 seq[MAX_SEQ_DATA];
u8 start_index[PM_SLEEP_MODE_NR];
};
Implement the support for SAW v4.1, used in at least MSM8998, SDM630, SDM660 and APQ variants and, while at it, also add the configuration for the SDM630/660 Silver and Gold cluster L2 Adaptive Voltage Scaler: this is also one of the prerequisites to allow the OSM controller to perform DCVS. Please note that despite there are various "versions" of these values downstream, these are the only ones that are perfectly stable on the entire set of tested devices. Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@somainline.org> --- drivers/soc/qcom/spm.c | 32 +++++++++++++++++++++++++++++--- include/soc/qcom/spm.h | 4 +++- 2 files changed, 32 insertions(+), 4 deletions(-)