blob: d6d867a5b5c62b8e546c12cbe39dbf8f250a184a [file] [log] [blame]
Neela Chithirala3ccb2472022-01-17 04:41:54 +00001// SPDX-License-Identifier: GPL-2.0
2/*
3 * Platform thermal driver for GXP.
4 *
5 * Copyright (C) 2021 Google LLC
6 */
7
8#include <linux/debugfs.h>
9#include <linux/device.h>
10#include <linux/gfp.h>
11#include <linux/kernel.h>
12#include <linux/mutex.h>
13#include <linux/of.h>
14#include <linux/platform_device.h>
15#include <linux/pm_runtime.h>
16#include <linux/slab.h>
17#include <linux/thermal.h>
18#include <linux/version.h>
19
20#ifdef CONFIG_GXP_CLOUDRIPPER
21#include <linux/acpm_dvfs.h>
22#endif
23
24#include "gxp-internal.h"
25#include "gxp-pm.h"
26#include "gxp-thermal.h"
27#include "gxp-lpm.h"
28
Neela Chithirala3ccb2472022-01-17 04:41:54 +000029/*
30 * Value comes from internal measurement
Wei Miaoa96a1982022-04-12 16:14:38 -070031 * b/229623553
Neela Chithirala3ccb2472022-01-17 04:41:54 +000032 */
Wei Miaoa96a1982022-04-12 16:14:38 -070033static struct gxp_state_pwr state_pwr_map[] = {
34 {1155000, 78},
35 {975000, 58},
36 {750000, 40},
37 {560000, 27},
38 {373000, 20},
39 {268000, 16},
40 {178000, 13},
Neela Chithirala3ccb2472022-01-17 04:41:54 +000041};
42
43static int gxp_get_max_state(struct thermal_cooling_device *cdev,
44 unsigned long *state)
45{
46 struct gxp_thermal_manager *thermal = cdev->devdata;
47
48 if (!thermal->gxp_num_states)
49 return -EIO;
50
51 *state = thermal->gxp_num_states - 1;
52 return 0;
53}
54
55/*
56 * Set cooling state.
57 */
58static int gxp_set_cur_state(struct thermal_cooling_device *cdev,
59 unsigned long cooling_state)
60{
61 int ret = 0;
62 struct gxp_thermal_manager *thermal = cdev->devdata;
63 struct device *dev = thermal->gxp->dev;
64 unsigned long pwr_state;
65
66 if (cooling_state >= thermal->gxp_num_states) {
67 dev_err(dev, "%s: invalid cooling state %lu\n", __func__,
68 cooling_state);
69 return -EINVAL;
70 }
71
72 mutex_lock(&thermal->lock);
73 cooling_state = max(thermal->sysfs_req, cooling_state);
74 if (cooling_state >= ARRAY_SIZE(state_pwr_map)) {
75 dev_err(dev, "Unsupported cooling state: %lu\n", cooling_state);
76 ret = -EINVAL;
77 goto out;
78 }
79 pwr_state = state_pwr_map[cooling_state].state;
80 dev_dbg(dev, "setting policy %ld\n", pwr_state);
81 if (cooling_state != thermal->cooling_state) {
82#ifdef CONFIG_GXP_CLOUDRIPPER
83 ret = exynos_acpm_set_policy(AUR_DVFS_DOMAIN,
Wei Miaoa96a1982022-04-12 16:14:38 -070084 pwr_state < aur_power_state2rate[AUR_UUD] ?
85 aur_power_state2rate[AUR_UUD] :
86 pwr_state);
Neela Chithirala3ccb2472022-01-17 04:41:54 +000087#endif
88 if (ret) {
89 dev_err(dev,
90 "error setting gxp cooling policy: %d\n", ret);
91 goto out;
92 }
93 thermal->cooling_state = cooling_state;
94 } else {
95 ret = -EALREADY;
96 }
97
98out:
99 mutex_unlock(&thermal->lock);
100 return ret;
101}
102
103static int gxp_get_cur_state(struct thermal_cooling_device *cdev,
104 unsigned long *state)
105{
106 int ret = 0;
107 struct gxp_thermal_manager *thermal = cdev->devdata;
108
109 mutex_lock(&thermal->lock);
110 *state = thermal->cooling_state;
111 if (*state >= thermal->gxp_num_states) {
112 dev_err(thermal->gxp->dev,
113 "Unknown cooling state: %lu, resetting\n", *state);
114 ret = -EINVAL;
115 goto out;
116 }
117out:
118 mutex_unlock(&thermal->lock);
119 return ret;
120}
121
122static int gxp_state2power_internal(unsigned long state, u32 *power,
123 struct gxp_thermal_manager *thermal)
124{
125 int i;
126
127 for (i = 0; i < thermal->gxp_num_states; i++) {
128 if (state == state_pwr_map[i].state) {
129 *power = state_pwr_map[i].power;
130 return 0;
131 }
132 }
133 dev_err(thermal->gxp->dev, "Unknown state req for: %lu\n", state);
134 *power = 0;
135 return -EINVAL;
136}
137
138static int gxp_get_requested_power(struct thermal_cooling_device *cdev,
139 u32 *power)
140{
141 /* Use ACTIVE_NOM as default value */
142 unsigned long power_state = AUR_NOM;
143 struct gxp_thermal_manager *cooling = cdev->devdata;
144#ifdef CONFIG_GXP_CLOUDRIPPER
145
146 power_state = exynos_acpm_get_rate(AUR_DVFS_DOMAIN, 0);
147#endif
148 return gxp_state2power_internal(power_state, power,
149 cooling);
150}
151
152/* TODO(b/213272324): Move state2power table to dts */
153static int gxp_state2power(struct thermal_cooling_device *cdev,
154 unsigned long state, u32 *power)
155{
156 struct gxp_thermal_manager *thermal = cdev->devdata;
157
158 if (state >= thermal->gxp_num_states) {
159 dev_err(thermal->gxp->dev, "%s: invalid state: %lu\n", __func__,
160 state);
161 return -EINVAL;
162 }
163
164 return gxp_state2power_internal(state_pwr_map[state].state, power,
165 thermal);
166}
167
168static int gxp_power2state(struct thermal_cooling_device *cdev,
169 u32 power, unsigned long *state)
170{
171 int i, penultimate_throttle_state;
172 struct gxp_thermal_manager *thermal = cdev->devdata;
173
174 *state = 0;
175 /* Less than 2 state means we cannot really throttle */
176 if (thermal->gxp_num_states < 2)
177 return thermal->gxp_num_states == 1 ? 0 : -EIO;
178
179 penultimate_throttle_state = thermal->gxp_num_states - 2;
180 /*
181 * argument "power" is the maximum allowed power consumption in mW as
182 * defined by the PID control loop. Check for the first state that is
183 * less than or equal to the current allowed power. state_pwr_map is
184 * descending, so lowest power consumption is last value in the array
185 * return lowest state even if it consumes more power than allowed as
186 * not all platforms can handle throttling below an active state
187 */
188 for (i = penultimate_throttle_state; i >= 0; --i) {
189 if (power < state_pwr_map[i].power) {
190 *state = i + 1;
191 break;
192 }
193 }
194 return 0;
195}
196
197static struct thermal_cooling_device_ops gxp_cooling_ops = {
198 .get_max_state = gxp_get_max_state,
199 .get_cur_state = gxp_get_cur_state,
200 .set_cur_state = gxp_set_cur_state,
201 .get_requested_power = gxp_get_requested_power,
202 .state2power = gxp_state2power,
203 .power2state = gxp_power2state,
204};
205
206static void gxp_thermal_exit(struct gxp_thermal_manager *thermal)
207{
208 if (!IS_ERR_OR_NULL(thermal->cdev))
209 thermal_cooling_device_unregister(thermal->cdev);
210}
211
212static void devm_gxp_thermal_release(struct device *dev, void *res)
213{
214 struct gxp_thermal_manager *thermal = res;
215
216 gxp_thermal_exit(thermal);
217}
218
219static ssize_t
220user_vote_show(struct device *dev, struct device_attribute *attr, char *buf)
221{
222 struct thermal_cooling_device *cdev =
223 container_of(dev, struct thermal_cooling_device,
224 device);
225 struct gxp_thermal_manager *cooling = cdev->devdata;
226
227 if (!cooling)
228 return -ENODEV;
229
230 return sysfs_emit(buf, "%lu\n", cooling->sysfs_req);
231}
232
233static ssize_t user_vote_store(struct device *dev,
234 struct device_attribute *attr,
235 const char *buf, size_t count)
236{
237 struct thermal_cooling_device *cdev =
238 container_of(dev, struct thermal_cooling_device,
239 device);
240 struct gxp_thermal_manager *cooling = cdev->devdata;
241 int ret;
242 unsigned long state;
243
244 if (!cooling)
245 return -ENODEV;
246
247 ret = kstrtoul(buf, 0, &state);
248 if (ret)
249 return ret;
250
251 if (state >= cooling->gxp_num_states)
252 return -EINVAL;
253
254 mutex_lock(&cdev->lock);
255 cooling->sysfs_req = state;
256 cdev->updated = false;
257 mutex_unlock(&cdev->lock);
258 thermal_cdev_update(cdev);
259 return count;
260}
261
262static DEVICE_ATTR_RW(user_vote);
263
264static int
265gxp_thermal_cooling_register(struct gxp_thermal_manager *thermal, char *type)
266{
267 struct device_node *cooling_node = NULL;
268
269 thermal->op_data = NULL;
270 thermal->gxp_num_states = ARRAY_SIZE(state_pwr_map);
271
272 mutex_init(&thermal->lock);
273 cooling_node = of_find_node_by_name(NULL, GXP_COOLING_NAME);
274
275 /* TODO: Change this to fatal error once dts change is merged */
276 if (!cooling_node)
277 dev_warn(thermal->gxp->dev, "failed to find cooling node\n");
278 /* Initialize the cooling state as 0, means "no cooling" */
279 thermal->cooling_state = 0;
280 thermal->cdev = thermal_of_cooling_device_register(
281 cooling_node, type, thermal, &gxp_cooling_ops);
282 if (IS_ERR(thermal->cdev))
283 return PTR_ERR(thermal->cdev);
284
285 return device_create_file(&thermal->cdev->device, &dev_attr_user_vote);
286}
287
288static int cooling_init(struct gxp_thermal_manager *thermal, struct device *dev)
289{
290 int err;
291 struct dentry *d;
292
293 d = debugfs_create_dir("cooling", thermal->gxp->d_entry);
294 /* don't let debugfs creation failure abort the init procedure */
295 if (IS_ERR_OR_NULL(d))
296 dev_warn(dev, "failed to create debug fs for cooling");
297 thermal->cooling_root = d;
298
299 err = gxp_thermal_cooling_register(thermal, GXP_COOLING_NAME);
300 if (err) {
301 dev_err(dev, "failed to initialize external cooling\n");
302 gxp_thermal_exit(thermal);
303 return err;
304 }
305 return 0;
306}
307
308struct gxp_thermal_manager
309*gxp_thermal_init(struct gxp_dev *gxp)
310{
311 struct device *dev = gxp->dev;
312 struct gxp_thermal_manager *thermal;
313 int err;
314
315 thermal = devres_alloc(devm_gxp_thermal_release, sizeof(*thermal),
316 GFP_KERNEL);
317 if (!thermal)
318 return ERR_PTR(-ENOMEM);
319
320 thermal->gxp = gxp;
321 err = cooling_init(thermal, dev);
322 if (err) {
323 devres_free(thermal);
324 return ERR_PTR(err);
325 }
326
327 devres_add(dev, thermal);
328 return thermal;
329}