msm: dcvs: rearrange platform data.

This change
-removes the use of group id and instead introduces core type
-rearranges platform data, adds energy curve coefficients and power
 parameters
-allow for the energy params to be -ve numbers

The change also mandates updates to the msm8974-gpu.dtsi and the
associated binding documentation.

Also take this opportunity to remove devices for unsupported platform
- 8930 and 8960

Signed-off-by: Abhijeet Dharmapurikar <adharmap@codeaurora.org>
(cherry picked from commit 4445166ad16be0c45b077bfb10487de355ed2e05)

Signed-off-by: Ram Kumar Chakravarthy Chebathini <rcheba@codeaurora.org>
(cherry picked from commit 24d2351f6a5e7069e5d554dbc999280a69288c5d)

Change-Id: I5c65c0e65cc7652eee72c525f0db10e128061cf9
Signed-off-by: Sudhir Sharma <sudsha@codeaurora.org>
diff --git a/Documentation/devicetree/bindings/arm/msm/dcvs-core-info.txt b/Documentation/devicetree/bindings/arm/msm/dcvs-core-info.txt
index a39356c..5b4d3cf 100644
--- a/Documentation/devicetree/bindings/arm/msm/dcvs-core-info.txt
+++ b/Documentation/devicetree/bindings/arm/msm/dcvs-core-info.txt
@@ -5,74 +5,135 @@
 
 Required properties:
 
-- qcom,core-max-time-us:	Maximum time limit in micorseconds for switching clock rate.
-				Limited to this value if switching time takes longer than this limit. Typical value is 100000.
-- qcom,algo-slack-time-us:	Time in microseconds after which the QoS guarantee will kick in
-				and the clock rate will increased as necessary. Typical value is about 30000.
-- qcom,algo-disable-pc-threshold:	If core frequency (kHz) is higher than this value, power collapse is disallowed. Set to 0 for GPU.
-- qcom,algo-ss-window-size:	Steady state window size in microseconds.
-- qcom,algo-ss-util-pct:	When determining the steady state level, this percentage value is used to provide headroom
-				from the utilized cpu to the selected level.
-- qcom,algo-ee-max-util-pct:	When determining the level with the lowest energy, any level that exceeds this busy
-				percentage, for the measured work in the last window, is disqualified for performance reasons.
-- qcom,algo-ss-iobusy-conv:	Used to convert correlation time into assumed IO Busy time, which is removed
-				from measured elapsed time when computing cpu utilization.
+- qcom,core-core-type:	indicates whether this core is a CPU(0) or a GPU(1)
 
+- qcom,algo-disable-pc-threshold:	sets highest frequency at which DCVS
+					will allow the CPU to power collapse.
+- qcom,algo-em-win-size-min-us:		sets minimum Energy Minimization(EM)
+					window size.
+- qcom,algo-em-win-size-max-us:		sets maximum EM window size.
+- qcom,algo-em-max-util-pct:		sets maximum CPU utilization that will
+					not be exceeded by any core when
+					MP-decision decides the number of
+					online cores.
+- qcom,algo-group-id:			specifies a group index of a core.
+- qcom,algo-max-freq-chg-time-us:	shows time taken for the most recent
+					frequency change.
+- qcom,algo-slack-mode-dynamic:	 	specifies if dynamic slack mode is
+					enabled or not.
+- qcom,algo-slack-weight-thresh-pct:	sets occurrence percentage of CPU
+					activity that will make slack timer
+					triggered.
+- qcom,algo-slack-time-min-us:		specifies the slack time that slack
+					timer would be set if the current clock
+					frequency is zero.
+- qcom,algo-slack-time-max-us:		sets maximum slack timer value to be
+					used by slack timer.
+- qcom,algo-ss-win-size-min-us:		sets minimum steady state window size.
+- qcom,algo-ss-win-size-max-us:		sets maximum steady state window size.
+- qcom,algo-ss-util-pct:		sets target CPU utilization during
+					steady-state.
+- qcom,algo-ss-iobusy-conv:		specifies how wait time (i/o busy time)
+					is incorporated into the steady-state
+					algorithm.
+
+- qcom,energy-active-coeff-a:	sets active power equation coefficient a.
+- qcom,energy-active-coeff-b:	sets active power equation coefficient b.
+- qcom,energy-active-coeff-c:	sets active power equation coefficient c.
+- qcom,energy-leakage-coeff-a:	sets leakage power equation coefficient a.
+- qcom,energy-leakage-coeff-b:	sets leakage power equation coefficient b.
+- qcom,energy-leakage-coeff-c:	sets leakage power equation coefficient c.
+- qcom,energy-leakage-coeff-d:	sets leakage power equation coefficient d.
+
+- qcom,power-current-temp:	the current temperature in degCelcius.
+- qcom,power-num-freq:		the number of freq this core supports.
 
 A number of frequency levels are represented as sub-nodes:
 
 required properties:
 - reg:			The index of the frequency entry
 - qcom,freq		The frequency of the DVS entry (in kHZ)
-- qcom,idle-energy: 	The idle energy cost of the entry (in micro watts)
-- qcom,active-energy:	The active energy cost of the entry (in micro watts)
+- qcom,is_trans_level	This frequency is transient step for DCVS
+- qcom,active-energy-offset:	The active energy cost of the entry
+- qcom,leakage-energy-offset: 	The leakage energy cost of the entry
 
 Sample:
 
 qcom,kgsl-3d0@fdb00000 {
 	...
-	qcom,dcvs-core-info {
-		#address-cells = <1>;
-		#size-cells = <0>;
+		qcom,dcvs-core-info {
+			#address-cells = <1>;
+			#size-cells = <0>;
 
-		compatible = "qcom,dcvs-core-info";
+			compatible = "qcom,dcvs-core-info";
 
-		qcom,core-max-time-us = <100000>;
-		qcom,algo-slack-time-us = <39000>;
-		qcom,algo-disable-pc-threshold = <86000>;
-		qcom,algo-ss-window-size = <1000000>;
-		qcom,algo-ss-util-pct = <95>;
-		qcom,algo-em-max-util-pct = <97>;
-		qcom,algo-ss-iobusy-conv = <100>;
+			qcom,num_cores = <1>;
+			qcom,sensors = <0>;
 
-		qcom,dcvs-freq@0 {
-			reg = <0>;
-			qcom,freq = <0>;
-			qcom,idle-energy = <0>;
-			qcom,active-energy = <333932>;
+			qcom,core-core-type = <1>;
+
+			qcom,algo-disable-pc-threshold = <0>;
+			qcom,algo-em-win-size-min-us = <100000>;
+			qcom,algo-em-win-size-max-us = <300000>;
+			qcom,algo-em-max-util-pct = <97>;
+			qcom,algo-group-id = <95>;
+			qcom,algo-max-freq-chg-time-us = <100000>;
+			qcom,algo-slack-mode-dynamic = <100000>;
+			qcom,algo-slack-weight-thresh-pct = <0>;
+			qcom,algo-slack-time-min-us = <39000>;
+			qcom,algo-slack-time-max-us = <39000>;
+			qcom,algo-ss-win-size-min-us = <1000000>;
+			qcom,algo-ss-win-size-max-us = <1000000>;
+			qcom,algo-ss-util-pct = <95>;
+			qcom,algo-ss-iobusy-conv = <100>;
+
+			qcom,energy-active-coeff-a = <2492>;
+			qcom,energy-active-coeff-b = <0>;
+			qcom,energy-active-coeff-c = <0>;
+			qcom,energy-leakage-coeff-a = <11>;
+			qcom,energy-leakage-coeff-b = <157150>;
+			qcom,energy-leakage-coeff-c = <0>;
+			qcom,energy-leakage-coeff-d = <0>;
+
+			qcom,power-current-temp = <25>;
+			qcom,power-num-freq = <4>;
+
+			qcom,dcvs-freq@0 {
+				reg = <0>;
+				qcom,freq = <0>;
+				qcom,voltage = <0>;
+				qcom,is_trans_level = <0>;
+				qcom,active-energy-offset = <100>;
+				qcom,leakage-energy-offset = <0>;
+			};
+
+			qcom,dcvs-freq@1 {
+				reg = <1>;
+				qcom,freq = <0>;
+				qcom,voltage = <0>;
+				qcom,is_trans_level = <0>;
+				qcom,active-energy-offset = <100>;
+				qcom,leakage-energy-offset = <0>;
+			};
+
+			qcom,dcvs-freq@2 {
+				reg = <2>;
+				qcom,freq = <0>;
+				qcom,voltage = <0>;
+				qcom,is_trans_level = <0>;
+				qcom,active-energy-offset = <100>;
+				qcom,leakage-energy-offset = <0>;
+			};
+
+			qcom,dcvs-freq@3 {
+				reg = <3>;
+				qcom,freq = <0>;
+				qcom,voltage = <0>;
+				qcom,is_trans_level = <0>;
+				qcom,active-energy-offset = <844545>;
+				qcom,leakage-energy-offset = <0>;
+			};
 		};
-
-		qcom,dcvs-freq@1 {
-			reg = <1>;
-			qcom,freq = <0>;
-			qcom,idle-energy = <0>;
-			qcom,active-energy = <497532>;
-		};
-
-		qcom,dcvs-freq@2 {
-			reg = <2>;
-			qcom,freq = <0>;
-			qcom,idle-energy = <0>;
-			qcom,active-energy = <707610>;
-		};
-
-		qcom,dcvs-freq@3 {
-			reg = <3>;
-			qcom,freq = <0>;
-			qcom,idle-energy = <0>;
-			qcom,active-energy = <844545>;
-		};
-	};
 	...
 };
 
diff --git a/arch/arm/boot/dts/msm8974-gpu.dtsi b/arch/arm/boot/dts/msm8974-gpu.dtsi
index a972d7f..88eeb33 100644
--- a/arch/arm/boot/dts/msm8974-gpu.dtsi
+++ b/arch/arm/boot/dts/msm8974-gpu.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, 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
@@ -85,40 +85,68 @@
 
 			compatible = "qcom,dcvs-core-info";
 
-			qcom,core-max-time-us = <100000>;
-			qcom,algo-slack-time-us = <39000>;
-			qcom,algo-disable-pc-threshold = <86000>;
-			qcom,algo-ss-window-size = <1000000>;
-			qcom,algo-ss-util-pct = <95>;
+			qcom,core-core-type = <1>;
+
+			qcom,algo-disable-pc-threshold = <0>;
+			qcom,algo-em-win-size-min-us = <100000>;
+			qcom,algo-em-win-size-max-us = <300000>;
 			qcom,algo-em-max-util-pct = <97>;
+			qcom,algo-group-id = <95>;
+			qcom,algo-max-freq-chg-time-us = <100000>;
+			qcom,algo-slack-mode-dynamic = <100000>;
+			qcom,algo-slack-weight-thresh-pct = <0>;
+			qcom,algo-slack-time-min-us = <39000>;
+			qcom,algo-slack-time-max-us = <39000>;
+			qcom,algo-ss-win-size-min-us = <1000000>;
+			qcom,algo-ss-win-size-max-us = <1000000>;
+			qcom,algo-ss-util-pct = <95>;
 			qcom,algo-ss-iobusy-conv = <100>;
 
+			qcom,energy-active-coeff-a = <2492>;
+			qcom,energy-active-coeff-b = <0>;
+			qcom,energy-active-coeff-c = <0>;
+			qcom,energy-leakage-coeff-a = <11>;
+			qcom,energy-leakage-coeff-b = <157150>;
+			qcom,energy-leakage-coeff-c = <0>;
+			qcom,energy-leakage-coeff-d = <0>;
+
+			qcom,power-current-temp = <25>;
+			qcom,power-num-freq = <4>;
+
 			qcom,dcvs-freq@0 {
 				reg = <0>;
 				qcom,freq = <0>;
-				qcom,idle-energy = <0>;
-				qcom,active-energy = <333932>;
+				qcom,voltage = <0>;
+				qcom,is_trans_level = <0>;
+				qcom,active-energy-offset = <100>;
+				qcom,leakage-energy-offset = <0>;
 			};
 
 			qcom,dcvs-freq@1 {
 				reg = <1>;
 				qcom,freq = <0>;
-				qcom,idle-energy = <0>;
-				qcom,active-energy = <497532>;
+				qcom,voltage = <0>;
+				qcom,is_trans_level = <0>;
+				qcom,active-energy-offset = <100>;
+				qcom,leakage-energy-offset = <0>;
 			};
 
 			qcom,dcvs-freq@2 {
 				reg = <2>;
 				qcom,freq = <0>;
-				qcom,idle-energy = <0>;
-				qcom,active-energy = <707610>;
+				qcom,voltage = <0>;
+				qcom,is_trans_level = <0>;
+				qcom,active-energy-offset = <100>;
+				qcom,leakage-energy-offset = <0>;
 			};
 
 			qcom,dcvs-freq@3 {
 				reg = <3>;
 				qcom,freq = <0>;
-				qcom,idle-energy = <0>;
-				qcom,active-energy = <844545>;
+				qcom,voltage = <0>;
+				qcom,is_trans_level = <0>;
+				qcom,active-energy-offset = <844545>;
+				qcom,leakage-energy-offset = <0>;
 			};
 		};
 
diff --git a/arch/arm/mach-msm/board-8064-gpu.c b/arch/arm/mach-msm/board-8064-gpu.c
index 122505e..26d4c27 100644
--- a/arch/arm/mach-msm/board-8064-gpu.c
+++ b/arch/arm/mach-msm/board-8064-gpu.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, 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
@@ -24,26 +24,49 @@
 
 #ifdef CONFIG_MSM_DCVS
 static struct msm_dcvs_freq_entry grp3d_freq[] = {
-	{0, 0, 333932},
-	{0, 0, 497532},
-	{0, 0, 707610},
-	{0, 0, 844545},
+	{0, 900, 0, 0, 0},
+	{0, 950, 0, 0, 0},
+	{0, 950, 0, 0, 0},
+	{0, 1200, 1, 100, 100},
 };
 
 static struct msm_dcvs_core_info grp3d_core_info = {
-	.freq_tbl = &grp3d_freq[0],
-	.core_param = {
-		.max_time_us = 100000,
-		.num_freq = ARRAY_SIZE(grp3d_freq),
+	.freq_tbl	= &grp3d_freq[0],
+	.core_param	= {
+		.core_type	= MSM_DCVS_CORE_TYPE_GPU,
 	},
-	.algo_param = {
-		.slack_time_us = 39000,
-		.disable_pc_threshold = 86000,
-		.ss_window_size = 1000000,
-		.ss_util_pct = 95,
-		.em_max_util_pct = 97,
-		.ss_iobusy_conv = 100,
+	.algo_param	= {
+		.disable_pc_threshold	= 0,
+		.em_win_size_min_us	= 100000,
+		.em_win_size_max_us	= 300000,
+		.em_max_util_pct	= 97,
+		.group_id		= 0,
+		.max_freq_chg_time_us	= 100000,
+		.slack_mode_dynamic	= 0,
+		.slack_time_min_us	= 39000,
+		.slack_time_max_us	= 39000,
+		.ss_win_size_min_us	= 1000000,
+		.ss_win_size_max_us	= 1000000,
+		.ss_util_pct		= 95,
+		.ss_iobusy_conv		= 100,
 	},
+
+
+	.energy_coeffs	= {
+		.leakage_coeff_a	= -17720,
+		.leakage_coeff_b	= 37,
+		.leakage_coeff_c	= 3329,
+		.leakage_coeff_d	= -277,
+
+		.active_coeff_a		= 2492,
+		.active_coeff_b		= 0,
+		.active_coeff_c		= 0
+	},
+
+	.power_param	= {
+		.current_temp	= 25,
+		.num_freq	= ARRAY_SIZE(grp3d_freq),
+	}
 };
 #endif /* CONFIG_MSM_DCVS */
 
diff --git a/arch/arm/mach-msm/board-8930.c b/arch/arm/mach-msm/board-8930.c
index a7147b5..ab2fbaf 100644
--- a/arch/arm/mach-msm/board-8930.c
+++ b/arch/arm/mach-msm/board-8930.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, 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
@@ -2251,7 +2251,6 @@
 #endif
 	&msm8930_rtb_device,
 	&msm8930_cpu_idle_device,
-	&msm8930_msm_gov_device,
 	&msm_bus_8930_apps_fabric,
 	&msm_bus_8930_sys_fabric,
 	&msm_bus_8930_mm_fabric,
diff --git a/arch/arm/mach-msm/board-8960.c b/arch/arm/mach-msm/board-8960.c
index e9a034e..a46c93e 100644
--- a/arch/arm/mach-msm/board-8960.c
+++ b/arch/arm/mach-msm/board-8960.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, 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
@@ -2671,7 +2671,6 @@
 	&msm8960_device_watchdog,
 	&msm8960_rtb_device,
 	&msm8960_cpu_idle_device,
-	&msm8960_msm_gov_device,
 	&msm8960_device_cache_erp,
 	&msm8960_device_ebi1_ch0_erp,
 	&msm8960_device_ebi1_ch1_erp,
diff --git a/arch/arm/mach-msm/devices-8064.c b/arch/arm/mach-msm/devices-8064.c
index d2d05b1..4032af6 100644
--- a/arch/arm/mach-msm/devices-8064.c
+++ b/arch/arm/mach-msm/devices-8064.c
@@ -2599,32 +2599,50 @@
 };
 
 static struct msm_dcvs_freq_entry apq8064_freq[] = {
-	{ 384000, 166981,  345600},
-	{ 702000, 213049,  632502},
-	{1026000, 285712,  925613},
-	{1242000, 383945, 1176550},
-	{1458000, 419729, 1465478},
-	{1512000, 434116, 1546674},
-
+	{ 384000, 900,  0, 0, 0},
+	{ 594000, 950,  0, 0, 0},
+	{ 702000, 975,  0, 0, 0},
+	{1026000, 1075, 0, 0, 0},
+	{1242000, 1150, 0, 100, 100},
+	{1458000, 1188, 0, 100, 100},
+	{1512000, 1200, 1, 100, 100},
 };
 
 static struct msm_dcvs_core_info apq8064_core_info = {
-	.freq_tbl = &apq8064_freq[0],
-	.core_param = {
-		.max_time_us = 100000,
-		.num_freq = ARRAY_SIZE(apq8064_freq),
+	.freq_tbl	= &apq8064_freq[0],
+	.core_param	= {
+		.core_type	= MSM_DCVS_CORE_TYPE_CPU,
 	},
-	.algo_param = {
-		.slack_time_us = 58000,
-		.scale_slack_time = 0,
-		.scale_slack_time_pct = 0,
-		.disable_pc_threshold = 1458000,
-		.em_window_size = 100000,
-		.em_max_util_pct = 97,
-		.ss_window_size = 1000000,
-		.ss_util_pct = 95,
-		.ss_iobusy_conv = 100,
+	.algo_param	= {
+		.disable_pc_threshold		= 1458000,
+		.em_win_size_min_us		= 100000,
+		.em_win_size_max_us		= 300000,
+		.em_max_util_pct		= 97,
+		.group_id			= 1,
+		.max_freq_chg_time_us		= 100000,
+		.slack_mode_dynamic		= 0,
+		.slack_weight_thresh_pct	= 3,
+		.slack_time_min_us		= 45000,
+		.slack_time_max_us		= 45000,
+		.ss_iobusy_conv			= 100,
+		.ss_win_size_min_us		= 1000000,
+		.ss_win_size_max_us		= 1000000,
+		.ss_util_pct			= 95,
 	},
+	.energy_coeffs	= {
+		.active_coeff_a		= 336,
+		.active_coeff_b		= 0,
+		.active_coeff_c		= 0,
+
+		.leakage_coeff_a	= -17720,
+		.leakage_coeff_b	= 37,
+		.leakage_coeff_c	= 3329,
+		.leakage_coeff_d	= -277,
+	},
+	.power_param	= {
+		.current_temp	= 25,
+		.num_freq	= ARRAY_SIZE(apq8064_freq),
+	}
 };
 
 struct platform_device apq8064_msm_gov_device = {
diff --git a/arch/arm/mach-msm/devices-8930.c b/arch/arm/mach-msm/devices-8930.c
index eac2140..0fbf856 100644
--- a/arch/arm/mach-msm/devices-8930.c
+++ b/arch/arm/mach-msm/devices-8930.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, 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
@@ -18,7 +18,6 @@
 #include <mach/msm_iomap.h>
 #include <mach/irqs-8930.h>
 #include <mach/rpm.h>
-#include <mach/msm_dcvs.h>
 #include <mach/msm_bus.h>
 #include <mach/msm_bus_board.h>
 #include <mach/board.h>
@@ -323,43 +322,6 @@
 	},
 };
 
-static struct msm_dcvs_freq_entry msm8930_freq[] = {
-	{ 384000, 166981,  345600},
-	{ 702000, 213049,  632502},
-	{1026000, 285712,  925613},
-	{1242000, 383945, 1176550},
-	{1458000, 419729, 1465478},
-	{1512000, 434116, 1546674},
-
-};
-
-static struct msm_dcvs_core_info msm8930_core_info = {
-	.freq_tbl = &msm8930_freq[0],
-	.core_param = {
-		.max_time_us = 100000,
-		.num_freq = ARRAY_SIZE(msm8930_freq),
-	},
-	.algo_param = {
-		.slack_time_us = 58000,
-		.scale_slack_time = 0,
-		.scale_slack_time_pct = 0,
-		.disable_pc_threshold = 1458000,
-		.em_window_size = 100000,
-		.em_max_util_pct = 97,
-		.ss_window_size = 1000000,
-		.ss_util_pct = 95,
-		.ss_iobusy_conv = 100,
-	},
-};
-
-struct platform_device msm8930_msm_gov_device = {
-	.name = "msm_dcvs_gov",
-	.id = -1,
-	.dev = {
-		.platform_data = &msm8930_core_info,
-	},
-};
-
 struct platform_device msm_bus_8930_sys_fabric = {
 	.name  = "msm_bus_fabric",
 	.id    =  MSM_BUS_FAB_SYSTEM,
diff --git a/arch/arm/mach-msm/devices-8960.c b/arch/arm/mach-msm/devices-8960.c
index 29edf1b..d0491a9 100644
--- a/arch/arm/mach-msm/devices-8960.c
+++ b/arch/arm/mach-msm/devices-8960.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, 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
@@ -2916,46 +2916,89 @@
 };
 
 static struct msm_dcvs_freq_entry grp3d_freq[] = {
-	{0, 0, 333932},
-	{0, 0, 497532},
-	{0, 0, 707610},
-	{0, 0, 844545},
+	{0, 900, 0, 0, 0},
+	{0, 950, 0, 0, 0},
+	{0, 950, 0, 0, 0},
+	{0, 1200, 1, 100, 100},
 };
 
 static struct msm_dcvs_freq_entry grp2d_freq[] = {
-	{0, 0, 86000},
-	{0, 0, 200000},
+	{0, 900, 0, 0, 0},
+	{0, 950, 1, 100, 100},
 };
 
 static struct msm_dcvs_core_info grp3d_core_info = {
-	.freq_tbl = &grp3d_freq[0],
-	.core_param = {
-		.max_time_us = 100000,
-		.num_freq = ARRAY_SIZE(grp3d_freq),
+	.freq_tbl	= &grp3d_freq[0],
+	.core_param	= {
+		.core_type	= MSM_DCVS_CORE_TYPE_GPU,
 	},
-	.algo_param = {
-		.slack_time_us = 39000,
-		.disable_pc_threshold = 86000,
-		.ss_window_size = 1000000,
-		.ss_util_pct = 95,
-		.em_max_util_pct = 97,
-		.ss_iobusy_conv = 100,
+	.algo_param	= {
+		.disable_pc_threshold		= 0,
+		.em_win_size_min_us		= 100000,
+		.em_win_size_max_us		= 300000,
+		.em_max_util_pct		= 97,
+		.group_id			= 0,
+		.max_freq_chg_time_us		= 100000,
+		.slack_mode_dynamic		= 0,
+		.slack_weight_thresh_pct	= 0,
+		.slack_time_min_us		= 39000,
+		.slack_time_max_us		= 39000,
+		.ss_win_size_min_us		= 1000000,
+		.ss_win_size_max_us		= 1000000,
+		.ss_util_pct			= 95,
+		.ss_iobusy_conv			= 100,
 	},
+	.energy_coeffs	= {
+		.active_coeff_a		= 2492,
+		.active_coeff_b		= 0,
+		.active_coeff_c		= 0,
+
+		.leakage_coeff_a	= -17720,
+		.leakage_coeff_b	= 37,
+		.leakage_coeff_c	= 2729,
+		.leakage_coeff_d	= -277,
+	},
+	.power_param	= {
+		.current_temp	= 25,
+		.num_freq	= ARRAY_SIZE(grp3d_freq),
+	}
 };
 
 static struct msm_dcvs_core_info grp2d_core_info = {
-	.freq_tbl = &grp2d_freq[0],
-	.core_param = {
-		.max_time_us = 100000,
-		.num_freq = ARRAY_SIZE(grp2d_freq),
+	.freq_tbl	= &grp2d_freq[0],
+	.core_param	= {
+		.core_type	= MSM_DCVS_CORE_TYPE_GPU,
 	},
-	.algo_param = {
-		.slack_time_us = 39000,
-		.disable_pc_threshold = 90000,
-		.ss_window_size = 1000000,
-		.ss_util_pct = 90,
-		.em_max_util_pct = 95,
+	.algo_param	= {
+		.disable_pc_threshold		= 0,
+		.em_win_size_min_us		= 100000,
+		.em_win_size_max_us		= 300000,
+		.em_max_util_pct		= 97,
+		.group_id			= 0,
+		.max_freq_chg_time_us		= 100000,
+		.slack_mode_dynamic		= 0,
+		.slack_weight_thresh_pct	= 0,
+		.slack_time_min_us		= 39000,
+		.slack_time_max_us		= 39000,
+		.ss_win_size_min_us		= 1000000,
+		.ss_win_size_max_us		= 1000000,
+		.ss_util_pct			= 95,
+		.ss_iobusy_conv			= 100,
 	},
+	.energy_coeffs	= {
+		.active_coeff_a		= 2492,
+		.active_coeff_b		= 0,
+		.active_coeff_c		= 0,
+
+		.leakage_coeff_a	= -17720,
+		.leakage_coeff_b	= 37,
+		.leakage_coeff_c	= 2729,
+		.leakage_coeff_d	= -277,
+	},
+	.power_param	= {
+		.current_temp	= 25,
+		.num_freq	= ARRAY_SIZE(grp2d_freq),
+	}
 };
 
 #ifdef CONFIG_MSM_BUS_SCALING
@@ -4001,43 +4044,6 @@
 	},
 };
 
-static struct msm_dcvs_freq_entry msm8960_freq[] = {
-	{ 384000, 166981,  345600},
-	{ 702000, 213049,  632502},
-	{1026000, 285712,  925613},
-	{1242000, 383945, 1176550},
-	{1458000, 419729, 1465478},
-	{1512000, 434116, 1546674},
-
-};
-
-static struct msm_dcvs_core_info msm8960_core_info = {
-	.freq_tbl = &msm8960_freq[0],
-	.core_param = {
-		.max_time_us = 100000,
-		.num_freq = ARRAY_SIZE(msm8960_freq),
-	},
-	.algo_param = {
-		.slack_time_us = 58000,
-		.scale_slack_time = 0,
-		.scale_slack_time_pct = 0,
-		.disable_pc_threshold = 1458000,
-		.em_window_size = 100000,
-		.em_max_util_pct = 97,
-		.ss_window_size = 1000000,
-		.ss_util_pct = 95,
-		.ss_iobusy_conv = 100,
-	},
-};
-
-struct platform_device msm8960_msm_gov_device = {
-	.name = "msm_dcvs_gov",
-	.id = -1,
-	.dev = {
-		.platform_data = &msm8960_core_info,
-	},
-};
-
 static struct resource msm_cache_erp_resources[] = {
 	{
 		.name = "l1_irq",
diff --git a/arch/arm/mach-msm/devices.h b/arch/arm/mach-msm/devices.h
index 8ee7891..f659831 100644
--- a/arch/arm/mach-msm/devices.h
+++ b/arch/arm/mach-msm/devices.h
@@ -393,8 +393,6 @@
 extern struct platform_device msm8930_cpu_idle_device;
 extern struct platform_device apq8064_cpu_idle_device;
 
-extern struct platform_device msm8960_msm_gov_device;
-extern struct platform_device msm8930_msm_gov_device;
 extern struct platform_device apq8064_msm_gov_device;
 
 extern struct platform_device msm_bus_8930_apps_fabric;
diff --git a/arch/arm/mach-msm/include/mach/msm_dcvs.h b/arch/arm/mach-msm/include/mach/msm_dcvs.h
index 78d0d4a..490a34b 100644
--- a/arch/arm/mach-msm/include/mach/msm_dcvs.h
+++ b/arch/arm/mach-msm/include/mach/msm_dcvs.h
@@ -90,15 +90,16 @@
  * before the sink driver can be registered.
  */
 struct msm_dcvs_core_info {
-	struct msm_dcvs_freq_entry *freq_tbl;
-	struct msm_dcvs_core_param core_param;
-	struct msm_dcvs_algo_param algo_param;
+	struct msm_dcvs_freq_entry		*freq_tbl;
+	struct msm_dcvs_core_param		core_param;
+	struct msm_dcvs_algo_param		algo_param;
+	struct msm_dcvs_energy_curve_coeffs	energy_coeffs;
+	struct msm_dcvs_power_params		power_param;
 };
 
 /**
  * msm_dcvs_register_core
  * @core_name: Unique name identifier for the core.
- * @group_id: Cores that are to be grouped for synchronized frequency scaling
  * @info: The core specific algorithm parameters.
  * @return :
  *	0 on success,
@@ -108,9 +109,8 @@
  * Register the core with msm_dcvs driver. Done once at init before calling
  * msm_dcvs_freq_sink_register
  * Cores that need to run synchronously must share the same group id.
- * If a core doesnt care to be in any group, the group_id should be 0.
  */
-extern int msm_dcvs_register_core(const char *core_name, uint32_t group_id,
+extern int msm_dcvs_register_core(const char *core_name,
 		struct msm_dcvs_core_info *info);
 
 /**
diff --git a/arch/arm/mach-msm/include/mach/msm_dcvs_scm.h b/arch/arm/mach-msm/include/mach/msm_dcvs_scm.h
index d97cd32..597fdc0 100644
--- a/arch/arm/mach-msm/include/mach/msm_dcvs_scm.h
+++ b/arch/arm/mach-msm/include/mach/msm_dcvs_scm.h
@@ -13,6 +13,11 @@
 #ifndef _ARCH_ARM_MACH_MSM_MSM_DCVS_SCM_H
 #define _ARCH_ARM_MACH_MSM_MSM_DCVS_SCM_H
 
+enum msm_dcvs_core_type {
+	MSM_DCVS_CORE_TYPE_CPU = 0,
+	MSM_DCVS_CORE_TYPE_GPU = 1,
+};
+
 enum msm_dcvs_algo_param_type {
 	MSM_DCVS_ALGO_DCVS_PARAM = 0,
 	MSM_DCVS_ALGO_MPD_PARAM  = 1,
@@ -33,28 +38,50 @@
 };
 
 struct msm_dcvs_algo_param {
-	uint32_t slack_time_us;
-	uint32_t scale_slack_time;
-	uint32_t scale_slack_time_pct;
 	uint32_t disable_pc_threshold;
-	uint32_t em_window_size;
+	uint32_t em_win_size_min_us;
+	uint32_t em_win_size_max_us;
 	uint32_t em_max_util_pct;
-	uint32_t ss_window_size;
-	uint32_t ss_util_pct;
+	uint32_t group_id;
+	uint32_t max_freq_chg_time_us;
+	uint32_t slack_mode_dynamic;
+	uint32_t slack_time_min_us;
+	uint32_t slack_time_max_us;
+	uint32_t slack_weight_thresh_pct;
 	uint32_t ss_iobusy_conv;
+	uint32_t ss_win_size_min_us;
+	uint32_t ss_win_size_max_us;
+	uint32_t ss_util_pct;
 };
 
 struct msm_dcvs_freq_entry {
-	uint32_t freq; /* Core freq in MHz */
-	uint32_t idle_energy;
-	uint32_t active_energy;
+	uint32_t freq;
+	uint32_t voltage;
+	uint32_t is_trans_level;
+	uint32_t active_energy_offset;
+	uint32_t leakage_energy_offset;
 };
 
-struct msm_dcvs_core_param {
-	uint32_t max_time_us;
+struct msm_dcvs_energy_curve_coeffs {
+	int32_t active_coeff_a;
+	int32_t active_coeff_b;
+	int32_t active_coeff_c;
+
+	int32_t leakage_coeff_a;
+	int32_t leakage_coeff_b;
+	int32_t leakage_coeff_c;
+	int32_t leakage_coeff_d;
+};
+
+struct msm_dcvs_power_params {
+	uint32_t current_temp;
 	uint32_t num_freq; /* number of msm_dcvs_freq_entry passed */
 };
 
+struct msm_dcvs_core_param {
+	uint32_t core_type;
+	uint32_t core_bitmask_id;
+};
 
 struct msm_mpd_algo_param {
 	uint32_t em_win_size_min_us;
@@ -83,20 +110,9 @@
 extern int msm_dcvs_scm_init(size_t size);
 
 /**
- * Create an empty core group
- *
- * @return:
- *	0 on success.
- *	-ENOMEM: Insufficient memory.
- *	-EINVAL: Invalid args.
- */
-extern int msm_dcvs_scm_create_group(uint32_t id);
-
-/**
- * Registers cores as part of a group
+ * Registers cores with the DCVS algo.
  *
  * @core_id: The core identifier that will be used for communication with DCVS
- * @group_id: The group to which this core will be added to.
  * @param: The core parameters
  * @freq: Array of frequency and energy values
  *
@@ -105,9 +121,8 @@
  *	-ENOMEM: Insufficient memory.
  *	-EINVAL: Invalid args.
  */
-extern int msm_dcvs_scm_register_core(uint32_t core_id, uint32_t group_id,
-		struct msm_dcvs_core_param *param,
-		struct msm_dcvs_freq_entry *freq);
+extern int msm_dcvs_scm_register_core(uint32_t core_id,
+		struct msm_dcvs_core_param *param);
 
 /**
  * Set DCVS algorithm parameters
@@ -132,6 +147,24 @@
 extern int msm_mpd_scm_set_algo_params(struct msm_mpd_algo_param *param);
 
 /**
+ * Set frequency and power characteristics for the core.
+ *
+ * @param core_id: The core identifier that will be used to interace with the
+ *                 DCVS algo.
+ * @param pwr_param: power params
+ * @param freq_entry: frequency characteristics desired
+ * @param coeffs: Coefficients that will describe the power curve
+ *
+ * @return int
+ *	0 on success.
+ *	-EINVAL: Invalid args.
+ */
+extern int msm_dcvs_scm_set_power_params(uint32_t core_id,
+				struct msm_dcvs_power_params *pwr_param,
+				struct msm_dcvs_freq_entry *freq_entry,
+				struct msm_dcvs_energy_curve_coeffs *coeffs);
+
+/**
  * Do an SCM call.
  *
  * @core_id: The core identifier.
@@ -157,19 +190,44 @@
  *		@param1: time taken in usec to switch to the frequency
  *		@ret0: New QoS timer value for the core in usec
  *		@ret1: unused
- *	MSM_DCVS_SCM_ENABLE_CORE
- *		@param0: enable(1) or disable(0) core
- *		@param1: active clock frequency of the core in KHz
- *		@ret0: New clock frequency for the core in KHz
- *		@ret1: unused
- *	MSM_DCVS_SCM_RESET_CORE
+ *	MSM_DCVS_SCM_CORE_ONLINE
  *		@param0: active clock frequency of the core in KHz
+ *		@param1: time taken to online the core
+ *		@ret0: unused
+ *		@ret1: unused
+ *	MSM_DCVS_SCM_CORE_OFFLINE
+ *		@param0: time taken to offline the core
+ *		@param1: unused
+ *		@ret0: unused
+ *		@ret1: unused
+ *	MSM_DCVS_SCM_CORE_UNAVAILABLE
+ *		@param0: TODO:bitmask
+ *		@param1: unused
+ *		@ret0: Bitmask of cores to bring online/offline.
+ *		@ret1: Mp Decision slack time. Common to all cores.
+ *	MSM_DCVS_SCM_DCVS_ENABLE
+ *		@param0: 1 to enable; 0 to disable DCVS
  *		@param1: unused
  *		@ret0: New clock frequency for the core in KHz
  *		@ret1: unused
- * @return:
- *	0 on success,
- *	SCM return values
+ *	MSM_DCVS_SCM_MPD_ENABLE
+ *		@param0: 1 to enable; 0 to disable MP Decision
+ *		@param1: unused
+ *		@ret0: unused
+ *		@ret1: unused
+ *	MSM_DCVS_SCM_RUNQ_UPDATE
+ *		@param0: run q value
+ *		@param1: unused
+ *		@ret0: Bitmask of cores online
+ *		@ret1: New QoS timer for MP Decision (usec)
+ *	MSM_DCVS_SCM_MPD_QOS_TIMER_EXPIRED
+ *		@param0: unused
+ *		@param1: unused
+ *		@ret0: Bitmask of cores online
+ *		@ret1: New QoS timer for MP Decision (usec)
+ *	@return:
+ *		0 on success,
+ *		SCM return values
  */
 extern int msm_dcvs_scm_event(uint32_t core_id,
 		enum msm_dcvs_scm_event event_id,
@@ -179,10 +237,7 @@
 #else
 static inline int msm_dcvs_scm_init(uint32_t phy, size_t bytes)
 { return -ENOSYS; }
-static inline int msm_dcvs_scm_create_group(uint32_t id)
-{ return -ENOSYS; }
 static inline int msm_dcvs_scm_register_core(uint32_t core_id,
-		uint32_t group_id,
 		struct msm_dcvs_core_param *param,
 		struct msm_dcvs_freq_entry *freq)
 { return -ENOSYS; }
@@ -192,6 +247,11 @@
 static inline int msm_mpd_scm_set_algo_params(
 		struct msm_mpd_algo_param *param)
 { return -ENOSYS; }
+static inline int msm_dcvs_set_power_params(uint32_t core_id,
+		struct msm_dcvs_power_params *pwr_param,
+		struct msm_dcvs_freq_entry *freq_entry,
+		struct msm_dcvs_energy_curve_coeffs *coeffs)
+{ return -ENOSYS; }
 static inline int msm_dcvs_scm_event(uint32_t core_id,
 		enum msm_dcvs_scm_event event_id,
 		uint32_t param0, uint32_t param1,
diff --git a/arch/arm/mach-msm/msm_dcvs.c b/arch/arm/mach-msm/msm_dcvs.c
index 890e450..9601b7e 100644
--- a/arch/arm/mach-msm/msm_dcvs.c
+++ b/arch/arm/mach-msm/msm_dcvs.c
@@ -39,22 +39,34 @@
 };
 
 struct core_attribs {
+	struct kobj_attribute core_id;
 	struct kobj_attribute idle_enabled;
 	struct kobj_attribute freq_change_enabled;
 	struct kobj_attribute actual_freq;
 	struct kobj_attribute freq_change_us;
 
-	struct kobj_attribute max_time_us;
-
-	struct kobj_attribute slack_time_us;
-	struct kobj_attribute scale_slack_time;
-	struct kobj_attribute scale_slack_time_pct;
 	struct kobj_attribute disable_pc_threshold;
-	struct kobj_attribute em_window_size;
+	struct kobj_attribute em_win_size_min_us;
+	struct kobj_attribute em_win_size_max_us;
 	struct kobj_attribute em_max_util_pct;
-	struct kobj_attribute ss_window_size;
-	struct kobj_attribute ss_util_pct;
+	struct kobj_attribute group_id;
+	struct kobj_attribute max_freq_chg_time_us;
+	struct kobj_attribute slack_mode_dynamic;
+	struct kobj_attribute slack_time_min_us;
+	struct kobj_attribute slack_time_max_us;
+	struct kobj_attribute slack_weight_thresh_pct;
 	struct kobj_attribute ss_iobusy_conv;
+	struct kobj_attribute ss_win_size_min_us;
+	struct kobj_attribute ss_win_size_max_us;
+	struct kobj_attribute ss_util_pct;
+
+	struct kobj_attribute active_coeff_a;
+	struct kobj_attribute active_coeff_b;
+	struct kobj_attribute active_coeff_c;
+	struct kobj_attribute leakage_coeff_a;
+	struct kobj_attribute leakage_coeff_b;
+	struct kobj_attribute leakage_coeff_c;
+	struct kobj_attribute leakage_coeff_d;
 
 	struct attribute_group attrib_group;
 };
@@ -68,6 +80,7 @@
 	uint32_t max_time_us; /* core param */
 
 	struct msm_dcvs_algo_param algo_param;
+	struct msm_dcvs_energy_curve_coeffs coeffs;
 	struct msm_dcvs_idle *idle_driver;
 	struct msm_dcvs_freq *freq_driver;
 
@@ -78,12 +91,12 @@
 	struct task_struct *task;
 	struct core_attribs attrib;
 	uint32_t handle;
-	uint32_t group_id;
 	uint32_t freq_pending;
 	struct hrtimer timer;
 	int32_t timer_disabled;
 	/* track if kthread for change_freq is active */
 	int32_t change_freq_activated;
+	struct msm_dcvs_core_info *info;
 };
 
 static int msm_dcvs_debug;
@@ -365,6 +378,39 @@
 	return count; \
 }
 
+#define DCVS_ENERGY_PARAM(_name) \
+static ssize_t msm_dcvs_attr_##_name##_show(struct kobject *kobj,\
+		struct kobj_attribute *attr, char *buf) \
+{ \
+	struct dcvs_core *core = CORE_FROM_ATTRIBS(attr, _name); \
+	return snprintf(buf, PAGE_SIZE, "%d\n", core->coeffs._name); \
+} \
+static ssize_t msm_dcvs_attr_##_name##_store(struct kobject *kobj, \
+		struct kobj_attribute *attr, const char *buf, size_t count) \
+{ \
+	int ret = 0; \
+	int32_t val = 0; \
+	struct dcvs_core *core = CORE_FROM_ATTRIBS(attr, _name); \
+	mutex_lock(&core->lock); \
+	ret = kstrtoint(buf, 10, &val); \
+	if (ret) { \
+		__err("Invalid input %s for %s\n", buf, __stringify(_name));\
+	} else { \
+		int32_t old_val = core->coeffs._name; \
+		core->coeffs._name = val; \
+		ret = msm_dcvs_scm_set_power_params(core->handle, \
+			&core->info->power_param, &core->info->freq_tbl[0], \
+				&core->coeffs); \
+		if (ret) { \
+			core->coeffs._name = old_val; \
+			__err("Error(%d) in setting %d for coeffs param %s\n",\
+					ret, val, __stringify(_name)); \
+		} \
+	} \
+	mutex_unlock(&core->lock); \
+	return count; \
+}
+
 #define DCVS_RO_ATTRIB(i, _name) \
 	core->attrib._name.attr.name = __stringify(_name); \
 	core->attrib._name.attr.mode = S_IRUGO; \
@@ -383,27 +429,40 @@
  * Function declarations for different attributes.
  * Gets used when setting the attribute show and store parameters.
  */
+DCVS_PARAM_SHOW(core_id, core->handle)
 DCVS_PARAM_SHOW(idle_enabled, (core->idle_driver != NULL))
 DCVS_PARAM_SHOW(freq_change_enabled, (core->freq_driver != NULL))
 DCVS_PARAM_SHOW(actual_freq, (core->actual_freq))
 DCVS_PARAM_SHOW(freq_change_us, (core->freq_change_us))
-DCVS_PARAM_SHOW(max_time_us, (core->max_time_us))
 
-DCVS_ALGO_PARAM(slack_time_us)
-DCVS_ALGO_PARAM(scale_slack_time)
-DCVS_ALGO_PARAM(scale_slack_time_pct)
 DCVS_ALGO_PARAM(disable_pc_threshold)
-DCVS_ALGO_PARAM(em_window_size)
+DCVS_ALGO_PARAM(em_win_size_min_us)
+DCVS_ALGO_PARAM(em_win_size_max_us)
 DCVS_ALGO_PARAM(em_max_util_pct)
-DCVS_ALGO_PARAM(ss_window_size)
-DCVS_ALGO_PARAM(ss_util_pct)
+DCVS_ALGO_PARAM(group_id)
+DCVS_ALGO_PARAM(max_freq_chg_time_us)
+DCVS_ALGO_PARAM(slack_mode_dynamic)
+DCVS_ALGO_PARAM(slack_time_min_us)
+DCVS_ALGO_PARAM(slack_time_max_us)
+DCVS_ALGO_PARAM(slack_weight_thresh_pct)
 DCVS_ALGO_PARAM(ss_iobusy_conv)
+DCVS_ALGO_PARAM(ss_win_size_min_us)
+DCVS_ALGO_PARAM(ss_win_size_max_us)
+DCVS_ALGO_PARAM(ss_util_pct)
+
+DCVS_ENERGY_PARAM(active_coeff_a)
+DCVS_ENERGY_PARAM(active_coeff_b)
+DCVS_ENERGY_PARAM(active_coeff_c)
+DCVS_ENERGY_PARAM(leakage_coeff_a)
+DCVS_ENERGY_PARAM(leakage_coeff_b)
+DCVS_ENERGY_PARAM(leakage_coeff_c)
+DCVS_ENERGY_PARAM(leakage_coeff_d)
 
 static int msm_dcvs_setup_core_sysfs(struct dcvs_core *core)
 {
 	int ret = 0;
 	struct kobject *core_kobj = NULL;
-	const int attr_count = 15;
+	const int attr_count = 27;
 
 	BUG_ON(!cores_kobj);
 
@@ -415,23 +474,37 @@
 		goto done;
 	}
 
-	DCVS_RO_ATTRIB(0, idle_enabled);
-	DCVS_RO_ATTRIB(1, freq_change_enabled);
-	DCVS_RO_ATTRIB(2, actual_freq);
-	DCVS_RO_ATTRIB(3, freq_change_us);
-	DCVS_RO_ATTRIB(4, max_time_us);
 
-	DCVS_RW_ATTRIB(5, slack_time_us);
-	DCVS_RW_ATTRIB(6, scale_slack_time);
-	DCVS_RW_ATTRIB(7, scale_slack_time_pct);
-	DCVS_RW_ATTRIB(8, disable_pc_threshold);
-	DCVS_RW_ATTRIB(9, em_window_size);
-	DCVS_RW_ATTRIB(10, em_max_util_pct);
-	DCVS_RW_ATTRIB(11, ss_window_size);
-	DCVS_RW_ATTRIB(12, ss_util_pct);
-	DCVS_RW_ATTRIB(13, ss_iobusy_conv);
+	DCVS_RO_ATTRIB(0, core_id);
+	DCVS_RO_ATTRIB(1, idle_enabled);
+	DCVS_RO_ATTRIB(2, freq_change_enabled);
+	DCVS_RO_ATTRIB(3, actual_freq);
+	DCVS_RO_ATTRIB(4, freq_change_us);
 
-	core->attrib.attrib_group.attrs[14] = NULL;
+	DCVS_RW_ATTRIB(5, disable_pc_threshold);
+	DCVS_RW_ATTRIB(6, em_win_size_min_us);
+	DCVS_RW_ATTRIB(7, em_win_size_max_us);
+	DCVS_RW_ATTRIB(8, em_max_util_pct);
+	DCVS_RW_ATTRIB(9, group_id);
+	DCVS_RW_ATTRIB(10, max_freq_chg_time_us);
+	DCVS_RW_ATTRIB(11, slack_mode_dynamic);
+	DCVS_RW_ATTRIB(12, slack_time_min_us);
+	DCVS_RW_ATTRIB(13, slack_time_max_us);
+	DCVS_RW_ATTRIB(14, slack_weight_thresh_pct);
+	DCVS_RW_ATTRIB(15, ss_iobusy_conv);
+	DCVS_RW_ATTRIB(16, ss_win_size_min_us);
+	DCVS_RW_ATTRIB(17, ss_win_size_max_us);
+	DCVS_RW_ATTRIB(18, ss_util_pct);
+
+	DCVS_RW_ATTRIB(19, active_coeff_a);
+	DCVS_RW_ATTRIB(20, active_coeff_b);
+	DCVS_RW_ATTRIB(21, active_coeff_c);
+	DCVS_RW_ATTRIB(22, leakage_coeff_a);
+	DCVS_RW_ATTRIB(23, leakage_coeff_b);
+	DCVS_RW_ATTRIB(24, leakage_coeff_c);
+	DCVS_RW_ATTRIB(25, leakage_coeff_d);
+
+	core->attrib.attrib_group.attrs[26] = NULL;
 
 	core_kobj = kobject_create_and_add(core->core_name, cores_kobj);
 	if (!core_kobj) {
@@ -497,11 +570,13 @@
 	return core;
 }
 
-int msm_dcvs_register_core(const char *core_name, uint32_t group_id,
+int msm_dcvs_register_core(const char *core_name,
 		struct msm_dcvs_core_info *info)
 {
 	int ret = -EINVAL;
 	struct dcvs_core *core = NULL;
+	uint32_t ret1;
+	uint32_t ret2;
 
 	if (!core_name || !core_name[0])
 		return ret;
@@ -511,25 +586,15 @@
 		return ret;
 
 	mutex_lock(&core->lock);
-	if (group_id) {
-		/**
-		 * Create a group for cores, if this core is part of a group
-		 * if the group_id is 0, the core is not part of a group.
-		 * If the group_id already exits, it will through an error
-		 * which we will ignore.
-		 */
-		ret = msm_dcvs_scm_create_group(group_id);
-		if (ret == -ENOMEM)
-			goto bail;
-	}
-	core->group_id = group_id;
 
-	core->max_time_us = info->core_param.max_time_us;
+	core->info = info;
 	memcpy(&core->algo_param, &info->algo_param,
 			sizeof(struct msm_dcvs_algo_param));
 
-	ret = msm_dcvs_scm_register_core(core->handle, group_id,
-			&info->core_param, info->freq_tbl);
+	memcpy(&core->coeffs, &info->energy_coeffs,
+			sizeof(struct msm_dcvs_energy_curve_coeffs));
+
+	ret = msm_dcvs_scm_register_core(core->handle, &info->core_param);
 	if (ret)
 		goto bail;
 
@@ -537,6 +602,16 @@
 	if (ret)
 		goto bail;
 
+	ret = msm_dcvs_scm_set_power_params(core->handle, &info->power_param,
+				&info->freq_tbl[0], &core->coeffs);
+	if (ret)
+		goto bail;
+
+	ret = msm_dcvs_scm_event(core->handle, MSM_DCVS_SCM_CORE_ONLINE,
+				core->actual_freq, 0, &ret1, &ret2);
+	if (ret)
+		goto bail;
+
 	ret = msm_dcvs_setup_core_sysfs(core);
 	if (ret) {
 		__err("Unable to setup core %s sysfs\n", core->core_name);
diff --git a/arch/arm/mach-msm/msm_dcvs_scm.c b/arch/arm/mach-msm/msm_dcvs_scm.c
index bf623df..df6c44f 100644
--- a/arch/arm/mach-msm/msm_dcvs_scm.c
+++ b/arch/arm/mach-msm/msm_dcvs_scm.c
@@ -21,17 +21,15 @@
 #include <mach/scm.h>
 #include <mach/msm_dcvs_scm.h>
 
-#define DCVS_CMD_CREATE_GROUP		1
 #define DCVS_CMD_REGISTER_CORE		2
 #define DCVS_CMD_SET_ALGO_PARAM		3
 #define DCVS_CMD_EVENT			4
 #define DCVS_CMD_INIT			5
+#define DCVS_CMD_SET_POWER_PARAM	6
 
 struct scm_register_core {
 	uint32_t core_id;
-	uint32_t group_id;
 	phys_addr_t core_param_phy;
-	phys_addr_t freq_phy;
 };
 
 struct scm_algo {
@@ -44,6 +42,13 @@
 	uint32_t size;
 };
 
+struct scm_pwr_param {
+	uint32_t	core_id;
+	phys_addr_t	pwr_param_phy;
+	phys_addr_t	freq_phy;
+	phys_addr_t	coeffs_phy;
+};
+
 struct msm_algo_param {
 	enum msm_dcvs_algo_param_type		type;
 	union {
@@ -77,49 +82,25 @@
 }
 EXPORT_SYMBOL(msm_dcvs_scm_init);
 
-int msm_dcvs_scm_create_group(uint32_t id)
-{
-	int ret = 0;
-
-	ret = scm_call(SCM_SVC_DCVS, DCVS_CMD_CREATE_GROUP,
-			&id, sizeof(uint32_t), NULL, 0);
-
-	return ret;
-}
-EXPORT_SYMBOL(msm_dcvs_scm_create_group);
-
-int msm_dcvs_scm_register_core(uint32_t core_id, uint32_t group_id,
-		struct msm_dcvs_core_param *param,
-		struct msm_dcvs_freq_entry *freq)
+int msm_dcvs_scm_register_core(uint32_t core_id,
+		struct msm_dcvs_core_param *param)
 {
 	int ret = 0;
 	struct scm_register_core reg_data;
 	struct msm_dcvs_core_param *p = NULL;
-	struct msm_dcvs_freq_entry *f = NULL;
 
 	p = kzalloc(PAGE_ALIGN(sizeof(struct msm_dcvs_core_param)), GFP_KERNEL);
 	if (!p)
 		return -ENOMEM;
 
-	f = kzalloc(PAGE_ALIGN(sizeof(struct msm_dcvs_freq_entry) *
-				param->num_freq), GFP_KERNEL);
-	if (!f) {
-		kfree(p);
-		return -ENOMEM;
-	}
-
 	memcpy(p, param, sizeof(struct msm_dcvs_core_param));
-	memcpy(f, freq, sizeof(struct msm_dcvs_freq_entry) * param->num_freq);
 
 	reg_data.core_id = core_id;
-	reg_data.group_id = group_id;
 	reg_data.core_param_phy = virt_to_phys(p);
-	reg_data.freq_phy = virt_to_phys(f);
 
 	ret = scm_call(SCM_SVC_DCVS, DCVS_CMD_REGISTER_CORE,
 			&reg_data, sizeof(reg_data), NULL, 0);
 
-	kfree(f);
 	kfree(p);
 
 	return ret;
@@ -137,7 +118,6 @@
 	if (!p)
 		return -ENOMEM;
 
-
 	p->type = MSM_DCVS_ALGO_DCVS_PARAM;
 	memcpy(&p->u.dcvs_param, param, sizeof(struct msm_dcvs_algo_param));
 
@@ -178,6 +158,60 @@
 }
 EXPORT_SYMBOL(msm_mpd_scm_set_algo_params);
 
+int msm_dcvs_scm_set_power_params(uint32_t core_id,
+		struct msm_dcvs_power_params *pwr_param,
+		struct msm_dcvs_freq_entry *freq_entry,
+		struct msm_dcvs_energy_curve_coeffs *coeffs)
+{
+	int ret = 0;
+	struct scm_pwr_param pwr;
+	struct msm_dcvs_power_params *pwrt = NULL;
+	struct msm_dcvs_freq_entry *freqt = NULL;
+	struct msm_dcvs_energy_curve_coeffs *coefft = NULL;
+
+	pwrt = kzalloc(PAGE_ALIGN(sizeof(struct msm_dcvs_power_params)),
+			GFP_KERNEL);
+	if (!pwrt)
+		return -ENOMEM;
+
+	freqt = kzalloc(PAGE_ALIGN(sizeof(struct msm_dcvs_freq_entry)
+				* pwr_param->num_freq),
+			GFP_KERNEL);
+	if (!freqt) {
+		kfree(pwrt);
+		return -ENOMEM;
+	}
+
+	coefft = kzalloc(PAGE_ALIGN(
+				sizeof(struct msm_dcvs_energy_curve_coeffs)),
+				GFP_KERNEL);
+	if (!coefft) {
+		kfree(pwrt);
+		kfree(freqt);
+		return -ENOMEM;
+	}
+
+	memcpy(pwrt, pwr_param, sizeof(struct msm_dcvs_power_params));
+	memcpy(freqt, freq_entry,
+			sizeof(struct msm_dcvs_freq_entry)*pwr_param->num_freq);
+	memcpy(coefft, coeffs, sizeof(struct msm_dcvs_energy_curve_coeffs));
+
+	pwr.core_id = core_id;
+	pwr.pwr_param_phy = virt_to_phys(pwrt);
+	pwr.freq_phy = virt_to_phys(freqt);
+	pwr.coeffs_phy = virt_to_phys(coefft);
+
+	ret = scm_call(SCM_SVC_DCVS, DCVS_CMD_SET_POWER_PARAM,
+			&pwr, sizeof(pwr), NULL, 0);
+
+	kfree(pwrt);
+	kfree(freqt);
+	kfree(coefft);
+
+	return ret;
+}
+EXPORT_SYMBOL(msm_dcvs_scm_set_power_params);
+
 int msm_dcvs_scm_event(uint32_t core_id,
 		enum msm_dcvs_scm_event event_id,
 		uint32_t param0, uint32_t param1,
diff --git a/drivers/cpufreq/cpufreq_gov_msm.c b/drivers/cpufreq/cpufreq_gov_msm.c
index 9c49f80..4eeff35 100644
--- a/drivers/cpufreq/cpufreq_gov_msm.c
+++ b/drivers/cpufreq/cpufreq_gov_msm.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, 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
@@ -138,7 +138,6 @@
 {
 	int ret = 0;
 	int cpu;
-	uint32_t group_id = 0x43505530; /* CPU0 */
 	struct msm_dcvs_core_info *core = NULL;
 
 	core = pdev->dev.platform_data;
@@ -146,7 +145,7 @@
 	for_each_possible_cpu(cpu) {
 		mutex_init(&per_cpu(gov_mutex, cpu));
 		snprintf(core_name[cpu], 10, "cpu%d", cpu);
-		ret = msm_dcvs_register_core(core_name[cpu], group_id, core);
+		ret = msm_dcvs_register_core(core_name[cpu], core);
 		if (ret)
 			pr_err("Unable to register core for %d\n", cpu);
 	}
diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c
index 3d1fbc8..8361430 100644
--- a/drivers/gpu/msm/adreno.c
+++ b/drivers/gpu/msm/adreno.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2002,2007-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2002,2007-2012, 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
@@ -865,15 +865,15 @@
 	for_each_child_of_node(node, child)
 		count++;
 
-	info->core_param.num_freq = count;
+	info->power_param.num_freq = count;
 
-	info->freq_tbl = kzalloc(info->core_param.num_freq *
+	info->freq_tbl = kzalloc(info->power_param.num_freq *
 			sizeof(struct msm_dcvs_freq_entry),
 			GFP_KERNEL);
 
 	if (info->freq_tbl == NULL) {
 		KGSL_CORE_ERR("kzalloc(%d) failed\n",
-			info->core_param.num_freq *
+			info->power_param.num_freq *
 			sizeof(struct msm_dcvs_freq_entry));
 		ret = -ENOMEM;
 		goto err;
@@ -885,7 +885,7 @@
 		if (adreno_of_read_property(child, "reg", &index))
 			goto err;
 
-		if (index >= info->core_param.num_freq) {
+		if (index >= info->power_param.num_freq) {
 			KGSL_CORE_ERR("DCVS freq entry %d is out of range\n",
 				index);
 			continue;
@@ -895,43 +895,96 @@
 			&info->freq_tbl[index].freq))
 			goto err;
 
-		if (adreno_of_read_property(child, "qcom,idle-energy",
-			&info->freq_tbl[index].idle_energy))
-			info->freq_tbl[index].idle_energy = 0;
+		if (adreno_of_read_property(child, "qcom,voltage",
+			&info->freq_tbl[index].voltage))
+			info->freq_tbl[index].voltage = 0;
 
-		if (adreno_of_read_property(child, "qcom,active-energy",
-			&info->freq_tbl[index].active_energy))
-			info->freq_tbl[index].active_energy = 0;
+		if (adreno_of_read_property(child, "qcom,is_trans_level",
+			&info->freq_tbl[index].is_trans_level))
+			info->freq_tbl[index].is_trans_level = 0;
+
+		if (adreno_of_read_property(child, "qcom,active-energy-offset",
+			&info->freq_tbl[index].active_energy_offset))
+			info->freq_tbl[index].active_energy_offset = 0;
+
+		if (adreno_of_read_property(child, "qcom,leakage-energy-offset",
+			&info->freq_tbl[index].leakage_energy_offset))
+			info->freq_tbl[index].leakage_energy_offset = 0;
 	}
 
-	if (adreno_of_read_property(node, "qcom,core-max-time-us",
-		&info->core_param.max_time_us))
-		goto err;
-
-	if (adreno_of_read_property(node, "qcom,algo-slack-time-us",
-		&info->algo_param.slack_time_us))
+	if (adreno_of_read_property(node, "qcom,core-core-type",
+		&info->core_param.core_type))
 		goto err;
 
 	if (adreno_of_read_property(node, "qcom,algo-disable-pc-threshold",
 		&info->algo_param.disable_pc_threshold))
 		goto err;
-
-	if (adreno_of_read_property(node, "qcom,algo-ss-window-size",
-		&info->algo_param.ss_window_size))
+	if (adreno_of_read_property(node, "qcom,algo-em-win-size-min-us",
+		&info->algo_param.em_win_size_min_us))
 		goto err;
-
-	if (adreno_of_read_property(node, "qcom,algo-ss-util-pct",
-		&info->algo_param.ss_util_pct))
+	if (adreno_of_read_property(node, "qcom,algo-em-win-size-max-us",
+		&info->algo_param.em_win_size_max_us))
 		goto err;
-
 	if (adreno_of_read_property(node, "qcom,algo-em-max-util-pct",
 		&info->algo_param.em_max_util_pct))
 		goto err;
-
+	if (adreno_of_read_property(node, "qcom,algo-group-id",
+		&info->algo_param.group_id))
+		goto err;
+	if (adreno_of_read_property(node, "qcom,algo-max-freq-chg-time-us",
+		&info->algo_param.max_freq_chg_time_us))
+		goto err;
+	if (adreno_of_read_property(node, "qcom,algo-slack-mode-dynamic",
+		&info->algo_param.slack_mode_dynamic))
+		goto err;
+	if (adreno_of_read_property(node, "qcom,algo-slack-weight-thresh-pct",
+		&info->algo_param.slack_weight_thresh_pct))
+		goto err;
+	if (adreno_of_read_property(node, "qcom,algo-slack-time-min-us",
+		&info->algo_param.slack_time_min_us))
+		goto err;
+	if (adreno_of_read_property(node, "qcom,algo-slack-time-max-us",
+		&info->algo_param.slack_time_max_us))
+		goto err;
+	if (adreno_of_read_property(node, "qcom,algo-ss-win-size-min-us",
+		&info->algo_param.ss_win_size_min_us))
+		goto err;
+	if (adreno_of_read_property(node, "qcom,algo-ss-win-size-max-us",
+		&info->algo_param.ss_win_size_max_us))
+		goto err;
+	if (adreno_of_read_property(node, "qcom,algo-ss-util-pct",
+		&info->algo_param.ss_util_pct))
+		goto err;
 	if (adreno_of_read_property(node, "qcom,algo-ss-iobusy-conv",
 		&info->algo_param.ss_iobusy_conv))
 		goto err;
 
+	if (adreno_of_read_property(node, "qcom,energy-active-coeff-a",
+		&info->energy_coeffs.active_coeff_a))
+		goto err;
+	if (adreno_of_read_property(node, "qcom,energy-active-coeff-b",
+		&info->energy_coeffs.active_coeff_b))
+		goto err;
+	if (adreno_of_read_property(node, "qcom,energy-active-coeff-c",
+		&info->energy_coeffs.active_coeff_c))
+		goto err;
+	if (adreno_of_read_property(node, "qcom,energy-leakage-coeff-a",
+		&info->energy_coeffs.leakage_coeff_a))
+		goto err;
+	if (adreno_of_read_property(node, "qcom,energy-leakage-coeff-b",
+		&info->energy_coeffs.leakage_coeff_b))
+		goto err;
+	if (adreno_of_read_property(node, "qcom,energy-leakage-coeff-c",
+		&info->energy_coeffs.leakage_coeff_c))
+		goto err;
+	if (adreno_of_read_property(node, "qcom,energy-leakage-coeff-d",
+		&info->energy_coeffs.leakage_coeff_d))
+		goto err;
+
+	if (adreno_of_read_property(node, "qcom,power-current-temp",
+		&info->power_param.current_temp))
+		goto err;
+
 	return info;
 
 err:
diff --git a/drivers/gpu/msm/kgsl_pwrscale_msm.c b/drivers/gpu/msm/kgsl_pwrscale_msm.c
index c6f8b1b..4b08e52 100644
--- a/drivers/gpu/msm/kgsl_pwrscale_msm.c
+++ b/drivers/gpu/msm/kgsl_pwrscale_msm.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, 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
@@ -148,9 +148,8 @@
 	/* Fill in frequency table from low to high, reversing order. */
 	low_level = pwr->num_pwrlevels - KGSL_PWRLEVEL_LAST_OFFSET;
 	for (i = 0; i <= low_level; i++)
-		tbl[i].freq =
-			pwr->pwrlevels[low_level - i].gpu_freq / 1000;
-	ret = msm_dcvs_register_core(device->name, 0, priv->core_info);
+		tbl[i].freq = pwr->pwrlevels[low_level - i].gpu_freq / 1000;
+	ret = msm_dcvs_register_core(device->name, priv->core_info);
 	if (ret) {
 		KGSL_PWR_ERR(device, "msm_dcvs_register_core failed");
 		goto err;