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