aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/mach-omap2/Makefile4
-rw-r--r--arch/arm/mach-omap2/smartreflex.c1129
-rw-r--r--arch/arm/plat-omap/Kconfig22
3 files changed, 5 insertions, 1150 deletions
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
index 518444acc90f..f8ee10a06f46 100644
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -70,8 +70,8 @@ obj-$(CONFIG_ARCH_OMAP4) += pm44xx.o omap-mpuss-lowpower.o \
70 cpuidle44xx.o 70 cpuidle44xx.o
71obj-$(CONFIG_PM_DEBUG) += pm-debug.o 71obj-$(CONFIG_PM_DEBUG) += pm-debug.o
72 72
73obj-$(CONFIG_POWER_AVS_OMAP) += sr_device.o smartreflex.o 73obj-$(CONFIG_POWER_AVS_OMAP) += sr_device.o
74obj-$(CONFIG_POWER_AVS_OMAP_CLASS3) += smartreflex-class3.o 74obj-$(CONFIG_POWER_AVS_OMAP_CLASS3) += smartreflex-class3.o
75 75
76AFLAGS_sleep24xx.o :=-Wa,-march=armv6 76AFLAGS_sleep24xx.o :=-Wa,-march=armv6
77AFLAGS_sleep34xx.o :=-Wa,-march=armv7-a$(plus_sec) 77AFLAGS_sleep34xx.o :=-Wa,-march=armv7-a$(plus_sec)
diff --git a/arch/arm/mach-omap2/smartreflex.c b/arch/arm/mach-omap2/smartreflex.c
deleted file mode 100644
index 515041ccccb8..000000000000
--- a/arch/arm/mach-omap2/smartreflex.c
+++ /dev/null
@@ -1,1129 +0,0 @@
1/*
2 * OMAP SmartReflex Voltage Control
3 *
4 * Author: Thara Gopinath <thara@ti.com>
5 *
6 * Copyright (C) 2010 Texas Instruments, Inc.
7 * Thara Gopinath <thara@ti.com>
8 *
9 * Copyright (C) 2008 Nokia Corporation
10 * Kalle Jokiniemi
11 *
12 * Copyright (C) 2007 Texas Instruments, Inc.
13 * Lesly A M <x0080970@ti.com>
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License version 2 as
17 * published by the Free Software Foundation.
18 */
19
20#include <linux/module.h>
21#include <linux/interrupt.h>
22#include <linux/clk.h>
23#include <linux/io.h>
24#include <linux/debugfs.h>
25#include <linux/delay.h>
26#include <linux/slab.h>
27#include <linux/pm_runtime.h>
28#include <linux/power/smartreflex.h>
29
30#include "common.h"
31#include "pm.h"
32
33#define SMARTREFLEX_NAME_LEN 16
34#define NVALUE_NAME_LEN 40
35#define SR_DISABLE_TIMEOUT 200
36
37/* sr_list contains all the instances of smartreflex module */
38static LIST_HEAD(sr_list);
39
40static struct omap_sr_class_data *sr_class;
41static struct omap_sr_pmic_data *sr_pmic_data;
42static struct dentry *sr_dbg_dir;
43
44static inline void sr_write_reg(struct omap_sr *sr, unsigned offset, u32 value)
45{
46 __raw_writel(value, (sr->base + offset));
47}
48
49static inline void sr_modify_reg(struct omap_sr *sr, unsigned offset, u32 mask,
50 u32 value)
51{
52 u32 reg_val;
53
54 /*
55 * Smartreflex error config register is special as it contains
56 * certain status bits which if written a 1 into means a clear
57 * of those bits. So in order to make sure no accidental write of
58 * 1 happens to those status bits, do a clear of them in the read
59 * value. This mean this API doesn't rewrite values in these bits
60 * if they are currently set, but does allow the caller to write
61 * those bits.
62 */
63 if (sr->ip_type == SR_TYPE_V1 && offset == ERRCONFIG_V1)
64 mask |= ERRCONFIG_STATUS_V1_MASK;
65 else if (sr->ip_type == SR_TYPE_V2 && offset == ERRCONFIG_V2)
66 mask |= ERRCONFIG_VPBOUNDINTST_V2;
67
68 reg_val = __raw_readl(sr->base + offset);
69 reg_val &= ~mask;
70
71 value &= mask;
72
73 reg_val |= value;
74
75 __raw_writel(reg_val, (sr->base + offset));
76}
77
78static inline u32 sr_read_reg(struct omap_sr *sr, unsigned offset)
79{
80 return __raw_readl(sr->base + offset);
81}
82
83static struct omap_sr *_sr_lookup(struct voltagedomain *voltdm)
84{
85 struct omap_sr *sr_info;
86
87 if (!voltdm) {
88 pr_err("%s: Null voltage domain passed!\n", __func__);
89 return ERR_PTR(-EINVAL);
90 }
91
92 list_for_each_entry(sr_info, &sr_list, node) {
93 if (voltdm == sr_info->voltdm)
94 return sr_info;
95 }
96
97 return ERR_PTR(-ENODATA);
98}
99
100static irqreturn_t sr_interrupt(int irq, void *data)
101{
102 struct omap_sr *sr_info = data;
103 u32 status = 0;
104
105 switch (sr_info->ip_type) {
106 case SR_TYPE_V1:
107 /* Read the status bits */
108 status = sr_read_reg(sr_info, ERRCONFIG_V1);
109
110 /* Clear them by writing back */
111 sr_write_reg(sr_info, ERRCONFIG_V1, status);
112 break;
113 case SR_TYPE_V2:
114 /* Read the status bits */
115 status = sr_read_reg(sr_info, IRQSTATUS);
116
117 /* Clear them by writing back */
118 sr_write_reg(sr_info, IRQSTATUS, status);
119 break;
120 default:
121 dev_err(&sr_info->pdev->dev, "UNKNOWN IP type %d\n",
122 sr_info->ip_type);
123 return IRQ_NONE;
124 }
125
126 if (sr_class->notify)
127 sr_class->notify(sr_info, status);
128
129 return IRQ_HANDLED;
130}
131
132static void sr_set_clk_length(struct omap_sr *sr)
133{
134 struct clk *sys_ck;
135 u32 sys_clk_speed;
136
137 if (cpu_is_omap34xx())
138 sys_ck = clk_get(NULL, "sys_ck");
139 else
140 sys_ck = clk_get(NULL, "sys_clkin_ck");
141
142 if (IS_ERR(sys_ck)) {
143 dev_err(&sr->pdev->dev, "%s: unable to get sys clk\n",
144 __func__);
145 return;
146 }
147
148 sys_clk_speed = clk_get_rate(sys_ck);
149 clk_put(sys_ck);
150
151 switch (sys_clk_speed) {
152 case 12000000:
153 sr->clk_length = SRCLKLENGTH_12MHZ_SYSCLK;
154 break;
155 case 13000000:
156 sr->clk_length = SRCLKLENGTH_13MHZ_SYSCLK;
157 break;
158 case 19200000:
159 sr->clk_length = SRCLKLENGTH_19MHZ_SYSCLK;
160 break;
161 case 26000000:
162 sr->clk_length = SRCLKLENGTH_26MHZ_SYSCLK;
163 break;
164 case 38400000:
165 sr->clk_length = SRCLKLENGTH_38MHZ_SYSCLK;
166 break;
167 default:
168 dev_err(&sr->pdev->dev, "%s: Invalid sysclk value: %d\n",
169 __func__, sys_clk_speed);
170 break;
171 }
172}
173
174static void sr_set_regfields(struct omap_sr *sr)
175{
176 /*
177 * For time being these values are defined in smartreflex.h
178 * and populated during init. May be they can be moved to board
179 * file or pmic specific data structure. In that case these structure
180 * fields will have to be populated using the pdata or pmic structure.
181 */
182 if (cpu_is_omap34xx() || cpu_is_omap44xx()) {
183 sr->err_weight = OMAP3430_SR_ERRWEIGHT;
184 sr->err_maxlimit = OMAP3430_SR_ERRMAXLIMIT;
185 sr->accum_data = OMAP3430_SR_ACCUMDATA;
186 if (!(strcmp(sr->name, "smartreflex_mpu_iva"))) {
187 sr->senn_avgweight = OMAP3430_SR1_SENNAVGWEIGHT;
188 sr->senp_avgweight = OMAP3430_SR1_SENPAVGWEIGHT;
189 } else {
190 sr->senn_avgweight = OMAP3430_SR2_SENNAVGWEIGHT;
191 sr->senp_avgweight = OMAP3430_SR2_SENPAVGWEIGHT;
192 }
193 }
194}
195
196static void sr_start_vddautocomp(struct omap_sr *sr)
197{
198 if (!sr_class || !(sr_class->enable) || !(sr_class->configure)) {
199 dev_warn(&sr->pdev->dev,
200 "%s: smartreflex class driver not registered\n",
201 __func__);
202 return;
203 }
204
205 if (!sr_class->enable(sr))
206 sr->autocomp_active = true;
207}
208
209static void sr_stop_vddautocomp(struct omap_sr *sr)
210{
211 if (!sr_class || !(sr_class->disable)) {
212 dev_warn(&sr->pdev->dev,
213 "%s: smartreflex class driver not registered\n",
214 __func__);
215 return;
216 }
217
218 if (sr->autocomp_active) {
219 sr_class->disable(sr, 1);
220 sr->autocomp_active = false;
221 }
222}
223
224/*
225 * This function handles the intializations which have to be done
226 * only when both sr device and class driver regiter has
227 * completed. This will be attempted to be called from both sr class
228 * driver register and sr device intializtion API's. Only one call
229 * will ultimately succeed.
230 *
231 * Currently this function registers interrupt handler for a particular SR
232 * if smartreflex class driver is already registered and has
233 * requested for interrupts and the SR interrupt line in present.
234 */
235static int sr_late_init(struct omap_sr *sr_info)
236{
237 struct omap_sr_data *pdata = sr_info->pdev->dev.platform_data;
238 struct resource *mem;
239 int ret = 0;
240
241 if (sr_class->notify && sr_class->notify_flags && sr_info->irq) {
242 ret = request_irq(sr_info->irq, sr_interrupt,
243 0, sr_info->name, sr_info);
244 if (ret)
245 goto error;
246 disable_irq(sr_info->irq);
247 }
248
249 if (pdata && pdata->enable_on_init)
250 sr_start_vddautocomp(sr_info);
251
252 return ret;
253
254error:
255 iounmap(sr_info->base);
256 mem = platform_get_resource(sr_info->pdev, IORESOURCE_MEM, 0);
257 release_mem_region(mem->start, resource_size(mem));
258 list_del(&sr_info->node);
259 dev_err(&sr_info->pdev->dev, "%s: ERROR in registering"
260 "interrupt handler. Smartreflex will"
261 "not function as desired\n", __func__);
262 kfree(sr_info);
263
264 return ret;
265}
266
267static void sr_v1_disable(struct omap_sr *sr)
268{
269 int timeout = 0;
270 int errconf_val = ERRCONFIG_MCUACCUMINTST | ERRCONFIG_MCUVALIDINTST |
271 ERRCONFIG_MCUBOUNDINTST;
272
273 /* Enable MCUDisableAcknowledge interrupt */
274 sr_modify_reg(sr, ERRCONFIG_V1,
275 ERRCONFIG_MCUDISACKINTEN, ERRCONFIG_MCUDISACKINTEN);
276
277 /* SRCONFIG - disable SR */
278 sr_modify_reg(sr, SRCONFIG, SRCONFIG_SRENABLE, 0x0);
279
280 /* Disable all other SR interrupts and clear the status as needed */
281 if (sr_read_reg(sr, ERRCONFIG_V1) & ERRCONFIG_VPBOUNDINTST_V1)
282 errconf_val |= ERRCONFIG_VPBOUNDINTST_V1;
283 sr_modify_reg(sr, ERRCONFIG_V1,
284 (ERRCONFIG_MCUACCUMINTEN | ERRCONFIG_MCUVALIDINTEN |
285 ERRCONFIG_MCUBOUNDINTEN | ERRCONFIG_VPBOUNDINTEN_V1),
286 errconf_val);
287
288 /*
289 * Wait for SR to be disabled.
290 * wait until ERRCONFIG.MCUDISACKINTST = 1. Typical latency is 1us.
291 */
292 sr_test_cond_timeout((sr_read_reg(sr, ERRCONFIG_V1) &
293 ERRCONFIG_MCUDISACKINTST), SR_DISABLE_TIMEOUT,
294 timeout);
295
296 if (timeout >= SR_DISABLE_TIMEOUT)
297 dev_warn(&sr->pdev->dev, "%s: Smartreflex disable timedout\n",
298 __func__);
299
300 /* Disable MCUDisableAcknowledge interrupt & clear pending interrupt */
301 sr_modify_reg(sr, ERRCONFIG_V1, ERRCONFIG_MCUDISACKINTEN,
302 ERRCONFIG_MCUDISACKINTST);
303}
304
305static void sr_v2_disable(struct omap_sr *sr)
306{
307 int timeout = 0;
308
309 /* Enable MCUDisableAcknowledge interrupt */
310 sr_write_reg(sr, IRQENABLE_SET, IRQENABLE_MCUDISABLEACKINT);
311
312 /* SRCONFIG - disable SR */
313 sr_modify_reg(sr, SRCONFIG, SRCONFIG_SRENABLE, 0x0);
314
315 /*
316 * Disable all other SR interrupts and clear the status
317 * write to status register ONLY on need basis - only if status
318 * is set.
319 */
320 if (sr_read_reg(sr, ERRCONFIG_V2) & ERRCONFIG_VPBOUNDINTST_V2)
321 sr_modify_reg(sr, ERRCONFIG_V2, ERRCONFIG_VPBOUNDINTEN_V2,
322 ERRCONFIG_VPBOUNDINTST_V2);
323 else
324 sr_modify_reg(sr, ERRCONFIG_V2, ERRCONFIG_VPBOUNDINTEN_V2,
325 0x0);
326 sr_write_reg(sr, IRQENABLE_CLR, (IRQENABLE_MCUACCUMINT |
327 IRQENABLE_MCUVALIDINT |
328 IRQENABLE_MCUBOUNDSINT));
329 sr_write_reg(sr, IRQSTATUS, (IRQSTATUS_MCUACCUMINT |
330 IRQSTATUS_MCVALIDINT |
331 IRQSTATUS_MCBOUNDSINT));
332
333 /*
334 * Wait for SR to be disabled.
335 * wait until IRQSTATUS.MCUDISACKINTST = 1. Typical latency is 1us.
336 */
337 sr_test_cond_timeout((sr_read_reg(sr, IRQSTATUS) &
338 IRQSTATUS_MCUDISABLEACKINT), SR_DISABLE_TIMEOUT,
339 timeout);
340
341 if (timeout >= SR_DISABLE_TIMEOUT)
342 dev_warn(&sr->pdev->dev, "%s: Smartreflex disable timedout\n",
343 __func__);
344
345 /* Disable MCUDisableAcknowledge interrupt & clear pending interrupt */
346 sr_write_reg(sr, IRQENABLE_CLR, IRQENABLE_MCUDISABLEACKINT);
347 sr_write_reg(sr, IRQSTATUS, IRQSTATUS_MCUDISABLEACKINT);
348}
349
350static struct omap_sr_nvalue_table *sr_retrieve_nvalue_row(
351 struct omap_sr *sr, u32 efuse_offs)
352{
353 int i;
354
355 if (!sr->nvalue_table) {
356 dev_warn(&sr->pdev->dev, "%s: Missing ntarget value table\n",
357 __func__);
358 return NULL;
359 }
360
361 for (i = 0; i < sr->nvalue_count; i++) {
362 if (sr->nvalue_table[i].efuse_offs == efuse_offs)
363 return &sr->nvalue_table[i];
364 }
365
366 return NULL;
367}
368
369/* Public Functions */
370
371/**
372 * sr_configure_errgen() - Configures the smrtreflex to perform AVS using the
373 * error generator module.
374 * @voltdm: VDD pointer to which the SR module to be configured belongs to.
375 *
376 * This API is to be called from the smartreflex class driver to
377 * configure the error generator module inside the smartreflex module.
378 * SR settings if using the ERROR module inside Smartreflex.
379 * SR CLASS 3 by default uses only the ERROR module where as
380 * SR CLASS 2 can choose between ERROR module and MINMAXAVG
381 * module. Returns 0 on success and error value in case of failure.
382 */
383int sr_configure_errgen(struct voltagedomain *voltdm)
384{
385 u32 sr_config, sr_errconfig, errconfig_offs;
386 u32 vpboundint_en, vpboundint_st;
387 u32 senp_en = 0, senn_en = 0;
388 u8 senp_shift, senn_shift;
389 struct omap_sr *sr = _sr_lookup(voltdm);
390
391 if (IS_ERR(sr)) {
392 pr_warning("%s: omap_sr struct for voltdm not found\n", __func__);
393 return PTR_ERR(sr);
394 }
395
396 if (!sr->clk_length)
397 sr_set_clk_length(sr);
398
399 senp_en = sr->senp_mod;
400 senn_en = sr->senn_mod;
401
402 sr_config = (sr->clk_length << SRCONFIG_SRCLKLENGTH_SHIFT) |
403 SRCONFIG_SENENABLE | SRCONFIG_ERRGEN_EN;
404
405 switch (sr->ip_type) {
406 case SR_TYPE_V1:
407 sr_config |= SRCONFIG_DELAYCTRL;
408 senn_shift = SRCONFIG_SENNENABLE_V1_SHIFT;
409 senp_shift = SRCONFIG_SENPENABLE_V1_SHIFT;
410 errconfig_offs = ERRCONFIG_V1;
411 vpboundint_en = ERRCONFIG_VPBOUNDINTEN_V1;
412 vpboundint_st = ERRCONFIG_VPBOUNDINTST_V1;
413 break;
414 case SR_TYPE_V2:
415 senn_shift = SRCONFIG_SENNENABLE_V2_SHIFT;
416 senp_shift = SRCONFIG_SENPENABLE_V2_SHIFT;
417 errconfig_offs = ERRCONFIG_V2;
418 vpboundint_en = ERRCONFIG_VPBOUNDINTEN_V2;
419 vpboundint_st = ERRCONFIG_VPBOUNDINTST_V2;
420 break;
421 default:
422 dev_err(&sr->pdev->dev, "%s: Trying to Configure smartreflex"
423 "module without specifying the ip\n", __func__);
424 return -EINVAL;
425 }
426
427 sr_config |= ((senn_en << senn_shift) | (senp_en << senp_shift));
428 sr_write_reg(sr, SRCONFIG, sr_config);
429 sr_errconfig = (sr->err_weight << ERRCONFIG_ERRWEIGHT_SHIFT) |
430 (sr->err_maxlimit << ERRCONFIG_ERRMAXLIMIT_SHIFT) |
431 (sr->err_minlimit << ERRCONFIG_ERRMINLIMIT_SHIFT);
432 sr_modify_reg(sr, errconfig_offs, (SR_ERRWEIGHT_MASK |
433 SR_ERRMAXLIMIT_MASK | SR_ERRMINLIMIT_MASK),
434 sr_errconfig);
435
436 /* Enabling the interrupts if the ERROR module is used */
437 sr_modify_reg(sr, errconfig_offs, (vpboundint_en | vpboundint_st),
438 vpboundint_en);
439
440 return 0;
441}
442
443/**
444 * sr_disable_errgen() - Disables SmartReflex AVS module's errgen component
445 * @voltdm: VDD pointer to which the SR module to be configured belongs to.
446 *
447 * This API is to be called from the smartreflex class driver to
448 * disable the error generator module inside the smartreflex module.
449 *
450 * Returns 0 on success and error value in case of failure.
451 */
452int sr_disable_errgen(struct voltagedomain *voltdm)
453{
454 u32 errconfig_offs;
455 u32 vpboundint_en, vpboundint_st;
456 struct omap_sr *sr = _sr_lookup(voltdm);
457
458 if (IS_ERR(sr)) {
459 pr_warning("%s: omap_sr struct for voltdm not found\n", __func__);
460 return PTR_ERR(sr);
461 }
462
463 switch (sr->ip_type) {
464 case SR_TYPE_V1:
465 errconfig_offs = ERRCONFIG_V1;
466 vpboundint_en = ERRCONFIG_VPBOUNDINTEN_V1;
467 vpboundint_st = ERRCONFIG_VPBOUNDINTST_V1;
468 break;
469 case SR_TYPE_V2:
470 errconfig_offs = ERRCONFIG_V2;
471 vpboundint_en = ERRCONFIG_VPBOUNDINTEN_V2;
472 vpboundint_st = ERRCONFIG_VPBOUNDINTST_V2;
473 break;
474 default:
475 dev_err(&sr->pdev->dev, "%s: Trying to Configure smartreflex"
476 "module without specifying the ip\n", __func__);
477 return -EINVAL;
478 }
479
480 /* Disable the interrupts of ERROR module */
481 sr_modify_reg(sr, errconfig_offs, vpboundint_en | vpboundint_st, 0);
482
483 /* Disable the Sensor and errorgen */
484 sr_modify_reg(sr, SRCONFIG, SRCONFIG_SENENABLE | SRCONFIG_ERRGEN_EN, 0);
485
486 return 0;
487}
488
489/**
490 * sr_configure_minmax() - Configures the smrtreflex to perform AVS using the
491 * minmaxavg module.
492 * @voltdm: VDD pointer to which the SR module to be configured belongs to.
493 *
494 * This API is to be called from the smartreflex class driver to
495 * configure the minmaxavg module inside the smartreflex module.
496 * SR settings if using the ERROR module inside Smartreflex.
497 * SR CLASS 3 by default uses only the ERROR module where as
498 * SR CLASS 2 can choose between ERROR module and MINMAXAVG
499 * module. Returns 0 on success and error value in case of failure.
500 */
501int sr_configure_minmax(struct voltagedomain *voltdm)
502{
503 u32 sr_config, sr_avgwt;
504 u32 senp_en = 0, senn_en = 0;
505 u8 senp_shift, senn_shift;
506 struct omap_sr *sr = _sr_lookup(voltdm);
507
508 if (IS_ERR(sr)) {
509 pr_warning("%s: omap_sr struct for voltdm not found\n", __func__);
510 return PTR_ERR(sr);
511 }
512
513 if (!sr->clk_length)
514 sr_set_clk_length(sr);
515
516 senp_en = sr->senp_mod;
517 senn_en = sr->senn_mod;
518
519 sr_config = (sr->clk_length << SRCONFIG_SRCLKLENGTH_SHIFT) |
520 SRCONFIG_SENENABLE |
521 (sr->accum_data << SRCONFIG_ACCUMDATA_SHIFT);
522
523 switch (sr->ip_type) {
524 case SR_TYPE_V1:
525 sr_config |= SRCONFIG_DELAYCTRL;
526 senn_shift = SRCONFIG_SENNENABLE_V1_SHIFT;
527 senp_shift = SRCONFIG_SENPENABLE_V1_SHIFT;
528 break;
529 case SR_TYPE_V2:
530 senn_shift = SRCONFIG_SENNENABLE_V2_SHIFT;
531 senp_shift = SRCONFIG_SENPENABLE_V2_SHIFT;
532 break;
533 default:
534 dev_err(&sr->pdev->dev, "%s: Trying to Configure smartreflex"
535 "module without specifying the ip\n", __func__);
536 return -EINVAL;
537 }
538
539 sr_config |= ((senn_en << senn_shift) | (senp_en << senp_shift));
540 sr_write_reg(sr, SRCONFIG, sr_config);
541 sr_avgwt = (sr->senp_avgweight << AVGWEIGHT_SENPAVGWEIGHT_SHIFT) |
542 (sr->senn_avgweight << AVGWEIGHT_SENNAVGWEIGHT_SHIFT);
543 sr_write_reg(sr, AVGWEIGHT, sr_avgwt);
544
545 /*
546 * Enabling the interrupts if MINMAXAVG module is used.
547 * TODO: check if all the interrupts are mandatory
548 */
549 switch (sr->ip_type) {
550 case SR_TYPE_V1:
551 sr_modify_reg(sr, ERRCONFIG_V1,
552 (ERRCONFIG_MCUACCUMINTEN | ERRCONFIG_MCUVALIDINTEN |
553 ERRCONFIG_MCUBOUNDINTEN),
554 (ERRCONFIG_MCUACCUMINTEN | ERRCONFIG_MCUACCUMINTST |
555 ERRCONFIG_MCUVALIDINTEN | ERRCONFIG_MCUVALIDINTST |
556 ERRCONFIG_MCUBOUNDINTEN | ERRCONFIG_MCUBOUNDINTST));
557 break;
558 case SR_TYPE_V2:
559 sr_write_reg(sr, IRQSTATUS,
560 IRQSTATUS_MCUACCUMINT | IRQSTATUS_MCVALIDINT |
561 IRQSTATUS_MCBOUNDSINT | IRQSTATUS_MCUDISABLEACKINT);
562 sr_write_reg(sr, IRQENABLE_SET,
563 IRQENABLE_MCUACCUMINT | IRQENABLE_MCUVALIDINT |
564 IRQENABLE_MCUBOUNDSINT | IRQENABLE_MCUDISABLEACKINT);
565 break;
566 default:
567 dev_err(&sr->pdev->dev, "%s: Trying to Configure smartreflex"
568 "module without specifying the ip\n", __func__);
569 return -EINVAL;
570 }
571
572 return 0;
573}
574
575/**
576 * sr_enable() - Enables the smartreflex module.
577 * @voltdm: VDD pointer to which the SR module to be configured belongs to.
578 * @volt: The voltage at which the Voltage domain associated with
579 * the smartreflex module is operating at.
580 * This is required only to program the correct Ntarget value.
581 *
582 * This API is to be called from the smartreflex class driver to
583 * enable a smartreflex module. Returns 0 on success. Returns error
584 * value if the voltage passed is wrong or if ntarget value is wrong.
585 */
586int sr_enable(struct voltagedomain *voltdm, unsigned long volt)
587{
588 struct omap_volt_data *volt_data;
589 struct omap_sr *sr = _sr_lookup(voltdm);
590 struct omap_sr_nvalue_table *nvalue_row;
591 int ret;
592
593 if (IS_ERR(sr)) {
594 pr_warning("%s: omap_sr struct for voltdm not found\n", __func__);
595 return PTR_ERR(sr);
596 }
597
598 volt_data = omap_voltage_get_voltdata(sr->voltdm, volt);
599
600 if (IS_ERR(volt_data)) {
601 dev_warn(&sr->pdev->dev, "%s: Unable to get voltage table"
602 "for nominal voltage %ld\n", __func__, volt);
603 return PTR_ERR(volt_data);
604 }
605
606 nvalue_row = sr_retrieve_nvalue_row(sr, volt_data->sr_efuse_offs);
607
608 if (!nvalue_row) {
609 dev_warn(&sr->pdev->dev, "%s: failure getting SR data for this voltage %ld\n",
610 __func__, volt);
611 return -ENODATA;
612 }
613
614 /* errminlimit is opp dependent and hence linked to voltage */
615 sr->err_minlimit = nvalue_row->errminlimit;
616
617 pm_runtime_get_sync(&sr->pdev->dev);
618
619 /* Check if SR is already enabled. If yes do nothing */
620 if (sr_read_reg(sr, SRCONFIG) & SRCONFIG_SRENABLE)
621 return 0;
622
623 /* Configure SR */
624 ret = sr_class->configure(sr);
625 if (ret)
626 return ret;
627
628 sr_write_reg(sr, NVALUERECIPROCAL, nvalue_row->nvalue);
629
630 /* SRCONFIG - enable SR */
631 sr_modify_reg(sr, SRCONFIG, SRCONFIG_SRENABLE, SRCONFIG_SRENABLE);
632 return 0;
633}
634
635/**
636 * sr_disable() - Disables the smartreflex module.
637 * @voltdm: VDD pointer to which the SR module to be configured belongs to.
638 *
639 * This API is to be called from the smartreflex class driver to
640 * disable a smartreflex module.
641 */
642void sr_disable(struct voltagedomain *voltdm)
643{
644 struct omap_sr *sr = _sr_lookup(voltdm);
645
646 if (IS_ERR(sr)) {
647 pr_warning("%s: omap_sr struct for voltdm not found\n", __func__);
648 return;
649 }
650
651 /* Check if SR clocks are already disabled. If yes do nothing */
652 if (pm_runtime_suspended(&sr->pdev->dev))
653 return;
654
655 /*
656 * Disable SR if only it is indeed enabled. Else just
657 * disable the clocks.
658 */
659 if (sr_read_reg(sr, SRCONFIG) & SRCONFIG_SRENABLE) {
660 switch (sr->ip_type) {
661 case SR_TYPE_V1:
662 sr_v1_disable(sr);
663 break;
664 case SR_TYPE_V2:
665 sr_v2_disable(sr);
666 break;
667 default:
668 dev_err(&sr->pdev->dev, "UNKNOWN IP type %d\n",
669 sr->ip_type);
670 }
671 }
672
673 pm_runtime_put_sync_suspend(&sr->pdev->dev);
674}
675
676/**
677 * sr_register_class() - API to register a smartreflex class parameters.
678 * @class_data: The structure containing various sr class specific data.
679 *
680 * This API is to be called by the smartreflex class driver to register itself
681 * with the smartreflex driver during init. Returns 0 on success else the
682 * error value.
683 */
684int sr_register_class(struct omap_sr_class_data *class_data)
685{
686 struct omap_sr *sr_info;
687
688 if (!class_data) {
689 pr_warning("%s:, Smartreflex class data passed is NULL\n",
690 __func__);
691 return -EINVAL;
692 }
693
694 if (sr_class) {
695 pr_warning("%s: Smartreflex class driver already registered\n",
696 __func__);
697 return -EBUSY;
698 }
699
700 sr_class = class_data;
701
702 /*
703 * Call into late init to do intializations that require
704 * both sr driver and sr class driver to be initiallized.
705 */
706 list_for_each_entry(sr_info, &sr_list, node)
707 sr_late_init(sr_info);
708
709 return 0;
710}
711
712/**
713 * omap_sr_enable() - API to enable SR clocks and to call into the
714 * registered smartreflex class enable API.
715 * @voltdm: VDD pointer to which the SR module to be configured belongs to.
716 *
717 * This API is to be called from the kernel in order to enable
718 * a particular smartreflex module. This API will do the initial
719 * configurations to turn on the smartreflex module and in turn call
720 * into the registered smartreflex class enable API.
721 */
722void omap_sr_enable(struct voltagedomain *voltdm)
723{
724 struct omap_sr *sr = _sr_lookup(voltdm);
725
726 if (IS_ERR(sr)) {
727 pr_warning("%s: omap_sr struct for voltdm not found\n", __func__);
728 return;
729 }
730
731 if (!sr->autocomp_active)
732 return;
733
734 if (!sr_class || !(sr_class->enable) || !(sr_class->configure)) {
735 dev_warn(&sr->pdev->dev, "%s: smartreflex class driver not"
736 "registered\n", __func__);
737 return;
738 }
739
740 sr_class->enable(sr);
741}
742
743/**
744 * omap_sr_disable() - API to disable SR without resetting the voltage
745 * processor voltage
746 * @voltdm: VDD pointer to which the SR module to be configured belongs to.
747 *
748 * This API is to be called from the kernel in order to disable
749 * a particular smartreflex module. This API will in turn call
750 * into the registered smartreflex class disable API. This API will tell
751 * the smartreflex class disable not to reset the VP voltage after
752 * disabling smartreflex.
753 */
754void omap_sr_disable(struct voltagedomain *voltdm)
755{
756 struct omap_sr *sr = _sr_lookup(voltdm);
757
758 if (IS_ERR(sr)) {
759 pr_warning("%s: omap_sr struct for voltdm not found\n", __func__);
760 return;
761 }
762
763 if (!sr->autocomp_active)
764 return;
765
766 if (!sr_class || !(sr_class->disable)) {
767 dev_warn(&sr->pdev->dev, "%s: smartreflex class driver not"
768 "registered\n", __func__);
769 return;
770 }
771
772 sr_class->disable(sr, 0);
773}
774
775/**
776 * omap_sr_disable_reset_volt() - API to disable SR and reset the
777 * voltage processor voltage
778 * @voltdm: VDD pointer to which the SR module to be configured belongs to.
779 *
780 * This API is to be called from the kernel in order to disable
781 * a particular smartreflex module. This API will in turn call
782 * into the registered smartreflex class disable API. This API will tell
783 * the smartreflex class disable to reset the VP voltage after
784 * disabling smartreflex.
785 */
786void omap_sr_disable_reset_volt(struct voltagedomain *voltdm)
787{
788 struct omap_sr *sr = _sr_lookup(voltdm);
789
790 if (IS_ERR(sr)) {
791 pr_warning("%s: omap_sr struct for voltdm not found\n", __func__);
792 return;
793 }
794
795 if (!sr->autocomp_active)
796 return;
797
798 if (!sr_class || !(sr_class->disable)) {
799 dev_warn(&sr->pdev->dev, "%s: smartreflex class driver not"
800 "registered\n", __func__);
801 return;
802 }
803
804 sr_class->disable(sr, 1);
805}
806
807/**
808 * omap_sr_register_pmic() - API to register pmic specific info.
809 * @pmic_data: The structure containing pmic specific data.
810 *
811 * This API is to be called from the PMIC specific code to register with
812 * smartreflex driver pmic specific info. Currently the only info required
813 * is the smartreflex init on the PMIC side.
814 */
815void omap_sr_register_pmic(struct omap_sr_pmic_data *pmic_data)
816{
817 if (!pmic_data) {
818 pr_warning("%s: Trying to register NULL PMIC data structure"
819 "with smartreflex\n", __func__);
820 return;
821 }
822
823 sr_pmic_data = pmic_data;
824}
825
826/* PM Debug FS entries to enable and disable smartreflex. */
827static int omap_sr_autocomp_show(void *data, u64 *val)
828{
829 struct omap_sr *sr_info = data;
830
831 if (!sr_info) {
832 pr_warning("%s: omap_sr struct not found\n", __func__);
833 return -EINVAL;
834 }
835
836 *val = sr_info->autocomp_active;
837
838 return 0;
839}
840
841static int omap_sr_autocomp_store(void *data, u64 val)
842{
843 struct omap_sr *sr_info = data;
844
845 if (!sr_info) {
846 pr_warning("%s: omap_sr struct not found\n", __func__);
847 return -EINVAL;
848 }
849
850 /* Sanity check */
851 if (val > 1) {
852 pr_warning("%s: Invalid argument %lld\n", __func__, val);
853 return -EINVAL;
854 }
855
856 /* control enable/disable only if there is a delta in value */
857 if (sr_info->autocomp_active != val) {
858 if (!val)
859 sr_stop_vddautocomp(sr_info);
860 else
861 sr_start_vddautocomp(sr_info);
862 }
863
864 return 0;
865}
866
867DEFINE_SIMPLE_ATTRIBUTE(pm_sr_fops, omap_sr_autocomp_show,
868 omap_sr_autocomp_store, "%llu\n");
869
870static int __init omap_sr_probe(struct platform_device *pdev)
871{
872 struct omap_sr *sr_info;
873 struct omap_sr_data *pdata = pdev->dev.platform_data;
874 struct resource *mem, *irq;
875 struct dentry *nvalue_dir;
876 int i, ret = 0;
877
878 sr_info = kzalloc(sizeof(struct omap_sr), GFP_KERNEL);
879 if (!sr_info) {
880 dev_err(&pdev->dev, "%s: unable to allocate sr_info\n",
881 __func__);
882 return -ENOMEM;
883 }
884
885 platform_set_drvdata(pdev, sr_info);
886
887 if (!pdata) {
888 dev_err(&pdev->dev, "%s: platform data missing\n", __func__);
889 ret = -EINVAL;
890 goto err_free_devinfo;
891 }
892
893 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
894 if (!mem) {
895 dev_err(&pdev->dev, "%s: no mem resource\n", __func__);
896 ret = -ENODEV;
897 goto err_free_devinfo;
898 }
899
900 mem = request_mem_region(mem->start, resource_size(mem),
901 dev_name(&pdev->dev));
902 if (!mem) {
903 dev_err(&pdev->dev, "%s: no mem region\n", __func__);
904 ret = -EBUSY;
905 goto err_free_devinfo;
906 }
907
908 irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
909
910 pm_runtime_enable(&pdev->dev);
911 pm_runtime_irq_safe(&pdev->dev);
912
913 sr_info->name = kasprintf(GFP_KERNEL, "%s", pdata->name);
914 if (!sr_info->name) {
915 dev_err(&pdev->dev, "%s: Unable to alloc SR instance name\n",
916 __func__);
917 ret = -ENOMEM;
918 goto err_release_region;
919 }
920
921 sr_info->pdev = pdev;
922 sr_info->srid = pdev->id;
923 sr_info->voltdm = pdata->voltdm;
924 sr_info->nvalue_table = pdata->nvalue_table;
925 sr_info->nvalue_count = pdata->nvalue_count;
926 sr_info->senn_mod = pdata->senn_mod;
927 sr_info->senp_mod = pdata->senp_mod;
928 sr_info->autocomp_active = false;
929 sr_info->ip_type = pdata->ip_type;
930 sr_info->base = ioremap(mem->start, resource_size(mem));
931 if (!sr_info->base) {
932 dev_err(&pdev->dev, "%s: ioremap fail\n", __func__);
933 ret = -ENOMEM;
934 goto err_release_region;
935 }
936
937 if (irq)
938 sr_info->irq = irq->start;
939
940 sr_set_clk_length(sr_info);
941 sr_set_regfields(sr_info);
942
943 list_add(&sr_info->node, &sr_list);
944
945 /*
946 * Call into late init to do intializations that require
947 * both sr driver and sr class driver to be initiallized.
948 */
949 if (sr_class) {
950 ret = sr_late_init(sr_info);
951 if (ret) {
952 pr_warning("%s: Error in SR late init\n", __func__);
953 goto err_iounmap;
954 }
955 }
956
957 dev_info(&pdev->dev, "%s: SmartReflex driver initialized\n", __func__);
958 if (!sr_dbg_dir) {
959 sr_dbg_dir = debugfs_create_dir("smartreflex", NULL);
960 if (IS_ERR_OR_NULL(sr_dbg_dir)) {
961 ret = PTR_ERR(sr_dbg_dir);
962 pr_err("%s:sr debugfs dir creation failed(%d)\n",
963 __func__, ret);
964 goto err_iounmap;
965 }
966 }
967
968 sr_info->dbg_dir = debugfs_create_dir(sr_info->name, sr_dbg_dir);
969 if (IS_ERR_OR_NULL(sr_info->dbg_dir)) {
970 dev_err(&pdev->dev, "%s: Unable to create debugfs directory\n",
971 __func__);
972 ret = PTR_ERR(sr_info->dbg_dir);
973 goto err_free_name;
974 }
975
976 (void) debugfs_create_file("autocomp", S_IRUGO | S_IWUSR,
977 sr_info->dbg_dir, (void *)sr_info, &pm_sr_fops);
978 (void) debugfs_create_x32("errweight", S_IRUGO, sr_info->dbg_dir,
979 &sr_info->err_weight);
980 (void) debugfs_create_x32("errmaxlimit", S_IRUGO, sr_info->dbg_dir,
981 &sr_info->err_maxlimit);
982
983 nvalue_dir = debugfs_create_dir("nvalue", sr_info->dbg_dir);
984 if (IS_ERR_OR_NULL(nvalue_dir)) {
985 dev_err(&pdev->dev, "%s: Unable to create debugfs directory"
986 "for n-values\n", __func__);
987 ret = PTR_ERR(nvalue_dir);
988 goto err_debugfs;
989 }
990
991 if (sr_info->nvalue_count == 0 || !sr_info->nvalue_table) {
992 dev_warn(&pdev->dev, "%s: %s: No Voltage table for the corresponding vdd. Cannot create debugfs entries for n-values\n",
993 __func__, sr_info->name);
994
995 ret = -ENODATA;
996 goto err_debugfs;
997 }
998
999 for (i = 0; i < sr_info->nvalue_count; i++) {
1000 char name[NVALUE_NAME_LEN + 1];
1001
1002 snprintf(name, sizeof(name), "volt_%lu",
1003 sr_info->nvalue_table[i].volt_nominal);
1004 (void) debugfs_create_x32(name, S_IRUGO | S_IWUSR, nvalue_dir,
1005 &(sr_info->nvalue_table[i].nvalue));
1006 snprintf(name, sizeof(name), "errminlimit_%lu",
1007 sr_info->nvalue_table[i].volt_nominal);
1008 (void) debugfs_create_x32(name, S_IRUGO | S_IWUSR, nvalue_dir,
1009 &(sr_info->nvalue_table[i].errminlimit));
1010
1011 }
1012
1013 return ret;
1014
1015err_debugfs:
1016 debugfs_remove_recursive(sr_info->dbg_dir);
1017err_free_name:
1018 kfree(sr_info->name);
1019err_iounmap:
1020 list_del(&sr_info->node);
1021 iounmap(sr_info->base);
1022err_release_region:
1023 release_mem_region(mem->start, resource_size(mem));
1024err_free_devinfo:
1025 kfree(sr_info);
1026
1027 return ret;
1028}
1029
1030static int __devexit omap_sr_remove(struct platform_device *pdev)
1031{
1032 struct omap_sr_data *pdata = pdev->dev.platform_data;
1033 struct omap_sr *sr_info;
1034 struct resource *mem;
1035
1036 if (!pdata) {
1037 dev_err(&pdev->dev, "%s: platform data missing\n", __func__);
1038 return -EINVAL;
1039 }
1040
1041 sr_info = _sr_lookup(pdata->voltdm);
1042 if (IS_ERR(sr_info)) {
1043 dev_warn(&pdev->dev, "%s: omap_sr struct not found\n",
1044 __func__);
1045 return PTR_ERR(sr_info);
1046 }
1047
1048 if (sr_info->autocomp_active)
1049 sr_stop_vddautocomp(sr_info);
1050 if (sr_info->dbg_dir)
1051 debugfs_remove_recursive(sr_info->dbg_dir);
1052
1053 list_del(&sr_info->node);
1054 iounmap(sr_info->base);
1055 kfree(sr_info->name);
1056 kfree(sr_info);
1057 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1058 release_mem_region(mem->start, resource_size(mem));
1059
1060 return 0;
1061}
1062
1063static void __devexit omap_sr_shutdown(struct platform_device *pdev)
1064{
1065 struct omap_sr_data *pdata = pdev->dev.platform_data;
1066 struct omap_sr *sr_info;
1067
1068 if (!pdata) {
1069 dev_err(&pdev->dev, "%s: platform data missing\n", __func__);
1070 return;
1071 }
1072
1073 sr_info = _sr_lookup(pdata->voltdm);
1074 if (IS_ERR(sr_info)) {
1075 dev_warn(&pdev->dev, "%s: omap_sr struct not found\n",
1076 __func__);
1077 return;
1078 }
1079
1080 if (sr_info->autocomp_active)
1081 sr_stop_vddautocomp(sr_info);
1082
1083 return;
1084}
1085
1086static struct platform_driver smartreflex_driver = {
1087 .remove = __devexit_p(omap_sr_remove),
1088 .shutdown = __devexit_p(omap_sr_shutdown),
1089 .driver = {
1090 .name = "smartreflex",
1091 },
1092};
1093
1094static int __init sr_init(void)
1095{
1096 int ret = 0;
1097
1098 /*
1099 * sr_init is a late init. If by then a pmic specific API is not
1100 * registered either there is no need for anything to be done on
1101 * the PMIC side or somebody has forgotten to register a PMIC
1102 * handler. Warn for the second condition.
1103 */
1104 if (sr_pmic_data && sr_pmic_data->sr_pmic_init)
1105 sr_pmic_data->sr_pmic_init();
1106 else
1107 pr_warning("%s: No PMIC hook to init smartreflex\n", __func__);
1108
1109 ret = platform_driver_probe(&smartreflex_driver, omap_sr_probe);
1110 if (ret) {
1111 pr_err("%s: platform driver register failed for SR\n",
1112 __func__);
1113 return ret;
1114 }
1115
1116 return 0;
1117}
1118late_initcall(sr_init);
1119
1120static void __exit sr_exit(void)
1121{
1122 platform_driver_unregister(&smartreflex_driver);
1123}
1124module_exit(sr_exit);
1125
1126MODULE_DESCRIPTION("OMAP Smartreflex Driver");
1127MODULE_LICENSE("GPL");
1128MODULE_ALIAS("platform:" DRIVER_NAME);
1129MODULE_AUTHOR("Texas Instruments Inc");
diff --git a/arch/arm/plat-omap/Kconfig b/arch/arm/plat-omap/Kconfig
index bba384dfbcf6..816dec062f3c 100644
--- a/arch/arm/plat-omap/Kconfig
+++ b/arch/arm/plat-omap/Kconfig
@@ -45,26 +45,12 @@ config OMAP_DEBUG_LEDS
45 depends on OMAP_DEBUG_DEVICES 45 depends on OMAP_DEBUG_DEVICES
46 default y if LEDS_CLASS 46 default y if LEDS_CLASS
47 47
48menuconfig POWER_AVS
49 tristate "Adaptive Voltage Scaling class support"
50 help
51 AVS(Adaptive Voltage Scaling) is a power management technique which
52 finely controls the operating voltage of a device in order to optimize
53 (i.e. reduce) its power consumption.
54 At a given operating point the voltage is adapted depending on
55 static factors (chip manufacturing process) and dynamic factors
56 (temperature depending performance).
57 AVS is also called SmartReflex on OMAP devices.
58
59 Say Y here to enable Adaptive Voltage Scaling class support.
60
61if POWER_AVS
62
63config POWER_AVS_OMAP 48config POWER_AVS_OMAP
64 bool "AVS(Adaptive Voltage Scaling) support for OMAP IP versions 1&2" 49 bool "AVS(Adaptive Voltage Scaling) support for OMAP IP versions 1&2"
65 depends on (ARCH_OMAP3 || ARCH_OMAP4) && PM 50 depends on POWER_AVS && (ARCH_OMAP3 || ARCH_OMAP4) && PM
66 help 51 help
67 Say Y to enable AVS support on OMAP containing the version 1 or 52 Say Y to enable AVS(Adaptive Voltage Scaling)
53 support on OMAP containing the version 1 or
68 version 2 of the SmartReflex IP. 54 version 2 of the SmartReflex IP.
69 V1 is the 65nm version used in OMAP3430. 55 V1 is the 65nm version used in OMAP3430.
70 V2 is the update for the 45nm version of the IP used in OMAP3630 56 V2 is the update for the 45nm version of the IP used in OMAP3630
@@ -89,8 +75,6 @@ config POWER_AVS_OMAP_CLASS3
89 Class 3 implementation of Smartreflex employs continuous hardware 75 Class 3 implementation of Smartreflex employs continuous hardware
90 voltage calibration. 76 voltage calibration.
91 77
92endif # POWER_AVS
93
94config OMAP_RESET_CLOCKS 78config OMAP_RESET_CLOCKS
95 bool "Reset unused clocks during boot" 79 bool "Reset unused clocks during boot"
96 depends on ARCH_OMAP 80 depends on ARCH_OMAP