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

Commit 4f19de38 authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "cpuidle: lpm_levels: Wakeup biased cpu"

parents d6cd604c f6a4d1b4
Loading
Loading
Loading
Loading
+56 −5
Original line number Diff line number Diff line
@@ -102,6 +102,7 @@ static DEFINE_PER_CPU(struct lpm_cpu*, cpu_lpm);
static bool suspend_in_progress;
static struct hrtimer lpm_hrtimer;
static DEFINE_PER_CPU(struct hrtimer, histtimer);
static DEFINE_PER_CPU(struct hrtimer, biastimer);
static struct lpm_debug *lpm_debug;
static phys_addr_t lpm_debug_phys;
static const int num_dbg_elements = 0x100;
@@ -428,6 +429,34 @@ static void msm_pm_set_timer(uint32_t modified_time_us)
	hrtimer_start(&lpm_hrtimer, modified_ktime, HRTIMER_MODE_REL_PINNED);
}

static void biastimer_cancel(void)
{
	unsigned int cpu = raw_smp_processor_id();
	struct hrtimer *cpu_biastimer = &per_cpu(biastimer, cpu);
	ktime_t time_rem;

	time_rem = hrtimer_get_remaining(cpu_biastimer);
	if (ktime_to_us(time_rem) <= 0)
		return;

	hrtimer_try_to_cancel(cpu_biastimer);
}

static enum hrtimer_restart biastimer_fn(struct hrtimer *h)
{
	return HRTIMER_NORESTART;
}

static void biastimer_start(uint32_t time_ns)
{
	ktime_t bias_ktime = ns_to_ktime(time_ns);
	unsigned int cpu = raw_smp_processor_id();
	struct hrtimer *cpu_biastimer = &per_cpu(biastimer, cpu);

	cpu_biastimer->function = biastimer_fn;
	hrtimer_start(cpu_biastimer, bias_ktime, HRTIMER_MODE_REL_PINNED);
}

static uint64_t lpm_cpuidle_predict(struct cpuidle_device *dev,
		struct lpm_cpu *cpu, int *idx_restrict,
		uint32_t *idx_restrict_time)
@@ -588,22 +617,36 @@ static void clear_predict_history(void)

static void update_history(struct cpuidle_device *dev, int idx);

static inline bool is_cpu_biased(int cpu)
static inline bool is_cpu_biased(int cpu, uint64_t *bias_time)
{
	u64 now = sched_clock();
	u64 last = sched_get_cpu_last_busy_time(cpu);
	u64 diff = 0;

	if (!last)
		return false;

	return (now - last) < BIAS_HYST;
	diff = now - last;
	if (diff < BIAS_HYST) {
		*bias_time = BIAS_HYST - diff;
		return true;
	}

	return false;
}

static inline bool lpm_disallowed(s64 sleep_us, int cpu)
static inline bool lpm_disallowed(s64 sleep_us, int cpu, struct lpm_cpu *pm_cpu)
{
	if ((sleep_disabled && !cpu_isolated(cpu)) || is_cpu_biased(cpu))
	uint64_t bias_time = 0;

	if (sleep_disabled && !cpu_isolated(cpu))
		return true;

	if (is_cpu_biased(cpu, &bias_time) && (!cpu_isolated(cpu))) {
		pm_cpu->bias = bias_time;
		return true;
	}

	if (sleep_us < 0)
		return true;

@@ -628,7 +671,7 @@ static int cpu_power_select(struct cpuidle_device *dev,
	uint32_t min_residency, max_residency;
	struct power_params *pwr_params;

	if (lpm_disallowed(sleep_us, dev->cpu))
	if (lpm_disallowed(sleep_us, dev->cpu, cpu))
		goto done_select;

	idx_restrict = cpu->nlevels + 1;
@@ -1294,6 +1337,8 @@ static bool psci_enter_sleep(struct lpm_cpu *cpu, int idx, bool from_idle)
	 */

	if (!idx) {
		if (cpu->bias)
			biastimer_start(cpu->bias);
		stop_critical_timings();
		wfi();
		start_critical_timings();
@@ -1404,6 +1449,10 @@ static int lpm_cpuidle_enter(struct cpuidle_device *dev,
		histtimer_cancel();
		clusttimer_cancel();
	}
	if (cpu->bias) {
		biastimer_cancel();
		cpu->bias = 0;
	}
	local_irq_enable();
	return idx;
}
@@ -1705,6 +1754,8 @@ static int lpm_probe(struct platform_device *pdev)
	for_each_possible_cpu(cpu) {
		cpu_histtimer = &per_cpu(histtimer, cpu);
		hrtimer_init(cpu_histtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
		cpu_histtimer = &per_cpu(biastimer, cpu);
		hrtimer_init(cpu_histtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
	}

	cluster_timer_init(lpm_root_node);
+1 −0
Original line number Diff line number Diff line
@@ -46,6 +46,7 @@ struct lpm_cpu {
	uint32_t ref_premature_cnt;
	uint32_t tmr_add;
	bool lpm_prediction;
	uint64_t bias;
	struct cpuidle_driver *drv;
	struct lpm_cluster *parent;
};