blob: 6c9a50b34112e6f021b482e92a8f91f4ae3a047f [file] [log] [blame]
Mahesh Sivasubramanianc2ea76f2016-02-01 10:40:26 -07001/* Copyright (c) 2014-2016, 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.h>
14#include <soc/qcom/spm.h>
15
16#define NR_LPM_LEVELS 8
17#define MAXSAMPLES 5
18#define CLUST_SMPL_INVLD_TIME 40000
19
20extern bool use_psci;
21
22struct lpm_lookup_table {
23 uint32_t modes;
24 const char *mode_name;
25};
26
27struct power_params {
28 uint32_t latency_us; /* Enter + Exit latency */
29 uint32_t ss_power; /* Steady state power */
30 uint32_t energy_overhead; /* Enter + exit over head */
31 uint32_t time_overhead_us; /* Enter + exit overhead */
32 uint32_t residencies[NR_LPM_LEVELS];
33 uint32_t min_residency;
34 uint32_t max_residency;
35};
36
37struct lpm_cpu_level {
38 const char *name;
39 enum msm_pm_sleep_mode mode;
40 bool use_bc_timer;
41 struct power_params pwr;
42 unsigned int psci_id;
43 bool is_reset;
44 bool jtag_save_restore;
45 bool hyp_psci;
46 int reset_level;
47};
48
49struct lpm_cpu {
50 struct lpm_cpu_level levels[NR_LPM_LEVELS];
51 int nlevels;
52 unsigned int psci_mode_shift;
53 unsigned int psci_mode_mask;
54 struct lpm_cluster *parent;
55};
56
57struct lpm_level_avail {
58 bool idle_enabled;
59 bool suspend_enabled;
60 struct kobject *kobj;
61 struct kobj_attribute idle_enabled_attr;
62 struct kobj_attribute suspend_enabled_attr;
63 void *data;
64 int idx;
65 bool cpu_node;
66};
67
68struct lpm_cluster_level {
69 const char *level_name;
70 int *mode; /* SPM mode to enter */
71 int min_child_level;
72 struct cpumask num_cpu_votes;
73 struct power_params pwr;
74 bool notify_rpm;
75 bool disable_dynamic_routing;
76 bool sync_level;
77 bool last_core_only;
78 struct lpm_level_avail available;
79 unsigned int psci_id;
80 bool is_reset;
81 int reset_level;
82};
83
84struct low_power_ops {
85 struct msm_spm_device *spm;
86 int (*set_mode)(struct low_power_ops *ops, int mode, bool notify_rpm);
87 enum msm_pm_l2_scm_flag tz_flag;
88};
89
90struct cluster_history {
91 uint32_t resi[MAXSAMPLES];
92 int mode[MAXSAMPLES];
93 int64_t stime[MAXSAMPLES];
94 uint32_t hptr;
95 uint32_t hinvalid;
96 uint32_t htmr_wkup;
97 uint64_t entry_time;
98 int entry_idx;
99 int nsamp;
100 int flag;
101};
102
103struct lpm_cluster {
104 struct list_head list;
105 struct list_head child;
106 const char *cluster_name;
107 const char **name;
108 unsigned long aff_level; /* Affinity level of the node */
109 struct low_power_ops *lpm_dev;
110 int ndevices;
111 struct lpm_cluster_level levels[NR_LPM_LEVELS];
112 int nlevels;
113 enum msm_pm_l2_scm_flag l2_flag;
114 int min_child_level;
115 int default_level;
116 int last_level;
117 struct lpm_cpu *cpu;
118 struct cpuidle_driver *drv;
119 spinlock_t sync_lock;
120 struct cpumask child_cpus;
121 struct cpumask num_children_in_sync;
122 struct lpm_cluster *parent;
123 struct lpm_stats *stats;
124 unsigned int psci_mode_shift;
125 unsigned int psci_mode_mask;
126 bool no_saw_devices;
127 struct cluster_history history;
128 struct hrtimer histtimer;
129};
130
131int set_l2_mode(struct low_power_ops *ops, int mode, bool notify_rpm);
132int set_system_mode(struct low_power_ops *ops, int mode, bool notify_rpm);
133int set_l3_mode(struct low_power_ops *ops, int mode, bool notify_rpm);
134void lpm_suspend_wake_time(uint64_t wakeup_time);
135
136struct lpm_cluster *lpm_of_parse_cluster(struct platform_device *pdev);
137void free_cluster_node(struct lpm_cluster *cluster);
138void cluster_dt_walkthrough(struct lpm_cluster *cluster);
139
140int create_cluster_lvl_nodes(struct lpm_cluster *p, struct kobject *kobj);
141bool lpm_cpu_mode_allow(unsigned int cpu,
142 unsigned int mode, bool from_idle);
143bool lpm_cluster_mode_allow(struct lpm_cluster *cluster,
144 unsigned int mode, bool from_idle);
145uint32_t *get_per_cpu_max_residency(int cpu);
146uint32_t *get_per_cpu_min_residency(int cpu);
147extern struct lpm_cluster *lpm_root_node;
148
Mahesh Sivasubramanianb9da25f2016-11-04 14:35:03 -0600149#if CONFIG_SMP
Mahesh Sivasubramanianc2ea76f2016-02-01 10:40:26 -0700150extern DEFINE_PER_CPU(bool, pending_ipi);
151static inline bool is_IPI_pending(const struct cpumask *mask)
152{
153 unsigned int cpu;
154
155 for_each_cpu(cpu, mask) {
156 if per_cpu(pending_ipi, cpu)
157 return true;
158 }
159 return false;
160}
161#else
162static inline bool is_IPI_pending(const struct cpumask *mask)
163{
164 return false;
165}
166#endif