Version:  2.0.40 2.2.26 2.4.37 3.13 3.14 3.15 3.16 3.17 3.18 3.19 4.0 4.1 4.2 4.3 4.4 4.5 4.6 4.7 4.8 4.9 4.10

Linux/drivers/power/avs/smartreflex.c

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

This page was automatically generated by LXR 0.3.1 (source).  •  Linux is a registered trademark of Linus Torvalds  •  Contact us