blob: 4a07355135acee9d6bf209c545a7365e42da009f [file] [log] [blame]
Raja Mallikb9ad4522018-04-19 15:23:49 +05301/* Copyright (c) 2014-2018, The Linux Foundation. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 */
12
13#include <soc/qcom/pm-legacy.h>
14#include <soc/qcom/spm.h>
15
16#define NR_LPM_LEVELS 8
17
18extern bool use_psci;
19
20struct lpm_lookup_table {
21 uint32_t modes;
22 const char *mode_name;
23};
24
25struct power_params {
26 uint32_t latency_us; /* Enter + Exit latency */
27 uint32_t ss_power; /* Steady state power */
28 uint32_t energy_overhead; /* Enter + exit over head */
29 uint32_t time_overhead_us; /* Enter + exit overhead */
30 uint32_t residencies[NR_LPM_LEVELS];
31 uint32_t max_residency;
32};
33
34struct lpm_cpu_level {
35 const char *name;
36 enum msm_pm_sleep_mode mode;
37 bool use_bc_timer;
38 struct power_params pwr;
39 unsigned int psci_id;
40 bool is_reset;
41 bool jtag_save_restore;
42 bool hyp_psci;
43 int reset_level;
44};
45
46struct lpm_cpu {
47 struct lpm_cpu_level levels[NR_LPM_LEVELS];
48 int nlevels;
49 unsigned int psci_mode_shift;
50 unsigned int psci_mode_mask;
51 struct lpm_cluster *parent;
52};
53
54struct lpm_level_avail {
55 bool idle_enabled;
56 bool suspend_enabled;
57 struct kobject *kobj;
58 struct kobj_attribute idle_enabled_attr;
59 struct kobj_attribute suspend_enabled_attr;
60 void *data;
61 int idx;
62 bool cpu_node;
63};
64
65struct lpm_cluster_level {
66 const char *level_name;
67 int *mode; /* SPM mode to enter */
68 int min_child_level;
69 struct cpumask num_cpu_votes;
70 struct power_params pwr;
71 bool notify_rpm;
72 bool disable_dynamic_routing;
73 bool sync_level;
74 bool last_core_only;
75 struct lpm_level_avail available;
76 unsigned int psci_id;
77 bool is_reset;
78 int reset_level;
79 bool no_cache_flush;
80};
81
82struct low_power_ops {
83 struct msm_spm_device *spm;
84 int (*set_mode)(struct low_power_ops *ops, int mode,
85 struct lpm_cluster_level *level);
86 enum msm_pm_l2_scm_flag tz_flag;
87};
88
89struct lpm_cluster {
90 struct list_head list;
91 struct list_head child;
92 const char *cluster_name;
93 const char **name;
94 unsigned long aff_level; /* Affinity level of the node */
95 struct low_power_ops *lpm_dev;
96 int ndevices;
97 struct lpm_cluster_level levels[NR_LPM_LEVELS];
98 int nlevels;
99 enum msm_pm_l2_scm_flag l2_flag;
100 int min_child_level;
101 int default_level;
102 int last_level;
103 struct lpm_cpu *cpu;
104 struct cpuidle_driver *drv;
105 spinlock_t sync_lock;
106 struct cpumask child_cpus;
107 struct cpumask num_children_in_sync;
108 struct lpm_cluster *parent;
109 struct lpm_stats *stats;
110 unsigned int psci_mode_shift;
111 unsigned int psci_mode_mask;
112 bool no_saw_devices;
113};
114
115int set_l2_mode(struct low_power_ops *ops, int mode,
116 struct lpm_cluster_level *level);
117int set_system_mode(struct low_power_ops *ops, int mode,
118 struct lpm_cluster_level *level);
119int set_l3_mode(struct low_power_ops *ops, int mode,
120 struct lpm_cluster_level *level);
121void lpm_suspend_wake_time(uint64_t wakeup_time);
122
123struct lpm_cluster *lpm_of_parse_cluster(struct platform_device *pdev);
124void free_cluster_node(struct lpm_cluster *cluster);
125void cluster_dt_walkthrough(struct lpm_cluster *cluster);
126
127int create_cluster_lvl_nodes(struct lpm_cluster *p, struct kobject *kobj);
128bool lpm_cpu_mode_allow(unsigned int cpu,
129 unsigned int mode, bool from_idle);
130bool lpm_cluster_mode_allow(struct lpm_cluster *cluster,
131 unsigned int mode, bool from_idle);
132uint32_t *get_per_cpu_max_residency(int cpu);
133extern struct lpm_cluster *lpm_root_node;
134
135#ifdef CONFIG_SMP
136extern DEFINE_PER_CPU(bool, pending_ipi);
137static inline bool is_IPI_pending(const struct cpumask *mask)
138{
139 unsigned int cpu;
140
141 for_each_cpu(cpu, mask) {
142 if per_cpu(pending_ipi, cpu)
143 return true;
144 }
145 return false;
146}
147#else
148static inline bool is_IPI_pending(const struct cpumask *mask)
149{
150 return false;
151}
152#endif