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