msm: avs: Restore core voltage when disabling AVS
AVS changes the core voltage to match the current operating conditions
on the part. Not all frequencies supported by the target have characterized
AVS delay synthesizer (AVSDSCR) values. For frequencies that do not have
AVSDSCR set, AVS is not enabled and so need to operate at the
characterized voltage for that frequency. Disabling AVS does not
however, restore the operating voltage to the value the rail was
configured to. This may cause frequencies that do not have AVSDSCR to
run at lower voltage than prescibed.
Set up the core voltage back to the last known good value when disabling
AVS.
Change-Id: I5389996288fa49e45c469d2a8917e00900261de7
CRs-fixed: 457772
Signed-off-by: Praveen Chidambaram <pchidamb@codeaurora.org>
Signed-off-by: Anji Jonnala <anjir@codeaurora.org>
diff --git a/arch/arm/mach-msm/avs.c b/arch/arm/mach-msm/avs.c
index aa257ef..b2185e3 100644
--- a/arch/arm/mach-msm/avs.c
+++ b/arch/arm/mach-msm/avs.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2013, 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
@@ -16,6 +16,7 @@
#include <asm/mach-types.h>
#include <asm/cputype.h>
#include "avs.h"
+#include "spm.h"
u32 avs_get_avscsr(void)
{
@@ -72,7 +73,10 @@
static void avs_disable_local(void *data)
{
+ int cpu = smp_processor_id();
+
avs_set_avscsr(0);
+ msm_spm_set_vdd(cpu, msm_spm_get_vdd(cpu));
}
void avs_enable(int cpu, u32 avsdscr)
diff --git a/arch/arm/mach-msm/spm_devices.c b/arch/arm/mach-msm/spm_devices.c
index 5cca411..3391dfd 100644
--- a/arch/arm/mach-msm/spm_devices.c
+++ b/arch/arm/mach-msm/spm_devices.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2013, 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,6 +36,7 @@
struct msm_spm_driver_data reg_data;
struct msm_spm_power_modes *modes;
uint32_t num_modes;
+ uint32_t cpu_vdd;
};
struct msm_spm_vdd_info {
@@ -54,6 +55,7 @@
struct msm_spm_vdd_info *info = (struct msm_spm_vdd_info *)data;
dev = &per_cpu(msm_cpu_spm_device, info->cpu);
+ dev->cpu_vdd = info->vlevel;
info->err = msm_spm_drv_set_vdd(&dev->reg_data, info->vlevel);
}
@@ -96,7 +98,7 @@
struct msm_spm_device *dev;
dev = &per_cpu(msm_cpu_spm_device, cpu);
- return msm_spm_drv_get_sts_curr_pmic_data(&dev->reg_data);
+ return dev->cpu_vdd;
}
EXPORT_SYMBOL(msm_spm_get_vdd);