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/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);