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

Commit d23cd815 authored by Maulik Shah's avatar Maulik Shah Committed by Gerrit - the friendly Code Review server
Browse files

cpuidle: lpm-levels: Enable LPM support for non psci target



Add non psci legacy lpm support. Modify and align changes
for clock event, MPM and cpu hotplug for LPM callback notification.

Remove deprecated scheduler c-state(idle cpu), d-state(idle cluster)
setting from lpm driver.

Snapshot is taken from msm-4.9 kernel version @commit b9ad452666da39.
("soc: qcom: bgrsb: Increase time out for RSB channel opening").

Change-Id: I8958ab4f098cc6d875071e3f100b8b74845e0cfa
Signed-off-by: default avatarRaghavendra Kakarla <rkakarla@codeaurora.org>
Signed-off-by: default avatarHaribabu Gattem <haribabu@codeaurora.org>
Signed-off-by: default avatarMaulik Shah <mkshah@codeaurora.org>
Signed-off-by: default avatarSuresh Kumar Allam <allamsuresh@codeaurora.org>
Signed-off-by: default avatarTushar Nimkar <tnimkar@codeaurora.org>
parent 606af3ec
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -22,8 +22,12 @@ obj-$(CONFIG_ARM_AT91_CPUIDLE) += cpuidle-at91.o
obj-$(CONFIG_ARM_EXYNOS_CPUIDLE)        += cpuidle-exynos.o
obj-$(CONFIG_ARM_CPUIDLE)		+= cpuidle-arm.o
obj-$(CONFIG_ARM_PSCI_CPUIDLE)		+= cpuidle-psci.o
ifeq ($(CONFIG_MSM_PM_LEGACY), y)
obj-y += lpm-levels-legacy.o lpm-levels-of-legacy.o
else
obj-$(CONFIG_ARM_QCOM_LPM_CPUIDLE)	+= lpm-levels.o
obj-$(CONFIG_ARM_QCOM_LPM_CPUIDLE)	+= lpm-levels-of.o
endif

###############################################################################
# MIPS drivers
+1517 −0

File added.

Preview size limit exceeded, changes collapsed.

+146 −0
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0-only */

/*
 * Copyright (c) 2014-2020, 2021 The Linux Foundation. All rights reserved.
 */

#include <soc/qcom/pm-legacy.h>
#include <soc/qcom/spm.h>

#define NR_LPM_LEVELS 8

extern bool use_psci;

struct lpm_lookup_table {
	uint32_t modes;
	const char *mode_name;
};

struct power_params {
	uint32_t latency_us;		/* Enter + Exit latency */
	uint32_t ss_power;		/* Steady state power */
	uint32_t energy_overhead;	/* Enter + exit over head */
	uint32_t time_overhead_us;	/* Enter + exit overhead */
	uint32_t residencies[NR_LPM_LEVELS];
	uint32_t max_residency;
};

struct lpm_cpu_level {
	const char *name;
	enum msm_pm_sleep_mode mode;
	bool use_bc_timer;
	struct power_params pwr;
	unsigned int psci_id;
	bool is_reset;
	bool jtag_save_restore;
	bool hyp_psci;
	int reset_level;
};

struct lpm_cpu {
	struct lpm_cpu_level levels[NR_LPM_LEVELS];
	int nlevels;
	unsigned int psci_mode_shift;
	unsigned int psci_mode_mask;
	struct lpm_cluster *parent;
};

struct lpm_level_avail {
	bool idle_enabled;
	bool suspend_enabled;
	struct kobject *kobj;
	struct kobj_attribute idle_enabled_attr;
	struct kobj_attribute suspend_enabled_attr;
	void *data;
	int idx;
	bool cpu_node;
};

struct lpm_cluster_level {
	const char *level_name;
	int *mode;			/* SPM mode to enter */
	int min_child_level;
	struct cpumask num_cpu_votes;
	struct power_params pwr;
	bool notify_rpm;
	bool disable_dynamic_routing;
	bool sync_level;
	bool last_core_only;
	struct lpm_level_avail available;
	unsigned int psci_id;
	bool is_reset;
	int reset_level;
	bool no_cache_flush;
};

struct low_power_ops {
	struct msm_spm_device *spm;
	int (*set_mode)(struct low_power_ops *ops, int mode,
				struct lpm_cluster_level *level);
	enum msm_pm_l2_scm_flag tz_flag;
};

struct lpm_cluster {
	struct list_head list;
	struct list_head child;
	const char *cluster_name;
	const char **name;
	unsigned long aff_level; /* Affinity level of the node */
	struct low_power_ops *lpm_dev;
	int ndevices;
	struct lpm_cluster_level levels[NR_LPM_LEVELS];
	int nlevels;
	enum msm_pm_l2_scm_flag l2_flag;
	int min_child_level;
	int default_level;
	int last_level;
	struct lpm_cpu *cpu;
	struct cpuidle_driver *drv;
	spinlock_t sync_lock;
	struct cpumask child_cpus;
	struct cpumask num_children_in_sync;
	struct lpm_cluster *parent;
	struct lpm_stats *stats;
	unsigned int psci_mode_shift;
	unsigned int psci_mode_mask;
	bool no_saw_devices;
};

int set_l2_mode(struct low_power_ops *ops, int mode,
				struct lpm_cluster_level *level);
int set_system_mode(struct low_power_ops *ops, int mode,
				struct lpm_cluster_level *level);
int set_l3_mode(struct low_power_ops *ops, int mode,
				struct lpm_cluster_level *level);
void lpm_suspend_wake_time(uint64_t wakeup_time);

struct lpm_cluster *lpm_of_parse_cluster(struct platform_device *pdev);
void free_cluster_node(struct lpm_cluster *cluster);
void cluster_dt_walkthrough(struct lpm_cluster *cluster);

int create_cluster_lvl_nodes(struct lpm_cluster *p, struct kobject *kobj);
bool lpm_cpu_mode_allow(unsigned int cpu,
		unsigned int mode, bool from_idle);
bool lpm_cluster_mode_allow(struct lpm_cluster *cluster,
		unsigned int mode, bool from_idle);
uint32_t *get_per_cpu_max_residency(int cpu);
extern struct lpm_cluster *lpm_root_node;

#ifdef CONFIG_SMP
extern DEFINE_PER_CPU(bool, pending_ipi);
static inline bool is_IPI_pending(const struct cpumask *mask)
{
	unsigned int cpu;

	for_each_cpu(cpu, mask) {
		if per_cpu(pending_ipi, cpu)
			return true;
	}
	return false;
}
#else
static inline bool is_IPI_pending(const struct cpumask *mask)
{
	return false;
}
#endif
+999 −0

File added.

Preview size limit exceeded, changes collapsed.

+13 −2
Original line number Diff line number Diff line
@@ -835,6 +835,17 @@ config QTI_SYSTEM_PM
config QTI_SYSTEM_PM_RPM
	bool

config MSM_PM_LEGACY
	depends on PM
	select MSM_IDLE_STATS if DEBUG_FS
	select CPU_IDLE_MULTIPLE_DRIVERS
	bool "Qualcomm Technologies, Inc. (QTI) platform specific Legacy PM driver"
	help
	  Platform specific legacy power driver to manage
	  cores and l2 low power modes. It interface with
	  various system driver and put the cores into
	  low power modes.

config QTI_PLH_SCMI_CLIENT
	tristate "Qualcomm Technologies Inc. SCMI client driver for PLH"
	depends on QTI_PLH
@@ -895,7 +906,7 @@ config QTI_HW_MEMLAT_LOG
	  This driver register with IPC_Logging framework, to have dedicated
	  buffer for memlat hw device.

if MSM_PM
if (MSM_PM || MSM_PM_LEGACY)
menuconfig MSM_IDLE_STATS
	bool "Collect idle statistics"
	help
@@ -928,7 +939,7 @@ config MSM_SUSPEND_STATS_FIRST_BUCKET
	  histogram.  This is for collecting statistics on suspend.

endif # MSM_IDLE_STATS
endif # MSM_PM
endif # MSM_PM || MSM_PM_LEGACY

config QTI_RPM_STATS_LOG
	tristate "Qualcomm Technologies RPM Stats Driver"
Loading