Loading Documentation/devicetree/bindings/arm/msm/lpm-levels.txt +24 −2 Original line number Diff line number Diff line Loading @@ -28,6 +28,14 @@ Required properties: mask of the cluster mode in the composite state ID used to define cluster low power modes in PSCI. Optional properties: - qcom,disable-prediction: This property is used to indicate the LPM governor will not use LPM prediction for this cluster. - qcom,clstr-tmr-add: This property is used as correction timer for wrong prediction by lpm prediction algorithm for cluster predictions. This value should be between 100 to 1500. Higher values would mean longer time staying in shallower state before waking up to select a deeper state in case of wrong prediction. qcom,pm-cluster contains qcom,pm-cluster-level nodes which identify the various low power modes that the cluster can enter. The qcom,pm-cluster node should also include another cluster node or a cpu Loading Loading @@ -77,8 +85,22 @@ that share the parameters.It contains the following properties. - qcom,pm-cpu-levels: The different low power modes that a CPU could enter. The following section explains the required properties of this node. -qcom,use-prediction: This optional property is used to indicate the the LPM governor is to apply sleep prediction to this cluster. Optional properties: - qcom,disable-prediction: This property is used to indicate the LPM governor is to disable sleep prediction to this cpu. - qcom,ref-stddev: This property is used as reference standard deviation in lpm prediction algorithm. This value should be between 100 to 1000. Higher value would result in more predictions and thereby resulting in shallower low power modes. - qcom,tmr-add: This property is used as correction timer for wrong prediction by lpm prediction algorithm. This value should be between 100 to 1500. Higher values would mean longer time staying in shallower state before waking up to select a deeper state in case of wrong prediction. - qcom,ref-premature-cnt: This property is used as reference premature count to predict next sleep state by the prediction algorithm. This value should be between 1 to 5. Higher value for this parameter would result in less predictions to disallow deeper low power modes. [Node bindings for qcom,pm-cpu-levels] Required properties: Loading drivers/cpuidle/lpm-levels-of.c +44 −6 Original line number Diff line number Diff line /* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved. /* Copyright (c) 2014-2018, 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 Loading Loading @@ -178,8 +178,8 @@ static ssize_t lpm_latency_show(struct kobject *kobj, struct kernel_param kp; struct lpm_level_avail *avail = get_avail_ptr(kobj, attr); if (!avail) pr_info("Error\n"); if (WARN_ON(!avail)) return -EINVAL; kp.arg = &avail->latency_us; Loading @@ -197,8 +197,15 @@ ssize_t lpm_enable_show(struct kobject *kobj, struct kobj_attribute *attr, { int ret = 0; struct kernel_param kp; struct lpm_level_avail *avail = get_avail_ptr(kobj, attr); if (WARN_ON(!avail)) return -EINVAL; kp.arg = get_enabled_ptr(attr, avail); if (WARN_ON(!kp.arg)) return -EINVAL; kp.arg = get_enabled_ptr(attr, get_avail_ptr(kobj, attr)); ret = param_get_bool(buf, &kp); if (ret > 0) { strlcat(buf, "\n", PAGE_SIZE); Loading Loading @@ -453,6 +460,17 @@ static int parse_cluster_params(struct device_node *node, if (ret) goto fail; key = "qcom,disable-prediction"; c->lpm_prediction = !(of_property_read_bool(node, key)); if (c->lpm_prediction) { key = "qcom,clstr-tmr-add"; ret = of_property_read_u32(node, key, &c->tmr_add); if (ret || c->tmr_add < TIMER_ADD_LOW || c->tmr_add > TIMER_ADD_HIGH) c->tmr_add = DEFAULT_TIMER_ADD; } /* Set default_level to 0 as default */ c->default_level = 0; Loading Loading @@ -713,8 +731,28 @@ static int parse_cpu_levels(struct device_node *node, struct lpm_cluster *c) if (ret) goto failed_parse_params; key = "qcom,use-prediction"; cpu->lpm_prediction = of_property_read_bool(node, key); key = "qcom,disable-prediction"; cpu->lpm_prediction = !(of_property_read_bool(node, key)); if (cpu->lpm_prediction) { key = "qcom,ref-stddev"; ret = of_property_read_u32(node, key, &cpu->ref_stddev); if (ret || cpu->ref_stddev < STDDEV_LOW || cpu->ref_stddev > STDDEV_HIGH) cpu->ref_stddev = DEFAULT_STDDEV; key = "qcom,tmr-add"; ret = of_property_read_u32(node, key, &cpu->tmr_add); if (ret || cpu->tmr_add < TIMER_ADD_LOW || cpu->tmr_add > TIMER_ADD_HIGH) cpu->tmr_add = DEFAULT_TIMER_ADD; key = "qcom,ref-premature-cnt"; ret = of_property_read_u32(node, key, &cpu->ref_premature_cnt); if (ret || cpu->ref_premature_cnt < PREMATURE_CNT_LOW || cpu->ref_premature_cnt > PREMATURE_CNT_HIGH) cpu->ref_premature_cnt = DEFAULT_PREMATURE_CNT; } key = "parse_cpu"; ret = parse_cpu(node, cpu); Loading drivers/cpuidle/lpm-levels.c +21 −25 Original line number Diff line number Diff line Loading @@ -92,15 +92,6 @@ struct lpm_cluster *lpm_root_node; static bool lpm_prediction = true; module_param_named(lpm_prediction, lpm_prediction, bool, 0664); static uint32_t ref_stddev = 500; module_param_named(ref_stddev, ref_stddev, uint, 0664); static uint32_t tmr_add = 1000; module_param_named(tmr_add, tmr_add, uint, 0664); static uint32_t ref_premature_cnt = 1; module_param_named(ref_premature_cnt, ref_premature_cnt, uint, 0664); static uint32_t bias_hyst; module_param_named(bias_hyst, bias_hyst, uint, 0664); Loading Loading @@ -496,7 +487,7 @@ static uint64_t lpm_cpuidle_predict(struct cpuidle_device *dev, * ignore one maximum sample and retry */ if (((avg > stddev * 6) && (divisor >= (MAXSAMPLES - 1))) || stddev <= ref_stddev) { || stddev <= cpu->ref_stddev) { history->stime = ktime_to_us(ktime_get()) + avg; return avg; } else if (divisor > (MAXSAMPLES - 1)) { Loading @@ -521,7 +512,7 @@ static uint64_t lpm_cpuidle_predict(struct cpuidle_device *dev, total += history->resi[i]; } } if (failed >= ref_premature_cnt) { if (failed >= cpu->ref_premature_cnt) { *idx_restrict = j; do_div(total, failed); for (i = 0; i < j; i++) { Loading @@ -545,8 +536,9 @@ static uint64_t lpm_cpuidle_predict(struct cpuidle_device *dev, static inline void invalidate_predict_history(struct cpuidle_device *dev) { struct lpm_history *history = &per_cpu(hist, dev->cpu); struct lpm_cpu *lpm_cpu = per_cpu(cpu_lpm, dev->cpu); if (!lpm_prediction) if (!lpm_prediction || !lpm_cpu->lpm_prediction) return; if (history->hinvalid) { Loading @@ -561,8 +553,9 @@ static void clear_predict_history(void) struct lpm_history *history; int i; unsigned int cpu; struct lpm_cpu *lpm_cpu = per_cpu(cpu_lpm, raw_smp_processor_id()); if (!lpm_prediction) if (!lpm_prediction || !lpm_cpu->lpm_prediction) return; for_each_possible_cpu(cpu) { Loading Loading @@ -681,8 +674,8 @@ static int cpu_power_select(struct cpuidle_device *dev, if ((predicted || (idx_restrict != (cpu->nlevels + 1))) && ((best_level >= 0) && (best_level < (cpu->nlevels-1)))) { htime = predicted + tmr_add; if (htime == tmr_add) htime = predicted + cpu->tmr_add; if (htime == cpu->tmr_add) htime = idx_restrict_time; else if (htime > max_residency[best_level]) htime = max_residency[best_level]; Loading Loading @@ -746,14 +739,14 @@ static uint64_t get_cluster_sleep_time(struct lpm_cluster *cluster, next_event.tv64 = next_event_c->tv64; } if (from_idle && lpm_prediction) { if (from_idle && lpm_prediction && cluster->lpm_prediction) { history = &per_cpu(hist, cpu); if (history->stime && (history->stime < prediction)) prediction = history->stime; } } if (from_idle && lpm_prediction) { if (from_idle && lpm_prediction && cluster->lpm_prediction) { if (prediction > ktime_to_us(ktime_get())) *pred_time = prediction - ktime_to_us(ktime_get()); } Loading @@ -772,7 +765,7 @@ static int cluster_predict(struct lpm_cluster *cluster, struct cluster_history *history = &cluster->history; int64_t cur_time = ktime_to_us(ktime_get()); if (!lpm_prediction) if (!lpm_prediction || !cluster->lpm_prediction) return 0; if (history->hinvalid) { Loading Loading @@ -847,7 +840,7 @@ static void update_cluster_history(struct cluster_history *history, int idx) struct lpm_cluster *cluster = container_of(history, struct lpm_cluster, history); if (!lpm_prediction) if (!lpm_prediction || !cluster->lpm_prediction) return; if ((history->entry_idx == -1) || (history->entry_idx == idx)) { Loading Loading @@ -908,7 +901,7 @@ static void clear_cl_predict_history(void) struct lpm_cluster *cluster = lpm_root_node; struct list_head *list; if (!lpm_prediction) if (!lpm_prediction || !cluster->lpm_prediction) return; clear_cl_history_each(&cluster->history); Loading Loading @@ -1034,7 +1027,7 @@ static int cluster_configure(struct lpm_cluster *cluster, int idx, cluster->child_cpus.bits[0], from_idle); lpm_stats_cluster_enter(cluster->stats, idx); if (from_idle && lpm_prediction) if (from_idle && lpm_prediction && cluster->lpm_prediction) update_cluster_history_time(&cluster->history, idx, ktime_to_us(ktime_get())); } Loading Loading @@ -1066,7 +1059,8 @@ static int cluster_configure(struct lpm_cluster *cluster, int idx, if (predicted && (idx < (cluster->nlevels - 1))) { struct power_params *pwr_params = &cluster->levels[idx].pwr; clusttimer_start(cluster, pwr_params->max_residency + tmr_add); clusttimer_start(cluster, pwr_params->max_residency + cluster->tmr_add); } return 0; Loading Loading @@ -1120,7 +1114,8 @@ static void cluster_prepare(struct lpm_cluster *cluster, &cluster->levels[0].pwr; clusttimer_start(cluster, pwr_params->max_residency + tmr_add); pwr_params->max_residency + cluster->tmr_add); goto failed; } Loading Loading @@ -1335,8 +1330,9 @@ static void update_history(struct cpuidle_device *dev, int idx) { struct lpm_history *history = &per_cpu(hist, dev->cpu); uint32_t tmr = 0; struct lpm_cpu *lpm_cpu = per_cpu(cpu_lpm, dev->cpu); if (!lpm_prediction) if (!lpm_prediction || !lpm_cpu->lpm_prediction) return; if (history->htmr_wkup) { Loading Loading @@ -1394,7 +1390,7 @@ static int lpm_cpuidle_enter(struct cpuidle_device *dev, update_history(dev, idx); trace_cpu_idle_exit(idx, success); local_irq_enable(); if (lpm_prediction) { if (lpm_prediction && cpu->lpm_prediction) { histtimer_cancel(); clusttimer_cancel(); } Loading drivers/cpuidle/lpm-levels.h +15 −1 Original line number Diff line number Diff line /* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved. /* Copyright (c) 2014-2018, 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 Loading @@ -16,6 +16,15 @@ #define NR_LPM_LEVELS 8 #define MAXSAMPLES 5 #define CLUST_SMPL_INVLD_TIME 40000 #define DEFAULT_PREMATURE_CNT 3 #define DEFAULT_STDDEV 100 #define DEFAULT_TIMER_ADD 100 #define TIMER_ADD_LOW 100 #define TIMER_ADD_HIGH 1500 #define STDDEV_LOW 100 #define STDDEV_HIGH 1000 #define PREMATURE_CNT_LOW 1 #define PREMATURE_CNT_HIGH 5 struct power_params { uint32_t latency_us; /* Enter + Exit latency */ Loading Loading @@ -43,6 +52,9 @@ struct lpm_cpu { int nlevels; unsigned int psci_mode_shift; unsigned int psci_mode_mask; uint32_t ref_stddev; uint32_t ref_premature_cnt; uint32_t tmr_add; bool lpm_prediction; struct cpuidle_driver *drv; struct lpm_cluster *parent; Loading Loading @@ -97,6 +109,8 @@ struct lpm_cluster { int min_child_level; int default_level; int last_level; uint32_t tmr_add; bool lpm_prediction; struct list_head cpu; spinlock_t sync_lock; struct cpumask child_cpus; Loading Loading
Documentation/devicetree/bindings/arm/msm/lpm-levels.txt +24 −2 Original line number Diff line number Diff line Loading @@ -28,6 +28,14 @@ Required properties: mask of the cluster mode in the composite state ID used to define cluster low power modes in PSCI. Optional properties: - qcom,disable-prediction: This property is used to indicate the LPM governor will not use LPM prediction for this cluster. - qcom,clstr-tmr-add: This property is used as correction timer for wrong prediction by lpm prediction algorithm for cluster predictions. This value should be between 100 to 1500. Higher values would mean longer time staying in shallower state before waking up to select a deeper state in case of wrong prediction. qcom,pm-cluster contains qcom,pm-cluster-level nodes which identify the various low power modes that the cluster can enter. The qcom,pm-cluster node should also include another cluster node or a cpu Loading Loading @@ -77,8 +85,22 @@ that share the parameters.It contains the following properties. - qcom,pm-cpu-levels: The different low power modes that a CPU could enter. The following section explains the required properties of this node. -qcom,use-prediction: This optional property is used to indicate the the LPM governor is to apply sleep prediction to this cluster. Optional properties: - qcom,disable-prediction: This property is used to indicate the LPM governor is to disable sleep prediction to this cpu. - qcom,ref-stddev: This property is used as reference standard deviation in lpm prediction algorithm. This value should be between 100 to 1000. Higher value would result in more predictions and thereby resulting in shallower low power modes. - qcom,tmr-add: This property is used as correction timer for wrong prediction by lpm prediction algorithm. This value should be between 100 to 1500. Higher values would mean longer time staying in shallower state before waking up to select a deeper state in case of wrong prediction. - qcom,ref-premature-cnt: This property is used as reference premature count to predict next sleep state by the prediction algorithm. This value should be between 1 to 5. Higher value for this parameter would result in less predictions to disallow deeper low power modes. [Node bindings for qcom,pm-cpu-levels] Required properties: Loading
drivers/cpuidle/lpm-levels-of.c +44 −6 Original line number Diff line number Diff line /* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved. /* Copyright (c) 2014-2018, 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 Loading Loading @@ -178,8 +178,8 @@ static ssize_t lpm_latency_show(struct kobject *kobj, struct kernel_param kp; struct lpm_level_avail *avail = get_avail_ptr(kobj, attr); if (!avail) pr_info("Error\n"); if (WARN_ON(!avail)) return -EINVAL; kp.arg = &avail->latency_us; Loading @@ -197,8 +197,15 @@ ssize_t lpm_enable_show(struct kobject *kobj, struct kobj_attribute *attr, { int ret = 0; struct kernel_param kp; struct lpm_level_avail *avail = get_avail_ptr(kobj, attr); if (WARN_ON(!avail)) return -EINVAL; kp.arg = get_enabled_ptr(attr, avail); if (WARN_ON(!kp.arg)) return -EINVAL; kp.arg = get_enabled_ptr(attr, get_avail_ptr(kobj, attr)); ret = param_get_bool(buf, &kp); if (ret > 0) { strlcat(buf, "\n", PAGE_SIZE); Loading Loading @@ -453,6 +460,17 @@ static int parse_cluster_params(struct device_node *node, if (ret) goto fail; key = "qcom,disable-prediction"; c->lpm_prediction = !(of_property_read_bool(node, key)); if (c->lpm_prediction) { key = "qcom,clstr-tmr-add"; ret = of_property_read_u32(node, key, &c->tmr_add); if (ret || c->tmr_add < TIMER_ADD_LOW || c->tmr_add > TIMER_ADD_HIGH) c->tmr_add = DEFAULT_TIMER_ADD; } /* Set default_level to 0 as default */ c->default_level = 0; Loading Loading @@ -713,8 +731,28 @@ static int parse_cpu_levels(struct device_node *node, struct lpm_cluster *c) if (ret) goto failed_parse_params; key = "qcom,use-prediction"; cpu->lpm_prediction = of_property_read_bool(node, key); key = "qcom,disable-prediction"; cpu->lpm_prediction = !(of_property_read_bool(node, key)); if (cpu->lpm_prediction) { key = "qcom,ref-stddev"; ret = of_property_read_u32(node, key, &cpu->ref_stddev); if (ret || cpu->ref_stddev < STDDEV_LOW || cpu->ref_stddev > STDDEV_HIGH) cpu->ref_stddev = DEFAULT_STDDEV; key = "qcom,tmr-add"; ret = of_property_read_u32(node, key, &cpu->tmr_add); if (ret || cpu->tmr_add < TIMER_ADD_LOW || cpu->tmr_add > TIMER_ADD_HIGH) cpu->tmr_add = DEFAULT_TIMER_ADD; key = "qcom,ref-premature-cnt"; ret = of_property_read_u32(node, key, &cpu->ref_premature_cnt); if (ret || cpu->ref_premature_cnt < PREMATURE_CNT_LOW || cpu->ref_premature_cnt > PREMATURE_CNT_HIGH) cpu->ref_premature_cnt = DEFAULT_PREMATURE_CNT; } key = "parse_cpu"; ret = parse_cpu(node, cpu); Loading
drivers/cpuidle/lpm-levels.c +21 −25 Original line number Diff line number Diff line Loading @@ -92,15 +92,6 @@ struct lpm_cluster *lpm_root_node; static bool lpm_prediction = true; module_param_named(lpm_prediction, lpm_prediction, bool, 0664); static uint32_t ref_stddev = 500; module_param_named(ref_stddev, ref_stddev, uint, 0664); static uint32_t tmr_add = 1000; module_param_named(tmr_add, tmr_add, uint, 0664); static uint32_t ref_premature_cnt = 1; module_param_named(ref_premature_cnt, ref_premature_cnt, uint, 0664); static uint32_t bias_hyst; module_param_named(bias_hyst, bias_hyst, uint, 0664); Loading Loading @@ -496,7 +487,7 @@ static uint64_t lpm_cpuidle_predict(struct cpuidle_device *dev, * ignore one maximum sample and retry */ if (((avg > stddev * 6) && (divisor >= (MAXSAMPLES - 1))) || stddev <= ref_stddev) { || stddev <= cpu->ref_stddev) { history->stime = ktime_to_us(ktime_get()) + avg; return avg; } else if (divisor > (MAXSAMPLES - 1)) { Loading @@ -521,7 +512,7 @@ static uint64_t lpm_cpuidle_predict(struct cpuidle_device *dev, total += history->resi[i]; } } if (failed >= ref_premature_cnt) { if (failed >= cpu->ref_premature_cnt) { *idx_restrict = j; do_div(total, failed); for (i = 0; i < j; i++) { Loading @@ -545,8 +536,9 @@ static uint64_t lpm_cpuidle_predict(struct cpuidle_device *dev, static inline void invalidate_predict_history(struct cpuidle_device *dev) { struct lpm_history *history = &per_cpu(hist, dev->cpu); struct lpm_cpu *lpm_cpu = per_cpu(cpu_lpm, dev->cpu); if (!lpm_prediction) if (!lpm_prediction || !lpm_cpu->lpm_prediction) return; if (history->hinvalid) { Loading @@ -561,8 +553,9 @@ static void clear_predict_history(void) struct lpm_history *history; int i; unsigned int cpu; struct lpm_cpu *lpm_cpu = per_cpu(cpu_lpm, raw_smp_processor_id()); if (!lpm_prediction) if (!lpm_prediction || !lpm_cpu->lpm_prediction) return; for_each_possible_cpu(cpu) { Loading Loading @@ -681,8 +674,8 @@ static int cpu_power_select(struct cpuidle_device *dev, if ((predicted || (idx_restrict != (cpu->nlevels + 1))) && ((best_level >= 0) && (best_level < (cpu->nlevels-1)))) { htime = predicted + tmr_add; if (htime == tmr_add) htime = predicted + cpu->tmr_add; if (htime == cpu->tmr_add) htime = idx_restrict_time; else if (htime > max_residency[best_level]) htime = max_residency[best_level]; Loading Loading @@ -746,14 +739,14 @@ static uint64_t get_cluster_sleep_time(struct lpm_cluster *cluster, next_event.tv64 = next_event_c->tv64; } if (from_idle && lpm_prediction) { if (from_idle && lpm_prediction && cluster->lpm_prediction) { history = &per_cpu(hist, cpu); if (history->stime && (history->stime < prediction)) prediction = history->stime; } } if (from_idle && lpm_prediction) { if (from_idle && lpm_prediction && cluster->lpm_prediction) { if (prediction > ktime_to_us(ktime_get())) *pred_time = prediction - ktime_to_us(ktime_get()); } Loading @@ -772,7 +765,7 @@ static int cluster_predict(struct lpm_cluster *cluster, struct cluster_history *history = &cluster->history; int64_t cur_time = ktime_to_us(ktime_get()); if (!lpm_prediction) if (!lpm_prediction || !cluster->lpm_prediction) return 0; if (history->hinvalid) { Loading Loading @@ -847,7 +840,7 @@ static void update_cluster_history(struct cluster_history *history, int idx) struct lpm_cluster *cluster = container_of(history, struct lpm_cluster, history); if (!lpm_prediction) if (!lpm_prediction || !cluster->lpm_prediction) return; if ((history->entry_idx == -1) || (history->entry_idx == idx)) { Loading Loading @@ -908,7 +901,7 @@ static void clear_cl_predict_history(void) struct lpm_cluster *cluster = lpm_root_node; struct list_head *list; if (!lpm_prediction) if (!lpm_prediction || !cluster->lpm_prediction) return; clear_cl_history_each(&cluster->history); Loading Loading @@ -1034,7 +1027,7 @@ static int cluster_configure(struct lpm_cluster *cluster, int idx, cluster->child_cpus.bits[0], from_idle); lpm_stats_cluster_enter(cluster->stats, idx); if (from_idle && lpm_prediction) if (from_idle && lpm_prediction && cluster->lpm_prediction) update_cluster_history_time(&cluster->history, idx, ktime_to_us(ktime_get())); } Loading Loading @@ -1066,7 +1059,8 @@ static int cluster_configure(struct lpm_cluster *cluster, int idx, if (predicted && (idx < (cluster->nlevels - 1))) { struct power_params *pwr_params = &cluster->levels[idx].pwr; clusttimer_start(cluster, pwr_params->max_residency + tmr_add); clusttimer_start(cluster, pwr_params->max_residency + cluster->tmr_add); } return 0; Loading Loading @@ -1120,7 +1114,8 @@ static void cluster_prepare(struct lpm_cluster *cluster, &cluster->levels[0].pwr; clusttimer_start(cluster, pwr_params->max_residency + tmr_add); pwr_params->max_residency + cluster->tmr_add); goto failed; } Loading Loading @@ -1335,8 +1330,9 @@ static void update_history(struct cpuidle_device *dev, int idx) { struct lpm_history *history = &per_cpu(hist, dev->cpu); uint32_t tmr = 0; struct lpm_cpu *lpm_cpu = per_cpu(cpu_lpm, dev->cpu); if (!lpm_prediction) if (!lpm_prediction || !lpm_cpu->lpm_prediction) return; if (history->htmr_wkup) { Loading Loading @@ -1394,7 +1390,7 @@ static int lpm_cpuidle_enter(struct cpuidle_device *dev, update_history(dev, idx); trace_cpu_idle_exit(idx, success); local_irq_enable(); if (lpm_prediction) { if (lpm_prediction && cpu->lpm_prediction) { histtimer_cancel(); clusttimer_cancel(); } Loading
drivers/cpuidle/lpm-levels.h +15 −1 Original line number Diff line number Diff line /* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved. /* Copyright (c) 2014-2018, 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 Loading @@ -16,6 +16,15 @@ #define NR_LPM_LEVELS 8 #define MAXSAMPLES 5 #define CLUST_SMPL_INVLD_TIME 40000 #define DEFAULT_PREMATURE_CNT 3 #define DEFAULT_STDDEV 100 #define DEFAULT_TIMER_ADD 100 #define TIMER_ADD_LOW 100 #define TIMER_ADD_HIGH 1500 #define STDDEV_LOW 100 #define STDDEV_HIGH 1000 #define PREMATURE_CNT_LOW 1 #define PREMATURE_CNT_HIGH 5 struct power_params { uint32_t latency_us; /* Enter + Exit latency */ Loading Loading @@ -43,6 +52,9 @@ struct lpm_cpu { int nlevels; unsigned int psci_mode_shift; unsigned int psci_mode_mask; uint32_t ref_stddev; uint32_t ref_premature_cnt; uint32_t tmr_add; bool lpm_prediction; struct cpuidle_driver *drv; struct lpm_cluster *parent; Loading Loading @@ -97,6 +109,8 @@ struct lpm_cluster { int min_child_level; int default_level; int last_level; uint32_t tmr_add; bool lpm_prediction; struct list_head cpu; spinlock_t sync_lock; struct cpumask child_cpus; Loading