Linux Audio

Check our new training course

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