Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 873317b6 authored by qctecmdr Service's avatar qctecmdr Service Committed by Gerrit - the friendly Code Review server
Browse files

Merge "cpuidle: lpm-levels: Add premature count to module parameter"

parents 3dc33941 a2113881
Loading
Loading
Loading
Loading
+64 −50
Original line number Original line Diff line number Diff line
@@ -39,8 +39,8 @@
#include <linux/sched/stat.h>
#include <linux/sched/stat.h>
#include <soc/qcom/pm.h>
#include <soc/qcom/pm.h>
#include <soc/qcom/event_timer.h>
#include <soc/qcom/event_timer.h>
#include <soc/qcom/lpm_levels.h>
#include <soc/qcom/lpm-stats.h>
#include <soc/qcom/lpm-stats.h>
#include <soc/qcom/system_pm.h>
#include <soc/qcom/minidump.h>
#include <soc/qcom/minidump.h>
#include <asm/arch_timer.h>
#include <asm/arch_timer.h>
#include <asm/suspend.h>
#include <asm/suspend.h>
@@ -79,6 +79,9 @@ struct lpm_debug {
	uint32_t arg4;
	uint32_t arg4;
};
};


static struct system_pm_ops *sys_pm_ops;


struct lpm_cluster *lpm_root_node;
struct lpm_cluster *lpm_root_node;


#define MAXSAMPLES 5
#define MAXSAMPLES 5
@@ -93,6 +96,8 @@ static uint32_t tmr_add = 1000;
module_param_named(tmr_add, tmr_add, uint, 0664);
module_param_named(tmr_add, tmr_add, uint, 0664);


static uint32_t ref_premature_cnt = 1;
static uint32_t ref_premature_cnt = 1;
module_param_named(ref_premature_cnt, ref_premature_cnt, uint, 0664);

static uint32_t bias_hyst;
static uint32_t bias_hyst;
module_param_named(bias_hyst, bias_hyst, uint, 0664);
module_param_named(bias_hyst, bias_hyst, uint, 0664);


@@ -123,11 +128,6 @@ static void cluster_prepare(struct lpm_cluster *cluster,
		const struct cpumask *cpu, int child_idx, bool from_idle,
		const struct cpumask *cpu, int child_idx, bool from_idle,
		int64_t time);
		int64_t time);


static int msm_pm_sleep_time_override;
module_param_named(sleep_time_override,
	msm_pm_sleep_time_override, int, 0664);
static uint64_t suspend_wake_time;

static bool print_parsed_dt;
static bool print_parsed_dt;
module_param_named(print_parsed_dt, print_parsed_dt, bool, 0664);
module_param_named(print_parsed_dt, print_parsed_dt, bool, 0664);


@@ -145,20 +145,15 @@ s32 msm_cpuidle_get_deep_idle_latency(void)
}
}
EXPORT_SYMBOL(msm_cpuidle_get_deep_idle_latency);
EXPORT_SYMBOL(msm_cpuidle_get_deep_idle_latency);


void lpm_suspend_wake_time(uint64_t wakeup_time)
uint32_t register_system_pm_ops(struct system_pm_ops *pm_ops)
{
{
	if (wakeup_time <= 0) {
	if (sys_pm_ops)
		suspend_wake_time = msm_pm_sleep_time_override;
		return -EUSERS;
		return;
	}


	if (msm_pm_sleep_time_override &&
	sys_pm_ops = pm_ops;
		(msm_pm_sleep_time_override < wakeup_time))

		suspend_wake_time = msm_pm_sleep_time_override;
	return 0;
	else
		suspend_wake_time = wakeup_time;
}
}
EXPORT_SYMBOL(lpm_suspend_wake_time);


static uint32_t least_cluster_latency(struct lpm_cluster *cluster,
static uint32_t least_cluster_latency(struct lpm_cluster *cluster,
					struct latency_level *lat_level)
					struct latency_level *lat_level)
@@ -703,28 +698,40 @@ static int cpu_power_select(struct cpuidle_device *dev,
	return best_level;
	return best_level;
}
}


static unsigned int get_next_online_cpu(bool from_idle)
{
	unsigned int cpu;
	ktime_t next_event;
	unsigned int next_cpu = raw_smp_processor_id();

	if (!from_idle)
		return next_cpu;
	next_event = KTIME_MAX;
	for_each_online_cpu(cpu) {
		ktime_t *next_event_c;

		next_event_c = get_next_event_cpu(cpu);
		if (*next_event_c < next_event) {
			next_event = *next_event_c;
			next_cpu = cpu;
		}
	}
	return next_cpu;
}

static uint64_t get_cluster_sleep_time(struct lpm_cluster *cluster,
static uint64_t get_cluster_sleep_time(struct lpm_cluster *cluster,
		struct cpumask *mask, bool from_idle, uint32_t *pred_time)
		bool from_idle, uint32_t *pred_time)
{
{
	int cpu;
	int cpu;
	int next_cpu = raw_smp_processor_id();
	ktime_t next_event;
	ktime_t next_event;
	struct cpumask online_cpus_in_cluster;
	struct cpumask online_cpus_in_cluster;
	struct lpm_history *history;
	struct lpm_history *history;
	int64_t prediction = LONG_MAX;
	int64_t prediction = LONG_MAX;


	next_event = KTIME_MAX;
	if (!from_idle)
	if (!suspend_wake_time)
		suspend_wake_time =  msm_pm_sleep_time_override;
	if (!from_idle) {
		if (mask)
			cpumask_copy(mask, cpumask_of(raw_smp_processor_id()));
		if (!suspend_wake_time)
		return ~0ULL;
		return ~0ULL;
		else
			return USEC_PER_SEC * suspend_wake_time;
	}


	next_event = KTIME_MAX;
	cpumask_and(&online_cpus_in_cluster,
	cpumask_and(&online_cpus_in_cluster,
			&cluster->num_children_in_sync, cpu_online_mask);
			&cluster->num_children_in_sync, cpu_online_mask);


@@ -732,10 +739,8 @@ static uint64_t get_cluster_sleep_time(struct lpm_cluster *cluster,
		ktime_t *next_event_c;
		ktime_t *next_event_c;


		next_event_c = get_next_event_cpu(cpu);
		next_event_c = get_next_event_cpu(cpu);
		if (*next_event_c < next_event) {
		if (*next_event_c < next_event)
			next_event = *next_event_c;
			next_event = *next_event_c;
			next_cpu = cpu;
		}


		if (from_idle && lpm_prediction) {
		if (from_idle && lpm_prediction) {
			history = &per_cpu(hist, cpu);
			history = &per_cpu(hist, cpu);
@@ -744,9 +749,6 @@ static uint64_t get_cluster_sleep_time(struct lpm_cluster *cluster,
		}
		}
	}
	}


	if (mask)
		cpumask_copy(mask, cpumask_of(next_cpu));

	if (from_idle && lpm_prediction) {
	if (from_idle && lpm_prediction) {
		if (prediction > ktime_to_us(ktime_get()))
		if (prediction > ktime_to_us(ktime_get()))
			*pred_time = prediction - ktime_to_us(ktime_get());
			*pred_time = prediction - ktime_to_us(ktime_get());
@@ -929,7 +931,7 @@ static int cluster_select(struct lpm_cluster *cluster, bool from_idle,
	if (!cluster)
	if (!cluster)
		return -EINVAL;
		return -EINVAL;


	sleep_us = (uint32_t)get_cluster_sleep_time(cluster, NULL,
	sleep_us = (uint32_t)get_cluster_sleep_time(cluster,
						from_idle, &cpupred_us);
						from_idle, &cpupred_us);


	if (from_idle) {
	if (from_idle) {
@@ -980,8 +982,12 @@ static int cluster_select(struct lpm_cluster *cluster, bool from_idle,
		if (suspend_in_progress && from_idle && level->notify_rpm)
		if (suspend_in_progress && from_idle && level->notify_rpm)
			continue;
			continue;


		if (level->notify_rpm && !system_sleep_allowed())
		if (level->notify_rpm) {
			if (!(sys_pm_ops && sys_pm_ops->sleep_allowed))
				continue;
				continue;
			if (!sys_pm_ops->sleep_allowed())
				continue;
		}


		best_level = i;
		best_level = i;


@@ -1015,6 +1021,11 @@ static int cluster_configure(struct lpm_cluster *cluster, int idx,
		bool from_idle, int predicted)
		bool from_idle, int predicted)
{
{
	struct lpm_cluster_level *level = &cluster->levels[idx];
	struct lpm_cluster_level *level = &cluster->levels[idx];
	struct cpumask online_cpus, cpumask;
	unsigned int cpu;

	cpumask_and(&online_cpus, &cluster->num_children_in_sync,
					cpu_online_mask);


	if (!cpumask_equal(&cluster->num_children_in_sync, &cluster->child_cpus)
	if (!cpumask_equal(&cluster->num_children_in_sync, &cluster->child_cpus)
			|| is_IPI_pending(&cluster->num_children_in_sync)) {
			|| is_IPI_pending(&cluster->num_children_in_sync)) {
@@ -1036,9 +1047,12 @@ static int cluster_configure(struct lpm_cluster *cluster, int idx,
	}
	}


	if (level->notify_rpm) {
	if (level->notify_rpm) {
		cpu = get_next_online_cpu(from_idle);
		cpumask_copy(&cpumask, cpumask_of(cpu));
		clear_predict_history();
		clear_predict_history();
		clear_cl_predict_history();
		clear_cl_predict_history();
		if (system_sleep_enter())
		if (sys_pm_ops && sys_pm_ops->enter)
			if ((sys_pm_ops->enter(&cpumask)))
				return -EBUSY;
				return -EBUSY;
	}
	}
	/* Notify cluster enter event after successfully config completion */
	/* Notify cluster enter event after successfully config completion */
@@ -1170,7 +1184,8 @@ static void cluster_unprepare(struct lpm_cluster *cluster,
	level = &cluster->levels[cluster->last_level];
	level = &cluster->levels[cluster->last_level];


	if (level->notify_rpm)
	if (level->notify_rpm)
		system_sleep_exit();
		if (sys_pm_ops && sys_pm_ops->exit)
			sys_pm_ops->exit();


	update_debug_pc_event(CLUSTER_EXIT, cluster->last_level,
	update_debug_pc_event(CLUSTER_EXIT, cluster->last_level,
			cluster->num_children_in_sync.bits[0],
			cluster->num_children_in_sync.bits[0],
@@ -1223,7 +1238,8 @@ static inline void cpu_unprepare(struct lpm_cpu *cpu, int cpu_index,
		cpu_pm_exit();
		cpu_pm_exit();
}
}


int get_cluster_id(struct lpm_cluster *cluster, int *aff_lvl)
static int get_cluster_id(struct lpm_cluster *cluster, int *aff_lvl,
				bool from_idle)
{
{
	int state_id = 0;
	int state_id = 0;


@@ -1236,7 +1252,7 @@ int get_cluster_id(struct lpm_cluster *cluster, int *aff_lvl)
				&cluster->child_cpus))
				&cluster->child_cpus))
		goto unlock_and_return;
		goto unlock_and_return;


	state_id |= get_cluster_id(cluster->parent, aff_lvl);
	state_id |= get_cluster_id(cluster->parent, aff_lvl, from_idle);


	if (cluster->last_level != cluster->default_level) {
	if (cluster->last_level != cluster->default_level) {
		struct lpm_cluster_level *level
		struct lpm_cluster_level *level
@@ -1250,7 +1266,8 @@ int get_cluster_id(struct lpm_cluster *cluster, int *aff_lvl)
		 * the wakeup value by reading the bc timer directly.
		 * the wakeup value by reading the bc timer directly.
		 */
		 */
		if (level->notify_rpm)
		if (level->notify_rpm)
			system_sleep_update_wakeup();
			if (sys_pm_ops && sys_pm_ops->update_wakeup)
				sys_pm_ops->update_wakeup(from_idle);
		if (level->psci_id)
		if (level->psci_id)
			(*aff_lvl)++;
			(*aff_lvl)++;
	}
	}
@@ -1279,7 +1296,7 @@ static bool psci_enter_sleep(struct lpm_cpu *cpu, int idx, bool from_idle)
			return success;
			return success;
	}
	}


	state_id = get_cluster_id(cpu->parent, &affinity_level);
	state_id = get_cluster_id(cpu->parent, &affinity_level, from_idle);
	power_state = PSCI_POWER_STATE(cpu->levels[idx].is_reset);
	power_state = PSCI_POWER_STATE(cpu->levels[idx].is_reset);
	affinity_level = PSCI_AFFINITY_LEVEL(affinity_level);
	affinity_level = PSCI_AFFINITY_LEVEL(affinity_level);
	state_id |= power_state | affinity_level | cpu->levels[idx].psci_id;
	state_id |= power_state | affinity_level | cpu->levels[idx].psci_id;
@@ -1352,9 +1369,6 @@ static int lpm_cpuidle_enter(struct cpuidle_device *dev,
	const struct cpumask *cpumask = get_cpu_mask(dev->cpu);
	const struct cpumask *cpumask = get_cpu_mask(dev->cpu);
	ktime_t start = ktime_get();
	ktime_t start = ktime_get();
	uint64_t start_time = ktime_to_ns(start), end_time;
	uint64_t start_time = ktime_to_ns(start), end_time;
	struct power_params *pwr_params;

	pwr_params = &cpu->levels[idx].pwr;


	cpu_prepare(cpu, idx, true);
	cpu_prepare(cpu, idx, true);
	cluster_prepare(cpu->parent, cpumask, idx, true, start_time);
	cluster_prepare(cpu->parent, cpumask, idx, true, start_time);
@@ -1724,7 +1738,7 @@ static int __init lpm_levels_module_init(void)
	int cpu;
	int cpu;


	for_each_possible_cpu(cpu) {
	for_each_possible_cpu(cpu) {
		rc = arm_cpuidle_init(smp_processor_id());
		rc = arm_cpuidle_init(cpu);
		if (rc) {
		if (rc) {
			pr_err("CPU%d ARM CPUidle init failed (%d)\n", cpu, rc);
			pr_err("CPU%d ARM CPUidle init failed (%d)\n", cpu, rc);
			return rc;
			return rc;
+0 −2
Original line number Original line Diff line number Diff line
@@ -108,8 +108,6 @@ struct lpm_cluster {
	struct hrtimer histtimer;
	struct hrtimer histtimer;
};
};


void lpm_suspend_wake_time(uint64_t wakeup_time);

struct lpm_cluster *lpm_of_parse_cluster(struct platform_device *pdev);
struct lpm_cluster *lpm_of_parse_cluster(struct platform_device *pdev);
void free_cluster_node(struct lpm_cluster *cluster);
void free_cluster_node(struct lpm_cluster *cluster);
void cluster_dt_walkthrough(struct lpm_cluster *cluster);
void cluster_dt_walkthrough(struct lpm_cluster *cluster);
+13 −15
Original line number Original line Diff line number Diff line
@@ -13,11 +13,9 @@


#include <linux/kernel.h>
#include <linux/kernel.h>
#include <linux/platform_device.h>
#include <linux/platform_device.h>

#include <soc/qcom/rpmh.h>
#include <soc/qcom/rpmh.h>
#include <soc/qcom/system_pm.h>

#include <clocksource/arm_arch_timer.h>
#include <clocksource/arm_arch_timer.h>
#include <soc/qcom/lpm_levels.h>


#define PDC_TIME_VALID_SHIFT	31
#define PDC_TIME_VALID_SHIFT	31
#define PDC_TIME_UPPER_MASK	0xFFFFFF
#define PDC_TIME_UPPER_MASK	0xFFFFFF
@@ -35,7 +33,7 @@ static int setup_wakeup(uint32_t lo, uint32_t hi)
	return rpmh_write_control(rpmh_client, cmd, ARRAY_SIZE(cmd));
	return rpmh_write_control(rpmh_client, cmd, ARRAY_SIZE(cmd));
}
}


int system_sleep_update_wakeup(void)
static int system_sleep_update_wakeup(bool from_idle)
{
{
	uint32_t lo = ~0U, hi = ~0U;
	uint32_t lo = ~0U, hi = ~0U;


@@ -44,16 +42,14 @@ int system_sleep_update_wakeup(void)


	return setup_wakeup(lo, hi);
	return setup_wakeup(lo, hi);
}
}
EXPORT_SYMBOL(system_sleep_update_wakeup);


/**
/**
 * system_sleep_allowed() - Returns if its okay to enter system low power modes
 * system_sleep_allowed() - Returns if its okay to enter system low power modes
 */
 */
bool system_sleep_allowed(void)
static bool system_sleep_allowed(void)
{
{
	return (rpmh_ctrlr_idle(rpmh_client) == 0);
	return (rpmh_ctrlr_idle(rpmh_client) == 0);
}
}
EXPORT_SYMBOL(system_sleep_allowed);


/**
/**
 * system_sleep_enter() - Activties done when entering system low power modes
 * system_sleep_enter() - Activties done when entering system low power modes
@@ -61,22 +57,24 @@ EXPORT_SYMBOL(system_sleep_allowed);
 * Returns 0 for success or error values from writing the sleep/wake values to
 * Returns 0 for success or error values from writing the sleep/wake values to
 * the hardware block.
 * the hardware block.
 */
 */
int system_sleep_enter(void)
static int system_sleep_enter(struct cpumask *mask)
{
{
	if (IS_ERR_OR_NULL(rpmh_client))
		return -EFAULT;

	return rpmh_flush(rpmh_client);
	return rpmh_flush(rpmh_client);
}
}
EXPORT_SYMBOL(system_sleep_enter);


/**
/**
 * system_sleep_exit() - Activities done when exiting system low power modes
 * system_sleep_exit() - Activities done when exiting system low power modes
 */
 */
void system_sleep_exit(void)
static void system_sleep_exit(void)
{
{
}
}
EXPORT_SYMBOL(system_sleep_exit);

static struct system_pm_ops pm_ops = {
	.enter = system_sleep_enter,
	.exit = system_sleep_exit,
	.update_wakeup = system_sleep_update_wakeup,
	.sleep_allowed = system_sleep_allowed,
};


static int sys_pm_probe(struct platform_device *pdev)
static int sys_pm_probe(struct platform_device *pdev)
{
{
@@ -84,7 +82,7 @@ static int sys_pm_probe(struct platform_device *pdev)
	if (IS_ERR_OR_NULL(rpmh_client))
	if (IS_ERR_OR_NULL(rpmh_client))
		return PTR_ERR(rpmh_client);
		return PTR_ERR(rpmh_client);


	return 0;
	return register_system_pm_ops(&pm_ops);
}
}


static const struct of_device_id sys_pm_drv_match[] = {
static const struct of_device_id sys_pm_drv_match[] = {
+30 −0
Original line number Original line Diff line number Diff line
/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
 *
 *
 * This program is free software; you can redistribute it and/or modify
 * 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
 * it under the terms of the GNU General Public License version 2 and
@@ -10,30 +10,21 @@
 * GNU General Public License for more details.
 * GNU General Public License for more details.
 *
 *
 */
 */
#ifndef __SOC_QCOM_SYS_PM_H__
#ifndef __SOC_QCOM_LPM_LEVEL_H__
#define __SOC_QCOM_SYS_PM_H__
#define __SOC_QCOM_LPM_LEVEL_H__


#ifdef CONFIG_QTI_SYSTEM_PM
struct system_pm_ops {
int system_sleep_enter(void);
	int (*enter)(struct cpumask *mask);

	void (*exit)(void);
void system_sleep_exit(void);
	int (*update_wakeup)(bool);

	bool (*sleep_allowed)(void);
bool system_sleep_allowed(void);
};


int system_sleep_update_wakeup(void);
#ifdef CONFIG_MSM_PM
uint32_t register_system_pm_ops(struct system_pm_ops *pm_ops);
#else
#else
static inline int system_sleep_enter(void)
static inline uint32_t register_system_pm_ops(struct system_pm_ops *pm_ops)
{ return -ENODEV; }
{ return -ENODEV; }
#endif


static inline void system_sleep_exit(void)
#endif
{ }

static inline bool system_sleep_allowed(void)
{ return false; }

static inline int system_sleep_update_wakeup(void)
{ return -ENODEV; }

#endif /* CONFIG_QTI_SYSTEM_PM */

#endif /* __SOC_QCOM_SYS_PM_H__ */