blob: 4aae8a0966a330c40f206129907b9804f3742d26 [file] [log] [blame]
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001/* Copyright (c) 2010-2011, Code Aurora Forum. 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
14#include <linux/module.h>
15#include <linux/kernel.h>
16#include <linux/init.h>
17#include <linux/types.h>
18#include <linux/bug.h>
19#include <linux/mutex.h>
20#include <linux/proc_fs.h>
21#include <linux/spinlock.h>
22#include <linux/cpu.h>
23#include <mach/rpm.h>
24#include <mach/msm_iomap.h>
25#include <asm/mach-types.h>
26#include <linux/io.h>
27#include "mpm.h"
28#include "rpm_resources.h"
29#include "spm.h"
30
31/******************************************************************************
32 * Debug Definitions
33 *****************************************************************************/
34
35enum {
36 MSM_RPMRS_DEBUG_OUTPUT = BIT(0),
37 MSM_RPMRS_DEBUG_BUFFER = BIT(1),
38};
39
40static int msm_rpmrs_debug_mask;
41module_param_named(
42 debug_mask, msm_rpmrs_debug_mask, int, S_IRUGO | S_IWUSR | S_IWGRP
43);
44
45static struct msm_rpmrs_level *msm_rpmrs_levels;
46static int msm_rpmrs_level_count;
47
48static bool msm_rpmrs_pxo_beyond_limits(struct msm_rpmrs_limits *limits);
49static void msm_rpmrs_aggregate_pxo(struct msm_rpmrs_limits *limits);
50static void msm_rpmrs_restore_pxo(void);
51static bool msm_rpmrs_l2_cache_beyond_limits(struct msm_rpmrs_limits *limits);
52static void msm_rpmrs_aggregate_l2_cache(struct msm_rpmrs_limits *limits);
53static void msm_rpmrs_restore_l2_cache(void);
54static bool msm_rpmrs_vdd_mem_beyond_limits(struct msm_rpmrs_limits *limits);
55static void msm_rpmrs_aggregate_vdd_mem(struct msm_rpmrs_limits *limits);
56static void msm_rpmrs_restore_vdd_mem(void);
57static bool msm_rpmrs_vdd_dig_beyond_limits(struct msm_rpmrs_limits *limits);
58static void msm_rpmrs_aggregate_vdd_dig(struct msm_rpmrs_limits *limits);
59static void msm_rpmrs_restore_vdd_dig(void);
60static void msm_rpmrs_aggregate_rpm_cpu(struct msm_rpmrs_limits *limits);
61static void msm_rpmrs_restore_rpm_cpu(void);
62
63#ifdef CONFIG_MSM_L2_SPM
64static void *msm_rpmrs_l2_counter_addr;
65static int msm_rpmrs_l2_reset_count;
66#define L2_PC_COUNTER_ADDR 0x660
67#endif
68
69#define MSM_RPMRS_MAX_RS_REGISTER_COUNT 2
70
71struct msm_rpmrs_resource {
72 struct msm_rpm_iv_pair rs[MSM_RPMRS_MAX_RS_REGISTER_COUNT];
73 uint32_t size;
74 char *name;
75
76 uint32_t enable_low_power;
77
78 bool (*beyond_limits)(struct msm_rpmrs_limits *limits);
79 void (*aggregate)(struct msm_rpmrs_limits *limits);
80 void (*restore)(void);
81};
82
83static struct msm_rpmrs_resource msm_rpmrs_pxo = {
84 .rs[0].id = MSM_RPMRS_ID_PXO_CLK,
85 .size = 1,
86 .name = "pxo",
87 .beyond_limits = msm_rpmrs_pxo_beyond_limits,
88 .aggregate = msm_rpmrs_aggregate_pxo,
89 .restore = msm_rpmrs_restore_pxo,
90};
91
92static struct msm_rpmrs_resource msm_rpmrs_l2_cache = {
93 .rs[0].id = MSM_RPMRS_ID_APPS_L2_CACHE_CTL,
94 .size = 1,
95 .name = "L2_cache",
96 .beyond_limits = msm_rpmrs_l2_cache_beyond_limits,
97 .aggregate = msm_rpmrs_aggregate_l2_cache,
98 .restore = msm_rpmrs_restore_l2_cache,
99};
100
101static struct msm_rpmrs_resource msm_rpmrs_vdd_mem = {
102 .rs[0].id = MSM_RPMRS_ID_VDD_MEM_0,
103 .rs[1].id = MSM_RPMRS_ID_VDD_MEM_1,
104 .size = 2,
105 .name = "vdd_mem",
106 .beyond_limits = msm_rpmrs_vdd_mem_beyond_limits,
107 .aggregate = msm_rpmrs_aggregate_vdd_mem,
108 .restore = msm_rpmrs_restore_vdd_mem,
109};
110
111static struct msm_rpmrs_resource msm_rpmrs_vdd_dig = {
112 .rs[0].id = MSM_RPMRS_ID_VDD_DIG_0,
113 .rs[1].id = MSM_RPMRS_ID_VDD_DIG_1,
114 .size = 2,
115 .name = "vdd_dig",
116 .beyond_limits = msm_rpmrs_vdd_dig_beyond_limits,
117 .aggregate = msm_rpmrs_aggregate_vdd_dig,
118 .restore = msm_rpmrs_restore_vdd_dig,
119};
120
121static struct msm_rpmrs_resource msm_rpmrs_rpm_cpu = {
122 .rs[0].id = MSM_RPMRS_ID_RPM_CTL,
123 .size = 1,
124 .name = "rpm_cpu",
125 .beyond_limits = NULL,
126 .aggregate = msm_rpmrs_aggregate_rpm_cpu,
127 .restore = msm_rpmrs_restore_rpm_cpu,
128};
129
130static struct msm_rpmrs_resource *msm_rpmrs_resources[] = {
131 &msm_rpmrs_pxo,
132 &msm_rpmrs_l2_cache,
133 &msm_rpmrs_vdd_mem,
134 &msm_rpmrs_vdd_dig,
135 &msm_rpmrs_rpm_cpu,
136};
137
138static uint32_t msm_rpmrs_buffer[MSM_RPM_ID_LAST + 1];
139static DECLARE_BITMAP(msm_rpmrs_buffered, MSM_RPM_ID_LAST + 1);
140static DECLARE_BITMAP(msm_rpmrs_listed, MSM_RPM_ID_LAST + 1);
141static DEFINE_SPINLOCK(msm_rpmrs_lock);
142
143#define MSM_RPMRS_VDD_MASK 0xfff
144#define MSM_RPMRS_VDD(v) ((v) & (MSM_RPMRS_VDD_MASK))
145
146/******************************************************************************
147 * Attribute Definitions
148 *****************************************************************************/
149
150struct msm_rpmrs_kboj_attribute {
151 struct msm_rpmrs_resource *rs;
152 struct kobj_attribute ka;
153};
154
155#define GET_RS_FROM_ATTR(attr) \
156 (container_of(attr, struct msm_rpmrs_kboj_attribute, ka)->rs)
157
158struct msm_rpmrs_resource_sysfs {
159 struct attribute_group attr_group;
160 struct attribute *attrs[2];
161 struct msm_rpmrs_kboj_attribute kas;
162};
163
164/******************************************************************************
165 * Resource Specific Functions
166 *****************************************************************************/
167
168static void msm_rpmrs_aggregate_sclk(uint32_t sclk_count)
169{
170 msm_rpmrs_buffer[MSM_RPM_ID_TRIGGER_TIMED_TO] = 0;
171 set_bit(MSM_RPM_ID_TRIGGER_TIMED_TO, msm_rpmrs_buffered);
172 msm_rpmrs_buffer[MSM_RPM_ID_TRIGGER_TIMED_SCLK_COUNT] = sclk_count;
173 set_bit(MSM_RPM_ID_TRIGGER_TIMED_SCLK_COUNT, msm_rpmrs_buffered);
174}
175
176static void msm_rpmrs_restore_sclk(void)
177{
178 clear_bit(MSM_RPM_ID_TRIGGER_TIMED_SCLK_COUNT, msm_rpmrs_buffered);
179 msm_rpmrs_buffer[MSM_RPM_ID_TRIGGER_TIMED_SCLK_COUNT] = 0;
180 clear_bit(MSM_RPM_ID_TRIGGER_TIMED_TO, msm_rpmrs_buffered);
181 msm_rpmrs_buffer[MSM_RPM_ID_TRIGGER_TIMED_TO] = 0;
182}
183
184static bool msm_rpmrs_pxo_beyond_limits(struct msm_rpmrs_limits *limits)
185{
186 struct msm_rpmrs_resource *rs = &msm_rpmrs_pxo;
187 uint32_t pxo;
188
189 if (rs->enable_low_power && test_bit(rs->rs[0].id, msm_rpmrs_buffered))
190 pxo = msm_rpmrs_buffer[rs->rs[0].id];
191 else
192 pxo = MSM_RPMRS_PXO_ON;
193
194 return pxo > limits->pxo;
195}
196
197static void msm_rpmrs_aggregate_pxo(struct msm_rpmrs_limits *limits)
198{
199 struct msm_rpmrs_resource *rs = &msm_rpmrs_pxo;
200 uint32_t *buf = &msm_rpmrs_buffer[rs->rs[0].id];
201
202 if (test_bit(rs->rs[0].id, msm_rpmrs_buffered)) {
203 rs->rs[0].value = *buf;
204 if (limits->pxo > *buf)
205 *buf = limits->pxo;
206 if (MSM_RPMRS_DEBUG_OUTPUT & msm_rpmrs_debug_mask)
207 pr_info("%s: %d (0x%x)\n", __func__, *buf, *buf);
208 }
209}
210
211static void msm_rpmrs_restore_pxo(void)
212{
213 struct msm_rpmrs_resource *rs = &msm_rpmrs_pxo;
214
215 if (test_bit(rs->rs[0].id, msm_rpmrs_buffered))
216 msm_rpmrs_buffer[rs->rs[0].id] = rs->rs[0].value;
217}
218
219static bool msm_rpmrs_l2_cache_beyond_limits(struct msm_rpmrs_limits *limits)
220{
221 struct msm_rpmrs_resource *rs = &msm_rpmrs_l2_cache;
222 uint32_t l2_cache;
223
224 if (rs->enable_low_power && test_bit(rs->rs[0].id, msm_rpmrs_buffered))
225 l2_cache = msm_rpmrs_buffer[rs->rs[0].id];
226 else
227 l2_cache = MSM_RPMRS_L2_CACHE_ACTIVE;
228
229 return l2_cache > limits->l2_cache;
230}
231
232static void msm_rpmrs_aggregate_l2_cache(struct msm_rpmrs_limits *limits)
233{
234 struct msm_rpmrs_resource *rs = &msm_rpmrs_l2_cache;
235 uint32_t *buf = &msm_rpmrs_buffer[rs->rs[0].id];
236
237 if (test_bit(rs->rs[0].id, msm_rpmrs_buffered)) {
238 rs->rs[0].value = *buf;
239 if (limits->l2_cache > *buf)
240 *buf = limits->l2_cache;
241
242 if (MSM_RPMRS_DEBUG_OUTPUT & msm_rpmrs_debug_mask)
243 pr_info("%s: %d (0x%x)\n", __func__, *buf, *buf);
244 }
245}
246
247#ifdef CONFIG_MSM_L2_SPM
248static bool msm_spm_l2_cache_beyond_limits(struct msm_rpmrs_limits *limits)
249{
250 struct msm_rpmrs_resource *rs = &msm_rpmrs_l2_cache;
251 uint32_t l2_cache = rs->rs[0].value;
252
253 if (!rs->enable_low_power)
254 l2_cache = MSM_RPMRS_L2_CACHE_ACTIVE;
255
256 return l2_cache > limits->l2_cache;
257}
258#endif
259
260static void msm_rpmrs_restore_l2_cache(void)
261{
262 struct msm_rpmrs_resource *rs = &msm_rpmrs_l2_cache;
263
264 if (test_bit(rs->rs[0].id, msm_rpmrs_buffered))
265 msm_rpmrs_buffer[rs->rs[0].id] = rs->rs[0].value;
266}
267
268static bool msm_rpmrs_vdd_mem_beyond_limits(struct msm_rpmrs_limits *limits)
269{
270 struct msm_rpmrs_resource *rs = &msm_rpmrs_vdd_mem;
271 uint32_t vdd_mem;
272
273 if (test_bit(rs->rs[0].id, msm_rpmrs_buffered)) {
274 uint32_t buffered_value = msm_rpmrs_buffer[rs->rs[0].id];
275
276 if (rs->enable_low_power == 0)
277 vdd_mem = MSM_RPMRS_VDD_MEM_ACTIVE;
278 else if (rs->enable_low_power == 1)
279 vdd_mem = MSM_RPMRS_VDD_MEM_RET_HIGH;
280 else
281 vdd_mem = MSM_RPMRS_VDD_MEM_RET_LOW;
282
283 if (MSM_RPMRS_VDD(buffered_value) > MSM_RPMRS_VDD(vdd_mem))
284 vdd_mem = buffered_value;
285 } else {
286 vdd_mem = MSM_RPMRS_VDD_MEM_ACTIVE;
287 }
288
289 return MSM_RPMRS_VDD(vdd_mem) >=
290 MSM_RPMRS_VDD(limits->vdd_mem_upper_bound);
291}
292
293static void msm_rpmrs_aggregate_vdd_mem(struct msm_rpmrs_limits *limits)
294{
295 struct msm_rpmrs_resource *rs = &msm_rpmrs_vdd_mem;
296 uint32_t *buf = &msm_rpmrs_buffer[rs->rs[0].id];
297
298 if (test_bit(rs->rs[0].id, msm_rpmrs_buffered)) {
299 rs->rs[0].value = *buf;
300 if (MSM_RPMRS_VDD(limits->vdd_mem) > MSM_RPMRS_VDD(*buf)) {
301 *buf &= ~MSM_RPMRS_VDD_MASK;
302 *buf |= MSM_RPMRS_VDD(limits->vdd_mem);
303 }
304
305 if (MSM_RPMRS_DEBUG_OUTPUT & msm_rpmrs_debug_mask)
306 pr_info("%s: vdd %d (0x%x)\n", __func__,
307 MSM_RPMRS_VDD(*buf), MSM_RPMRS_VDD(*buf));
308 }
309}
310
311static void msm_rpmrs_restore_vdd_mem(void)
312{
313 struct msm_rpmrs_resource *rs = &msm_rpmrs_vdd_mem;
314
315 if (test_bit(rs->rs[0].id, msm_rpmrs_buffered))
316 msm_rpmrs_buffer[rs->rs[0].id] = rs->rs[0].value;
317}
318
319static bool msm_rpmrs_vdd_dig_beyond_limits(struct msm_rpmrs_limits *limits)
320{
321 struct msm_rpmrs_resource *rs = &msm_rpmrs_vdd_dig;
322 uint32_t vdd_dig;
323
324 if (test_bit(rs->rs[0].id, msm_rpmrs_buffered)) {
325 uint32_t buffered_value = msm_rpmrs_buffer[rs->rs[0].id];
326
327 if (rs->enable_low_power == 0)
328 vdd_dig = MSM_RPMRS_VDD_DIG_ACTIVE;
329 else if (rs->enable_low_power == 1)
330 vdd_dig = MSM_RPMRS_VDD_DIG_RET_HIGH;
331 else
332 vdd_dig = MSM_RPMRS_VDD_DIG_RET_LOW;
333
334 if (MSM_RPMRS_VDD(buffered_value) > MSM_RPMRS_VDD(vdd_dig))
335 vdd_dig = buffered_value;
336 } else {
337 vdd_dig = MSM_RPMRS_VDD_DIG_ACTIVE;
338 }
339
340 return MSM_RPMRS_VDD(vdd_dig) >=
341 MSM_RPMRS_VDD(limits->vdd_dig_upper_bound);
342}
343
344static void msm_rpmrs_aggregate_vdd_dig(struct msm_rpmrs_limits *limits)
345{
346 struct msm_rpmrs_resource *rs = &msm_rpmrs_vdd_dig;
347 uint32_t *buf = &msm_rpmrs_buffer[rs->rs[0].id];
348
349 if (test_bit(rs->rs[0].id, msm_rpmrs_buffered)) {
350 rs->rs[0].value = *buf;
351 if (MSM_RPMRS_VDD(limits->vdd_dig) > MSM_RPMRS_VDD(*buf)) {
352 *buf &= ~MSM_RPMRS_VDD_MASK;
353 *buf |= MSM_RPMRS_VDD(limits->vdd_dig);
354 }
355
356
357 if (MSM_RPMRS_DEBUG_OUTPUT & msm_rpmrs_debug_mask)
358 pr_info("%s: vdd %d (0x%x)\n", __func__,
359 MSM_RPMRS_VDD(*buf), MSM_RPMRS_VDD(*buf));
360 }
361}
362
363static void msm_rpmrs_restore_vdd_dig(void)
364{
365 struct msm_rpmrs_resource *rs = &msm_rpmrs_vdd_dig;
366
367 if (test_bit(rs->rs[0].id, msm_rpmrs_buffered))
368 msm_rpmrs_buffer[rs->rs[0].id] = rs->rs[0].value;
369}
370
371static void msm_rpmrs_aggregate_rpm_cpu(struct msm_rpmrs_limits *limits)
372{
373 struct msm_rpmrs_resource *rs = &msm_rpmrs_rpm_cpu;
374
375 if (test_bit(rs->rs[0].id, msm_rpmrs_buffered)) {
376 rs->rs[0].value = msm_rpmrs_buffer[rs->rs[0].id];
377 if (!msm_rpmrs_rpm_cpu.enable_low_power)
378 msm_rpmrs_buffer[rs->rs[0].id] = 1;
379 }
380}
381
382static void msm_rpmrs_restore_rpm_cpu(void)
383{
384 struct msm_rpmrs_resource *rs = &msm_rpmrs_rpm_cpu;
385
386 if (test_bit(rs->rs[0].id, msm_rpmrs_buffered))
387 msm_rpmrs_buffer[rs->rs[0].id] = rs->rs[0].value;
388}
389
390/******************************************************************************
391 * Buffering Functions
392 *****************************************************************************/
393
394static bool msm_rpmrs_irqs_detectable(struct msm_rpmrs_limits *limits,
395 bool irqs_detect, bool gpio_detect)
396{
397
398 if (limits->vdd_dig <= MSM_RPMRS_VDD_DIG_RET_HIGH)
399 return irqs_detect;
400
401 if (limits->pxo == MSM_RPMRS_PXO_OFF)
402 return gpio_detect;
403
404 return true;
405}
406
407static bool msm_rpmrs_use_mpm(struct msm_rpmrs_limits *limits)
408{
409 return (limits->pxo == MSM_RPMRS_PXO_OFF) ||
410 (limits->vdd_dig <= MSM_RPMRS_VDD_DIG_RET_HIGH);
411}
412
413static void msm_rpmrs_update_levels(void)
414{
415 int i, k;
416
417 for (i = 0; i < msm_rpmrs_level_count; i++) {
418 struct msm_rpmrs_level *level = &msm_rpmrs_levels[i];
419
420 if (level->sleep_mode != MSM_PM_SLEEP_MODE_POWER_COLLAPSE)
421 continue;
422
423 level->available = true;
424
425 for (k = 0; k < ARRAY_SIZE(msm_rpmrs_resources); k++) {
426 struct msm_rpmrs_resource *rs = msm_rpmrs_resources[k];
427
428 if (rs->beyond_limits &&
429 rs->beyond_limits(&level->rs_limits)) {
430 level->available = false;
431 break;
432 }
433 }
434 }
435}
436
437/*
438 * Return value:
439 * 0: no entries in <req> is on our resource list
440 * 1: one or more entries in <req> is on our resource list
441 * -EINVAL: invalid id in <req> array
442 */
443static int msm_rpmrs_buffer_request(struct msm_rpm_iv_pair *req, int count)
444{
445 bool listed;
446 int i;
447
448 for (i = 0; i < count; i++)
449 if (req[i].id > MSM_RPM_ID_LAST)
450 return -EINVAL;
451
452 for (i = 0, listed = false; i < count; i++) {
453 msm_rpmrs_buffer[req[i].id] = req[i].value;
454 set_bit(req[i].id, msm_rpmrs_buffered);
455
456 if (MSM_RPMRS_DEBUG_BUFFER & msm_rpmrs_debug_mask)
457 pr_info("%s: reg %d: 0x%x\n",
458 __func__, req[i].id, req[i].value);
459
460 if (listed)
461 continue;
462
463 if (test_bit(req[i].id, msm_rpmrs_listed))
464 listed = true;
465 }
466
467 return listed ? 1 : 0;
468}
469
470/*
471 * Return value:
472 * 0: no entries in <req> is on our resource list
473 * 1: one or more entries in <req> is on our resource list
474 * -EINVAL: invalid id in <req> array
475 */
476static int msm_rpmrs_clear_buffer(struct msm_rpm_iv_pair *req, int count)
477{
478 bool listed;
479 int i;
480
481 for (i = 0; i < count; i++)
482 if (req[i].id > MSM_RPM_ID_LAST)
483 return -EINVAL;
484
485 for (i = 0, listed = false; i < count; i++) {
486 msm_rpmrs_buffer[req[i].id] = 0;
487 clear_bit(req[i].id, msm_rpmrs_buffered);
488
489 if (MSM_RPMRS_DEBUG_BUFFER & msm_rpmrs_debug_mask)
490 pr_info("%s: reg %d\n", __func__, req[i].id);
491
492 if (listed)
493 continue;
494
495 if (test_bit(req[i].id, msm_rpmrs_listed))
496 listed = true;
497 }
498
499 return listed ? 1 : 0;
500}
501
502#ifdef CONFIG_MSM_L2_SPM
503static int msm_rpmrs_flush_L2(struct msm_rpmrs_limits *limits, int notify_rpm)
504{
505 int rc = 0;
506 int lpm;
507
508 switch (limits->l2_cache) {
509 case MSM_RPMRS_L2_CACHE_HSFS_OPEN:
510 lpm = MSM_SPM_L2_MODE_POWER_COLLAPSE;
511 /* Increment the counter for TZ to init L2 on warmboot */
512 /* Barrier in msm_spm_l2_set_low_power_mode */
513 BUG_ON(!msm_rpmrs_l2_counter_addr);
514 writel_relaxed(++msm_rpmrs_l2_reset_count,
515 msm_rpmrs_l2_counter_addr);
516 break;
517 case MSM_RPMRS_L2_CACHE_GDHS:
518 lpm = MSM_SPM_L2_MODE_GDHS;
519 break;
520 case MSM_RPMRS_L2_CACHE_RETENTION:
521 lpm = MSM_SPM_L2_MODE_RETENTION;
522 break;
523 default:
524 case MSM_RPMRS_L2_CACHE_ACTIVE:
525 lpm = MSM_SPM_L2_MODE_DISABLED;
526 break;
527 }
528
529 rc = msm_spm_l2_set_low_power_mode(lpm, notify_rpm);
530 if (MSM_RPMRS_DEBUG_BUFFER & msm_rpmrs_debug_mask)
531 pr_info("%s: Requesting low power mode %d returned %d\n",
532 __func__, lpm, rc);
533
534 return rc;
535}
536#else
537static int msm_rpmrs_flush_L2(struct msm_rpmrs_limits *limits, int notify_rpm)
538{
539 return 0;
540}
541#endif
542
543static int msm_rpmrs_flush_buffer(
544 uint32_t sclk_count, struct msm_rpmrs_limits *limits, int from_idle)
545{
546 struct msm_rpm_iv_pair *req;
547 int count;
548 int rc;
549 int i;
550
551 msm_rpmrs_aggregate_sclk(sclk_count);
552 for (i = 0; i < ARRAY_SIZE(msm_rpmrs_resources); i++) {
553 if (msm_rpmrs_resources[i]->aggregate)
554 msm_rpmrs_resources[i]->aggregate(limits);
555 }
556
557 count = bitmap_weight(msm_rpmrs_buffered, MSM_RPM_ID_LAST + 1);
558
559 req = kmalloc(sizeof(*req) * count, GFP_ATOMIC);
560 if (!req) {
561 rc = -ENOMEM;
562 goto flush_buffer_restore;
563 }
564
565 count = 0;
566 i = find_first_bit(msm_rpmrs_buffered, MSM_RPM_ID_LAST + 1);
567
568 while (i < MSM_RPM_ID_LAST + 1) {
569 if (MSM_RPMRS_DEBUG_OUTPUT & msm_rpmrs_debug_mask)
570 pr_info("%s: reg %d: 0x%x\n",
571 __func__, i, msm_rpmrs_buffer[i]);
572
573 req[count].id = i;
574 req[count].value = msm_rpmrs_buffer[i];
575 count++;
576
577 i = find_next_bit(msm_rpmrs_buffered, MSM_RPM_ID_LAST+1, i+1);
578 }
579
580 rc = msm_rpm_set_noirq(MSM_RPM_CTX_SET_SLEEP, req, count);
581 kfree(req);
582
583 if (rc)
584 goto flush_buffer_restore;
585
586 bitmap_and(msm_rpmrs_buffered,
587 msm_rpmrs_buffered, msm_rpmrs_listed, MSM_RPM_ID_LAST + 1);
588
589flush_buffer_restore:
590 for (i = 0; i < ARRAY_SIZE(msm_rpmrs_resources); i++) {
591 if (msm_rpmrs_resources[i]->restore)
592 msm_rpmrs_resources[i]->restore();
593 }
594 msm_rpmrs_restore_sclk();
595
596 if (rc)
597 pr_err("%s: failed: %d\n", __func__, rc);
598 return rc;
599}
600
601static int msm_rpmrs_set_common(
602 int ctx, struct msm_rpm_iv_pair *req, int count, bool noirq)
603{
604 if (ctx == MSM_RPM_CTX_SET_SLEEP) {
605 unsigned long flags;
606 int rc;
607
608 spin_lock_irqsave(&msm_rpmrs_lock, flags);
609 rc = msm_rpmrs_buffer_request(req, count);
610 if (rc > 0) {
611 msm_rpmrs_update_levels();
612 rc = 0;
613 }
614 spin_unlock_irqrestore(&msm_rpmrs_lock, flags);
615
616 return rc;
617 }
618
619 if (noirq)
620 return msm_rpm_set_noirq(ctx, req, count);
621 else
622 return msm_rpm_set(ctx, req, count);
623}
624
625static int msm_rpmrs_clear_common(
626 int ctx, struct msm_rpm_iv_pair *req, int count, bool noirq)
627{
628 if (ctx == MSM_RPM_CTX_SET_SLEEP) {
629 unsigned long flags;
630 int rc;
631
632 spin_lock_irqsave(&msm_rpmrs_lock, flags);
633 rc = msm_rpmrs_clear_buffer(req, count);
634 if (rc > 0) {
635 msm_rpmrs_update_levels();
636 rc = 0;
637 }
638 spin_unlock_irqrestore(&msm_rpmrs_lock, flags);
639
640 if (rc < 0)
641 return rc;
642 }
643
644 if (noirq)
645 return msm_rpm_clear_noirq(ctx, req, count);
646 else
647 return msm_rpm_clear(ctx, req, count);
648}
649
650/******************************************************************************
651 * Attribute Functions
652 *****************************************************************************/
653
654static ssize_t msm_rpmrs_resource_attr_show(
655 struct kobject *kobj, struct kobj_attribute *attr, char *buf)
656{
657 struct kernel_param kp;
658 unsigned long flags;
659 unsigned int temp;
660 int rc;
661
662 spin_lock_irqsave(&msm_rpmrs_lock, flags);
663 temp = GET_RS_FROM_ATTR(attr)->enable_low_power;
664 spin_unlock_irqrestore(&msm_rpmrs_lock, flags);
665
666 kp.arg = &temp;
667 rc = param_get_uint(buf, &kp);
668
669 if (rc > 0) {
670 strcat(buf, "\n");
671 rc++;
672 }
673
674 return rc;
675}
676
677static ssize_t msm_rpmrs_resource_attr_store(struct kobject *kobj,
678 struct kobj_attribute *attr, const char *buf, size_t count)
679{
680 struct kernel_param kp;
681 unsigned long flags;
682 unsigned int temp;
683 int rc;
684
685 kp.arg = &temp;
686 rc = param_set_uint(buf, &kp);
687 if (rc)
688 return rc;
689
690 spin_lock_irqsave(&msm_rpmrs_lock, flags);
691 GET_RS_FROM_ATTR(attr)->enable_low_power = temp;
692 msm_rpmrs_update_levels();
693 spin_unlock_irqrestore(&msm_rpmrs_lock, flags);
694
695 return count;
696}
697
698static int __init msm_rpmrs_resource_sysfs_add(void)
699{
700 struct kobject *module_kobj;
701 struct kobject *low_power_kboj;
702 struct msm_rpmrs_resource_sysfs *rs;
703 int i;
704 int rc;
705
706 module_kobj = kset_find_obj(module_kset, KBUILD_MODNAME);
707 if (!module_kobj) {
708 pr_err("%s: cannot find kobject for module %s\n",
709 __func__, KBUILD_MODNAME);
710 rc = -ENOENT;
711 goto resource_sysfs_add_exit;
712 }
713
714 low_power_kboj = kobject_create_and_add(
715 "enable_low_power", module_kobj);
716 if (!low_power_kboj) {
717 pr_err("%s: cannot create kobject\n", __func__);
718 rc = -ENOMEM;
719 goto resource_sysfs_add_exit;
720 }
721
722 for (i = 0; i < ARRAY_SIZE(msm_rpmrs_resources); i++) {
723 rs = kzalloc(sizeof(*rs), GFP_KERNEL);
724 if (!rs) {
725 pr_err("%s: cannot allocate memory for attributes\n",
726 __func__);
727 rc = -ENOMEM;
728 goto resource_sysfs_add_exit;
729 }
730
731 rs->kas.rs = msm_rpmrs_resources[i];
732 rs->kas.ka.attr.name = msm_rpmrs_resources[i]->name;
733 rs->kas.ka.attr.mode = 0644;
734 rs->kas.ka.show = msm_rpmrs_resource_attr_show;
735 rs->kas.ka.store = msm_rpmrs_resource_attr_store;
736
737 rs->attrs[0] = &rs->kas.ka.attr;
738 rs->attrs[1] = NULL;
739 rs->attr_group.attrs = rs->attrs;
740
741 rc = sysfs_create_group(low_power_kboj, &rs->attr_group);
742 if (rc) {
743 pr_err("%s: cannot create kobject attribute group\n",
744 __func__);
745 goto resource_sysfs_add_exit;
746 }
747 }
748
749 rc = 0;
750
751resource_sysfs_add_exit:
752 return rc;
753}
754
755/******************************************************************************
756 * Public Functions
757 *****************************************************************************/
758
759int msm_rpmrs_set(int ctx, struct msm_rpm_iv_pair *req, int count)
760{
761 return msm_rpmrs_set_common(ctx, req, count, false);
762}
763
764int msm_rpmrs_set_noirq(int ctx, struct msm_rpm_iv_pair *req, int count)
765{
766 WARN(!irqs_disabled(), "msm_rpmrs_set_noirq can only be called "
767 "safely when local irqs are disabled. Consider using "
768 "msm_rpmrs_set or msm_rpmrs_set_nosleep instead.");
769 return msm_rpmrs_set_common(ctx, req, count, true);
770}
771
772int msm_rpmrs_clear(int ctx, struct msm_rpm_iv_pair *req, int count)
773{
774 return msm_rpmrs_clear_common(ctx, req, count, false);
775}
776
777int msm_rpmrs_clear_noirq(int ctx, struct msm_rpm_iv_pair *req, int count)
778{
779 WARN(!irqs_disabled(), "msm_rpmrs_clear_noirq can only be called "
780 "safely when local irqs are disabled. Consider using "
781 "msm_rpmrs_clear or msm_rpmrs_clear_nosleep instead.");
782 return msm_rpmrs_clear_common(ctx, req, count, true);
783}
784
785void msm_rpmrs_show_resources(void)
786{
787 struct msm_rpmrs_resource *rs;
788 unsigned long flags;
789 int i;
790
791 spin_lock_irqsave(&msm_rpmrs_lock, flags);
792 for (i = 0; i < ARRAY_SIZE(msm_rpmrs_resources); i++) {
793 rs = msm_rpmrs_resources[i];
794 if (rs->rs[0].id < MSM_RPM_ID_LAST + 1)
795 pr_info("%s: resource %s: buffered %d, value 0x%x\n",
796 __func__, rs->name,
797 test_bit(rs->rs[0].id, msm_rpmrs_buffered),
798 msm_rpmrs_buffer[rs->rs[0].id]);
799 else
800 pr_info("%s: resource %s: value %d\n",
801 __func__, rs->name, rs->rs[0].value);
802 }
803 spin_unlock_irqrestore(&msm_rpmrs_lock, flags);
804}
805
806struct msm_rpmrs_limits *msm_rpmrs_lowest_limits(
807 bool from_idle, enum msm_pm_sleep_mode sleep_mode, uint32_t latency_us,
808 uint32_t sleep_us)
809{
810 unsigned int cpu = smp_processor_id();
811 struct msm_rpmrs_level *best_level = NULL;
812 bool irqs_detectable = false;
813 bool gpio_detectable = false;
814 int i;
815
816 if (sleep_mode == MSM_PM_SLEEP_MODE_POWER_COLLAPSE) {
817 irqs_detectable = msm_mpm_irqs_detectable(from_idle);
818 gpio_detectable = msm_mpm_gpio_irqs_detectable(from_idle);
819 }
820
821 for (i = 0; i < msm_rpmrs_level_count; i++) {
822 struct msm_rpmrs_level *level = &msm_rpmrs_levels[i];
823 uint32_t power;
824
825 if (!level->available)
826 continue;
827
828 if (sleep_mode != level->sleep_mode)
829 continue;
830
831 if (latency_us < level->latency_us)
832 continue;
833
834 if (!msm_rpmrs_irqs_detectable(&level->rs_limits,
835 irqs_detectable, gpio_detectable))
836 continue;
837
838 if (sleep_us <= 1) {
839 power = level->energy_overhead;
840 } else if (sleep_us <= level->time_overhead_us) {
841 power = level->energy_overhead / sleep_us;
842 } else if ((sleep_us >> 10) > level->time_overhead_us) {
843 power = level->steady_state_power;
844 } else {
845 power = (sleep_us - level->time_overhead_us);
846 power *= level->steady_state_power;
847 power /= sleep_us;
848 power += level->energy_overhead / sleep_us;
849 }
850
851 if (!best_level ||
852 best_level->rs_limits.power[cpu] >= power) {
853 level->rs_limits.latency_us[cpu] = level->latency_us;
854 level->rs_limits.power[cpu] = power;
855 best_level = level;
856 }
857 }
858
859 return best_level ? &best_level->rs_limits : NULL;
860}
861
862int msm_rpmrs_enter_sleep(uint32_t sclk_count, struct msm_rpmrs_limits *limits,
863 bool from_idle, bool notify_rpm)
864{
865 int rc = 0;
866
867 rc = msm_rpmrs_flush_L2(limits, notify_rpm);
868 if (rc)
869 return rc;
870
871 if (notify_rpm) {
872 rc = msm_rpmrs_flush_buffer(sclk_count, limits, from_idle);
873 if (rc)
874 return rc;
875
876 if (msm_rpmrs_use_mpm(limits))
877 msm_mpm_enter_sleep(from_idle);
878 }
879
880 return rc;
881}
882
883void msm_rpmrs_exit_sleep(struct msm_rpmrs_limits *limits,
884 bool from_idle, bool notify_rpm)
885{
886
887 /* Disable L2 for now, we dont want L2 to do retention by default */
888 msm_spm_l2_set_low_power_mode(MSM_SPM_MODE_DISABLED, notify_rpm);
889
890 if (msm_rpmrs_use_mpm(limits))
891 msm_mpm_exit_sleep(from_idle);
892}
893
894#ifdef CONFIG_MSM_L2_SPM
895static int rpmrs_cpu_callback(struct notifier_block *nfb,
896 unsigned long action, void *hcpu)
897{
898 switch (action) {
899 case CPU_ONLINE_FROZEN:
900 case CPU_ONLINE:
901 if (num_online_cpus() > 1)
902 msm_rpmrs_l2_cache.rs[0].value =
903 MSM_RPMRS_L2_CACHE_ACTIVE;
904 break;
905 case CPU_DEAD_FROZEN:
906 case CPU_DEAD:
907 if (num_online_cpus() == 1)
908 msm_rpmrs_l2_cache.rs[0].value =
909 MSM_RPMRS_L2_CACHE_HSFS_OPEN;
910 break;
911 }
912
913 msm_rpmrs_update_levels();
914 return NOTIFY_OK;
915}
916
917static struct notifier_block __refdata rpmrs_cpu_notifier = {
918 .notifier_call = rpmrs_cpu_callback,
919};
920#endif
921
922int __init msm_rpmrs_levels_init(struct msm_rpmrs_level *levels, int size)
923{
924 msm_rpmrs_levels = kzalloc(sizeof(struct msm_rpmrs_level) * size,
925 GFP_KERNEL);
926 if (!msm_rpmrs_levels)
927 return -ENOMEM;
928 msm_rpmrs_level_count = size;
929 memcpy(msm_rpmrs_levels, levels, size * sizeof(struct msm_rpmrs_level));
930
931 return 0;
932}
933
934static int __init msm_rpmrs_init(void)
935{
936 struct msm_rpm_iv_pair req;
937 int rc;
938
939 BUG_ON(!msm_rpmrs_levels);
940
941 if (machine_is_msm8x60_surf() || machine_is_msm8x60_ffa() ||
942 machine_is_msm8x60_fluid() || machine_is_msm8x60_fusion() ||
943 machine_is_msm8x60_fusn_ffa()) {
944
945 req.id = MSM_RPMRS_ID_APPS_L2_CACHE_CTL;
946 req.value = 1;
947
948 rc = msm_rpm_set(MSM_RPM_CTX_SET_0, &req, 1);
949 if (rc) {
950 pr_err("%s: failed to request L2 cache: %d\n",
951 __func__, rc);
952 goto init_exit;
953 }
954
955 req.id = MSM_RPMRS_ID_APPS_L2_CACHE_CTL;
956 req.value = 0;
957
958 rc = msm_rpmrs_set(MSM_RPM_CTX_SET_SLEEP, &req, 1);
959 if (rc) {
960 pr_err("%s: failed to initialize L2 cache for sleep: "
961 "%d\n", __func__, rc);
962 goto init_exit;
963 }
964 }
965
966 req.id = MSM_RPMRS_ID_RPM_CTL;
967 req.value = 0;
968
969 rc = msm_rpmrs_set(MSM_RPM_CTX_SET_SLEEP, &req, 1);
970 if (rc) {
971 pr_err("%s: failed to initialize RPM CPU for sleep: %d\n",
972 __func__, rc);
973 goto init_exit;
974 }
975
976 rc = msm_rpmrs_resource_sysfs_add();
977
978init_exit:
979 return rc;
980}
981device_initcall(msm_rpmrs_init);
982
983static int __init msm_rpmrs_early_init(void)
984{
985 int i, k;
986
987 /* Initialize listed bitmap for valid resource IDs */
988 for (i = 0; i < ARRAY_SIZE(msm_rpmrs_resources); i++) {
989 for (k = 0; k < msm_rpmrs_resources[i]->size; k++)
990 set_bit(msm_rpmrs_resources[i]->rs[k].id,
991 msm_rpmrs_listed);
992 }
993
994 return 0;
995}
996early_initcall(msm_rpmrs_early_init);
997
998#ifdef CONFIG_MSM_L2_SPM
999static int __init msm_rpmrs_l2_counter_init(void)
1000{
1001 msm_rpmrs_l2_counter_addr = MSM_IMEM_BASE + L2_PC_COUNTER_ADDR;
1002 writel_relaxed(msm_rpmrs_l2_reset_count, msm_rpmrs_l2_counter_addr);
1003 mb();
1004
1005 msm_rpmrs_l2_cache.beyond_limits = msm_spm_l2_cache_beyond_limits;
1006 msm_rpmrs_l2_cache.aggregate = NULL;
1007 msm_rpmrs_l2_cache.restore = NULL;
1008
1009 register_hotcpu_notifier(&rpmrs_cpu_notifier);
1010
1011 return 0;
1012}
1013early_initcall(msm_rpmrs_l2_counter_init);
1014#endif